generate MANIFEST.MF during artifact pre-processing phase instead of model loading phase, otherwise if output directory of an artifact was deleted it can be recreated before build is started so rebuild won't be triggered (IDEA-139412)

This commit is contained in:
nik
2015-04-29 17:51:49 +02:00
parent fb1b255cb7
commit 4bbc2713b0
4 changed files with 90 additions and 80 deletions
@@ -0,0 +1 @@
org.jetbrains.jps.maven.compiler.MavenManifestGenerationBuildTaskProvider
@@ -1,3 +1,2 @@
org.jetbrains.jps.maven.compiler.MavenWebArtifactRootCopyingHandlerProvider
org.jetbrains.jps.maven.compiler.MavenEjbArtifactRootCopyingHandlerProvider
org.jetbrains.jps.maven.compiler.MavenCommonArtifactRootCopyingHandlerProvider
org.jetbrains.jps.maven.compiler.MavenEjbArtifactRootCopyingHandlerProvider
@@ -1,78 +0,0 @@
/*
* Copyright 2000-2015 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.maven.compiler;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.Base64;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jps.builders.storage.BuildDataPaths;
import org.jetbrains.jps.incremental.artifacts.instructions.ArtifactRootCopyingHandlerProvider;
import org.jetbrains.jps.incremental.artifacts.instructions.FileCopyingHandler;
import org.jetbrains.jps.maven.model.JpsMavenExtensionService;
import org.jetbrains.jps.maven.model.impl.MavenModuleResourceConfiguration;
import org.jetbrains.jps.maven.model.impl.MavenProjectConfiguration;
import org.jetbrains.jps.model.JpsModel;
import org.jetbrains.jps.model.artifact.JpsArtifact;
import org.jetbrains.jps.model.artifact.elements.JpsModuleOutputPackagingElement;
import org.jetbrains.jps.model.artifact.elements.JpsPackagingElement;
import java.io.File;
import java.io.IOException;
/**
* @author Vladislav.Soroka
* @since 4/3/2015
*/
public class MavenCommonArtifactRootCopyingHandlerProvider extends ArtifactRootCopyingHandlerProvider {
private static final Logger LOG = Logger.getInstance(MavenCommonArtifactRootCopyingHandlerProvider.class);
@Nullable
@Override
public FileCopyingHandler createCustomHandler(@NotNull JpsArtifact artifact,
@NotNull File root,
@NotNull JpsPackagingElement contextElement,
@NotNull JpsModel model,
@NotNull BuildDataPaths buildDataPaths) {
if (contextElement instanceof JpsModuleOutputPackagingElement) return null;
MavenProjectConfiguration projectConfiguration = JpsMavenExtensionService.getInstance().getMavenProjectConfiguration(buildDataPaths);
if (projectConfiguration == null) return null;
if ("MANIFEST.MF".equals(root.getName())) {
MavenModuleResourceConfiguration moduleResourceConfiguration =
projectConfiguration.moduleConfigurations.get(getModuleName(artifact.getName()));
if (moduleResourceConfiguration != null && StringUtil.isNotEmpty(moduleResourceConfiguration.manifest)) {
try {
FileUtil.writeToFile(root, Base64.decode(moduleResourceConfiguration.manifest));
}
// do not fail the whole 'Make' if there is an invalid manifest cached (e.g. non encoded string generated by previous IDEA version)
catch (Exception e) {
LOG.debug(e);
}
}
}
return null;
}
@Nullable
private static String getModuleName(@NotNull String artifactName) {
return StringUtil.substringBefore(artifactName, ":");
}
}
@@ -0,0 +1,88 @@
/*
* Copyright 2000-2015 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.maven.compiler;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.Base64;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jps.builders.artifacts.ArtifactBuildTaskProvider;
import org.jetbrains.jps.builders.storage.BuildDataPaths;
import org.jetbrains.jps.incremental.BuildTask;
import org.jetbrains.jps.incremental.CompileContext;
import org.jetbrains.jps.incremental.ProjectBuildException;
import org.jetbrains.jps.maven.model.JpsMavenExtensionService;
import org.jetbrains.jps.maven.model.impl.MavenModuleResourceConfiguration;
import org.jetbrains.jps.maven.model.impl.MavenProjectConfiguration;
import org.jetbrains.jps.model.artifact.JpsArtifact;
import org.jetbrains.jps.model.artifact.elements.JpsArtifactRootElement;
import java.io.File;
import java.util.Collections;
import java.util.List;
import java.util.jar.JarFile;
/**
* @author nik
*/
public class MavenManifestGenerationBuildTaskProvider extends ArtifactBuildTaskProvider {
@NotNull
@Override
public List<? extends BuildTask> createArtifactBuildTasks(@NotNull JpsArtifact artifact,
@NotNull ArtifactBuildPhase buildPhase) {
String artifactName = artifact.getName();
if (buildPhase == ArtifactBuildPhase.PRE_PROCESSING && (artifactName.endsWith(" exploded") || artifactName.endsWith("ejb-client"))
&& artifact.getRootElement() instanceof JpsArtifactRootElement) {
return Collections.singletonList(new MavenManifestGenerationBuildTask(artifact));
}
return Collections.emptyList();
}
private static class MavenManifestGenerationBuildTask extends BuildTask {
private static final Logger LOG = Logger.getInstance(MavenManifestGenerationBuildTask.class);
private final JpsArtifact myArtifact;
public MavenManifestGenerationBuildTask(JpsArtifact artifact) {
myArtifact = artifact;
}
@Override
public void build(CompileContext context) throws ProjectBuildException {
BuildDataPaths dataPaths = context.getProjectDescriptor().dataManager.getDataPaths();
MavenProjectConfiguration projectConfiguration = JpsMavenExtensionService.getInstance().getMavenProjectConfiguration(dataPaths);
if (projectConfiguration == null) return;
final MavenModuleResourceConfiguration moduleResourceConfiguration = projectConfiguration.moduleConfigurations.get(getModuleName(myArtifact.getName()));
if (moduleResourceConfiguration != null && StringUtil.isNotEmpty(moduleResourceConfiguration.manifest)) {
try {
File output = new File(myArtifact.getOutputPath(), JarFile.MANIFEST_NAME);
FileUtil.writeToFile(output, Base64.decode(moduleResourceConfiguration.manifest));
}
// do not fail the whole 'Make' if there is an invalid manifest cached (e.g. non encoded string generated by previous IDEA version)
catch (Exception e) {
LOG.debug(e);
}
}
}
@Nullable
private static String getModuleName(@NotNull String artifactName) {
return StringUtil.substringBefore(artifactName, ":");
}
}
}