diff --git a/Changelog.txt b/Changelog.txt index 802c949..54c68c4 100644 --- a/Changelog.txt +++ b/Changelog.txt @@ -1,13 +1,21 @@ cmvn-0.1.2: -* Fixed: Errors while parsing pom.xml.cmvn are silently dropped and - all content of template file is ignored further +* Fixed: Errors while parsing pom.xml.cmvn are silently dropped and all + content of template file is ignored further * Let user specifiy Maven executable (--maven-bin) * cmvn-0.1.1 looses configured state in some situations -* Also respect classifier when (distinct) comparing dependencies so - that it is possible to include same GA with different classifier in - dependency list (e.g. a normal jar and the tests-jar) +* Also respect classifier when (distinct) comparing dependencies so that it is + possible to include same GA with different classifier in dependency list + (e.g. a normal jar and the tests-jar) * Improved ivy.xml and ivysettings.xml generation * Experimental support for forced system-scope dependencies +* Experimental support for systen-scoped dependency to local available + artifacts, thus making the 'install' goal of maven unneccessary (using the + 'package' goal is now equal and better) +* New default: --auto-regenerate +* Regenerating a sub-module does not change state outside of this + module/directory +* Added new build option --build-from-root to start Maven always from root + project with the complete reactor (alowing to use -am and -amd options) cmvn-0.1.1: * Generated files now have correct default XML namespace set diff --git a/de.tototec.tools.cmvn/src/main/java/de/tototec/tools/cmvn/CmvnApp.java b/de.tototec.tools.cmvn/src/main/java/de/tototec/tools/cmvn/CmvnApp.java index 9394a1c..3386a7f 100644 --- a/de.tototec.tools.cmvn/src/main/java/de/tototec/tools/cmvn/CmvnApp.java +++ b/de.tototec.tools.cmvn/src/main/java/de/tototec/tools/cmvn/CmvnApp.java @@ -103,7 +103,7 @@ public void run(final String[] args) { // Configure mode boolean runConfigure = false; boolean forceGenerate = false; - boolean autoReconfigure = false; + boolean autoReconfigure = true; final String[] mavenSettingsFile = new String[1]; final String[] mavenRepoDir = new String[1]; final String[] mavenBin = new String[1]; @@ -111,6 +111,8 @@ public void run(final String[] args) { // Experimental boolean generateIvyFiles = false; boolean forceSystemScope = false; + boolean localArtifactsAsSystemScope = false; + boolean buildFromRootProject = false; NextArgAction nextArgAction = null; @@ -162,6 +164,10 @@ public void run(final String[] args) { runMaven = true; } else if (arg.equals("--force-system-scope")) { forceSystemScope = true; + } else if (arg.equals("--local-artifacts-as-system-scope")) { + localArtifactsAsSystemScope = true; + } else if (arg.equals("--build-from-root")) { + buildFromRootProject = true; } else if (arg.equals("--maven-bin")) { nextArgAction = new NextArgAction() { @Override @@ -205,7 +211,23 @@ public NextArgAction processArg(final String arg) { throw new RuntimeException("Invalid arguments in --configure mode: " + mavenArgs); } - final CmvnProject project = new CmvnProject(new File(System.getProperty("user.dir"))); + final File currentProjectDir = new File(System.getProperty("user.dir")); + CmvnProject projectCandidate = new CmvnProject(currentProjectDir); + File mvnExecDir = null; + String subDir = null; + if (buildFromRootProject) { + final String rootProjectFilePath = projectCandidate.getConfiguredState().getRootProjectFile(); + final File rootProjectFile = new File(rootProjectFilePath); + if (currentProjectDir.getAbsolutePath().startsWith(rootProjectFile.getParentFile().getAbsolutePath())) { + final int index = rootProjectFile.getParentFile().getAbsolutePath().length(); + subDir = currentProjectDir.getAbsolutePath().substring(index); + } + if (subDir != null && subDir.length() > 0) { + mvnExecDir = rootProjectFile.getParentFile(); + projectCandidate = new CmvnProject(rootProjectFile); + } + } + final CmvnProject project = projectCandidate; final boolean upToDate = project.isUpToDateRecursive(); System.out.println("Project up-to-date: " + upToDate); @@ -243,6 +265,7 @@ public NextArgAction processArg(final String arg) { } if (regenerate) { + if (!upToDate || forceGenerate) { System.out.println("Reconfiguring..."); @@ -290,6 +313,8 @@ public NextArgAction processArg(final String arg) { configureRequest.setMavenExecutable(file.getPath()); } configureRequest.setForceSystemScope(forceSystemScope); + configureRequest.setSystemScopeForLocalProjects(localArtifactsAsSystemScope); + project.configureProjectRecursive(configureRequest); } @@ -313,6 +338,11 @@ public NextArgAction processArg(final String arg) { // } final ProcessBuilder pB = new ProcessBuilder(mvnArgs); + if (buildFromRootProject && mvnExecDir != null && subDir != null) { + pB.directory(mvnExecDir); + mvnArgs.add(3, "-pl"); + mvnArgs.add(4, subDir); + } Process process = null; Thread outThread = null; try { @@ -377,6 +407,7 @@ private void printUsage() { help += "Mode:\n"; help += " --build Enables BUILD mode\n"; help += " --configure Enables CONFIGURE mode\n"; + help += " --regenerate Enables REGENERATE mode. Regenerate all files with same config\n"; help += " --clean Enables CLEAN mode\n"; help += " --distclean Enables DISTCLEAN mode\n"; help += "\n"; @@ -384,15 +415,17 @@ private void printUsage() { help += " --auto-regenerate (Deprecated) Same as --auto-reconfigure\n"; help += " --auto-reconfigure Enable automatic reconfiguration for out-of-date files\n"; help += " --force Configure and generate all files\n"; + help += " --generate-ivy (Experimental) Generate ivy.xml and ivysettings.xml\n"; help += " --maven-repo DIR Use the given (existing) directory DIR as local Maven repository\n"; help += " --maven-settings FILE Use the following Maven settings file (may result in unrepeatable builds)\n"; help += " --maven-bin FILE Use the given Maven executable (instead of 'mvn')\n"; - help += " --generate-ivy Generate ivy.xml and ivysettings.xml\n"; - help += " --force-system-scope Forces all dependencies to be of system scope (in pom.xml)\n"; + help += " --force-system-scope (Experimental) Forces all dependencies to be of system scope (in pom.xml)\n"; + help += " --local-artifacts-as-system-scope (Experimental) Convert dependencies to local artifact to system-scope dependenies\n"; help += "\n"; help += "Options for BUILD mode:\n"; - help += " --regenerate Automatically reconfigure if some source files are out-of-date\n"; - help += " --reconfigure (Deprecated) Same as --regenerate\n"; + help += " --build-from-root Run Maven from root project with additional '-pl '\n"; + help += " --regenerate Automatically reconfigure if some source files are out-of-date\n"; + help += " --reconfigure (Deprecated) Same as --regenerate\n"; help += "\n"; System.out.println(help); } diff --git a/de.tototec.tools.cmvn/src/main/java/de/tototec/tools/cmvn/CmvnConfigKey.java b/de.tototec.tools.cmvn/src/main/java/de/tototec/tools/cmvn/CmvnConfigKey.java index 709e1e4..a985d21 100644 --- a/de.tototec.tools.cmvn/src/main/java/de/tototec/tools/cmvn/CmvnConfigKey.java +++ b/de.tototec.tools.cmvn/src/main/java/de/tototec/tools/cmvn/CmvnConfigKey.java @@ -7,11 +7,11 @@ import de.tototec.tools.cmvn.configfile.KeyValue; import de.tototec.tools.cmvn.configfile.KeyValueWithOptions; import de.tototec.tools.cmvn.model.Build; +import de.tototec.tools.cmvn.model.CmvnProjectConfig; import de.tototec.tools.cmvn.model.ConfigClassGenerator; import de.tototec.tools.cmvn.model.Dependency; import de.tototec.tools.cmvn.model.Module; import de.tototec.tools.cmvn.model.Plugin; -import de.tototec.tools.cmvn.model.CmvnProjectConfig; import de.tototec.tools.cmvn.model.Repository; public enum CmvnConfigKey implements ProjectConfigKeyValueReader { diff --git a/de.tototec.tools.cmvn/src/main/java/de/tototec/tools/cmvn/CmvnConfiguredState.java b/de.tototec.tools.cmvn/src/main/java/de/tototec/tools/cmvn/CmvnConfiguredState.java index d25a116..3970df2 100644 --- a/de.tototec.tools.cmvn/src/main/java/de/tototec/tools/cmvn/CmvnConfiguredState.java +++ b/de.tototec.tools.cmvn/src/main/java/de/tototec/tools/cmvn/CmvnConfiguredState.java @@ -13,4 +13,5 @@ public class CmvnConfiguredState { private boolean forceSystemScope; private String mavenExecutable; private boolean generateIvy; + private boolean referenceLocalArtifactsAsSystemScope; } diff --git a/de.tototec.tools.cmvn/src/main/java/de/tototec/tools/cmvn/CmvnConfiguredStateFile.java b/de.tototec.tools.cmvn/src/main/java/de/tototec/tools/cmvn/CmvnConfiguredStateFile.java index 2243f9c..0f4a7cb 100644 --- a/de.tototec.tools.cmvn/src/main/java/de/tototec/tools/cmvn/CmvnConfiguredStateFile.java +++ b/de.tototec.tools.cmvn/src/main/java/de/tototec/tools/cmvn/CmvnConfiguredStateFile.java @@ -48,6 +48,8 @@ public CmvnConfiguredState read() throws FileNotFoundException { config.setMavenExecutable(value); } else if (key.equals("generateIvy")) { config.setGenerateIvy(value.equals("true")); + } else if (key.equals("referenceLocalArtifactsAsSystemScope")) { + config.setReferenceLocalArtifactsAsSystemScope(value.equals("true")); } else { System.out.println("Unknown config option found: " + keyValue); } @@ -80,6 +82,8 @@ public void write(final CmvnConfiguredState cmvnConfiguredState) throws FileNotF } configWriter.append("generateIvy: ").append(cmvnConfiguredState.isGenerateIvy() ? "true" : "false") .append("\n"); + configWriter.append("referenceLocalArtifactsAsSystemScope: ") + .append(cmvnConfiguredState.isReferenceLocalArtifactsAsSystemScope() ? "true" : "false").append("\n"); configWriter.close(); } diff --git a/de.tototec.tools.cmvn/src/main/java/de/tototec/tools/cmvn/CmvnProject.java b/de.tototec.tools.cmvn/src/main/java/de/tototec/tools/cmvn/CmvnProject.java index ce0216c..b988560 100644 --- a/de.tototec.tools.cmvn/src/main/java/de/tototec/tools/cmvn/CmvnProject.java +++ b/de.tototec.tools.cmvn/src/main/java/de/tototec/tools/cmvn/CmvnProject.java @@ -13,6 +13,7 @@ import de.tototec.tools.cmvn.configfile.KeyValue; import de.tototec.tools.cmvn.configfile.bndlike.ConfigFileReaderImpl; import de.tototec.tools.cmvn.model.ConfigClassGenerator; +import de.tototec.tools.cmvn.model.Dependency; import de.tototec.tools.cmvn.model.Module; import de.tototec.tools.cmvn.model.CmvnProjectConfig; @@ -304,32 +305,52 @@ protected void configureProject(final ConfigureRequest configureRequest) { if (configureRequest.getGenerateIvy() != null) { configuredState.setGenerateIvy(configureRequest.getGenerateIvy().booleanValue()); } + if (configureRequest.getSystemScopeForLocalProjects() != null) { + configuredState.setReferenceLocalArtifactsAsSystemScope(configureRequest + .getSystemScopeForLocalProjects().booleanValue()); + } } if (configuredState == null) { throw new RuntimeException("Internal Error: No configured state"); } + persistCmvnState(configuredState); + + // now generate files + generateProject(false); + } + + private void persistCmvnState(final CmvnConfiguredState configuredState) { // Persisting configured state try { new CmvnConfiguredStateFile(mavenConfigFile).write(configuredState); + this.configuredState = configuredState; } catch (final FileNotFoundException e) { throw new RuntimeException("Could not write maven config file: " + mavenConfigFile, e); } - - this.configuredState = configuredState; - - generateProject(false); } protected void generateProject(final boolean onlyIfChanged) { // we need an already persisted config - final CmvnConfiguredState cmvnConfig = getConfiguredState(); + CmvnConfiguredState cmvnConfig = getConfiguredState(); if (cmvnConfig == null) { - throw new RuntimeException( - "The project is not configured. Please configure it first (cmvn --configure). Project: " - + projectFile); + if (rootProject != null && rootProject.getConfiguredState() != null) { + // special case, the root project is not up-to-date because a + // new + // submodule was added. In this case we want it to beconfigured + // exactly as the root project + System.out.println("Configuring new project: " + projectFile); + + cmvnConfig = rootProject.getConfiguredState(); + persistCmvnState(cmvnConfig); + } else { + + throw new RuntimeException( + "The project is not configured. Please configure it first (cmvn --configure). Project: " + + projectFile); + } } if (onlyIfChanged && isUpToDate()) { @@ -344,6 +365,21 @@ protected void generateProject(final boolean onlyIfChanged) { // Generate Maven POM final MavenPomGenerator mavenPomGenerator = new MavenPomGenerator(pomFile, cmvnConfig, projectConfig); + if (cmvnConfig.isReferenceLocalArtifactsAsSystemScope()) { + System.out.println("Converting local artifacts to system scope..."); + final List localArtifacts = new LinkedList(); + final List localProjects = rootProject != null ? rootProject.getMultiProjects() + : getMultiProjects(); + for (final CmvnProject project : localProjects) { + final CmvnProjectConfig locProj = project.getProjectConfig(); + final Dependency locArtifact = new Dependency(locProj.getProject().getGroupId(), locProj.getProject() + .getArtifactId(), locProj.getProject().getVersion()); + locArtifact.setJarPath(new File(new File(locProj.getBaseDir(), "target"), locArtifact.getArtifactId() + + "-" + locArtifact.getVersion() + ".jar").getAbsolutePath()); + localArtifacts.add(locArtifact); + } + mavenPomGenerator.setLocalArtifacts(localArtifacts); + } mavenPomGenerator.generate(); // Generate Ivy diff --git a/de.tototec.tools.cmvn/src/main/java/de/tototec/tools/cmvn/Config.java b/de.tototec.tools.cmvn/src/main/java/de/tototec/tools/cmvn/Config.java index 45b37fd..f122cf1 100644 --- a/de.tototec.tools.cmvn/src/main/java/de/tototec/tools/cmvn/Config.java +++ b/de.tototec.tools.cmvn/src/main/java/de/tototec/tools/cmvn/Config.java @@ -1,6 +1,6 @@ package de.tototec.tools.cmvn; -// Class generated by cmvn-0.1.2-SNAPSHOT +// Class generated by cmvn-0.1.1 public abstract class Config { public static String cmvnVersion() { diff --git a/de.tototec.tools.cmvn/src/main/java/de/tototec/tools/cmvn/ConfigureRequest.java b/de.tototec.tools.cmvn/src/main/java/de/tototec/tools/cmvn/ConfigureRequest.java index f523a7d..d700ee8 100644 --- a/de.tototec.tools.cmvn/src/main/java/de/tototec/tools/cmvn/ConfigureRequest.java +++ b/de.tototec.tools.cmvn/src/main/java/de/tototec/tools/cmvn/ConfigureRequest.java @@ -10,5 +10,6 @@ public class ConfigureRequest { private String mavenRepo; private Boolean generateIvy; private Boolean forceSystemScope; + private Boolean systemScopeForLocalProjects; private String mavenExecutable; } diff --git a/de.tototec.tools.cmvn/src/main/java/de/tototec/tools/cmvn/MavenPomGenerator.java b/de.tototec.tools.cmvn/src/main/java/de/tototec/tools/cmvn/MavenPomGenerator.java index f623582..f662ccc 100644 --- a/de.tototec.tools.cmvn/src/main/java/de/tototec/tools/cmvn/MavenPomGenerator.java +++ b/de.tototec.tools.cmvn/src/main/java/de/tototec/tools/cmvn/MavenPomGenerator.java @@ -11,6 +11,8 @@ import java.util.Map; import java.util.Map.Entry; +import lombok.Setter; + import org.apache.maven.pom.x400.Build.Plugins; import org.apache.maven.pom.x400.Dependency.Exclusions; import org.apache.maven.pom.x400.DependencyManagement; @@ -29,10 +31,10 @@ import org.apache.xmlbeans.XmlOptions; import de.tototec.tools.cmvn.model.Build; +import de.tototec.tools.cmvn.model.CmvnProjectConfig; import de.tototec.tools.cmvn.model.Dependency; import de.tototec.tools.cmvn.model.Module; import de.tototec.tools.cmvn.model.Plugin; -import de.tototec.tools.cmvn.model.CmvnProjectConfig; import de.tototec.tools.cmvn.model.Repository; public class MavenPomGenerator { @@ -40,6 +42,8 @@ public class MavenPomGenerator { private final CmvnConfiguredState cmvnConfig; private final CmvnProjectConfig projectConfig; private final File pomFile; + @Setter + private List localArtifacts; public MavenPomGenerator(final File pomFile, final CmvnConfiguredState cmvnConfig, final CmvnProjectConfig projectConfig) { @@ -247,7 +251,7 @@ protected void generateMarkerComment(final Model mvn) { cursor.insertChars("\n"); cursor.insertComment(" DO NOT EDIT THIS FILE! "); cursor.insertChars("\n"); - cursor.insertComment(" Your changes might be lost next time emvn is run. "); + cursor.insertComment(" Your changes might be lost next time cmvn is run. "); cursor.insertChars("\n"); } @@ -468,13 +472,50 @@ protected void generateDependenciesBlock(final List dependencies, protected void generateDependencyBlock(final Dependency dep, final org.apache.maven.pom.x400.Dependency mvnDep, final boolean forceSystemScope) { + String scope = dep.getScope(); + String jarPath = dep.getJarPath(); + + if (forceSystemScope && !dep.getScope().equals("system")) { + scope = "system"; + // we need to evaluate a system path + File repoPath = new File(cmvnConfig.getLocalRepository()); + for (final String group : dep.getGroupId().split("\\.")) { + repoPath = new File(repoPath, group); + } + repoPath = new File(repoPath, dep.getArtifactId()); + repoPath = new File(repoPath, dep.getVersion()); + + final String classifier = dep.getClassifier() == null ? "" : "-" + dep.getClassifier(); + final String fileName = dep.getArtifactId() + classifier + "-" + dep.getVersion() + ".jar"; + + jarPath = new File(repoPath, fileName).getAbsolutePath(); + } + + if (cmvnConfig.isReferenceLocalArtifactsAsSystemScope() && localArtifacts != null + && !dep.getScope().equals("system")) { + // check if dep is local + for (final Dependency localDep : localArtifacts) { + if (dep.getGroupId().equals(localDep.getGroupId()) + && dep.getArtifactId().equals(localDep.getArtifactId()) + && dep.getVersion().equals(localDep.getVersion()) + && (dep.getClassifier() != null && dep.getClassifier().equals(localDep.getClassifier()) || dep + .getClassifier() == null && localDep.getClassifier() == null) + && localDep.getJarPath() != null) { + + // TODO: should we force conrete versions? Actually we do. + + scope = "system"; + jarPath = localDep.getJarPath(); + break; + } + } + } + mvnDep.setGroupId(dep.getGroupId()); mvnDep.setArtifactId(dep.getArtifactId()); mvnDep.setVersion(dep.getVersion()); - if (forceSystemScope) { - mvnDep.setScope("system"); - } else if (dep.getScope() != null) { - mvnDep.setScope(dep.getScope()); + if (scope != null) { + mvnDep.setScope(scope); } if (dep.getClassifier() != null) { mvnDep.setClassifier(dep.getClassifier()); @@ -494,22 +535,7 @@ protected void generateDependencyBlock(final Dependency dep, final org.apache.ma mvnExclusion.setArtifactId(exclude.getArtifactId()); } } - String jarPath = dep.getJarPath(); - - if (forceSystemScope && !dep.getScope().equals("system")) { - // we need to evaluate a system path - File repoPath = new File(cmvnConfig.getLocalRepository()); - for (final String group : dep.getGroupId().split("\\.")) { - repoPath = new File(repoPath, group); - } - repoPath = new File(repoPath, dep.getArtifactId()); - repoPath = new File(repoPath, dep.getVersion()); - - final String classifier = dep.getClassifier() == null ? "" : "-" + dep.getClassifier(); - final String fileName = dep.getArtifactId() + classifier + "-" + dep.getVersion() + ".jar"; - jarPath = new File(repoPath, fileName).getAbsolutePath(); - } if (jarPath != null) { if (!new File(jarPath).isAbsolute()) { jarPath = "${basedir}/" + jarPath; @@ -517,5 +543,4 @@ protected void generateDependencyBlock(final Dependency dep, final org.apache.ma mvnDep.setSystemPath(jarPath); } } - } diff --git a/de.tototec.tools.cmvn/src/main/java/de/tototec/tools/cmvn/ProjectReaderImpl.java b/de.tototec.tools.cmvn/src/main/java/de/tototec/tools/cmvn/ProjectReaderImpl.java index 8b73df2..f97ef30 100644 --- a/de.tototec.tools.cmvn/src/main/java/de/tototec/tools/cmvn/ProjectReaderImpl.java +++ b/de.tototec.tools.cmvn/src/main/java/de/tototec/tools/cmvn/ProjectReaderImpl.java @@ -29,7 +29,7 @@ public CmvnProjectConfig readConfigFile(final File file) { throw new RuntimeException("No ProjectConfigKeyValueReader registered."); } - final CmvnProjectConfig projectConfig = new CmvnProjectConfig(); + final CmvnProjectConfig projectConfig = new CmvnProjectConfig(file.getParentFile().getAbsolutePath()); for (final KeyValue keyValue : readKeyValues) { if (supportedKeys.containsKey(keyValue.getKey())) { diff --git a/de.tototec.tools.cmvn/src/main/java/de/tototec/tools/cmvn/model/CmvnProjectConfig.java b/de.tototec.tools.cmvn/src/main/java/de/tototec/tools/cmvn/model/CmvnProjectConfig.java index 81883f4..640e2e7 100644 --- a/de.tototec.tools.cmvn/src/main/java/de/tototec/tools/cmvn/model/CmvnProjectConfig.java +++ b/de.tototec.tools.cmvn/src/main/java/de/tototec/tools/cmvn/model/CmvnProjectConfig.java @@ -9,6 +9,7 @@ @Data public class CmvnProjectConfig { + private final String baseDir; private Dependency project; private final List dependencies = new LinkedList(); private final Map properties = new LinkedHashMap();