DiffCommand.java
package org.docascode.api;
import org.docascode.api.core.DocAsCodeRepository;
import org.docascode.api.core.errors.DocAsCodeException;
import org.docascode.api.diff.Differencer;
import org.docascode.api.event.Event;
import org.docascode.api.retrieve.GitRetriever;
import org.eclipse.aether.resolution.ArtifactResult;
import org.eclipse.aether.version.Version;
import org.eclipse.jgit.lib.*;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.revwalk.RevWalk;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.io.File;
public class DiffCommand extends DocAsCodeCommand<DiffCommand>{
private String oldRevision;
public DiffCommand setOldRevision(String oldRevision){
this.oldRevision = oldRevision;
return this;
}
private String newRevision;
public DiffCommand setNewRevision(String newRevision){
this.newRevision = newRevision;
return this;
}
private String revision;
public DiffCommand setRevision(String revision){
this.revision = revision;
return this;
}
private File toFile;
public DiffCommand toFile(File toFile){
this.toFile = toFile;
return this;
}
private File file;
public DiffCommand setFile(File file){
this.file = file;
return this;
}
DiffCommand(DocAsCodeRepository repo) {
super(repo);
}
private boolean openAtEnd = false;
public DiffCommand openAtEnd(boolean openAtEnd){
this.openAtEnd = openAtEnd;
return this;
}
private File resolve(String revision) throws DocAsCodeException {
String path = getRepository().relativize(file);
Map<String, org.eclipse.aether.artifact.Artifact> artifactMap =
((DocAsCodeRepository) getRepository().addListener(this)).chrono().toArtifactFileMap();
if (artifactMap.keySet().contains(path)){
if (revision.equals("WorkTree")){
return file;
}
org.eclipse.aether.artifact.Artifact artifact = artifactMap.get(path);
List<Version> listVersion = getRepository().mvn()
.addRemoteRepositories(null) //default repository
.getVersionRange(artifact);
List<String> listVersionString = new ArrayList<>();
for (Version v : listVersion){
listVersionString.add(v.toString());
}
if (listVersionString.contains(revision) ||
(!listVersionString.isEmpty() && revision.equals("LATEST")) ){
artifact = artifact.setVersion(revision);
ArtifactResult artifactResult = getRepository().mvn().resolve(artifact);
return artifactResult.getArtifact().getFile();
}
}
try (RevWalk revWalk = new RevWalk(getRepository().git())){
ObjectId revisionId = getRepository().git().resolve(revision);
if (revisionId!= null){
RevCommit commit = revWalk.parseCommit(revisionId);
return new GitRetriever()
.setCommit(commit)
.setPath(path)
.setRepository(getRepository().git())
.toDir(new File(
getRepository().getTmpDir().getAbsolutePath(),
commit.getName()))
.call();
} else {
Event e = new Event(this);
e.setMessage(String.format(
"File '%s' not found at revision '%s'...",
path,
revision));
fireEvent(e);
return null;
}
} catch (IOException e) {
throw new DocAsCodeException(
String.format(
"Revision '%s' not found in git repository",
revision),
e
);
}
}
@Override
public DiffCommand call() throws DocAsCodeException {
File newFile;
if (newRevision == null){
newFile = file;
newRevision = "WorkTree";
} else {
newFile = resolve(newRevision);
}
if (revision==null){
revision = oldRevision+":"+newRevision;
}
File oldFile = resolve(oldRevision);
try {
Files.deleteIfExists(Paths.get(toFile.getAbsolutePath()));
toFile.getParentFile().mkdirs();
if (!toFile.createNewFile()){
throw new DocAsCodeException(
String.format(
"Unable to create file '%s'",
toFile));
}
} catch (IOException e) {
throw new DocAsCodeException(
String.format(
"Unable to create file '%s'",
toFile),e);
}
Differencer diff = (Differencer) new Differencer().addListener(this);
diff.setBaseFile(oldFile)
.setRevisedFile(newFile)
.setRevision(this.revision)
.setTargetFile(toFile)
.openAtEnd(openAtEnd)
.diff();
return this;
}
}