From 793ad0d11a1d2f6fdd2cb10656c27ca77b347dd9 Mon Sep 17 00:00:00 2001 From: Eugene Kudelevsky Date: Thu, 2 Feb 2012 15:59:36 +0400 Subject: [PATCH] IDEA-80640 setting if include test code and resources into apk --- .../messages/AndroidBundle.properties | 3 +- .../android/compiler/AndroidDexCompiler.java | 2 + .../android/compiler/AndroidIdlCompiler.java | 2 +- .../compiler/AndroidPackagingCompiler.java | 17 ++++--- .../facet/AndroidFacetConfiguration.java | 2 + .../android/facet/AndroidFacetEditorTab.form | 20 ++++++--- .../android/facet/AndroidFacetEditorTab.java | 7 +++ .../android/facet/AndroidRootUtil.java | 10 +---- .../newProject/AndroidModuleBuilder.java | 1 + .../android/run/AndroidRunConfiguration.java | 7 ++- .../run/AndroidRunConfigurationBase.java | 2 +- .../android/run/AndroidRunningState.java | 5 +-- .../testing/AndroidTestRunConfiguration.java | 44 ++++++++++++++++++- 13 files changed, 89 insertions(+), 33 deletions(-) diff --git a/plugins/android/resources/messages/AndroidBundle.properties b/plugins/android/resources/messages/AndroidBundle.properties index 4ed608cd7172..b32689f9ade4 100644 --- a/plugins/android/resources/messages/AndroidBundle.properties +++ b/plugins/android/resources/messages/AndroidBundle.properties @@ -322,4 +322,5 @@ android.lint.inspections.set.to.wrap.content=Replace size attribute with 'wrap_c android.lint.inspections.add.permission.attribute=Add 'permission' attribute android.lint.inspections.add.input.type.attribute=Add 'inputType' attribute android.lint.inspections.remove.unnecessary.view=Remove unnecessary view -android.lint.inspections.replace.with.suggested.characters=Replace with suggested characters \ No newline at end of file +android.lint.inspections.replace.with.suggested.characters=Replace with suggested characters +android.facet.settings.pack.test.sources=Include test code and resources into APK \ No newline at end of file diff --git a/plugins/android/src/org/jetbrains/android/compiler/AndroidDexCompiler.java b/plugins/android/src/org/jetbrains/android/compiler/AndroidDexCompiler.java index 21e042f5c5ba..1be64ac6c0d4 100644 --- a/plugins/android/src/org/jetbrains/android/compiler/AndroidDexCompiler.java +++ b/plugins/android/src/org/jetbrains/android/compiler/AndroidDexCompiler.java @@ -164,10 +164,12 @@ public class AndroidDexCompiler implements ClassPostProcessingCompiler { } } + if (facet.getConfiguration().PACK_TEST_CODE) { VirtualFile outputDirForTests = extension.getCompilerOutputPathForTests(); if (outputDirForTests != null) { addModuleOutputDir(files, outputDirForTests); + } } } diff --git a/plugins/android/src/org/jetbrains/android/compiler/AndroidIdlCompiler.java b/plugins/android/src/org/jetbrains/android/compiler/AndroidIdlCompiler.java index 594e6a40429c..dddc60b173d4 100644 --- a/plugins/android/src/org/jetbrains/android/compiler/AndroidIdlCompiler.java +++ b/plugins/android/src/org/jetbrains/android/compiler/AndroidIdlCompiler.java @@ -226,7 +226,7 @@ public class AndroidIdlCompiler implements SourceGeneratingCompiler { } try { - VirtualFile[] sourceRoots = AndroidPackagingCompiler.getSourceRootsForModuleAndDependencies(idlItem.myModule); + VirtualFile[] sourceRoots = AndroidPackagingCompiler.getSourceRootsForModuleAndDependencies(idlItem.myModule, false); final String[] sourceRootPaths = AndroidCompileUtil.toOsPaths(sourceRoots); final Map> messages = AndroidIdl diff --git a/plugins/android/src/org/jetbrains/android/compiler/AndroidPackagingCompiler.java b/plugins/android/src/org/jetbrains/android/compiler/AndroidPackagingCompiler.java index 9fa3535efe81..d39188ed8012 100644 --- a/plugins/android/src/org/jetbrains/android/compiler/AndroidPackagingCompiler.java +++ b/plugins/android/src/org/jetbrains/android/compiler/AndroidPackagingCompiler.java @@ -65,11 +65,14 @@ public class AndroidPackagingCompiler implements PackagingCompiler { return VirtualFile.EMPTY_ARRAY; } - private static void fillSourceRoots(@NotNull Module module, @NotNull Set visited, @NotNull Set result) { + private static void fillSourceRoots(@NotNull Module module, + @NotNull Set visited, + @NotNull Set result, + boolean includingTests) { visited.add(module); VirtualFile resDir = AndroidRootUtil.getResourceDir(module); ModuleRootManager manager = ModuleRootManager.getInstance(module); - for (VirtualFile sourceRoot : manager.getSourceRoots()) { + for (VirtualFile sourceRoot : manager.getSourceRoots(includingTests)) { if (resDir != sourceRoot) { result.add(sourceRoot); } @@ -78,10 +81,10 @@ public class AndroidPackagingCompiler implements PackagingCompiler { if (entry instanceof ModuleOrderEntry) { ModuleOrderEntry moduleOrderEntry = (ModuleOrderEntry)entry; DependencyScope scope = moduleOrderEntry.getScope(); - if (scope == DependencyScope.COMPILE || scope == DependencyScope.TEST) { + if (scope == DependencyScope.COMPILE) { Module depModule = moduleOrderEntry.getModule(); if (depModule != null && !visited.contains(depModule)) { - fillSourceRoots(depModule, visited, result); + fillSourceRoots(depModule, visited, result, false); } } } @@ -89,9 +92,9 @@ public class AndroidPackagingCompiler implements PackagingCompiler { } @NotNull - public static VirtualFile[] getSourceRootsForModuleAndDependencies(@NotNull Module module) { + public static VirtualFile[] getSourceRootsForModuleAndDependencies(@NotNull Module module, boolean includingTests) { Set result = new HashSet(); - fillSourceRoots(module, new HashSet(), result); + fillSourceRoots(module, new HashSet(), result, includingTests); return VfsUtil.toVirtualFileArray(result); } @@ -102,7 +105,7 @@ public class AndroidPackagingCompiler implements PackagingCompiler { AndroidFacet facet = AndroidFacet.getInstance(module); if (facet != null && !facet.getConfiguration().LIBRARY_PROJECT) { VirtualFile manifestFile = AndroidRootUtil.getManifestFileForCompiler(facet); - VirtualFile[] sourceRoots = getSourceRootsForModuleAndDependencies(module); + VirtualFile[] sourceRoots = getSourceRootsForModuleAndDependencies(module, facet.getConfiguration().PACK_TEST_CODE); if (manifestFile != null) { AndroidFacetConfiguration configuration = facet.getConfiguration(); VirtualFile outputDir = AndroidDexCompiler.getOutputDirectoryForDex(module); diff --git a/plugins/android/src/org/jetbrains/android/facet/AndroidFacetConfiguration.java b/plugins/android/src/org/jetbrains/android/facet/AndroidFacetConfiguration.java index 1e400ddc4cba..510911d99ac0 100644 --- a/plugins/android/src/org/jetbrains/android/facet/AndroidFacetConfiguration.java +++ b/plugins/android/src/org/jetbrains/android/facet/AndroidFacetConfiguration.java @@ -81,6 +81,8 @@ public class AndroidFacetConfiguration implements FacetConfiguration { public String CUSTOM_DEBUG_KEYSTORE_PATH = ""; + public boolean PACK_TEST_CODE = false; + private AndroidFacet myFacet = null; public void init(@NotNull Module module, @NotNull VirtualFile contentRoot) { diff --git a/plugins/android/src/org/jetbrains/android/facet/AndroidFacetEditorTab.form b/plugins/android/src/org/jetbrains/android/facet/AndroidFacetEditorTab.form index 73c9b53d0f2d..c588020758ea 100644 --- a/plugins/android/src/org/jetbrains/android/facet/AndroidFacetEditorTab.form +++ b/plugins/android/src/org/jetbrains/android/facet/AndroidFacetEditorTab.form @@ -115,8 +115,8 @@ - - + + @@ -124,7 +124,7 @@ - + @@ -198,11 +198,11 @@ - + - + @@ -237,7 +237,7 @@ - + @@ -297,6 +297,14 @@ + + + + + + + + diff --git a/plugins/android/src/org/jetbrains/android/facet/AndroidFacetEditorTab.java b/plugins/android/src/org/jetbrains/android/facet/AndroidFacetEditorTab.java index dbbdfa6fc0e2..658462b9787c 100644 --- a/plugins/android/src/org/jetbrains/android/facet/AndroidFacetEditorTab.java +++ b/plugins/android/src/org/jetbrains/android/facet/AndroidFacetEditorTab.java @@ -93,6 +93,7 @@ public class AndroidFacetEditorTab extends FacetEditorTab { private JLabel myRGenPathLabel; private TextFieldWithBrowseButton myCustomDebugKeystoreField; private JBLabel myCustomKeystoreLabel; + private JCheckBox myIncludeTestCodeAndCheckBox; public AndroidFacetEditorTab(FacetEditorContext context, AndroidFacetConfiguration androidFacetConfiguration) { final Project project = context.getProject(); @@ -282,6 +283,9 @@ public class AndroidFacetEditorTab extends FacetEditorTab { if (!myConfiguration.CUSTOM_DEBUG_KEYSTORE_PATH.equals(getSelectedCustomKeystorePath())) { return true; } + if (myConfiguration.PACK_TEST_CODE != myIncludeTestCodeAndCheckBox.isSelected()) { + return true; + } return false; } @@ -390,6 +394,8 @@ public class AndroidFacetEditorTab extends FacetEditorTab { myConfiguration.RUN_PROCESS_RESOURCES_MAVEN_TASK = myRunProcessResourcesRadio.isSelected(); myConfiguration.GENERATE_UNSIGNED_APK = myGenerateUnsignedApk.isSelected(); + + myConfiguration.PACK_TEST_CODE = myIncludeTestCodeAndCheckBox.isSelected(); boolean useCustomAptSrc = myUseCustomSourceDirectoryRadio.isSelected(); @@ -513,6 +519,7 @@ public class AndroidFacetEditorTab extends FacetEditorTab { myCompileResourcesByIdeRadio.setSelected(!myConfiguration.RUN_PROCESS_RESOURCES_MAVEN_TASK); myGenerateUnsignedApk.setSelected(myConfiguration.GENERATE_UNSIGNED_APK); + myIncludeTestCodeAndCheckBox.setSelected(myConfiguration.PACK_TEST_CODE); updateAptPanel(); diff --git a/plugins/android/src/org/jetbrains/android/facet/AndroidRootUtil.java b/plugins/android/src/org/jetbrains/android/facet/AndroidRootUtil.java index 9633ed4c480a..0b7a0410bb6d 100644 --- a/plugins/android/src/org/jetbrains/android/facet/AndroidRootUtil.java +++ b/plugins/android/src/org/jetbrains/android/facet/AndroidRootUtil.java @@ -257,14 +257,8 @@ public class AndroidRootUtil { } } // do not support android-app->android-app compile dependencies - else if (facet == null) { - if (!outputDirs.contains(classDir) && classDir != null && classDir.exists()) { - outputDirs.add(classDir); - } - VirtualFile classDirForTests = extension.getCompilerOutputPathForTests(); - if (!outputDirs.contains(classDirForTests) && classDirForTests != null && classDirForTests.exists()) { - outputDirs.add(classDirForTests); - } + else if (facet == null && !outputDirs.contains(classDir) && classDir != null && classDir.exists()) { + outputDirs.add(classDir); } } fillExternalLibrariesAndModules(depModule, outputDirs, libraries, visited, !libraryProject || exportedLibrariesOnly); diff --git a/plugins/android/src/org/jetbrains/android/newProject/AndroidModuleBuilder.java b/plugins/android/src/org/jetbrains/android/newProject/AndroidModuleBuilder.java index 35a6e6e89c82..672a47f4bb79 100644 --- a/plugins/android/src/org/jetbrains/android/newProject/AndroidModuleBuilder.java +++ b/plugins/android/src/org/jetbrains/android/newProject/AndroidModuleBuilder.java @@ -128,6 +128,7 @@ public class AndroidModuleBuilder extends JavaModuleBuilder { if (myProjectType == ProjectType.TEST) { assert myTestedModule != null; + facet.getConfiguration().PACK_TEST_CODE = true; ModuleOrderEntry entry = rootModel.addModuleOrderEntry(myTestedModule); entry.setScope(DependencyScope.PROVIDED); } diff --git a/plugins/android/src/org/jetbrains/android/run/AndroidRunConfiguration.java b/plugins/android/src/org/jetbrains/android/run/AndroidRunConfiguration.java index 436dbf46988b..ce0a5c8cf1c6 100644 --- a/plugins/android/src/org/jetbrains/android/run/AndroidRunConfiguration.java +++ b/plugins/android/src/org/jetbrains/android/run/AndroidRunConfiguration.java @@ -92,11 +92,10 @@ public class AndroidRunConfiguration extends AndroidRunConfigurationBase impleme } @Override - public RunProfileState getState(@NotNull Executor executor, @NotNull ExecutionEnvironment env) throws ExecutionException { - RunProfileState state = super.getState(executor, env); + public AndroidRunningState getState(@NotNull Executor executor, @NotNull ExecutionEnvironment env) throws ExecutionException { + AndroidRunningState state = super.getState(executor, env); if (state != null) { - assert state instanceof AndroidRunningState; - ((AndroidRunningState)state).setDeploy(DEPLOY); + state.setDeploy(DEPLOY); } return state; } diff --git a/plugins/android/src/org/jetbrains/android/run/AndroidRunConfigurationBase.java b/plugins/android/src/org/jetbrains/android/run/AndroidRunConfigurationBase.java index 9675f7469784..54e28b8b1012 100644 --- a/plugins/android/src/org/jetbrains/android/run/AndroidRunConfigurationBase.java +++ b/plugins/android/src/org/jetbrains/android/run/AndroidRunConfigurationBase.java @@ -183,7 +183,7 @@ public abstract class AndroidRunConfigurationBase extends ModuleBasedConfigurati return true; } - public RunProfileState getState(@NotNull final Executor executor, @NotNull ExecutionEnvironment env) throws ExecutionException { + public AndroidRunningState getState(@NotNull final Executor executor, @NotNull ExecutionEnvironment env) throws ExecutionException { final Module module = getConfigurationModule().getModule(); if (module == null) { throw new ExecutionException("Module is not found"); diff --git a/plugins/android/src/org/jetbrains/android/run/AndroidRunningState.java b/plugins/android/src/org/jetbrains/android/run/AndroidRunningState.java index 4f6233148d6f..976b7eb14a90 100644 --- a/plugins/android/src/org/jetbrains/android/run/AndroidRunningState.java +++ b/plugins/android/src/org/jetbrains/android/run/AndroidRunningState.java @@ -218,10 +218,6 @@ public abstract class AndroidRunningState implements RunProfileState, AndroidDeb return myLock; } - public AndroidFacet getAndroidFacet() { - return myFacet; - } - public String getPackageName() { return myPackageName; } @@ -230,6 +226,7 @@ public abstract class AndroidRunningState implements RunProfileState, AndroidDeb return myFacet.getModule(); } + @NotNull public AndroidFacet getFacet() { return myFacet; } diff --git a/plugins/android/src/org/jetbrains/android/run/testing/AndroidTestRunConfiguration.java b/plugins/android/src/org/jetbrains/android/run/testing/AndroidTestRunConfiguration.java index 9f64c41095cc..210a3984fc4d 100644 --- a/plugins/android/src/org/jetbrains/android/run/testing/AndroidTestRunConfiguration.java +++ b/plugins/android/src/org/jetbrains/android/run/testing/AndroidTestRunConfiguration.java @@ -28,6 +28,7 @@ import com.intellij.execution.Executor; import com.intellij.execution.configurations.*; import com.intellij.execution.junit.JUnitUtil; import com.intellij.execution.process.ProcessOutputTypes; +import com.intellij.execution.runners.ExecutionEnvironment; import com.intellij.execution.testframework.sm.SMTestRunnerConnectionUtil; import com.intellij.execution.testframework.ui.BaseTestsOutputConsoleView; import com.intellij.execution.ui.ConsoleView; @@ -35,6 +36,8 @@ import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.module.Module; import com.intellij.openapi.options.SettingsEditor; import com.intellij.openapi.project.Project; +import com.intellij.openapi.roots.ModuleRootManager; +import com.intellij.openapi.ui.Messages; import com.intellij.openapi.util.Disposer; import com.intellij.psi.JavaPsiFacade; import com.intellij.psi.PsiClass; @@ -43,6 +46,7 @@ import com.intellij.psi.PsiPackage; import org.jetbrains.android.dom.manifest.Instrumentation; import org.jetbrains.android.dom.manifest.Manifest; import org.jetbrains.android.facet.AndroidFacet; +import org.jetbrains.android.facet.AndroidFacetConfiguration; import org.jetbrains.android.run.AndroidApplicationLauncher; import org.jetbrains.android.run.AndroidRunConfigurationBase; import org.jetbrains.android.run.AndroidRunConfigurationEditor; @@ -108,6 +112,44 @@ public class AndroidTestRunConfiguration extends AndroidRunConfigurationBase { } } + @Override + public AndroidRunningState getState(@NotNull Executor executor, @NotNull ExecutionEnvironment env) throws ExecutionException { + final AndroidRunningState state = super.getState(executor, env); + + if (state == null) { + return null; + } + + final AndroidFacet facet = state.getFacet(); + final AndroidFacetConfiguration configuration = facet.getConfiguration(); + + if (!configuration.PACK_TEST_CODE) { + final Module module = facet.getModule(); + final int count = getTestSourceRootCount(module); + + if (count > 0) { + final String message = "Code and resources under test source " + (count > 1 ? "roots" : "root") + + " aren't included into debug APK.\nWould you like to include them and recompile " + + module.getName() + " module?" + "\n(You may change this option in Android facet settings later)"; + final int result = + Messages.showYesNoCancelDialog(getProject(), message, "Test code not included into APK", Messages.getQuestionIcon()); + + if (result == Messages.YES) { + configuration.PACK_TEST_CODE = true; + } + else if (result == Messages.CANCEL) { + return null; + } + } + } + return state; + } + + private static int getTestSourceRootCount(@NotNull Module module) { + final ModuleRootManager manager = ModuleRootManager.getInstance(module); + return manager.getSourceRoots(true).length - manager.getSourceRoots(false).length; + } + private void checkTestMethod() throws RuntimeConfigurationException { JavaRunConfigurationModule configurationModule = getConfigurationModule(); final PsiClass testClass = @@ -166,7 +208,7 @@ public class AndroidTestRunConfiguration extends AndroidRunConfigurationBase { BaseTestsOutputConsoleView consoleView = SMTestRunnerConnectionUtil .createAndAttachConsole("Android", state.getProcessHandler(), properties, state.getRunnerSettings(), state.getConfigurationSettings() ); - Disposer.register(state.getAndroidFacet().getModule().getProject(), consoleView); + Disposer.register(state.getFacet().getModule().getProject(), consoleView); return consoleView; }