compile server: ignored file patterns supported

This commit is contained in:
nik
2012-03-07 19:13:24 +04:00
parent 87bb0c8810
commit f93842f44a
15 changed files with 227 additions and 24 deletions
@@ -33,6 +33,7 @@ import com.intellij.openapi.compiler.CompilerManager;
import com.intellij.openapi.compiler.CompilerTopics;
import com.intellij.openapi.components.ApplicationComponent;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.fileTypes.FileTypeManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ProjectManager;
import com.intellij.openapi.project.ProjectManagerAdapter;
@@ -506,7 +507,8 @@ public class CompileServerManager implements ApplicationComponent{
fillSdks(globals);
fillGlobalLibraries(globals);
return client.sendSetupRequest(data, globals, EncodingManager.getInstance().getDefaultCharsetName());
final String ignoredFilesList = FileTypeManager.getInstance().getIgnoredFilesList();
return client.sendSetupRequest(data, globals, EncodingManager.getInstance().getDefaultCharsetName(), ignoredFilesList);
}
private static void fillSdks(List<GlobalLibrary> globals) {
@@ -74,6 +74,7 @@ message Message {
repeated KeyValuePair path_variable = 1;
repeated GlobalLibrary global_library = 2;
optional string global_encoding = 3;
optional string ignored_files_patterns = 4;
}
message ReloadProjectCommand {
@@ -2743,6 +2743,10 @@ public final class JpsRemoteProto {
// optional string global_encoding = 3;
boolean hasGlobalEncoding();
String getGlobalEncoding();
// optional string ignored_files_patterns = 4;
boolean hasIgnoredFilesPatterns();
String getIgnoredFilesPatterns();
}
public static final class SetupCommand extends
com.google.protobuf.GeneratedMessageLite
@@ -3558,10 +3562,43 @@ public final class JpsRemoteProto {
}
}
// optional string ignored_files_patterns = 4;
public static final int IGNORED_FILES_PATTERNS_FIELD_NUMBER = 4;
private java.lang.Object ignoredFilesPatterns_;
public boolean hasIgnoredFilesPatterns() {
return ((bitField0_ & 0x00000002) == 0x00000002);
}
public String getIgnoredFilesPatterns() {
java.lang.Object ref = ignoredFilesPatterns_;
if (ref instanceof String) {
return (String) ref;
} else {
com.google.protobuf.ByteString bs =
(com.google.protobuf.ByteString) ref;
String s = bs.toStringUtf8();
if (com.google.protobuf.Internal.isValidUtf8(bs)) {
ignoredFilesPatterns_ = s;
}
return s;
}
}
private com.google.protobuf.ByteString getIgnoredFilesPatternsBytes() {
java.lang.Object ref = ignoredFilesPatterns_;
if (ref instanceof String) {
com.google.protobuf.ByteString b =
com.google.protobuf.ByteString.copyFromUtf8((String) ref);
ignoredFilesPatterns_ = b;
return b;
} else {
return (com.google.protobuf.ByteString) ref;
}
}
private void initFields() {
pathVariable_ = java.util.Collections.emptyList();
globalLibrary_ = java.util.Collections.emptyList();
globalEncoding_ = "";
ignoredFilesPatterns_ = "";
}
private byte memoizedIsInitialized = -1;
public final boolean isInitialized() {
@@ -3596,6 +3633,9 @@ public final class JpsRemoteProto {
if (((bitField0_ & 0x00000001) == 0x00000001)) {
output.writeBytes(3, getGlobalEncodingBytes());
}
if (((bitField0_ & 0x00000002) == 0x00000002)) {
output.writeBytes(4, getIgnoredFilesPatternsBytes());
}
}
private int memoizedSerializedSize = -1;
@@ -3616,6 +3656,10 @@ public final class JpsRemoteProto {
size += com.google.protobuf.CodedOutputStream
.computeBytesSize(3, getGlobalEncodingBytes());
}
if (((bitField0_ & 0x00000002) == 0x00000002)) {
size += com.google.protobuf.CodedOutputStream
.computeBytesSize(4, getIgnoredFilesPatternsBytes());
}
memoizedSerializedSize = size;
return size;
}
@@ -3724,6 +3768,8 @@ public final class JpsRemoteProto {
bitField0_ = (bitField0_ & ~0x00000002);
globalEncoding_ = "";
bitField0_ = (bitField0_ & ~0x00000004);
ignoredFilesPatterns_ = "";
bitField0_ = (bitField0_ & ~0x00000008);
return this;
}
@@ -3771,6 +3817,10 @@ public final class JpsRemoteProto {
to_bitField0_ |= 0x00000001;
}
result.globalEncoding_ = globalEncoding_;
if (((from_bitField0_ & 0x00000008) == 0x00000008)) {
to_bitField0_ |= 0x00000002;
}
result.ignoredFilesPatterns_ = ignoredFilesPatterns_;
result.bitField0_ = to_bitField0_;
return result;
}
@@ -3800,6 +3850,9 @@ public final class JpsRemoteProto {
if (other.hasGlobalEncoding()) {
setGlobalEncoding(other.getGlobalEncoding());
}
if (other.hasIgnoredFilesPatterns()) {
setIgnoredFilesPatterns(other.getIgnoredFilesPatterns());
}
return this;
}
@@ -3853,6 +3906,11 @@ public final class JpsRemoteProto {
globalEncoding_ = input.readBytes();
break;
}
case 34: {
bitField0_ |= 0x00000008;
ignoredFilesPatterns_ = input.readBytes();
break;
}
}
}
}
@@ -4073,6 +4131,42 @@ public final class JpsRemoteProto {
}
// optional string ignored_files_patterns = 4;
private java.lang.Object ignoredFilesPatterns_ = "";
public boolean hasIgnoredFilesPatterns() {
return ((bitField0_ & 0x00000008) == 0x00000008);
}
public String getIgnoredFilesPatterns() {
java.lang.Object ref = ignoredFilesPatterns_;
if (!(ref instanceof String)) {
String s = ((com.google.protobuf.ByteString) ref).toStringUtf8();
ignoredFilesPatterns_ = s;
return s;
} else {
return (String) ref;
}
}
public Builder setIgnoredFilesPatterns(String value) {
if (value == null) {
throw new NullPointerException();
}
bitField0_ |= 0x00000008;
ignoredFilesPatterns_ = value;
return this;
}
public Builder clearIgnoredFilesPatterns() {
bitField0_ = (bitField0_ & ~0x00000008);
ignoredFilesPatterns_ = getDefaultInstance().getIgnoredFilesPatterns();
return this;
}
void setIgnoredFilesPatterns(com.google.protobuf.ByteString value) {
bitField0_ |= 0x00000008;
ignoredFilesPatterns_ = value;
}
// @@protoc_insertion_point(builder_scope:org.jetbrains.jpsservice.Message.Request.SetupCommand)
}
@@ -120,7 +120,10 @@ public class ProtoUtil {
return JpsRemoteProto.Message.Request.newBuilder().setRequestType(JpsRemoteProto.Message.Request.Type.PING).build();
}
public static JpsRemoteProto.Message.Request createSetupRequest(final Map<String, String> pathVars, List<GlobalLibrary> sdkAndLibs, @Nullable String globalEncoding) {
public static JpsRemoteProto.Message.Request createSetupRequest(final Map<String, String> pathVars,
List<GlobalLibrary> sdkAndLibs,
@Nullable String globalEncoding,
String ignoredFilesPatterns) {
final JpsRemoteProto.Message.Request.SetupCommand.Builder cmdBuilder = JpsRemoteProto.Message.Request.SetupCommand.newBuilder();
if (!pathVars.isEmpty()) {
@@ -152,6 +155,7 @@ public class ProtoUtil {
}
cmdBuilder.setGlobalEncoding(globalEncoding);
cmdBuilder.setIgnoredFilesPatterns(ignoredFilesPatterns);
return JpsRemoteProto.Message.Request.newBuilder().setRequestType(JpsRemoteProto.Message.Request.Type.SETUP_COMMAND).setSetupCommand(cmdBuilder.build()).build();
}
@@ -56,9 +56,10 @@ public class CompileServerClient extends SimpleProtobufClient<JpsServerResponseH
}
@NotNull
public RequestFuture sendSetupRequest(final Map<String, String> pathVariables, final List<GlobalLibrary> sdkAndLibs, final String globalEncoding) throws Exception {
public RequestFuture sendSetupRequest(final Map<String, String> pathVariables, final List<GlobalLibrary> sdkAndLibs,
final String globalEncoding, final String ignoredFilesPatterns) throws Exception {
checkConnected();
return sendRequest(ProtoUtil.createSetupRequest(pathVariables, sdkAndLibs, globalEncoding), null);
return sendRequest(ProtoUtil.createSetupRequest(pathVariables, sdkAndLibs, globalEncoding, ignoredFilesPatterns), null);
}
@NotNull
@@ -138,7 +138,7 @@ public class ArtifactSourceFilesState {
private ArtifactInstructionsBuilder computeInstructions() {
final LayoutElement rootElement = myArtifact.getRootElement();
ArtifactInstructionsBuilderContext context = new ArtifactInstructionsBuilderContextImpl(myProject, new ProjectPaths(myProject));
final ArtifactInstructionsBuilderImpl instructionsBuilder = new ArtifactInstructionsBuilderImpl(myRootsIndex);
final ArtifactInstructionsBuilderImpl instructionsBuilder = new ArtifactInstructionsBuilderImpl(myRootsIndex, myProject.getIgnoredFilePatterns());
final CopyToDirectoryInstructionCreator instructionCreator = new CopyToDirectoryInstructionCreator(instructionsBuilder, myArtifact.getOutputPath());
LayoutElementBuildersRegistry.getInstance().generateInstructions(rootElement, instructionCreator, context);
return instructionsBuilder;
@@ -163,7 +163,7 @@ public class JarsBuilder {
final ArtifactSourceRoot root = pair.getSecond();
final ArtifactBuilderLogger logger = myContext.getLoggingManager().getArtifactBuilderLogger();
if (root instanceof FileBasedArtifactSourceRoot) {
addFileToJar(jarOutputStream, jarFile, root.getRootFile(), pair.getFirst(), writtenPaths);
addFileToJar(jarOutputStream, jarFile, root.getRootFile(), root.getFilter(), pair.getFirst(), writtenPaths);
}
else {
logger.fileCopied(FileUtil.toSystemIndependentName(root.getRootFile().getAbsolutePath()));
@@ -174,7 +174,7 @@ public class JarsBuilder {
for (Pair<String, JarInfo> nestedJar : jar.getPackedJars()) {
File nestedJarFile = myBuiltJars.get(nestedJar.getSecond());
if (nestedJarFile != null) {
addFileToJar(jarOutputStream, jarFile, nestedJarFile, nestedJar.getFirst(), writtenPaths);
addFileToJar(jarOutputStream, jarFile, nestedJarFile, SourceFileFilter.ALL, nestedJar.getFirst(), writtenPaths);
}
else {
LOG.debug("nested jar file " + nestedJar.getFirst() + " for " + jar.getPresentableDestination() + " not found");
@@ -211,17 +211,24 @@ public class JarsBuilder {
}
private void addFileToJar(final @NotNull JarOutputStream jarOutputStream, final @NotNull File jarFile, @NotNull File file,
@NotNull String relativePath, final @NotNull Set<String> writtenPaths) throws IOException {
SourceFileFilter filter, @NotNull String relativePath, final @NotNull Set<String> writtenPaths) throws IOException {
if (!file.exists() || FileUtil.isAncestor(file, jarFile, false)) {
return;
}
relativePath = addParentDirectories(jarOutputStream, writtenPaths, relativePath);
addFileOrDirRecursively(jarOutputStream, file, relativePath, writtenPaths);
addFileOrDirRecursively(jarOutputStream, file, filter, relativePath, writtenPaths);
}
private void addFileOrDirRecursively(@NotNull ZipOutputStream jarOutputStream, @NotNull File file, @NotNull String relativePath,
private void addFileOrDirRecursively(@NotNull ZipOutputStream jarOutputStream,
@NotNull File file,
SourceFileFilter filter,
@NotNull String relativePath,
@NotNull Set<String> writtenItemRelativePaths) throws IOException {
if (!filter.accept(FileUtil.toSystemIndependentName(file.getAbsolutePath()))) {
return;
}
if (file.isDirectory()) {
final String directoryPath = relativePath.length() == 0 ? "" : relativePath + "/";
if (!directoryPath.isEmpty()) {
@@ -230,7 +237,7 @@ public class JarsBuilder {
final File[] children = file.listFiles();
if (children != null) {
for (File child : children) {
addFileOrDirRecursively(jarOutputStream, child, directoryPath + child.getName(), writtenItemRelativePaths);
addFileOrDirRecursively(jarOutputStream, child, filter, directoryPath + child.getName(), writtenItemRelativePaths);
}
}
return;
@@ -18,6 +18,8 @@ package org.jetbrains.jps.incremental.artifacts.instructions;
import com.intellij.openapi.util.text.StringUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jps.IgnoredFilePatterns;
import org.jetbrains.jps.PathUtil;
import org.jetbrains.jps.incremental.ModuleRootsIndex;
import org.jetbrains.jps.incremental.artifacts.JarPathUtil;
@@ -40,13 +42,15 @@ public abstract class ArtifactCompilerInstructionCreatorBase implements Artifact
public void addDirectoryCopyInstructions(@NotNull File directory, @Nullable SourceFileFilter filter) {
final boolean copyExcluded = myInstructionsBuilder.getRootsIndex().isExcluded(directory);
SourceFileFilter fileFilter = new SourceFileFilterImpl(filter, myInstructionsBuilder.getRootsIndex(), copyExcluded);
SourceFileFilter fileFilter = new SourceFileFilterImpl(filter, myInstructionsBuilder.getRootsIndex(), myInstructionsBuilder.getIgnoredFilePatterns(), copyExcluded);
addDirectoryCopyInstructions(new FileBasedArtifactSourceRoot(directory, fileFilter));
}
@Override
public void addExtractDirectoryInstruction(@NotNull File jarFile, @NotNull String pathInJar) {
addDirectoryCopyInstructions(new JarBasedArtifactSourceRoot(jarFile, pathInJar, new SourceFileFilterImpl(null, myInstructionsBuilder.getRootsIndex(), false)));
final SourceFileFilterImpl filter = new SourceFileFilterImpl(null, myInstructionsBuilder.getRootsIndex(),
myInstructionsBuilder.getIgnoredFilePatterns(), false);
addDirectoryCopyInstructions(new JarBasedArtifactSourceRoot(jarFile, pathInJar, filter));
}
protected abstract void addDirectoryCopyInstructions(ArtifactSourceRoot root);
@@ -66,11 +70,16 @@ public abstract class ArtifactCompilerInstructionCreatorBase implements Artifact
private static class SourceFileFilterImpl extends SourceFileFilter {
private final SourceFileFilter myBaseFilter;
private final ModuleRootsIndex myRootsIndex;
private final IgnoredFilePatterns myIgnoredFilePatterns;
private final boolean myIncludeExcluded;
private SourceFileFilterImpl(@Nullable SourceFileFilter baseFilter, @NotNull ModuleRootsIndex rootsIndex, boolean includeExcluded) {
private SourceFileFilterImpl(@Nullable SourceFileFilter baseFilter,
@NotNull ModuleRootsIndex rootsIndex,
IgnoredFilePatterns patterns,
boolean includeExcluded) {
myBaseFilter = baseFilter;
myRootsIndex = rootsIndex;
myIgnoredFilePatterns = patterns;
myIncludeExcluded = includeExcluded;
}
@@ -78,7 +87,10 @@ public abstract class ArtifactCompilerInstructionCreatorBase implements Artifact
public boolean accept(@NotNull String fullFilePath) {
if (myBaseFilter != null && !myBaseFilter.accept(fullFilePath)) return false;
//todo[nik] check FileTypeManager.isFileIgnored()
if (myIgnoredFilePatterns.isIgnored(PathUtil.getFileName(fullFilePath))) {
return false;
}
if (!myIncludeExcluded) {
final File file = JarPathUtil.getLocalFile(fullFilePath);
if (myRootsIndex.isExcluded(file)) {
@@ -4,6 +4,7 @@ import com.intellij.openapi.util.io.FileUtil;
import com.intellij.util.containers.MultiMap;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jps.IgnoredFilePatterns;
import org.jetbrains.jps.incremental.ModuleRootsIndex;
import java.io.File;
@@ -20,14 +21,20 @@ public class ArtifactInstructionsBuilderImpl implements ArtifactInstructionsBuil
private final Map<String, JarInfo> myJarByPath;
private final MultiMap<ArtifactSourceRoot, DestinationInfo> myInstructions;
private final ModuleRootsIndex myRootsIndex;
private final IgnoredFilePatterns myIgnoredFilePatterns;
public ArtifactInstructionsBuilderImpl(ModuleRootsIndex rootsIndex) {
public ArtifactInstructionsBuilderImpl(ModuleRootsIndex rootsIndex, IgnoredFilePatterns patterns) {
myRootsIndex = rootsIndex;
myIgnoredFilePatterns = patterns;
mySourceByOutput = new HashMap<String, ArtifactSourceRoot>();
myJarByPath = new HashMap<String, JarInfo>();
myInstructions = new MultiMap<ArtifactSourceRoot, DestinationInfo>();
}
public IgnoredFilePatterns getIgnoredFilePatterns() {
return myIgnoredFilePatterns;
}
public boolean addDestination(@NotNull ArtifactSourceRoot root, @NotNull DestinationInfo destinationInfo) {
if (destinationInfo instanceof ExplodedDestinationInfo && root instanceof FileBasedArtifactSourceRoot
&& root.getRootFile().equals(new File(FileUtil.toSystemDependentName(destinationInfo.getOutputFilePath())))) {
@@ -81,7 +81,7 @@ class ServerMessageHandler extends SimpleChannelHandler {
);
}
final String globalEncoding = setupCommand.isInitialized()? setupCommand.getGlobalEncoding() : null;
facade.setGlobals(libs, pathVars, globalEncoding);
facade.setGlobals(libs, pathVars, globalEncoding, setupCommand.getIgnoredFilesPatterns());
reply = ProtoUtil.toMessage(sessionId, ProtoUtil.createCommandCompletedEvent(null));
break;
@@ -45,13 +45,15 @@ class ServerState {
private final List<GlobalLibrary> myGlobalLibraries = new ArrayList<GlobalLibrary>();
private volatile String myGlobalEncoding = null;
private volatile boolean myKeepTempCachesInMemory = false;
private String myIgnoredFilesPatterns;
public void setGlobals(List<GlobalLibrary> libs, Map<String, String> pathVars, String globalEncoding) {
public void setGlobals(List<GlobalLibrary> libs, Map<String, String> pathVars, String globalEncoding, String ignoredFilesPatterns) {
synchronized (myConfigurationLock) {
clearCahedState();
myGlobalLibraries.addAll(libs);
myPathVariables.putAll(pathVars);
myGlobalEncoding = StringUtil.isEmpty(globalEncoding)? null : globalEncoding;
myIgnoredFilesPatterns = ignoredFilesPatterns;
}
}
@@ -328,6 +330,7 @@ class ServerState {
if (globalEncoding != null && project.getProjectCharset() == null) {
project.setProjectCharset(globalEncoding);
}
project.getIgnoredFilePatterns().loadFromString(myIgnoredFilesPatterns);
return project;
}
@@ -210,8 +210,7 @@ public class ArtifactBuilderTest extends ArtifactBuilderTestCase {
assertOutput(artifact, fs().file("A.class"));
}
//todo[nik] support ignored names
public void _testIgnoredFile() {
public void testIgnoredFile() {
final String file = createFile("a/.svn/a.txt");
createFile("a/svn/b.txt");
final Artifact a = addArtifact(root().dirCopy(PathUtil.getParentPath(PathUtil.getParentPath(file))));
@@ -219,8 +218,15 @@ public class ArtifactBuilderTest extends ArtifactBuilderTestCase {
assertOutput(a, fs().dir("svn").file("b.txt"));
}
//todo[nik] support ignored names
public void _testCopyExcludedFolder() {
public void testIgnoredFileInArchive() {
final String file = createFile("a/.svn/a.txt");
createFile("a/svn/b.txt");
final Artifact a = addArtifact(archive("a.jar").dirCopy(PathUtil.getParentPath(PathUtil.getParentPath(file))));
buildAll();
assertOutput(a, fs().archive("a.jar").dir("svn").file("b.txt"));
}
public void testCopyExcludedFolder() {
//explicitly added excluded files should be copied (e.g. compile output)
final String file = createFile("xxx/excluded/a.txt");
createFile("xxx/excluded/CVS");
@@ -236,8 +242,7 @@ public class ArtifactBuilderTest extends ArtifactBuilderTestCase {
assertOutput(a, fs().file("a.txt"));
}
//todo[nik] support ignored names
public void _testCopyExcludedFile() {
public void testCopyExcludedFile() {
//excluded files under non-excluded directory should not be copied
final String file = createFile("xxx/excluded/a.txt");
createFile("xxx/b.txt");
@@ -0,0 +1,56 @@
package org.jetbrains.jps;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.text.StringUtil;
import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;
/**
* @author nik
*/
public class IgnoredFilePatterns {
private static final Logger LOG = Logger.getInstance("#org.jetbrains.jps.IgnoredFilePatterns");
private List<Pattern> myPatterns = new ArrayList<Pattern>();
public IgnoredFilePatterns() {
loadFromString("CVS;SCCS;RCS;rcs;.DS_Store;.svn;.pyc;.pyo;*.pyc;*.pyo;.git;*.hprof;_svn;.hg;*.lib;*~;__pycache__;.bundle;vssver.scc;vssver2.scc;*.rbc;");
}
public void loadFromString(String patterns) {
myPatterns.clear();
StringTokenizer tokenizer = new StringTokenizer(patterns, ";");
while (tokenizer.hasMoreTokens()) {
String pattern = tokenizer.nextToken();
if (!StringUtil.isEmptyOrSpaces(pattern)) {
try {
myPatterns.add(Pattern.compile(convertToJavaPattern(pattern)));
}
catch (PatternSyntaxException e) {
LOG.info("Cannot load ignored file pattern " + pattern, e);
}
}
}
}
public boolean isIgnored(String fileName) {
for (Pattern pattern : myPatterns) {
if (pattern.matcher(fileName).matches()) {
return true;
}
}
return false;
}
public static String convertToJavaPattern(String wildcardPattern) {
wildcardPattern = StringUtil.replace(wildcardPattern, ".", "\\.");
wildcardPattern = StringUtil.replace(wildcardPattern, "*?", ".+");
wildcardPattern = StringUtil.replace(wildcardPattern, "?*", ".+");
wildcardPattern = StringUtil.replace(wildcardPattern, "*", ".*");
wildcardPattern = StringUtil.replace(wildcardPattern, "?", ".");
return wildcardPattern;
}
}
@@ -54,4 +54,14 @@ public class PathUtil {
}
return false;
}
public static String getFileName(String path) {
if (path.length() == 0) {
return "";
}
final char c = path.charAt(path.length() - 1);
int end = c == '/' || c == '\\' ? path.length() - 1 : path.length();
int start = Math.max(path.lastIndexOf('/', end - 1), path.lastIndexOf('\\', end - 1)) + 1;
return path.substring(start, end);
}
}
@@ -18,6 +18,7 @@ class Project {
final Map<String, Artifact> artifacts = [:]
final Map<String, RunConfiguration> runConfigurations = [:]
final CompilerConfiguration compilerConfiguration = new CompilerConfiguration()
final IgnoredFilePatterns ignoredFilePatterns = new IgnoredFilePatterns()
String projectCharset; // contains project charset, if not specified default charset will be used (used by compilers)