diff --git a/src/main/java/jenkins/branch/CustomOrganizationFolderDescriptor.java b/src/main/java/jenkins/branch/CustomOrganizationFolderDescriptor.java index 3c230b08..3400e4a0 100644 --- a/src/main/java/jenkins/branch/CustomOrganizationFolderDescriptor.java +++ b/src/main/java/jenkins/branch/CustomOrganizationFolderDescriptor.java @@ -55,6 +55,12 @@ public class CustomOrganizationFolderDescriptor extends TopLevelItemDescriptor i private static final Logger LOGGER = Logger.getLogger(CustomOrganizationFolderDescriptor.class.getName()); + // JENKINS-41171 disabling generic organization folders in favour of single blend. + // Leaving the code path as it is tested and otherwise we would need to write migration tests if we need + // multi navigator support in the future. NOTE: Blue Ocean as of Jan 2017 has hard-coded the assumption + // that there is one and only one SCMNavigator in an OrganizationFolder + static final boolean SHOW_GENERIC = false; + public final SCMNavigatorDescriptor delegate; CustomOrganizationFolderDescriptor(SCMNavigatorDescriptor delegate) { @@ -194,6 +200,9 @@ public boolean filter(Object context, Descriptor descriptor) { LOGGER.log(Level.FINER, "filtering {0}", descriptor.getId()); if (descriptor instanceof OrganizationFolder.DescriptorImpl && (context instanceof View || context instanceof ViewGroup)) { + if (!SHOW_GENERIC) { + return false; + } if (ExtensionList.lookup(MultiBranchProjectFactoryDescriptor.class).isEmpty()) { // if we have no factories, so do not display return false; diff --git a/src/main/java/jenkins/branch/OrganizationFolder.java b/src/main/java/jenkins/branch/OrganizationFolder.java index da78859c..ee9f7dba 100644 --- a/src/main/java/jenkins/branch/OrganizationFolder.java +++ b/src/main/java/jenkins/branch/OrganizationFolder.java @@ -251,6 +251,15 @@ public MultiBranchProject getItemByProjectName(@NonNull String projectName) return super.getItem(NameEncoder.encode(projectName)); } + /** + * Returns {@code true} if this is a single origin {@link OrganizationFolder}. + * + * @return {@code true} if this is a single origin {@link OrganizationFolder}. + */ + public boolean isSingleOrigin() { + // JENKINS-41171 we expect everything except for rare legacy instances to be single origin. + return navigators.size() == 1; + } public DescribableList getNavigators() { return navigators; diff --git a/src/main/resources/jenkins/branch/Messages.properties b/src/main/resources/jenkins/branch/Messages.properties index 61babd01..9b065a72 100644 --- a/src/main/resources/jenkins/branch/Messages.properties +++ b/src/main/resources/jenkins/branch/Messages.properties @@ -45,7 +45,7 @@ OrganizationFolder.OrganizationScan.displayName=Scan {0} OrganizationFolder.DefaultPronoun=Organization OrganizationFolder.DefaultProject=Multibranch OrganizationFolder.DisplayName={0} Folder -OrganizationFolder.Description=Creates a set of {0} projects for {1} matching a defined criteria from a {2} +OrganizationFolder.Description=Creates a set of {0} projects for {1} matching a defined criteria combining projects from more than one {2} OrganizationFolder.OrJoin2={0} or {1} OrganizationFolder.OrJoinN.First={0}, {1} OrganizationFolder.OrJoinN.Middle={0}, {1} diff --git a/src/main/resources/jenkins/branch/OrganizationFolder/configure-entries.jelly b/src/main/resources/jenkins/branch/OrganizationFolder/configure-entries.jelly index af74a6f8..34db54fe 100644 --- a/src/main/resources/jenkins/branch/OrganizationFolder/configure-entries.jelly +++ b/src/main/resources/jenkins/branch/OrganizationFolder/configure-entries.jelly @@ -23,11 +23,28 @@ ~ THE SOFTWARE. --> - - - - - + + + + + + + + + + + + +
+
+
+ + +
${%deprecated}
+ +
+
+
diff --git a/src/main/resources/jenkins/branch/OrganizationFolder/configure-entries.properties b/src/main/resources/jenkins/branch/OrganizationFolder/configure-entries.properties new file mode 100644 index 00000000..29e7e32e --- /dev/null +++ b/src/main/resources/jenkins/branch/OrganizationFolder/configure-entries.properties @@ -0,0 +1,26 @@ +# +# The MIT License +# +# Copyright (c) 2017, CloudBees, Inc. +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. +# +deprecated=This organization folder has a legacy configuration and does not have a single repository source. The \ + ability to have an organization folders with multiple repository sources may be removed in a future release \ + of the Branch API plugin. diff --git a/src/test/java/jenkins/branch/CustomOrganizationFolderDescriptorTest.java b/src/test/java/jenkins/branch/CustomOrganizationFolderDescriptorTest.java index 490600e5..a9397fef 100644 --- a/src/test/java/jenkins/branch/CustomOrganizationFolderDescriptorTest.java +++ b/src/test/java/jenkins/branch/CustomOrganizationFolderDescriptorTest.java @@ -49,11 +49,13 @@ import org.jvnet.hudson.test.LoggerRule; import org.jvnet.hudson.test.TestExtension; +import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.Matchers.containsInAnyOrder; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; +import static org.junit.Assume.assumeThat; public class CustomOrganizationFolderDescriptorTest { @@ -134,6 +136,7 @@ public void dynamicLoadReversed() throws Exception { @SuppressWarnings("deprecation") // ExtensionList.add simulating dynamic installation @Test public void dynamicLoad2() throws Exception { + assumeThat(CustomOrganizationFolderDescriptor.SHOW_GENERIC, is(true)); assertEquals(Collections.emptyList(), newItemTypes()); ExtensionList.lookup(SCMNavigatorDescriptor.class).add(new SomeNavigatorNoFactoryInstalledDescriptor()); ExtensionList.lookup(MultiBranchProjectFactoryDescriptor.class).add(new SomeNavigatorSomeFactoryInstalledDescriptor2()); @@ -142,6 +145,19 @@ public void dynamicLoad2() throws Exception { newItemTypes(), containsInAnyOrder("MockNavigator", "MockNavigator", "Organization Folder")); } + @Issue("JENKINS-41171") + @SuppressWarnings("deprecation") // ExtensionList.add simulating dynamic installation + @Test + public void dynamicLoad3() throws Exception { + assumeThat(CustomOrganizationFolderDescriptor.SHOW_GENERIC, is(false)); + assertEquals(Collections.emptyList(), newItemTypes()); + ExtensionList.lookup(SCMNavigatorDescriptor.class).add(new SomeNavigatorNoFactoryInstalledDescriptor()); + ExtensionList.lookup(MultiBranchProjectFactoryDescriptor.class).add(new SomeNavigatorSomeFactoryInstalledDescriptor2()); + ExtensionList.lookup(SCMNavigatorDescriptor.class).add(new SomeNavigatorSomeFactoryInstalledDescriptor1()); + assertThat("When there is more than one navigator then the generic organization folder makes sense to show", + newItemTypes(), containsInAnyOrder("MockNavigator", "MockNavigator")); + } + @Issue("JENKINS-31949") @Test public void insideFolder() throws Exception {