/** * @param bs A given {@link BuildStep}. * @return the full tokenized command line including the program name. */ @Nullable public static ImmutableList<String> resolveFullCmd(BuildStep bs) { for (BuildStepDetailsProvider<BuildStep> provider : all()) { if (provider.isApplicable(bs)) { String fullCmd = provider.getFullCmd(bs); // Some build steps are not triggered by command line command, // for example, GoogleCloudStorageUploader. For them, the fullCmd // with be null or empty. if (!Strings.isNullOrEmpty(fullCmd)) { return ImmutableList.copyOf(Arrays.asList(fullCmd.split("\\s+"))); } else { return ImmutableList.<String>of(); } } } return null; }
private void initPython() { if (pexec == null) { pexec = new PythonExecutor(this); String[] jMethods = new String[2]; jMethods[0] = "started"; jMethods[1] = "finished"; String[] pFuncs = new String[2]; pFuncs[0] = "started"; pFuncs[1] = "finished"; Class[][] argTypes = new Class[2][]; argTypes[0] = new Class[3]; argTypes[0][0] = AbstractBuild.class; argTypes[0][1] = BuildStep.class; argTypes[0][2] = BuildListener.class; argTypes[1] = new Class[4]; argTypes[1][0] = AbstractBuild.class; argTypes[1][1] = BuildStep.class; argTypes[1][2] = BuildListener.class; argTypes[1][3] = boolean.class; pexec.checkAbstrMethods(jMethods, pFuncs, argTypes); String[] functions = new String[0]; int[] argsCount = new int[0]; pexec.registerFunctions(functions, argsCount); } }
/** * @param bs A given {@link BuildStep}. * @return the details obtained from the {@link BuildStep}, null if there is not an extension to * obtain details. */ @Nullable public static String resolveDetails(BuildStep bs) { for (BuildStepDetailsProvider<BuildStep> provider : all()) { if (provider.isApplicable(bs)) { return provider.getDetails(bs); } } return null; }
/** * @param bs a {@link BuildStep}. * @return the display name of the {@link BuildStep}, if it is a {@link Describable}, otherwise * null. */ @Nullable public static String resolveName(BuildStep bs) { for (BuildStepDetailsProvider<BuildStep> provider : all()) { if (provider.isApplicable(bs)) { return provider.getName(bs); } } // Default to the display name of the plugin, if there isn't // a detail provider return defaultName(bs); }
private Class<? extends BuildStep> getSupportedBuildStepClass() { DetailFor detailFor = getClass().getAnnotation(DetailFor.class); requireNonNull(detailFor, "@DetailFor must be present on BuildStepDetailsProviders"); requireNonNull(detailFor.value(), "@DetailFor must have a value()"); return detailFor.value(); }
@Test @WithoutJenkins public void getDetails_noJenkins() { assertThat(BuildStepDetailsProvider.all()).isEmpty(); assertNull(BuildStepDetailsProvider.resolveDetails(mock(Maven.class))); assertNull(BuildStepDetailsProvider.resolveName(mock(BuildStep.class))); }
protected static String defaultName(BuildStep bs) { return bs instanceof Describable<?> ? ((Describable<?>) bs).getDescriptor().getDisplayName() : null; }
private boolean isApplicable(Class<? extends BuildStep> buildStepClass) { // Checks whether this extension supports the given build step class. return getSupportedBuildStepClass().isAssignableFrom(buildStepClass); }
@Override public boolean performStep(final BuildStep execution, final BuildListener listener) throws IOException, InterruptedException { return perform(execution, listener); }
@Override public boolean performStep(final BuildStep buildStep, final BuildListener listener) throws InterruptedException, IOException { return perform(buildStep, listener); }
@Override public void started(AbstractBuild build, BuildStep bs, BuildListener listener) { initPython(); pexec.execPythonVoid("started", build, bs, listener); }
@Override public void finished(AbstractBuild build, BuildStep bs, BuildListener listener, boolean canContinue) { initPython(); pexec.execPythonVoid("finished", build, bs, listener, DataConvertor.fromBool(canContinue)); }
public static boolean inheritanceLookupRequired(InheritanceProject root, boolean forcedInherit) { //In a cyclic dependency, any form of inheritance would be ill-advised try { if (root.hasCyclicDependency()) { return false; } } catch (NullPointerException ex) { //The project might not be loaded completely yet; this will cause //an NPE which means no inheritance should be queried return false; } /* Otherwise, an exploration is only required when one of the following * holds: * 1.) The user wants to force inheritance * 2.) The project is transient and has no real own configuration * 3.) The project is called in the context of a build * 4.) The queue queries properties of the project */ //Check forced inheritance or transience if (forcedInherit || root.getIsTransient()) { return true; } //Checking the Stapler Request, because it is fast StaplerRequest req = Stapler.getCurrentRequest(); if (req != null) { String uri = req.getRequestURI(); //Check if we request the build page if (uri.endsWith("/build")) { return true; } //Check if we were requested by page for a run if (runUriRegExp.matcher(uri).matches()) { return true; } } //Check via expensive stack reflection if (Reflection.calledFromClass( Build.class, BuildCommand.class, Queue.class, BuildTrigger.class, Trigger.class, BuildStep.class ) || Reflection.calledFromMethod( InheritanceProject.class, "doBuild", "scheduleBuild2", "doBuildWithParameters" ) ) { return true; } //In all other cases, we don't require (or want) inheritance return false; }
/** * @param buildStep a given {@link BuildStep}. * @return whether the {@link BuildStep} is supported by this extension. */ protected boolean isApplicable(BuildStep buildStep) { return isApplicable(buildStep.getClass()); }
boolean performStep(BuildStep buildStep, BuildListener listener) throws InterruptedException, IOException;