Skip to content

Commit 0832c38

Browse files
Merge branch 'master' into migrate_to_junit5_test_2
# Conflicts: # test/src/test/java/hudson/tasks/LogRotatorTest.java
2 parents aeec2cb + 3f79665 commit 0832c38

File tree

21 files changed

+672
-705
lines changed

21 files changed

+672
-705
lines changed

.github/renovate.json

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,6 @@
2323
"team:sig-ux"
2424
]
2525
},
26-
{
27-
"matchPackageNames": [
28-
"node"
29-
],
30-
"allowedVersions": "/22.[0-9]+.[0-9]+(.[0-9]+)?$/"
31-
},
3226
{
3327
"description": "Should be upgraded in lockstep in order to keep their corresponding Jetty versions aligned",
3428
"matchManagers": [
@@ -124,7 +118,7 @@
124118
"<node.version>(?<currentValue>.*?)</node.version>"
125119
],
126120
"depNameTemplate": "node",
127-
"datasourceTemplate": "npm"
121+
"datasourceTemplate": "node-version"
128122
},
129123
{
130124
"customType": "regex",

bom/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ THE SOFTWARE.
4141
<commons-fileupload2.version>2.0.0-M2</commons-fileupload2.version>
4242
<groovy.version>2.4.21</groovy.version>
4343
<jelly.version>1.1-jenkins-20250108</jelly.version>
44-
<stapler.version>1971.vf47a_d79853d7</stapler.version>
44+
<stapler.version>1979.v5048d87384d7</stapler.version>
4545
</properties>
4646

4747
<dependencyManagement>

core/src/main/java/hudson/console/AnnotatedLargeText.java

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,10 @@ public void doProgressiveText(StaplerRequest req, StaplerResponse rsp) throws IO
141141
* and use this request attribute to differentiate.
142142
*/
143143
private boolean isHtml() {
144-
StaplerRequest2 req = Stapler.getCurrentRequest2();
144+
return isHtml(Stapler.getCurrentRequest2());
145+
}
146+
147+
private boolean isHtml(StaplerRequest2 req) {
145148
return req != null && req.getAttribute("html") != null;
146149
}
147150

@@ -207,6 +210,11 @@ public long writeLogTo(long start, Writer w) throws IOException {
207210
return super.writeLogTo(start, w);
208211
}
209212

213+
@Override
214+
protected boolean delegateToWriteLogTo(StaplerRequest2 req, StaplerResponse2 rsp) {
215+
return isHtml(req);
216+
}
217+
210218
/**
211219
* Strips annotations using a {@link PlainTextConsoleOutputStream}.
212220
* {@inheritDoc}

core/src/main/java/hudson/console/ConsoleAnnotator.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,11 @@ public ConsoleAnnotator annotate(T context, MarkupText text) {
118118
default: return this;
119119
}
120120
}
121+
122+
@Override
123+
public String toString() {
124+
return "ConsoleAnnotatorAggregator" + list;
125+
}
121126
}
122127

123128
/**

core/src/main/java/hudson/logging/LogRecorder.java

Lines changed: 0 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@
3131
import hudson.BulkChange;
3232
import hudson.Extension;
3333
import hudson.FilePath;
34-
import hudson.RestrictedSince;
3534
import hudson.Util;
3635
import hudson.XmlFile;
3736
import hudson.model.AbstractModelObject;
@@ -43,7 +42,6 @@
4342
import hudson.remoting.Channel;
4443
import hudson.remoting.VirtualChannel;
4544
import hudson.slaves.ComputerListener;
46-
import hudson.util.CopyOnWriteList;
4745
import hudson.util.FormApply;
4846
import hudson.util.FormValidation;
4947
import hudson.util.HttpResponses;
@@ -104,15 +102,6 @@
104102
public class LogRecorder extends AbstractModelObject implements Loadable, Saveable {
105103
private volatile String name;
106104

107-
/**
108-
* No longer used.
109-
*
110-
* @deprecated use {@link #getLoggers()}
111-
*/
112-
@Deprecated
113-
@Restricted(NoExternalUse.class)
114-
@RestrictedSince("2.324")
115-
public final transient CopyOnWriteList<Target> targets = new CopyOnWriteList<>();
116105
private List<Target> loggers = new ArrayList<>();
117106
private static final TargetComparator TARGET_COMPARATOR = new TargetComparator();
118107

@@ -124,22 +113,6 @@ public LogRecorder(String name) {
124113
new WeakLogHandler(handler, Logger.getLogger(""));
125114
}
126115

127-
private Object readResolve() {
128-
if (loggers == null) {
129-
loggers = new ArrayList<>();
130-
}
131-
132-
List<Target> tempLoggers = new ArrayList<>(loggers);
133-
134-
if (!targets.isEmpty()) {
135-
loggers.addAll(targets.getView());
136-
}
137-
if (!tempLoggers.isEmpty() && !targets.getView().equals(tempLoggers)) {
138-
targets.addAll(tempLoggers);
139-
}
140-
return this;
141-
}
142-
143116
public List<Target> getLoggers() {
144117
return loggers;
145118
}
@@ -455,7 +428,6 @@ public synchronized void doConfigSubmit(StaplerRequest2 req, StaplerResponse2 rs
455428
recorders.remove(new LogRecorder(name));
456429
this.name = newName;
457430
recorders.add(this);
458-
getParent().setRecorders(recorders); // ensure that legacy logRecorders field is synced on save
459431
redirect = "../" + Util.rawEncode(newName) + '/';
460432
}
461433

@@ -491,31 +463,12 @@ public synchronized void load() throws IOException {
491463
public synchronized void save() throws IOException {
492464
if (BulkChange.contains(this)) return;
493465

494-
handlePluginUpdatingLegacyLogManagerMap();
495466
getConfigFile().write(this);
496467
loggers.forEach(Target::enable);
497468

498469
SaveableListener.fireOnChange(this, getConfigFile());
499470
}
500471

501-
@SuppressWarnings("deprecation") // this is for compatibility
502-
private void handlePluginUpdatingLegacyLogManagerMap() {
503-
if (getParent().logRecorders.size() > getParent().getRecorders().size()) {
504-
for (LogRecorder logRecorder : getParent().logRecorders.values()) {
505-
if (!getParent().getRecorders().contains(logRecorder)) {
506-
getParent().getRecorders().add(logRecorder);
507-
}
508-
}
509-
}
510-
if (getParent().getRecorders().size() > getParent().logRecorders.size()) {
511-
for (LogRecorder logRecorder : getParent().getRecorders()) {
512-
if (!getParent().logRecorders.containsKey(logRecorder.getName())) {
513-
getParent().logRecorders.put(logRecorder.getName(), logRecorder);
514-
}
515-
}
516-
}
517-
}
518-
519472
@Override
520473
public boolean equals(Object o) {
521474
if (this == o) {

core/src/main/java/hudson/logging/LogRecorderManager.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,6 @@ public void load() throws IOException {
155155
lr.load();
156156
recorders.add(lr);
157157
}
158-
setRecorders(recorders); // ensure that legacy logRecorders field is synced on load
159158
}
160159

161160
/**

core/src/main/java/hudson/model/Run.java

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,6 @@
7272
import io.jenkins.servlet.ServletExceptionWrapper;
7373
import jakarta.servlet.ServletException;
7474
import jakarta.servlet.http.HttpServletResponse;
75-
import java.io.BufferedInputStream;
7675
import java.io.ByteArrayInputStream;
7776
import java.io.File;
7877
import java.io.IOException;
@@ -1466,19 +1465,34 @@ public Collection<Fingerprint> getBuildFingerprints() {
14661465
*/
14671466
@SuppressFBWarnings(value = "RV_RETURN_VALUE_IGNORED", justification = "method signature does not permit plumbing through the return value")
14681467
public void writeLogTo(long offset, @NonNull XMLOutput out) throws IOException {
1469-
long start = offset;
1468+
AnnotatedLargeText<?> logText = getLogText();
14701469
if (offset > 0) {
1471-
try (BufferedInputStream bufferedInputStream = new BufferedInputStream(getLogInputStream())) {
1472-
if (offset == bufferedInputStream.skip(offset)) {
1473-
int r;
1474-
do {
1475-
r = bufferedInputStream.read();
1476-
start = r == -1 ? 0 : start + 1;
1477-
} while (r != -1 && r != '\n');
1478-
}
1470+
long _offset = offset;
1471+
try {
1472+
logText.writeRawLogTo(offset - 1, new OutputStream() {
1473+
long pos = _offset;
1474+
@Override
1475+
public void write(int b) throws IOException {
1476+
if (b == '\n') {
1477+
throw new Halt(pos);
1478+
} else {
1479+
pos++;
1480+
}
1481+
}
1482+
});
1483+
} catch (Halt halt) {
1484+
offset = halt.offset;
14791485
}
14801486
}
1481-
getLogText().writeHtmlTo(start, out.asWriter());
1487+
logText.writeHtmlTo(offset, out.asWriter());
1488+
}
1489+
1490+
private static final class Halt extends IOException {
1491+
final long offset;
1492+
1493+
Halt(long offset) {
1494+
this.offset = offset;
1495+
}
14821496
}
14831497

14841498
/**

core/src/main/java/jenkins/model/GlobalBuildDiscarderListener.java

Lines changed: 31 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -24,14 +24,20 @@
2424

2525
package jenkins.model;
2626

27+
import com.google.common.annotations.VisibleForTesting;
2728
import hudson.Extension;
29+
import hudson.ExtensionList;
2830
import hudson.model.Job;
2931
import hudson.model.Run;
3032
import hudson.model.listeners.RunListener;
33+
import hudson.remoting.SingleLaneExecutorService;
3134
import hudson.util.LogTaskListener;
35+
import java.util.concurrent.ExecutorService;
3236
import java.util.logging.Level;
3337
import java.util.logging.Logger;
38+
import jenkins.util.Timer;
3439
import org.kohsuke.accmod.Restricted;
40+
import org.kohsuke.accmod.restrictions.DoNotUse;
3541
import org.kohsuke.accmod.restrictions.NoExternalUse;
3642

3743
/**
@@ -43,18 +49,32 @@ public class GlobalBuildDiscarderListener extends RunListener<Run> {
4349

4450
private static final Logger LOGGER = Logger.getLogger(GlobalBuildDiscarderListener.class.getName());
4551

52+
private final ExecutorService executor = new SingleLaneExecutorService(Timer.get());
53+
4654
@Override
4755
public void onFinalized(Run run) {
48-
Job job = run.getParent();
49-
try {
50-
// Job-level build discarder execution is unconditional.
51-
job.logRotate();
52-
} catch (Exception e) {
53-
LOGGER.log(Level.WARNING, e, () -> "Failed to rotate log for " + run);
54-
}
55-
// Avoid calling Job.logRotate twice in case JobGlobalBuildDiscarderStrategy is configured globally.
56-
BackgroundGlobalBuildDiscarder.processJob(new LogTaskListener(LOGGER, Level.FINE), job,
57-
GlobalBuildDiscarderConfiguration.get().getConfiguredBuildDiscarders().stream()
58-
.filter(s -> !(s instanceof JobGlobalBuildDiscarderStrategy)));
56+
executor.execute(() -> {
57+
Job job = run.getParent();
58+
try {
59+
// Job-level build discarder execution is unconditional.
60+
job.logRotate();
61+
} catch (Exception e) {
62+
LOGGER.log(Level.WARNING, e, () -> "Failed to rotate log for " + run);
63+
}
64+
// Avoid calling Job.logRotate twice in case JobGlobalBuildDiscarderStrategy is configured globally.
65+
BackgroundGlobalBuildDiscarder.processJob(new LogTaskListener(LOGGER, Level.FINE), job,
66+
GlobalBuildDiscarderConfiguration.get().getConfiguredBuildDiscarders().stream()
67+
.filter(s -> !(s instanceof JobGlobalBuildDiscarderStrategy)));
68+
});
69+
}
70+
71+
/**
72+
* Waits for all currently scheduled or running discards to complete.
73+
*/
74+
@VisibleForTesting
75+
@Restricted(DoNotUse.class)
76+
public static void await() throws Exception {
77+
ExtensionList.lookupSingleton(GlobalBuildDiscarderListener.class).executor.submit(() -> {}).get();
5978
}
79+
6080
}

core/src/main/resources/lib/layout/header/actions.jelly

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@
4646
<x:attribute name="data-type">header-action</x:attribute>
4747
<x:attribute name="draggable">false</x:attribute>
4848
<x:attribute name="class">jenkins-button ${isCurrent ? '' : 'jenkins-button--tertiary'}</x:attribute>
49-
<l:icon src="${icon}" class="jenkins-avatar" />
49+
<l:icon src="${icon}" class="${action.class.name == 'jenkins.model.navigation.UserAction' ? 'jenkins-avatar' : ''}"/>
5050
<span class="jenkins-visually-hidden" data-type="action-label">${action.displayName}</span>
5151
<j:if test="${badge != null}">
5252
<span class="jenkins-badge jenkins-!-${badge.severity}-color" />

core/src/test/java/hudson/model/RunTest.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -280,6 +280,11 @@ public void wontPushOffsetOnRenderingFromBeginning() throws Exception {
280280
assertWriteLogToEquals(new String(new char[5]).replace("\0", SAMPLE_BUILD_OUTPUT) + "Finished: SUCCESS.\n", 0);
281281
}
282282

283+
@Test
284+
public void wontPushOffsetOnRenderingFromBeginningOfLine() throws Exception {
285+
assertWriteLogToEquals(new String(new char[3]).replace("\0", SAMPLE_BUILD_OUTPUT) + "Finished: SUCCESS.\n", 2 * SAMPLE_BUILD_OUTPUT.length());
286+
}
287+
283288
@Test
284289
public void willRenderNothingIfOffsetSetOnLastLine() throws Exception {
285290
assertWriteLogToEquals("", 5 * SAMPLE_BUILD_OUTPUT.length() + 6);

0 commit comments

Comments
 (0)