in changes-patch-builder/src/jetbrains/buildServer/vcs/patches/ChangesPatchBuilder.java [39:179]
public void buildPatch(@NotNull PatchBuilder builder,
@NotNull List<VcsChange> changes,
@NotNull FileContentProvider provider,
boolean strictErrorChecking)
throws IOException, VcsException {
LOG.debug("Start building minimal patch for collected changes");
myStrict = strictErrorChecking;
final MemoryFileSystem positive = new MemoryFileSystem();
final MemoryFileSystem negative = new MemoryFileSystem();
for (final VcsChange change : changes) {
Assert.isNotNull(change, "Change is null");
LOG.debug("Vcs change" + change);
final String path = change.getFileName();
if (!MemoryFileSystem.checkPath(path))
throw new VcsException((new StringBuilder()).append("Incorrect path ").append(path).toString());
final VcsChangeInfo.Type type = change.getType();
try {
switch (type)
{
case ADDED:
if (!positive.containsAncestor(path) && negative.containsAncestor(path)) {
fail((new StringBuilder()).append("Parent directory has been deleted, can't create a file ").append(path).append(" there").toString());
} else {
if (negative.containsFile(path)) {
negative.deleteFile(path);
positive.writeFile(path);
} else {
positive.createFile(path);
}
myVersions.put(path, change.getAfterChangeRevisionNumber());
}
break;
case CHANGED:
if (!positive.containsAncestor(path) && negative.containsAncestor(path))
fail((new StringBuilder()).append("Parent directory has been deleted, can't modify a file ").append(path).append(" there").toString());
else if (negative.containsFile(path)) {
fail((new StringBuilder()).append("Cannot modify a deleted file ").append(path).toString());
} else {
if (!positive.containsFile(path))
positive.writeFile(path);
myVersions.put(path, change.getAfterChangeRevisionNumber());
}
break;
case REMOVED:
if (!positive.containsAncestor(path) && negative.containsAncestor(path)) {
fail((new StringBuilder()).append("Parent directory for ").append(path).append(" has already been deleted").toString());
} else {
if (!positive.containsNewFile(path))
negative.createFile(path);
if (positive.containsFile(path))
positive.deleteFile(path);
myVersions.remove(path);
}
break;
case DIRECTORY_ADDED:
if (!positive.containsAncestor(path) && negative.containsAncestor(path)) {
fail((new StringBuilder()).append("Parent directory has been deleted, can't create a directory ").append(path).append(" there").toString());
} else if (positive.containsNode(path) && !negative.containsNode(path)) {
fail((new StringBuilder()).append("Directory ").append(path).append(" already added").toString());
} else {
positive.createDirectory(path);
}
break;
case DIRECTORY_REMOVED:
if (positive.containsDirectory(path)) {
positive.deleteDirectory(path);
} else {
if (positive.containsNode(path)) {
positive.deleteDirectory(path);
} else {
if (negative.containsAncestor(path))
fail((new StringBuilder()).append("Parent directory for ").append(path).append(" has already been deleted").toString());
if (negative.containsDirectory(path))
fail((new StringBuilder()).append("Directory ").append(path).append(" has already been deleted").toString());
}
if (negative.containsNode(path))
negative.deleteDirectory(path);
negative.createDirectory(path);
}
break;
default:
fail((new StringBuilder()).append("Unexpected VCS change type: ").append(type).toString());
break;
}
}
catch (FileSystemException e) {
fail(e);
}
catch (AssertionFailedException e) {
fail(e);
}
}
final ArrayList<String> newFiles = new ArrayList<String>();
final ArrayList<String> modifiedFiles = new ArrayList<String>();
final ArrayList<String> newDirectories = new ArrayList<String>();
positive.toCollections(newFiles, modifiedFiles, newDirectories);
final ArrayList<String> deletedFiles = new ArrayList<String>();
final ArrayList<String> deletedDirectories = new ArrayList<String>();
negative.toCollections(deletedFiles, deletedFiles, deletedDirectories);
for (String path : deletedFiles) {
LOG.debug("Delete file in patch: " + path);
builder.deleteFile(new File(path), false);
}
for (String path : deletedDirectories) {
LOG.debug("Delete folder in patch: " + path);
builder.deleteDirectory(new File(path), false);
}
for (String path : newDirectories) {
LOG.debug("Create folder in patch: " + path);
builder.createDirectory(new File(path));
}
for (String path : newFiles) {
final String version = myVersions.get(path);
LOG.debug("Create file in patch: " + path + " version: " + version);
if (version == null)
throw new VcsException((new StringBuilder()).append("Unexpected error: No version for ").append(path).append(" prepared").toString());
final File content = provider.getFile(path, version);
builder.createBinaryFile(new File(path), version, new FileInputStream(content), content.length());
}
for (String path : modifiedFiles) {
final String version = myVersions.get(path);
LOG.debug("Changed file in patch: " + path + " version: " + version);
if (version == null)
throw new VcsException((new StringBuilder()).append("Unexpected error: No version for ").append(path).append(" prepared").toString());
final File content = provider.getFile(path, version);
builder.changeOrCreateBinaryFile(new File(path), version, new FileInputStream(content), content.length());
}
}