diff --git a/src/io/flutter/FlutterBundle.properties b/src/io/flutter/FlutterBundle.properties index f62bd13cc9..23d62c9243 100644 --- a/src/io/flutter/FlutterBundle.properties +++ b/src/io/flutter/FlutterBundle.properties @@ -89,3 +89,35 @@ devicelist.empty=No devices flutter.pop.frame.action.text=Drop Frame (Flutter) flutter.pop.frame.action.description=Pop the current frame off the stack + +flutter.module.create.settings.radios.type.label=Project type: +flutter.module.create.settings.radios.type.application=Application +flutter.module.create.settings.radios.type.plugin=Plugin +flutter.module.create.settings.radios.type.tip=Select a project type. +flutter.module.create.settings.radios.org.label=Organization: +flutter.module.create.settings.org.default_text=com.yourcompany +flutter.module.create.settings.org.tip=Enter a domain. +flutter.module.create.settings.description.label=Description: +flutter.module.create.settings.description.tip=Enter a project description which shows up in the pubsec.yaml. +flutter.module.create.settings.description.default_text=A new Flutter project. +flutter.module.create.settings.radios.android.label=Android language: +flutter.module.create.settings.radios.android.java=Java +flutter.module.create.settings.radios.android.kotlin=Kotlin +flutter.module.create.settings.radios.android.tip=Select an Android language. +flutter.module.create.settings.radios.ios.label=iOS language: +flutter.module.create.settings.radios.ios.object_c=Objective C +flutter.module.create.settings.radios.ios.swift=Swift +flutter.module.create.settings.radios.ios.tip=Select an iOS language. +flutter.module.create.settings.includedriver.label=Include driver test: +flutter.module.create.settings.includedriver.tip=Include generating a driver test. + +flutter.module.create.settings.help.label=Help: +flutter.module.create.settings.help.getting_started_html=Getting started with your first Flutter app. +flutter.module.create.settings.help.project_name.label=Project name: +flutter.module.create.settings.help.project_name.description=Enter the project name with all lower case letters. +flutter.module.create.settings.help.org.label=Organization: +flutter.module.create.settings.help.org.description=Enter the organization domain name in reverse domain notation. +flutter.module.create.settings.help.project_type.label=Project type: +flutter.module.create.settings.help.project_type.description.app=Select an "Application" when building for end users. +flutter.module.create.settings.help.project_type.description.plugin=Select a "Plugin" when building system hooks for developers. + diff --git a/src/io/flutter/module/FlutterModuleBuilder.java b/src/io/flutter/module/FlutterModuleBuilder.java index 4b0390000c..19aac081f5 100644 --- a/src/io/flutter/module/FlutterModuleBuilder.java +++ b/src/io/flutter/module/FlutterModuleBuilder.java @@ -9,6 +9,7 @@ import com.intellij.execution.process.ProcessListener; import com.intellij.ide.util.projectWizard.ModuleBuilder; import com.intellij.ide.util.projectWizard.ModuleWizardStep; +import com.intellij.ide.util.projectWizard.SettingsStep; import com.intellij.ide.util.projectWizard.WizardContext; import com.intellij.openapi.Disposable; import com.intellij.openapi.application.WriteAction; @@ -27,7 +28,10 @@ import io.flutter.FlutterBundle; import io.flutter.FlutterConstants; import io.flutter.FlutterUtils; +import io.flutter.module.settings.FlutterCreateAddtionalSettingsFields; +import io.flutter.module.settings.RadiosForm; import io.flutter.pub.PubRoot; +import io.flutter.sdk.FlutterCreateAdditionalSettings; import io.flutter.sdk.FlutterSdk; import io.flutter.sdk.FlutterSdkUtil; import io.flutter.utils.FlutterModuleUtils; @@ -35,6 +39,8 @@ import org.jetbrains.annotations.Nullable; import javax.swing.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; import java.io.IOException; import java.util.concurrent.atomic.AtomicReference; @@ -46,6 +52,7 @@ public class FlutterModuleBuilder extends ModuleBuilder { private static final String DART_GROUP_NAME = "Static Web"; // == WebModuleBuilder.GROUP_NAME private FlutterModuleWizardStep myStep; + private FlutterCreateAddtionalSettingsFields settingsFields; @Override public String getName() { @@ -101,7 +108,7 @@ public Module commitModule(@NotNull Project project, @Nullable ModifiableModuleM } final OutputListener listener = new OutputListener(); - final PubRoot root = runFlutterCreateWithProgress(baseDir, sdk, project, listener); + final PubRoot root = runFlutterCreateWithProgress(baseDir, sdk, project, listener, settingsFields.getAddtionalSettings()); if (root == null) { final String stderr = listener.getOutput().getStderr(); final String msg = stderr.isEmpty() ? "Flutter create command was unsuccessful" : stderr; @@ -172,11 +179,11 @@ public boolean validate(Project current, Project dest) { return myStep.getFlutterSdk() != null; } + /** + * @See: https://www.dartlang.org/tools/pub/pubspec#name + */ @Override public boolean validateModuleName(@NotNull String moduleName) throws ConfigurationException { - - // See: https://www.dartlang.org/tools/pub/pubspec#name - if (!FlutterUtils.isValidPackageName(moduleName)) { throw new ConfigurationException( "Invalid module name: '" + moduleName + "' - must be a valid Dart package name (lower_case_with_underscores)."); @@ -203,6 +210,19 @@ public boolean validateModuleName(@NotNull String moduleName) throws Configurati return super.validateModuleName(moduleName); } + @Nullable + @Override + public ModuleWizardStep modifySettingsStep(@NotNull SettingsStep settingsStep) { + final ModuleWizardStep wizard = super.modifySettingsStep(settingsStep); + + if (settingsFields == null) { + settingsFields = new FlutterCreateAddtionalSettingsFields(); + } + settingsFields.addSettingsFields(settingsStep); + + return wizard; + } + @Nullable @Override public ModuleWizardStep getCustomOptionsStep(final WizardContext context, final Disposable parentDisposable) { @@ -239,13 +259,14 @@ public ModuleType getModuleType() { private static PubRoot runFlutterCreateWithProgress(@NotNull VirtualFile baseDir, @NotNull FlutterSdk sdk, @NotNull Project project, - @Nullable ProcessListener processListener) { + @Nullable ProcessListener processListener, + @Nullable FlutterCreateAdditionalSettings additionalSettings) { final ProgressManager progress = ProgressManager.getInstance(); final AtomicReference result = new AtomicReference<>(null); progress.runProcessWithProgressSynchronously(() -> { progress.getProgressIndicator().setIndeterminate(true); - result.set(sdk.createFiles(baseDir, null, processListener)); + result.set(sdk.createFiles(baseDir, null, processListener, additionalSettings)); }, "Creating Flutter Project", false, project); return result.get(); diff --git a/src/io/flutter/module/FlutterSmallIDEGeneratorPeer.java b/src/io/flutter/module/FlutterSmallIDEGeneratorPeer.java index c9a849be98..d174f7f4a9 100644 --- a/src/io/flutter/module/FlutterSmallIDEGeneratorPeer.java +++ b/src/io/flutter/module/FlutterSmallIDEGeneratorPeer.java @@ -3,7 +3,6 @@ * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ - package io.flutter.module; import com.intellij.ide.util.projectWizard.SettingsStep; @@ -16,6 +15,8 @@ import com.intellij.ui.ComboboxWithBrowseButton; import com.intellij.ui.DocumentAdapter; import io.flutter.FlutterBundle; +import io.flutter.module.settings.FlutterCreateAddtionalSettingsFields; +import io.flutter.sdk.FlutterCreateAdditionalSettings; import io.flutter.sdk.FlutterSdkUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -28,8 +29,8 @@ // (and replaced with DirectoryProjectGenerator) public class FlutterSmallIDEGeneratorPeer implements WebProjectGenerator.GeneratorPeer { - private JPanel myMainPanel; private final ComboboxWithBrowseButton sdkPathComboWithBrowse; + private final FlutterCreateAddtionalSettingsFields settingsFields; public FlutterSmallIDEGeneratorPeer() { sdkPathComboWithBrowse = new ComboboxWithBrowseButton(new ComboBox<>()); @@ -40,17 +41,21 @@ public FlutterSmallIDEGeneratorPeer() { FlutterBundle.message("flutter.sdk.browse.path.label"), null, null, FileChooserDescriptorFactory.createSingleFolderDescriptor(), TextComponentAccessor.STRING_COMBOBOX_WHOLE_TEXT); + + settingsFields = new FlutterCreateAddtionalSettingsFields(); } @NotNull @Override public JComponent getComponent() { - return myMainPanel; + return null; } @Override public void buildUI(@NotNull SettingsStep settingsStep) { settingsStep.addSettingsField("Flutter SDK", sdkPathComboWithBrowse); + + settingsFields.addSettingsFields(settingsStep); } @NotNull @@ -94,6 +99,11 @@ protected void textChanged(DocumentEvent e) { } } + @NotNull + public FlutterCreateAdditionalSettings getAddtionalSettings() { + return settingsFields.getAddtionalSettings(); + } + @NotNull private String getSdkComboPath() { return FileUtilRt.toSystemIndependentName(sdkPathComboWithBrowse.getComboBox().getEditor().getItem().toString().trim()); diff --git a/src/io/flutter/module/FlutterSmallIDEProjectGenerator.java b/src/io/flutter/module/FlutterSmallIDEProjectGenerator.java index ddaccb22f7..1eb894095f 100644 --- a/src/io/flutter/module/FlutterSmallIDEProjectGenerator.java +++ b/src/io/flutter/module/FlutterSmallIDEProjectGenerator.java @@ -1,3 +1,8 @@ +/* + * Copyright 2016 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. + */ package io.flutter.module; import com.intellij.execution.OutputListener; @@ -24,6 +29,8 @@ // https://youtrack.jetbrains.com/issue/WEB-27537 public class FlutterSmallIDEProjectGenerator extends WebProjectTemplate { + private FlutterSmallIDEGeneratorPeer generatorPeer; + @NotNull @Override public String getName() { @@ -38,7 +45,8 @@ public String getDescription() { @NotNull @Override public GeneratorPeer createPeer() { - return new FlutterSmallIDEGeneratorPeer(); + generatorPeer = new FlutterSmallIDEGeneratorPeer(); + return generatorPeer; } @Override @@ -51,7 +59,6 @@ public void generateProject(@NotNull Project project, @NotNull VirtualFile baseDir, @NotNull String flutterSdkPath, @NotNull Module module) { - final FlutterSdk sdk = FlutterSdk.forPath(flutterSdkPath); if (sdk == null) { FlutterMessages.showError("Error creating project", flutterSdkPath + " is not a valid Flutter SDK"); @@ -60,7 +67,7 @@ public void generateProject(@NotNull Project project, // Run "flutter create". final OutputListener listener = new OutputListener(); - final PubRoot root = sdk.createFiles(baseDir, module, listener); + final PubRoot root = sdk.createFiles(baseDir, module, listener, generatorPeer.getAddtionalSettings()); if (root == null) { final String stderr = listener.getOutput().getStderr(); final String msg = stderr.isEmpty() ? "Flutter create command was unsuccessful" : stderr; diff --git a/src/io/flutter/module/settings/FlutterCreateAddtionalSettingsFields.java b/src/io/flutter/module/settings/FlutterCreateAddtionalSettingsFields.java new file mode 100644 index 0000000000..053bb9132c --- /dev/null +++ b/src/io/flutter/module/settings/FlutterCreateAddtionalSettingsFields.java @@ -0,0 +1,75 @@ +/* + * 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. + */ +package io.flutter.module.settings; + +import com.intellij.ide.util.projectWizard.SettingsStep; +import io.flutter.FlutterBundle; +import io.flutter.sdk.FlutterCreateAdditionalSettings; +import org.jetbrains.annotations.NotNull; + +import javax.swing.*; + +public class FlutterCreateAddtionalSettingsFields { + private final RadiosForm projectTypeRadios; + private final JTextField orgField; + private final JTextField descriptionField; + private final RadiosForm androidLanguageRadios; + private final RadiosForm iosLanguageRadios; + private final JCheckBox includeDriverTextField; + + public FlutterCreateAddtionalSettingsFields() { + projectTypeRadios = new RadiosForm(FlutterBundle.message("flutter.module.create.settings.radios.type.application"), + FlutterBundle.message("flutter.module.create.settings.radios.type.plugin")); + projectTypeRadios.setToolTipText(FlutterBundle.message("flutter.module.create.settings.radios.type.tip")); + + orgField = new JTextField(); + orgField.setText(FlutterBundle.message("flutter.module.create.settings.org.default_text")); + orgField.setToolTipText(FlutterBundle.message("flutter.module.create.settings.org.tip")); + + descriptionField = new JTextField(); + descriptionField.setToolTipText(FlutterBundle.message("flutter.module.create.settings.description.tip")); + descriptionField.setText(FlutterBundle.message("flutter.module.create.settings.description.default_text")); + + androidLanguageRadios = new RadiosForm(FlutterBundle.message("flutter.module.create.settings.radios.android.java"), + FlutterBundle.message("flutter.module.create.settings.radios.android.kotlin")); + androidLanguageRadios.setToolTipText(FlutterBundle.message("flutter.module.create.settings.radios.android.tip")); + + iosLanguageRadios = new RadiosForm(FlutterBundle.message("flutter.module.create.settings.radios.ios.object_c"), + FlutterBundle.message("flutter.module.create.settings.radios.ios.swift")); + iosLanguageRadios.setToolTipText(FlutterBundle.message("flutter.module.create.settings.radios.ios.tip")); + + includeDriverTextField = new JCheckBox(); + includeDriverTextField.setSelected(true); + includeDriverTextField.setToolTipText(FlutterBundle.message("flutter.module.create.settings.includedriver.tip")); + } + + public void addSettingsFields(@NotNull SettingsStep settingsStep) { + settingsStep.addSettingsField(FlutterBundle.message("flutter.module.create.settings.radios.type.label"), + projectTypeRadios.getComponent()); + settingsStep.addSettingsField(FlutterBundle.message("flutter.module.create.settings.radios.org.label"), orgField); + settingsStep.addSettingsField(FlutterBundle.message("flutter.module.create.settings.description.label"), descriptionField); + settingsStep.addSettingsField(FlutterBundle.message("flutter.module.create.settings.radios.android.label"), + androidLanguageRadios.getComponent()); + settingsStep.addSettingsField(FlutterBundle.message("flutter.module.create.settings.radios.ios.label"), + iosLanguageRadios.getComponent()); + settingsStep.addSettingsField(FlutterBundle.message("flutter.module.create.settings.includedriver.label"), includeDriverTextField); + + settingsStep.addSettingsComponent(new SettingsHelpForm().getComponent()); + } + + public FlutterCreateAdditionalSettings getAddtionalSettings() { + FlutterCreateAdditionalSettings addtionalSettings = new FlutterCreateAdditionalSettings.Builder() + .setDescription(!descriptionField.getText().trim().isEmpty() ? descriptionField.getText().trim() : null) + .setGeneratePlugin(projectTypeRadios.isRadio2Selected() ? true : null) + .setIncludeDriverTest(!includeDriverTextField.isSelected() ? null : true) + .setKotlin(androidLanguageRadios.isRadio2Selected() ? true : null) + .setOrg(!orgField.getText().trim().isEmpty() ? orgField.getText().trim() : null) + .setSwift(iosLanguageRadios.isRadio2Selected() ? true : null) + .build(); + + return addtionalSettings; + } +} diff --git a/src/io/flutter/module/settings/RadiosForm.form b/src/io/flutter/module/settings/RadiosForm.form new file mode 100644 index 0000000000..bc119aed83 --- /dev/null +++ b/src/io/flutter/module/settings/RadiosForm.form @@ -0,0 +1,41 @@ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/src/io/flutter/module/settings/RadiosForm.java b/src/io/flutter/module/settings/RadiosForm.java new file mode 100644 index 0000000000..81f9592a36 --- /dev/null +++ b/src/io/flutter/module/settings/RadiosForm.java @@ -0,0 +1,43 @@ +/* + * 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. + */ +package io.flutter.module.settings; + +import org.jetbrains.annotations.NotNull; + +import javax.swing.*; + +/** + * A panel with two radios in a group. + */ +public class RadiosForm { + private JRadioButton radio1; + private JRadioButton radio2; + private JPanel radiosPanel; + + public RadiosForm(String label1, String label2) { + radio1.setText(label1); + radio1.setSelected(true); + + radio2.setText(label2); + + final ButtonGroup radioGroup = new ButtonGroup(); + radioGroup.add(radio1); + radioGroup.add(radio2); + } + + @NotNull + public JComponent getComponent() { + return radiosPanel; + } + + public void setToolTipText(String text) { + radiosPanel.setToolTipText(text); + } + + public boolean isRadio2Selected() { + return radio2.isSelected(); + } +} diff --git a/src/io/flutter/module/settings/SettingsHelpForm.form b/src/io/flutter/module/settings/SettingsHelpForm.form new file mode 100644 index 0000000000..e220ace248 --- /dev/null +++ b/src/io/flutter/module/settings/SettingsHelpForm.form @@ -0,0 +1,138 @@ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/io/flutter/module/settings/SettingsHelpForm.java b/src/io/flutter/module/settings/SettingsHelpForm.java new file mode 100644 index 0000000000..12046b2513 --- /dev/null +++ b/src/io/flutter/module/settings/SettingsHelpForm.java @@ -0,0 +1,80 @@ +/* + * 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. + */ +package io.flutter.module.settings; + +import io.flutter.FlutterBundle; +import org.jetbrains.annotations.NotNull; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; + +/** + * The settings panel that list helps. + */ +public class SettingsHelpForm { + private JPanel mainPanel; + private JPanel helpPanel; + + private JLabel helpLabel; + + private JLabel projectNameLabel; + private JLabel projectNameDescription; + + private JLabel projectTypeLabel; + private JLabel projectTypeDescriptionForApp; + private JLabel projectTypeDescriptionForPlugin; + + private JLabel orgLabel; + private JLabel orgDescription; + + private JTextPane gettingStartedUrl; + + public SettingsHelpForm() { + projectNameLabel.setText(FlutterBundle.message("flutter.module.create.settings.help.label")); + + projectNameLabel.setText(FlutterBundle.message("flutter.module.create.settings.help.project_name.label")); + projectNameDescription.setText(FlutterBundle.message("flutter.module.create.settings.help.project_name.description")); + + projectTypeLabel.setText(FlutterBundle.message("flutter.module.create.settings.help.project_type.label")); + projectTypeDescriptionForApp.setText(FlutterBundle.message("flutter.module.create.settings.help.project_type.description.app")); + projectTypeDescriptionForPlugin.setText(FlutterBundle.message("flutter.module.create.settings.help.project_type.description.plugin")); + + orgLabel.setText(FlutterBundle.message("flutter.module.create.settings.help.org.label")); + orgDescription.setText(FlutterBundle.message("flutter.module.create.settings.help.org.description")); + + gettingStartedUrl.setText(FlutterBundle.message("flutter.module.create.settings.help.getting_started_html")); + gettingStartedUrl.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); + gettingStartedUrl.addMouseListener(new MouseAdapter() { + public void mouseClicked(MouseEvent e) { + if (e.getClickCount() > 0) { + if (Desktop.isDesktopSupported()) { + Desktop desktop = Desktop.getDesktop(); + try { + URI uri = new URI("https://flutter.io/getting-started/"); + desktop.browse(uri); + } catch (IOException ex) { + // do nothing + } catch (URISyntaxException ex) { + //do nothing + } + } else { + //do nothing + } + } + } + }); + } + + @NotNull + public JComponent getComponent() { + return mainPanel; + } +} diff --git a/src/io/flutter/run/SdkFields.java b/src/io/flutter/run/SdkFields.java index 9d84ac3e85..7f4cec470c 100644 --- a/src/io/flutter/run/SdkFields.java +++ b/src/io/flutter/run/SdkFields.java @@ -99,7 +99,6 @@ void checkRunnable(@NotNull Project project) throws RuntimeConfigurationError { public GeneralCommandLine createFlutterSdkRunCommand(@NotNull Project project, @Nullable FlutterDevice device, @NotNull RunMode mode) throws ExecutionException { - final MainFile main = MainFile.verify(filePath, project).get(); final FlutterSdk flutterSdk = FlutterSdk.getFlutterSdk(project); diff --git a/src/io/flutter/sdk/FlutterCreateAdditionalSettings.java b/src/io/flutter/sdk/FlutterCreateAdditionalSettings.java new file mode 100644 index 0000000000..511eb4caca --- /dev/null +++ b/src/io/flutter/sdk/FlutterCreateAdditionalSettings.java @@ -0,0 +1,127 @@ +/* + * 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. + */ +package io.flutter.sdk; + +import com.intellij.openapi.util.text.StringUtil; +import org.apache.commons.lang3.BooleanUtils; +import org.jetbrains.annotations.Nullable; +import java.util.ArrayList; +import java.util.List; + +public class FlutterCreateAdditionalSettings { + public static class Builder { + @Nullable + private Boolean includeDriverTest; + @Nullable + private Boolean generatePlugin; + @Nullable + private String description; + @Nullable + private String org; + @Nullable + private Boolean swift; + @Nullable + private Boolean kotlin; + + public Builder() { + } + + public Builder setIncludeDriverTest(@Nullable Boolean includeDriverTest) { + this.includeDriverTest = includeDriverTest; + return this; + } + + public Builder setGeneratePlugin(@Nullable Boolean generatePlugin) { + this.generatePlugin = generatePlugin; + return this; + } + + public Builder setDescription(@Nullable String description) { + this.description = description; + return this; + } + + public Builder setOrg(@Nullable String org) { + this.org = org; + return this; + } + + public Builder setSwift(@Nullable Boolean swift) { + this.swift = swift; + return this; + } + + public Builder setKotlin(@Nullable Boolean kotlin) { + this.kotlin = kotlin; + return this; + } + + public FlutterCreateAdditionalSettings build() { + return new FlutterCreateAdditionalSettings(includeDriverTest, generatePlugin, description, org, swift, kotlin); + } + } + + @Nullable + private Boolean includeDriverTest; + @Nullable + private Boolean generatePlugin; + @Nullable + private String description; + @Nullable + private String org; + @Nullable + private Boolean swift; + @Nullable + private Boolean kotlin; + + private FlutterCreateAdditionalSettings(Boolean includeDriverTest, + Boolean generatePlugin, + String description, + String org, + Boolean swift, + Boolean kotlin) { + this.includeDriverTest = includeDriverTest; + this.generatePlugin = generatePlugin; + this.description = description; + this.org = org; + this.swift = swift; + this.kotlin = kotlin; + } + + public List getArgs() { + final List args = new ArrayList<>(); + + if (BooleanUtils.isTrue(includeDriverTest)) { + args.add("--with-driver-test"); + } + + if (BooleanUtils.isTrue(generatePlugin)) { + args.add("--plugin"); + } + + if (!StringUtil.isEmptyOrSpaces(description) ) { + args.add("--description"); + args.add(description); + } + + if (!StringUtil.isEmptyOrSpaces(org)) { + args.add("--org"); + args.add(org); + } + + if (BooleanUtils.isTrue(swift)) { + args.add("--ios-language"); + args.add("swift"); + } + + if (BooleanUtils.isTrue(kotlin)) { + args.add("--android-language"); + args.add("kotlin"); + } + + return args; + } +} diff --git a/src/io/flutter/sdk/FlutterSdk.java b/src/io/flutter/sdk/FlutterSdk.java index 8e26adb377..f5cf1b5e78 100644 --- a/src/io/flutter/sdk/FlutterSdk.java +++ b/src/io/flutter/sdk/FlutterSdk.java @@ -120,8 +120,18 @@ public FlutterCommand flutterDoctor() { return new FlutterCommand(this, getHome(), FlutterCommand.Type.DOCTOR); } - public FlutterCommand flutterCreate(@NotNull VirtualFile appDir) { - return new FlutterCommand(this, appDir.getParent(), FlutterCommand.Type.CREATE, appDir.getName()); + public FlutterCommand flutterCreate(@NotNull VirtualFile appDir, @Nullable FlutterCreateAdditionalSettings additionalSettings) { + final List args = new ArrayList<>(); + if (additionalSettings != null) { + args.addAll(additionalSettings.getArgs()); + } + + // keep as the last argument + args.add(appDir.getName()); + + final String[] vargs = args.stream().toArray(String[]::new); + + return new FlutterCommand(this, appDir.getParent(), FlutterCommand.Type.CREATE, vargs); } public FlutterCommand flutterPackagesGet(@NotNull PubRoot root) { @@ -240,14 +250,13 @@ public boolean sync(@NotNull Project project) { * Returns the PubRoot if successful. */ @Nullable - public PubRoot createFiles(@NotNull VirtualFile baseDir, @Nullable Module module, @Nullable ProcessListener listener) { - + public PubRoot createFiles(@NotNull VirtualFile baseDir, @Nullable Module module, @Nullable ProcessListener listener, + @Nullable FlutterCreateAdditionalSettings additionalSettings) { final Process process; if (module == null) { - process = flutterCreate(baseDir).start(null, listener); - } - else { - process = flutterCreate(baseDir).startInModuleConsole(module, null, listener); + process = flutterCreate(baseDir, additionalSettings).start(null, listener); + } else { + process = flutterCreate(baseDir, additionalSettings).startInModuleConsole(module, null, listener); } if (process == null) { return null; diff --git a/testSrc/unit/io/flutter/sdk/FlutterCreateAddtionalSettingsTest.java b/testSrc/unit/io/flutter/sdk/FlutterCreateAddtionalSettingsTest.java new file mode 100644 index 0000000000..8fdb2e2319 --- /dev/null +++ b/testSrc/unit/io/flutter/sdk/FlutterCreateAddtionalSettingsTest.java @@ -0,0 +1,145 @@ +/* + * 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. + */ +package io.flutter.sdk; + +import org.junit.Test; + +import java.util.List; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertEquals; + +public class FlutterCreateAddtionalSettingsTest { + @Test + public void includeDriverPropertyTest() { + final FlutterCreateAdditionalSettings addtionalSettings1 = + new FlutterCreateAdditionalSettings.Builder().setIncludeDriverTest(true).build(); + final FlutterCreateAdditionalSettings addtionalSettings2 = + new FlutterCreateAdditionalSettings.Builder().setIncludeDriverTest(false).build(); + final FlutterCreateAdditionalSettings addtionalSettings3 = + new FlutterCreateAdditionalSettings.Builder().setIncludeDriverTest(null).build(); + + final List args1 = addtionalSettings1.getArgs(); + final List args2 = addtionalSettings2.getArgs(); + final List args3 = addtionalSettings3.getArgs(); + + assertEquals(1, args1.size()); + assertEquals("--with-driver-test", args1.get(0)); + + assertEquals(0, args2.size()); + assertEquals(0, args3.size()); + } + + @Test + public void generatePluginPropertyTest() { + final FlutterCreateAdditionalSettings addtionalSettings1 = + new FlutterCreateAdditionalSettings.Builder().setGeneratePlugin(true).build(); + final FlutterCreateAdditionalSettings addtionalSettings2 = + new FlutterCreateAdditionalSettings.Builder().setGeneratePlugin(false).build(); + final FlutterCreateAdditionalSettings addtionalSettings3 = + new FlutterCreateAdditionalSettings.Builder().setGeneratePlugin(null).build(); + + final List args1 = addtionalSettings1.getArgs(); + final List args2 = addtionalSettings2.getArgs(); + final List args3 = addtionalSettings3.getArgs(); + + assertEquals(1, args1.size()); + assertEquals("--plugin", args1.get(0)); + + assertEquals(0, args2.size()); + assertEquals(0, args3.size()); + } + + @Test + public void descriptionPropertyTest() { + final String d = "My description."; + final FlutterCreateAdditionalSettings addtionalSettings1 = new FlutterCreateAdditionalSettings.Builder().setDescription(d).build(); + final FlutterCreateAdditionalSettings addtionalSettings2 = new FlutterCreateAdditionalSettings.Builder().setDescription(" ").build(); + final FlutterCreateAdditionalSettings addtionalSettings3 = new FlutterCreateAdditionalSettings.Builder().setDescription(null).build(); + + final List args1 = addtionalSettings1.getArgs(); + final List args2 = addtionalSettings2.getArgs(); + final List args3 = addtionalSettings3.getArgs(); + + assertEquals(2, args1.size()); + assertEquals("--description", args1.get(0)); + assertEquals(d, args1.get(1)); + + assertEquals(0, args2.size()); + assertEquals(0, args3.size()); + } + + @Test + public void orgPropertyTest() { + final String d = "tld.domain"; + final FlutterCreateAdditionalSettings addtionalSettings1 = new FlutterCreateAdditionalSettings.Builder().setOrg(d).build(); + final FlutterCreateAdditionalSettings addtionalSettings2 = new FlutterCreateAdditionalSettings.Builder().setOrg(" ").build(); + final FlutterCreateAdditionalSettings addtionalSettings3 = new FlutterCreateAdditionalSettings.Builder().setOrg(null).build(); + + final List args1 = addtionalSettings1.getArgs(); + final List args2 = addtionalSettings2.getArgs(); + final List args3 = addtionalSettings3.getArgs(); + + assertEquals(2, args1.size()); + assertEquals("--org", args1.get(0)); + assertEquals(d, args1.get(1)); + + assertEquals(0, args2.size()); + assertEquals(0, args3.size()); + } + + @Test + public void iosPropertyTest() { + final FlutterCreateAdditionalSettings addtionalSettings1 = new FlutterCreateAdditionalSettings.Builder().setSwift(true).build(); + final FlutterCreateAdditionalSettings addtionalSettings2 = new FlutterCreateAdditionalSettings.Builder().setSwift(false).build(); + final FlutterCreateAdditionalSettings addtionalSettings3 = new FlutterCreateAdditionalSettings.Builder().setSwift(null).build(); + + final List args1 = addtionalSettings1.getArgs(); + final List args2 = addtionalSettings2.getArgs(); + final List args3 = addtionalSettings3.getArgs(); + + assertEquals(2, args1.size()); + assertEquals("--ios-language", args1.get(0)); + + assertEquals(0, args2.size()); + assertEquals(0, args3.size()); + } + + @Test + public void kotlinPropertyTest() { + final FlutterCreateAdditionalSettings addtionalSettings1 = new FlutterCreateAdditionalSettings.Builder().setKotlin(true).build(); + final FlutterCreateAdditionalSettings addtionalSettings2 = new FlutterCreateAdditionalSettings.Builder().setKotlin(false).build(); + final FlutterCreateAdditionalSettings addtionalSettings3 = new FlutterCreateAdditionalSettings.Builder().setKotlin(null).build(); + + final List args1 = addtionalSettings1.getArgs(); + final List args2 = addtionalSettings2.getArgs(); + final List args3 = addtionalSettings3.getArgs(); + + assertEquals(2, args1.size()); + assertEquals("--android-language", args1.get(0)); + + assertEquals(0, args2.size()); + assertEquals(0, args3.size()); + } + + @Test + public void testMultipleProperties() { + final FlutterCreateAdditionalSettings addtionalSettings = new FlutterCreateAdditionalSettings.Builder() + .setOrg("tld.domain") + .setGeneratePlugin(true) + .setDescription("a b c") + .setSwift(true) + .setKotlin(true) + .build(); + + final List args = addtionalSettings.getArgs(); + + final String line = String.join(" ", args); + + assertEquals(9, args.size()); + assertEquals("--plugin --description a b c --org tld.domain --ios-language swift --android-language kotlin", line); + } +}