summaryrefslogtreecommitdiff
path: root/jps
diff options
context:
space:
mode:
authorTor Norbye <tnorbye@google.com>2013-05-01 12:55:43 -0700
committerTor Norbye <tnorbye@google.com>2013-05-01 12:55:43 -0700
commit8fb0021093e7d978cc06043ba4c06b0a47778294 (patch)
treeb95f5f920574415ae49b26ad6abac86eb6d7b38d /jps
parentb17587c84879dd2ea42495f1fbdadbc806b9475b (diff)
downloadidea-8fb0021093e7d978cc06043ba4c06b0a47778294.tar.gz
Snapshot dddb119296e7ee16fa8180784610b89b89112ebb from master branch of git://git.jetbrains.org/idea/community.git
Change-Id: I5fe892d3e4d06009445cc2270aa90bb57dea9d39
Diffstat (limited to 'jps')
-rw-r--r--jps/jps-builders/src/org/jetbrains/jps/cmdline/BuildRunner.java52
-rw-r--r--jps/jps-builders/src/org/jetbrains/jps/cmdline/BuildSession.java16
-rw-r--r--jps/jps-builders/src/org/jetbrains/jps/incremental/IncProjectBuilder.java6
-rw-r--r--jps/jps-builders/src/org/jetbrains/jps/incremental/artifacts/builders/ArtifactLayoutCustomizationService.java34
-rw-r--r--jps/jps-builders/src/org/jetbrains/jps/incremental/artifacts/builders/LayoutElementBuildersRegistry.java29
-rw-r--r--jps/jps-builders/src/org/jetbrains/jps/incremental/artifacts/impl/JpsArtifactUtil.java5
-rw-r--r--jps/jps-builders/src/org/jetbrains/jps/incremental/artifacts/instructions/ArtifactInstructionsBuilderContext.java6
-rw-r--r--jps/jps-builders/src/org/jetbrains/jps/incremental/artifacts/instructions/ArtifactInstructionsBuilderContextImpl.java7
-rw-r--r--jps/jps-builders/src/org/jetbrains/jps/incremental/messages/BuildingTargetProgressMessage.java47
-rw-r--r--jps/jps-builders/testSrc/org/jetbrains/ether/IncrementalTestCase.java14
-rw-r--r--jps/jps-builders/testSrc/org/jetbrains/jps/builders/JpsBuildTestCase.java33
-rw-r--r--jps/standalone-builder/src/org/jetbrains/jps/build/Standalone.java33
-rw-r--r--jps/standalone-builder/src/org/jetbrains/jps/gant/JpsGantProjectBuilder.java14
13 files changed, 233 insertions, 63 deletions
diff --git a/jps/jps-builders/src/org/jetbrains/jps/cmdline/BuildRunner.java b/jps/jps-builders/src/org/jetbrains/jps/cmdline/BuildRunner.java
index f2650717ff50..7fe98f331a26 100644
--- a/jps/jps-builders/src/org/jetbrains/jps/cmdline/BuildRunner.java
+++ b/jps/jps-builders/src/org/jetbrains/jps/cmdline/BuildRunner.java
@@ -18,14 +18,12 @@ package org.jetbrains.jps.cmdline;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.io.FileUtil;
import gnu.trove.THashSet;
+import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jps.api.BuildType;
import org.jetbrains.jps.api.CanceledStatus;
import org.jetbrains.jps.api.GlobalOptions;
-import org.jetbrains.jps.builders.BuildRootDescriptor;
-import org.jetbrains.jps.builders.BuildTarget;
-import org.jetbrains.jps.builders.BuildTargetLoader;
-import org.jetbrains.jps.builders.BuildTargetType;
+import org.jetbrains.jps.builders.*;
import org.jetbrains.jps.builders.impl.BuildDataPathsImpl;
import org.jetbrains.jps.builders.impl.BuildRootIndexImpl;
import org.jetbrains.jps.builders.impl.BuildTargetIndexImpl;
@@ -59,14 +57,12 @@ public class BuildRunner {
public static final boolean PARALLEL_BUILD_ENABLED = Boolean.parseBoolean(System.getProperty(GlobalOptions.COMPILE_PARALLEL_OPTION, "false"));
private static final boolean STORE_TEMP_CACHES_IN_MEMORY = PARALLEL_BUILD_ENABLED || System.getProperty(GlobalOptions.USE_MEMORY_TEMP_CACHE_OPTION) != null;
private final JpsModelLoader myModelLoader;
- private final List<TargetTypeBuildScope> myScopes;
private final List<String> myFilePaths;
private final Map<String, String> myBuilderParams;
private boolean myForceCleanCaches;
- public BuildRunner(JpsModelLoader modelLoader, List<TargetTypeBuildScope> scopes, List<String> filePaths, Map<String, String> builderParams) {
+ public BuildRunner(JpsModelLoader modelLoader, List<String> filePaths, Map<String, String> builderParams) {
myModelLoader = modelLoader;
- myScopes = scopes;
myFilePaths = filePaths;
myBuilderParams = builderParams;
}
@@ -116,11 +112,15 @@ public class BuildRunner {
myForceCleanCaches = forceCleanCaches;
}
- public void runBuild(ProjectDescriptor pd, CanceledStatus cs, @Nullable Callbacks.ConstantAffectionResolver constantSearch,
- MessageHandler msgHandler, BuildType buildType) throws Exception {
+ public void runBuild(ProjectDescriptor pd,
+ CanceledStatus cs,
+ @Nullable Callbacks.ConstantAffectionResolver constantSearch,
+ MessageHandler msgHandler,
+ BuildType buildType,
+ List<TargetTypeBuildScope> scopes, final boolean includeDependenciesToScope) throws Exception {
for (int attempt = 0; attempt < 2; attempt++) {
final boolean forceClean = myForceCleanCaches && myFilePaths.isEmpty();
- final CompileScope compileScope = createCompilationScope(pd, myScopes, myFilePaths, forceClean);
+ final CompileScope compileScope = createCompilationScope(pd, scopes, myFilePaths, forceClean, includeDependenciesToScope);
final IncProjectBuilder builder = new IncProjectBuilder(pd, BuilderRegistry.getInstance(), myBuilderParams, cs, constantSearch);
builder.addMessageHandler(msgHandler);
try {
@@ -151,8 +151,8 @@ public class BuildRunner {
}
}
- private static CompileScope createCompilationScope(ProjectDescriptor pd, List<TargetTypeBuildScope> scopes,
- Collection<String> paths, final boolean forceClean) throws Exception {
+ private static CompileScope createCompilationScope(ProjectDescriptor pd, List<TargetTypeBuildScope> scopes, Collection<String> paths,
+ final boolean forceClean, final boolean includeDependenciesToScope) throws Exception {
Set<BuildTargetType<?>> targetTypes = new HashSet<BuildTargetType<?>>();
Set<BuildTargetType<?>> targetTypesToForceBuild = new HashSet<BuildTargetType<?>>();
Set<BuildTarget<?>> targets = new HashSet<BuildTarget<?>>();
@@ -184,6 +184,9 @@ public class BuildRunner {
}
}
}
+ if (includeDependenciesToScope) {
+ includeDependenciesToScope(targetTypes, targets, pd);
+ }
final Timestamps timestamps = pd.timestamps.getStorage();
if (!paths.isEmpty()) {
@@ -211,7 +214,28 @@ public class BuildRunner {
return new CompileScopeImpl(targetTypes, targetTypesToForceBuild, targets, files);
}
- public List<TargetTypeBuildScope> getScopes() {
- return myScopes;
+ private static void includeDependenciesToScope(Set<BuildTargetType<?>> targetTypes, Set<BuildTarget<?>> targets,
+ ProjectDescriptor descriptor) {
+ //todo[nik] get rid of CompileContext parameter for BuildTargetIndex.getDependencies() and use it here
+ TargetOutputIndex dummyIndex = new TargetOutputIndex() {
+ @Override
+ public Collection<BuildTarget<?>> getTargetsByOutputFile(@NotNull File file) {
+ return Collections.emptyList();
+ }
+ };
+
+ List<BuildTarget<?>> current = new ArrayList<BuildTarget<?>>(targets);
+ while (!current.isEmpty()) {
+ List<BuildTarget<?>> next = new ArrayList<BuildTarget<?>>();
+ for (BuildTarget<?> target : current) {
+ for (BuildTarget<?> depTarget : target.computeDependencies(descriptor.getBuildTargetIndex(), dummyIndex)) {
+ if (!targets.contains(depTarget) && !targetTypes.contains(depTarget.getTargetType())) {
+ next.add(depTarget);
+ }
+ }
+ }
+ targets.addAll(next);
+ current = next;
+ }
}
}
diff --git a/jps/jps-builders/src/org/jetbrains/jps/cmdline/BuildSession.java b/jps/jps-builders/src/org/jetbrains/jps/cmdline/BuildSession.java
index e246ad13a5fa..b1ffe29b9788 100644
--- a/jps/jps-builders/src/org/jetbrains/jps/cmdline/BuildSession.java
+++ b/jps/jps-builders/src/org/jetbrains/jps/cmdline/BuildSession.java
@@ -72,7 +72,8 @@ final class BuildSession implements Runnable, CanceledStatus {
private final ConstantSearch myConstantSearch = new ConstantSearch();
private final BuildRunner myBuildRunner;
private final boolean myForceModelLoading;
- private BuildType myBuildType;
+ private final BuildType myBuildType;
+ private final List<TargetTypeBuildScope> myScopes;
BuildSession(UUID sessionId,
Channel channel,
@@ -85,7 +86,7 @@ final class BuildSession implements Runnable, CanceledStatus {
myProjectPath = FileUtil.toCanonicalPath(params.getProjectId());
String globalOptionsPath = FileUtil.toCanonicalPath(globals.getGlobalOptionsPath());
myBuildType = convertCompileType(params.getBuildType());
- List<TargetTypeBuildScope> scopes = params.getScopeList();
+ myScopes = params.getScopeList();
List<String> filePaths = params.getFilePathList();
Map<String, String> builderParams = new HashMap<String, String>();
for (CmdlineRemoteProto.Message.KeyValuePair pair : params.getBuilderParameterList()) {
@@ -94,7 +95,7 @@ final class BuildSession implements Runnable, CanceledStatus {
myInitialFSDelta = delta;
JpsModelLoaderImpl loader = new JpsModelLoaderImpl(myProjectPath, globalOptionsPath, null);
myForceModelLoading = Boolean.parseBoolean(builderParams.get(BuildMain.FORCE_MODEL_LOADING_PARAMETER.toString()));
- myBuildRunner = new BuildRunner(loader, scopes, filePaths, builderParams);
+ myBuildRunner = new BuildRunner(loader, filePaths, builderParams);
}
public void run() {
@@ -138,13 +139,16 @@ final class BuildSession implements Runnable, CanceledStatus {
CustomBuilderMessage builderMessage = (CustomBuilderMessage)buildMessage;
response = CmdlineProtoUtil.createCustomBuilderMessage(builderMessage.getBuilderId(), builderMessage.getMessageType(), builderMessage.getMessageText());
}
- else {
+ else if (!(buildMessage instanceof BuildingTargetProgressMessage)) {
float done = -1.0f;
if (buildMessage instanceof ProgressMessage) {
done = ((ProgressMessage)buildMessage).getDone();
}
response = CmdlineProtoUtil.createCompileProgressMessageResponse(buildMessage.getMessageText(), done);
}
+ else {
+ response = null;
+ }
if (response != null) {
Channels.write(myChannel, CmdlineProtoUtil.toMessage(mySessionId, response));
}
@@ -181,7 +185,7 @@ final class BuildSession implements Runnable, CanceledStatus {
// optimization: check whether we can skip the build
final boolean hasWorkToDoWithModules = fsStateStream.readBoolean();
if (!myForceModelLoading && (myBuildType == BuildType.BUILD || myBuildType == BuildType.UP_TO_DATE_CHECK) && !hasWorkToDoWithModules
- && scopeContainsModulesOnlyForIncrementalMake(myBuildRunner.getScopes()) && !containsChanges(myInitialFSDelta)) {
+ && scopeContainsModulesOnlyForIncrementalMake(myScopes) && !containsChanges(myInitialFSDelta)) {
updateFsStateOnDisk(dataStorageRoot, fsStateStream, myInitialFSDelta.getOrdinal());
return;
}
@@ -213,7 +217,7 @@ final class BuildSession implements Runnable, CanceledStatus {
// ensure events from controller are processed after FSState initialization
myEventsProcessor.startProcessing();
- myBuildRunner.runBuild(pd, cs, myConstantSearch, msgHandler, myBuildType);
+ myBuildRunner.runBuild(pd, cs, myConstantSearch, msgHandler, myBuildType, myScopes, false);
}
finally {
saveData(fsState, dataStorageRoot);
diff --git a/jps/jps-builders/src/org/jetbrains/jps/incremental/IncProjectBuilder.java b/jps/jps-builders/src/org/jetbrains/jps/incremental/IncProjectBuilder.java
index 2e6a288e900d..37ea688b5101 100644
--- a/jps/jps-builders/src/org/jetbrains/jps/incremental/IncProjectBuilder.java
+++ b/jps/jps-builders/src/org/jetbrains/jps/incremental/IncProjectBuilder.java
@@ -809,6 +809,7 @@ public class IncProjectBuilder {
private void buildTargetsChunk(CompileContext context, final BuildTargetChunk chunk) throws ProjectBuildException {
boolean doneSomething;
try {
+ sendBuildingTargetMessages(chunk.getTargets(), BuildingTargetProgressMessage.Event.STARTED);
Utils.ERRORS_DETECTED_KEY.set(context, Boolean.FALSE);
for (BuildTarget<?> target : chunk.getTargets()) {
@@ -864,9 +865,14 @@ public class IncProjectBuilder {
finally {
Utils.REMOVED_SOURCES_KEY.set(context, null);
}
+ sendBuildingTargetMessages(chunk.getTargets(), BuildingTargetProgressMessage.Event.FINISHED);
}
}
+ private void sendBuildingTargetMessages(@NotNull Set<? extends BuildTarget<?>> targets, @NotNull BuildingTargetProgressMessage.Event event) {
+ myMessageDispatcher.processMessage(new BuildingTargetProgressMessage(targets, event));
+ }
+
private static void createClasspathIndex(final BuildTargetChunk chunk) {
final Set<File> outputDirs = new THashSet<File>(FileUtil.FILE_HASHING_STRATEGY);
for (BuildTarget<?> target : chunk.getTargets()) {
diff --git a/jps/jps-builders/src/org/jetbrains/jps/incremental/artifacts/builders/ArtifactLayoutCustomizationService.java b/jps/jps-builders/src/org/jetbrains/jps/incremental/artifacts/builders/ArtifactLayoutCustomizationService.java
new file mode 100644
index 000000000000..e82fc15c918d
--- /dev/null
+++ b/jps/jps-builders/src/org/jetbrains/jps/incremental/artifacts/builders/ArtifactLayoutCustomizationService.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2000-2013 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jetbrains.jps.incremental.artifacts.builders;
+
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.jps.model.artifact.JpsArtifact;
+import org.jetbrains.jps.model.artifact.elements.JpsPackagingElement;
+
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * @author nik
+ */
+public abstract class ArtifactLayoutCustomizationService {
+ @Nullable
+ public abstract List<JpsPackagingElement> getCustomizedLayout(@NotNull JpsArtifact artifact,
+ @NotNull Collection<JpsArtifact> parentArtifacts);
+
+}
diff --git a/jps/jps-builders/src/org/jetbrains/jps/incremental/artifacts/builders/LayoutElementBuildersRegistry.java b/jps/jps-builders/src/org/jetbrains/jps/incremental/artifacts/builders/LayoutElementBuildersRegistry.java
index 0d0e90f0a532..5cef20f4dfb4 100644
--- a/jps/jps-builders/src/org/jetbrains/jps/incremental/artifacts/builders/LayoutElementBuildersRegistry.java
+++ b/jps/jps-builders/src/org/jetbrains/jps/incremental/artifacts/builders/LayoutElementBuildersRegistry.java
@@ -16,7 +16,6 @@
package org.jetbrains.jps.incremental.artifacts.builders;
import com.intellij.openapi.diagnostic.Logger;
-import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.containers.ClassMap;
import org.jetbrains.annotations.NotNull;
@@ -25,8 +24,6 @@ import org.jetbrains.jps.builders.BuildTarget;
import org.jetbrains.jps.builders.TargetOutputIndex;
import org.jetbrains.jps.builders.java.JavaModuleBuildTargetType;
import org.jetbrains.jps.incremental.ModuleBuildTarget;
-import org.jetbrains.jps.model.module.JpsModule;
-import org.jetbrains.jps.util.JpsPathUtil;
import org.jetbrains.jps.incremental.artifacts.instructions.ArtifactCompilerInstructionCreator;
import org.jetbrains.jps.incremental.artifacts.instructions.ArtifactInstructionsBuilderContext;
import org.jetbrains.jps.incremental.artifacts.instructions.CopyToDirectoryInstructionCreator;
@@ -34,12 +31,15 @@ import org.jetbrains.jps.model.artifact.JpsArtifact;
import org.jetbrains.jps.model.artifact.elements.*;
import org.jetbrains.jps.model.java.JpsProductionModuleOutputPackagingElement;
import org.jetbrains.jps.model.java.JpsTestModuleOutputPackagingElement;
+import org.jetbrains.jps.model.module.JpsModule;
import org.jetbrains.jps.service.JpsServiceManager;
+import org.jetbrains.jps.util.JpsPathUtil;
import java.io.File;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
+import java.util.Set;
/**
* @author nik
@@ -305,11 +305,19 @@ public class LayoutElementBuildersRegistry {
final JpsArtifact artifact = element.getArtifactReference().resolve();
if (artifact == null) return;
+ Set<JpsArtifact> parentArtifacts = builderContext.getParentArtifacts();
+ List<JpsPackagingElement> customLayout = getCustomArtifactLayout(artifact, parentArtifacts);
+
final String outputPath = artifact.getOutputPath();
- if (StringUtil.isEmpty(outputPath)) {
+ if (StringUtil.isEmpty(outputPath) || customLayout != null) {
try {
if (builderContext.enterArtifact(artifact)) {
- generateSubstitutionInstructions(element, instructionCreator, builderContext);
+ if (customLayout != null) {
+ LayoutElementBuildersRegistry.this.generateInstructions(customLayout, instructionCreator, builderContext);
+ }
+ else {
+ generateSubstitutionInstructions(element, instructionCreator, builderContext);
+ }
}
}
finally {
@@ -328,5 +336,16 @@ public class LayoutElementBuildersRegistry {
instructionCreator.addDirectoryCopyInstructions(outputDir);
}
}
+
+ @Nullable
+ private List<JpsPackagingElement> getCustomArtifactLayout(@NotNull JpsArtifact artifact, @NotNull Set<JpsArtifact> parentArtifacts) {
+ for (ArtifactLayoutCustomizationService service : JpsServiceManager.getInstance().getExtensions(ArtifactLayoutCustomizationService.class)) {
+ List<JpsPackagingElement> elements = service.getCustomizedLayout(artifact, parentArtifacts);
+ if (elements != null) {
+ return elements;
+ }
+ }
+ return null;
+ }
}
}
diff --git a/jps/jps-builders/src/org/jetbrains/jps/incremental/artifacts/impl/JpsArtifactUtil.java b/jps/jps-builders/src/org/jetbrains/jps/incremental/artifacts/impl/JpsArtifactUtil.java
index f91a576366b6..55c8b3478269 100644
--- a/jps/jps-builders/src/org/jetbrains/jps/incremental/artifacts/impl/JpsArtifactUtil.java
+++ b/jps/jps-builders/src/org/jetbrains/jps/incremental/artifacts/impl/JpsArtifactUtil.java
@@ -15,6 +15,7 @@
*/
package org.jetbrains.jps.incremental.artifacts.impl;
+import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.Processor;
import com.intellij.util.containers.HashSet;
import org.jetbrains.annotations.NotNull;
@@ -55,4 +56,8 @@ public class JpsArtifactUtil {
}
return true;
}
+
+ public static boolean isArchiveName(String name) {
+ return name.length() >= 4 && name.charAt(name.length() - 4) == '.' && StringUtil.endsWithIgnoreCase(name, "ar");
+ }
}
diff --git a/jps/jps-builders/src/org/jetbrains/jps/incremental/artifacts/instructions/ArtifactInstructionsBuilderContext.java b/jps/jps-builders/src/org/jetbrains/jps/incremental/artifacts/instructions/ArtifactInstructionsBuilderContext.java
index 5d201f17e529..91256a63ab4b 100644
--- a/jps/jps-builders/src/org/jetbrains/jps/incremental/artifacts/instructions/ArtifactInstructionsBuilderContext.java
+++ b/jps/jps-builders/src/org/jetbrains/jps/incremental/artifacts/instructions/ArtifactInstructionsBuilderContext.java
@@ -15,10 +15,13 @@
*/
package org.jetbrains.jps.incremental.artifacts.instructions;
+import org.jetbrains.annotations.NotNull;
import org.jetbrains.jps.builders.storage.BuildDataPaths;
import org.jetbrains.jps.model.JpsModel;
import org.jetbrains.jps.model.artifact.JpsArtifact;
+import java.util.Set;
+
/**
* @author nik
*/
@@ -31,4 +34,7 @@ public interface ArtifactInstructionsBuilderContext {
BuildDataPaths getDataPaths();
JpsModel getModel();
+
+ @NotNull
+ Set<JpsArtifact> getParentArtifacts();
}
diff --git a/jps/jps-builders/src/org/jetbrains/jps/incremental/artifacts/instructions/ArtifactInstructionsBuilderContextImpl.java b/jps/jps-builders/src/org/jetbrains/jps/incremental/artifacts/instructions/ArtifactInstructionsBuilderContextImpl.java
index 0d2cf4b2dc4d..88e9139f4579 100644
--- a/jps/jps-builders/src/org/jetbrains/jps/incremental/artifacts/instructions/ArtifactInstructionsBuilderContextImpl.java
+++ b/jps/jps-builders/src/org/jetbrains/jps/incremental/artifacts/instructions/ArtifactInstructionsBuilderContextImpl.java
@@ -15,6 +15,7 @@
*/
package org.jetbrains.jps.incremental.artifacts.instructions;
+import org.jetbrains.annotations.NotNull;
import org.jetbrains.jps.builders.storage.BuildDataPaths;
import org.jetbrains.jps.model.JpsModel;
import org.jetbrains.jps.model.artifact.JpsArtifact;
@@ -52,6 +53,12 @@ public class ArtifactInstructionsBuilderContextImpl implements ArtifactInstructi
}
@Override
+ @NotNull
+ public Set<JpsArtifact> getParentArtifacts() {
+ return myParentArtifacts;
+ }
+
+ @Override
public void leaveArtifact(JpsArtifact artifact) {
myParentArtifacts.remove(artifact);
}
diff --git a/jps/jps-builders/src/org/jetbrains/jps/incremental/messages/BuildingTargetProgressMessage.java b/jps/jps-builders/src/org/jetbrains/jps/incremental/messages/BuildingTargetProgressMessage.java
new file mode 100644
index 000000000000..50399f74baab
--- /dev/null
+++ b/jps/jps-builders/src/org/jetbrains/jps/incremental/messages/BuildingTargetProgressMessage.java
@@ -0,0 +1,47 @@
+package org.jetbrains.jps.incremental.messages;
+
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.util.NotNullFunction;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.jps.builders.BuildTarget;
+
+import java.util.Collection;
+
+/**
+ * @author nik
+ */
+public class BuildingTargetProgressMessage extends BuildMessage {
+ private final Collection<? extends BuildTarget<?>> myTargets;
+ @NotNull private final Event myEventType;
+
+ public enum Event {
+ STARTED, FINISHED
+ }
+
+ public BuildingTargetProgressMessage(@NotNull Collection<? extends BuildTarget<?>> targets, @NotNull Event event) {
+ super(composeMessageText(targets, event), Kind.PROGRESS);
+ myTargets = targets;
+ myEventType = event;
+ }
+
+ private static String composeMessageText(Collection<? extends BuildTarget<?>> targets, Event event) {
+ String targetsString = StringUtil.join(targets, new NotNullFunction<BuildTarget<?>, String>() {
+ @NotNull
+ @Override
+ public String fun(BuildTarget<?> dom) {
+ return dom.getPresentableName();
+ }
+ }, ", ");
+ return (event == Event.STARTED ? "Started" : "Finished") + " building " + targetsString;
+ }
+
+ @NotNull
+ public Collection<? extends BuildTarget<?>> getTargets() {
+ return myTargets;
+ }
+
+ @NotNull
+ public Event getEventType() {
+ return myEventType;
+ }
+}
diff --git a/jps/jps-builders/testSrc/org/jetbrains/ether/IncrementalTestCase.java b/jps/jps-builders/testSrc/org/jetbrains/ether/IncrementalTestCase.java
index 6e38f95a7c52..3fec8d342cbb 100644
--- a/jps/jps-builders/testSrc/org/jetbrains/ether/IncrementalTestCase.java
+++ b/jps/jps-builders/testSrc/org/jetbrains/ether/IncrementalTestCase.java
@@ -16,6 +16,7 @@
package org.jetbrains.ether;
import com.intellij.openapi.application.ex.PathManagerEx;
+import com.intellij.openapi.util.io.FileSystemUtil;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.Processor;
@@ -110,12 +111,15 @@ public abstract class IncrementalTestCase extends JpsBuildTestCase {
return true;
}
});
+ final long[] timestamp = {0};
FileUtil.processFilesRecursively(baseDir, new Processor<File>() {
@Override
public boolean process(File file) {
try {
if (file.getName().endsWith(newSuffix)) {
- FileUtil.copyContent(file, getTargetFile(file, newSuffix));
+ File targetFile = getTargetFile(file, newSuffix);
+ FileUtil.copyContent(file, targetFile);
+ timestamp[0] = Math.max(timestamp[0], FileSystemUtil.lastModified(targetFile));
}
}
catch (IOException e) {
@@ -124,13 +128,7 @@ public abstract class IncrementalTestCase extends JpsBuildTestCase {
return true;
}
});
- if (TIMESTAMP_ACCURACY > 1) {
- try {
- Thread.sleep(TIMESTAMP_ACCURACY);
- }
- catch (InterruptedException ignored) {
- }
- }
+ sleepUntil(timestamp[0]);
}
private File getTargetFile(File sourceFile, final String suffix) {
diff --git a/jps/jps-builders/testSrc/org/jetbrains/jps/builders/JpsBuildTestCase.java b/jps/jps-builders/testSrc/org/jetbrains/jps/builders/JpsBuildTestCase.java
index 68b617670adc..5e353c9315c8 100644
--- a/jps/jps-builders/testSrc/org/jetbrains/jps/builders/JpsBuildTestCase.java
+++ b/jps/jps-builders/testSrc/org/jetbrains/jps/builders/JpsBuildTestCase.java
@@ -17,7 +17,6 @@ package org.jetbrains.jps.builders;
import com.intellij.openapi.application.PathManager;
import com.intellij.openapi.application.ex.PathManagerEx;
-import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.util.io.FileSystemUtil;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
@@ -67,7 +66,6 @@ import static org.jetbrains.jps.builders.CompileScopeTestBuilder.make;
* @author nik
*/
public abstract class JpsBuildTestCase extends UsefulTestCase {
- protected static final long TIMESTAMP_ACCURACY = SystemInfo.isMac ? 1000 : 1;
private File myProjectDir;
protected JpsProject myProject;
protected JpsModel myModel;
@@ -118,19 +116,15 @@ public abstract class JpsBuildTestCase extends UsefulTestCase {
long time = System.currentTimeMillis();
setLastModified(file, time);
if (FileSystemUtil.lastModified(file) <= oldTimestamp) {
- setLastModified(file, time + TIMESTAMP_ACCURACY);
+ setLastModified(file, time + 1);
long newTimeStamp = FileSystemUtil.lastModified(file);
- assertTrue("Failed to change timestamp for " + file.getAbsolutePath(), newTimeStamp > oldTimestamp);
- long delta;
- while ((delta = newTimeStamp - System.currentTimeMillis()) > 0) {
- try {
- //we need this to ensure that the file won't be treated as changed by user during compilation and marked for recompilation
- //noinspection BusyWait
- Thread.sleep(delta);
- }
- catch (InterruptedException ignored) {
- }
+ if (newTimeStamp <= oldTimestamp) {
+ //Mac OS and some versions of Linux truncates timestamp to nearest second
+ setLastModified(file, time + 1000);
+ newTimeStamp = FileSystemUtil.lastModified(file);
+ assertTrue("Failed to change timestamp for " + file.getAbsolutePath(), newTimeStamp > oldTimestamp);
}
+ sleepUntil(newTimeStamp);
}
}
catch (IOException e) {
@@ -138,6 +132,19 @@ public abstract class JpsBuildTestCase extends UsefulTestCase {
}
}
+ protected static void sleepUntil(long time) {
+ //we need this to ensure that the file won't be treated as changed by user during compilation and therefore marked for recompilation
+ long delta;
+ while ((delta = time - System.currentTimeMillis()) > 0) {
+ try {
+ //noinspection BusyWait
+ Thread.sleep(delta);
+ }
+ catch (InterruptedException ignored) {
+ }
+ }
+ }
+
private static void setLastModified(File file, long time) {
boolean updated = file.setLastModified(time);
assertTrue("Cannot modify timestamp for " + file.getAbsolutePath(), updated);
diff --git a/jps/standalone-builder/src/org/jetbrains/jps/build/Standalone.java b/jps/standalone-builder/src/org/jetbrains/jps/build/Standalone.java
index e52c8ac3b087..4572c4d32d1c 100644
--- a/jps/standalone-builder/src/org/jetbrains/jps/build/Standalone.java
+++ b/jps/standalone-builder/src/org/jetbrains/jps/build/Standalone.java
@@ -55,6 +55,9 @@ public class Standalone {
@Argument(value = "modules", prefix = "--", delimiter = ",", description = "Comma-separated list of modules to compile")
public String[] modules = ArrayUtil.EMPTY_STRING_ARRAY;
+ @Argument(value = "all-modules", prefix = "--", description = "Compile all modules")
+ public boolean allModules;
+
@Argument(value = "artifacts", prefix = "--", delimiter = ",", description = "Comma-separated list of artifacts to build")
public String[] artifacts = ArrayUtil.EMPTY_STRING_ARRAY;
@@ -81,8 +84,6 @@ public class Standalone {
printUsageAndExit();
}
-
-
instance.loadAndRunBuild(projectPaths.get(0));
System.exit(0);
}
@@ -114,6 +115,11 @@ public class Standalone {
initializer = new GroovyModelInitializer(scriptFile);
}
+ if (modules.length == 0 && artifacts.length == 0 && !allModules) {
+ System.err.println("Nothing to compile: at least one of --modules, --artifacts or --all-modules parameters must be specified");
+ return;
+ }
+
JpsModelLoaderImpl loader = new JpsModelLoaderImpl(projectPath, globalOptionsPath, initializer);
Set<String> modulesSet = new HashSet<String>(Arrays.asList(modules));
List<String> artifactsList = Arrays.asList(artifacts);
@@ -131,7 +137,7 @@ public class Standalone {
long start = System.currentTimeMillis();
try {
- runBuild(loader, dataStorageRoot, !incremental, modulesSet, artifactsList, true, new ConsoleMessageHandler());
+ runBuild(loader, dataStorageRoot, !incremental, modulesSet, allModules, artifactsList, true, new ConsoleMessageHandler());
}
catch (Throwable t) {
System.err.println("Internal error: " + t.getMessage());
@@ -140,28 +146,35 @@ public class Standalone {
System.out.println("Build finished in " + Utils.formatDuration(System.currentTimeMillis() - start));
}
+ @Deprecated
public static void runBuild(JpsModelLoader loader, final File dataStorageRoot, boolean forceBuild, Set<String> modulesSet,
List<String> artifactsList, final boolean includeTests, final MessageHandler messageHandler) throws Exception {
+ runBuild(loader, dataStorageRoot, forceBuild, modulesSet, modulesSet.isEmpty(), artifactsList, includeTests, messageHandler);
+ }
+
+ public static void runBuild(JpsModelLoader loader, final File dataStorageRoot, boolean forceBuild, Set<String> modulesSet,
+ final boolean allModules, List<String> artifactsList, final boolean includeTests,
+ final MessageHandler messageHandler) throws Exception {
List<TargetTypeBuildScope> scopes = new ArrayList<TargetTypeBuildScope>();
for (JavaModuleBuildTargetType type : JavaModuleBuildTargetType.ALL_TYPES) {
if (includeTests || !type.isTests()) {
TargetTypeBuildScope.Builder builder = TargetTypeBuildScope.newBuilder().setTypeId(type.getTypeId()).setForceBuild(forceBuild);
- if (modulesSet.isEmpty()) {
- builder.setAllTargets(true);
+ if (allModules) {
+ scopes.add(builder.setAllTargets(true).build());
}
- else {
- builder.addAllTargetId(modulesSet);
+ else if (!modulesSet.isEmpty()) {
+ scopes.add(builder.addAllTargetId(modulesSet).build());
}
- scopes.add(builder.build());
}
}
if (!artifactsList.isEmpty()) {
scopes.add(TargetTypeBuildScope.newBuilder().setTypeId(ArtifactBuildTargetType.INSTANCE.getTypeId()).setForceBuild(forceBuild).addAllTargetId(artifactsList).build());
}
- final BuildRunner buildRunner = new BuildRunner(loader, scopes, Collections.<String>emptyList(), Collections.<String, String>emptyMap());
+
+ final BuildRunner buildRunner = new BuildRunner(loader, Collections.<String>emptyList(), Collections.<String, String>emptyMap());
ProjectDescriptor descriptor = buildRunner.load(messageHandler, dataStorageRoot, new BuildFSState(true));
try {
- buildRunner.runBuild(descriptor, CanceledStatus.NULL, null, messageHandler, BuildType.BUILD);
+ buildRunner.runBuild(descriptor, CanceledStatus.NULL, null, messageHandler, BuildType.BUILD, scopes, true);
}
finally {
descriptor.release();
diff --git a/jps/standalone-builder/src/org/jetbrains/jps/gant/JpsGantProjectBuilder.java b/jps/standalone-builder/src/org/jetbrains/jps/gant/JpsGantProjectBuilder.java
index 3ec94962dd20..838b9ebbd60a 100644
--- a/jps/standalone-builder/src/org/jetbrains/jps/gant/JpsGantProjectBuilder.java
+++ b/jps/standalone-builder/src/org/jetbrains/jps/gant/JpsGantProjectBuilder.java
@@ -133,19 +133,19 @@ public class JpsGantProjectBuilder {
}
public void makeModule(JpsModule module) {
- runBuild(getModuleDependencies(module, false), false);
+ runBuild(getModuleDependencies(module, false), false, false);
}
public void makeModuleTests(JpsModule module) {
- runBuild(getModuleDependencies(module, true), true);
+ runBuild(getModuleDependencies(module, true), false, true);
}
public void buildAll() {
- runBuild(Collections.<String>emptySet(), true);
+ runBuild(Collections.<String>emptySet(), true, true);
}
public void buildProduction() {
- runBuild(Collections.<String>emptySet(), false);
+ runBuild(Collections.<String>emptySet(), true, false);
}
public void exportModuleOutputProperties() {
@@ -166,14 +166,14 @@ public class JpsGantProjectBuilder {
return names;
}
- private void runBuild(final Set<String> modulesSet, boolean includeTests) {
+ private void runBuild(final Set<String> modulesSet, final boolean allModules, boolean includeTests) {
if (!myDryRun) {
final AntMessageHandler messageHandler = new AntMessageHandler();
Logger.setFactory(new AntLoggerFactory(messageHandler));
info("Starting build: modules = " + modulesSet + ", caches are saved to " + myDataStorageRoot.getAbsolutePath());
try {
- Standalone.runBuild(myModelLoader, myDataStorageRoot, true, modulesSet, Collections.<String>emptyList(),
- includeTests, messageHandler);
+ Standalone.runBuild(myModelLoader, myDataStorageRoot, true, modulesSet, allModules, Collections.<String>emptyList(), includeTests,
+ messageHandler);
}
catch (Throwable e) {
error(e);