diff --git a/.gitignore b/.gitignore index 74ae26a0da5..c7f0a565e11 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ .idea .history .DS_Store +*.iml diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 9d0adf14b81..db2baf61501 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -44,14 +44,17 @@ Getting the code and configuring your environment * Run `flutter update-packages` This will fetch all the Dart packages that Flutter depends on. You can replicate what this script does by running `pub get` in each directory that contains a `pubspec.yaml` file. + * If you plan on using IntelliJ as your IDE, then also run + `flutter ide-config --overwrite` to create all of the IntelliJ configuration + files so you can open the main flutter directory as a project and run examples + from within the IDE. Running the examples -------------------- -To run an example with a prebuilt binary from the cloud, switch to that -example's directory, run `pub get` to make sure its dependencies have been -downloaded, and use `flutter run`. Make sure you have a device connected over -USB and debugging enabled on that device. +To run an example, switch to that example's directory, and use `flutter run`. +Make sure you have an emulator running, or a device connected over USB and +debugging enabled on that device. * `cd examples/hello_world` * `flutter run` diff --git a/examples/flutter_gallery/.idea/libraries/Dart_SDK.xml b/examples/flutter_gallery/.idea/libraries/Dart_SDK.xml deleted file mode 100644 index 26389a366d2..00000000000 --- a/examples/flutter_gallery/.idea/libraries/Dart_SDK.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/examples/flutter_gallery/.idea/modules.xml b/examples/flutter_gallery/.idea/modules.xml deleted file mode 100644 index 180cda925db..00000000000 --- a/examples/flutter_gallery/.idea/modules.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/examples/flutter_gallery/.idea/runConfigurations/main_dart.xml b/examples/flutter_gallery/.idea/runConfigurations/main_dart.xml deleted file mode 100644 index aab7b5cd832..00000000000 --- a/examples/flutter_gallery/.idea/runConfigurations/main_dart.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - \ No newline at end of file diff --git a/examples/flutter_view/.idea/libraries/Dart_SDK.xml b/examples/flutter_view/.idea/libraries/Dart_SDK.xml deleted file mode 100644 index 26389a366d2..00000000000 --- a/examples/flutter_view/.idea/libraries/Dart_SDK.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/examples/flutter_view/.idea/modules.xml b/examples/flutter_view/.idea/modules.xml deleted file mode 100644 index e26bec79dfb..00000000000 --- a/examples/flutter_view/.idea/modules.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/examples/flutter_view/.idea/runConfigurations/main_dart.xml b/examples/flutter_view/.idea/runConfigurations/main_dart.xml deleted file mode 100644 index aab7b5cd832..00000000000 --- a/examples/flutter_view/.idea/runConfigurations/main_dart.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - \ No newline at end of file diff --git a/examples/hello_world/.idea/libraries/Dart_SDK.xml b/examples/hello_world/.idea/libraries/Dart_SDK.xml deleted file mode 100644 index 26389a366d2..00000000000 --- a/examples/hello_world/.idea/libraries/Dart_SDK.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/examples/hello_world/.idea/modules.xml b/examples/hello_world/.idea/modules.xml deleted file mode 100644 index 6c4ef6201ed..00000000000 --- a/examples/hello_world/.idea/modules.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/examples/hello_world/.idea/runConfigurations/main_dart.xml b/examples/hello_world/.idea/runConfigurations/main_dart.xml deleted file mode 100644 index f94721b31b0..00000000000 --- a/examples/hello_world/.idea/runConfigurations/main_dart.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - diff --git a/examples/layers/.idea/libraries/Dart_SDK.xml b/examples/layers/.idea/libraries/Dart_SDK.xml deleted file mode 100644 index 26389a366d2..00000000000 --- a/examples/layers/.idea/libraries/Dart_SDK.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/examples/layers/.idea/modules.xml b/examples/layers/.idea/modules.xml deleted file mode 100644 index ec44738db89..00000000000 --- a/examples/layers/.idea/modules.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/examples/platform_channel/.idea/libraries/Dart_SDK.xml b/examples/platform_channel/.idea/libraries/Dart_SDK.xml deleted file mode 100644 index 26389a366d2..00000000000 --- a/examples/platform_channel/.idea/libraries/Dart_SDK.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/examples/platform_channel/.idea/modules.xml b/examples/platform_channel/.idea/modules.xml deleted file mode 100644 index 65b2dcbcc16..00000000000 --- a/examples/platform_channel/.idea/modules.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - diff --git a/examples/platform_channel/.idea/runConfigurations/main_dart.xml b/examples/platform_channel/.idea/runConfigurations/main_dart.xml deleted file mode 100644 index aab7b5cd832..00000000000 --- a/examples/platform_channel/.idea/runConfigurations/main_dart.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - \ No newline at end of file diff --git a/examples/platform_channel_swift/.idea/libraries/Dart_SDK.xml b/examples/platform_channel_swift/.idea/libraries/Dart_SDK.xml deleted file mode 100644 index 26389a366d2..00000000000 --- a/examples/platform_channel_swift/.idea/libraries/Dart_SDK.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/examples/platform_channel_swift/.idea/modules.xml b/examples/platform_channel_swift/.idea/modules.xml deleted file mode 100644 index 002f5cb15e9..00000000000 --- a/examples/platform_channel_swift/.idea/modules.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - diff --git a/examples/platform_channel_swift/.idea/runConfigurations/main_dart.xml b/examples/platform_channel_swift/.idea/runConfigurations/main_dart.xml deleted file mode 100644 index aab7b5cd832..00000000000 --- a/examples/platform_channel_swift/.idea/runConfigurations/main_dart.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - \ No newline at end of file diff --git a/examples/platform_view/full_platform_view.iml b/examples/platform_view/full_platform_view.iml deleted file mode 100644 index e75a6371f79..00000000000 --- a/examples/platform_view/full_platform_view.iml +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - - - - - - - - diff --git a/examples/stocks/.idea/libraries/Dart_SDK.xml b/examples/stocks/.idea/libraries/Dart_SDK.xml deleted file mode 100644 index 26389a366d2..00000000000 --- a/examples/stocks/.idea/libraries/Dart_SDK.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/examples/stocks/.idea/modules.xml b/examples/stocks/.idea/modules.xml deleted file mode 100644 index c668e7d46c0..00000000000 --- a/examples/stocks/.idea/modules.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/examples/stocks/.idea/runConfigurations/main_dart.xml b/examples/stocks/.idea/runConfigurations/main_dart.xml deleted file mode 100644 index f94721b31b0..00000000000 --- a/examples/stocks/.idea/runConfigurations/main_dart.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - diff --git a/examples/stocks/stocks.iml b/examples/stocks/stocks.iml deleted file mode 100644 index e75a6371f79..00000000000 --- a/examples/stocks/stocks.iml +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - - - - - - - - diff --git a/.idea/.name b/packages/flutter_tools/ide_templates/intellij/.idea/.name.copy.tmpl similarity index 100% rename from .idea/.name rename to packages/flutter_tools/ide_templates/intellij/.idea/.name.copy.tmpl diff --git a/.idea/modules.xml b/packages/flutter_tools/ide_templates/intellij/.idea/modules.xml.copy.tmpl similarity index 51% rename from .idea/modules.xml rename to packages/flutter_tools/ide_templates/intellij/.idea/modules.xml.copy.tmpl index d57a93f57ba..65465354193 100644 --- a/.idea/modules.xml +++ b/packages/flutter_tools/ide_templates/intellij/.idea/modules.xml.copy.tmpl @@ -2,7 +2,10 @@ + + + @@ -10,7 +13,14 @@ + + + + + + + diff --git a/packages/flutter_tools/ide_templates/intellij/.idea/runConfigurations/benchmarks___complex_layout.xml.copy.tmpl b/packages/flutter_tools/ide_templates/intellij/.idea/runConfigurations/benchmarks___complex_layout.xml.copy.tmpl new file mode 100644 index 00000000000..ad550babd28 --- /dev/null +++ b/packages/flutter_tools/ide_templates/intellij/.idea/runConfigurations/benchmarks___complex_layout.xml.copy.tmpl @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/packages/flutter_tools/ide_templates/intellij/.idea/runConfigurations/catalog.xml.copy.tmpl b/packages/flutter_tools/ide_templates/intellij/.idea/runConfigurations/catalog.xml.copy.tmpl new file mode 100644 index 00000000000..93428232d87 --- /dev/null +++ b/packages/flutter_tools/ide_templates/intellij/.idea/runConfigurations/catalog.xml.copy.tmpl @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/.idea/runConfigurations/flutter_gallery.xml b/packages/flutter_tools/ide_templates/intellij/.idea/runConfigurations/flutter_gallery.xml.copy.tmpl similarity index 100% rename from .idea/runConfigurations/flutter_gallery.xml rename to packages/flutter_tools/ide_templates/intellij/.idea/runConfigurations/flutter_gallery.xml.copy.tmpl diff --git a/.idea/runConfigurations/flutter_tools.xml b/packages/flutter_tools/ide_templates/intellij/.idea/runConfigurations/flutter_tools.xml.copy.tmpl similarity index 100% rename from .idea/runConfigurations/flutter_tools.xml rename to packages/flutter_tools/ide_templates/intellij/.idea/runConfigurations/flutter_tools.xml.copy.tmpl diff --git a/packages/flutter_tools/ide_templates/intellij/.idea/runConfigurations/flutter_view.xml.copy.tmpl b/packages/flutter_tools/ide_templates/intellij/.idea/runConfigurations/flutter_view.xml.copy.tmpl new file mode 100644 index 00000000000..252726a240d --- /dev/null +++ b/packages/flutter_tools/ide_templates/intellij/.idea/runConfigurations/flutter_view.xml.copy.tmpl @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/.idea/runConfigurations/hello_world.xml b/packages/flutter_tools/ide_templates/intellij/.idea/runConfigurations/hello_world.xml.copy.tmpl similarity index 100% rename from .idea/runConfigurations/hello_world.xml rename to packages/flutter_tools/ide_templates/intellij/.idea/runConfigurations/hello_world.xml.copy.tmpl diff --git a/packages/flutter_tools/ide_templates/intellij/.idea/runConfigurations/layers___custom_render_box.xml.copy.tmpl b/packages/flutter_tools/ide_templates/intellij/.idea/runConfigurations/layers___custom_render_box.xml.copy.tmpl new file mode 100644 index 00000000000..f2ae4241025 --- /dev/null +++ b/packages/flutter_tools/ide_templates/intellij/.idea/runConfigurations/layers___custom_render_box.xml.copy.tmpl @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/packages/flutter_tools/ide_templates/intellij/.idea/runConfigurations/layers___gestures.xml.copy.tmpl b/packages/flutter_tools/ide_templates/intellij/.idea/runConfigurations/layers___gestures.xml.copy.tmpl new file mode 100644 index 00000000000..0cd8785b251 --- /dev/null +++ b/packages/flutter_tools/ide_templates/intellij/.idea/runConfigurations/layers___gestures.xml.copy.tmpl @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/packages/flutter_tools/ide_templates/intellij/.idea/runConfigurations/layers___hello_world.xml.copy.tmpl b/packages/flutter_tools/ide_templates/intellij/.idea/runConfigurations/layers___hello_world.xml.copy.tmpl new file mode 100644 index 00000000000..3aae9f135b7 --- /dev/null +++ b/packages/flutter_tools/ide_templates/intellij/.idea/runConfigurations/layers___hello_world.xml.copy.tmpl @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/packages/flutter_tools/ide_templates/intellij/.idea/runConfigurations/layers___isolate.xml.copy.tmpl b/packages/flutter_tools/ide_templates/intellij/.idea/runConfigurations/layers___isolate.xml.copy.tmpl new file mode 100644 index 00000000000..d0a3d705231 --- /dev/null +++ b/packages/flutter_tools/ide_templates/intellij/.idea/runConfigurations/layers___isolate.xml.copy.tmpl @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/packages/flutter_tools/ide_templates/intellij/.idea/runConfigurations/layers___lifecycle.xml.copy.tmpl b/packages/flutter_tools/ide_templates/intellij/.idea/runConfigurations/layers___lifecycle.xml.copy.tmpl new file mode 100644 index 00000000000..755fe18966a --- /dev/null +++ b/packages/flutter_tools/ide_templates/intellij/.idea/runConfigurations/layers___lifecycle.xml.copy.tmpl @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/packages/flutter_tools/ide_templates/intellij/.idea/runConfigurations/layers___sectors.xml.copy.tmpl b/packages/flutter_tools/ide_templates/intellij/.idea/runConfigurations/layers___sectors.xml.copy.tmpl new file mode 100644 index 00000000000..7b5ba1a256e --- /dev/null +++ b/packages/flutter_tools/ide_templates/intellij/.idea/runConfigurations/layers___sectors.xml.copy.tmpl @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/packages/flutter_tools/ide_templates/intellij/.idea/runConfigurations/layers___spinning_square.xml.copy.tmpl b/packages/flutter_tools/ide_templates/intellij/.idea/runConfigurations/layers___spinning_square.xml.copy.tmpl new file mode 100644 index 00000000000..676994cbe42 --- /dev/null +++ b/packages/flutter_tools/ide_templates/intellij/.idea/runConfigurations/layers___spinning_square.xml.copy.tmpl @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/packages/flutter_tools/ide_templates/intellij/.idea/runConfigurations/layers___styled_text.xml.copy.tmpl b/packages/flutter_tools/ide_templates/intellij/.idea/runConfigurations/layers___styled_text.xml.copy.tmpl new file mode 100644 index 00000000000..635a3279b68 --- /dev/null +++ b/packages/flutter_tools/ide_templates/intellij/.idea/runConfigurations/layers___styled_text.xml.copy.tmpl @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/packages/flutter_tools/ide_templates/intellij/.idea/runConfigurations/manual_tests___card_collection.xml.copy.tmpl b/packages/flutter_tools/ide_templates/intellij/.idea/runConfigurations/manual_tests___card_collection.xml.copy.tmpl new file mode 100644 index 00000000000..5d63d14d0a6 --- /dev/null +++ b/packages/flutter_tools/ide_templates/intellij/.idea/runConfigurations/manual_tests___card_collection.xml.copy.tmpl @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/packages/flutter_tools/ide_templates/intellij/.idea/runConfigurations/manual_tests___color_testing_demo.xml.copy.tmpl b/packages/flutter_tools/ide_templates/intellij/.idea/runConfigurations/manual_tests___color_testing_demo.xml.copy.tmpl new file mode 100644 index 00000000000..25d54cb01dc --- /dev/null +++ b/packages/flutter_tools/ide_templates/intellij/.idea/runConfigurations/manual_tests___color_testing_demo.xml.copy.tmpl @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/packages/flutter_tools/ide_templates/intellij/.idea/runConfigurations/manual_tests___drag_and_drop.xml.copy.tmpl b/packages/flutter_tools/ide_templates/intellij/.idea/runConfigurations/manual_tests___drag_and_drop.xml.copy.tmpl new file mode 100644 index 00000000000..f1d3b034b5e --- /dev/null +++ b/packages/flutter_tools/ide_templates/intellij/.idea/runConfigurations/manual_tests___drag_and_drop.xml.copy.tmpl @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/packages/flutter_tools/ide_templates/intellij/.idea/runConfigurations/manual_tests___material_arc.xml.copy.tmpl b/packages/flutter_tools/ide_templates/intellij/.idea/runConfigurations/manual_tests___material_arc.xml.copy.tmpl new file mode 100644 index 00000000000..b14c448dcc5 --- /dev/null +++ b/packages/flutter_tools/ide_templates/intellij/.idea/runConfigurations/manual_tests___material_arc.xml.copy.tmpl @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/packages/flutter_tools/ide_templates/intellij/.idea/runConfigurations/manual_tests___overlay_geometry.xml.copy.tmpl b/packages/flutter_tools/ide_templates/intellij/.idea/runConfigurations/manual_tests___overlay_geometry.xml.copy.tmpl new file mode 100644 index 00000000000..230c1cff695 --- /dev/null +++ b/packages/flutter_tools/ide_templates/intellij/.idea/runConfigurations/manual_tests___overlay_geometry.xml.copy.tmpl @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/packages/flutter_tools/ide_templates/intellij/.idea/runConfigurations/manual_tests___page_view.xml.copy.tmpl b/packages/flutter_tools/ide_templates/intellij/.idea/runConfigurations/manual_tests___page_view.xml.copy.tmpl new file mode 100644 index 00000000000..d41e48c073e --- /dev/null +++ b/packages/flutter_tools/ide_templates/intellij/.idea/runConfigurations/manual_tests___page_view.xml.copy.tmpl @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/packages/flutter_tools/ide_templates/intellij/.idea/runConfigurations/manual_tests___raw_keyboard.xml.copy.tmpl b/packages/flutter_tools/ide_templates/intellij/.idea/runConfigurations/manual_tests___raw_keyboard.xml.copy.tmpl new file mode 100644 index 00000000000..66ad97acc83 --- /dev/null +++ b/packages/flutter_tools/ide_templates/intellij/.idea/runConfigurations/manual_tests___raw_keyboard.xml.copy.tmpl @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/packages/flutter_tools/ide_templates/intellij/.idea/runConfigurations/manual_tests___text.xml.copy.tmpl b/packages/flutter_tools/ide_templates/intellij/.idea/runConfigurations/manual_tests___text.xml.copy.tmpl new file mode 100644 index 00000000000..74fbeb77be2 --- /dev/null +++ b/packages/flutter_tools/ide_templates/intellij/.idea/runConfigurations/manual_tests___text.xml.copy.tmpl @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/packages/flutter_tools/ide_templates/intellij/.idea/runConfigurations/plaform_view.xml.copy.tmpl b/packages/flutter_tools/ide_templates/intellij/.idea/runConfigurations/plaform_view.xml.copy.tmpl new file mode 100644 index 00000000000..bfe7a7db883 --- /dev/null +++ b/packages/flutter_tools/ide_templates/intellij/.idea/runConfigurations/plaform_view.xml.copy.tmpl @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/packages/flutter_tools/ide_templates/intellij/.idea/runConfigurations/platform_channel.xml.copy.tmpl b/packages/flutter_tools/ide_templates/intellij/.idea/runConfigurations/platform_channel.xml.copy.tmpl new file mode 100644 index 00000000000..755c3bebbea --- /dev/null +++ b/packages/flutter_tools/ide_templates/intellij/.idea/runConfigurations/platform_channel.xml.copy.tmpl @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/packages/flutter_tools/ide_templates/intellij/.idea/runConfigurations/platform_channel_swift.xml.copy.tmpl b/packages/flutter_tools/ide_templates/intellij/.idea/runConfigurations/platform_channel_swift.xml.copy.tmpl new file mode 100644 index 00000000000..1e80ea684b3 --- /dev/null +++ b/packages/flutter_tools/ide_templates/intellij/.idea/runConfigurations/platform_channel_swift.xml.copy.tmpl @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/packages/flutter_tools/ide_templates/intellij/.idea/runConfigurations/stocks.xml.copy.tmpl b/packages/flutter_tools/ide_templates/intellij/.idea/runConfigurations/stocks.xml.copy.tmpl new file mode 100644 index 00000000000..0e4976d2357 --- /dev/null +++ b/packages/flutter_tools/ide_templates/intellij/.idea/runConfigurations/stocks.xml.copy.tmpl @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/packages/flutter_tools/ide_templates/intellij/.idea/vcs.xml.copy.tmpl b/packages/flutter_tools/ide_templates/intellij/.idea/vcs.xml.copy.tmpl new file mode 100644 index 00000000000..94a25f7f4cb --- /dev/null +++ b/packages/flutter_tools/ide_templates/intellij/.idea/vcs.xml.copy.tmpl @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/packages/flutter_tools/ide_templates/intellij/dev/benchmarks/complex_layout/complex_layout.iml.copy.tmpl b/packages/flutter_tools/ide_templates/intellij/dev/benchmarks/complex_layout/complex_layout.iml.copy.tmpl new file mode 100644 index 00000000000..65865e3ec94 --- /dev/null +++ b/packages/flutter_tools/ide_templates/intellij/dev/benchmarks/complex_layout/complex_layout.iml.copy.tmpl @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dev/bots/bots.iml b/packages/flutter_tools/ide_templates/intellij/dev/bots/bots.iml.copy.tmpl similarity index 100% rename from dev/bots/bots.iml rename to packages/flutter_tools/ide_templates/intellij/dev/bots/bots.iml.copy.tmpl diff --git a/dev/devicelab/devicelab.iml b/packages/flutter_tools/ide_templates/intellij/dev/devicelab/devicelab.iml.copy.tmpl similarity index 100% rename from dev/devicelab/devicelab.iml rename to packages/flutter_tools/ide_templates/intellij/dev/devicelab/devicelab.iml.copy.tmpl diff --git a/dev/manual_tests/android.iml b/packages/flutter_tools/ide_templates/intellij/dev/manual_tests/android.iml.copy.tmpl similarity index 100% rename from dev/manual_tests/android.iml rename to packages/flutter_tools/ide_templates/intellij/dev/manual_tests/android.iml.copy.tmpl diff --git a/examples/layers/layers.iml b/packages/flutter_tools/ide_templates/intellij/dev/manual_tests/manual_tests.iml.copy.tmpl similarity index 98% rename from examples/layers/layers.iml rename to packages/flutter_tools/ide_templates/intellij/dev/manual_tests/manual_tests.iml.copy.tmpl index cedac514e4c..cd38844c2d5 100644 --- a/examples/layers/layers.iml +++ b/packages/flutter_tools/ide_templates/intellij/dev/manual_tests/manual_tests.iml.copy.tmpl @@ -13,4 +13,4 @@ - + \ No newline at end of file diff --git a/dev/tools/tools.iml b/packages/flutter_tools/ide_templates/intellij/dev/tools/tools.iml.copy.tmpl similarity index 100% rename from dev/tools/tools.iml rename to packages/flutter_tools/ide_templates/intellij/dev/tools/tools.iml.copy.tmpl diff --git a/packages/flutter_tools/ide_templates/intellij/examples/catalog/catalog.iml.copy.tmpl b/packages/flutter_tools/ide_templates/intellij/examples/catalog/catalog.iml.copy.tmpl new file mode 100644 index 00000000000..ff4051b3b5f --- /dev/null +++ b/packages/flutter_tools/ide_templates/intellij/examples/catalog/catalog.iml.copy.tmpl @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/flutter_gallery/android.iml b/packages/flutter_tools/ide_templates/intellij/examples/flutter_gallery/android.iml.copy.tmpl similarity index 100% rename from examples/flutter_gallery/android.iml rename to packages/flutter_tools/ide_templates/intellij/examples/flutter_gallery/android.iml.copy.tmpl diff --git a/examples/flutter_gallery/flutter_gallery.iml b/packages/flutter_tools/ide_templates/intellij/examples/flutter_gallery/flutter_gallery.iml.copy.tmpl similarity index 100% rename from examples/flutter_gallery/flutter_gallery.iml rename to packages/flutter_tools/ide_templates/intellij/examples/flutter_gallery/flutter_gallery.iml.copy.tmpl diff --git a/examples/flutter_view/flutter_view.iml b/packages/flutter_tools/ide_templates/intellij/examples/flutter_view/flutter_view.iml.copy.tmpl similarity index 98% rename from examples/flutter_view/flutter_view.iml rename to packages/flutter_tools/ide_templates/intellij/examples/flutter_view/flutter_view.iml.copy.tmpl index f251445ba75..1e956bd50a7 100644 --- a/examples/flutter_view/flutter_view.iml +++ b/packages/flutter_tools/ide_templates/intellij/examples/flutter_view/flutter_view.iml.copy.tmpl @@ -12,4 +12,4 @@ - + \ No newline at end of file diff --git a/examples/hello_world/android.iml b/packages/flutter_tools/ide_templates/intellij/examples/hello_world/android.iml.copy.tmpl similarity index 100% rename from examples/hello_world/android.iml rename to packages/flutter_tools/ide_templates/intellij/examples/hello_world/android.iml.copy.tmpl diff --git a/examples/hello_world/hello_world.iml b/packages/flutter_tools/ide_templates/intellij/examples/hello_world/hello_world.iml.copy.tmpl similarity index 100% rename from examples/hello_world/hello_world.iml rename to packages/flutter_tools/ide_templates/intellij/examples/hello_world/hello_world.iml.copy.tmpl diff --git a/packages/flutter_tools/ide_templates/intellij/examples/layers/layers.iml.copy.tmpl b/packages/flutter_tools/ide_templates/intellij/examples/layers/layers.iml.copy.tmpl new file mode 100644 index 00000000000..7a21b7757cd --- /dev/null +++ b/packages/flutter_tools/ide_templates/intellij/examples/layers/layers.iml.copy.tmpl @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/platform_channel/android.iml b/packages/flutter_tools/ide_templates/intellij/examples/platform_channel/android.iml.copy.tmpl similarity index 100% rename from examples/platform_channel/android.iml rename to packages/flutter_tools/ide_templates/intellij/examples/platform_channel/android.iml.copy.tmpl diff --git a/examples/platform_channel_swift/platform_channel_swift.iml b/packages/flutter_tools/ide_templates/intellij/examples/platform_channel/platform_channel.iml.copy.tmpl similarity index 89% rename from examples/platform_channel_swift/platform_channel_swift.iml rename to packages/flutter_tools/ide_templates/intellij/examples/platform_channel/platform_channel.iml.copy.tmpl index e75a6371f79..6beca6a0689 100644 --- a/examples/platform_channel_swift/platform_channel_swift.iml +++ b/packages/flutter_tools/ide_templates/intellij/examples/platform_channel/platform_channel.iml.copy.tmpl @@ -6,10 +6,9 @@ - - + - + \ No newline at end of file diff --git a/examples/platform_channel/platform_channel.iml b/packages/flutter_tools/ide_templates/intellij/examples/platform_channel_swift/platform_channel_swift.iml.copy.tmpl similarity index 89% rename from examples/platform_channel/platform_channel.iml rename to packages/flutter_tools/ide_templates/intellij/examples/platform_channel_swift/platform_channel_swift.iml.copy.tmpl index e75a6371f79..6beca6a0689 100644 --- a/examples/platform_channel/platform_channel.iml +++ b/packages/flutter_tools/ide_templates/intellij/examples/platform_channel_swift/platform_channel_swift.iml.copy.tmpl @@ -6,10 +6,9 @@ - - + - + \ No newline at end of file diff --git a/examples/platform_view/android.iml b/packages/flutter_tools/ide_templates/intellij/examples/platform_view/android.iml.copy.tmpl similarity index 100% rename from examples/platform_view/android.iml rename to packages/flutter_tools/ide_templates/intellij/examples/platform_view/android.iml.copy.tmpl diff --git a/packages/flutter_tools/ide_templates/intellij/examples/platform_view/full_platform_view.iml.copy.tmpl b/packages/flutter_tools/ide_templates/intellij/examples/platform_view/full_platform_view.iml.copy.tmpl new file mode 100644 index 00000000000..6beca6a0689 --- /dev/null +++ b/packages/flutter_tools/ide_templates/intellij/examples/platform_view/full_platform_view.iml.copy.tmpl @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/stocks/android.iml b/packages/flutter_tools/ide_templates/intellij/examples/stocks/android.iml.copy.tmpl similarity index 100% rename from examples/stocks/android.iml rename to packages/flutter_tools/ide_templates/intellij/examples/stocks/android.iml.copy.tmpl diff --git a/dev/manual_tests/manual_tests.iml b/packages/flutter_tools/ide_templates/intellij/examples/stocks/stocks.iml.copy.tmpl similarity index 90% rename from dev/manual_tests/manual_tests.iml rename to packages/flutter_tools/ide_templates/intellij/examples/stocks/stocks.iml.copy.tmpl index e75a6371f79..cd38844c2d5 100644 --- a/dev/manual_tests/manual_tests.iml +++ b/packages/flutter_tools/ide_templates/intellij/examples/stocks/stocks.iml.copy.tmpl @@ -7,9 +7,10 @@ + - + - + \ No newline at end of file diff --git a/packages/flutter/flutter.iml b/packages/flutter_tools/ide_templates/intellij/packages/flutter/flutter.iml.copy.tmpl similarity index 100% rename from packages/flutter/flutter.iml rename to packages/flutter_tools/ide_templates/intellij/packages/flutter/flutter.iml.copy.tmpl diff --git a/packages/flutter_driver/flutter_driver.iml b/packages/flutter_tools/ide_templates/intellij/packages/flutter_driver/flutter_driver.iml.copy.tmpl similarity index 100% rename from packages/flutter_driver/flutter_driver.iml rename to packages/flutter_tools/ide_templates/intellij/packages/flutter_driver/flutter_driver.iml.copy.tmpl diff --git a/packages/flutter_localizations/flutter_localizations.iml b/packages/flutter_tools/ide_templates/intellij/packages/flutter_localizations/flutter_localizations.iml.copy.tmpl similarity index 100% rename from packages/flutter_localizations/flutter_localizations.iml rename to packages/flutter_tools/ide_templates/intellij/packages/flutter_localizations/flutter_localizations.iml.copy.tmpl diff --git a/packages/flutter_test/flutter_test.iml b/packages/flutter_tools/ide_templates/intellij/packages/flutter_test/flutter_test.iml.copy.tmpl similarity index 100% rename from packages/flutter_test/flutter_test.iml rename to packages/flutter_tools/ide_templates/intellij/packages/flutter_test/flutter_test.iml.copy.tmpl diff --git a/packages/flutter_tools/flutter_tools.iml b/packages/flutter_tools/ide_templates/intellij/packages/flutter_tools/flutter_tools.iml.copy.tmpl similarity index 99% rename from packages/flutter_tools/flutter_tools.iml rename to packages/flutter_tools/ide_templates/intellij/packages/flutter_tools/flutter_tools.iml.copy.tmpl index 1b442a90ec8..a534a0a0ee6 100644 --- a/packages/flutter_tools/flutter_tools.iml +++ b/packages/flutter_tools/ide_templates/intellij/packages/flutter_tools/flutter_tools.iml.copy.tmpl @@ -22,7 +22,7 @@ - + \ No newline at end of file diff --git a/packages/flutter_tools/lib/executable.dart b/packages/flutter_tools/lib/executable.dart index 5e890400f3f..43ca13b5259 100644 --- a/packages/flutter_tools/lib/executable.dart +++ b/packages/flutter_tools/lib/executable.dart @@ -17,6 +17,7 @@ import 'src/commands/doctor.dart'; import 'src/commands/drive.dart'; import 'src/commands/format.dart'; import 'src/commands/fuchsia_reload.dart'; +import 'src/commands/ide_config.dart'; import 'src/commands/install.dart'; import 'src/commands/logs.dart'; import 'src/commands/packages.dart'; @@ -52,6 +53,7 @@ Future main(List args) async { new DriveCommand(), new FormatCommand(), new FuchsiaReloadCommand(), + new IdeConfigCommand(hidden: !verboseHelp), new InstallCommand(), new LogsCommand(), new PackagesCommand(), diff --git a/packages/flutter_tools/lib/src/commands/ide_config.dart b/packages/flutter_tools/lib/src/commands/ide_config.dart new file mode 100644 index 00000000000..1a7ee40f322 --- /dev/null +++ b/packages/flutter_tools/lib/src/commands/ide_config.dart @@ -0,0 +1,273 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'dart:async'; + +import '../base/common.dart'; +import '../base/file_system.dart'; +import '../cache.dart'; +import '../globals.dart'; +import '../runner/flutter_command.dart'; +import '../template.dart'; + +class IdeConfigCommand extends FlutterCommand { + IdeConfigCommand({this.hidden: false}) { + argParser.addFlag( + 'overwrite', + negatable: true, + defaultsTo: false, + help: 'When performing operations, overwrite existing files.', + ); + argParser.addFlag( + 'update-templates', + negatable: false, + help: 'Update the templates in the template directory from the current ' + 'configuration files. This is the opposite of what $name usually does. ' + 'Will search the flutter tree for .iml files and copy any missing ones ' + 'into the template directory. If --overwrite is also specified, it will ' + 'update any out-of-date files, and remove any deleted files from the ' + 'template directory.', + ); + } + + @override + final String name = 'ide-config'; + + @override + final String description = 'Configure the IDE for use in the Flutter tree.\n\n' + 'If run on a Flutter tree that is already configured for the IDE, this ' + 'command will add any new configurations, recreate any files that are ' + 'missing. If --overwrite is specified, will revert existing files to ' + 'the template versions, reset the module list, and return configuration ' + 'settings to the template versions.\n\n' + 'This command is intended for Flutter developers to help them set up the' + "Flutter tree for development in an IDE. It doesn't affect other projects.\n\n" + 'Currently, IntelliJ is the default (and only) IDE that may be configured.'; + + @override + final bool hidden; + + @override + String get invocation => '${runner.executableName} $name'; + + static const String _ideName = 'intellij'; + Directory get _templateDirectory { + return fs.directory(fs.path.join( + Cache.flutterRoot, + 'packages', + 'flutter_tools', + 'ide_templates', + _ideName, + )); + } + + Directory get _createTemplatesDirectory { + return fs.directory(fs.path.join( + Cache.flutterRoot, + 'packages', + 'flutter_tools', + 'templates', + )); + } + + Directory get _flutterRoot => fs.directory(fs.path.absolute(Cache.flutterRoot)); + + // Returns true if any entire path element is equal to dir. + bool _hasDirectoryInPath(FileSystemEntity entity, String dir) { + String path = entity.absolute.path; + while (path.isNotEmpty && fs.path.dirname(path) != path) { + if (fs.path.basename(path) == dir) { + return true; + } + path = fs.path.dirname(path); + } + return false; + } + + // Returns true if child is anywhere underneath parent. + bool _isChildDirectoryOf(FileSystemEntity parent, FileSystemEntity child) { + return child.absolute.path.startsWith(parent.absolute.path); + } + + // Checks the contents of the two files to see if they have changes. + bool _fileIsIdentical(File src, File dest) { + if (src.lengthSync() != dest.lengthSync()) { + return false; + } + + // Test byte by byte. We're assuming that these are small files. + final List srcBytes = src.readAsBytesSync(); + final List destBytes = dest.readAsBytesSync(); + for (int i = 0; i < srcBytes.length; ++i) { + if (srcBytes[i] != destBytes[i]) { + return false; + } + } + return true; + } + + // Discovers and syncs with existing configuration files in the Flutter tree. + void _handleTemplateUpdate() { + if (!_flutterRoot.existsSync()) { + return; + } + + final Set manifest = new Set(); + final List flutterFiles = _flutterRoot.listSync(recursive: true); + for (FileSystemEntity entity in flutterFiles) { + final String relativePath = fs.path.relative(entity.path, from: _flutterRoot.absolute.path); + if (entity is! File) { + continue; + } + + final File srcFile = entity; + + // Skip template files in both the ide_templates and templates + // directories to avoid copying onto themselves. + if (_isChildDirectoryOf(_templateDirectory, srcFile) || + _isChildDirectoryOf(_createTemplatesDirectory, srcFile)) { + continue; + } + + // Skip files we aren't interested in. + final RegExp _trackedIdeaFileRegExp = new RegExp( + r'(\.name|modules.xml|vcs.xml)$', + ); + final bool isATrackedIdeaFile = _hasDirectoryInPath(srcFile, '.idea') && + (_trackedIdeaFileRegExp.hasMatch(relativePath) || + _hasDirectoryInPath(srcFile, 'runConfigurations')); + final bool isAnImlOutsideIdea = !isATrackedIdeaFile && srcFile.path.endsWith('.iml'); + if (!isATrackedIdeaFile && !isAnImlOutsideIdea) { + continue; + } + + final File finalDestinationFile = fs.file(fs.path.absolute( + _templateDirectory.absolute.path, '$relativePath${Template.copyTemplateExtension}')); + final String relativeDestination = + fs.path.relative(finalDestinationFile.path, from: _flutterRoot.absolute.path); + if (finalDestinationFile.existsSync()) { + if (_fileIsIdentical(srcFile, finalDestinationFile)) { + printTrace(' $relativeDestination (identical)'); + manifest.add('$relativePath${Template.copyTemplateExtension}'); + continue; + } + if (argResults['overwrite']) { + finalDestinationFile.deleteSync(); + printStatus(' $relativeDestination (overwritten)'); + } else { + printTrace(' $relativeDestination (existing - skipped)'); + manifest.add('$relativePath${Template.copyTemplateExtension}'); + continue; + } + } else { + printStatus(' $relativeDestination (added)'); + } + final Directory finalDestinationDir = fs.directory(finalDestinationFile.dirname); + if (!finalDestinationDir.existsSync()) { + printTrace(" ${finalDestinationDir.path} doesn't exist, creating."); + finalDestinationDir.createSync(recursive: true); + } + srcFile.copySync(finalDestinationFile.path); + manifest.add('$relativePath${Template.copyTemplateExtension}'); + } + + // If we're not overwriting, then we're not going to remove missing items either. + if (!argResults['overwrite']) { + return; + } + + // Look for any files under the template dir that don't exist in the manifest and remove + // them. + final List templateFiles = _templateDirectory.listSync(recursive: true); + for (FileSystemEntity entity in templateFiles) { + if (entity is! File) { + continue; + } + final File templateFile = entity; + final String relativePath = fs.path.relative( + templateFile.absolute.path, + from: _templateDirectory.absolute.path, + ); + if (!manifest.contains(relativePath)) { + templateFile.deleteSync(); + final String relativeDestination = + fs.path.relative(templateFile.path, from: _flutterRoot.absolute.path); + printStatus(' $relativeDestination (removed)'); + } + // If the directory is now empty, then remove it, and do the same for its parent, + // until we escape to the template directory. + Directory parentDir = fs.directory(templateFile.dirname); + while (parentDir.listSync().isEmpty) { + parentDir.deleteSync(); + printTrace(' ${fs.path.relative(parentDir.absolute.path)} (empty directory - removed)'); + parentDir = fs.directory(parentDir.dirname); + if (fs.path.isWithin(_templateDirectory.absolute.path, parentDir.absolute.path)) { + break; + } + } + } + } + + @override + Future runCommand() async { + if (argResults.rest.isNotEmpty) { + throwToolExit('Currently, the only supported IDE is IntelliJ\n$usage', exitCode: 2); + } + + await Cache.instance.updateAll(); + + if (argResults['update-templates']) { + _handleTemplateUpdate(); + return; + } + + final String flutterRoot = fs.path.absolute(Cache.flutterRoot); + String dirPath = fs.path.normalize( + fs.directory(fs.path.absolute(Cache.flutterRoot)).absolute.path, + ); + // TODO(goderbauer): Work-around for: https://github.com/dart-lang/path/issues/24 + if (fs.path.basename(dirPath) == '.') { + dirPath = fs.path.dirname(dirPath); + } + + final String error = _validateFlutterDir(dirPath, flutterRoot: flutterRoot); + if (error != null) { + throwToolExit(error); + } + + printStatus('Updating IDE configuration for Flutter tree at $dirPath...'); + int generatedCount = 0; + generatedCount += _renderTemplate(_ideName, dirPath, {}); + + printStatus('Wrote $generatedCount files.'); + printStatus(''); + printStatus('Your IntelliJ configuration is now up to date. It is prudent to ' + 'restart IntelliJ, if running.'); + } + + int _renderTemplate(String templateName, String dirPath, Map context) { + final Template template = new Template(_templateDirectory, _templateDirectory); + return template.render( + fs.directory(dirPath), + context, + overwriteExisting: argResults['overwrite'], + ); + } +} + +/// Return null if the flutter root directory is a valid destination. Return a +/// validation message if we should disallow the directory. +String _validateFlutterDir(String dirPath, {String flutterRoot}) { + final FileSystemEntityType type = fs.typeSync(dirPath); + + if (type != FileSystemEntityType.NOT_FOUND) { + switch (type) { + case FileSystemEntityType.LINK: + // Do not overwrite links. + return "Invalid project root dir: '$dirPath' - refers to a link."; + } + } + + return null; +} diff --git a/packages/flutter_tools/lib/src/template.dart b/packages/flutter_tools/lib/src/template.dart index 5d96db7656d..a2fa206ddcd 100644 --- a/packages/flutter_tools/lib/src/template.dart +++ b/packages/flutter_tools/lib/src/template.dart @@ -8,10 +8,6 @@ import 'base/file_system.dart'; import 'cache.dart'; import 'globals.dart'; -const String _kTemplateExtension = '.tmpl'; -const String _kCopyTemplateExtension = '.copy.tmpl'; -final Pattern _kTemplateLanguageVariant = new RegExp(r'(\w+)-(\w+)\.tmpl.*'); - /// Expands templates in a directory to a destination. All files that must /// undergo template expansion should end with the '.tmpl' extension. All other /// files are ignored. In case the contents of entire directories must be copied @@ -45,7 +41,7 @@ class Template { final String relativePath = fs.path.relative(entity.path, from: baseDir.absolute.path); - if (relativePath.contains(_kTemplateExtension)) { + if (relativePath.contains(templateExtension)) { // If '.tmpl' appears anywhere within the path of this entity, it is // is a candidate for rendering. This catches cases where the folder // itself is a template. @@ -56,10 +52,14 @@ class Template { factory Template.fromName(String name) { // All named templates are placed in the 'templates' directory - final Directory templateDir = _templateDirectoryInPackage(name); + final Directory templateDir = templateDirectoryInPackage(name); return new Template(templateDir, templateDir); } + static const String templateExtension = '.tmpl'; + static const String copyTemplateExtension = '.copy.tmpl'; + final Pattern _kTemplateLanguageVariant = new RegExp(r'(\w+)-(\w+)\.tmpl.*'); + Map _templateFilePaths; int render( @@ -91,8 +91,8 @@ class Template { final String pathSeparator = fs.path.separator; String finalDestinationPath = fs.path .join(destinationDirPath, relativeDestinationPath) - .replaceAll(_kCopyTemplateExtension, '') - .replaceAll(_kTemplateExtension, ''); + .replaceAll(copyTemplateExtension, '') + .replaceAll(templateExtension, ''); if (androidIdentifier != null) { finalDestinationPath = finalDestinationPath @@ -116,7 +116,7 @@ class Template { if (finalDestinationFile.existsSync()) { if (overwriteExisting) { - finalDestinationFile.delete(recursive: true); + finalDestinationFile.deleteSync(recursive: true); printStatus(' $relativePathForLogging (overwritten)'); } else { // The file exists but we cannot overwrite it, move on. @@ -124,7 +124,7 @@ class Template { return; } } else { - printTrace(' $relativePathForLogging'); + printStatus(' $relativePathForLogging (created)'); } fileCount++; @@ -132,11 +132,11 @@ class Template { finalDestinationFile.createSync(recursive: true); final File sourceFile = fs.file(absoluteSourcePath); - // Step 2: If the absolute paths ends with a 'copy.tmpl', this file does + // Step 2: If the absolute paths ends with a '.copy.tmpl', this file does // not need mustache rendering but needs to be directly copied. - if (sourceFile.path.endsWith(_kCopyTemplateExtension)) { - finalDestinationFile.writeAsBytesSync(sourceFile.readAsBytesSync()); + if (sourceFile.path.endsWith(copyTemplateExtension)) { + sourceFile.copySync(finalDestinationFile.path); return; } @@ -144,7 +144,7 @@ class Template { // Step 3: If the absolute path ends with a '.tmpl', this file needs // rendering via mustache. - if (sourceFile.path.endsWith(_kTemplateExtension)) { + if (sourceFile.path.endsWith(templateExtension)) { final String templateContents = sourceFile.readAsStringSync(); final String renderedContents = new mustache.Template(templateContents).renderString(context); @@ -163,7 +163,7 @@ class Template { } } -Directory _templateDirectoryInPackage(String name) { +Directory templateDirectoryInPackage(String name) { final String templatesDir = fs.path.join(Cache.flutterRoot, 'packages', 'flutter_tools', 'templates'); return fs.directory(fs.path.join(templatesDir, name)); diff --git a/packages/flutter_tools/test/commands/ide_config_test.dart b/packages/flutter_tools/test/commands/ide_config_test.dart new file mode 100644 index 00000000000..4cc0a512996 --- /dev/null +++ b/packages/flutter_tools/test/commands/ide_config_test.dart @@ -0,0 +1,311 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'dart:async'; + +import 'package:args/command_runner.dart'; +import 'package:flutter_tools/src/base/file_system.dart'; +import 'package:flutter_tools/src/cache.dart'; +import 'package:flutter_tools/src/template.dart'; +import 'package:flutter_tools/src/commands/ide_config.dart'; +import 'package:test/test.dart'; + +import '../src/common.dart'; +import '../src/context.dart'; + +void main() { + group('ide_config', () { + Directory temp; + Directory templateDir; + Directory intellijDir; + Directory toolsDir; + + Map _getFilesystemContents([Directory root]) { + final String tempPath = temp.absolute.path; + final List paths = + (root ?? temp).listSync(recursive: true).map((FileSystemEntity entity) { + final String relativePath = fs.path.relative(entity.path, from: tempPath); + return relativePath; + }).toList(); + final Map contents = {}; + for (String path in paths) { + final String absPath = fs.path.join(tempPath, path); + if (fs.isDirectorySync(absPath)) { + contents[path] = 'dir'; + } else if (fs.isFileSync(absPath)) { + contents[path] = fs.file(absPath).readAsStringSync(); + } + } + return contents; + } + + Map _getManifest(Directory base, String marker, {bool isTemplate: false}) { + final String basePath = fs.path.relative(base.path, from: temp.absolute.path); + final String suffix = isTemplate ? Template.copyTemplateExtension : ''; + return { + fs.path.join(basePath, '.idea'): 'dir', + fs.path.join(basePath, '.idea', 'modules.xml$suffix'): 'modules $marker', + fs.path.join(basePath, '.idea', 'vcs.xml$suffix'): 'vcs $marker', + fs.path.join(basePath, '.idea', '.name$suffix'): + 'codeStyleSettings $marker', + fs.path.join(basePath, '.idea', 'runConfigurations'): 'dir', + fs.path.join(basePath, '.idea', 'runConfigurations', 'hello_world.xml$suffix'): + 'hello_world $marker', + fs.path.join(basePath, 'flutter.iml$suffix'): 'flutter $marker', + fs.path.join(basePath, 'packages', 'new', 'deep.iml$suffix'): 'deep $marker', + }; + } + + void _populateDir(Map manifest) { + for (String key in manifest.keys) { + if (manifest[key] == 'dir') { + temp.childDirectory(key)..createSync(recursive: true); + } + } + for (String key in manifest.keys) { + if (manifest[key] != 'dir') { + temp.childFile(key) + ..createSync(recursive: true) + ..writeAsStringSync(manifest[key]); + } + } + } + + bool _fileOrDirectoryExists(String path) { + final String absPath = fs.path.join(temp.absolute.path, path); + return fs.file(absPath).existsSync() || fs.directory(absPath).existsSync(); + } + + Future _updateIdeConfig({ + Directory dir, + List args = const [], + Map expectedContents = const {}, + List unexpectedPaths = const [], + }) async { + dir ??= temp; + final IdeConfigCommand command = new IdeConfigCommand(); + final CommandRunner runner = createTestCommandRunner(command); + final List finalArgs = ['--flutter-root=${temp.absolute.path}', 'ide-config']; + finalArgs.addAll(args); + await runner.run(finalArgs); + + for (String path in expectedContents.keys) { + final String absPath = fs.path.join(temp.absolute.path, path); + expect(_fileOrDirectoryExists(fs.path.join(dir.path, path)), true, + reason: "$path doesn't exist"); + if (fs.file(absPath).existsSync()) { + expect(fs.file(absPath).readAsStringSync(), equals(expectedContents[path]), + reason: "$path contents don't match"); + } + } + for (String path in unexpectedPaths) { + expect(_fileOrDirectoryExists(fs.path.join(dir.path, path)), false, reason: '$path exists'); + } + } + + setUpAll(() { + Cache.disableLocking(); + }); + + setUp(() { + temp = fs.systemTempDirectory.createTempSync('flutter_tools_'); + final Directory packagesDir = temp.childDirectory('packages')..createSync(recursive: true); + toolsDir = packagesDir.childDirectory('flutter_tools')..createSync(); + templateDir = toolsDir.childDirectory('ide_templates')..createSync(); + intellijDir = templateDir.childDirectory('intellij')..createSync(); + }); + + tearDown(() { + temp.deleteSync(recursive: true); + }); + + testUsingContext("doesn't touch existing files without --overwrite", () async { + final Map templateManifest = _getManifest( + intellijDir, + 'template', + isTemplate: true, + ); + final Map flutterManifest = _getManifest( + temp, + 'existing', + ); + _populateDir(templateManifest); + _populateDir(flutterManifest); + final Map expectedContents = _getFilesystemContents(); + return _updateIdeConfig( + expectedContents: expectedContents, + ); + }, timeout: const Timeout.factor(2.0)); + + testUsingContext('creates non-existent files', () async { + final Map templateManifest = _getManifest( + intellijDir, + 'template', + isTemplate: true, + ); + final Map flutterManifest = _getManifest( + temp, + 'template', + ); + _populateDir(templateManifest); + final Map expectedContents = templateManifest; + expectedContents.addAll(flutterManifest); + return _updateIdeConfig( + expectedContents: expectedContents, + ); + }, timeout: const Timeout.factor(2.0)); + + testUsingContext('overwrites existing files with --overwrite', () async { + final Map templateManifest = _getManifest( + intellijDir, + 'template', + isTemplate: true, + ); + final Map flutterManifest = _getManifest( + temp, + 'existing', + ); + _populateDir(templateManifest); + _populateDir(flutterManifest); + final Map overwrittenManifest = _getManifest( + temp, + 'template', + ); + final Map expectedContents = templateManifest; + expectedContents.addAll(overwrittenManifest); + return _updateIdeConfig( + args: ['--overwrite'], + expectedContents: expectedContents, + ); + }, timeout: const Timeout.factor(2.0)); + + testUsingContext('only adds new templates without --overwrite', () async { + final Map templateManifest = _getManifest( + intellijDir, + 'template', + isTemplate: true, + ); + final String flutterIml = fs.path.join( + 'packages', + 'flutter_tools', + 'ide_templates', + 'intellij', + 'flutter.iml${Template.copyTemplateExtension}', + ); + templateManifest.remove(flutterIml); + _populateDir(templateManifest); + templateManifest[flutterIml] = 'flutter existing'; + final Map flutterManifest = _getManifest( + temp, + 'existing', + ); + _populateDir(flutterManifest); + final Map expectedContents = flutterManifest; + expectedContents.addAll(templateManifest); + return _updateIdeConfig( + args: ['--update-templates'], + expectedContents: expectedContents, + ); + }, timeout: const Timeout.factor(2.0)); + + testUsingContext('update all templates with --overwrite', () async { + final Map templateManifest = _getManifest( + intellijDir, + 'template', + isTemplate: true, + ); + _populateDir(templateManifest); + final Map flutterManifest = _getManifest( + temp, + 'existing', + ); + _populateDir(flutterManifest); + final Map updatedTemplates = _getManifest( + intellijDir, + 'existing', + isTemplate: true, + ); + final Map expectedContents = flutterManifest; + expectedContents.addAll(updatedTemplates); + return _updateIdeConfig( + args: ['--update-templates', '--overwrite'], + expectedContents: expectedContents, + ); + }, timeout: const Timeout.factor(2.0)); + + testUsingContext('removes delted imls with --overwrite', () async { + final Map templateManifest = _getManifest( + intellijDir, + 'template', + isTemplate: true, + ); + _populateDir(templateManifest); + final Map flutterManifest = _getManifest( + temp, + 'existing', + ); + flutterManifest.remove('flutter.iml'); + _populateDir(flutterManifest); + final Map updatedTemplates = _getManifest( + intellijDir, + 'existing', + isTemplate: true, + ); + final String flutterIml = fs.path.join( + 'packages', + 'flutter_tools', + 'ide_templates', + 'intellij', + 'flutter.iml${Template.copyTemplateExtension}', + ); + updatedTemplates.remove(flutterIml); + final Map expectedContents = flutterManifest; + expectedContents.addAll(updatedTemplates); + return _updateIdeConfig( + args: ['--update-templates', '--overwrite'], + expectedContents: expectedContents, + ); + }, timeout: const Timeout.factor(2.0)); + + testUsingContext('removes delted imls with --overwrite, including empty parent dirs', () async { + final Map templateManifest = _getManifest( + intellijDir, + 'template', + isTemplate: true, + ); + _populateDir(templateManifest); + final Map flutterManifest = _getManifest( + temp, + 'existing', + ); + flutterManifest.remove(fs.path.join('packages', 'new', 'deep.iml')); + _populateDir(flutterManifest); + final Map updatedTemplates = _getManifest( + intellijDir, + 'existing', + isTemplate: true, + ); + String deepIml = fs.path.join( + 'packages', + 'flutter_tools', + 'ide_templates', + 'intellij'); + // Remove the all the dir entries too. + updatedTemplates.remove(deepIml); + deepIml = fs.path.join(deepIml, 'packages'); + updatedTemplates.remove(deepIml); + deepIml = fs.path.join(deepIml, 'new'); + updatedTemplates.remove(deepIml); + deepIml = fs.path.join(deepIml, 'deep.iml'); + updatedTemplates.remove(deepIml); + final Map expectedContents = flutterManifest; + expectedContents.addAll(updatedTemplates); + return _updateIdeConfig( + args: ['--update-templates', '--overwrite'], + expectedContents: expectedContents, + ); + }, timeout: const Timeout.factor(2.0)); + + }); +}