package scaffolding;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.filefilter.FileFilterUtils;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.InitCommand;
import org.eclipse.jgit.api.errors.GitAPIException;
import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.atomic.AtomicInteger;
import static com.github.danielflower.mavenplugins.release.FileUtils.pathOf;
import static scaffolding.Photocopier.copyTestProjectToTemporaryLocation;
public class TestProject {
private static final MvnRunner defaultRunner = new MvnRunner(null);
private static final String PLUGIN_VERSION_FOR_TESTS = "2.1-SNAPSHOT";
public final File originDir;
public final Git origin;
public final File localDir;
public final Git local;
private final AtomicInteger commitCounter = new AtomicInteger(1);
private MvnRunner mvnRunner = defaultRunner;
private TestProject(File originDir, Git origin, File localDir, Git local) {
this.originDir = originDir;
this.origin = origin;
this.localDir = localDir;
this.local = local;
}
/**
* Runs a mvn command against the local repo and returns the console output.
*/
public List<String> mvn(String... arguments) throws IOException {
return mvnRunner.runMaven(localDir, arguments);
}
public List<String> mvnRelease(String buildNumber, String...arguments) throws IOException, InterruptedException {
return mvnRun("releaser:release", buildNumber, arguments);
}
public List<String> mvnReleaserNext(String buildNumber, String...arguments) throws IOException, InterruptedException {
return mvnRun("releaser:next", buildNumber, arguments);
}
public TestProject commitRandomFile(String module) throws IOException, GitAPIException {
File moduleDir = new File(localDir, module);
if (!moduleDir.isDirectory()) {
throw new RuntimeException("Could not find " + moduleDir.getCanonicalPath());
}
File random = new File(moduleDir, UUID.randomUUID() + ".txt");
random.createNewFile();
String modulePath = module.equals(".") ? "" : module + "/";
local.add().addFilepattern(modulePath + random.getName()).call();
local.commit().setMessage("Commit " + commitCounter.getAndIncrement() + ": adding " + random.getName()).call();
return this;
}
public void pushIt() throws GitAPIException {
local.push().call();
}
private List<String> mvnRun(String goal, String buildNumber, String[] arguments) {
String[] args = new String[arguments.length + 2];
args[0] = "-DbuildNumber=" + buildNumber;
System.arraycopy(arguments, 0, args, 1, arguments.length);
args[args.length-1] = goal;
return mvnRunner.runMaven(localDir, args);
}
private static TestProject project(String name) {
try {
File originDir = copyTestProjectToTemporaryLocation(name);
performPomSubstitution(originDir);
InitCommand initCommand = Git.init();
initCommand.setDirectory(originDir);
Git origin = initCommand.call();
origin.add().addFilepattern(".").call();
origin.commit().setMessage("Initial commit").call();
File localDir = Photocopier.folderForSampleProject(name);
Git local = Git.cloneRepository()
.setBare(false)
.setDirectory(localDir)
.setURI(originDir.toURI().toString())
.call();
return new TestProject(originDir, origin, localDir, local);
} catch (Exception e) {
throw new RuntimeException("Error while creating copies of the test project", e);
}
}
public static void performPomSubstitution(File sourceDir) throws IOException {
File pom = new File(sourceDir, "pom.xml");
if (pom.exists()) {
String xml = FileUtils.readFileToString(pom, "UTF-8");
if (xml.contains("${scm.url}")) {
xml = xml.replace("${scm.url}", dirToGitScmReference(sourceDir));
}
xml = xml.replace("${current.plugin.version}", PLUGIN_VERSION_FOR_TESTS);
FileUtils.writeStringToFile(pom, xml, "UTF-8");
}
for (File child : sourceDir.listFiles((FileFilter)FileFilterUtils.directoryFileFilter())) {
performPomSubstitution(child);
}
}
public static String dirToGitScmReference(File sourceDir) {
return "scm:git:file://localhost/" + pathOf(sourceDir).replace('\\', '/').toLowerCase();
}
public static TestProject singleModuleProject() {
return project("single-module");
}
public static TestProject nestedProject() {
return project("nested-project");
}
public static TestProject moduleWithScmTag() {
return project("module-with-scm-tag");
}
public static TestProject moduleWithProfilesProject() {
return project("module-with-profiles");
}
public static TestProject inheritedVersionsFromParent() {
return project("inherited-versions-from-parent");
}
public static TestProject independentVersionsProject() {
return project("independent-versions");
}
public static TestProject parentAsSibilngProject() {
return project("parent-as-sibling");
}
public static TestProject deepDependenciesProject() {
return project("deep-dependencies");
}
public static TestProject moduleWithTestFailure() {
return project("module-with-test-failure");
}
public static TestProject moduleWithSnapshotDependencies() {
return project("snapshot-dependencies");
}
public static TestProject moduleWithSnapshotDependenciesWithVersionProperties() {
return project("snapshot-dependencies-with-version-properties");
}
public void setMvnRunner(MvnRunner mvnRunner) {
this.mvnRunner = mvnRunner;
}
}