Created
September 2, 2013 15:49
-
-
Save chrisdavidmills/6414344 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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