diff --git a/src/main/java/io/jenkins/plugins/forensics/miner/CommitStatisticsBuildAction.java b/src/main/java/io/jenkins/plugins/forensics/miner/CommitStatisticsBuildAction.java new file mode 100644 index 00000000..bb60b001 --- /dev/null +++ b/src/main/java/io/jenkins/plugins/forensics/miner/CommitStatisticsBuildAction.java @@ -0,0 +1,90 @@ +package io.jenkins.plugins.forensics.miner; + +import java.io.Serializable; +import java.util.Collection; +import java.util.Collections; + +import edu.umd.cs.findbugs.annotations.CheckForNull; +import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; + +import hudson.model.Action; +import hudson.model.InvisibleAction; +import hudson.model.Run; +import jenkins.model.RunAction2; +import jenkins.tasks.SimpleBuildStep.LastBuildAction; + +import io.jenkins.plugins.forensics.reference.ReferenceBuild; + +/** + * Controls the life cycle of the commit statistics in a job. This action persists the results of a build and displays a + * summary on the build page. The actual visualization of the results is defined in the matching {@code summary.jelly} + * file. + * + * @author Ullrich Hafner + */ +@SuppressWarnings("PMD.DataClass") +public class CommitStatisticsBuildAction extends InvisibleAction implements LastBuildAction, RunAction2, Serializable { + private static final long serialVersionUID = -263122257268060032L; + + @SuppressFBWarnings(value = "SE", justification = "transient field owner ist restored using a Jenkins callback") + private transient Run owner; + + private final String scmKey; + private final CommitStatistics commitStatistics; + + /** + * Creates a new instance of {@link CommitStatisticsBuildAction}. + * + * @param owner + * the associated build that created the statistics + * @param scmKey + * key of the repository + * @param commitStatistics + * the statistics to persist with this action + */ + public CommitStatisticsBuildAction(final Run owner, + final String scmKey, final CommitStatistics commitStatistics) { + super(); + + this.owner = owner; + this.scmKey = scmKey; + this.commitStatistics = commitStatistics; + } + + public Run getOwner() { + return owner; + } + + public String getScmKey() { + return scmKey; + } + + public CommitStatistics getCommitStatistics() { + return commitStatistics; + } + + @CheckForNull + public ReferenceBuild getReferenceBuild() { + return getOwner().getAction(ReferenceBuild.class); + } + + @Override + public String toString() { + return String.format("%s [%s]", scmKey, commitStatistics); + } + + @Override + public void onAttached(final Run run) { + owner = run; + } + + @Override + public void onLoad(final Run run) { + owner = run; + } + + @Override + public Collection getProjectActions() { + return Collections.emptyList(); + } +} diff --git a/src/main/java/io/jenkins/plugins/forensics/miner/ForensicsBuildAction.java b/src/main/java/io/jenkins/plugins/forensics/miner/ForensicsBuildAction.java index 34011f98..24540ca8 100644 --- a/src/main/java/io/jenkins/plugins/forensics/miner/ForensicsBuildAction.java +++ b/src/main/java/io/jenkins/plugins/forensics/miner/ForensicsBuildAction.java @@ -11,23 +11,24 @@ import io.jenkins.plugins.util.BuildAction; /** - * Controls the live cycle of the forensics results in a job. This action persists the results of a build and displays a + * Controls the life cycle of the forensics results in a job. This action persists the results of a build and displays a * summary on the build page. The actual visualization of the results is defined in the matching {@code summary.jelly} * file. This action also provides access to the forensics details: these are rendered using a new view instance. * * @author Ullrich Hafner */ +@SuppressWarnings("PMD.DataClass") public class ForensicsBuildAction extends BuildAction implements StaplerProxy { private static final long serialVersionUID = -263122257268060032L; private static final String DEFAULT_FILE_NAME = "repository-statistics.xml"; - private final int numberOfFiles; private final int miningDurationSeconds; private final String urlName; private String scmKey; // since 0.9.0 private String fileName; // since 0.9.0 + private final int numberOfFiles; private final int totalLinesOfCode; // since 1.1.0 private final int totalChurn; // since 1.1.0 private CommitStatistics commitStatistics; // since 1.1.0 diff --git a/src/main/java/io/jenkins/plugins/forensics/miner/RepositoryMinerStep.java b/src/main/java/io/jenkins/plugins/forensics/miner/RepositoryMinerStep.java index 0cca6a6e..a747a8da 100644 --- a/src/main/java/io/jenkins/plugins/forensics/miner/RepositoryMinerStep.java +++ b/src/main/java/io/jenkins/plugins/forensics/miner/RepositoryMinerStep.java @@ -37,6 +37,8 @@ *
  • total number of different authors
  • *
  • creation time
  • *
  • last modification time
  • + *
  • lines of code (from the commit details)
  • + *
  • code churn (changed lines since created)
  • * * Stores the created statistics in a {@link RepositoryStatistics} instance. The result is attached to * a {@link Run} by registering a {@link ForensicsBuildAction}. @@ -62,6 +64,7 @@ public RepositoryMinerStep() { * * @return this */ + @SuppressWarnings("unused") @SuppressFBWarnings(value = "RCN_REDUNDANT_NULLCHECK_OF_NONNULL_VALUE", justification = "Deserialization of instances that do not have all fields yet") protected Object readResolve() { if (scm == null) { diff --git a/src/main/resources/io/jenkins/plugins/forensics/miner/CommitStatisticsBuildAction/summary.jelly b/src/main/resources/io/jenkins/plugins/forensics/miner/CommitStatisticsBuildAction/summary.jelly new file mode 100644 index 00000000..443e0098 --- /dev/null +++ b/src/main/resources/io/jenkins/plugins/forensics/miner/CommitStatisticsBuildAction/summary.jelly @@ -0,0 +1,26 @@ + + + + + ${%title}: ${it.scmKey} + +
      +
    • + Commits: ${s.commitCount} - + + + compared to target branch of build + + compared to previous build + +
    • +
    • + Changed files: ${s.filesCount} +
    • +
    • + Changed lines: ${s.addedLines} added, ${s.deletedLines} deleted +
    • +
    +
    + +
    diff --git a/src/main/resources/io/jenkins/plugins/forensics/miner/CommitStatisticsBuildAction/summary.properties b/src/main/resources/io/jenkins/plugins/forensics/miner/CommitStatisticsBuildAction/summary.properties new file mode 100644 index 00000000..3c096b16 --- /dev/null +++ b/src/main/resources/io/jenkins/plugins/forensics/miner/CommitStatisticsBuildAction/summary.properties @@ -0,0 +1 @@ +title=Commit Diff Statistics diff --git a/src/main/resources/io/jenkins/plugins/forensics/miner/ForensicsBuildAction/summary.jelly b/src/main/resources/io/jenkins/plugins/forensics/miner/ForensicsBuildAction/summary.jelly index 04ef129b..cf266e05 100644 --- a/src/main/resources/io/jenkins/plugins/forensics/miner/ForensicsBuildAction/summary.jelly +++ b/src/main/resources/io/jenkins/plugins/forensics/miner/ForensicsBuildAction/summary.jelly @@ -13,10 +13,7 @@ New commits: ${s.commitCount} (from ${s.authorCount} authors in ${s.filesCount} files)
  • - New added lines: ${s.addedLines} -
  • -
  • - New deleted lines: ${s.deletedLines} + Changed lines: ${s.addedLines} added, ${s.deletedLines} deleted
  • Miner runtime: ${it.miningDurationSeconds} seconds diff --git a/src/main/webapp/icons/LICENSE.txt b/src/main/webapp/icons/LICENSE.txt index 69fbbd56..b5d249c5 100644 --- a/src/main/webapp/icons/LICENSE.txt +++ b/src/main/webapp/icons/LICENSE.txt @@ -1,4 +1,4 @@ -License for FontAwesome icon: CC BY 4.0 License +License for FontAwesome icons: CC BY 4.0 License https://fontawesome.com/license/free diff --git a/src/main/webapp/icons/diff-stat-24x24.png b/src/main/webapp/icons/diff-stat-24x24.png new file mode 100644 index 00000000..566c7a08 Binary files /dev/null and b/src/main/webapp/icons/diff-stat-24x24.png differ diff --git a/src/main/webapp/icons/diff-stat-48x48.png b/src/main/webapp/icons/diff-stat-48x48.png new file mode 100644 index 00000000..4619f45f Binary files /dev/null and b/src/main/webapp/icons/diff-stat-48x48.png differ diff --git a/src/test/resources/design.puml b/src/test/resources/design.puml index dd5ced63..e909e65a 100644 --- a/src/test/resources/design.puml +++ b/src/test/resources/design.puml @@ -14,6 +14,7 @@ skinparam component { [Blamer] --> [Utilities] [Miner] --> [Utilities] +[Miner] -> [Reference Recorder] [Reference Recorder] --> [Utilities] @enduml