diff --git a/src/main/java/com/jenkinsci/plugins/badge/action/AbstractBadgeAction.java b/src/main/java/com/jenkinsci/plugins/badge/action/AbstractBadgeAction.java index 337c986..c233996 100644 --- a/src/main/java/com/jenkinsci/plugins/badge/action/AbstractBadgeAction.java +++ b/src/main/java/com/jenkinsci/plugins/badge/action/AbstractBadgeAction.java @@ -35,6 +35,8 @@ import jenkins.model.Jenkins; import org.apache.commons.lang.StringUtils; import org.jenkinsci.plugins.scriptsecurity.sandbox.whitelists.Whitelisted; +import org.kohsuke.accmod.Restricted; +import org.kohsuke.accmod.restrictions.NoExternalUse; /** * An abstract action providing an id amongst other fields to build a badge. @@ -209,7 +211,7 @@ protected Object readResolve() { } else if (color.startsWith("jenkins-!-")) { style += "color: var(--" + color.replaceFirst("jenkins-!-", "") + ");"; } else { - style += "color: " + color + ";"; + style += "color: " + getJenkinsColorStyle(color) + ";"; } } if (!style.isEmpty()) { @@ -218,4 +220,51 @@ protected Object readResolve() { return this; } + + /** + * Get the Jenkins color style for the given color reference. Returns {@code color} if the color is not a + * known Jenkins palette color or semantic color. + * @param color color reference + * @return jenkins color style variable + */ + @NonNull + @Restricted(NoExternalUse.class) + public static String getJenkinsColorStyle(@NonNull String color) { + String primary = color; + if (color.startsWith("light-") && color.length() > 6) { + primary = color.substring(6); + } else if (color.startsWith("dark-") && color.length() > 5) { + primary = color.substring(5); + } + // https://github.com/jenkinsci/jenkins/blob/master/src/main/scss/abstracts/_theme.scss + switch (primary) { + // palette + case "blue": + case "brown": + case "cyan": + case "green": + case "indigo": + case "orange": + case "pink": + case "purple": + case "red": + case "yellow": + case "white": + case "black": + return "var(--" + color + ")"; + // semantics + case "accent": + case "text": + case "error": + case "warning": + case "success": + case "destructive": + case "build": + case "danger": + case "info": + return "var(--" + color + "-color)"; + default: + return color; + } + } } diff --git a/src/main/java/com/jenkinsci/plugins/badge/dsl/AddBadgeStep.java b/src/main/java/com/jenkinsci/plugins/badge/dsl/AddBadgeStep.java index a274bdd..542359d 100644 --- a/src/main/java/com/jenkinsci/plugins/badge/dsl/AddBadgeStep.java +++ b/src/main/java/com/jenkinsci/plugins/badge/dsl/AddBadgeStep.java @@ -23,6 +23,7 @@ */ package com.jenkinsci.plugins.badge.dsl; +import com.jenkinsci.plugins.badge.action.AbstractBadgeAction; import com.jenkinsci.plugins.badge.action.BadgeAction; import edu.umd.cs.findbugs.annotations.NonNull; import hudson.Extension; @@ -60,7 +61,7 @@ public void setColor(String color) { } else if (color.startsWith("jenkins-!-")) { newStyle += "color: var(--" + color.replaceFirst("jenkins-!-", "") + ");"; } else { - newStyle += "color: " + color + ";"; + newStyle += "color: " + AbstractBadgeAction.getJenkinsColorStyle(color) + ";"; } setStyle(newStyle + StringUtils.defaultString(getStyle())); } diff --git a/src/main/java/com/jenkinsci/plugins/badge/dsl/AddShortTextStep.java b/src/main/java/com/jenkinsci/plugins/badge/dsl/AddShortTextStep.java index 5f196fe..21f250b 100644 --- a/src/main/java/com/jenkinsci/plugins/badge/dsl/AddShortTextStep.java +++ b/src/main/java/com/jenkinsci/plugins/badge/dsl/AddShortTextStep.java @@ -23,6 +23,7 @@ */ package com.jenkinsci.plugins.badge.dsl; +import com.jenkinsci.plugins.badge.action.AbstractBadgeAction; import com.jenkinsci.plugins.badge.action.BadgeAction; import edu.umd.cs.findbugs.annotations.NonNull; import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; @@ -220,7 +221,7 @@ protected Void run() throws Exception { } else if (shortText.getColor().startsWith("jenkins-!-")) { style += "color: var(--" + shortText.getColor().replaceFirst("jenkins-!-", "") + ");"; } else { - style += "color: " + shortText.getColor() + ";"; + style += "color: " + AbstractBadgeAction.getJenkinsColorStyle(shortText.getColor()) + ";"; } } diff --git a/src/test/java/com/jenkinsci/plugins/badge/dsl/LegacyPipelineTest.java b/src/test/java/com/jenkinsci/plugins/badge/dsl/LegacyPipelineTest.java index 5ef43f3..f4e84fc 100644 --- a/src/test/java/com/jenkinsci/plugins/badge/dsl/LegacyPipelineTest.java +++ b/src/test/java/com/jenkinsci/plugins/badge/dsl/LegacyPipelineTest.java @@ -23,19 +23,22 @@ */ package com.jenkinsci.plugins.badge.dsl; +import static org.junit.jupiter.api.Assertions.assertAll; import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNull; import com.jenkinsci.plugins.badge.action.BadgeAction; import com.jenkinsci.plugins.badge.action.BadgeSummaryAction; import hudson.markup.RawHtmlMarkupFormatter; import hudson.model.BuildBadgeAction; +import java.util.Arrays; import java.util.List; import java.util.UUID; +import java.util.stream.Stream; import org.jenkinsci.plugins.workflow.cps.CpsFlowDefinition; import org.jenkinsci.plugins.workflow.job.WorkflowJob; import org.jenkinsci.plugins.workflow.job.WorkflowRun; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.function.Executable; import org.jvnet.hudson.test.JenkinsRule; import org.jvnet.hudson.test.junit.jupiter.WithJenkins; @@ -44,38 +47,49 @@ class LegacyPipelineTest { @Test - void color(JenkinsRule r) throws Exception { - WorkflowRun run = runJob(r, "addBadge(color: 'red')"); - - List badgeActions = run.getBadgeActions(); - assertEquals(1, badgeActions.size()); - - BadgeAction action = (BadgeAction) badgeActions.get(0); - assertEquals("color: red;", action.getStyle()); - - run = runJob(r, "addBadge(color: 'jenkins-!-color-red')"); - - badgeActions = run.getBadgeActions(); - assertEquals(1, badgeActions.size()); - - action = (BadgeAction) badgeActions.get(0); - assertEquals("color: var(--red);", action.getStyle()); - - run = runJob(r, "addBadge(color: 'jenkins-!-warning-color')"); - - badgeActions = run.getBadgeActions(); - assertEquals(1, badgeActions.size()); - - action = (BadgeAction) badgeActions.get(0); - assertEquals("color: var(--warning-color);", action.getStyle()); + void color(JenkinsRule r) { + List colors = Arrays.asList( + "blue", "brown", "cyan", "green", "indigo", "orange", "pink", "purple", "red", "yellow", "white", + "black"); + Stream> palette = + colors.stream().map(c -> Arrays.asList("'" + c + "'", "color: var(--" + c + ");")); + Stream> paletteLight = + colors.stream().map(c -> Arrays.asList("'light-" + c + "'", "color: var(--light-" + c + ");")); + Stream> paletteDark = + colors.stream().map(c -> Arrays.asList("'dark-" + c + "'", "color: var(--dark-" + c + ");")); + + List semantics = Arrays.asList( + "accent", "text", "error", "warning", "success", "destructive", "build", "danger", "info"); + Stream> semantic = + semantics.stream().map(c -> Arrays.asList("'" + c + "'", "color: var(--" + c + "-color);")); + + Stream> other = Stream.of( + Arrays.asList("'light-'", "color: light-;"), + Arrays.asList("'dark-'", "color: dark-;"), + Arrays.asList("'#ff0000'", "color: #ff0000;"), + Arrays.asList("'tortoise'", "color: tortoise;"), + Arrays.asList("'jenkins-!-color-red'", "color: var(--red);"), + Arrays.asList("'jenkins-!-warning-color'", "color: var(--warning-color);"), + Arrays.asList("''", "color: ;"), + Arrays.asList("null", null)); + + assertAll("palette", colorTests(r, palette)); + assertAll("palette-light", colorTests(r, paletteLight)); + assertAll("palette-dark", colorTests(r, paletteDark)); + assertAll("semantic", colorTests(r, semantic)); + assertAll("other", colorTests(r, other)); + } - run = runJob(r, "addBadge(color: null)"); + private static Stream colorTests(JenkinsRule r, Stream> tests) { + return tests.map(params -> () -> { + WorkflowRun run = runJob(r, "addBadge(color: " + params.get(0) + ")"); - badgeActions = run.getBadgeActions(); - assertEquals(1, badgeActions.size()); + List badgeActions = run.getBadgeActions(); + assertEquals(1, badgeActions.size()); - action = (BadgeAction) badgeActions.get(0); - assertNull(action.getStyle()); + BadgeAction action = (BadgeAction) badgeActions.get(0); + assertEquals(params.get(1), action.getStyle()); + }); } @Test