Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Generate markdown and summary-only reports #77

Merged
merged 5 commits into from
Aug 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions README.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ oldArchives:: The jar files which will be used as the baseline for comparison. T
newArchives:: The jar files we want to analyze. Type: Type: _FileCollection_.
onlyModified:: Outputs only modified classes/methods. If not set to true, all classes and methods are printed. Type: _boolean_. Default value: _false_
onlyBinaryIncompatibleModified:: Outputs only classes/methods with modifications that result in binary incompatibility. Type: _boolean_. Default value: _false_
reportOnlySummary:: Reports only a breakdown of classes and their status. Type: _boolean_. Default value: _false_
packageIncludes:: List of package names to include, * can be used as wildcard. Type: _List<String>_
packageExcludes:: List of package names to exclude, * can be used as wildcard. Type: _List<String>_
classIncludes:: List of classes to include. Type: _List<String>_
Expand All @@ -68,6 +69,7 @@ failOnSourceIncompatibility:: Fails if the changes result in source level incomp
failOnModification:: When set to true, the build fails in case a modification has been detected. Type: _boolean_. Default value: _false_
xmlOutputFile:: Path to the generated XML report. Type: _File_. Default value: _null_
htmlOutputFile:: Path to the generated HTML report. Type: _File_. Default value: _null_
mdOutputFile:: Path to the generated Markdown report. Type: _File_. Default value: _null_
txtOutputFile:: Path to the generated TXT report. Type: _File_. Default value: _null_
semverOutputFile:: Path to the generated semantic versioning report. Type: _File_. Default value: _null_
includeSynthetic:: Synthetic classes and class members (like e.g. bridge methods) are not tracked per default. This new option enables the tracking of such kind of classes and class members
Expand Down
2 changes: 1 addition & 1 deletion build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ buildScanRecipes {
}

dependencies {
api("com.github.siom79.japicmp:japicmp:0.22.0") {
api("com.github.siom79.japicmp:japicmp:0.23.0") {
exclude(group = "com.google.guava")
exclude(group = "io.airlift")
exclude(group = "javax.xml.bind")
Expand Down
19 changes: 19 additions & 0 deletions src/main/java/me/champeau/gradle/japicmp/JApiCmpWorkerAction.java
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
import japicmp.output.html.HtmlOutput;
import japicmp.output.html.HtmlOutputGenerator;
import japicmp.output.html.HtmlOutputGeneratorOptions;
import japicmp.output.markdown.MarkdownOutputGenerator;
import japicmp.output.semver.SemverOut;
import japicmp.output.stdout.StdoutOutputGenerator;
import japicmp.output.xml.XmlOutput;
Expand Down Expand Up @@ -100,10 +101,12 @@ public JApiCmpWorkerAction(final JapiCmpWorkerConfiguration configuration) {
configuration.newArchives,
configuration.onlyModified,
configuration.onlyBinaryIncompatibleModified,
configuration.reportOnlySummary,
configuration.failOnSourceIncompatibility,
configuration.accessModifier,
configuration.xmlOutputFile,
configuration.htmlOutputFile,
configuration.mdOutputFile,
configuration.txtOutputFile,
configuration.semverOutputFile,
configuration.failOnModification,
Expand Down Expand Up @@ -227,6 +230,7 @@ private void generateOutput(JarArchiveComparator jarArchiveComparator) {
options.setReportOnlyFilename(true);
options.setOutputOnlyModifications(onlyModified);
options.setOutputOnlyBinaryIncompatibleModifications(onlyBinaryIncompatibleModified);
options.setReportOnlySummary(reportOnlySummary);
options.setIncludeSynthetic(includeSynthetic);
options.setAccessModifier(AccessModifier.valueOf(accessModifier.toUpperCase()));
File reportFile = null;
Expand Down Expand Up @@ -261,6 +265,21 @@ private void generateOutput(JarArchiveComparator jarArchiveComparator) {
reportFile = htmlOutputFile;
}

if (mdOutputFile != null) {
MarkdownOutputGenerator markdownOutputGenerator = new MarkdownOutputGenerator(options, jApiClasses);
String output = markdownOutputGenerator.generate();
try (BufferedWriter writer = new BufferedWriter(
new OutputStreamWriter(new FileOutputStream(mdOutputFile), StandardCharsets.UTF_8)
)) {
writer.write(output);
} catch (IOException ex) {
throw new GradleException("Unable to write markdown report", ex);
}
if (reportFile == null) {
reportFile = mdOutputFile;
}
}

if (txtOutputFile != null) {
StdoutOutputGenerator stdoutOutputGenerator = new StdoutOutputGenerator(options, jApiClasses);
String output = stdoutOutputGenerator.generate();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,12 @@ public class JapiCmpWorkerConfiguration implements Serializable {
protected final List<JApiCmpWorkerAction.Archive> newArchives;
protected final boolean onlyModified;
protected final boolean onlyBinaryIncompatibleModified;
protected final boolean reportOnlySummary;
protected final boolean failOnSourceIncompatibility;
protected final String accessModifier;
protected final File xmlOutputFile;
protected final File htmlOutputFile;
protected final File mdOutputFile;
protected final File txtOutputFile;
protected final File semverOutputFile;
protected final boolean failOnModification;
Expand All @@ -74,10 +76,12 @@ public JapiCmpWorkerConfiguration(final boolean includeSynthetic,
final List<JApiCmpWorkerAction.Archive> newArchives,
final boolean onlyModified,
final boolean onlyBinaryIncompatibleModified,
final boolean reportOnlySummary,
final boolean failOnSourceIncompatibility,
final String accessModifier,
final File xmlOutputFile,
final File htmlOutputFile,
final File mdOutputFile,
final File txtOutputFile,
final File semverOutputFile,
final boolean failOnModification,
Expand All @@ -103,10 +107,12 @@ public JapiCmpWorkerConfiguration(final boolean includeSynthetic,
this.newArchives = newArchives;
this.onlyModified = onlyModified;
this.onlyBinaryIncompatibleModified = onlyBinaryIncompatibleModified;
this.reportOnlySummary = reportOnlySummary;
this.failOnSourceIncompatibility = failOnSourceIncompatibility;
this.accessModifier = accessModifier;
this.xmlOutputFile = xmlOutputFile;
this.htmlOutputFile = htmlOutputFile;
this.mdOutputFile = mdOutputFile;
this.txtOutputFile = txtOutputFile;
this.semverOutputFile = semverOutputFile;
this.failOnModification = failOnModification | failOnSourceIncompatibility;
Expand Down
10 changes: 10 additions & 0 deletions src/main/java/me/champeau/gradle/japicmp/JapicmpTask.java
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ public JapicmpTask() {
getFailOnSourceIncompatibility().convention(false);
getIgnoreMissingClasses().convention(false);
getIncludeSynthetic().convention(false);
getReportOnlySummary().convention(false);
getOnlyBinaryIncompatibleModified().convention(false);
getOnlyModified().convention(false);
getAccessModifier().convention("public");
Expand Down Expand Up @@ -128,10 +129,12 @@ private JapiCmpWorkerConfiguration calculateWorkerConfiguration(List<JApiCmpWork
current,
getOnlyModified().get(),
getOnlyBinaryIncompatibleModified().get(),
getReportOnlySummary().get(),
getFailOnSourceIncompatibility().get(),
getAccessModifier().get(),
maybeFile(getXmlOutputFile()),
maybeFile(getHtmlOutputFile()),
maybeFile(getMdOutputFile()),
maybeFile(getTxtOutputFile()),
maybeFile(getSemverOutputFile()),
getFailOnModification().get(),
Expand Down Expand Up @@ -298,6 +301,9 @@ public void addExcludeFilter(Class<? extends Filter> excludeFilterClass) {
@Input
public abstract Property<Boolean> getOnlyBinaryIncompatibleModified();

@Input
public abstract Property<Boolean> getReportOnlySummary();

@Input
public abstract Property<Boolean> getFailOnSourceIncompatibility();

Expand All @@ -309,6 +315,10 @@ public void addExcludeFilter(Class<? extends Filter> excludeFilterClass) {
@Optional
public abstract RegularFileProperty getHtmlOutputFile();

@OutputFile
@Optional
public abstract RegularFileProperty getMdOutputFile();

@OutputFile
@Optional
public abstract RegularFileProperty getTxtOutputFile();
Expand Down
8 changes: 8 additions & 0 deletions src/test/groovy/me/champeau/gradle/BaseFunctionalTest.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,10 @@ abstract class BaseFunctionalTest extends Specification {
}
}

void hasmarkdownReport(String lookup = '') {
hasReport('japi', 'md', lookup)
}

void hasTextReport(String lookup = '') {
hasReport('japi', 'txt', lookup)
}
Expand All @@ -68,6 +72,10 @@ abstract class BaseFunctionalTest extends Specification {
hasReport('rich', 'html', lookup)
}

void noMarkdownReport() {
assert !getReport('japi', 'md').exists()
}

void noTxtReport() {
assert !getReport('japi', 'txt').exists()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ class BomFunctionalTest extends BaseFunctionalTest {
hasTextReport('CLASS FILE FORMAT VERSION: 50.0 <- 50.0')
noSemverReport()
noHtmlReport()
noMarkdownReport()
noRichReport()

when:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ class ClasspathIsUsedFunctionalTest extends BaseFunctionalTest {
\t=== UNCHANGED CONSTRUCTOR: PUBLIC Subtype()
""")
noSemverReport()
noMarkdownReport()
noHtmlReport()
noRichReport()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ class Compare2JarsFunctionalTest extends BaseFunctionalTest {
hasTextReport('Comparing source compatibility of commons-lang3-3.6.jar against commons-lang3-3.5.jar')
hasTextReport('UNCHANGED CLASS: PUBLIC org.apache.commons.lang3.AnnotationUtils')
noSemverReport()
noMarkdownReport()
noHtmlReport()
noRichReport()

Expand All @@ -33,6 +34,7 @@ class Compare2JarsFunctionalTest extends BaseFunctionalTest {
hasTextReport('Comparing source compatibility of commons-lang3-3.6.jar against commons-lang3-3.5.jar')
hasTextReport('UNCHANGED CLASS: PUBLIC org.apache.commons.lang3.AnnotationUtils')
noSemverReport()
noMarkdownReport()
noHtmlReport()
noRichReport()

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ class Compare2LibrariesFunctionalTest extends BaseFunctionalTest {
hasTextReport('Comparing source compatibility of commons-lang3-3.6.jar against commons-lang3-3.5.jar')
hasTextReport('UNCHANGED CLASS: PUBLIC org.apache.commons.lang3.AnnotationUtils')
noSemverReport()
noMarkdownReport()
noHtmlReport()
noRichReport()

Expand Down
43 changes: 43 additions & 0 deletions src/test/groovy/me/champeau/gradle/ReportsFunctionalTest.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ class ReportsFunctionalTest extends BaseFunctionalTest {
\t\t\t</td>""")
hasHtmlReport('<a href="#org.apache.commons.lang3.event.EventListenerSupport">')
noTxtReport()
noMarkdownReport()
noSemverReport()
noRichReport()

Expand All @@ -42,6 +43,7 @@ class ReportsFunctionalTest extends BaseFunctionalTest {
hasRichReport('<a class=\'navbar-brand\' href=\'#\'>Binary compatibility report</a>')
hasRichReport('A test of rich report')
noTxtReport()
noMarkdownReport()
noSemverReport()
noHtmlReport()

Expand All @@ -60,6 +62,7 @@ class ReportsFunctionalTest extends BaseFunctionalTest {
result.task(":japicmpSemver").outcome == TaskOutcome.SUCCESS
hasSemverReport('0.1.0')
noTxtReport()
noMarkdownReport()
noHtmlReport()
noRichReport()

Expand All @@ -69,4 +72,44 @@ class ReportsFunctionalTest extends BaseFunctionalTest {
then:
result.task(":japicmpSemver").outcome == TaskOutcome.UP_TO_DATE
}

def "can generate a markdown report"() {
when:
def result = run 'japicmpMarkdown'

then:
result.task(":japicmpMarkdown").outcome == TaskOutcome.SUCCESS
hasmarkdownReport('# Compatibility Report')
hasmarkdownReport('- **Report only summary**: No')
noTxtReport()
noSemverReport()
noHtmlReport()
noRichReport()

when:
result = run 'japicmpMarkdown'

then:
result.task(":japicmpMarkdown").outcome == TaskOutcome.UP_TO_DATE
}

def "can generate a summary-only markdown report"() {
when:
def result = run 'japicmpMarkdownReportOnlySummary'

then:
result.task(":japicmpMarkdownReportOnlySummary").outcome == TaskOutcome.SUCCESS
hasmarkdownReport('# Compatibility Report')
hasmarkdownReport('- **Report only summary**: Yes')
noTxtReport()
noSemverReport()
noHtmlReport()
noRichReport()

when:
result = run 'japicmpMarkdownReportOnlySummary'

then:
result.task(":japicmpMarkdownReportOnlySummary").outcome == TaskOutcome.UP_TO_DATE
}
}
13 changes: 13 additions & 0 deletions src/test/test-projects/html-report/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,19 @@ task japicmpRich(type: me.champeau.gradle.japicmp.JapicmpTask) {
}
}

task japicmpMarkdown(type: me.champeau.gradle.japicmp.JapicmpTask) {
oldClasspath.from(configurations.baseline)
newClasspath.from(configurations.current)
mdOutputFile = layout.buildDirectory.file('reports/japi.md').get().asFile
}

task japicmpMarkdownReportOnlySummary(type: me.champeau.gradle.japicmp.JapicmpTask) {
oldClasspath.from(configurations.baseline)
newClasspath.from(configurations.current)
mdOutputFile = layout.buildDirectory.file('reports/japi.md').get().asFile
reportOnlySummary = true
}

task japicmpSemver(type: me.champeau.gradle.japicmp.JapicmpTask) {
oldClasspath.from(configurations.baseline)
newClasspath.from(configurations.current)
Expand Down