Last active
August 31, 2020 17:08
-
-
Save fbricon/4028e0e2dda01acd0e7bd0f3e3c2ed63 to your computer and use it in GitHub Desktop.
Generate changelogs
This file contains 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
//usr/bin/env jbang "$0" "$@" ; exit $? | |
//DEPS com.google.code.gson:gson:2.8.6 | |
import java.io.InputStream; | |
import java.io.InputStreamReader; | |
import java.io.Reader; | |
import java.net.URL; | |
import java.net.URLConnection; | |
import java.util.ArrayList; | |
import java.util.LinkedHashMap; | |
import java.util.List; | |
import java.util.Map; | |
import java.util.Objects; | |
import java.util.stream.Stream; | |
import com.google.gson.Gson; | |
/** | |
* Generate changelog for a release. Requires | |
* <a href="https://github.com/maxandersen/jbang">j'bang</a> to be installed. | |
* <p> | |
* Execute with: | |
* <ul> | |
* <li><code>jbang GenerateChangelog.java repo1/milestone/number1 repoN/milestone/numberN ...</code></li> | |
* <li>eg. <code>jbang GenerateChangelog.java | |
* https://github.com/eclipse/lemminx/milestone/14 | |
* https://github.com/eclipse/lemminx/milestone/13 | |
* | |
* </ul> | |
* </p> | |
*/ | |
public class GenerateChangelog { | |
private static final Map<String, List<Issue>> labeledIssues = new LinkedHashMap<>(); | |
public static void main(String[] args) throws Exception { | |
for (String repo : args) { | |
String url = repo.replace("https://github.com/", "https://api.github.com/repos/") | |
.replace("/milestone/", "/issues?state=closed&milestone="); | |
fillIssues(url); | |
} | |
// Performance | |
generateIssues("performance -", labeledIssues.get("performance")); | |
// enhancement | |
generateIssues("enhancement -", labeledIssues.get("enhancement")); | |
// Bug Fixes | |
generateIssues("bug fix -", labeledIssues.get("bug")); | |
// Performance | |
generateIssues("build -", labeledIssues.get("build")); | |
// Other | |
generateIssues("other -", labeledIssues.get("other")); | |
System.exit(0); | |
} | |
private static void generateIssues(String title, List<Issue> list) { | |
if (list == null) { | |
return; | |
} | |
for (Issue issue : list) { | |
String url = issue.html_url; | |
String number = url.substring(url.lastIndexOf("/") + 1); | |
String line = " * " + title + " " + issue.title + ". See [#" + number + "](" + url + ")."; | |
generateLine(line); | |
} | |
} | |
private static void generateLine(String line) { | |
System.out.println(line); | |
} | |
private static void fillIssues(String url) throws Exception { | |
int page = 1; | |
boolean hasMore = true; | |
do { | |
String pageUrl = url+"&page="+(page++); | |
System.out.println("Fetching issues from " + pageUrl); | |
URL u = new URL(pageUrl); | |
URLConnection connection = u.openConnection(); | |
try (InputStream in = connection.getInputStream()) { | |
Reader reader = new InputStreamReader(in, "UTF-8"); | |
Issue[] issues = new Gson().fromJson(reader, Issue[].class); | |
hasMore = issues.length == 30; | |
Stream.of(issues).filter(Issue::isValid).forEach(i -> { | |
labeledIssues.computeIfAbsent(i.getMainLabel(), k -> new ArrayList<>()).add(i); | |
}); | |
} | |
} while (hasMore); | |
} | |
static class Label { | |
public String name; | |
} | |
static class Issue { | |
private static String[] SIGNIFICANT_LABELS = { "build", "enhancement", "bug", "performance", "other" }; | |
String html_url; | |
String title; | |
Label[] labels; | |
public String getMainLabel() { | |
String mainLabel = findLabel(SIGNIFICANT_LABELS); | |
return mainLabel == null ? "other" : mainLabel; | |
} | |
public String findLabel(String... names) { | |
if (labels != null) { | |
for (Label label : labels) { | |
for (String name : names) { | |
if (Objects.equals(label.name, name)) { | |
return name; | |
} | |
} | |
} | |
} | |
return null; | |
} | |
public boolean isValid() { | |
return findLabel("invalid") == null; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment