mirror of https://github.com/jenkinsci/jenkins.git
Merge branch 'master' into new-buttons-1-dashboard
This commit is contained in:
commit
c4075772f0
|
@ -0,0 +1,27 @@
|
|||
tasks:
|
||||
- init: |
|
||||
mvn -am -pl war,bom -P quick-build clean install
|
||||
command: |
|
||||
mvn -pl war jetty:run -Dhost=0.0.0.0
|
||||
name: Run
|
||||
- command: gp await-port 8080 && gp url 8080 && gp preview $(gp url 8080)/jenkins/
|
||||
name: Preview
|
||||
|
||||
github:
|
||||
prebuilds:
|
||||
pullRequestsFromForks: true
|
||||
addBadge: true
|
||||
|
||||
jetbrains:
|
||||
intellij:
|
||||
plugins:
|
||||
- Stapler plugin for IntelliJ IDEA
|
||||
prebuilds:
|
||||
version: stable
|
||||
|
||||
vscode:
|
||||
extensions:
|
||||
- vscjava.vscode-java-pack
|
||||
|
||||
image:
|
||||
file: .gitpod/Dockerfile
|
|
@ -0,0 +1,4 @@
|
|||
FROM gitpod/workspace-full
|
||||
|
||||
RUN brew install gh && \
|
||||
bash -c ". /home/gitpod/.sdkman/bin/sdkman-init.sh && sdk install maven 3.8.4 && sdk default maven 3.8.4"
|
File diff suppressed because one or more lines are too long
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 21 KiB |
|
@ -1 +1 @@
|
|||
-Xmx800m
|
||||
-Xmx1100m
|
||||
|
|
|
@ -31,7 +31,7 @@ You can read a description of the [building and debugging process here].
|
|||
If you want simply to build the `jenkins.war` file as fast as possible without tests, run:
|
||||
|
||||
```sh
|
||||
mvn -am -pl war,bom -DskipTests -Dspotbugs.skip -Dspotless.check.skip clean install
|
||||
mvn -am -pl war,bom -Pquick-build clean install
|
||||
```
|
||||
|
||||
The WAR file will be created in `war/target/jenkins.war`.
|
||||
|
@ -62,6 +62,16 @@ On another terminal, move to the war folder and start a [webpack](https://webpac
|
|||
cd war; yarn start
|
||||
```
|
||||
|
||||
### Gitpod
|
||||
|
||||
You can open this project as a [Gitpod workspace](https://www.gitpod.io/) which comes pre-configured with all the tools you will need.
|
||||
You can use IntelliJ IDEA (preferred) or VS Code (alternate) in the browser.
|
||||
|
||||
[](https://gitpod.io/#https://github.com/jenkinsci/jenkins)
|
||||
|
||||
If you prefer using IntelliJ IDEA, you can setup Gitpod integration with JetBrains Gateway using the instructions on [gitpod.io](https://www.gitpod.io/docs/ides-and-editors/intellij),
|
||||
which will open the workspace in IntelliJ IDEA using JetBrains Gateway.
|
||||
|
||||
## Testing changes
|
||||
|
||||
Jenkins core includes unit and functional tests as a part of the repository.
|
||||
|
@ -220,4 +230,4 @@ just submit a pull request.
|
|||
[Jenkins Pipeline]: https://www.jenkins.io/doc/book/pipeline/
|
||||
[Jenkinsfile]: ./Jenkinsfile
|
||||
[download Maven here]: https://maven.apache.org/download.cgi
|
||||
[GitHub pull request]: https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/about-pull-requests
|
||||
[GitHub pull request]: https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/about-pull-requests
|
||||
|
|
|
@ -61,9 +61,13 @@ for (i = 0; i < buildTypes.size(); i++) {
|
|||
'clean',
|
||||
'install',
|
||||
]
|
||||
infra.runMaven(mavenOptions, jdk)
|
||||
if (isUnix()) {
|
||||
sh 'git add . && git diff --exit-code HEAD'
|
||||
try {
|
||||
infra.runMaven(mavenOptions, jdk)
|
||||
if (isUnix()) {
|
||||
sh 'git add . && git diff --exit-code HEAD'
|
||||
}
|
||||
} finally {
|
||||
archiveArtifacts allowEmptyArchive: true, artifacts: '**/target/surefire-reports/*.dumpstream'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -71,7 +75,6 @@ for (i = 0; i < buildTypes.size(); i++) {
|
|||
|
||||
// Once we've built, archive the artifacts and the test results.
|
||||
stage("${buildType} Publishing") {
|
||||
archiveArtifacts allowEmptyArchive: true, artifacts: '**/target/surefire-reports/*.dumpstream'
|
||||
if (!fileExists('core/target/surefire-reports/TEST-jenkins.Junit4TestsRanTest.xml')) {
|
||||
error 'JUnit 4 tests are no longer being run for the core package'
|
||||
}
|
||||
|
|
|
@ -187,6 +187,7 @@ import org.xml.sax.helpers.DefaultHandler;
|
|||
* @author Kohsuke Kawaguchi
|
||||
*/
|
||||
@ExportedBean
|
||||
@SuppressFBWarnings(value = "THROWS_METHOD_THROWS_CLAUSE_BASIC_EXCEPTION", justification = "TODO needs triage")
|
||||
public abstract class PluginManager extends AbstractModelObject implements OnMaster, StaplerOverridable, StaplerProxy {
|
||||
/** Custom plugin manager system property or context param. */
|
||||
public static final String CUSTOM_PLUGIN_MANAGER = PluginManager.class.getName() + ".className";
|
||||
|
|
|
@ -27,6 +27,7 @@ package hudson.cli.declarative;
|
|||
import static java.util.logging.Level.SEVERE;
|
||||
|
||||
import edu.umd.cs.findbugs.annotations.NonNull;
|
||||
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
|
||||
import hudson.AbortException;
|
||||
import hudson.Extension;
|
||||
import hudson.ExtensionComponent;
|
||||
|
@ -71,6 +72,12 @@ import org.springframework.security.core.context.SecurityContextHolder;
|
|||
* @author Kohsuke Kawaguchi
|
||||
*/
|
||||
@Extension
|
||||
@SuppressFBWarnings(
|
||||
value = {
|
||||
"THROWS_METHOD_THROWS_CLAUSE_BASIC_EXCEPTION",
|
||||
"THROWS_METHOD_THROWS_RUNTIMEEXCEPTION"
|
||||
},
|
||||
justification = "TODO needs triage")
|
||||
public class CLIRegisterer extends ExtensionFinder {
|
||||
@Override
|
||||
public ExtensionComponentSet refresh() throws ExtensionRefreshException {
|
||||
|
|
|
@ -110,6 +110,7 @@ import org.xml.sax.SAXException;
|
|||
// Item doesn't necessarily have to be Actionable, but
|
||||
// Java doesn't let multiple inheritance.
|
||||
@ExportedBean
|
||||
@SuppressFBWarnings(value = "THROWS_METHOD_THROWS_CLAUSE_THROWABLE", justification = "TODO needs triage")
|
||||
public abstract class AbstractItem extends Actionable implements Item, HttpDeletable, AccessControlled, DescriptorByNameOwner, StaplerProxy {
|
||||
|
||||
private static final Logger LOGGER = Logger.getLogger(AbstractItem.class.getName());
|
||||
|
|
|
@ -32,6 +32,7 @@ import static java.util.logging.Level.WARNING;
|
|||
|
||||
import edu.umd.cs.findbugs.annotations.CheckForNull;
|
||||
import edu.umd.cs.findbugs.annotations.NonNull;
|
||||
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
|
||||
import hudson.FilePath;
|
||||
import hudson.Functions;
|
||||
import hudson.Util;
|
||||
|
@ -89,6 +90,12 @@ import org.springframework.security.core.Authentication;
|
|||
* @author Kohsuke Kawaguchi
|
||||
*/
|
||||
@ExportedBean
|
||||
@SuppressFBWarnings(
|
||||
value = {
|
||||
"THROWS_METHOD_THROWS_CLAUSE_BASIC_EXCEPTION",
|
||||
"THROWS_METHOD_THROWS_CLAUSE_THROWABLE"
|
||||
},
|
||||
justification = "TODO needs triage")
|
||||
public class Executor extends Thread implements ModelObject {
|
||||
protected final @NonNull Computer owner;
|
||||
private final Queue queue;
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
|
||||
package hudson.model;
|
||||
|
||||
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
|
||||
import hudson.Util;
|
||||
import hudson.XmlFile;
|
||||
import hudson.model.listeners.ItemListener;
|
||||
|
@ -61,6 +62,7 @@ import org.xml.sax.SAXException;
|
|||
* @author Kohsuke Kawaguchi
|
||||
* @see ViewGroupMixIn
|
||||
*/
|
||||
@SuppressFBWarnings(value = "THROWS_METHOD_THROWS_CLAUSE_THROWABLE", justification = "TODO needs triage")
|
||||
public abstract class ItemGroupMixIn {
|
||||
/**
|
||||
* {@link ItemGroup} for which we are working.
|
||||
|
|
|
@ -171,6 +171,7 @@ import org.springframework.security.core.Authentication;
|
|||
* @see QueueTaskDispatcher
|
||||
*/
|
||||
@ExportedBean
|
||||
@SuppressFBWarnings(value = "THROWS_METHOD_THROWS_CLAUSE_BASIC_EXCEPTION", justification = "TODO needs triage")
|
||||
public class Queue extends ResourceController implements Saveable {
|
||||
|
||||
/**
|
||||
|
|
|
@ -39,6 +39,12 @@ import jenkins.security.NotReallyRoleSensitiveCallable;
|
|||
* Controls mutual exclusion of {@link ResourceList}.
|
||||
* @author Kohsuke Kawaguchi
|
||||
*/
|
||||
@SuppressFBWarnings(
|
||||
value = {
|
||||
"THROWS_METHOD_THROWS_CLAUSE_BASIC_EXCEPTION",
|
||||
"THROWS_METHOD_THROWS_CLAUSE_THROWABLE"
|
||||
},
|
||||
justification = "TODO needs triage")
|
||||
public class ResourceController {
|
||||
/**
|
||||
* {@link ResourceList}s that are used by activities that are in progress.
|
||||
|
|
|
@ -104,6 +104,7 @@ import org.kohsuke.stapler.interceptor.RequirePOST;
|
|||
* @since 1.333
|
||||
*/
|
||||
@ExportedBean
|
||||
@SuppressFBWarnings(value = "THROWS_METHOD_THROWS_CLAUSE_BASIC_EXCEPTION", justification = "TODO needs triage")
|
||||
public class UpdateSite {
|
||||
/**
|
||||
* What's the time stamp of data file?
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
|
||||
package hudson.triggers;
|
||||
|
||||
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
|
||||
import hudson.model.AperiodicWork;
|
||||
import hudson.model.AsyncAperiodicWork;
|
||||
import hudson.model.AsyncPeriodicWork;
|
||||
|
@ -47,6 +48,7 @@ import jenkins.util.Timer;
|
|||
* @author Kohsuke Kawaguchi
|
||||
* @since 1.124
|
||||
*/
|
||||
@SuppressFBWarnings(value = "THROWS_METHOD_THROWS_CLAUSE_BASIC_EXCEPTION", justification = "TODO needs triage")
|
||||
public abstract class SafeTimerTask extends TimerTask {
|
||||
|
||||
/**
|
||||
|
|
|
@ -230,14 +230,12 @@ public abstract class FormFieldValidator {
|
|||
ok();
|
||||
} else {
|
||||
response.setContentType("text/html;charset=UTF-8");
|
||||
// 1x16 spacer needed for IE since it doesn't support min-height
|
||||
if (APPLY_CONTENT_SECURITY_POLICY_HEADERS) {
|
||||
for (String header : new String[]{"Content-Security-Policy", "X-WebKit-CSP", "X-Content-Security-Policy"}) {
|
||||
response.setHeader(header, "sandbox; default-src 'none';");
|
||||
}
|
||||
}
|
||||
response.getWriter().print("<div class=" + cssClass + "><img src='" +
|
||||
request.getContextPath() + Jenkins.RESOURCE_PATH + "/images/none.gif' height=16 width=1>" +
|
||||
response.getWriter().print("<div class=" + cssClass + ">" +
|
||||
message + "</div>");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,7 +31,6 @@ import java.io.IOException;
|
|||
import java.util.Locale;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import jenkins.model.Jenkins;
|
||||
import org.kohsuke.stapler.HttpResponse;
|
||||
import org.kohsuke.stapler.Stapler;
|
||||
import org.kohsuke.stapler.StaplerRequest;
|
||||
|
@ -95,7 +94,7 @@ public abstract class FormFillFailure extends IOException implements HttpRespons
|
|||
}
|
||||
|
||||
return _errorWithMarkup(Util.escape(message) +
|
||||
" <a href='#' class='showDetails'>"
|
||||
" </div><div><a href='#' class='showDetails'>"
|
||||
+ Messages.FormValidation_Error_Details()
|
||||
+ "</a><pre style='display:none'>"
|
||||
+ Util.escape(Functions.printThrowable(e)) +
|
||||
|
@ -137,9 +136,7 @@ public abstract class FormFillFailure extends IOException implements HttpRespons
|
|||
if (req == null) { // being called from some other context
|
||||
return message;
|
||||
}
|
||||
// 1x16 spacer needed for IE since it doesn't support min-height
|
||||
return "<div class=" + getKind().name().toLowerCase(Locale.ENGLISH) + "><img src='" +
|
||||
req.getContextPath() + Jenkins.RESOURCE_PATH + "/images/none.gif' height=16 width=1>" +
|
||||
return "<div class=" + getKind().name().toLowerCase(Locale.ENGLISH) + ">" +
|
||||
message + "</div>";
|
||||
}
|
||||
|
||||
|
|
|
@ -198,7 +198,7 @@ public abstract class FormValidation extends IOException implements HttpResponse
|
|||
if (e == null) return _errorWithMarkup(Util.escape(message), kind);
|
||||
|
||||
return _errorWithMarkup(Util.escape(message) +
|
||||
" <a href='#' class='showDetails'>"
|
||||
" </div><div><a href='#' class='showDetails'>"
|
||||
+ Messages.FormValidation_Error_Details()
|
||||
+ "</a><pre style='display:none'>"
|
||||
+ Util.escape(Functions.printThrowable(e)) +
|
||||
|
@ -272,9 +272,7 @@ public abstract class FormValidation extends IOException implements HttpResponse
|
|||
if (req == null) { // being called from some other context
|
||||
return message;
|
||||
}
|
||||
// 1x16 spacer needed for IE since it doesn't support min-height
|
||||
return "<div class=" + kind.name().toLowerCase(Locale.ENGLISH) + "><img src='" +
|
||||
req.getContextPath() + Jenkins.RESOURCE_PATH + "/images/none.gif' height=16 width=1>" +
|
||||
return "<div class=\"" + kind.name().toLowerCase(Locale.ENGLISH) + "\">" +
|
||||
message + "</div>";
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package hudson.util;
|
||||
|
||||
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
|
||||
import java.lang.reflect.InvocationHandler;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
|
@ -10,6 +11,7 @@ import java.lang.reflect.Proxy;
|
|||
*
|
||||
* @author Kohsuke Kawaguchi
|
||||
*/
|
||||
@SuppressFBWarnings(value = "THROWS_METHOD_THROWS_CLAUSE_THROWABLE", justification = "TODO needs triage")
|
||||
public abstract class InterceptingProxy {
|
||||
/**
|
||||
* Intercepts every method call.
|
||||
|
|
|
@ -44,6 +44,7 @@ import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
|
|||
import com.thoughtworks.xstream.mapper.Mapper;
|
||||
import com.thoughtworks.xstream.security.InputManipulationException;
|
||||
import edu.umd.cs.findbugs.annotations.NonNull;
|
||||
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
|
||||
import hudson.diagnosis.OldDataMonitor;
|
||||
import hudson.model.Saveable;
|
||||
import hudson.security.ACL;
|
||||
|
@ -77,6 +78,7 @@ import org.acegisecurity.Authentication;
|
|||
* </ul>
|
||||
*
|
||||
*/
|
||||
@SuppressFBWarnings(value = "THROWS_METHOD_THROWS_RUNTIMEEXCEPTION", justification = "TODO needs triage")
|
||||
@SuppressWarnings({"rawtypes", "unchecked"})
|
||||
public class RobustReflectionConverter implements Converter {
|
||||
|
||||
|
|
|
@ -337,6 +337,7 @@ import org.xml.sax.InputSource;
|
|||
* @author Kohsuke Kawaguchi
|
||||
*/
|
||||
@ExportedBean
|
||||
@SuppressFBWarnings(value = "THROWS_METHOD_THROWS_CLAUSE_BASIC_EXCEPTION", justification = "TODO needs triage")
|
||||
public class Jenkins extends AbstractCIBase implements DirectlyModifiableTopLevelItemGroup, StaplerProxy, StaplerFallback,
|
||||
ModifiableViewGroup, AccessControlled, DescriptorByNameOwner,
|
||||
ModelObjectWithContextMenu, ModelObjectWithChildren, OnMaster {
|
||||
|
|
|
@ -26,6 +26,7 @@ package jenkins.model;
|
|||
|
||||
import edu.umd.cs.findbugs.annotations.CheckForNull;
|
||||
import edu.umd.cs.findbugs.annotations.NonNull;
|
||||
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
|
||||
import hudson.BulkChange;
|
||||
import hudson.Util;
|
||||
import hudson.XmlFile;
|
||||
|
@ -61,6 +62,7 @@ import org.kohsuke.accmod.restrictions.NoExternalUse;
|
|||
* @since 1.607
|
||||
*/
|
||||
@Restricted(NoExternalUse.class) // for now, we may make it public later
|
||||
@SuppressFBWarnings(value = "THROWS_METHOD_THROWS_CLAUSE_BASIC_EXCEPTION", justification = "TODO needs triage")
|
||||
public class Nodes implements Saveable {
|
||||
|
||||
/**
|
||||
|
|
|
@ -28,6 +28,7 @@ import com.google.common.cache.CacheBuilder;
|
|||
import com.google.common.cache.CacheLoader;
|
||||
import com.google.common.cache.LoadingCache;
|
||||
import edu.umd.cs.findbugs.annotations.NonNull;
|
||||
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
|
||||
import hudson.ExtensionList;
|
||||
import hudson.ExtensionListListener;
|
||||
import hudson.ExtensionPoint;
|
||||
|
@ -48,6 +49,7 @@ import org.kohsuke.accmod.restrictions.NoExternalUse;
|
|||
* @see Actionable#getAllActions
|
||||
* @since 1.548
|
||||
*/
|
||||
@SuppressFBWarnings(value = "THROWS_METHOD_THROWS_CLAUSE_BASIC_EXCEPTION", justification = "TODO needs triage")
|
||||
public abstract class TransientActionFactory<T> implements ExtensionPoint {
|
||||
|
||||
/**
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
|
||||
package jenkins.security;
|
||||
|
||||
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
|
||||
import hudson.security.ACL;
|
||||
import hudson.security.ACLContext;
|
||||
import java.util.concurrent.Callable;
|
||||
|
@ -36,6 +37,7 @@ import org.springframework.security.core.Authentication;
|
|||
* @see SecurityContextExecutorService
|
||||
* @since 2.51
|
||||
*/
|
||||
@SuppressFBWarnings(value = "THROWS_METHOD_THROWS_CLAUSE_BASIC_EXCEPTION", justification = "TODO needs triage")
|
||||
public final class ImpersonatingExecutorService extends InterceptingExecutorService {
|
||||
|
||||
private final Authentication authentication;
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
|
||||
package jenkins.security;
|
||||
|
||||
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
|
||||
import hudson.security.ACL;
|
||||
import hudson.security.ACLContext;
|
||||
import java.util.concurrent.Callable;
|
||||
|
@ -35,6 +36,7 @@ import org.springframework.security.core.Authentication;
|
|||
* Variant of {@link ImpersonatingExecutorService} for scheduled services.
|
||||
* @since 2.51
|
||||
*/
|
||||
@SuppressFBWarnings(value = "THROWS_METHOD_THROWS_CLAUSE_BASIC_EXCEPTION", justification = "TODO needs triage")
|
||||
public final class ImpersonatingScheduledExecutorService extends InterceptingScheduledExecutorService {
|
||||
|
||||
private final Authentication authentication;
|
||||
|
|
|
@ -27,6 +27,7 @@ package jenkins.security;
|
|||
import static org.springframework.security.core.context.SecurityContextHolder.getContext;
|
||||
import static org.springframework.security.core.context.SecurityContextHolder.setContext;
|
||||
|
||||
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import jenkins.util.InterceptingExecutorService;
|
||||
|
@ -43,6 +44,7 @@ import org.springframework.security.core.context.SecurityContext;
|
|||
* @author Kohsuke Kawaguchi
|
||||
* @since 1.561
|
||||
*/
|
||||
@SuppressFBWarnings(value = "THROWS_METHOD_THROWS_CLAUSE_BASIC_EXCEPTION", justification = "TODO needs triage")
|
||||
public class SecurityContextExecutorService extends InterceptingExecutorService {
|
||||
|
||||
public SecurityContextExecutorService(ExecutorService service) {
|
||||
|
|
|
@ -44,6 +44,7 @@ import jenkins.security.ImpersonatingExecutorService;
|
|||
* @author Kohsuke Kawaguchi
|
||||
* @see AtmostOneThreadExecutor
|
||||
*/
|
||||
@SuppressFBWarnings(value = "THROWS_METHOD_THROWS_CLAUSE_BASIC_EXCEPTION", justification = "TODO needs triage")
|
||||
public class AtmostOneTaskExecutor<V> {
|
||||
|
||||
private static final Logger LOGGER = Logger.getLogger(AtmostOneTaskExecutor.class.getName());
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package jenkins.util;
|
||||
|
||||
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
|
||||
|
@ -11,6 +12,7 @@ import java.util.concurrent.ExecutorService;
|
|||
*
|
||||
* @author Kohsuke Kawaguchi
|
||||
*/
|
||||
@SuppressFBWarnings(value = "THROWS_METHOD_THROWS_CLAUSE_BASIC_EXCEPTION", justification = "TODO needs triage")
|
||||
public class ContextResettingExecutorService extends InterceptingExecutorService {
|
||||
public ContextResettingExecutorService(ExecutorService base) {
|
||||
super(base);
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
package jenkins.util;
|
||||
|
||||
import edu.umd.cs.findbugs.annotations.NonNull;
|
||||
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
|
||||
import hudson.model.AbstractItem;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.InvocationHandler;
|
||||
|
@ -73,6 +74,7 @@ import org.springframework.security.core.context.SecurityContextHolder;
|
|||
* {@code ui-samples-plugin} demonstrates all this.
|
||||
* @since 1.484
|
||||
*/
|
||||
@SuppressFBWarnings(value = "THROWS_METHOD_THROWS_CLAUSE_THROWABLE", justification = "TODO needs triage")
|
||||
public abstract class ProgressiveRendering {
|
||||
|
||||
private static final Logger LOG = Logger.getLogger(ProgressiveRendering.class.getName());
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
|
||||
package org.acegisecurity.providers.dao;
|
||||
|
||||
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
|
||||
import org.acegisecurity.AcegiSecurityException;
|
||||
import org.acegisecurity.Authentication;
|
||||
import org.acegisecurity.AuthenticationException;
|
||||
|
@ -35,6 +36,7 @@ import org.acegisecurity.userdetails.UserDetails;
|
|||
* @deprecated use {@link org.springframework.security.authentication.dao.AbstractUserDetailsAuthenticationProvider}
|
||||
*/
|
||||
@Deprecated
|
||||
@SuppressFBWarnings(value = "THROWS_METHOD_THROWS_RUNTIMEEXCEPTION", justification = "TODO needs triage")
|
||||
public abstract class AbstractUserDetailsAuthenticationProvider implements AuthenticationProvider {
|
||||
|
||||
private final org.springframework.security.authentication.dao.AbstractUserDetailsAuthenticationProvider delegate =
|
||||
|
|
|
@ -84,13 +84,12 @@ THE SOFTWARE.
|
|||
<j:out value="${escapeEntryTitleAndDescription ? h.escape(attrs.description) : attrs.description}"/>
|
||||
</f:description>
|
||||
</j:if>
|
||||
<!-- Needs to have a .tr class otherwise custom uses of findFollowing
|
||||
findFollowingTR(listBox, "validation-error-area") will break -->
|
||||
<div class="setting-main">
|
||||
<d:invokeBody />
|
||||
</div>
|
||||
<!-- used to display the form validation error -->
|
||||
<div class="validation-error-area tr"><div colspan="2"></div><div></div><div></div></div>
|
||||
<div class="validation-error-area">
|
||||
<!-- Used to display the form validation status -->
|
||||
</div>
|
||||
<j:if test="${attrs.help!=null}">
|
||||
<f:helpArea />
|
||||
</j:if>
|
||||
|
@ -109,8 +108,9 @@ THE SOFTWARE.
|
|||
</div>
|
||||
</j:otherwise>
|
||||
</j:choose>
|
||||
<!-- used to display the form validation error -->
|
||||
<div class="validation-error-area tr"><div colspan="2"></div><div></div><div></div></div>
|
||||
<div class="validation-error-area">
|
||||
<!-- Used to display the form validation status -->
|
||||
</div>
|
||||
<f:helpArea />
|
||||
<j:if test="${!empty(attrs.description)}">
|
||||
<f:description>
|
||||
|
|
|
@ -33,12 +33,13 @@ THE SOFTWARE.
|
|||
and the presence of the value.
|
||||
<st:attribute name="field" use="required" />
|
||||
<st:attribute name="title" use="required" />
|
||||
<st:attribute name="help" />
|
||||
</st:documentation>
|
||||
<!--
|
||||
Without @checked, optionalBlock will try to coerce an object to a boolean, which fails,
|
||||
so override @checked manually.
|
||||
-->
|
||||
<f:optionalBlock field="${field}" title="${title}" checked="${instance[field]!=null}">
|
||||
<f:optionalBlock field="${field}" title="${title}" checked="${instance[field]!=null}" help="${help}">
|
||||
<j:set var="descriptor" value="${app.getDescriptorOrDie(descriptor.getPropertyTypeOrDie(instance,field).clazz)}" />
|
||||
<j:set var="instance" value="${instance[field]}"/>
|
||||
<st:include from="${descriptor}" page="${descriptor.configPage}" />
|
||||
|
|
|
@ -11,12 +11,12 @@ function updateListBox(listBox,url,config) {
|
|||
// form entry using tables-to-divs markup.
|
||||
function getStatusElement() {
|
||||
function getStatusForTabularForms() {
|
||||
return findFollowingTR(listBox, "validation-error-area").firstElementChild.nextSibling;
|
||||
return listBox.parentNode.querySelector(".validation-error-area");
|
||||
}
|
||||
function getStatusForDivBasedForms() {
|
||||
var settingMain = listBox.closest('.setting-main')
|
||||
if (!settingMain) {
|
||||
console.warn("Couldn't find the expected parent element (.setting-main) for element", listBox)
|
||||
console.warn("Couldn't find the expected validation element (.validation-error-area) for element", listBox.parentNode)
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -51,16 +51,18 @@ THE SOFTWARE.
|
|||
</st:attribute>
|
||||
</st:documentation>
|
||||
<f:entry>
|
||||
<div style="float:right">
|
||||
<div class="jenkins-validate-button__container">
|
||||
<div style="display:none;">
|
||||
<l:spinner text="${attrs.progress}" />
|
||||
</div>
|
||||
<input type="button" value="${title}" class="yui-button validate-button ${attrs.clazz} Behaviour-validateButton"
|
||||
data-validate-button-descriptor-url="${descriptor.descriptorFullUrl}"
|
||||
data-validate-button-method="${method}"
|
||||
data-validate-button-with="${with}" />
|
||||
<div class="jenkins-validate-button__container__status">
|
||||
<!-- Used to display the form validation status -->
|
||||
</div>
|
||||
</div>
|
||||
<div style="display:none;">
|
||||
<l:spinner text="${attrs.progress}" />
|
||||
</div>
|
||||
<div><!-- this is where the error message goes --></div>
|
||||
<st:adjunct includes="lib.form.validateButton.adjunct"/>
|
||||
</f:entry>
|
||||
</j:jelly>
|
||||
|
|
|
@ -52,7 +52,7 @@ THE SOFTWARE.
|
|||
</j:when>
|
||||
<j:otherwise>
|
||||
<a href="${attrs.href ?: rootURL+'/'+r.url}" class="model-link">
|
||||
<l:icon alt="${r.iconColor.description}" class="${r.buildStatusIconClassName} icon-sm" style="margin-left: 0; position: relative; top: 0.2rem;"/><span class="jenkins-icon-adjacent">${jobName_}#<!-- -->${number}</span></a>
|
||||
<l:icon alt="${r.iconColor.description}" class="${r.buildStatusIconClassName} icon-sm" style="margin-left: 0; position: relative; top: -0.1rem;"/><span class="jenkins-icon-adjacent">${jobName_}#<!-- -->${number}</span></a>
|
||||
</j:otherwise>
|
||||
</j:choose>
|
||||
</j:otherwise>
|
||||
|
|
14
pom.xml
14
pom.xml
|
@ -28,7 +28,7 @@ THE SOFTWARE.
|
|||
<parent>
|
||||
<groupId>org.jenkins-ci</groupId>
|
||||
<artifactId>jenkins</artifactId>
|
||||
<version>1.74</version>
|
||||
<version>1.76</version>
|
||||
<relativePath />
|
||||
</parent>
|
||||
|
||||
|
@ -71,7 +71,7 @@ THE SOFTWARE.
|
|||
</issueManagement>
|
||||
|
||||
<properties>
|
||||
<revision>2.351</revision>
|
||||
<revision>2.355</revision>
|
||||
<changelist>-SNAPSHOT</changelist>
|
||||
|
||||
<!-- *.html files are in UTF-8, and *.properties are in iso-8859-1, so this configuration is actually incorrect,
|
||||
|
@ -101,12 +101,8 @@ THE SOFTWARE.
|
|||
<access-modifier.version>1.27</access-modifier.version>
|
||||
<bridge-method-injector.version>1.23</bridge-method-injector.version>
|
||||
<junit.jupiter.version>5.8.2</junit.jupiter.version>
|
||||
<mockito.version>4.6.0</mockito.version>
|
||||
<spotless.version>2.22.5</spotless.version>
|
||||
|
||||
<!-- TODO 3.x versions expose "GC overhead limit exceeded" errors in this test suite -->
|
||||
<maven-surefire-plugin.version>2.22.2</maven-surefire-plugin.version>
|
||||
<maven-surefire-report-plugin.version>2.22.2</maven-surefire-report-plugin.version>
|
||||
<mockito.version>4.6.1</mockito.version>
|
||||
<spotless.version>2.22.7</spotless.version>
|
||||
</properties>
|
||||
|
||||
<dependencyManagement>
|
||||
|
@ -475,7 +471,7 @@ THE SOFTWARE.
|
|||
<arguments>-P release,sign</arguments>
|
||||
<!-- work around for a bug in javadoc plugin that causes the release to fail. see MRELEASE-271 -->
|
||||
<preparationGoals>clean install</preparationGoals>
|
||||
<goals>-DskipTests -Danimal.sniffer.skip=false javadoc:javadoc deploy</goals>
|
||||
<goals>-DskipTests -Danimal.sniffer.skip=false -Dspotbugs.skip -Dmaven.checkstyle.skip -Dspotless.check.skip generate-resources javadoc:javadoc deploy</goals>
|
||||
<pushChanges>false</pushChanges>
|
||||
<localCheckout>true</localCheckout>
|
||||
<tagNameFormat>jenkins-@{project.version}</tagNameFormat>
|
||||
|
|
|
@ -573,6 +573,194 @@
|
|||
<Class name="jenkins.security.CryptoConfidentialKey"/>
|
||||
</Or>
|
||||
</And>
|
||||
<And>
|
||||
<Bug pattern="THROWS_METHOD_THROWS_CLAUSE_BASIC_EXCEPTION"/>
|
||||
<Or>
|
||||
<Class name="hudson.ClassicPluginStrategy"/>
|
||||
<Class name="hudson.cli.AbstractBuildRangeCommand"/>
|
||||
<Class name="hudson.cli.AddJobToViewCommand"/>
|
||||
<Class name="hudson.cli.BuildCommand"/>
|
||||
<Class name="hudson.cli.CancelQuietDownCommand"/>
|
||||
<Class name="hudson.cli.ClearQueueCommand"/>
|
||||
<Class name="hudson.cli.CLI"/>
|
||||
<Class name="hudson.cli.CLICommand"/>
|
||||
<Class name="hudson.cli.ConnectNodeCommand"/>
|
||||
<Class name="hudson.cli.ConsoleCommand"/>
|
||||
<Class name="hudson.cli.CopyJobCommand"/>
|
||||
<Class name="hudson.cli.CreateJobCommand"/>
|
||||
<Class name="hudson.cli.CreateNodeCommand"/>
|
||||
<Class name="hudson.cli.CreateViewCommand"/>
|
||||
<Class name="hudson.cli.declarative.MethodBinder"/>
|
||||
<Class name="hudson.cli.DeleteJobCommand"/>
|
||||
<Class name="hudson.cli.DeleteNodeCommand"/>
|
||||
<Class name="hudson.cli.DeleteViewCommand"/>
|
||||
<Class name="hudson.cli.DisablePluginCommand"/>
|
||||
<Class name="hudson.cli.DisconnectNodeCommand"/>
|
||||
<Class name="hudson.cli.EnablePluginCommand"/>
|
||||
<Class name="hudson.cli.GetJobCommand"/>
|
||||
<Class name="hudson.cli.GetViewCommand"/>
|
||||
<Class name="hudson.cli.GroovyCommand"/>
|
||||
<Class name="hudson.cli.HelpCommand"/>
|
||||
<Class name="hudson.cli.InstallPluginCommand"/>
|
||||
<Class name="hudson.cli.ListJobsCommand"/>
|
||||
<Class name="hudson.cli.OfflineNodeCommand"/>
|
||||
<Class name="hudson.cli.OnlineNodeCommand"/>
|
||||
<Class name="hudson.cli.QuietDownCommand"/>
|
||||
<Class name="hudson.cli.ReloadConfigurationCommand"/>
|
||||
<Class name="hudson.cli.ReloadJobCommand"/>
|
||||
<Class name="hudson.cli.RemoveJobFromViewCommand"/>
|
||||
<Class name="hudson.cli.RunRangeCommand"/>
|
||||
<Class name="hudson.cli.SetBuildDescriptionCommand"/>
|
||||
<Class name="hudson.cli.SetBuildDisplayNameCommand"/>
|
||||
<Class name="hudson.cli.UpdateJobCommand"/>
|
||||
<Class name="hudson.cli.UpdateViewCommand"/>
|
||||
<Class name="hudson.cli.WaitNodeOfflineCommand"/>
|
||||
<Class name="hudson.cli.WaitNodeOnlineCommand"/>
|
||||
<Class name="hudson.Functions"/>
|
||||
<Class name="hudson.logging.LogRecorderManager"/>
|
||||
<Class name="hudson.Main"/>
|
||||
<Class name="hudson.model.AbstractBuild$AbstractBuildExecution"/>
|
||||
<Class name="hudson.model.Actionable"/>
|
||||
<Class name="hudson.model.AperiodicWork"/>
|
||||
<Class name="hudson.model.Build$BuildExecution"/>
|
||||
<Class name="hudson.model.ComputerSet"/>
|
||||
<Class name="hudson.model.FileParameterValue$FileItemImpl"/>
|
||||
<Class name="hudson.model.Job"/>
|
||||
<Class name="hudson.model.Label"/>
|
||||
<Class name="hudson.model.listeners.SCMListener"/>
|
||||
<Class name="hudson.model.Run$RunExecution"/>
|
||||
<Class name="hudson.model.TaskThread"/>
|
||||
<Class name="hudson.model.User"/>
|
||||
<Class name="hudson.model.View"/>
|
||||
<Class name="hudson.model.View$AsynchPeople"/>
|
||||
<Class name="hudson.Plugin"/>
|
||||
<Class name="hudson.PluginWrapper"/>
|
||||
<Class name="hudson.security.ACL"/>
|
||||
<Class name="hudson.slaves.SlaveComputer"/>
|
||||
<Class name="hudson.tools.ToolInstallation"/>
|
||||
<Class name="hudson.util.Retrier"/>
|
||||
<Class name="jenkins.agents.WebSocketAgents$Session"/>
|
||||
<Class name="jenkins.ClassLoaderReflectionToolkit"/>
|
||||
<Class name="jenkins.cli.StopBuildsCommand"/>
|
||||
<Class name="jenkins.management.AsynchronousAdministrativeMonitor"/>
|
||||
<Class name="jenkins.model.ModelObjectWithChildren"/>
|
||||
<Class name="jenkins.model.ModelObjectWithContextMenu"/>
|
||||
<Class name="jenkins.model.RunIdMigrator"/>
|
||||
<Class name="jenkins.security.RekeySecretAdminMonitor"/>
|
||||
<Class name="jenkins.security.ResourceDomainRootAction"/>
|
||||
<Class name="jenkins.security.UserDetailsCache$Retriever"/>
|
||||
<Class name="jenkins.slaves.restarter.JnlpSlaveRestarterInstaller$Install"/>
|
||||
<Class name="jenkins.slaves.restarter.SlaveRestarter"/>
|
||||
<Class name="jenkins.slaves.restarter.UnixSlaveRestarter"/>
|
||||
<Class name="jenkins.slaves.restarter.WinswSlaveRestarter"/>
|
||||
<Class name="jenkins.slaves.StandardOutputSwapper$ChannelSwapper"/>
|
||||
<Class name="jenkins.util.ProgressiveRendering"/>
|
||||
<Class name="jenkins.websocket.WebSockets"/>
|
||||
<Class name="jenkins.websocket.WebSocketSession"/>
|
||||
<Class name="jenkins.widgets.RunListProgressiveRendering"/>
|
||||
</Or>
|
||||
</And>
|
||||
<And>
|
||||
<Bug pattern="THROWS_METHOD_THROWS_CLAUSE_THROWABLE"/>
|
||||
<Or>
|
||||
<Class name="hudson.EnvVars$GetEnvVars"/>
|
||||
<Class name="hudson.FilePath"/>
|
||||
<Class name="hudson.FilePath$GetHomeDirectory"/>
|
||||
<Class name="hudson.FilePath$IsUnix"/>
|
||||
<Class name="hudson.Launcher$RemoteChannelLaunchCallable"/>
|
||||
<Class name="hudson.Launcher$RemoteLaunchCallable"/>
|
||||
<Class name="hudson.Launcher$RemoteLauncher$KillTask"/>
|
||||
<Class name="hudson.logging.LogRecorder$SetLevel"/>
|
||||
<Class name="hudson.model.Computer$DumpExportTableTask"/>
|
||||
<Class name="hudson.model.Computer$GetFallbackName"/>
|
||||
<Class name="hudson.model.Computer$ListPossibleNames"/>
|
||||
<Class name="hudson.model.DirectoryBrowserSupport$BuildChildPaths"/>
|
||||
<Class name="hudson.model.DirectoryBrowserSupport$IsAbsolute"/>
|
||||
<Class name="hudson.model.Items"/>
|
||||
<Class name="hudson.model.Queue"/>
|
||||
<Class name="hudson.model.Queue$LockedHRCallable"/>
|
||||
<Class name="hudson.model.Run$AddArtifacts"/>
|
||||
<Class name="hudson.model.Slave$GetClockDifference1"/>
|
||||
<Class name="hudson.model.Slave$GetClockDifference2"/>
|
||||
<Class name="hudson.node_monitors.ArchitectureMonitor$GetArchTask"/>
|
||||
<Class name="hudson.node_monitors.ResponseTimeMonitor$Step1"/>
|
||||
<Class name="hudson.node_monitors.ResponseTimeMonitor$Step2"/>
|
||||
<Class name="hudson.node_monitors.SwapSpaceMonitor$MonitorTask"/>
|
||||
<Class name="hudson.os.SU"/>
|
||||
<Class name="hudson.slaves.ChannelPinger$SetUpRemotePing"/>
|
||||
<Class name="hudson.slaves.ConnectionActivityMonitor$PingCommand"/>
|
||||
<Class name="hudson.slaves.SlaveComputer$AbsolutePath"/>
|
||||
<Class name="hudson.slaves.SlaveComputer$CommunicationProtocol"/>
|
||||
<Class name="hudson.slaves.SlaveComputer$DetectDefaultCharset"/>
|
||||
<Class name="hudson.slaves.SlaveComputer$DetectOS"/>
|
||||
<Class name="hudson.slaves.SlaveComputer$ListFullEnvironment"/>
|
||||
<Class name="hudson.slaves.SlaveComputer$LoadingCount"/>
|
||||
<Class name="hudson.slaves.SlaveComputer$LoadingPrefetchCacheCount"/>
|
||||
<Class name="hudson.slaves.SlaveComputer$LoadingTime"/>
|
||||
<Class name="hudson.slaves.SlaveComputer$SlaveInitializer"/>
|
||||
<Class name="hudson.slaves.SlaveComputer$SlaveLogFetcher"/>
|
||||
<Class name="hudson.slaves.SlaveComputer$SlaveVersion"/>
|
||||
<Class name="hudson.tasks.Maven$MavenInstallation$GetExecutable"/>
|
||||
<Class name="hudson.tasks.Maven$MavenInstallation$GetMavenVersion"/>
|
||||
<Class name="hudson.tasks.Shell$DescriptorImpl$Shellinterpreter"/>
|
||||
<Class name="hudson.util.AtomicFileWriter"/>
|
||||
<Class name="hudson.util.InvocationInterceptor"/>
|
||||
<Class name="hudson.util.io.ParserConfigurator$GetParserConfigurators"/>
|
||||
<Class name="hudson.util.jna.InitializationErrorInvocationHandler"/>
|
||||
<Class name="hudson.util.jna.RegistryKey"/>
|
||||
<Class name="hudson.util.ProcessTree$DoVetoersExist"/>
|
||||
<Class name="hudson.util.ProcessTree$ListAll"/>
|
||||
<Class name="hudson.util.ProcessTree$OSProcess$CheckVetoes"/>
|
||||
<Class name="hudson.util.RemotingDiagnostics$GetHeapDump"/>
|
||||
<Class name="hudson.util.RemotingDiagnostics$GetSystemProperties"/>
|
||||
<Class name="hudson.util.RemotingDiagnostics$GetThreadDump"/>
|
||||
<Class name="hudson.util.RemotingDiagnostics$Script"/>
|
||||
<Class name="jenkins.model.Jenkins$ClockDifferenceCallable"/>
|
||||
<Class name="jenkins.slaves.restarter.JnlpSlaveRestarterInstaller$FindEffectiveRestarters"/>
|
||||
<Class name="jenkins.slaves.StandardOutputSwapper$ChannelSwapper"/>
|
||||
<Class name="jenkins.util.SystemProperties$AgentCopier$CopySystemProperties"/>
|
||||
<Class name="jenkins.util.VirtualFile$CollectFiles"/>
|
||||
</Or>
|
||||
</And>
|
||||
<And>
|
||||
<Bug pattern="THROWS_METHOD_THROWS_RUNTIMEEXCEPTION"/>
|
||||
<Or>
|
||||
<Class name="hudson.cli.CLICommand"/>
|
||||
<Class name="hudson.cli.GroovyshCommand"/>
|
||||
<Class name="hudson.cli.ListChangesCommand"/>
|
||||
<Class name="hudson.cli.ReloadConfigurationCommand"/>
|
||||
<Class name="hudson.ExtensionFinder$GuiceFinder$SezpozModule"/>
|
||||
<Class name="hudson.lifecycle.Lifecycle"/>
|
||||
<Class name="hudson.model.queue.Executables"/>
|
||||
<Class name="hudson.model.UpdateCenter"/>
|
||||
<Class name="hudson.model.UpdateCenter$InstallationJob"/>
|
||||
<Class name="hudson.model.User"/>
|
||||
<Class name="hudson.search.ParsedQuickSilver$MethodGetter"/>
|
||||
<Class name="hudson.security.AbstractPasswordBasedSecurityRealm"/>
|
||||
<Class name="hudson.security.HudsonPrivateSecurityRealm"/>
|
||||
<Class name="hudson.security.SecurityRealm"/>
|
||||
<Class name="hudson.slaves.SlaveComputer"/>
|
||||
<Class name="hudson.util.ChunkedInputStream"/>
|
||||
<Class name="hudson.util.ConsistentHash"/>
|
||||
<Class name="hudson.util.DescribableList$ConverterImpl"/>
|
||||
<Class name="hudson.util.DoubleLaunchChecker"/>
|
||||
<Class name="hudson.util.PersistedList"/>
|
||||
<Class name="hudson.util.PersistedList$ConverterImpl"/>
|
||||
<Class name="jenkins.ClassLoaderReflectionToolkit"/>
|
||||
<Class name="jenkins.install.InstallState$InitialSecuritySetup"/>
|
||||
<Class name="jenkins.install.InstallState$InitialSetupCompleted"/>
|
||||
<Class name="jenkins.install.SetupWizard"/>
|
||||
<Class name="jenkins.model.Jenkins"/>
|
||||
<Class name="jenkins.model.lazy.LazyBuildMixIn"/>
|
||||
<Class name="jenkins.model.Nodes"/>
|
||||
<Class name="jenkins.security.AcegiSecurityExceptionFilter"/>
|
||||
<Class name="jenkins.security.ImpersonatingUserDetailsService"/>
|
||||
<Class name="jenkins.security.ImpersonatingUserDetailsService2"/>
|
||||
<Class name="org.acegisecurity.AuthenticationManager"/>
|
||||
<Class name="org.acegisecurity.userdetails.UserDetailsService"/>
|
||||
<Class name="org.acegisecurity.util.FieldUtils"/>
|
||||
</Or>
|
||||
</And>
|
||||
<And>
|
||||
<Bug pattern="UNENCRYPTED_SERVER_SOCKET"/>
|
||||
<Class name="hudson.slaves.Channels"/>
|
||||
|
|
|
@ -85,7 +85,7 @@ THE SOFTWARE.
|
|||
<dependency>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<artifactId>jenkins-test-harness</artifactId>
|
||||
<version>1752.v86627a_c48d91</version>
|
||||
<version>1753.v45c760e2400f</version>
|
||||
<scope>test</scope>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
|
@ -145,13 +145,13 @@ THE SOFTWARE.
|
|||
<dependency>
|
||||
<groupId>org.jenkins-ci.plugins</groupId>
|
||||
<artifactId>cloudbees-folder</artifactId>
|
||||
<version>6.722.v8165b_a_cf25e9</version>
|
||||
<version>6.729.v2b_9d1a_74d673</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jenkins-ci.plugins</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>1.63</version>
|
||||
<version>1119.va_a_5e9068da_d7</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
|
|
|
@ -613,17 +613,16 @@ public class AbstractProjectTest {
|
|||
* </div>
|
||||
*/
|
||||
DomNodeList<DomNode> domNodes = htmlPage.getDocumentElement().querySelectorAll("*");
|
||||
assertThat(domNodes, hasSize(5));
|
||||
assertThat(domNodes, hasSize(4));
|
||||
assertEquals("head", domNodes.get(0).getNodeName());
|
||||
assertEquals("body", domNodes.get(1).getNodeName());
|
||||
assertEquals("div", domNodes.get(2).getNodeName());
|
||||
assertEquals("img", domNodes.get(3).getNodeName());
|
||||
assertEquals("a", domNodes.get(4).getNodeName());
|
||||
assertEquals("a", domNodes.get(3).getNodeName());
|
||||
|
||||
// only: "><img src=x onerror=alert(123)>
|
||||
// the first double quote was escaped during creation (with the backslash)
|
||||
String unquotedLabel = Label.parseExpression(label).getName();
|
||||
HtmlAnchor anchor = (HtmlAnchor) domNodes.get(4);
|
||||
HtmlAnchor anchor = (HtmlAnchor) domNodes.get(3);
|
||||
assertThat(anchor.getHrefAttribute(), containsString(Util.rawEncode(unquotedLabel)));
|
||||
|
||||
assertThat(responseContent, containsString("ok"));
|
||||
|
|
|
@ -177,7 +177,7 @@ public class NumberTest {
|
|||
input.reset(); // Remove the value that already in the <input>
|
||||
input.type(value); // Type value to <input>
|
||||
input.fireEvent(Event.TYPE_CHANGE); // The error message is triggered by change event
|
||||
return input.getParentNode().getNextSibling().getChildNodes().get(1).getChildNodes().get(0).getTextContent();
|
||||
return input.getParentNode().getNextSibling().getTextContent();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -542,64 +542,6 @@ div.behavior-loading {
|
|||
padding: 0;
|
||||
}
|
||||
|
||||
|
||||
/* ======================== error/warning message (mainly in the form.) Use them on block elements ======================== */
|
||||
.error {
|
||||
color: #c00;
|
||||
font-weight: bold;
|
||||
padding-left: 20px;
|
||||
min-height: 16px;
|
||||
line-height: 16px;
|
||||
background-image: url("../../images/svgs/error.svg");
|
||||
background-position: left top;
|
||||
background-repeat: no-repeat;
|
||||
background-size: 16px 16px;
|
||||
}
|
||||
|
||||
.error-inline {
|
||||
color: #c00;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.warning {
|
||||
color: #c4a000;
|
||||
font-weight: bold;
|
||||
padding-left: 20px;
|
||||
min-height: 16px;
|
||||
line-height: 16px;
|
||||
background-image: url("../../images/svgs/warning.svg");
|
||||
background-position: left top;
|
||||
background-repeat: no-repeat;
|
||||
background-size: 16px 16px;
|
||||
}
|
||||
|
||||
.warning-inline {
|
||||
color: #c4a000;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.info {
|
||||
position: relative;
|
||||
color: var(--text-color);
|
||||
font-weight: bold;
|
||||
min-height: 16px;
|
||||
padding-left: 30px;
|
||||
|
||||
&::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
width: 20px;
|
||||
background: currentColor;
|
||||
mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' class='ionicon' viewBox='0 0 512 512'%3E%3Ctitle%3EArrow Forward%3C/title%3E%3Cpath fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='32' d='M268 112l144 144-144 144M392 256H100'/%3E%3C/svg%3E");
|
||||
mask-position: center;
|
||||
mask-size: contain;
|
||||
mask-repeat: no-repeat;
|
||||
}
|
||||
}
|
||||
|
||||
.icon16x16 {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
|
|
|
@ -0,0 +1,84 @@
|
|||
.validation-error-area {
|
||||
transition: var(--standard-transition);
|
||||
opacity: 0;
|
||||
height: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.validation-error-area--visible {
|
||||
margin-top: 0.75rem;
|
||||
opacity: 1;
|
||||
|
||||
& > * {
|
||||
animation: animate-validation-error-area var(--standard-transition);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes animate-validation-error-area {
|
||||
from {
|
||||
opacity: 0;
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.error,
|
||||
.warning,
|
||||
.info {
|
||||
position: relative;
|
||||
padding-left: calc(22px + 0.4rem);
|
||||
font-weight: 500;
|
||||
|
||||
&::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
width: 22px;
|
||||
height: 22px;
|
||||
background-color: currentColor;
|
||||
mask-position: top center;
|
||||
mask-repeat: no-repeat;
|
||||
mask-size: contain;
|
||||
}
|
||||
}
|
||||
|
||||
.ok {
|
||||
color: var(--text-color-secondary);
|
||||
}
|
||||
|
||||
.error {
|
||||
color: var(--red);
|
||||
|
||||
&::before {
|
||||
mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='512' height='512' viewBox='0 0 512 512'%3E%3Ctitle%3Eionicons-v5-a%3C/title%3E%3Cpath d='M256,48C141.31,48,48,141.31,48,256s93.31,208,208,208,208-93.31,208-208S370.69,48,256,48Zm0,319.91a20,20,0,1,1,20-20A20,20,0,0,1,256,367.91Zm21.72-201.15-5.74,122a16,16,0,0,1-32,0l-5.74-121.94v-.05a21.74,21.74,0,1,1,43.44,0Z'/%3E%3C/svg%3E");
|
||||
}
|
||||
}
|
||||
|
||||
.error-inline {
|
||||
color: var(--red);
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.warning {
|
||||
color: var(--orange);
|
||||
|
||||
&::before {
|
||||
mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='512' height='512' viewBox='0 0 512 512'%3E%3Ctitle%3Eionicons-v5-r%3C/title%3E%3Cpath d='M449.07,399.08,278.64,82.58c-12.08-22.44-44.26-22.44-56.35,0L51.87,399.08A32,32,0,0,0,80,446.25H420.89A32,32,0,0,0,449.07,399.08Zm-198.6-1.83a20,20,0,1,1,20-20A20,20,0,0,1,250.47,397.25ZM272.19,196.1l-5.74,122a16,16,0,0,1-32,0l-5.74-121.95v0a21.73,21.73,0,0,1,21.5-22.69h.21a21.74,21.74,0,0,1,21.73,22.7Z'/%3E%3C/svg%3E");
|
||||
}
|
||||
}
|
||||
|
||||
.warning-inline {
|
||||
color: var(--orange);
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.info {
|
||||
color: var(--text-color);
|
||||
|
||||
&::before {
|
||||
mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' class='ionicon' viewBox='0 0 512 512'%3E%3Ctitle%3EArrow Forward%3C/title%3E%3Cpath fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='32' d='M268 112l144 144-144 144M392 256H100'/%3E%3C/svg%3E");
|
||||
}
|
||||
}
|
|
@ -32,6 +32,7 @@ html {
|
|||
@import './form/search';
|
||||
@import './form/select';
|
||||
@import './form/toggle-switch';
|
||||
@import './form/validation';
|
||||
|
||||
@import './modules/app-bar';
|
||||
@import './modules/badges';
|
||||
|
|
|
@ -232,7 +232,7 @@ var FormChecker = {
|
|||
this.sendRequest(next.url, {
|
||||
method : next.method,
|
||||
onComplete : function(x) {
|
||||
applyErrorMessage(next.target, x);
|
||||
updateValidationArea(next.target, x.responseText);
|
||||
FormChecker.inProgress--;
|
||||
FormChecker.schedule();
|
||||
layoutUpdateCallback.call();
|
||||
|
@ -500,16 +500,53 @@ var tooltip;
|
|||
// Behavior rules
|
||||
//========================================================
|
||||
// using tag names in CSS selector makes the processing faster
|
||||
|
||||
|
||||
/**
|
||||
* Updates the validation area for a form element
|
||||
* @param {HTMLElement} validationArea The validation area for a given form element
|
||||
* @param {string} content The content to update the validation area with
|
||||
*/
|
||||
function updateValidationArea(validationArea, content) {
|
||||
validationArea.classList.add("validation-error-area--visible");
|
||||
|
||||
if (content === "<div/>") {
|
||||
validationArea.classList.remove("validation-error-area--visible");
|
||||
validationArea.style.height = "0px";
|
||||
validationArea.innerHTML = content;
|
||||
} else {
|
||||
// Only change content if different, causes an unnecessary animation otherwise
|
||||
if (validationArea.innerHTML !== content) {
|
||||
validationArea.innerHTML = content;
|
||||
validationArea.style.height = validationArea.children[0].offsetHeight + "px";
|
||||
|
||||
// Only include the notice in the validation-error-area, move all other elements out
|
||||
if (validationArea.children.length > 1) {
|
||||
Array.from(validationArea.children).slice(1).forEach((element) => {
|
||||
validationArea.after(element);
|
||||
})
|
||||
}
|
||||
|
||||
Behaviour.applySubtree(validationArea);
|
||||
// For errors with additional details, apply the subtree to the expandable details pane
|
||||
if (validationArea.nextElementSibling) {
|
||||
Behaviour.applySubtree(validationArea.nextElementSibling);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function registerValidator(e) {
|
||||
|
||||
// Retrieve the validation error area
|
||||
var tr = findFollowingTR(e, "validation-error-area");
|
||||
var tr = e.closest(".jenkins-form-item").querySelector(".validation-error-area");
|
||||
if (!tr) {
|
||||
console.warn("Couldn't find the expected parent element (.setting-main) for element", e)
|
||||
console.warn("Couldn't find the expected validation element (.validation-error-area) for element",
|
||||
e.closest(".jenkins-form-item"))
|
||||
return;
|
||||
}
|
||||
// find the validation-error-area
|
||||
e.targetElement = tr.firstElementChild.nextSibling;
|
||||
e.targetElement = tr;
|
||||
|
||||
e.targetUrl = function() {
|
||||
var url = this.getAttribute("checkUrl");
|
||||
|
@ -545,19 +582,13 @@ function registerValidator(e) {
|
|||
}
|
||||
|
||||
var checker = function() {
|
||||
var target = this.targetElement;
|
||||
const validationArea = this.targetElement;
|
||||
FormChecker.sendRequest(this.targetUrl(), {
|
||||
method : method,
|
||||
onComplete : function(x) {
|
||||
if (x.status == 200) {
|
||||
// All FormValidation responses are 200
|
||||
target.innerHTML = x.responseText;
|
||||
} else {
|
||||
// Content is taken from FormValidation#_errorWithMarkup
|
||||
// TODO Add i18n support
|
||||
target.innerHTML = "<div class='error'>An internal error occurred during form field validation (HTTP " + x.status + "). Please reload the page and if the problem persists, ask the administrator for help.</div>";
|
||||
}
|
||||
Behaviour.applySubtree(target);
|
||||
onComplete: function({status, responseText}) {
|
||||
// TODO Add i18n support
|
||||
const errorMessage = `<div class="error">An internal error occurred during form field validation (HTTP ${status}). Please reload the page and if the problem persists, ask the administrator for help.</div>`;
|
||||
updateValidationArea(validationArea, status === 200 ? responseText : errorMessage);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -584,22 +615,25 @@ function registerValidator(e) {
|
|||
}
|
||||
|
||||
function registerRegexpValidator(e,regexp,message) {
|
||||
var tr = findFollowingTR(e, "validation-error-area");
|
||||
var tr = e.closest(".jenkins-form-item").querySelector( ".validation-error-area");
|
||||
if (!tr) {
|
||||
console.warn("Couldn't find the expected parent element (.setting-main) for element", e)
|
||||
console.warn("Couldn't find the expected parent element (.setting-main) for element",
|
||||
e.closest(".jenkins-form-item"))
|
||||
return;
|
||||
}
|
||||
// find the validation-error-area
|
||||
e.targetElement = tr.firstElementChild.nextSibling;
|
||||
e.targetElement = tr;
|
||||
var checkMessage = e.getAttribute('checkMessage');
|
||||
if (checkMessage) message = checkMessage;
|
||||
var oldOnchange = e.onchange;
|
||||
e.onchange = function() {
|
||||
var set = oldOnchange != null ? oldOnchange.call(this) : false;
|
||||
if (this.value.match(regexp)) {
|
||||
if (!set) this.targetElement.innerHTML = "<div/>";
|
||||
if (!set) {
|
||||
updateValidationArea(this.targetElement, `<div/>`)
|
||||
}
|
||||
} else {
|
||||
this.targetElement.innerHTML = "<div class=error>" + message + "</div>";
|
||||
updateValidationArea(this.targetElement, `<div class="error">${message}</div>`);
|
||||
set = true;
|
||||
}
|
||||
return set;
|
||||
|
@ -613,13 +647,14 @@ function registerRegexpValidator(e,regexp,message) {
|
|||
* @param e Input element
|
||||
*/
|
||||
function registerMinMaxValidator(e) {
|
||||
var tr = findFollowingTR(e, "validation-error-area");
|
||||
var tr = e.closest(".jenkins-form-item").querySelector( ".validation-error-area");
|
||||
if (!tr) {
|
||||
console.warn("Couldn't find the expected parent element (.setting-main) for element", e)
|
||||
console.warn("Couldn't find the expected parent element (.setting-main) for element",
|
||||
e.closest(".jenkins-form-item"))
|
||||
return;
|
||||
}
|
||||
// find the validation-error-area
|
||||
e.targetElement = tr.firstElementChild.nextSibling;
|
||||
e.targetElement = tr;
|
||||
var checkMessage = e.getAttribute('checkMessage');
|
||||
if (checkMessage) message = checkMessage;
|
||||
var oldOnchange = e.onchange;
|
||||
|
@ -638,29 +673,35 @@ function registerMinMaxValidator(e) {
|
|||
|
||||
if (min <= max) { // Add the validator if min <= max
|
||||
if (parseInt(min) > parseInt(this.value) || parseInt(this.value) > parseInt(max)) { // The value is out of range
|
||||
this.targetElement.innerHTML = "<div class=error>This value should be between " + min + " and " + max + "</div>";
|
||||
updateValidationArea(this.targetElement, `<div class="error">This value should be between ${min} and ${max}</div>`);
|
||||
set = true;
|
||||
} else {
|
||||
if (!set) this.targetElement.innerHTML = "<div/>"; // The value is valid
|
||||
if (!set) {
|
||||
updateValidationArea(this.targetElement, `<div/>`)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} else if ((min !== null && isInteger(min)) && (max === null || !isInteger(max))) { // There is only 'min' available
|
||||
|
||||
if (parseInt(min) > parseInt(this.value)) {
|
||||
this.targetElement.innerHTML = "<div class=error>This value should be larger than " + min + "</div>";
|
||||
updateValidationArea(this.targetElement, `<div class="error">This value should be larger than ${min}</div>`);
|
||||
set = true;
|
||||
} else {
|
||||
if (!set) this.targetElement.innerHTML = "<div/>";
|
||||
if (!set) {
|
||||
updateValidationArea(this.targetElement, `<div/>`)
|
||||
}
|
||||
}
|
||||
|
||||
} else if ((min === null || !isInteger(min)) && (max !== null && isInteger(max))) { // There is only 'max' available
|
||||
|
||||
if (parseInt(max) < parseInt(this.value)) {
|
||||
this.targetElement.innerHTML = "<div class=error>This value should be less than " + max + "</div>";
|
||||
updateValidationArea(this.targetElement, `<div class="error">This value should be less than ${max}</div>`);
|
||||
set = true;
|
||||
} else {
|
||||
if (!set) this.targetElement.innerHTML = "<div/>";
|
||||
if (!set) {
|
||||
updateValidationArea(this.targetElement, `<div/>`)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2324,15 +2365,16 @@ function validateButton(checkUrl,paramList,button) {
|
|||
}
|
||||
});
|
||||
|
||||
var spinner = $(button).up("DIV").next();
|
||||
var target = spinner.next();
|
||||
var spinner = button.up("DIV").children[0];
|
||||
var target = spinner.next().next();
|
||||
spinner.style.display="block";
|
||||
|
||||
new Ajax.Request(checkUrl, {
|
||||
parameters: parameters,
|
||||
onComplete: function(rsp) {
|
||||
spinner.style.display="none";
|
||||
applyErrorMessage(target, rsp);
|
||||
target.innerHTML = `<div class="validation-error-area" />`;
|
||||
updateValidationArea(target.children[0], rsp.responseText);
|
||||
layoutUpdateCallback.call();
|
||||
var s = rsp.getResponseHeader("script");
|
||||
try {
|
||||
|
@ -2344,26 +2386,6 @@ function validateButton(checkUrl,paramList,button) {
|
|||
});
|
||||
}
|
||||
|
||||
function applyErrorMessage(elt, rsp) {
|
||||
if (rsp.status == 200) {
|
||||
elt.innerHTML = rsp.responseText;
|
||||
} else {
|
||||
var id = 'valerr' + (iota++);
|
||||
elt.innerHTML = '<a href="" onclick="document.getElementById(\'' + id
|
||||
+ '\').style.display=\'block\';return false">ERROR</a><div id="'
|
||||
+ id + '" style="display:none">' + rsp.responseText + '</div>';
|
||||
var error = document.getElementById('error-description'); // cf. oops.jelly
|
||||
if (error) {
|
||||
var div = document.getElementById(id);
|
||||
while (div.firstElementChild) {
|
||||
div.removeChild(div.firstElementChild);
|
||||
}
|
||||
div.appendChild(error);
|
||||
}
|
||||
}
|
||||
Behaviour.applySubtree(elt);
|
||||
}
|
||||
|
||||
// create a combobox.
|
||||
// @param idOrField
|
||||
// ID of the <input type=text> element that becomes a combobox, or the field itself.
|
||||
|
|
Loading…
Reference in New Issue