From 9d5653e99da04c0422bea0c3c6049bffbcd8230f Mon Sep 17 00:00:00 2001 From: nik Date: Mon, 13 Aug 2012 16:00:08 +0400 Subject: [PATCH] standalone JPS distribution --- .idea/modules.xml | 1 + build/build.iml | 1 + build/scripts/layouts.gant | 31 ++ .../jetbrains/jps/cmdline/BuildRunner.java | 284 ++++++++++++++++++ .../jetbrains/jps/cmdline/BuildSession.java | 258 ++-------------- .../jps/builders/JpsBuildTestCase.java | 3 +- .../org/jetbrains/jps/model/JpsGlobal.java | 3 + .../jps/model/java/JpsJavaSdkType.java | 11 +- .../jps/model/impl/JpsGlobalImpl.java | 6 + .../jetbrains/jps/model/JpsModuleTest.java | 2 +- .../jps-standalone-builder.iml | 25 ++ 11 files changed, 384 insertions(+), 241 deletions(-) create mode 100644 jps/jps-builders/src/org/jetbrains/jps/cmdline/BuildRunner.java create mode 100644 jps/standalone-builder/jps-standalone-builder.iml diff --git a/.idea/modules.xml b/.idea/modules.xml index 7da03cdac9b9..25816dd77122 100644 --- a/.idea/modules.xml +++ b/.idea/modules.xml @@ -76,6 +76,7 @@ + diff --git a/build/build.iml b/build/build.iml index f73edf9d908f..63d877ab3628 100644 --- a/build/build.iml +++ b/build/build.iml @@ -10,6 +10,7 @@ + diff --git a/build/scripts/layouts.gant b/build/scripts/layouts.gant index 5603df66909a..d9992a0cf614 100644 --- a/build/scripts/layouts.gant +++ b/build/scripts/layouts.gant @@ -23,6 +23,11 @@ target('default': "Developers update") { ant.delete(dir: patchedDescriptorDir) } +target('build-jps': 'Build JPS standalone distribution') { + println("Building jps standalone distribution") + layout_jps("$home/build/lib/jps") +} + String appInfoFileName() { return "idea/IdeaApplicationInfo.xml" } @@ -492,6 +497,32 @@ def reorder(String home, String targetDirectory) { } } +def layout_jps(String target) { + layout(target) { + jar("util.jar") { + module("annotations") + module("util-rt") + module("util") + } + jar("jps-model.jar") { + module("jps-model") + module("jps-model-api") + module("jps-model-impl") + module("jps-model-serialization") + } + jar("jps-builders.jar") { + module("forms_rt") + module("forms-compiler") + module("instrumentation-util") + module("jps-builders") + module("jps-standalone-builder") + } + jar("jps-groovy-plugin.jar") { + module("groovy_rt") + } + } +} + def layout_core(String home, String target) { layout(target) { jar("intellij-core.jar") { diff --git a/jps/jps-builders/src/org/jetbrains/jps/cmdline/BuildRunner.java b/jps/jps-builders/src/org/jetbrains/jps/cmdline/BuildRunner.java new file mode 100644 index 000000000000..5c5cd2154c21 --- /dev/null +++ b/jps/jps-builders/src/org/jetbrains/jps/cmdline/BuildRunner.java @@ -0,0 +1,284 @@ +package org.jetbrains.jps.cmdline; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.util.io.FileUtil; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.util.ParameterizedRunnable; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.ether.dependencyView.Callbacks; +import org.jetbrains.jps.Project; +import org.jetbrains.jps.api.BuildType; +import org.jetbrains.jps.api.CanceledStatus; +import org.jetbrains.jps.api.GlobalOptions; +import org.jetbrains.jps.idea.IdeaProjectLoader; +import org.jetbrains.jps.idea.SystemOutErrorReporter; +import org.jetbrains.jps.incremental.*; +import org.jetbrains.jps.incremental.artifacts.JpsBuilderArtifactService; +import org.jetbrains.jps.incremental.fs.BuildFSState; +import org.jetbrains.jps.incremental.fs.RootDescriptor; +import org.jetbrains.jps.incremental.messages.BuildMessage; +import org.jetbrains.jps.incremental.messages.CompilerMessage; +import org.jetbrains.jps.incremental.storage.BuildDataManager; +import org.jetbrains.jps.incremental.storage.ProjectTimestamps; +import org.jetbrains.jps.incremental.storage.Timestamps; +import org.jetbrains.jps.model.JpsElementFactory; +import org.jetbrains.jps.model.JpsModel; +import org.jetbrains.jps.model.artifact.JpsArtifact; +import org.jetbrains.jps.model.module.JpsModule; +import org.jetbrains.jps.model.serialization.JpsGlobalLoader; +import org.jetbrains.jps.model.serialization.JpsProjectLoader; + +import java.io.File; +import java.io.IOException; +import java.util.*; + +/** + * @author nik + */ +public class BuildRunner { + public static final String IDEA_PROJECT_DIRNAME = ".idea"; + private static final Logger LOG = Logger.getInstance("#org.jetbrains.jps.cmdline.BuildRunner"); + private final String myProjectPath; + // globals + private final Map myPathVars; + private final String myGlobalEncoding; + private final String myIgnorePatterns; + // build params + private final Set myModules; + private BuildType myBuildType; + private final List myArtifacts; + private final List myFilePaths; + private final Map myBuilderParams; + private final String myGlobalOptionsPath; + private boolean myForceCleanCaches; + private ParameterizedRunnable myModelInitializer; + + public BuildRunner(String projectPath, String globalOptionsPath, Map pathVars, + String globalEncoding, + String ignorePatterns, + Set modules, + BuildType buildType, + List artifacts, List filePaths, Map builderParams) { + myProjectPath = projectPath; + myGlobalOptionsPath = globalOptionsPath; + myPathVars = pathVars; + myGlobalEncoding = globalEncoding; + myIgnorePatterns = ignorePatterns; + myModules = modules; + myBuildType = buildType; + myArtifacts = artifacts; + myFilePaths = filePaths; + myBuilderParams = builderParams; + } + + public void setModelInitializer(ParameterizedRunnable modelInitializer) { + myModelInitializer = modelInitializer; + } + + public ProjectDescriptor load(MessageHandler msgHandler, File dataStorageRoot, BuildFSState fsState) throws IOException { + if (!dataStorageRoot.exists()) { + // invoked the very first time for this project. Force full rebuild + myBuildType = BuildType.PROJECT_REBUILD; + } + + final boolean inMemoryMappingsDelta = System.getProperty(GlobalOptions.USE_MEMORY_TEMP_CACHE_OPTION) != null; + ProjectTimestamps projectTimestamps = null; + BuildDataManager dataManager = null; + try { + projectTimestamps = new ProjectTimestamps(dataStorageRoot); + dataManager = new BuildDataManager(dataStorageRoot, inMemoryMappingsDelta); + if (dataManager.versionDiffers()) { + myForceCleanCaches = true; + msgHandler.processMessage(new CompilerMessage("build", BuildMessage.Kind.INFO, "Dependency data format has changed, project rebuild required")); + } + } + catch (Exception e) { + // second try + LOG.info(e); + if (projectTimestamps != null) { + projectTimestamps.close(); + } + if (dataManager != null) { + dataManager.close(); + } + myForceCleanCaches = true; + FileUtil.delete(dataStorageRoot); + projectTimestamps = new ProjectTimestamps(dataStorageRoot); + dataManager = new BuildDataManager(dataStorageRoot, inMemoryMappingsDelta); + // second attempt succeded + msgHandler.processMessage(new CompilerMessage("build", BuildMessage.Kind.INFO, "Project rebuild forced: " + e.getMessage())); + } + + final JpsModel jpsModel = loadJpsModel(); + final Project project = loadProject(); + return new ProjectDescriptor(project, jpsModel, fsState, projectTimestamps, dataManager, BuildLoggingManager.DEFAULT); + } + + private JpsModel loadJpsModel() { + final long start = System.currentTimeMillis(); + try { + final JpsModel model = JpsElementFactory.getInstance().createModel(); + try { + if (myGlobalOptionsPath != null) { + JpsGlobalLoader.loadGlobalSettings(model.getGlobal(), myPathVars, myGlobalOptionsPath); + } + JpsProjectLoader.loadProject(model.getProject(), myPathVars, myProjectPath); + if (myModelInitializer != null) { + myModelInitializer.run(model); + } + LOG.info("New JPS model: " + model.getProject().getModules().size() + " modules, " + model.getProject().getLibraryCollection().getLibraries().size() + " libraries"); + } + catch (IOException e) { + LOG.info(e); + } + return model; + } + finally { + final long loadTime = System.currentTimeMillis() - start; + LOG.info("New JPS model: project " + myProjectPath + " loaded in " + loadTime + " ms"); + } + } + + private Project loadProject() { + final long start = System.currentTimeMillis(); + try { + final Project project = new Project(); + + final File projectFile = new File(myProjectPath); + + final String loadPath = isDirectoryBased(projectFile) ? new File(projectFile, IDEA_PROJECT_DIRNAME).getPath() : myProjectPath; + IdeaProjectLoader.loadFromPath(project, loadPath, myPathVars, null, new SystemOutErrorReporter(false)); + final String globalEncoding = myGlobalEncoding; + if (!StringUtil.isEmpty(globalEncoding) && project.getProjectCharset() == null) { + project.setProjectCharset(globalEncoding); + } + project.getIgnoredFilePatterns().loadFromString(myIgnorePatterns); + return project; + } + finally { + final long loadTime = System.currentTimeMillis() - start; + LOG.info("Project " + myProjectPath + " loaded in " + loadTime + " ms"); + } + } + + public void runBuild(ProjectDescriptor pd, CanceledStatus cs, @Nullable Callbacks.ConstantAffectionResolver constantSearch, + MessageHandler msgHandler) throws Exception { + for (int attempt = 0; attempt < 2; attempt++) { + if (myForceCleanCaches && myModules.isEmpty() && myFilePaths.isEmpty()) { + // if compilation scope is the whole project and cache rebuild is forced, use PROJECT_REBUILD for faster compilation + myBuildType = BuildType.PROJECT_REBUILD; + } + + final CompileScope compileScope = createCompilationScope(myBuildType, pd, myModules, myArtifacts, myFilePaths); + final IncProjectBuilder builder = new IncProjectBuilder(pd, BuilderRegistry.getInstance(), myBuilderParams, cs, constantSearch); + builder.addMessageHandler(msgHandler); + try { + switch (myBuildType) { + case PROJECT_REBUILD: + builder.build(compileScope, false, true, myForceCleanCaches); + break; + + case FORCED_COMPILATION: + builder.build(compileScope, false, false, myForceCleanCaches); + break; + + case MAKE: + builder.build(compileScope, true, false, myForceCleanCaches); + break; + + case CLEAN: + //todo[nik] + // new ProjectBuilder(new GantBinding(), project).clean(); + break; + } + break; // break attempts loop + } + catch (RebuildRequestedException e) { + if (attempt == 0) { + LOG.info(e); + myForceCleanCaches = true; + } + else { + throw e; + } + } + } + } + + public BuildType getBuildType() { + return myBuildType; + } + + private static boolean isDirectoryBased(File projectFile) { + return !(projectFile.isFile() && projectFile.getName().endsWith(".ipr")); + } + + private static CompileScope createCompilationScope(BuildType buildType, + ProjectDescriptor pd, + Set modules, + Collection artifactNames, + Collection paths) throws Exception { + final Timestamps timestamps = pd.timestamps.getStorage(); + Set artifacts = new HashSet(); + if (artifactNames.isEmpty() && buildType == BuildType.PROJECT_REBUILD) { + artifacts.addAll(JpsBuilderArtifactService.getInstance().getArtifacts(pd.jpsModel, false)); + } + else { + for (JpsArtifact artifact : JpsBuilderArtifactService.getInstance().getArtifacts(pd.jpsModel, false)) { + if (artifactNames.contains(artifact.getName()) && !StringUtil.isEmpty(artifact.getOutputPath())) { + artifacts.add(artifact); + } + } + } + + final CompileScope compileScope; + if (buildType == BuildType.PROJECT_REBUILD || (modules.isEmpty() && paths.isEmpty())) { + compileScope = new AllProjectScope(pd.project, pd.jpsProject, artifacts, buildType != BuildType.MAKE); + } + else { + final Set forcedModules; + if (!modules.isEmpty()) { + forcedModules = new HashSet(); + for (JpsModule m : pd.jpsProject.getModules()) { + if (modules.contains(m.getName())) { + forcedModules.add(m); + } + } + } + else { + forcedModules = Collections.emptySet(); + } + + final Map> filesToCompile; + if (!paths.isEmpty()) { + filesToCompile = new HashMap>(); + for (String path : paths) { + final File file = new File(path); + final RootDescriptor rd = pd.rootsIndex.getModuleAndRoot(null, file); + if (rd != null) { + Set files = filesToCompile.get(rd.module); + if (files == null) { + files = new HashSet(); + filesToCompile.put(rd.module, files); + } + files.add(file); + if (buildType == BuildType.FORCED_COMPILATION) { + pd.fsState.markDirty(null, file, rd, timestamps); + } + } + } + } + else { + filesToCompile = Collections.emptyMap(); + } + + if (filesToCompile.isEmpty()) { + compileScope = new ModulesScope(pd.project, pd.jpsProject, forcedModules, artifacts, buildType != BuildType.MAKE); + } + else { + compileScope = new ModulesAndFilesScope(pd.project, pd.jpsProject, forcedModules, filesToCompile, artifacts, buildType != BuildType.MAKE); + } + } + return compileScope; + } +} 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 0f8c5ceb01c8..3274384d6cce 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/cmdline/BuildSession.java +++ b/jps/jps-builders/src/org/jetbrains/jps/cmdline/BuildSession.java @@ -5,32 +5,20 @@ import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.Ref; import com.intellij.openapi.util.io.BufferExposingByteArrayOutputStream; import com.intellij.openapi.util.io.FileUtil; -import com.intellij.openapi.util.text.StringUtil; import com.intellij.util.io.DataOutputStream; import org.jboss.netty.channel.Channel; import org.jboss.netty.channel.Channels; import org.jetbrains.annotations.Nullable; import org.jetbrains.ether.dependencyView.Callbacks; -import org.jetbrains.jps.Project; import org.jetbrains.jps.api.*; -import org.jetbrains.jps.idea.IdeaProjectLoader; -import org.jetbrains.jps.idea.SystemOutErrorReporter; -import org.jetbrains.jps.incremental.*; +import org.jetbrains.jps.incremental.MessageHandler; +import org.jetbrains.jps.incremental.Utils; import org.jetbrains.jps.incremental.artifacts.ArtifactSourceTimestampStorage; -import org.jetbrains.jps.incremental.artifacts.JpsBuilderArtifactService; import org.jetbrains.jps.incremental.artifacts.instructions.ArtifactRootDescriptor; import org.jetbrains.jps.incremental.fs.BuildFSState; import org.jetbrains.jps.incremental.fs.RootDescriptor; import org.jetbrains.jps.incremental.messages.*; -import org.jetbrains.jps.incremental.storage.BuildDataManager; -import org.jetbrains.jps.incremental.storage.ProjectTimestamps; import org.jetbrains.jps.incremental.storage.Timestamps; -import org.jetbrains.jps.model.JpsElementFactory; -import org.jetbrains.jps.model.JpsModel; -import org.jetbrains.jps.model.artifact.JpsArtifact; -import org.jetbrains.jps.model.module.JpsModule; -import org.jetbrains.jps.model.serialization.JpsGlobalLoader; -import org.jetbrains.jps.model.serialization.JpsProjectLoader; import java.io.*; import java.util.*; @@ -46,21 +34,10 @@ import java.util.concurrent.atomic.AtomicBoolean; */ final class BuildSession implements Runnable, CanceledStatus { private static final Logger LOG = Logger.getInstance("#org.jetbrains.jps.cmdline.BuildSession"); - public static final String IDEA_PROJECT_DIRNAME = ".idea"; private static final String FS_STATE_FILE = "fs_state.dat"; private final UUID mySessionId; private final Channel myChannel; private volatile boolean myCanceled = false; - // globals - private final Map myPathVars; - private final String myGlobalEncoding; - private final String myIgnorePatterns; - // build params - private final BuildType myBuildType; - private final Set myModules; - private final List myArtifacts; - private final List myFilePaths; - private final Map myBuilderParams; private String myProjectPath; @Nullable private CmdlineRemoteProto.Message.ControllerMessage.FSEvent myInitialFSDelta; @@ -70,8 +47,7 @@ final class BuildSession implements Runnable, CanceledStatus { private volatile ProjectDescriptor myProjectDescriptor; private final Map, ConstantSearchFuture> mySearchTasks = Collections.synchronizedMap(new HashMap, ConstantSearchFuture>()); private final ConstantSearch myConstantSearch = new ConstantSearch(); - private final String myGlobalOptiosnPath; - + private final BuildRunner myBuildRunner; BuildSession(UUID sessionId, Channel channel, @@ -81,26 +57,27 @@ final class BuildSession implements Runnable, CanceledStatus { myChannel = channel; // globals - myPathVars = new HashMap(); + Map pathVars = new HashMap(); final CmdlineRemoteProto.Message.ControllerMessage.GlobalSettings globals = params.getGlobalSettings(); for (CmdlineRemoteProto.Message.KeyValuePair variable : globals.getPathVariableList()) { - myPathVars.put(variable.getKey(), variable.getValue()); + pathVars.put(variable.getKey(), variable.getValue()); } - myGlobalEncoding = globals.hasGlobalEncoding()? globals.getGlobalEncoding() : null; - myIgnorePatterns = globals.hasIgnoredFilesPatterns()? globals.getIgnoredFilesPatterns() : null; + String globalEncoding = globals.hasGlobalEncoding() ? globals.getGlobalEncoding() : null; + String ignorePatterns = globals.hasIgnoredFilesPatterns() ? globals.getIgnoredFilesPatterns() : null; // session params myProjectPath = FileUtil.toCanonicalPath(params.getProjectId()); - myGlobalOptiosnPath = FileUtil.toCanonicalPath(globals.getGlobalOptionsPath()); - myBuildType = convertCompileType(params.getBuildType()); - myModules = new HashSet(params.getModuleNameList()); - myArtifacts = params.getArtifactNameList(); - myFilePaths = params.getFilePathList(); - myBuilderParams = new HashMap(); + String globalOptionsPath = FileUtil.toCanonicalPath(globals.getGlobalOptionsPath()); + BuildType myBuildType = convertCompileType(params.getBuildType()); + Set modules = new HashSet(params.getModuleNameList()); + List artifacts = params.getArtifactNameList(); + List filePaths = params.getFilePathList(); + Map builderParams = new HashMap(); for (CmdlineRemoteProto.Message.KeyValuePair pair : params.getBuilderParameterList()) { - myBuilderParams.put(pair.getKey(), pair.getValue()); + builderParams.put(pair.getKey(), pair.getValue()); } myInitialFSDelta = delta; + myBuildRunner = new BuildRunner(myProjectPath, globalOptionsPath, pathVars, globalEncoding, ignorePatterns, modules, myBuildType, artifacts, filePaths, builderParams); } public void run() { @@ -108,7 +85,7 @@ final class BuildSession implements Runnable, CanceledStatus { final Ref hasErrors = new Ref(false); final Ref markedFilesUptodate = new Ref(false); try { - runBuild(myBuildType, myModules, myArtifacts, myBuilderParams, myFilePaths, new MessageHandler() { + runBuild(new MessageHandler() { public void processMessage(BuildMessage buildMessage) { final CmdlineRemoteProto.Message.BuilderMessage response; if (buildMessage instanceof FileGeneratedEvent) { @@ -155,10 +132,7 @@ final class BuildSession implements Runnable, CanceledStatus { } } - private void runBuild(BuildType buildType, Set modules, Collection artifacts, Map builderParams, - Collection paths, final MessageHandler msgHandler, CanceledStatus cs) throws Throwable{ - boolean forceCleanCaches = false; - + private void runBuild(final MessageHandler msgHandler, CanceledStatus cs) throws Throwable{ final File dataStorageRoot = Utils.getDataStorageRoot(myProjectPath); if (dataStorageRoot == null) { msgHandler.processMessage(new CompilerMessage("build", BuildMessage.Kind.ERROR, "Cannot determine build data storage root for project " + @@ -169,49 +143,14 @@ final class BuildSession implements Runnable, CanceledStatus { try { final boolean shouldApplyEvent = loadFsState(fsState, dataStorageRoot, myInitialFSDelta); - if (shouldApplyEvent && buildType == BuildType.MAKE && !containsChanges(myInitialFSDelta) && !fsState.hasWorkToDo()) { + if (shouldApplyEvent && myBuildRunner.getBuildType() == BuildType.MAKE && !containsChanges(myInitialFSDelta) && !fsState.hasWorkToDo()) { applyFSEvent(null, myInitialFSDelta); return; } - if (!dataStorageRoot.exists()) { - // invoked the very first time for this project. Force full rebuild - buildType = BuildType.PROJECT_REBUILD; - } - - final boolean inMemoryMappingsDelta = System.getProperty(GlobalOptions.USE_MEMORY_TEMP_CACHE_OPTION) != null; - ProjectTimestamps projectTimestamps = null; - BuildDataManager dataManager = null; - try { - projectTimestamps = new ProjectTimestamps(dataStorageRoot); - dataManager = new BuildDataManager(dataStorageRoot, inMemoryMappingsDelta); - if (dataManager.versionDiffers()) { - forceCleanCaches = true; - msgHandler.processMessage(new CompilerMessage("build", BuildMessage.Kind.INFO, "Dependency data format has changed, project rebuild required")); - } - } - catch (Exception e) { - // second try - LOG.info(e); - if (projectTimestamps != null) { - projectTimestamps.close(); - } - if (dataManager != null) { - dataManager.close(); - } - forceCleanCaches = true; - FileUtil.delete(dataStorageRoot); - projectTimestamps = new ProjectTimestamps(dataStorageRoot); - dataManager = new BuildDataManager(dataStorageRoot, inMemoryMappingsDelta); - // second attempt succeded - msgHandler.processMessage(new CompilerMessage("build", BuildMessage.Kind.INFO, "Project rebuild forced: " + e.getMessage())); - } - - final JpsModel jpsModel = loadJpsModel(); - final Project project = loadProject(); - final ProjectDescriptor pd = new ProjectDescriptor(project, jpsModel, fsState, projectTimestamps, dataManager, BuildLoggingManager.DEFAULT); + ProjectDescriptor pd = myBuildRunner.load(msgHandler, dataStorageRoot, fsState); myProjectDescriptor = pd; if (shouldApplyEvent) { - applyFSEvent(pd, myInitialFSDelta); + applyFSEvent(myProjectDescriptor, myInitialFSDelta); } @@ -220,46 +159,7 @@ final class BuildSession implements Runnable, CanceledStatus { // ensure events from controller are processed after FSState initialization myEventsProcessor.startProcessing(); - for (int attempt = 0; attempt < 2; attempt++) { - if (forceCleanCaches && modules.isEmpty() && paths.isEmpty()) { - // if compilation scope is the whole project and cache rebuild is forced, use PROJECT_REBUILD for faster compilation - buildType = BuildType.PROJECT_REBUILD; - } - - final CompileScope compileScope = createCompilationScope(buildType, pd, modules, artifacts, paths); - final IncProjectBuilder builder = new IncProjectBuilder(pd, BuilderRegistry.getInstance(), builderParams, cs, myConstantSearch); - builder.addMessageHandler(msgHandler); - try { - switch (buildType) { - case PROJECT_REBUILD: - builder.build(compileScope, false, true, forceCleanCaches); - break; - - case FORCED_COMPILATION: - builder.build(compileScope, false, false, forceCleanCaches); - break; - - case MAKE: - builder.build(compileScope, true, false, forceCleanCaches); - break; - - case CLEAN: - //todo[nik] - // new ProjectBuilder(new GantBinding(), project).clean(); - break; - } - break; // break attempts loop - } - catch (RebuildRequestedException e) { - if (attempt == 0) { - LOG.info(e); - forceCleanCaches = true; - } - else { - throw e; - } - } - } + myBuildRunner.runBuild(pd, cs, myConstantSearch, msgHandler); } finally { saveData(fsState, dataStorageRoot); @@ -514,122 +414,6 @@ final class BuildSession implements Runnable, CanceledStatus { return myCanceled; } - private JpsModel loadJpsModel() { - final long start = System.currentTimeMillis(); - try { - final JpsModel model = JpsElementFactory.getInstance().createModel(); - try { - JpsGlobalLoader.loadGlobalSettings(model.getGlobal(), myPathVars, myGlobalOptiosnPath); - JpsProjectLoader.loadProject(model.getProject(), myPathVars, myProjectPath); - LOG.info("New JPS model: " + model.getProject().getModules().size() + " modules, " + model.getProject().getLibraryCollection().getLibraries().size() + " libraries"); - } - catch (IOException e) { - LOG.info(e); - } - return model; - } - finally { - final long loadTime = System.currentTimeMillis() - start; - LOG.info("New JPS model: project " + myProjectPath + " loaded in " + loadTime + " ms"); - } - } - - private Project loadProject() { - final long start = System.currentTimeMillis(); - try { - final Project project = new Project(); - - final File projectFile = new File(myProjectPath); - - final String loadPath = isDirectoryBased(projectFile) ? new File(projectFile, IDEA_PROJECT_DIRNAME).getPath() : myProjectPath; - IdeaProjectLoader.loadFromPath(project, loadPath, myPathVars, null, new SystemOutErrorReporter(false)); - final String globalEncoding = myGlobalEncoding; - if (!StringUtil.isEmpty(globalEncoding) && project.getProjectCharset() == null) { - project.setProjectCharset(globalEncoding); - } - project.getIgnoredFilePatterns().loadFromString(myIgnorePatterns); - return project; - } - finally { - final long loadTime = System.currentTimeMillis() - start; - LOG.info("Project " + myProjectPath + " loaded in " + loadTime + " ms"); - } - } - - private static boolean isDirectoryBased(File projectFile) { - return !(projectFile.isFile() && projectFile.getName().endsWith(".ipr")); - } - - private static CompileScope createCompilationScope(BuildType buildType, - ProjectDescriptor pd, - Set modules, - Collection artifactNames, - Collection paths) throws Exception { - final Timestamps timestamps = pd.timestamps.getStorage(); - Set artifacts = new HashSet(); - if (artifactNames.isEmpty() && buildType == BuildType.PROJECT_REBUILD) { - artifacts.addAll(JpsBuilderArtifactService.getInstance().getArtifacts(pd.jpsModel, false)); - } - else { - for (JpsArtifact artifact : JpsBuilderArtifactService.getInstance().getArtifacts(pd.jpsModel, false)) { - if (artifactNames.contains(artifact.getName()) && !StringUtil.isEmpty(artifact.getOutputPath())) { - artifacts.add(artifact); - } - } - } - - final CompileScope compileScope; - if (buildType == BuildType.PROJECT_REBUILD || (modules.isEmpty() && paths.isEmpty())) { - compileScope = new AllProjectScope(pd.project, pd.jpsProject, artifacts, buildType != BuildType.MAKE); - } - else { - final Set forcedModules; - if (!modules.isEmpty()) { - forcedModules = new HashSet(); - for (JpsModule m : pd.jpsProject.getModules()) { - if (modules.contains(m.getName())) { - forcedModules.add(m); - } - } - } - else { - forcedModules = Collections.emptySet(); - } - - final Map> filesToCompile; - if (!paths.isEmpty()) { - filesToCompile = new HashMap>(); - for (String path : paths) { - final File file = new File(path); - final RootDescriptor rd = pd.rootsIndex.getModuleAndRoot(null, file); - if (rd != null) { - Set files = filesToCompile.get(rd.module); - if (files == null) { - files = new HashSet(); - filesToCompile.put(rd.module, files); - } - files.add(file); - if (buildType == BuildType.FORCED_COMPILATION) { - pd.fsState.markDirty(null, file, rd, timestamps); - } - } - } - } - else { - filesToCompile = Collections.emptyMap(); - } - - if (filesToCompile.isEmpty()) { - compileScope = new ModulesScope(pd.project, pd.jpsProject, forcedModules, artifacts, buildType != BuildType.MAKE); - } - else { - compileScope = new ModulesAndFilesScope(pd.project, pd.jpsProject, forcedModules, filesToCompile, artifacts, buildType != BuildType.MAKE); - } - } - return compileScope; - } - - private static BuildType convertCompileType(CmdlineRemoteProto.Message.ControllerMessage.ParametersMessage.Type compileType) { switch (compileType) { case CLEAN: return BuildType.CLEAN; 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 ae47e67808ae..113304cf9b38 100644 --- a/jps/jps-builders/testSrc/org/jetbrains/jps/builders/JpsBuildTestCase.java +++ b/jps/jps-builders/testSrc/org/jetbrains/jps/builders/JpsBuildTestCase.java @@ -64,8 +64,7 @@ public abstract class JpsBuildTestCase extends UsefulTestCase { protected JpsSdk initJdk(final String name, final String path) { String homePath = System.getProperty("java.home"); String versionString = System.getProperty("java.version"); - JpsTypedLibrary> jdk = myModel.getGlobal().addSdk(name, homePath, versionString, JpsJavaSdkType.INSTANCE, - JpsElementFactory.getInstance().createDummyElement()); + JpsTypedLibrary> jdk = myModel.getGlobal().addSdk(name, homePath, versionString, JpsJavaSdkType.INSTANCE); jdk.addRoot(JpsPathUtil.pathToUrl(path), JpsOrderRootType.COMPILED); return jdk.getProperties(); } diff --git a/jps/model-api/src/org/jetbrains/jps/model/JpsGlobal.java b/jps/model-api/src/org/jetbrains/jps/model/JpsGlobal.java index bf197f154c02..bef3d0d8603f 100644 --- a/jps/model-api/src/org/jetbrains/jps/model/JpsGlobal.java +++ b/jps/model-api/src/org/jetbrains/jps/model/JpsGlobal.java @@ -14,6 +14,9 @@ public interface JpsGlobal extends JpsCompositeElement, JpsReferenceableElement<

& JpsElementTypeWithDefaultProperties

> JpsLibrary addLibrary(@NotNull LibraryType libraryType, final @NotNull String name); +

& JpsElementTypeWithDefaultProperties

> + JpsTypedLibrary> addSdk(@NotNull String name, @Nullable String homePath, @Nullable String versionString, @NotNull SdkType type); +

JpsTypedLibrary> addSdk(@NotNull String name, @Nullable String homePath, @Nullable String versionString, @NotNull JpsSdkType

type, @NotNull P properties); diff --git a/jps/model-api/src/org/jetbrains/jps/model/java/JpsJavaSdkType.java b/jps/model-api/src/org/jetbrains/jps/model/java/JpsJavaSdkType.java index 6b4aba1f0112..d934f125c9e4 100644 --- a/jps/model-api/src/org/jetbrains/jps/model/java/JpsJavaSdkType.java +++ b/jps/model-api/src/org/jetbrains/jps/model/java/JpsJavaSdkType.java @@ -1,15 +1,24 @@ package org.jetbrains.jps.model.java; +import org.jetbrains.annotations.NotNull; import org.jetbrains.jps.model.JpsDummyElement; +import org.jetbrains.jps.model.JpsElementFactory; +import org.jetbrains.jps.model.JpsElementTypeWithDefaultProperties; import org.jetbrains.jps.model.library.sdk.JpsSdkType; import org.jetbrains.jps.model.library.sdk.JpsSdk; /** * @author nik */ -public class JpsJavaSdkType extends JpsSdkType { +public class JpsJavaSdkType extends JpsSdkType implements JpsElementTypeWithDefaultProperties { public static final JpsJavaSdkType INSTANCE = new JpsJavaSdkType(); + @NotNull + @Override + public JpsDummyElement createDefaultProperties() { + return JpsElementFactory.getInstance().createDummyElement(); + } + public static String getJavaExecutable(JpsSdk sdk) { return sdk.getHomePath() + "/bin/java"; } diff --git a/jps/model-impl/src/org/jetbrains/jps/model/impl/JpsGlobalImpl.java b/jps/model-impl/src/org/jetbrains/jps/model/impl/JpsGlobalImpl.java index 71fca3024c85..9cddc57c3b31 100644 --- a/jps/model-impl/src/org/jetbrains/jps/model/impl/JpsGlobalImpl.java +++ b/jps/model-impl/src/org/jetbrains/jps/model/impl/JpsGlobalImpl.java @@ -42,6 +42,12 @@ public class JpsGlobalImpl extends JpsRootElementBase implements return sdk; } + @Override + public

& JpsElementTypeWithDefaultProperties

> JpsTypedLibrary> + addSdk(@NotNull String name, @Nullable String homePath, @Nullable String versionString, @NotNull SdkType type) { + return addSdk(name, homePath, versionString, type, type.createDefaultProperties()); + } + @NotNull @Override public JpsLibraryCollection getLibraryCollection() { diff --git a/jps/model-impl/testSrc/org/jetbrains/jps/model/JpsModuleTest.java b/jps/model-impl/testSrc/org/jetbrains/jps/model/JpsModuleTest.java index a98400a89c39..c4a52de241da 100644 --- a/jps/model-impl/testSrc/org/jetbrains/jps/model/JpsModuleTest.java +++ b/jps/model-impl/testSrc/org/jetbrains/jps/model/JpsModuleTest.java @@ -105,7 +105,7 @@ public class JpsModuleTest extends JpsModelTestCase { } public void testSdkDependency() { - JpsSdk sdk = myModel.getGlobal().addSdk("sdk", null, null, JpsJavaSdkType.INSTANCE, JpsElementFactory.getInstance().createDummyElement()).getProperties(); + JpsSdk sdk = myModel.getGlobal().addSdk("sdk", null, null, JpsJavaSdkType.INSTANCE).getProperties(); final JpsModule module = myModel.getProject().addModule("m", JpsJavaModuleType.INSTANCE); module.getSdkReferencesTable().setSdkReference(JpsJavaSdkType.INSTANCE, sdk.createReference()); module.getDependenciesList().addSdkDependency(JpsJavaSdkType.INSTANCE); diff --git a/jps/standalone-builder/jps-standalone-builder.iml b/jps/standalone-builder/jps-standalone-builder.iml new file mode 100644 index 000000000000..0642d526888b --- /dev/null +++ b/jps/standalone-builder/jps-standalone-builder.iml @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + +