diff --git a/pom.xml b/pom.xml index e41e876..30311e6 100644 --- a/pom.xml +++ b/pom.xml @@ -23,9 +23,11 @@ ${project.groupId}.prism + 2.426.1 + 1.29.0-9 + 1.19.2 1.16.2 - diff --git a/src/main/java/io/jenkins/plugins/prism/PrismAppearanceConfiguration.java b/src/main/java/io/jenkins/plugins/prism/PrismAppearanceConfiguration.java new file mode 100644 index 0000000..e64e055 --- /dev/null +++ b/src/main/java/io/jenkins/plugins/prism/PrismAppearanceConfiguration.java @@ -0,0 +1,107 @@ +package io.jenkins.plugins.prism; + +import edu.hm.hafner.util.VisibleForTesting; +import edu.umd.cs.findbugs.annotations.NonNull; +import hudson.Extension; +import hudson.util.ListBoxModel; +import io.jenkins.plugins.util.GlobalConfigurationFacade; +import io.jenkins.plugins.util.GlobalConfigurationItem; +import io.jenkins.plugins.util.JenkinsFacade; +import jenkins.appearance.AppearanceCategory; +import jenkins.model.GlobalConfiguration; +import jenkins.model.GlobalConfigurationCategory; +import jenkins.model.Jenkins; +import org.jenkinsci.Symbol; +import org.kohsuke.stapler.DataBoundSetter; +import org.kohsuke.stapler.verb.POST; + +/** + * Global system configuration for Prism. These configuration options are used globally for all jobs and require + * administrator permissions. + *

+ * The following settings can be configured: + *

+ * + * + * + * @author Ullrich Hafner + */ +@Extension +@Symbol("prism") +@SuppressWarnings("PMD.DataClass") +public class PrismAppearanceConfiguration extends GlobalConfigurationItem { + private PrismTheme theme = PrismTheme.PRISM; + private final JenkinsFacade jenkins; + + /** + * Creates the global configuration and loads the initial values from the corresponding + * XML file. + */ + public PrismAppearanceConfiguration() { + super(); + + jenkins = new JenkinsFacade(); + + load(); + } + + @VisibleForTesting + PrismAppearanceConfiguration(final GlobalConfigurationFacade facade, final JenkinsFacade jenkins) { + super(facade); + + this.jenkins = jenkins; + + load(); + } + + @NonNull + @Override + public GlobalConfigurationCategory getCategory() { + return GlobalConfigurationCategory.get(AppearanceCategory.class); + } + + /** + * Returns the singleton instance of this {@link PrismAppearanceConfiguration}. + * + * @return the singleton instance + */ + public static PrismAppearanceConfiguration getInstance() { + return GlobalConfiguration.all().get(PrismAppearanceConfiguration.class); + } + + /** + * Sets the active theme to be used when rendering the source code with prism. + * + * @param theme + * the theme to use + */ + @DataBoundSetter + public void setTheme(final PrismTheme theme) { + this.theme = theme; + + save(); + } + + public PrismTheme getTheme() { + return theme; + } + + /** + * Returns all available themes. + * + * @return a model with all available themes + */ + @POST + public ListBoxModel doFillThemeItems() { + ListBoxModel options = new ListBoxModel(); + if (jenkins.hasPermission(Jenkins.ADMINISTER)) { + options.addAll(PrismTheme.getAllDisplayNames()); + } + return options; + } +} diff --git a/src/main/java/io/jenkins/plugins/prism/PrismConfiguration.java b/src/main/java/io/jenkins/plugins/prism/PrismConfiguration.java index 3ced1a6..39c440a 100644 --- a/src/main/java/io/jenkins/plugins/prism/PrismConfiguration.java +++ b/src/main/java/io/jenkins/plugins/prism/PrismConfiguration.java @@ -1,25 +1,20 @@ package io.jenkins.plugins.prism; +import edu.hm.hafner.util.PathUtil; +import edu.hm.hafner.util.VisibleForTesting; +import edu.umd.cs.findbugs.annotations.NonNull; +import hudson.Extension; +import io.jenkins.plugins.util.GlobalConfigurationFacade; +import io.jenkins.plugins.util.GlobalConfigurationItem; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Set; import java.util.stream.Collectors; - -import edu.hm.hafner.util.PathUtil; -import edu.hm.hafner.util.VisibleForTesting; - -import org.kohsuke.stapler.DataBoundSetter; -import org.kohsuke.stapler.verb.POST; -import org.jenkinsci.Symbol; -import hudson.Extension; -import hudson.util.ListBoxModel; import jenkins.model.GlobalConfiguration; -import jenkins.model.Jenkins; - -import io.jenkins.plugins.util.GlobalConfigurationFacade; -import io.jenkins.plugins.util.GlobalConfigurationItem; -import io.jenkins.plugins.util.JenkinsFacade; +import jenkins.model.GlobalConfigurationCategory; +import org.jenkinsci.Symbol; +import org.kohsuke.stapler.DataBoundSetter; /** * Global system configuration for Prism. These configuration options are used globally for all jobs and require @@ -37,24 +32,23 @@ * that are allowed to be shown in Jenkins user interface here. Note, that such a directory must be an absolute path * on the agent that executes the build. * - *
  • - * Theme: Prism supports several themes that can be used to adapt the look and feel. You can configure the - * default theme that is used for all Jenkins jobs. - *
  • * * * @author Ullrich Hafner */ @Extension -@Symbol("prismConfiguration") +@Symbol("prism") @SuppressWarnings("PMD.DataClass") public class PrismConfiguration extends GlobalConfigurationItem { private static final PathUtil PATH_UTIL = new PathUtil(); private List sourceDirectories = Collections.emptyList(); private Set normalizedSourceDirectories = Collections.emptySet(); - private PrismTheme theme = PrismTheme.PRISM; - private final JenkinsFacade jenkins; + + /** + * Moved to {@link PrismAppearanceConfiguration}. + */ + private transient PrismTheme theme; /** * Creates the global configuration of source code directories and loads the initial values from the corresponding @@ -63,20 +57,22 @@ public class PrismConfiguration extends GlobalConfigurationItem { public PrismConfiguration() { super(); - jenkins = new JenkinsFacade(); - load(); } @VisibleForTesting - PrismConfiguration(final GlobalConfigurationFacade facade, final JenkinsFacade jenkins) { + PrismConfiguration(final GlobalConfigurationFacade facade) { super(facade); - this.jenkins = jenkins; - load(); } + @NonNull + @Override + public GlobalConfigurationCategory getCategory() { + return GlobalConfigurationCategory.get(GlobalConfigurationCategory.Security.class); + } + @Override protected void clearRepeatableProperties() { setSourceDirectories(new ArrayList<>()); @@ -118,6 +114,17 @@ public void setSourceDirectories(final List source save(); } + /** + * For maintaining compatibility after the move to {@link PrismAppearanceConfiguration}. + * + * @deprecated use {@link PrismAppearanceConfiguration} instead + * @return a model with the currently selected theme + */ + @Deprecated + public PrismTheme getTheme() { + return PrismAppearanceConfiguration.getInstance().getTheme(); + } + /** * Returns whether the specified director is registered as permitted source code directory. * @@ -129,33 +136,4 @@ public void setSourceDirectories(final List source public boolean isAllowedSourceDirectory(final String sourceDirectory) { return normalizedSourceDirectories.contains(PATH_UTIL.getAbsolutePath(sourceDirectory)); } - - /** - * Sets the active theme to be used when rendering the source code with prism. - * - * @param theme - * the theme to use - */ - @DataBoundSetter - public void setTheme(final PrismTheme theme) { - this.theme = theme; - } - - public PrismTheme getTheme() { - return theme; - } - - /** - * Returns all available themes. - * - * @return a model with all available themes - */ - @POST - public ListBoxModel doFillThemeItems() { - ListBoxModel options = new ListBoxModel(); - if (jenkins.hasPermission(Jenkins.ADMINISTER)) { - options.addAll(PrismTheme.getAllDisplayNames()); - } - return options; - } } diff --git a/src/main/resources/io/jenkins/plugins/prism/PrismAppearanceConfiguration/config.jelly b/src/main/resources/io/jenkins/plugins/prism/PrismAppearanceConfiguration/config.jelly new file mode 100644 index 0000000..961bf28 --- /dev/null +++ b/src/main/resources/io/jenkins/plugins/prism/PrismAppearanceConfiguration/config.jelly @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/src/main/resources/io/jenkins/plugins/prism/PrismAppearanceConfiguration/config.properties b/src/main/resources/io/jenkins/plugins/prism/PrismAppearanceConfiguration/config.properties new file mode 100644 index 0000000..59e85c7 --- /dev/null +++ b/src/main/resources/io/jenkins/plugins/prism/PrismAppearanceConfiguration/config.properties @@ -0,0 +1,2 @@ +sourceDirectories.title=Permitted Source Code Directories +sourceDirectories.description=Valid and permitted source code locations on agents (outside the workspace). diff --git a/src/main/resources/io/jenkins/plugins/prism/PrismAppearanceConfiguration/help-sourceDirectories.html b/src/main/resources/io/jenkins/plugins/prism/PrismAppearanceConfiguration/help-sourceDirectories.html new file mode 100644 index 0000000..f7395ce --- /dev/null +++ b/src/main/resources/io/jenkins/plugins/prism/PrismAppearanceConfiguration/help-sourceDirectories.html @@ -0,0 +1,7 @@ +
    + Some plugins copy source code files to Jenkins' build folder so that these files can be rendered in the user + interface together with build results (coverage, warnings, etc.). If these files are not part of the workspace + of a build then Jenkins will not show them by default: otherwise sensitive files could be shown by accident. + You can provide a list of additional source code directories that are allowed to be shown in Jenkins user interface + here. Note, that such a directory must be an absolute path on the agent that executes the build. +
    diff --git a/src/main/resources/io/jenkins/plugins/prism/PrismConfiguration/config.jelly b/src/main/resources/io/jenkins/plugins/prism/PrismConfiguration/config.jelly index 2f34ae2..edae577 100644 --- a/src/main/resources/io/jenkins/plugins/prism/PrismConfiguration/config.jelly +++ b/src/main/resources/io/jenkins/plugins/prism/PrismConfiguration/config.jelly @@ -1,7 +1,7 @@ - +
    @@ -14,9 +14,6 @@
    - - -
    diff --git a/src/test/java/io/jenkins/plugins/prism/ConfigurationAsCodeITest.java b/src/test/java/io/jenkins/plugins/prism/ConfigurationAsCodeITest.java index a64e8cb..6f4c873 100644 --- a/src/test/java/io/jenkins/plugins/prism/ConfigurationAsCodeITest.java +++ b/src/test/java/io/jenkins/plugins/prism/ConfigurationAsCodeITest.java @@ -34,7 +34,7 @@ void shouldImportSourceDirectoriesFromYaml() { void shouldImportTheme() { configureJenkins("theme.yaml"); - assertThat(PrismConfiguration.getInstance().getTheme()).isEqualTo(PrismTheme.DARK); + assertThat(PrismAppearanceConfiguration.getInstance().getTheme()).isEqualTo(PrismTheme.DARK); } private void configureJenkins(final String fileName) { diff --git a/src/test/java/io/jenkins/plugins/prism/PrismAppearanceConfigurationTest.java b/src/test/java/io/jenkins/plugins/prism/PrismAppearanceConfigurationTest.java new file mode 100644 index 0000000..5f84a35 --- /dev/null +++ b/src/test/java/io/jenkins/plugins/prism/PrismAppearanceConfigurationTest.java @@ -0,0 +1,38 @@ +package io.jenkins.plugins.prism; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import io.jenkins.plugins.util.GlobalConfigurationFacade; +import io.jenkins.plugins.util.JenkinsFacade; +import jenkins.model.Jenkins; +import org.junit.jupiter.api.Test; + +/** + * Tests the class {@link PrismAppearanceConfiguration}. + * + * @author Ullrich Hafner + */ +class PrismAppearanceConfigurationTest { + + @Test + void shouldInitializeThemes() { + PrismAppearanceConfiguration configuration = createConfiguration(); + + assertThat(configuration.getTheme()) + .isEqualTo(PrismTheme.PRISM) + .extracting(PrismTheme::getFileName) + .isEqualTo("prism.css"); + configuration.setTheme(PrismTheme.COY); + assertThat(configuration.getTheme()).isEqualTo(PrismTheme.COY); + + assertThat(configuration.doFillThemeItems()).extracting(o -> o.value).contains(PrismTheme.PRISM.name()); + } + + private PrismAppearanceConfiguration createConfiguration() { + JenkinsFacade jenkins = mock(JenkinsFacade.class); + when(jenkins.hasPermission(Jenkins.ADMINISTER)).thenReturn(true); + return new PrismAppearanceConfiguration(mock(GlobalConfigurationFacade.class), jenkins); + } +} diff --git a/src/test/java/io/jenkins/plugins/prism/PrismConfigurationTest.java b/src/test/java/io/jenkins/plugins/prism/PrismConfigurationTest.java index 2cf3fec..692bbf4 100644 --- a/src/test/java/io/jenkins/plugins/prism/PrismConfigurationTest.java +++ b/src/test/java/io/jenkins/plugins/prism/PrismConfigurationTest.java @@ -1,24 +1,19 @@ package io.jenkins.plugins.prism; +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; + +import edu.hm.hafner.util.FilteredLog; +import edu.hm.hafner.util.PathUtil; +import io.jenkins.plugins.util.GlobalConfigurationFacade; import java.util.Arrays; import java.util.HashSet; import java.util.List; import java.util.Set; import java.util.stream.Collectors; - import org.junit.jupiter.api.Test; -import edu.hm.hafner.util.FilteredLog; -import edu.hm.hafner.util.PathUtil; - -import jenkins.model.Jenkins; - -import io.jenkins.plugins.util.GlobalConfigurationFacade; -import io.jenkins.plugins.util.JenkinsFacade; - -import static org.assertj.core.api.Assertions.*; -import static org.mockito.Mockito.*; - /** * Tests the class {@link PrismConfiguration}. * @@ -57,7 +52,7 @@ void shouldHaveNoRootFoldersWhenCreated() { @Test void shouldSaveConfigurationIfFoldersAreAdded() { GlobalConfigurationFacade facade = mock(GlobalConfigurationFacade.class); - PrismConfiguration configuration = new PrismConfiguration(facade, mock(JenkinsFacade.class)); + PrismConfiguration configuration = new PrismConfiguration(facade); configuration.setSourceDirectories(SOURCE_ROOTS); @@ -103,20 +98,6 @@ void shouldNormalizePath() { assertThat(log.getErrorMessages()).isEmpty(); } - @Test - void shouldInitializeThemes() { - PrismConfiguration configuration = createConfiguration(); - - assertThat(configuration.getTheme()) - .isEqualTo(PrismTheme.PRISM) - .extracting(PrismTheme::getFileName) - .isEqualTo("prism.css"); - configuration.setTheme(PrismTheme.COY); - assertThat(configuration.getTheme()).isEqualTo(PrismTheme.COY); - - assertThat(configuration.doFillThemeItems()).extracting(o -> o.value).contains(PrismTheme.PRISM.name()); - } - private String getWorkspaceChild(final String expected) { return PATH_UTIL.createAbsolutePath(NORMALIZED, expected); } @@ -143,8 +124,6 @@ private Set asSet(final String... absolutePaths) { } private PrismConfiguration createConfiguration() { - JenkinsFacade jenkins = mock(JenkinsFacade.class); - when(jenkins.hasPermission(Jenkins.ADMINISTER)).thenReturn(true); - return new PrismConfiguration(mock(GlobalConfigurationFacade.class), jenkins); + return new PrismConfiguration(mock(GlobalConfigurationFacade.class)); } } diff --git a/src/test/resources/io/jenkins/plugins/prism/sourceDirectories.yaml b/src/test/resources/io/jenkins/plugins/prism/sourceDirectories.yaml index e38dacb..2c7365b 100644 --- a/src/test/resources/io/jenkins/plugins/prism/sourceDirectories.yaml +++ b/src/test/resources/io/jenkins/plugins/prism/sourceDirectories.yaml @@ -1,5 +1,5 @@ -unclassified: - prismConfiguration: +security: + prism: sourceDirectories: - path: "C:\\Windows" - path: "/absolute" diff --git a/src/test/resources/io/jenkins/plugins/prism/theme.yaml b/src/test/resources/io/jenkins/plugins/prism/theme.yaml index d9a8a51..096c775 100644 --- a/src/test/resources/io/jenkins/plugins/prism/theme.yaml +++ b/src/test/resources/io/jenkins/plugins/prism/theme.yaml @@ -1,3 +1,3 @@ -unclassified: - prismConfiguration: +appearance: + prism: theme: "DARK"