diff options
Diffstat (limited to 'openecomp-be/tools/compile-helper-plugin/src/main/java/org/openecomp/sdc/onboarding/PreCompileHelperMojo.java')
-rw-r--r-- | openecomp-be/tools/compile-helper-plugin/src/main/java/org/openecomp/sdc/onboarding/PreCompileHelperMojo.java | 382 |
1 files changed, 336 insertions, 46 deletions
diff --git a/openecomp-be/tools/compile-helper-plugin/src/main/java/org/openecomp/sdc/onboarding/PreCompileHelperMojo.java b/openecomp-be/tools/compile-helper-plugin/src/main/java/org/openecomp/sdc/onboarding/PreCompileHelperMojo.java index faa3167e37..854ef7fa97 100644 --- a/openecomp-be/tools/compile-helper-plugin/src/main/java/org/openecomp/sdc/onboarding/PreCompileHelperMojo.java +++ b/openecomp-be/tools/compile-helper-plugin/src/main/java/org/openecomp/sdc/onboarding/PreCompileHelperMojo.java @@ -16,127 +16,417 @@ package org.openecomp.sdc.onboarding; +import static org.openecomp.sdc.onboarding.BuildHelper.getArtifactPathInLocalRepo; +import static org.openecomp.sdc.onboarding.BuildHelper.getChecksum; +import static org.openecomp.sdc.onboarding.BuildHelper.getSourceChecksum; +import static org.openecomp.sdc.onboarding.BuildHelper.readState; +import static org.openecomp.sdc.onboarding.Constants.ANY_EXT; +import static org.openecomp.sdc.onboarding.Constants.COLON; +import static org.openecomp.sdc.onboarding.Constants.DOT; +import static org.openecomp.sdc.onboarding.Constants.EMPTY_JAR; +import static org.openecomp.sdc.onboarding.Constants.GENERATED_SOURCE_CHECKSUM; +import static org.openecomp.sdc.onboarding.Constants.INSTRUMENT_ONLY; +import static org.openecomp.sdc.onboarding.Constants.INSTRUMENT_WITH_TEST_ONLY; +import static org.openecomp.sdc.onboarding.Constants.JAR; +import static org.openecomp.sdc.onboarding.Constants.JAVA_EXT; import static org.openecomp.sdc.onboarding.Constants.MAIN; +import static org.openecomp.sdc.onboarding.Constants.MAIN_CHECKSUM; +import static org.openecomp.sdc.onboarding.Constants.MAIN_SOURCE_CHECKSUM; +import static org.openecomp.sdc.onboarding.Constants.RESOURCES_CHANGED; +import static org.openecomp.sdc.onboarding.Constants.RESOURCE_CHECKSUM; +import static org.openecomp.sdc.onboarding.Constants.RESOURCE_ONLY; +import static org.openecomp.sdc.onboarding.Constants.RESOURCE_WITH_TEST_ONLY; +import static org.openecomp.sdc.onboarding.Constants.SHA1; +import static org.openecomp.sdc.onboarding.Constants.SKIP_MAIN_SOURCE_COMPILE; +import static org.openecomp.sdc.onboarding.Constants.SKIP_PMD; import static org.openecomp.sdc.onboarding.Constants.SKIP_TEST_RUN; +import static org.openecomp.sdc.onboarding.Constants.SKIP_TEST_SOURCE_COMPILE; import static org.openecomp.sdc.onboarding.Constants.TEST; +import static org.openecomp.sdc.onboarding.Constants.TEST_CHECKSUM; +import static org.openecomp.sdc.onboarding.Constants.TEST_ONLY; +import static org.openecomp.sdc.onboarding.Constants.TEST_RESOURCE_ONLY; +import static org.openecomp.sdc.onboarding.Constants.TEST_SOURCE_CHECKSUM; import static org.openecomp.sdc.onboarding.Constants.UNICORN; import java.io.File; import java.io.IOException; import java.io.UncheckedIOException; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.nio.file.StandardOpenOption; +import java.security.NoSuchAlgorithmException; +import java.util.Arrays; import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Optional; +import java.util.Set; import org.apache.maven.artifact.Artifact; +import org.apache.maven.execution.MavenSession; +import org.apache.maven.model.Plugin; +import org.apache.maven.model.PluginExecution; import org.apache.maven.plugin.AbstractMojo; +import org.apache.maven.plugin.InvalidPluginDescriptorException; +import org.apache.maven.plugin.MavenPluginManager; import org.apache.maven.plugin.MojoExecutionException; +import org.apache.maven.plugin.MojoFailureException; +import org.apache.maven.plugin.MojoNotFoundException; +import org.apache.maven.plugin.PluginDescriptorParsingException; +import org.apache.maven.plugin.PluginResolutionException; +import org.apache.maven.plugin.descriptor.MojoDescriptor; +import org.apache.maven.plugins.annotations.Component; import org.apache.maven.plugins.annotations.LifecyclePhase; import org.apache.maven.plugins.annotations.Mojo; import org.apache.maven.plugins.annotations.Parameter; import org.apache.maven.plugins.annotations.ResolutionScope; import org.apache.maven.project.MavenProject; -@Mojo(name = "pre-compile-helper", threadSafe = true, defaultPhase = LifecyclePhase.GENERATE_SOURCES, + +@Mojo(name = "pre-compile-helper", threadSafe = true, defaultPhase = LifecyclePhase.GENERATE_RESOURCES, requiresDependencyResolution = ResolutionScope.TEST) public class PreCompileHelperMojo extends AbstractMojo { - @Parameter(defaultValue = "${project}", readonly = true) + @Parameter(defaultValue = "${project}") private MavenProject project; @Parameter(defaultValue = "${project.artifact.groupId}:${project.artifact.artifactId}") private String moduleCoordinates; + @Parameter(defaultValue = "${session}") + private MavenSession session; @Parameter private String excludePackaging; @Parameter private List<String> excludeDependencies; @Parameter - private File mainCompiledLocation; + private BuildState buildState; @Parameter - private File testCompiledLocation; + private File mainSourceLocation; @Parameter - private File inputSourceFilesList; + private File testSourceLocation; @Parameter - private File inputTestFilesList; + private File generatedSourceLocation; + @Component + private MavenPluginManager pluginManager; @Parameter - private BuildState buildState; + private File mainResourceLocation; + @Parameter + private File testResourceLocation; + private Map<String, Object> resourceBuildData; - public void execute() throws MojoExecutionException { - if (!System.getProperties().containsKey(UNICORN)) { + private static Map<String, String> checksumMap; + + static { + checksumMap = readCurrentPMDState("pmd.dat"); + } + + public void execute() throws MojoExecutionException, MojoFailureException { + + long mainChecksum = 0, testChecksum = 0, resourceChecksum = 0; + Optional<String> artifactPath; + + if (project.getPackaging().equals(excludePackaging)) { return; } - if (project.getPackaging().equals(excludePackaging)) { + init(); + project.getProperties() + .setProperty(MAIN_CHECKSUM, String.valueOf(mainChecksum = getChecksum(mainSourceLocation, JAVA_EXT))); + project.getProperties() + .setProperty(TEST_CHECKSUM, String.valueOf(testChecksum = getChecksum(testSourceLocation, JAVA_EXT))); + String checksum = mainChecksum + COLON + testChecksum; + if (!checksum.equals(checksumMap.get(moduleCoordinates)) || isPMDMandatory(project.getArtifacts())) { + project.getProperties().setProperty(SKIP_PMD, Boolean.FALSE.toString()); + buildState.recordPMDRun(moduleCoordinates); + } + project.getProperties().setProperty(EMPTY_JAR, ""); + if (!System.getProperties().containsKey(UNICORN)) { return; } + project.getProperties().setProperty(RESOURCE_CHECKSUM, + String.valueOf(resourceChecksum = getChecksum(mainResourceLocation, ANY_EXT))); + byte[] sourceChecksum = calculateChecksum(mainChecksum, resourceChecksum).getBytes(); + boolean instrumented = isCurrentModuleInstrumented(); + artifactPath = getArtifactPathInLocalRepo(session.getLocalRepository().getUrl(), project, sourceChecksum); + + boolean isFirstBuild = buildState.getBuildTime(moduleCoordinates) == 0 || !artifactPath.isPresent(); + Map<String, Object> moduleBuildData = getCurrentModuleBuildData(); Map<String, Object> lastTimeModuleBuildData = buildState.readModuleBuildData(); + resourceBuildData = getCurrentResourceBuildData(); + Map<String, Object> lastTimeResourceBuildData = buildState.readResourceBuildData(); - boolean buildDataSameWithPreviousBuild = lastTimeModuleBuildData.get(MAIN) != null && moduleBuildData.get(MAIN) - .equals(lastTimeModuleBuildData - .get(MAIN)); - boolean isFirstBuild = buildState.getBuildTime(moduleCoordinates) == 0; - - if (isCompileNeeded(HashMap.class.cast(moduleBuildData.get(MAIN)).keySet(), isFirstBuild, - buildDataSameWithPreviousBuild)) { - try { - buildState.markModuleDirty(inputSourceFilesList); - buildState.markModuleDirty(inputTestFilesList); - project.getProperties().setProperty(SKIP_TEST_RUN, "false"); - } catch (IOException e) { - throw new UncheckedIOException(e); - } + boolean buildDataSameWithPreviousBuild = + isBuildDataSameWithPreviousBuild(lastTimeModuleBuildData, moduleBuildData); + boolean resourceMainBuildDataSameWithPreviousBuild = + isResourceMainBuildDataSameWithPreviousBuild(lastTimeResourceBuildData); + + boolean mainToBeCompiled = isCompileNeeded(HashMap.class.cast(moduleBuildData.get(MAIN)).keySet(), isFirstBuild, + buildDataSameWithPreviousBuild); + + boolean resourceDataSame = resourceBuildData.equals(lastTimeResourceBuildData); + + boolean testToBeCompiled = + lastTimeModuleBuildData == null || !moduleBuildData.get(TEST).equals(lastTimeModuleBuildData.get(TEST)); + setMainBuildAttribute(mainToBeCompiled, testToBeCompiled); + generateSignature(sourceChecksum); + setTestBuild(resourceDataSame, resourceMainBuildDataSameWithPreviousBuild, testToBeCompiled, mainToBeCompiled); + setInstrumentedBuild(testToBeCompiled, mainToBeCompiled, instrumented); + + if (!moduleBuildData.equals(lastTimeModuleBuildData) || isFirstBuild) { + buildState.addModuleBuildData(moduleCoordinates, moduleBuildData); } + setResourceBuild(resourceMainBuildDataSameWithPreviousBuild, mainToBeCompiled, testToBeCompiled); + setJarFlags(mainToBeCompiled, instrumented, !resourceMainBuildDataSameWithPreviousBuild); + setInstallFlags(mainToBeCompiled, instrumented, project.getPackaging(), + !resourceMainBuildDataSameWithPreviousBuild); - if (!moduleBuildData.get(TEST).equals(lastTimeModuleBuildData.get(TEST))) { - try { - buildState.markModuleDirty(inputTestFilesList); - project.getProperties().setProperty(SKIP_TEST_RUN, Boolean.FALSE.toString()); - } catch (IOException e) { - throw new UncheckedIOException(e); - } + if (!mainToBeCompiled && !instrumented && JAR.equals(project.getPackaging()) + && resourceMainBuildDataSameWithPreviousBuild) { + project.getProperties().setProperty("artifactPathToCopy", artifactPath.orElse(null)); } + } - if (!moduleBuildData.equals(lastTimeModuleBuildData)) { - buildState.addModuleBuildData(moduleCoordinates, moduleBuildData); + private void generateSignature(byte[] sourceChecksum) { + try { + Files.write(Paths.get(project.getBuild().getDirectory(), project.getBuild().getFinalName() + DOT + UNICORN), + sourceChecksum, StandardOpenOption.CREATE); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + } + + private String calculateChecksum(long mainChecksum, long resourceChecksum) throws MojoExecutionException { + try { + return getSourceChecksum(mainChecksum + COLON + resourceChecksum, SHA1); + } catch (NoSuchAlgorithmException e) { + throw new MojoExecutionException(e.getMessage(), e); + } + } + + private boolean isResourceMainBuildDataSameWithPreviousBuild(Map<String, Object> lastTimeResourceBuildData) { + return lastTimeResourceBuildData != null && (lastTimeResourceBuildData.get(MAIN) != null && resourceBuildData + .get(MAIN) + .equals(lastTimeResourceBuildData + .get(MAIN))); + } + + private boolean isBuildDataSameWithPreviousBuild(Map<String, Object> lastTimeModuleBuildData, + Map<String, Object> moduleBuildData) { + return lastTimeModuleBuildData != null && (lastTimeModuleBuildData.get(MAIN) != null && moduleBuildData + .get(MAIN) + .equals(lastTimeModuleBuildData + .get(MAIN))); + } + + private void setInstrumentedBuild(boolean testToBeCompiled, boolean mainToBeCompiled, boolean instrumented) { + if (!testToBeCompiled && !mainToBeCompiled && instrumented) { + project.getProperties().setProperty(INSTRUMENT_ONLY, Boolean.TRUE.toString()); + project.getProperties().remove(SKIP_MAIN_SOURCE_COMPILE); + project.getProperties().remove(SKIP_TEST_SOURCE_COMPILE); + } + if (testToBeCompiled && !mainToBeCompiled && instrumented) { + project.getProperties().setProperty(INSTRUMENT_WITH_TEST_ONLY, Boolean.TRUE.toString()); + project.getProperties().remove(SKIP_MAIN_SOURCE_COMPILE); } + if (instrumented) { + buildState.markTestsMandatoryModule(moduleCoordinates); + project.getProperties().setProperty(SKIP_TEST_RUN, Boolean.FALSE.toString()); + } + } - if (inputSourceFilesList.isFile() && inputSourceFilesList.length() == 0) { - if (!inputSourceFilesList.delete()) { - throw new MojoExecutionException( - "****** Please remove 'target' directory manually under path " + project.getBasedir() - .getAbsolutePath()); + private void setResourceBuild(boolean resourceMainBuildDataSameWithPreviousBuild, boolean mainToBeCompiled, + boolean testToBeCompiled) { + if (resourceMainBuildDataSameWithPreviousBuild) { + project.getProperties().setProperty("skipResourceCollection", Boolean.TRUE.toString()); + } else { + project.getProperties().setProperty(RESOURCES_CHANGED, Boolean.TRUE.toString()); + } + if (!resourceMainBuildDataSameWithPreviousBuild && !mainToBeCompiled) { + project.getProperties().remove(SKIP_MAIN_SOURCE_COMPILE); + if (!testToBeCompiled) { + project.getProperties().remove(SKIP_TEST_SOURCE_COMPILE); + project.getProperties().setProperty(RESOURCE_ONLY, Boolean.TRUE.toString()); + } else { + project.getProperties().setProperty(RESOURCE_WITH_TEST_ONLY, Boolean.TRUE.toString()); } } - if (inputTestFilesList.isFile() && inputTestFilesList.length() == 0) { - if (!inputTestFilesList.delete()) { - throw new MojoExecutionException( - "****** Please remove 'target' directory manually under path " + project.getBasedir() - .getAbsolutePath()); + } + + private void setTestBuild(boolean resourceDataSame, boolean resourceMainBuildDataSameWithPreviousBuild, + boolean testToBeCompiled, boolean mainToBeCompiled) { + if (!resourceDataSame) { + buildState.addResourceBuildData(moduleCoordinates, resourceBuildData); + project.getProperties().setProperty(SKIP_TEST_RUN, Boolean.FALSE.toString()); + if (resourceMainBuildDataSameWithPreviousBuild && !testToBeCompiled && !mainToBeCompiled) { + project.getProperties().setProperty(TEST_RESOURCE_ONLY, Boolean.TRUE.toString()); + project.getProperties().remove(SKIP_MAIN_SOURCE_COMPILE); + project.getProperties().remove(SKIP_TEST_SOURCE_COMPILE); } } } + private void setMainBuildAttribute(boolean mainToBeCompiled, boolean testToBeCompiled) { + if (!mainToBeCompiled) { + project.getProperties().setProperty(SKIP_MAIN_SOURCE_COMPILE, Boolean.TRUE.toString()); + } + if (testToBeCompiled && !mainToBeCompiled) { + project.getProperties().setProperty(TEST_ONLY, Boolean.TRUE.toString()); + project.getProperties().remove(SKIP_MAIN_SOURCE_COMPILE); + } + + if (mainToBeCompiled || testToBeCompiled) { + project.getProperties().setProperty(SKIP_TEST_RUN, Boolean.FALSE.toString()); + } else { + project.getProperties().setProperty(SKIP_TEST_SOURCE_COMPILE, Boolean.TRUE.toString()); + } + } + + private void setJarFlags(boolean compile, boolean instrumented, boolean resourceChanged) { + if (compile || instrumented || resourceChanged) { + project.getProperties().setProperty(EMPTY_JAR, ""); + } else { + project.getProperties().setProperty(EMPTY_JAR, "**/*"); + project.getProperties().setProperty("mvnDsc", "false"); + } + } + + private void setInstallFlags(boolean compile, boolean instrumented, String packaging, boolean resourceChanged) { + if (!compile && !instrumented && !resourceChanged && JAR.equals(packaging)) { + project.getProperties().setProperty("skipInstall", Boolean.TRUE.toString()); + } + } + private boolean isCompileNeeded(Collection<String> dependencyCoordinates, boolean isFirstBuild, - boolean buildDataSame) { + boolean buildDataSame) throws MojoFailureException { return isFirstBuild || !buildDataSame || buildState.isCompileMust(moduleCoordinates, dependencyCoordinates); } + private boolean isCurrentModuleInstrumented() { + try { + return scanModuleFor(LifecyclePhase.PROCESS_CLASSES.id(), LifecyclePhase.PROCESS_TEST_CLASSES.id(), + LifecyclePhase.COMPILE.id(), LifecyclePhase.TEST_COMPILE.id()); + } catch (Exception e) { + return true; + } + } + + boolean isCodeGenerator() { + try { + return scanModuleFor(LifecyclePhase.GENERATE_RESOURCES.id(), LifecyclePhase.GENERATE_SOURCES.id(), + LifecyclePhase.GENERATE_TEST_RESOURCES.id(), LifecyclePhase.GENERATE_TEST_SOURCES.id()); + } catch (Exception e) { + return true; + } + } + private Map<String, Object> getCurrentModuleBuildData() { Map<String, Object> moduleBuildData = new HashMap<>(); moduleBuildData.put(MAIN, new HashMap<String, String>()); moduleBuildData.put(TEST, new HashMap<String, String>()); + HashMap.class.cast(moduleBuildData.get(MAIN)) + .put(MAIN_SOURCE_CHECKSUM, project.getProperties().getProperty(MAIN_CHECKSUM)); + HashMap.class.cast(moduleBuildData.get(TEST)) + .put(TEST_SOURCE_CHECKSUM, project.getProperties().getProperty(TEST_CHECKSUM)); + if (isCodeGenerator()) { + HashMap.class.cast(moduleBuildData.get(MAIN)) + .put(GENERATED_SOURCE_CHECKSUM, getChecksum(generatedSourceLocation, JAVA_EXT)); + } if (project.getArtifacts() == null || project.getArtifacts().isEmpty()) { return moduleBuildData; } for (Artifact dependency : project.getArtifacts()) { + String fileNme = dependency.getFile().getName(); if (excludeDependencies.contains(dependency.getScope())) { HashMap.class.cast(moduleBuildData.get(TEST)) - .put(dependency.getGroupId() + ":" + dependency.getArtifactId(), dependency.getVersion()); + .put(dependency.getGroupId() + COLON + dependency.getArtifactId(), + fileNme.endsWith(dependency.getVersion() + DOT + JAR) ? dependency.getVersion() : + fileNme); continue; } HashMap.class.cast(moduleBuildData.get(MAIN)) - .put(dependency.getGroupId() + ":" + dependency.getArtifactId(), dependency.getVersion()); + .put(dependency.getGroupId() + COLON + dependency.getArtifactId(), + fileNme.endsWith(dependency.getVersion() + DOT + JAR) ? dependency.getVersion() : + fileNme); } return moduleBuildData; } + + private static Map<String, String> readCurrentPMDState(String fileName) { + Optional<HashMap> val = readState(fileName, HashMap.class); + return val.orElseGet(HashMap::new); + } + + private boolean isPMDMandatory(Set<Artifact> dependencies) { + for (Artifact artifact : dependencies) { + if (buildState.isPMDRun(artifact.getGroupId() + COLON + artifact.getArtifactId())) { + return true; + } + } + return false; + } + + private boolean scanModuleFor(String... types) + throws InvalidPluginDescriptorException, PluginResolutionException, MojoNotFoundException, + PluginDescriptorParsingException { + for (Plugin plugin : project.getBuildPlugins()) { + if (!(plugin.getGroupId().equals("org.apache.maven.plugins") && plugin.getArtifactId().startsWith("maven")) + && !plugin.getGroupId().startsWith("org.openecomp.sdc")) { + if (scanPlugin(plugin, types)) { + return true; + } + } + } + return false; + } + + private boolean scanPlugin(Plugin plugin, String... types) + throws InvalidPluginDescriptorException, PluginDescriptorParsingException, MojoNotFoundException, + PluginResolutionException { + for (PluginExecution pluginExecution : plugin.getExecutions()) { + if (pluginExecution.getPhase() != null) { + if (Arrays.asList(types).contains(pluginExecution.getPhase())) { + return true; + } + } + for (String goal : pluginExecution.getGoals()) { + MojoDescriptor md = pluginManager.getMojoDescriptor(plugin, goal, project.getRemotePluginRepositories(), + session.getRepositorySession()); + if (Arrays.asList(types).contains(md.getPhase())) { + return true; + } + } + } + return false; + } + + private Map<String, Object> getCurrentResourceBuildData() { + HashMap<String, Object> resourceBuildStateData = new HashMap<>(); + resourceBuildStateData.put(MAIN, project.getProperties().getProperty(RESOURCE_CHECKSUM)); + resourceBuildStateData.put(TEST, getChecksum(testResourceLocation, ANY_EXT)); + resourceBuildStateData.put("dependency", getDependencies().hashCode()); + return resourceBuildStateData; + } + + private Map<String, String> getDependencies() { + Map<String, String> dependencies = new HashMap<>(); + for (Artifact d : project.getArtifacts()) { + dependencies.put(d.getGroupId() + COLON + d.getArtifactId(), d.getVersion()); + } + return dependencies; + } + + private void init() { + if (mainSourceLocation == null) { + mainSourceLocation = Paths.get(project.getBuild().getSourceDirectory()).toFile(); + } + if (testSourceLocation == null) { + testSourceLocation = Paths.get(project.getBuild().getTestSourceDirectory()).toFile(); + } + if (mainResourceLocation == null) { + mainResourceLocation = Paths.get(project.getBuild().getResources().get(0).getDirectory()).toFile(); + } + if (testResourceLocation == null) { + testResourceLocation = Paths.get(project.getBuild().getTestResources().get(0).getDirectory()).toFile(); + } + } } |