Skip to content

Instantly share code, notes, and snippets.

@chrisdavidmills
Created September 2, 2013 15:49
Show Gist options
  • Save chrisdavidmills/6414344 to your computer and use it in GitHub Desktop.
Save chrisdavidmills/6414344 to your computer and use it in GitHub Desktop.
package nightBuild.jobs;
import java.io.File;
import java.io.IOException;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Deque;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.consulo.compiler.server.rmi.CompilerServerInterface;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.eclipse.egit.github.core.Repository;
import org.eclipse.egit.github.core.RepositoryCommit;
import org.eclipse.egit.github.core.client.GitHubClient;
import org.eclipse.egit.github.core.client.PageIterator;
import org.eclipse.egit.github.core.service.CommitService;
import org.eclipse.egit.github.core.service.RepositoryService;
import org.eclipse.jgit.api.CloneCommand;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.lib.EmptyProgressMonitor;
import org.eclipse.jgit.util.FileUtils;
import nightBuild.BuildManager;
import nightBuild.build.consulo.ConsuloConnector;
import nightBuild.build.consulo.LocalCompilerClientImpl;
import nightBuild.model.BuildJob;
import nightBuild.model.BuildJobProvider;
import nightBuild.model.BuildProcessor;
import nightBuild.model.BuildProperties;
import play.Play;
/**
* @author VISTALL
* @since 20:35/01.09.13
*/
public class TestBuildJobProvider implements BuildJobProvider
{
private static final String LAST_COMMIT = "lastCommit";
@Override
public void tryToCreateJob(final BuildManager buildManager)
{
buildManager.addJob("consulo-worker", this, new BuildProcessor()
{
@Override
public void process(BuildJob buildJob) throws Exception
{
GitHubClient client = new GitHubClient();
RepositoryService repositoryService = new RepositoryService(client);
CommitService commitService = new CommitService(client);
List<RepoInfo> tasks = new ArrayList<RepoInfo>();
List<Repository> repos = repositoryService.getOrgRepositories("consulo");
for(Repository repository : repos)
{
//TODO [VISTALL] hack
if("consulo-emmet".equals(repository.getName()) ||
"consulo-google-gwt".equals(repository.getName()) ||
"consulo-javascript".equals(repository.getName()) ||
"consulo-manifest".equals(repository.getName()))
{
PageIterator<RepositoryCommit> collections = commitService.pageCommits(repository, 1);
if(!collections.hasNext())
{
continue;
}
BuildProperties properties = buildManager.getProperties(TestBuildJobProvider.class.getSimpleName() + ":" + repository.getName());
Collection<RepositoryCommit> collection = collections.next();
RepositoryCommit commit = collection.iterator().next();
String sha = commit.getSha();
String lastSha = properties.getString(LAST_COMMIT);
if(lastSha == null || !lastSha.equals(sha))
{
properties.set(LAST_COMMIT, sha);
RepoInfo repoInfo = new RepoInfo(repository.getName(), repository.getCloneUrl(), sha);
final File file = new File(Play.tmpDir, repository.getName() + buildJob.id);
repoInfo.file = file;
tasks.add(repoInfo);
cloneRepo(buildJob, file, repository);
}
}
}
if(tasks.isEmpty())
{
buildJob.done();
return;
}
buildJob.setProcessMessage("Calculating depends");
SAXReader reader = new SAXReader(false);
for(RepoInfo task : tasks)
{
File options = new File(task.file, ".options");
if(!options.exists())
{
continue;
}
Document read = reader.read(options);
Element rootElement = read.getRootElement();
List<Element> dep = rootElement.elements("dep");
for(Element element : dep)
{
task.deps.add(element.getTextTrim());
}
}
buildJob.setProcessMessage("Calculating for processing");
Collections.sort(tasks, RepoInfoComparator.INSTANCE);
resolveDepends(tasks);
buildJob.setProcessMessage("Processing tasks");
Deque<BuildJob> jobs = new ArrayDeque<BuildJob>();
for(RepoInfo repoInfo : tasks)
{
jobs.add(startBuild(buildManager, repoInfo, jobs));
}
for(BuildJob job : jobs)
{
job.start();
}
buildJob.done();
}
});
}
private BuildJob startBuild(final BuildManager buildManager, final RepoInfo repoInfo, final Deque<BuildJob> repoInfos)
{
return buildManager.addJobAndNotRun(repoInfo.name, TestBuildJobProvider.this, new BuildProcessor()
{
@Override
public void process(BuildJob buildJob) throws Exception
{
buildJob.setProcessMessage("Waiting");
while(true)
{
BuildJob first = repoInfos.peekFirst();
if(first != buildJob)
{
Thread.sleep(5000L);
continue;
}
copyDepends(buildJob, repoInfo);
buildJob.setProcessMessage("Compile starting");
CompilerServerInterface connect = new ConsuloConnector().connect();
connect.compile(new LocalCompilerClientImpl(repoInfo.file, buildJob, repoInfos));
break;
}
}
});
}
private void copyDepends(BuildJob buildJob, RepoInfo repoInfo)
{
List<RepoInfo> depInstances = repoInfo.depInstances;
if(depInstances.isEmpty())
{
return;
}
buildJob.setProcessMessage("Copy depends");
for(RepoInfo depInstance : depInstances)
{
File src = new File(depInstance.file, "out/artifacts/dist");
File desc = new File(repoInfo.file, "dep");
desc.mkdirs();
try
{
org.apache.commons.io.FileUtils.copyDirectory(src, desc);
}
catch(IOException e)
{
e.printStackTrace();
}
}
}
private void resolveDepends(List<RepoInfo> repoInfos)
{
Map<String, RepoInfo> map = new HashMap<String, RepoInfo>();
for(RepoInfo repoInfo : repoInfos)
{
map.put(repoInfo.name, repoInfo);
}
for(RepoInfo repoInfo : repoInfos)
{
for(String dep : repoInfo.deps)
{
RepoInfo depend = map.get(dep);
if(depend != null)
{
repoInfo.depInstances.add(depend);
}
}
}
}
private void cloneRepo(final BuildJob buildJob, File file, Repository repository) throws Exception
{
try
{
FileUtils.delete(file, FileUtils.RECURSIVE);
}
catch(IOException e)
{
//
}
buildJob.setProcessMessage("Starting clone: " + repository.getName());
CloneCommand clone = Git.cloneRepository().setDirectory(file).setProgressMonitor(new EmptyProgressMonitor()
{
@Override
public void beginTask(String title, int totalWork)
{
buildJob.setProcessMessage(title + ": " + totalWork);
}
}).setURI(repository.getCloneUrl());
clone.call();
buildJob.setProcessMessage("Clone finished: " + repository.getName());
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment