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

Introduce HistoricalBuild interface #9674

Merged
merged 5 commits into from
Sep 11, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
9 changes: 5 additions & 4 deletions core/src/main/java/hudson/model/Job.java
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@
import jenkins.model.BuildDiscarder;
import jenkins.model.BuildDiscarderProperty;
import jenkins.model.DirectlyModifiableTopLevelItemGroup;
import jenkins.model.HistoricalBuild;
import jenkins.model.Jenkins;
import jenkins.model.JenkinsLocationConfiguration;
import jenkins.model.ModelObjectWithChildren;
Expand Down Expand Up @@ -632,9 +633,9 @@ protected HistoryWidget createHistoryWidget() {
throw new IllegalStateException("HistoryWidget is now created via WidgetFactory implementation");
}

public static final HistoryWidget.Adapter<Run> HISTORY_ADAPTER = new Adapter<>() {
public static final HistoryWidget.Adapter<HistoricalBuild> HISTORY_ADAPTER = new Adapter<>() {
@Override
public int compare(Run record, String key) {
public int compare(HistoricalBuild record, String key) {
try {
int k = Integer.parseInt(key);
return record.getNumber() - k;
Expand All @@ -644,12 +645,12 @@ public int compare(Run record, String key) {
}

@Override
public String getKey(Run record) {
public String getKey(HistoricalBuild record) {
return String.valueOf(record.getNumber());
}

@Override
public boolean isBuilding(Run record) {
public boolean isBuilding(HistoricalBuild record) {
return record.isBuilding();
}

Expand Down
134 changes: 23 additions & 111 deletions core/src/main/java/hudson/model/Run.java
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@
import jenkins.model.ArtifactManagerConfiguration;
import jenkins.model.ArtifactManagerFactory;
import jenkins.model.BuildDiscarder;
import jenkins.model.HistoricalBuild;
import jenkins.model.Jenkins;
import jenkins.model.JenkinsLocationConfiguration;
import jenkins.model.RunAction2;
Expand Down Expand Up @@ -153,23 +154,14 @@
*/
@ExportedBean
public abstract class Run<JobT extends Job<JobT, RunT>, RunT extends Run<JobT, RunT>>
extends Actionable implements ExtensionPoint, Comparable<RunT>, AccessControlled, PersistenceRoot, DescriptorByNameOwner, OnMaster, StaplerProxy {
extends Actionable implements ExtensionPoint, Comparable<RunT>, AccessControlled, PersistenceRoot, DescriptorByNameOwner, OnMaster, StaplerProxy, HistoricalBuild {

/**
* The original {@link Queue.Item#getId()} has not yet been mapped onto the {@link Run} instance.
* @since 1.601
*/
public static final long QUEUE_ID_UNKNOWN = -1;

/**
* Target size limit for truncated {@link #description}s in the Build History Widget.
* This is applied to the raw, unformatted description. Especially complex formatting
* like hyperlinks can result in much less text being shown than this might imply.
* Negative values will disable truncation, {@code 0} will enforce empty strings.
* @since 2.223
*/
private static /* non-final for Groovy */ int TRUNCATED_DESCRIPTION_LIMIT = SystemProperties.getInteger("historyWidget.descriptionLimit", 100);
Comment on lines -170 to -177
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Inlined in HistoricalBuild#getTruncatedDescription


protected final transient @NonNull JobT project;

/**
Expand Down Expand Up @@ -457,12 +449,12 @@ public int compareTo(@NonNull RunT that) {
}

/**
* Get the {@link Queue.Item#getId()} of the original queue item from where this Run instance
* originated.
* @return The queue item ID.
* {@inheritDoc}
*
* @since 1.601
*/
@Exported
@Override
public long getQueueId() {
return queueId;
}
Expand All @@ -478,15 +470,8 @@ public void setQueueId(long queueId) {
this.queueId = queueId;
}

/**
* Returns the build result.
*
* <p>
* When a build is {@link #isBuilding() in progress}, this method
* returns an intermediate result.
* @return The status of the build, if it has completed or some build step has set a status; may be null if the build is ongoing.
*/
@Exported
@Override
public @CheckForNull Result getResult() {
return result;
}
Expand Down Expand Up @@ -514,6 +499,7 @@ public void setResult(@NonNull Result r) {
/**
* Gets the subset of {@link #getActions()} that consists of {@link BuildBadgeAction}s.
*/
@Override
Comment on lines 505 to +508
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should Javadoc be pulled up then?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since getActions() doesn't exist on HistoricalBuild, I left it there.

public @NonNull List<BuildBadgeAction> getBadgeActions() {
List<BuildBadgeAction> r = getActions(BuildBadgeAction.class);
if (isKeepLog()) {
Expand All @@ -523,11 +509,8 @@ public void setResult(@NonNull Result r) {
return r;
}

/**
* Returns true if the build is not completed yet.
* This includes "not started yet" state.
*/
@Exported
@Override
public boolean isBuilding() {
return state.compareTo(State.POST_PRODUCTION) < 0;
}
Expand Down Expand Up @@ -646,11 +629,11 @@ public final boolean isKeepLog() {
}

/**
* When the build is scheduled.
*
* {@inheritDoc}
* @see #getStartTimeInMillis()
*/
@Exported
@Override
public @NonNull Calendar getTimestamp() {
GregorianCalendar c = new GregorianCalendar();
c.setTimeInMillis(timestamp);
Expand Down Expand Up @@ -685,73 +668,12 @@ public final long getStartTimeInMillis() {
}

@Exported
@Override
@CheckForNull
public String getDescription() {
return description;
}


/**
* Returns the length-limited description.
* The method tries to take HTML tags within the description into account, but it is a best-effort attempt.
* Also, the method will likely not work properly if a non-HTML {@link hudson.markup.MarkupFormatter} is used.
* @return The length-limited description.
* @deprecated truncated description based on the {@link #TRUNCATED_DESCRIPTION_LIMIT} setting.
*/
@Deprecated
public @CheckForNull String getTruncatedDescription() {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moved to HistoricalBuild

if (TRUNCATED_DESCRIPTION_LIMIT < 0) { // disabled
return description;
}
if (TRUNCATED_DESCRIPTION_LIMIT == 0) { // Someone wants to suppress descriptions, why not?
return "";
}

final int maxDescrLength = TRUNCATED_DESCRIPTION_LIMIT;
final String localDescription = description;
if (localDescription == null || localDescription.length() < maxDescrLength) {
return localDescription;
}

final String ending = "...";
final int sz = localDescription.length(), maxTruncLength = maxDescrLength - ending.length();

boolean inTag = false;
int displayChars = 0;
int lastTruncatablePoint = -1;

for (int i = 0; i < sz; i++) {
char ch = localDescription.charAt(i);
if (ch == '<') {
inTag = true;
} else if (ch == '>') {
inTag = false;
if (displayChars <= maxTruncLength) {
lastTruncatablePoint = i + 1;
}
}
if (!inTag) {
displayChars++;
if (displayChars <= maxTruncLength && ch == ' ') {
lastTruncatablePoint = i;
}
}
}

String truncDesc = localDescription;

// Could not find a preferred truncatable index, force a trunc at maxTruncLength
if (lastTruncatablePoint == -1)
lastTruncatablePoint = maxTruncLength;

if (displayChars >= maxDescrLength) {
truncDesc = truncDesc.substring(0, lastTruncatablePoint) + ending;
}

return truncDesc;

}

/**
* Gets the string that says how long since this build has started.
*
Expand All @@ -770,9 +692,7 @@ public String getDescription() {
return Util.XS_DATETIME_FORMATTER2.format(Instant.ofEpochMilli(timestamp));
}

/**
* Gets the string that says how long the build took to run.
*/
@Override
public @NonNull String getDurationString() {
if (hasntStartedYet()) {
return Messages.Run_NotStartedYet();
Expand All @@ -791,9 +711,7 @@ public long getDuration() {
return duration;
}

/**
* Gets the icon color for display.
*/
@Override
public @NonNull BallColor getIconColor() {
if (!isBuilding()) {
// already built
Expand Down Expand Up @@ -828,6 +746,7 @@ public String toString() {
}

@Exported
@Override
public String getFullDisplayName() {
return project.getFullDisplayName() + ' ' + getDisplayName();
}
Expand All @@ -853,6 +772,7 @@ public void setDisplayName(String value) throws IOException {
}

@Exported(visibility = 2)
@Override
public int getNumber() {
return number;
}
Expand Down Expand Up @@ -1030,14 +950,8 @@ protected void dropLinks() {
return nextBuild;
}

/**
* Returns the URL of this {@link Run}, relative to the context root of Hudson.
*
* @return
* String like "job/foo/32/" with trailing slash but no leading slash.
*/
// I really messed this up. I'm hoping to fix this some time
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lol that ship has sailed

// it shouldn't have trailing '/', and instead it should have leading '/'

@Override
public @NonNull String getUrl() {

// RUN may be accessed using permalinks, as "/lastSuccessful" or other, so try to retrieve this base URL
Expand Down Expand Up @@ -1093,6 +1007,12 @@ protected void dropLinks() {
return new File(project.getBuildDir(), Integer.toString(number));
}

@Override
public List<ParameterValue> getParameterValues() {
ParametersAction a = getAction(ParametersAction.class);
return a != null ? a.getParameters() : List.of();
}

/**
* Gets an object responsible for storing and retrieving build artifacts.
* If {@link #pickArtifactManager} has previously been called on this build,
Expand Down Expand Up @@ -2161,14 +2081,6 @@ public void doBuildStatus(StaplerRequest req, StaplerResponse rsp) throws IOExce
rsp.sendRedirect2(req.getContextPath() + "/images/48x48/" + getBuildStatusUrl());
}

public @NonNull String getBuildStatusUrl() {
return getIconColor().getImage();
}

public String getBuildStatusIconClassName() {
return getIconColor().getIconClassName();
}
Comment on lines -2178 to -2184
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moved to HistoricalBuild


public static class Summary {
/**
* Is this build worse or better, compared to the previous build?
Expand Down
4 changes: 2 additions & 2 deletions core/src/main/java/hudson/widgets/BuildHistoryWidget.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import jenkins.model.HistoricalBuild;
import jenkins.model.Jenkins;
import jenkins.model.queue.QueueItem;
import jenkins.widgets.HistoryPageFilter;
Expand All @@ -47,7 +48,7 @@
* <p>
* This widget enhances {@link HistoryWidget} by groking the notion
* that {@link #owner} can be in the queue toward the next build.
*
* @param <T> typically {@link HistoricalBuild}
* @author Kohsuke Kawaguchi
*/
public class BuildHistoryWidget<T> extends HistoryWidget<Task, T> {
Expand Down Expand Up @@ -84,7 +85,6 @@ public HistoryPageFilter getHistoryPageFilter() {
final HistoryPageFilter<T> historyPageFilter = newPageFilter();

historyPageFilter.add(baseList, getQueuedItems());
historyPageFilter.widget = this;

return updateFirstTransientBuildKey(historyPageFilter);
}
Expand Down
13 changes: 7 additions & 6 deletions core/src/main/java/hudson/widgets/HistoryWidget.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@
import hudson.model.Job;
import hudson.model.ModelObject;
import hudson.model.Queue;
import hudson.model.Run;
import hudson.util.AlternativeUiTextProvider;
import java.io.IOException;
import java.util.ArrayList;
Expand All @@ -40,6 +39,7 @@
import java.util.Iterator;
import java.util.List;
import javax.servlet.ServletException;
import jenkins.model.HistoricalBuild;
import jenkins.util.SystemProperties;
import jenkins.widgets.HistoryPageEntry;
import jenkins.widgets.HistoryPageFilter;
Expand All @@ -53,12 +53,12 @@
import org.kohsuke.stapler.StaplerResponse;

/**
* Displays the history of records (normally {@link Run}s) on the side panel.
* Displays the history of records on the side panel.
*
* @param <O>
* Owner of the widget.
* Owner of the widget, typically {@link Job}
* @param <T>
* Type individual record.
* Type individual record, typically {@link HistoricalBuild}
* @author Kohsuke Kawaguchi
*/
public class HistoryWidget<O extends ModelObject, T> extends Widget {
Expand Down Expand Up @@ -142,7 +142,7 @@ public String getFirstTransientBuildKey() {
* @return
* The history page filter that was passed in.
*/
@SuppressWarnings("unchecked")
@SuppressWarnings("unchecked") // TODO actually not type-safe
protected HistoryPageFilter updateFirstTransientBuildKey(HistoryPageFilter historyPageFilter) {
updateFirstTransientBuildKey(historyPageFilter.runs);
return historyPageFilter;
Expand Down Expand Up @@ -195,7 +195,7 @@ private List<HistoryPageEntry<T>> toPageEntries(Iterable<T> historyItemList) {
/**
* Get a {@link jenkins.widgets.HistoryPageFilter} for rendering a page of queue items.
*/
public HistoryPageFilter getHistoryPageFilter() {
public HistoryPageFilter<T> getHistoryPageFilter() {
HistoryPageFilter<T> historyPageFilter = newPageFilter();

historyPageFilter.add(baseList);
Expand All @@ -205,6 +205,7 @@ public HistoryPageFilter getHistoryPageFilter() {

protected HistoryPageFilter<T> newPageFilter() {
HistoryPageFilter<T> historyPageFilter = new HistoryPageFilter<>(THRESHOLD);
historyPageFilter.widget = this;

if (newerThan != null) {
historyPageFilter.setNewerThan(newerThan);
Expand Down
Loading