package hudson.plugins.im.tools; import hudson.model.AbstractBuild; import hudson.model.Run; import hudson.model.Result; import hudson.model.ResultTrend; /** * Helper class to work with Hudson builds. * * @author kutzi */ public class BuildHelper { /** * Extended result description of a build. * * @author kutzi * * @deprecated use {@link ResultTrend}! */ @Deprecated public static enum ExtResult { FIXED, SUCCESS, /** * Marks a build which was previously a failure and is now 'only' unstable. */ NOW_UNSTABLE("NOW UNSTABLE"), STILL_UNSTABLE("STILL UNSTABLE"), UNSTABLE, STILL_FAILING("STILL FAILING"), FAILURE, ABORTED, NOT_BUILT("NOT BUILT"); private final String description; private ExtResult() { this.description = null; } private ExtResult(String description) { this.description = description; } @Override public String toString() { return this.description != null ? this.description : super.toString(); } } private BuildHelper() { // no instances } /** * Returns true if this build represents a 'fix'. * I.e. it is the first successful build after previous * 'failed' and/or 'unstable' builds. * Ignores 'aborted' and 'not built' builds. * * @deprecated use {@link ResultTrend#FIXED}! */ @Deprecated public static boolean isFix(AbstractBuild<?, ?> build) { if (build.getResult() != Result.SUCCESS) { return false; } AbstractBuild<?, ?> previousBuild = getPreviousNonAbortedBuild(build); if (previousBuild != null) { Result previousResult = previousBuild.getResult(); return previousResult != null && previousResult.isWorseThan(Result.SUCCESS); } return false; } /** * Does what the name says. * * @deprecated use {@link ResultTrend#FAILURE} || {@link ResultTrend#UNSTABLE}! */ @Deprecated public static boolean isFailureOrUnstable(AbstractBuild<?,?> build) { return build.getResult() == Result.FAILURE || build.getResult() == Result.UNSTABLE; } /** * @deprecated use {@link ResultTrend#STILL_FAILING} || {@link ResultTrend#STILL_UNSTABLE}! */ @Deprecated public static boolean isStillFailureOrUnstable(AbstractBuild<?, ?> build) { ExtResult result = getExtendedResult(build); return result == ExtResult.STILL_FAILING || result == ExtResult.STILL_UNSTABLE; } /** * Returns the previous 'not aborted' build (i.e. ignores ABORTED and NOT_BUILT builds) * or null. */ public static AbstractBuild<?, ?> getPreviousNonAbortedBuild(AbstractBuild<?, ?> build) { AbstractBuild<?, ?> previousBuild = build.getPreviousBuild(); while (previousBuild != null) { if (previousBuild.getResult() == Result.ABORTED || previousBuild.getResult() == Result.NOT_BUILT) { previousBuild = previousBuild.getPreviousBuild(); } else { return previousBuild; } } return previousBuild; } /** * Returns the previous successful build (i.e. build with result SUCCESS) * or null. * * @deprecated use {@link Run#getPreviousSuccessfulBuild()} */ public static AbstractBuild<?, ?> getPreviousSuccessfulBuild(AbstractBuild<?, ?> build) { AbstractBuild<?, ?> previousBuild = build.getPreviousBuild(); while (previousBuild != null) { if (previousBuild.getResult() != Result.SUCCESS) { previousBuild = previousBuild.getPreviousBuild(); } else { return previousBuild; } } return null; } /** * Returns a textual description of the result taking the previous build into * account. * E.g. reports 'fixes' and 'still failing/unstable' builds. * * @deprecated use ResultTrend.getResultTrend(build).getID() */ @Deprecated public static String getResultDescription(AbstractBuild<?, ?> build) { ExtResult result = getExtendedResult(build); return result.toString(); } /** * Returns the extended result description of a build. */ public static ExtResult getExtendedResult(AbstractBuild<?, ?> build) { Result result = build.getResult(); if (result == Result.ABORTED) { return ExtResult.ABORTED; } else if (result == Result.NOT_BUILT) { return ExtResult.NOT_BUILT; } if (result == Result.SUCCESS) { if (isFix(build)) { return ExtResult.FIXED; } else { return ExtResult.SUCCESS; } } AbstractBuild<?, ?> previousBuild = getPreviousNonAbortedBuild(build); if (result == Result.UNSTABLE) { if (previousBuild == null) { return ExtResult.UNSTABLE; } if (previousBuild.getResult() == Result.UNSTABLE) { return ExtResult.STILL_UNSTABLE; } else if (previousBuild.getResult() == Result.FAILURE) { return ExtResult.NOW_UNSTABLE; } else { return ExtResult.UNSTABLE; } } else if (result == Result.FAILURE) { if (previousBuild != null && previousBuild.getResult() == Result.FAILURE) { return ExtResult.STILL_FAILING; } else { return ExtResult.FAILURE; } } throw new IllegalArgumentException("Unknown result: '" + result + "' for build: " + build); } /** * Returns the name of the project the build belongs to in a human readable * format. */ public static String getProjectName(AbstractBuild<?, ?> build) { return build.getProject().getFullDisplayName(); } }