From b08fa38819f120a747444fd5c05e82fcef24e703 Mon Sep 17 00:00:00 2001 From: Mykola Lynnyk Date: Thu, 14 Sep 2017 15:07:33 +0300 Subject: [PATCH 1/2] * Support for disabling default sync strategies. * Fix for Job Sync strategy on Windows. --- .../ScmSyncConfigurationBusiness.java | 4 +- .../ScmSyncConfigurationPlugin.java | 78 ++++++++++++++++--- ...JobOrFolderConfigurationEntityMatcher.java | 3 + .../ScmSyncConfigurationXStreamConverter.java | 16 ++++ .../xstream/migration/AbstractMigrator.java | 20 +++++ .../xstream/migration/DefaultSSCPOJO.java | 31 ++++++++ .../migration/ScmSyncConfigurationPOJO.java | 8 ++ .../ScmSyncConfigurationPlugin/config.jelly | 40 ++++++++++ .../HudsonExtensionsSubversionTest.java | 4 +- .../repository/HudsonExtensionsTest.java | 22 +++--- .../repository/InitRepositoryTest.java | 2 +- .../impl/JobConfigScmSyncStrategyTest.java | 2 +- .../util/ScmSyncConfigurationBaseTest.java | 4 + 13 files changed, 206 insertions(+), 28 deletions(-) diff --git a/src/main/java/hudson/plugins/scm_sync_configuration/ScmSyncConfigurationBusiness.java b/src/main/java/hudson/plugins/scm_sync_configuration/ScmSyncConfigurationBusiness.java index a2feba7b..6a631370 100644 --- a/src/main/java/hudson/plugins/scm_sync_configuration/ScmSyncConfigurationBusiness.java +++ b/src/main/java/hudson/plugins/scm_sync_configuration/ScmSyncConfigurationBusiness.java @@ -295,10 +295,10 @@ private void createScmContent(Path pathRelativeToJenkinsRoot, byte[] content, Fi } } - public void synchronizeAllConfigs(ScmSyncStrategy[] availableStrategies){ + public void synchronizeAllConfigs(List enabledStrategies){ List filesToSync = new ArrayList(); // Building synced files from strategies - for(ScmSyncStrategy strategy : availableStrategies){ + for(ScmSyncStrategy strategy : enabledStrategies){ filesToSync.addAll(strategy.collect()); } diff --git a/src/main/java/hudson/plugins/scm_sync_configuration/ScmSyncConfigurationPlugin.java b/src/main/java/hudson/plugins/scm_sync_configuration/ScmSyncConfigurationPlugin.java index ef1b7da9..45ee1cc4 100644 --- a/src/main/java/hudson/plugins/scm_sync_configuration/ScmSyncConfigurationPlugin.java +++ b/src/main/java/hudson/plugins/scm_sync_configuration/ScmSyncConfigurationPlugin.java @@ -6,7 +6,6 @@ import com.google.common.collect.Collections2; import com.google.common.collect.ImmutableList; import com.google.common.collect.Iterables; -import com.google.common.collect.Lists; import hudson.Plugin; import hudson.model.Descriptor; @@ -60,18 +59,37 @@ public class ScmSyncConfigurationPlugin extends Plugin{ - public static final transient ScmSyncStrategy[] AVAILABLE_STRATEGIES = new ScmSyncStrategy[]{ + private static final transient ScmSyncStrategy[] AVAILABLE_STRATEGIES = new ScmSyncStrategy[]{ new JenkinsConfigScmSyncStrategy(), new BasicPluginsConfigScmSyncStrategy(), new JobConfigScmSyncStrategy(), new UserConfigScmSyncStrategy(), new ManualIncludesScmSyncStrategy() }; - + + private List enabledStrategies = new ArrayList(); + + private void setEnabledStrategies() { + enabledStrategies.clear(); + for (ScmSyncStrategy strategy : AVAILABLE_STRATEGIES) { + if ( (strategy instanceof JenkinsConfigScmSyncStrategy && syncJenkinsConfig) || + (strategy instanceof BasicPluginsConfigScmSyncStrategy && syncBasicPluginsConfig) || + (strategy instanceof JobConfigScmSyncStrategy && syncJobConfig) || + (strategy instanceof UserConfigScmSyncStrategy && syncUserConfig) || + (strategy instanceof ManualIncludesScmSyncStrategy) ) { + enabledStrategies.add(strategy); + } + } + } + + public List getEnabledStrategies() { + return enabledStrategies; + } + /** * Strategies that cannot be updated by user */ - public static final transient List DEFAULT_STRATEGIES = ImmutableList.copyOf( + private static final transient List DEFAULT_STRATEGIES = ImmutableList.copyOf( Collections2.filter(Arrays.asList(AVAILABLE_STRATEGIES), new Predicate() { @Override public boolean apply(@Nullable ScmSyncStrategy scmSyncStrategy) { @@ -109,6 +127,11 @@ public static interface AtomicTransactionFactory { private SCM scm; private boolean noUserCommitMessage; private boolean displayStatus = true; + private boolean syncJenkinsConfig = true; + private boolean syncBasicPluginsConfig = true; + private boolean syncJobConfig = true; + private boolean syncUserConfig = true; + // The [message] is a magic string that will be replaced with commit message // when commit occurs private String commitMessagePattern = "[message]"; @@ -162,8 +185,13 @@ public void loadData(ScmSyncConfigurationPOJO pojo){ this.scm = pojo.getScm(); this.noUserCommitMessage = pojo.isNoUserCommitMessage(); this.displayStatus = pojo.isDisplayStatus(); + this.syncJenkinsConfig = pojo.isSyncJenkinsConfig(); + this.syncBasicPluginsConfig = pojo.isSyncBasicPluginsConfig(); + this.syncJobConfig = pojo.isSyncJobConfig(); + this.syncUserConfig = pojo.isSyncUserConfig(); this.commitMessagePattern = pojo.getCommitMessagePattern(); this.manualSynchronizationIncludes = pojo.getManualSynchronizationIncludes(); + this.setEnabledStrategies(); } protected void initialInit() throws Exception { @@ -199,6 +227,10 @@ public void configure(StaplerRequest req, JSONObject formData) this.noUserCommitMessage = formData.getBoolean("noUserCommitMessage"); this.displayStatus = formData.getBoolean("displayStatus"); + this.syncJenkinsConfig = formData.getBoolean("syncJenkinsConfig"); + this.syncBasicPluginsConfig = formData.getBoolean("syncBasicPluginsConfig"); + this.syncJobConfig = formData.getBoolean("syncJobConfig"); + this.syncUserConfig = formData.getBoolean("syncUserConfig"); this.commitMessagePattern = req.getParameter("commitMessagePattern"); String oldScmRepositoryUrl = this.scmRepositoryUrl; @@ -223,18 +255,26 @@ public void configure(StaplerRequest req, JSONObject formData) } this.manualSynchronizationIncludes = submittedManualIncludes; - configsResynchronizationRequired = !newManualIncludes.isEmpty(); + configsResynchronizationRequired = configsResynchronizationRequired || !newManualIncludes.isEmpty(); } else { this.manualSynchronizationIncludes = new ArrayList(); } + // Load strategies and check whether they should be reloaded + List currentEnabledStrategies = new ArrayList(this.enabledStrategies); + this.setEnabledStrategies(); + if (currentEnabledStrategies.size() < this.enabledStrategies.size()) { + currentEnabledStrategies.removeAll(this.enabledStrategies); + configsResynchronizationRequired = configsResynchronizationRequired || currentEnabledStrategies.isEmpty(); + } + // Repo initialization should be made _before_ plugin save, in order to let scm-sync-configuration.xml // file synchronizable if(repoInitializationRequired){ this.business.initializeRepository(createScmContext(), true); } if(configsResynchronizationRequired){ - this.business.synchronizeAllConfigs(AVAILABLE_STRATEGIES); + this.business.synchronizeAllConfigs(this.enabledStrategies); } if(repoCleaningRequired){ this.business.cleanChekoutScmDirectory(); @@ -247,7 +287,7 @@ public void configure(StaplerRequest req, JSONObject formData) } public Iterable collectAllFilesForScm() { - return Iterables.concat(Iterables.transform(Lists.newArrayList(AVAILABLE_STRATEGIES), new Function>() { + return Iterables.concat(Iterables.transform(enabledStrategies, new Function>() { @Override public Iterable apply(ScmSyncStrategy strategy) { return strategy.collect(); @@ -255,7 +295,7 @@ public Iterable apply(ScmSyncStrategy strategy) { } public Iterable collectAllFilesForScm(final File fromSubDirectory) { - return Iterables.concat(Iterables.transform(Lists.newArrayList(AVAILABLE_STRATEGIES), new Function>() { + return Iterables.concat(Iterables.transform(enabledStrategies, new Function>() { @Override public Iterable apply(ScmSyncStrategy strategy) { return strategy.collect(fromSubDirectory); @@ -332,7 +372,7 @@ public static ScmSyncConfigurationPlugin getInstance(){ } public ScmSyncStrategy getStrategyForSaveable(Saveable s, File f){ - for(ScmSyncStrategy strat : AVAILABLE_STRATEGIES){ + for(ScmSyncStrategy strat : enabledStrategies){ if(strat.isSaveableApplicable(s, f)){ return strat; } @@ -350,7 +390,7 @@ public ScmSyncStrategy getStrategyForSaveable(Saveable s, File f){ * @return a strategy that thinks it might have applied */ public ScmSyncStrategy getStrategyForDeletedSaveable(Saveable s, String pathRelativeToRoot, boolean wasDirectory) { - for (ScmSyncStrategy strategy : AVAILABLE_STRATEGIES) { + for (ScmSyncStrategy strategy : enabledStrategies) { if (strategy.mightHaveBeenApplicableToDeletedSaveable(s, pathRelativeToRoot, wasDirectory)) { return strategy; } @@ -376,7 +416,7 @@ public boolean shouldDecorationOccursOnURL(String url){ } public ScmSyncStrategy getStrategyForURL(String url){ - for(ScmSyncStrategy strat : AVAILABLE_STRATEGIES){ + for(ScmSyncStrategy strat : enabledStrategies){ if(strat.isCurrentUrlApplicable(url)){ return strat; } @@ -429,6 +469,22 @@ public boolean isDisplayStatus() { return displayStatus; } + public boolean isSyncJenkinsConfig() { + return syncJenkinsConfig; + } + + public boolean isSyncBasicPluginsConfig() { + return syncBasicPluginsConfig; + } + + public boolean isSyncJobConfig() { + return syncJobConfig; + } + + public boolean isSyncUserConfig() { + return syncUserConfig; + } + public String getCommitMessagePattern() { return commitMessagePattern; } diff --git a/src/main/java/hudson/plugins/scm_sync_configuration/strategies/model/JobOrFolderConfigurationEntityMatcher.java b/src/main/java/hudson/plugins/scm_sync_configuration/strategies/model/JobOrFolderConfigurationEntityMatcher.java index 2da878c5..e72ad008 100644 --- a/src/main/java/hudson/plugins/scm_sync_configuration/strategies/model/JobOrFolderConfigurationEntityMatcher.java +++ b/src/main/java/hudson/plugins/scm_sync_configuration/strategies/model/JobOrFolderConfigurationEntityMatcher.java @@ -77,6 +77,9 @@ public String[] matchingFilesFrom(File rootDirectory, FileSelector selector) { FileSelector combinedSelector = new FileSelector() { @Override public boolean isSelected(File basedir, String pathRelativeToBaseDir, File file) throws BuildException { + // Make paths match the defined patterns on Windows + pathRelativeToBaseDir = pathRelativeToBaseDir.replace('\\', '/'); + if (originalSelector != null && !originalSelector.isSelected(basedir, pathRelativeToBaseDir, file)) { return false; } diff --git a/src/main/java/hudson/plugins/scm_sync_configuration/xstream/ScmSyncConfigurationXStreamConverter.java b/src/main/java/hudson/plugins/scm_sync_configuration/xstream/ScmSyncConfigurationXStreamConverter.java index ac5b7a5f..a3723cb6 100644 --- a/src/main/java/hudson/plugins/scm_sync_configuration/xstream/ScmSyncConfigurationXStreamConverter.java +++ b/src/main/java/hudson/plugins/scm_sync_configuration/xstream/ScmSyncConfigurationXStreamConverter.java @@ -78,7 +78,23 @@ public void marshal(Object source, HierarchicalStreamWriter writer, writer.startNode(AbstractMigrator.SCM_DISPLAY_STATUS); writer.setValue(Boolean.toString(plugin.isDisplayStatus())); writer.endNode(); + + writer.startNode(AbstractMigrator.SCM_SYNC_JENKINS_CONFIG); + writer.setValue(Boolean.toString(plugin.isSyncJenkinsConfig())); + writer.endNode(); + writer.startNode(AbstractMigrator.SCM_SYNC_PLUGINS_CONFIG); + writer.setValue(Boolean.toString(plugin.isSyncBasicPluginsConfig())); + writer.endNode(); + + writer.startNode(AbstractMigrator.SCM_SYNC_JOB_CONFIG); + writer.setValue(Boolean.toString(plugin.isSyncJobConfig())); + writer.endNode(); + + writer.startNode(AbstractMigrator.SCM_SYNC_USER_DATA); + writer.setValue(Boolean.toString(plugin.isSyncUserConfig())); + writer.endNode(); + if(plugin.getCommitMessagePattern() != null){ writer.startNode(AbstractMigrator.SCM_COMMIT_MESSAGE_PATTERN); writer.setValue(plugin.getCommitMessagePattern()); diff --git a/src/main/java/hudson/plugins/scm_sync_configuration/xstream/migration/AbstractMigrator.java b/src/main/java/hudson/plugins/scm_sync_configuration/xstream/migration/AbstractMigrator.java index 408473c3..e43ef2c9 100644 --- a/src/main/java/hudson/plugins/scm_sync_configuration/xstream/migration/AbstractMigrator.java +++ b/src/main/java/hudson/plugins/scm_sync_configuration/xstream/migration/AbstractMigrator.java @@ -16,6 +16,10 @@ public abstract class AbstractMigrator manualIncludes = null; @@ -51,6 +59,14 @@ public TTO readScmSyncConfigurationPOJO( noUserCommitMessage = Boolean.parseBoolean(reader.getValue()); } else if(SCM_DISPLAY_STATUS.equals(reader.getNodeName())){ displayStatus = Boolean.parseBoolean(reader.getValue()); + } else if(SCM_SYNC_JENKINS_CONFIG.equals(reader.getNodeName())){ + syncJenkinsConfig = Boolean.parseBoolean(reader.getValue()); + } else if(SCM_SYNC_PLUGINS_CONFIG.equals(reader.getNodeName())){ + syncBasicPluginsConfig = Boolean.parseBoolean(reader.getValue()); + } else if(SCM_SYNC_JOB_CONFIG.equals(reader.getNodeName())){ + syncJobConfig = Boolean.parseBoolean(reader.getValue()); + } else if(SCM_SYNC_USER_DATA.equals(reader.getNodeName())){ + syncUserConfig = Boolean.parseBoolean(reader.getValue()); } else if(SCM_TAG.equals(reader.getNodeName())){ scmClassAttribute = reader.getAttribute(SCM_CLASS_ATTRIBUTE); scmContent = reader.getValue(); @@ -76,6 +92,10 @@ public TTO readScmSyncConfigurationPOJO( pojo.setScmRepositoryUrl(scmRepositoryUrl); pojo.setNoUserCommitMessage(noUserCommitMessage); pojo.setDisplayStatus(displayStatus); + pojo.setSyncJenkinsConfig(syncJenkinsConfig); + pojo.setSyncBasicPluginsConfig(syncBasicPluginsConfig); + pojo.setSyncJobConfig(syncJobConfig); + pojo.setSyncUserConfig(syncUserConfig); pojo.setCommitMessagePattern(commitMessagePattern); pojo.setManualSynchronizationIncludes(manualIncludes); diff --git a/src/main/java/hudson/plugins/scm_sync_configuration/xstream/migration/DefaultSSCPOJO.java b/src/main/java/hudson/plugins/scm_sync_configuration/xstream/migration/DefaultSSCPOJO.java index f592157c..4c7ee633 100644 --- a/src/main/java/hudson/plugins/scm_sync_configuration/xstream/migration/DefaultSSCPOJO.java +++ b/src/main/java/hudson/plugins/scm_sync_configuration/xstream/migration/DefaultSSCPOJO.java @@ -10,6 +10,12 @@ public class DefaultSSCPOJO implements ScmSyncConfigurationPOJO { private SCM scm; private boolean noUserCommitMessage; private boolean displayStatus; + private boolean syncJenkinsConfig; + private boolean syncBasicPluginsConfig; + private boolean syncJobConfig; + private boolean syncUserConfig; + + private String commitMessagePattern; private List manualSynchronizationIncludes; @@ -37,6 +43,31 @@ public boolean isDisplayStatus() { public void setDisplayStatus(boolean displayStatus) { this.displayStatus = displayStatus; } + + public boolean isSyncJenkinsConfig() { + return syncJenkinsConfig; + } + public void setSyncJenkinsConfig(boolean syncJenkinsConfig) { + this.syncJenkinsConfig = syncJenkinsConfig; + } + public boolean isSyncBasicPluginsConfig() { + return syncBasicPluginsConfig; + } + public void setSyncBasicPluginsConfig(boolean syncBasicPluginsConfig) { + this.syncBasicPluginsConfig = syncBasicPluginsConfig; + } + public boolean isSyncJobConfig() { + return syncJobConfig; + } + public void setSyncJobConfig(boolean syncJobConfig) { + this.syncJobConfig = syncJobConfig; + } + public boolean isSyncUserConfig() { + return syncUserConfig; + } + public void setSyncUserConfig(boolean syncUserConfig) { + this.syncUserConfig = syncUserConfig; + } public String getCommitMessagePattern() { return commitMessagePattern; diff --git a/src/main/java/hudson/plugins/scm_sync_configuration/xstream/migration/ScmSyncConfigurationPOJO.java b/src/main/java/hudson/plugins/scm_sync_configuration/xstream/migration/ScmSyncConfigurationPOJO.java index eea89608..538a84d3 100644 --- a/src/main/java/hudson/plugins/scm_sync_configuration/xstream/migration/ScmSyncConfigurationPOJO.java +++ b/src/main/java/hudson/plugins/scm_sync_configuration/xstream/migration/ScmSyncConfigurationPOJO.java @@ -17,6 +17,14 @@ public interface ScmSyncConfigurationPOJO { public void setNoUserCommitMessage(boolean noUserCommitMessage); public boolean isDisplayStatus(); public void setDisplayStatus(boolean displayStatus); + public boolean isSyncJenkinsConfig(); + public void setSyncJenkinsConfig(boolean syncJenkinsConfig); + public boolean isSyncBasicPluginsConfig(); + public void setSyncBasicPluginsConfig(boolean syncBasicPluginsConfig); + public boolean isSyncJobConfig(); + public void setSyncJobConfig(boolean syncJobConfig); + public boolean isSyncUserConfig(); + public void setSyncUserConfig(boolean syncUserConfig); public String getCommitMessagePattern(); public void setCommitMessagePattern(String commitMessagePattern); public List getManualSynchronizationIncludes(); diff --git a/src/main/resources/hudson/plugins/scm_sync_configuration/ScmSyncConfigurationPlugin/config.jelly b/src/main/resources/hudson/plugins/scm_sync_configuration/ScmSyncConfigurationPlugin/config.jelly index 043a21a3..d2960a88 100644 --- a/src/main/resources/hudson/plugins/scm_sync_configuration/ScmSyncConfigurationPlugin/config.jelly +++ b/src/main/resources/hudson/plugins/scm_sync_configuration/ScmSyncConfigurationPlugin/config.jelly @@ -30,6 +30,46 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/test/java/hudson/plugins/scm_sync_configuration/repository/HudsonExtensionsSubversionTest.java b/src/test/java/hudson/plugins/scm_sync_configuration/repository/HudsonExtensionsSubversionTest.java index 401c0c80..9571fd82 100644 --- a/src/test/java/hudson/plugins/scm_sync_configuration/repository/HudsonExtensionsSubversionTest.java +++ b/src/test/java/hudson/plugins/scm_sync_configuration/repository/HudsonExtensionsSubversionTest.java @@ -30,7 +30,7 @@ public void shouldJobDeleteDoesntPerformAnyScmUpdate() throws Throwable { createSCMMock(); // Synchronizing hudson config files - sscBusiness.synchronizeAllConfigs(ScmSyncConfigurationPlugin.AVAILABLE_STRATEGIES); + sscBusiness.synchronizeAllConfigs(ScmSyncConfigurationPlugin.getInstance().getEnabledStrategies()); // Let's checkout current scm view ... and commit something in it ... SCMManipulator scmManipulator = createMockedScmManipulator(); @@ -64,7 +64,7 @@ public void shouldJobRenameDoesntPerformAnyScmUpdate() throws Throwable { createSCMMock(); // Synchronizing hudson config files - sscBusiness.synchronizeAllConfigs(ScmSyncConfigurationPlugin.AVAILABLE_STRATEGIES); + sscBusiness.synchronizeAllConfigs(ScmSyncConfigurationPlugin.getInstance().getEnabledStrategies()); // Let's checkout current scm view ... and commit something in it ... SCMManipulator scmManipulator = createMockedScmManipulator(); diff --git a/src/test/java/hudson/plugins/scm_sync_configuration/repository/HudsonExtensionsTest.java b/src/test/java/hudson/plugins/scm_sync_configuration/repository/HudsonExtensionsTest.java index c884c0f9..4c2e1a46 100644 --- a/src/test/java/hudson/plugins/scm_sync_configuration/repository/HudsonExtensionsTest.java +++ b/src/test/java/hudson/plugins/scm_sync_configuration/repository/HudsonExtensionsTest.java @@ -51,7 +51,7 @@ public void shouldJobRenameBeCorrectlyImpactedOnSCM() throws Throwable { createSCMMock(); // Synchronizing hudson config files - sscBusiness.synchronizeAllConfigs(ScmSyncConfigurationPlugin.AVAILABLE_STRATEGIES); + sscBusiness.synchronizeAllConfigs(ScmSyncConfigurationPlugin.getInstance().getEnabledStrategies()); // Renaming fakeJob to newFakeJob Item mockedItem = Mockito.mock(Job.class); @@ -76,7 +76,7 @@ public void shouldJobAddBeCorrectlyImpactedOnSCM() throws Throwable { createSCMMock(); // Synchronizing hudson config files - sscBusiness.synchronizeAllConfigs(ScmSyncConfigurationPlugin.AVAILABLE_STRATEGIES); + sscBusiness.synchronizeAllConfigs(ScmSyncConfigurationPlugin.getInstance().getEnabledStrategies()); File jobDirectory = new File(getCurrentHudsonRootDirectory() + "/jobs/newFakeJob/" ); File configFile = new File(jobDirectory.getAbsolutePath() + File.separator + "config.xml"); @@ -104,7 +104,7 @@ public void shouldJobModificationBeCorrectlyImpactedOnSCM() throws Throwable { createSCMMock(); // Synchronizing hudson config files - sscBusiness.synchronizeAllConfigs(ScmSyncConfigurationPlugin.AVAILABLE_STRATEGIES); + sscBusiness.synchronizeAllConfigs(ScmSyncConfigurationPlugin.getInstance().getEnabledStrategies()); File jobDirectory = new File(getCurrentHudsonRootDirectory() + "/jobs/fakeJob/" ); File configFile = new File(jobDirectory.getAbsolutePath() + File.separator + "config.xml"); @@ -134,7 +134,7 @@ public void shouldConfigModificationBeCorrectlyImpactedOnSCM() throws Throwable createSCMMock(); // Synchronizing hudson config files - sscBusiness.synchronizeAllConfigs(ScmSyncConfigurationPlugin.AVAILABLE_STRATEGIES); + sscBusiness.synchronizeAllConfigs(ScmSyncConfigurationPlugin.getInstance().getEnabledStrategies()); File configFile = new File(getCurrentHudsonRootDirectory() + "/hudson.tasks.Shell.xml" ); @@ -160,7 +160,7 @@ public void shouldJobDeleteBeCorrectlyImpactedOnSCM() throws Throwable { createSCMMock(); // Synchronizing hudson config files - sscBusiness.synchronizeAllConfigs(ScmSyncConfigurationPlugin.AVAILABLE_STRATEGIES); + sscBusiness.synchronizeAllConfigs(ScmSyncConfigurationPlugin.getInstance().getEnabledStrategies()); // Deleting fakeJob Item mockedItem = Mockito.mock(Job.class); @@ -183,7 +183,7 @@ public void shouldJobDeleteWithTwoJobsBeCorrectlyImpactedOnSCM() throws Throwabl createSCMMock(); // Synchronizing hudson config files - sscBusiness.synchronizeAllConfigs(ScmSyncConfigurationPlugin.AVAILABLE_STRATEGIES); + sscBusiness.synchronizeAllConfigs(ScmSyncConfigurationPlugin.getInstance().getEnabledStrategies()); // Deleting fakeJob Item mockedItem = Mockito.mock(Job.class); @@ -203,7 +203,7 @@ public void shouldReloadAllFilesUpdateScmAndReloadAllFiles() throws Throwable { createSCMMock(); // Synchronizing hudson config files - sscBusiness.synchronizeAllConfigs(ScmSyncConfigurationPlugin.AVAILABLE_STRATEGIES); + sscBusiness.synchronizeAllConfigs(ScmSyncConfigurationPlugin.getInstance().getEnabledStrategies()); // Let's checkout current scm view ... and commit something in it ... SCMManipulator scmManipulator = createMockedScmManipulator(); @@ -240,7 +240,7 @@ public void shouldReloadAllFilesUpdateScmAndReloadAllFilesWithFileAdd() throws T createSCMMock(); // Synchronizing hudson config files - sscBusiness.synchronizeAllConfigs(ScmSyncConfigurationPlugin.AVAILABLE_STRATEGIES); + sscBusiness.synchronizeAllConfigs(ScmSyncConfigurationPlugin.getInstance().getEnabledStrategies()); // Let's checkout current scm view ... and commit something in it ... SCMManipulator scmManipulator = createMockedScmManipulator(); @@ -279,7 +279,7 @@ public void shouldReloadAllFilesUpdateScmAndReloadAllFilesWithFileAdd() throws T @Test public void testJobNameStartingWithDash() throws Exception { createSCMMock(); - sscBusiness.synchronizeAllConfigs(ScmSyncConfigurationPlugin.AVAILABLE_STRATEGIES); + sscBusiness.synchronizeAllConfigs(ScmSyncConfigurationPlugin.getInstance().getEnabledStrategies()); File jobDirectory = new File(getCurrentHudsonRootDirectory(), "jobs/-newFakeJob/" ); File configFile = new File(jobDirectory, "config.xml"); @@ -315,7 +315,7 @@ public void testJobNameStartingWithDash() throws Exception { @Test public void testJobNameWithBlanks() throws Exception { createSCMMock(); - sscBusiness.synchronizeAllConfigs(ScmSyncConfigurationPlugin.AVAILABLE_STRATEGIES); + sscBusiness.synchronizeAllConfigs(ScmSyncConfigurationPlugin.getInstance().getEnabledStrategies()); File jobDirectory = new File(getCurrentHudsonRootDirectory(), "jobs/new fake Job/" ); File configFile = new File(jobDirectory, "config.xml"); @@ -351,7 +351,7 @@ public void testJobNameWithBlanks() throws Exception { @Test public void testJobRenameWithBlanksAndDash() throws Exception { createSCMMock(); - sscBusiness.synchronizeAllConfigs(ScmSyncConfigurationPlugin.AVAILABLE_STRATEGIES); + sscBusiness.synchronizeAllConfigs(ScmSyncConfigurationPlugin.getInstance().getEnabledStrategies()); File jobDirectory = new File(getCurrentHudsonRootDirectory(), "jobs/-newFakeJob/" ); File configFile = new File(jobDirectory, "config.xml"); diff --git a/src/test/java/hudson/plugins/scm_sync_configuration/repository/InitRepositoryTest.java b/src/test/java/hudson/plugins/scm_sync_configuration/repository/InitRepositoryTest.java index 434a0cd0..80aa5d77 100644 --- a/src/test/java/hudson/plugins/scm_sync_configuration/repository/InitRepositoryTest.java +++ b/src/test/java/hudson/plugins/scm_sync_configuration/repository/InitRepositoryTest.java @@ -75,7 +75,7 @@ public void shouldSynchronizeHudsonFiles() throws Throwable { createSCMMock(); // Synchronizing hudson config files - sscBusiness.synchronizeAllConfigs(ScmSyncConfigurationPlugin.AVAILABLE_STRATEGIES); + sscBusiness.synchronizeAllConfigs(ScmSyncConfigurationPlugin.getInstance().getEnabledStrategies()); verifyCurrentScmContentMatchesHierarchy("expected-scm-hierarchies/InitRepositoryTest.shouldSynchronizeHudsonFiles/"); diff --git a/src/test/java/hudson/plugins/scm_sync_configuration/strategies/impl/JobConfigScmSyncStrategyTest.java b/src/test/java/hudson/plugins/scm_sync_configuration/strategies/impl/JobConfigScmSyncStrategyTest.java index 153223bc..32d2af60 100644 --- a/src/test/java/hudson/plugins/scm_sync_configuration/strategies/impl/JobConfigScmSyncStrategyTest.java +++ b/src/test/java/hudson/plugins/scm_sync_configuration/strategies/impl/JobConfigScmSyncStrategyTest.java @@ -45,7 +45,7 @@ public void shouldConfigInSubmodulesNotSynced() throws ComponentLookupException, createSCMMock(); // Synchronizing hudson config files - sscBusiness.synchronizeAllConfigs(ScmSyncConfigurationPlugin.AVAILABLE_STRATEGIES); + sscBusiness.synchronizeAllConfigs(ScmSyncConfigurationPlugin.getInstance().getEnabledStrategies()); File subModuleConfigFile = new File(getCurrentHudsonRootDirectory() + "/jobs/fakeJob/modules/submodule/config.xml" ); diff --git a/src/test/java/hudson/plugins/scm_sync_configuration/util/ScmSyncConfigurationBaseTest.java b/src/test/java/hudson/plugins/scm_sync_configuration/util/ScmSyncConfigurationBaseTest.java index 2bef1afe..cd85f535 100644 --- a/src/test/java/hudson/plugins/scm_sync_configuration/util/ScmSyncConfigurationBaseTest.java +++ b/src/test/java/hudson/plugins/scm_sync_configuration/util/ScmSyncConfigurationBaseTest.java @@ -165,6 +165,10 @@ protected SCM createSCMMock(String url){ ScmSyncConfigurationPOJO config = new DefaultSSCPOJO(); config.setScm(scmContext.getScm()); config.setScmRepositoryUrl(scmContext.getScmRepositoryUrl()); + config.setSyncJenkinsConfig(true); + config.setSyncBasicPluginsConfig(true); + config.setSyncJobConfig(true); + config.setSyncUserConfig(true); ScmSyncConfigurationPlugin.getInstance().loadData(config); ScmSyncConfigurationPlugin.getInstance().init(); From b767e502dc2a5969c14e46604c33e177bfb1ca1c Mon Sep 17 00:00:00 2001 From: Mykola Lynnyk Date: Fri, 15 Sep 2017 17:48:34 +0300 Subject: [PATCH 2/2] Merge from GitHub pull requests: Fixing renaming and deletion issues --- .../SCMManipulator.java | 13 +++++++++- .../ScmSyncConfigurationBusiness.java | 26 ++++++++++++++++--- .../ScmSyncConfigurationPlugin.java | 3 +++ .../model/ChangeSet.java | 8 +++--- 4 files changed, 43 insertions(+), 7 deletions(-) diff --git a/src/main/java/hudson/plugins/scm_sync_configuration/SCMManipulator.java b/src/main/java/hudson/plugins/scm_sync_configuration/SCMManipulator.java index 24de088f..ffd36058 100644 --- a/src/main/java/hudson/plugins/scm_sync_configuration/SCMManipulator.java +++ b/src/main/java/hudson/plugins/scm_sync_configuration/SCMManipulator.java @@ -9,6 +9,7 @@ import org.apache.maven.scm.command.checkin.CheckInScmResult; import org.apache.maven.scm.command.checkout.CheckOutScmResult; import org.apache.maven.scm.command.remove.RemoveScmResult; +import org.apache.maven.scm.command.status.StatusScmResult; import org.apache.maven.scm.command.update.UpdateScmResult; import org.apache.maven.scm.manager.NoSuchScmProviderException; import org.apache.maven.scm.manager.ScmManager; @@ -124,7 +125,17 @@ public List deleteHierarchy(File hierarchyToDelete){ try { ScmFileSet deleteFileSet = new ScmFileSet(enclosingDirectory, hierarchyToDelete); - RemoveScmResult removeResult = this.scmManager.remove(this.scmRepository, deleteFileSet, ""); + StatusScmResult checkForChanges = this.scmManager.status(scmRepository, deleteFileSet); + LOGGER.fine("Checking for changes on SCM hierarchy ["+hierarchyToDelete.getAbsolutePath()+"] from SCM ..."); + for (ScmFile changedFile : checkForChanges.getChangedFiles()) { + //check in this change as it affect our hierarchy + LOGGER.fine("[checkForChanges] Found changed file "+changedFile.toString()+", try to check-in..."); + CheckInScmResult checkedInChangedFile = scmManager.checkIn(scmRepository, new ScmFileSet(enclosingDirectory.getParentFile(), new File(changedFile.getPath())), "Check-In changes for "+changedFile.getPath()); + if(!checkedInChangedFile.isSuccess()){ + LOGGER.severe("[checkForChanges] Failed to check-in changed file ["+changedFile.getPath()+"]: "+checkedInChangedFile.getProviderMessage()); + } + } + RemoveScmResult removeResult = this.scmManager.remove(this.scmRepository, deleteFileSet, "Delete hierarchy "+hierarchyToDelete.getPath()); if(!removeResult.isSuccess()){ LOGGER.severe("[deleteHierarchy] Problem during remove : "+removeResult.getProviderMessage()); return null; diff --git a/src/main/java/hudson/plugins/scm_sync_configuration/ScmSyncConfigurationBusiness.java b/src/main/java/hudson/plugins/scm_sync_configuration/ScmSyncConfigurationBusiness.java index 6a631370..3adfb633 100644 --- a/src/main/java/hudson/plugins/scm_sync_configuration/ScmSyncConfigurationBusiness.java +++ b/src/main/java/hudson/plugins/scm_sync_configuration/ScmSyncConfigurationBusiness.java @@ -39,6 +39,7 @@ public class ScmSyncConfigurationBusiness { private SCMManipulator scmManipulator; private File checkoutScmDirectory = null; private ScmSyncConfigurationStatusManager scmSyncConfigurationStatusManager = null; + private List manualSynchronizationIncludes = new ArrayList(); /** * Use of a size 1 thread pool frees us from worrying about accidental thread death and @@ -187,8 +188,17 @@ private void processCommitsQueue() { String firstNonExistingParentScmPath = pathRelativeToJenkinsRoot.getFirstNonExistingParentScmPath(); try { - FileUtils.copyDirectory(JenkinsFilesHelper.buildFileFromPathRelativeToHudsonRoot(pathRelativeToJenkinsRoot.getPath()), - fileTranslatedInScm); + File buildFileFromPathRelativeToHudsonRoot = JenkinsFilesHelper.buildFileFromPathRelativeToHudsonRoot(pathRelativeToJenkinsRoot.getPath()); + FileUtils.copyDirectory(buildFileFromPathRelativeToHudsonRoot, fileTranslatedInScm, new FileFilter() { + @Override + public boolean accept(File pathname) { + if(pathname.getPath().endsWith(".xml") + || getManualSynchronizationIncludes().contains(pathname)){ + return true; + } + return false; + } + }); } catch (IOException e) { throw new LoggableException("Error while copying file hierarchy to SCM directory", FileUtils.class, "copyDirectory", e); } @@ -212,7 +222,9 @@ private void processCommitsQueue() { } for(Path path : commit.getChangeset().getPathsToDelete()){ List deletedFiles = deleteHierarchy(commit.getScmContext(), path); - updatedFiles.addAll(deletedFiles); + if(deletedFiles != null) { + updatedFiles.addAll(deletedFiles); + } } if(updatedFiles.isEmpty()){ @@ -245,6 +257,14 @@ private void processCommitsQueue() { } } + public List getManualSynchronizationIncludes() { + return manualSynchronizationIncludes; + } + public void setManualSynchronizationIncludes( + List manualSynchronizationIncludes) { + this.manualSynchronizationIncludes = manualSynchronizationIncludes; + } + private boolean writeScmContentOnlyIfItDiffers(Path pathRelativeToJenkinsRoot, byte[] content, File fileTranslatedInScm) throws LoggableException { boolean scmContentUpdated = false; diff --git a/src/main/java/hudson/plugins/scm_sync_configuration/ScmSyncConfigurationPlugin.java b/src/main/java/hudson/plugins/scm_sync_configuration/ScmSyncConfigurationPlugin.java index 45ee1cc4..6a37e689 100644 --- a/src/main/java/hudson/plugins/scm_sync_configuration/ScmSyncConfigurationPlugin.java +++ b/src/main/java/hudson/plugins/scm_sync_configuration/ScmSyncConfigurationPlugin.java @@ -191,6 +191,7 @@ public void loadData(ScmSyncConfigurationPOJO pojo){ this.syncUserConfig = pojo.isSyncUserConfig(); this.commitMessagePattern = pojo.getCommitMessagePattern(); this.manualSynchronizationIncludes = pojo.getManualSynchronizationIncludes(); + this.business.setManualSynchronizationIncludes(manualSynchronizationIncludes); this.setEnabledStrategies(); } @@ -260,6 +261,8 @@ public void configure(StaplerRequest req, JSONObject formData) this.manualSynchronizationIncludes = new ArrayList(); } + this.business.setManualSynchronizationIncludes(manualSynchronizationIncludes); + // Load strategies and check whether they should be reloaded List currentEnabledStrategies = new ArrayList(this.enabledStrategies); this.setEnabledStrategies(); diff --git a/src/main/java/hudson/plugins/scm_sync_configuration/model/ChangeSet.java b/src/main/java/hudson/plugins/scm_sync_configuration/model/ChangeSet.java index d2927b29..2538a6fd 100644 --- a/src/main/java/hudson/plugins/scm_sync_configuration/model/ChangeSet.java +++ b/src/main/java/hudson/plugins/scm_sync_configuration/model/ChangeSet.java @@ -58,8 +58,10 @@ public void registerPath(String path) { public void registerPathForDeletion(String path){ // We should determine if path is a directory by watching scm path (and not hudson path) because in most of time, // when we are here, directory is already deleted in hudson hierarchy... - boolean isDirectory = new Path(path).getScmFile().isDirectory(); - pathsToDelete.add(new Path(path, isDirectory)); + if(new Path(path).getScmFile().exists()) { + boolean isDirectory = new Path(path).getScmFile().isDirectory(); + pathsToDelete.add(new Path(path, isDirectory)); + } } public boolean isEmpty(){ @@ -75,7 +77,7 @@ public Map getPathContents(){ for(Path pathToAdd : filteredPathContents.keySet()){ for(Path pathToDelete : pathsToDelete){ // Removing paths being both in pathsToDelete and pathContents - if(pathToDelete.contains(pathToAdd)){ + if(pathToDelete.equals(pathToAdd)){ filteredPaths.add(pathToAdd); } }