Skip to content

Commit

Permalink
Merge pull request #163 from stephenc/lightweight-changelog
Browse files Browse the repository at this point in the history
[JENKINS-47585] Implement lightweight changelog
  • Loading branch information
stephenc committed Dec 18, 2017
2 parents 3bf8714 + cc8d912 commit a3b8a4c
Showing 1 changed file with 105 additions and 3 deletions.
@@ -1,7 +1,7 @@
/*
* The MIT License
*
* Copyright (c) 2016 CloudBees, Inc.
* Copyright (c) 2016-2017 CloudBees, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
Expand Down Expand Up @@ -30,8 +30,13 @@
import edu.umd.cs.findbugs.annotations.NonNull;
import hudson.Extension;
import hudson.model.Item;
import hudson.plugins.git.GitSCM;
import hudson.scm.SCM;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.charset.StandardCharsets;
import java.util.Locale;
import java.util.Objects;
import jenkins.plugins.git.AbstractGitSCMSource;
import jenkins.plugins.git.GitTagSCMRevision;
import jenkins.scm.api.SCMFile;
Expand All @@ -40,14 +45,19 @@
import jenkins.scm.api.SCMRevision;
import jenkins.scm.api.SCMSource;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.time.FastDateFormat;
import org.eclipse.jgit.lib.Constants;
import org.kohsuke.github.GHCommit;
import org.kohsuke.github.GHRef;
import org.kohsuke.github.GHRepository;
import org.kohsuke.github.GHUser;
import org.kohsuke.github.GHTagObject;
import org.kohsuke.github.GitHub;
import org.kohsuke.github.HttpException;

/**
* Implements {@link SCMFileSystem} for GitHub.
*/
public class GitHubSCMFileSystem extends SCMFileSystem implements GitHubClosable {
private final GitHub gitHub;
private final GHRepository repo;
Expand Down Expand Up @@ -83,6 +93,9 @@ protected GitHubSCMFileSystem(GitHub gitHub, GHRepository repo, String refName,
}
}

/**
* {@inheritDoc}
*/
@Override
public void close() throws IOException {
synchronized (this) {
Expand All @@ -94,17 +107,94 @@ public void close() throws IOException {
Connector.release(gitHub);
}

/**
* {@inheritDoc}
*/
@Override
public synchronized boolean isOpen() {
return open;
}

/**
* {@inheritDoc}
*/
@Override
public long lastModified() throws IOException {
// TODO figure out how to implement this
return 0L;
return repo.getCommit(ref).getCommitDate().getTime();
}

/**
* {@inheritDoc}
*/
@Override
public boolean changesSince(SCMRevision revision, @NonNull OutputStream changeLogStream)
throws UnsupportedOperationException, IOException, InterruptedException {
if (Objects.equals(getRevision(), revision)) {
// special case where somebody is asking one of two stupid questions:
// 1. what has changed between the latest and the latest
// 2. what has changed between the current revision and the current revision
return false;
}
int count = 0;
FastDateFormat iso = FastDateFormat.getInstance("yyyy-MM-dd'T'HH:mm:ssZ");
StringBuilder log = new StringBuilder(1024);
String endHash;
if (revision instanceof AbstractGitSCMSource.SCMRevisionImpl) {
endHash = ((AbstractGitSCMSource.SCMRevisionImpl) revision).getHash().toLowerCase(Locale.ENGLISH);
} else {
endHash = null;
}
// this is the format expected by GitSCM, so we need to format each GHCommit with the same format
// commit %H%ntree %T%nparent %P%nauthor %aN <%aE> %ai%ncommitter %cN <%cE> %ci%n%n%w(76,4,4)%s%n%n%b
for (GHCommit commit: repo.queryCommits().from(ref).pageSize(GitSCM.MAX_CHANGELOG).list()) {
if (commit.getSHA1().toLowerCase(Locale.ENGLISH).equals(endHash)) {
break;
}
log.setLength(0);
log.append("commit ").append(commit.getSHA1()).append('\n');
log.append("tree ").append(commit.getTree().getSha()).append('\n');
log.append("parent");
for (String parent: commit.getParentSHA1s()) {
log.append(' ').append(parent);
}
log.append('\n');
GHCommit.ShortInfo info = commit.getCommitShortInfo();
log.append("author ")
.append(info.getAuthor().getName())
.append(" <")
.append(info.getAuthor().getEmail())
.append("> ")
.append(iso.format(info.getAuthoredDate()))
.append('\n');
log.append("committer ")
.append(info.getCommitter().getName())
.append(" <")
.append(info.getCommitter().getEmail())
.append("> ")
.append(iso.format(info.getCommitDate()))
.append('\n');
log.append('\n');
String msg = info.getMessage();
if (msg.endsWith("\r\n")) {
msg = msg.substring(0, msg.length() - 2);
} else if (msg.endsWith("\n")) {
msg = msg.substring(0, msg.length() - 1);
}
msg = msg.replace("\r\n", "\n").replace("\r", "\n").replace("\n", "\n ");
log.append(" ").append(msg).append('\n');
changeLogStream.write(log.toString().getBytes(StandardCharsets.UTF_8));
changeLogStream.flush();
count++;
if (count >= GitSCM.MAX_CHANGELOG) {
break;
}
}
return count > 0;
}

/**
* {@inheritDoc}
*/
@NonNull
@Override
public SCMFile getRoot() {
Expand All @@ -114,22 +204,34 @@ public SCMFile getRoot() {
@Extension
public static class BuilderImpl extends SCMFileSystem.Builder {

/**
* {@inheritDoc}
*/
@Override
public boolean supports(SCM source) {
// TODO implement a GitHubSCM so we can work for those
return false;
}

/**
* {@inheritDoc}
*/
@Override
public boolean supports(SCMSource source) {
return source instanceof GitHubSCMSource;
}

/**
* {@inheritDoc}
*/
@Override
public SCMFileSystem build(@NonNull Item owner, @NonNull SCM scm, @CheckForNull SCMRevision rev) {
return null;
}

/**
* {@inheritDoc}
*/
@Override
public SCMFileSystem build(@NonNull SCMSource source, @NonNull SCMHead head, @CheckForNull SCMRevision rev)
throws IOException, InterruptedException {
Expand Down

0 comments on commit a3b8a4c

Please sign in to comment.