├── .gitignore ├── LICENSE.txt ├── README.md ├── pom.xml └── src ├── main ├── java │ └── hudson │ │ └── plugins │ │ └── scm_sync_configuration │ │ ├── JenkinsFilesHelper.java │ │ ├── SCMManagerFactory.java │ │ ├── SCMManipulator.java │ │ ├── ScmSyncConfigurationBusiness.java │ │ ├── ScmSyncConfigurationDataProvider.java │ │ ├── ScmSyncConfigurationPlugin.java │ │ ├── ScmSyncConfigurationStatusManager.java │ │ ├── exceptions │ │ └── LoggableException.java │ │ ├── extensions │ │ ├── ScmSyncConfigurationFilter.java │ │ ├── ScmSyncConfigurationItemListener.java │ │ ├── ScmSyncConfigurationPageDecorator.java │ │ └── ScmSyncConfigurationSaveableListener.java │ │ ├── model │ │ ├── BotherTimeout.java │ │ ├── ChangeSet.java │ │ ├── Commit.java │ │ ├── MessageWeight.java │ │ ├── Path.java │ │ ├── ScmContext.java │ │ └── WeightedMessage.java │ │ ├── scms │ │ ├── SCM.java │ │ ├── SCMCredentialConfiguration.java │ │ ├── ScmSyncGitSCM.java │ │ ├── ScmSyncNoSCM.java │ │ ├── ScmSyncSubversionSCM.java │ │ └── customproviders │ │ │ └── git │ │ │ └── gitexe │ │ │ ├── FixedGitStatusConsumer.java │ │ │ ├── ScmSyncGitAddCommand.java │ │ │ ├── ScmSyncGitCheckInCommand.java │ │ │ ├── ScmSyncGitExeScmProvider.java │ │ │ ├── ScmSyncGitRemoveCommand.java │ │ │ ├── ScmSyncGitStatusCommand.java │ │ │ └── ScmSyncGitUtils.java │ │ ├── strategies │ │ ├── AbstractScmSyncStrategy.java │ │ ├── ScmSyncStrategy.java │ │ ├── impl │ │ │ ├── BasicPluginsConfigScmSyncStrategy.java │ │ │ ├── JenkinsConfigScmSyncStrategy.java │ │ │ ├── JobConfigScmSyncStrategy.java │ │ │ ├── ManualIncludesScmSyncStrategy.java │ │ │ └── UserConfigScmSyncStrategy.java │ │ └── model │ │ │ ├── ClassAndFileConfigurationEntityMatcher.java │ │ │ ├── ConfigurationEntityMatcher.java │ │ │ ├── JobOrFolderConfigurationEntityMatcher.java │ │ │ ├── PageMatcher.java │ │ │ └── PatternsEntityMatcher.java │ │ ├── transactions │ │ ├── AtomicTransaction.java │ │ ├── ScmTransaction.java │ │ └── ThreadedTransaction.java │ │ ├── utils │ │ └── Checksums.java │ │ └── xstream │ │ ├── ScmSyncConfigurationXStreamConverter.java │ │ └── migration │ │ ├── AbstractMigrator.java │ │ ├── DefaultSSCPOJO.java │ │ ├── ScmSyncConfigurationDataMigrator.java │ │ ├── ScmSyncConfigurationPOJO.java │ │ ├── ScmSyncConfigurationXStreamReader.java │ │ ├── v0 │ │ ├── InitialMigrator.java │ │ └── V0ScmSyncConfigurationPOJO.java │ │ └── v1 │ │ ├── V0ToV1Migrator.java │ │ └── V1ScmSyncConfigurationPOJO.java ├── resources │ ├── META-INF │ │ └── plexus │ │ │ └── components.xml │ ├── hudson │ │ └── plugins │ │ │ └── scm_sync_configuration │ │ │ ├── Messages.properties │ │ │ ├── ScmSyncConfigurationPlugin │ │ │ ├── config.jelly │ │ │ ├── config_fr.properties │ │ │ ├── help │ │ │ │ ├── manualSynchronizationIncludes.jelly │ │ │ │ └── manualSynchronizationIncludes_fr.properties │ │ │ └── scms │ │ │ │ ├── git │ │ │ │ ├── config.jelly │ │ │ │ ├── config_fr.properties │ │ │ │ ├── url-help.jelly │ │ │ │ ├── url-help.properties │ │ │ │ └── url-help_fr.properties │ │ │ │ ├── none │ │ │ │ └── config.jelly │ │ │ │ └── svn │ │ │ │ ├── config.jelly │ │ │ │ ├── config_fr.properties │ │ │ │ ├── url-help.jelly │ │ │ │ ├── url-help.properties │ │ │ │ └── url-help_fr.properties │ │ │ ├── extensions │ │ │ └── ScmSyncConfigurationPageDecorator │ │ │ │ └── footer.jelly │ │ │ └── reload.jelly │ └── index.jelly └── webapp │ ├── help │ ├── commitMessagePattern-help.html │ ├── commitMessagePattern-help_fr.html │ ├── displayStatus-help.html │ ├── displayStatus-help_fr.html │ ├── noUserCommitMessage-help.html │ ├── noUserCommitMessage-help_fr.html │ ├── reloadScmConfig-help.html │ ├── reloadScmConfig-help_fr.html │ ├── scm-help.html │ └── scm-help_fr.html │ └── scripts │ └── scm-sync-configuration │ └── scm-sync-configuration-page-handler.js └── test ├── java └── hudson │ └── plugins │ ├── scm_sync_configuration │ ├── basic │ │ └── ScmSyncConfigurationBasicTest.java │ ├── data │ │ ├── CurrentVersionCompatibilityTest.java │ │ ├── V0_0_2CompatibilityTest.java │ │ ├── V0_0_3CompatibilityTest.java │ │ └── V0_0_4CompatibilityTest.java │ ├── repository │ │ ├── HudsonExtensionsGitTest.java │ │ ├── HudsonExtensionsSubversionTest.java │ │ ├── HudsonExtensionsTest.java │ │ ├── InitRepositoryGitTest.java │ │ ├── InitRepositorySubversionTest.java │ │ └── InitRepositoryTest.java │ ├── strategies │ │ └── impl │ │ │ └── JobConfigScmSyncStrategyTest.java │ └── util │ │ ├── ScmSyncConfigurationBaseTest.java │ │ └── ScmSyncConfigurationPluginBaseTest.java │ └── test │ └── utils │ ├── DirectoryUtils.java │ ├── PluginUtil.java │ └── scms │ ├── ScmUnderTest.java │ ├── ScmUnderTestGit.java │ └── ScmUnderTestSubversion.java └── resources ├── HudsonExtensionsTest.shouldFileWhichHaveToBeInSCM ├── config.xml ├── hudson.config.xml2 ├── hudson.scm.SubversionSCM.xml ├── jobs │ ├── config.xml │ ├── myFolder │ │ ├── config.xml │ │ └── jobs │ │ │ └── myJob │ │ │ └── config.xml │ └── myJob │ │ ├── config.xml │ │ └── config2.xml ├── nodeMonitors.xml ├── scm-sync-configuration.xml └── toto │ ├── config.xml │ └── hudson.config.xml ├── expected-scm-hierarchies ├── HudsonExtensionsTest.shouldConfigModificationBeCorrectlyImpactedOnSCM │ ├── config.xml │ ├── hudson.tasks.Shell.xml │ ├── jobs │ │ └── fakeJob │ │ │ └── config.xml │ └── scm-sync-configuration.xml ├── HudsonExtensionsTest.shouldJobAddBeCorrectlyImpactedOnSCM │ ├── config.xml │ ├── hudson.tasks.Shell.xml │ ├── jobs │ │ ├── fakeJob │ │ │ └── config.xml │ │ └── newFakeJob │ │ │ └── config.xml │ └── scm-sync-configuration.xml ├── HudsonExtensionsTest.shouldJobDeleteBeCorrectlyImpactedOnSCM.git │ ├── config.xml │ ├── hudson.tasks.Shell.xml │ └── scm-sync-configuration.xml ├── HudsonExtensionsTest.shouldJobDeleteBeCorrectlyImpactedOnSCM.subversion │ ├── config.xml │ ├── hudson.tasks.Shell.xml │ ├── jobs │ │ └── .gitkeep │ └── scm-sync-configuration.xml ├── HudsonExtensionsTest.shouldJobDeleteWithTwoJobsBeCorrectlyImpactedOnSCM │ ├── config.xml │ ├── hudson.tasks.Shell.xml │ ├── jobs │ │ ├── .gitkeep │ │ └── newFakeJob │ │ │ └── config.xml │ └── scm-sync-configuration.xml ├── HudsonExtensionsTest.shouldJobModificationBeCorrectlyImpactedOnSCM │ ├── config.xml │ ├── hudson.tasks.Shell.xml │ ├── jobs │ │ └── fakeJob │ │ │ └── config.xml │ └── scm-sync-configuration.xml ├── HudsonExtensionsTest.shouldJobRenameBeCorrectlyImpactedOnSCM │ ├── config.xml │ ├── hudson.tasks.Shell.xml │ ├── jobs │ │ └── newFakeJob │ │ │ └── config.xml │ └── scm-sync-configuration.xml ├── HudsonExtensionsTest.testAddJobNameStartingWithDash │ ├── config.xml │ ├── hudson.tasks.Shell.xml │ ├── jobs │ │ ├── -newFakeJob │ │ │ └── config.xml │ │ └── fakeJob │ │ │ └── config.xml │ └── scm-sync-configuration.xml ├── HudsonExtensionsTest.testAddJobNameWithBlanks │ ├── config.xml │ ├── hudson.tasks.Shell.xml │ ├── jobs │ │ ├── fakeJob │ │ │ └── config.xml │ │ └── new fake Job │ │ │ └── config.xml │ └── scm-sync-configuration.xml ├── InitRepositoryTest.shouldSynchronizeHudsonFiles │ ├── config.xml │ ├── hudson.tasks.Shell.xml │ ├── jobs │ │ └── fakeJob │ │ │ └── config.xml │ └── scm-sync-configuration.xml └── JobConfigScmSyncStrategyTest.shouldConfigInSubmodulesNotSynced │ ├── config.xml │ ├── hudson.tasks.Shell.xml │ ├── jobs │ └── fakeJob │ │ └── config.xml │ └── scm-sync-configuration.xml ├── hudsonRoot0.0.2BaseTemplate ├── config.xml └── scm-sync-configuration.xml ├── hudsonRoot0.0.2WithEmptyConfTemplate ├── config.xml └── scm-sync-configuration.xml ├── hudsonRoot0.0.3BaseTemplate ├── config.xml └── scm-sync-configuration.xml ├── hudsonRoot0.0.4WithEmptyConfTemplate ├── config.xml └── scm-sync-configuration.xml ├── hudsonRootBaseTemplate ├── config.xml ├── hudson.tasks.Shell.xml ├── jobs │ └── fakeJob │ │ └── config.xml └── scm-sync-configuration.xml └── jobConfigStrategyTemplate ├── config.xml ├── hudson.tasks.Shell.xml ├── jobs └── fakeJob │ ├── config.xml │ └── modules │ └── submodule │ └── config.xml └── scm-sync-configuration.xml /.gitignore: -------------------------------------------------------------------------------- 1 | target/ 2 | work*/ 3 | 4 | # IntelliJ project files 5 | *.iml 6 | *.ipr 7 | *.iws 8 | .idea/ 9 | 10 | # eclipse project file 11 | .factorypath 12 | .settings 13 | .classpath 14 | .project 15 | build/ -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | The MIT License 2 | 3 | Copyright (c) 2010-, Frédéric Camblor 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Jenkins SCM Sync Configuration Plugin 2 | ===================== 3 | 4 | Read more: [https://wiki.jenkins-ci.org/display/JENKINS/SCM+Sync+configuration+plugin](https://wiki.jenkins-ci.org/display/JENKINS/SCM+Sync+configuration+plugin) 5 | 6 | -------------------------------------------------------------------------------- /src/main/java/hudson/plugins/scm_sync_configuration/JenkinsFilesHelper.java: -------------------------------------------------------------------------------- 1 | package hudson.plugins.scm_sync_configuration; 2 | 3 | import java.io.File; 4 | 5 | import jenkins.model.Jenkins; 6 | 7 | public class JenkinsFilesHelper { 8 | 9 | public static String buildPathRelativeToHudsonRoot(File file) { 10 | File jenkinsRoot = Jenkins.getInstance().getRootDir(); 11 | String jenkinsRootPath = jenkinsRoot.getAbsolutePath(); 12 | String fileAbsolutePath = file.getAbsolutePath(); 13 | if (fileAbsolutePath.equals(jenkinsRootPath)) { 14 | // Hmmm. Should never occur. 15 | throw new IllegalArgumentException("Cannot build relative path to $JENKINS_HOME for $JENKINS_HOME itself; would be empty."); 16 | } 17 | if (!jenkinsRootPath.endsWith(File.separator)) { 18 | jenkinsRootPath += File.separator; 19 | } 20 | if (!fileAbsolutePath.startsWith(jenkinsRootPath)) { 21 | // Oops, the file is not relative to $JENKINS_HOME 22 | return null; 23 | } 24 | String truncatedPath = fileAbsolutePath.substring(jenkinsRootPath.length()); 25 | return truncatedPath.replace(File.separatorChar, '/'); 26 | } 27 | 28 | public static File buildFileFromPathRelativeToHudsonRoot(String pathRelativeToJenkinsRoot){ 29 | return new File(Jenkins.getInstance().getRootDir(), pathRelativeToJenkinsRoot); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/hudson/plugins/scm_sync_configuration/SCMManagerFactory.java: -------------------------------------------------------------------------------- 1 | package hudson.plugins.scm_sync_configuration; 2 | 3 | import org.apache.maven.scm.manager.ScmManager; 4 | import org.codehaus.plexus.DefaultPlexusContainer; 5 | import org.codehaus.plexus.PlexusContainer; 6 | import org.codehaus.plexus.PlexusContainerException; 7 | import org.codehaus.plexus.component.repository.exception.ComponentLookupException; 8 | 9 | public class SCMManagerFactory { 10 | 11 | private static final SCMManagerFactory INSTANCE = new SCMManagerFactory(); 12 | 13 | private PlexusContainer plexus = null; 14 | 15 | private SCMManagerFactory(){ 16 | } 17 | 18 | public void start() throws PlexusContainerException { 19 | if(plexus == null){ 20 | this.plexus = new DefaultPlexusContainer(); 21 | try { 22 | // These will only be useful for Hudson v1.395 and under 23 | // ... Since the use of sisu-plexus-inject will initialize 24 | // everything in the constructor 25 | PlexusContainer.class.getDeclaredMethod("initialize").invoke(this.plexus); 26 | PlexusContainer.class.getDeclaredMethod("start").invoke(this.plexus); 27 | } catch (Throwable e) { /* Don't do anything here ... initialize/start methods should be called prior to v1.395 ! */ } 28 | } 29 | } 30 | 31 | public ScmManager createScmManager() throws ComponentLookupException { 32 | return (ScmManager)this.plexus.lookup(ScmManager.ROLE); 33 | } 34 | 35 | public void stop() throws Exception { 36 | this.plexus.dispose(); 37 | this.plexus = null; 38 | } 39 | 40 | public static SCMManagerFactory getInstance(){ 41 | return INSTANCE; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/main/java/hudson/plugins/scm_sync_configuration/ScmSyncConfigurationStatusManager.java: -------------------------------------------------------------------------------- 1 | package hudson.plugins.scm_sync_configuration; 2 | 3 | import java.io.File; 4 | import java.io.IOException; 5 | import java.util.Date; 6 | import java.util.logging.Logger; 7 | 8 | import jenkins.model.Jenkins; 9 | 10 | import org.codehaus.plexus.util.FileUtils; 11 | 12 | public class ScmSyncConfigurationStatusManager { 13 | 14 | private static final Logger LOGGER = Logger.getLogger(ScmSyncConfigurationStatusManager.class.getName()); 15 | 16 | public static final String LOG_SUCCESS_FILENAME = "scm-sync-configuration.success.log"; 17 | 18 | public static final String LOG_FAIL_FILENAME = "scm-sync-configuration.fail.log"; 19 | 20 | private final File fail; 21 | private final File success; 22 | 23 | public ScmSyncConfigurationStatusManager() { 24 | fail = new File(Jenkins.getInstance().getRootDir().getAbsolutePath(), LOG_FAIL_FILENAME); 25 | success = new File(Jenkins.getInstance().getRootDir().getAbsolutePath(), LOG_SUCCESS_FILENAME); 26 | } 27 | 28 | public String getLastFail() { 29 | return readFile(fail); 30 | } 31 | 32 | public String getLastSuccess() { 33 | return readFile(success); 34 | } 35 | 36 | public void signalSuccess() { 37 | writeFile(success, new Date().toString()); 38 | } 39 | 40 | public void signalFailed(String description) { 41 | appendFile(fail, new Date().toString() + " : " + description + "
"); 42 | } 43 | 44 | private static String readFile(File f) { 45 | try { 46 | if(f.exists()) { 47 | return FileUtils.fileRead(f); 48 | } 49 | } 50 | catch(IOException e) { 51 | LOGGER.severe("Unable to read file " + f.getAbsolutePath() + " : " + e.getMessage()); 52 | } 53 | return null; 54 | } 55 | 56 | private static void writeFile(File f, String data) { 57 | try { 58 | FileUtils.fileWrite(f.getAbsolutePath(), data); 59 | } 60 | catch(IOException e) { 61 | LOGGER.severe("Unable to write file " + f.getAbsolutePath() + " : " + e.getMessage()); 62 | } 63 | } 64 | 65 | private static void appendFile(File f, String data) { 66 | try { 67 | FileUtils.fileAppend(f.getAbsolutePath(), data); 68 | } 69 | catch(IOException e) { 70 | LOGGER.severe("Unable to write file " + f.getAbsolutePath() + " : " + e.getMessage()); 71 | } 72 | } 73 | 74 | public void purgeFailLogs() { 75 | fail.delete(); 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /src/main/java/hudson/plugins/scm_sync_configuration/exceptions/LoggableException.java: -------------------------------------------------------------------------------- 1 | package hudson.plugins.scm_sync_configuration.exceptions; 2 | 3 | /** 4 | * @author fcamblor 5 | * Exception which will be easily loggable, by providing both class and method called, causing the exception 6 | */ 7 | public class LoggableException extends RuntimeException { 8 | 9 | private static final long serialVersionUID = 442135528912013310L; 10 | 11 | private final Class clazz; 12 | private final String methodName; 13 | 14 | public LoggableException(String message, Class clazz, String methodName, Throwable cause) { 15 | super(message, cause); 16 | this.clazz = clazz; 17 | this.methodName = methodName; 18 | } 19 | 20 | public LoggableException(String message, Class clazz, String methodName) { 21 | super(message); 22 | this.clazz = clazz; 23 | this.methodName = methodName; 24 | } 25 | 26 | public Class getClazz() { 27 | return clazz; 28 | } 29 | 30 | public String getMethodName() { 31 | return methodName; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/hudson/plugins/scm_sync_configuration/extensions/ScmSyncConfigurationFilter.java: -------------------------------------------------------------------------------- 1 | package hudson.plugins.scm_sync_configuration.extensions; 2 | 3 | import hudson.Extension; 4 | import hudson.plugins.scm_sync_configuration.ScmSyncConfigurationDataProvider; 5 | import hudson.plugins.scm_sync_configuration.ScmSyncConfigurationPlugin; 6 | 7 | import javax.servlet.*; 8 | import javax.servlet.http.HttpServletRequest; 9 | import java.io.IOException; 10 | import java.util.concurrent.Callable; 11 | import java.util.logging.Level; 12 | 13 | /** 14 | * @author fcamblor 15 | * Very important class in the plugin : it is the entry point allowing to decide what files should be 16 | * synchronized or not during current thread execution 17 | */ 18 | @Extension 19 | public class ScmSyncConfigurationFilter implements Filter { 20 | 21 | private static final java.util.logging.Logger LOG = java.util.logging.Logger.getLogger(ScmSyncConfigurationFilter.class.getName()); 22 | 23 | @Override 24 | public void init(FilterConfig filterConfig) throws ServletException { 25 | } 26 | 27 | @Override 28 | public void doFilter(final ServletRequest request, final ServletResponse response, final FilterChain chain) throws IOException, ServletException { 29 | // In the beginning of every http request, we should create a new threaded transaction 30 | final ScmSyncConfigurationPlugin plugin; 31 | try { 32 | plugin = ScmSyncConfigurationPlugin.getInstance(); 33 | } catch(Throwable t){ 34 | LOG.log(Level.SEVERE, "Error when retrieving ScmSyncConfig plugin instance => No filtering enabled on current request", t); 35 | return; 36 | } 37 | 38 | if(plugin != null){ 39 | plugin.startThreadedTransaction(); 40 | 41 | try { 42 | // Providing current ServletRequest in ScmSyncConfigurationDataProvider's thread local 43 | // in order to be able to access it from everywhere inside this call 44 | ScmSyncConfigurationDataProvider.provideRequestDuring((HttpServletRequest)request, new Callable() { 45 | @Override 46 | public Void call() throws Exception { 47 | try { 48 | // Handling "normally" http request 49 | chain.doFilter(request, response); 50 | }finally{ 51 | // In the end of http request, we should commit current transaction 52 | plugin.getTransaction().commit(); 53 | } 54 | 55 | return null; 56 | } 57 | }); 58 | } catch(RuntimeException e){ 59 | throw e; 60 | } catch(ServletException e){ 61 | throw e; 62 | } catch(IOException e){ 63 | throw e; 64 | } catch(Exception e){ 65 | throw new ServletException(e); 66 | } 67 | } 68 | } 69 | 70 | @Override 71 | public void destroy() { 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /src/main/java/hudson/plugins/scm_sync_configuration/extensions/ScmSyncConfigurationItemListener.java: -------------------------------------------------------------------------------- 1 | package hudson.plugins.scm_sync_configuration.extensions; 2 | 3 | import hudson.Extension; 4 | import hudson.model.Item; 5 | import hudson.model.TopLevelItem; 6 | import hudson.model.listeners.ItemListener; 7 | import hudson.plugins.scm_sync_configuration.JenkinsFilesHelper; 8 | import hudson.plugins.scm_sync_configuration.ScmSyncConfigurationPlugin; 9 | import hudson.plugins.scm_sync_configuration.model.WeightedMessage; 10 | import hudson.plugins.scm_sync_configuration.strategies.ScmSyncStrategy; 11 | import hudson.plugins.scm_sync_configuration.transactions.ScmTransaction; 12 | 13 | import java.io.File; 14 | 15 | import jenkins.model.DirectlyModifiableTopLevelItemGroup; 16 | import jenkins.model.Jenkins; 17 | 18 | @Extension 19 | public class ScmSyncConfigurationItemListener extends ItemListener { 20 | 21 | @Override 22 | public void onLoaded() { 23 | super.onLoaded(); 24 | 25 | // After every plugin is loaded, let's init ScmSyncConfigurationPlugin 26 | // Init is needed after plugin loads since it relies on scm implementations plugins loaded 27 | ScmSyncConfigurationPlugin plugin = ScmSyncConfigurationPlugin.getInstance(); 28 | if (plugin != null) { 29 | plugin.init(); 30 | } 31 | } 32 | 33 | @Override 34 | public void onDeleted(Item item) { 35 | super.onDeleted(item); 36 | 37 | ScmSyncConfigurationPlugin plugin = ScmSyncConfigurationPlugin.getInstance(); 38 | if(plugin != null){ 39 | String path = JenkinsFilesHelper.buildPathRelativeToHudsonRoot(item.getRootDir()); 40 | ScmSyncStrategy strategy = plugin.getStrategyForDeletedSaveable(item, path, true); 41 | if (strategy != null) { 42 | WeightedMessage message = strategy.getCommitMessageFactory().getMessageWhenItemDeleted(item); 43 | ScmTransaction transaction = plugin.getTransaction(); 44 | transaction.defineCommitMessage(message); 45 | transaction.registerPathForDeletion(path); 46 | } 47 | } 48 | } 49 | 50 | @Override 51 | public void onLocationChanged(Item item, String oldFullName, String newFullName) { 52 | super.onLocationChanged(item, oldFullName, newFullName); 53 | ScmSyncConfigurationPlugin plugin = ScmSyncConfigurationPlugin.getInstance(); 54 | if (plugin == null) { 55 | return; 56 | } 57 | // Figure out where the item previously might have been. 58 | File oldDir = null; 59 | Jenkins jenkins = Jenkins.getInstance(); 60 | int i = oldFullName.lastIndexOf('/'); 61 | String oldSimpleName = i > 0 ? oldFullName.substring(i+1) : oldFullName; 62 | Object oldParent = i > 0 ? jenkins.getItemByFullName(oldFullName.substring(0, i)) : jenkins; 63 | Object newParent = item.getParent(); 64 | if (newParent == null) { 65 | // Shouldn't happen. 66 | newParent = jenkins; 67 | } 68 | if (oldParent == newParent && oldParent != null) { 69 | // Simple rename within the same directory 70 | oldDir = new File (item.getRootDir().getParentFile(), oldSimpleName); 71 | } else if (oldParent instanceof DirectlyModifiableTopLevelItemGroup && item instanceof TopLevelItem) { 72 | oldDir = ((DirectlyModifiableTopLevelItemGroup) oldParent).getRootDirFor((TopLevelItem) item); 73 | oldDir = new File (oldDir.getParentFile(), oldSimpleName); 74 | } 75 | ScmSyncStrategy oldStrategy = null; 76 | if (oldDir != null) { 77 | oldStrategy = plugin.getStrategyForDeletedSaveable(item, JenkinsFilesHelper.buildPathRelativeToHudsonRoot(oldDir), true); 78 | } 79 | File newDir = item.getRootDir(); 80 | ScmSyncStrategy newStrategy = plugin.getStrategyForSaveable(item, newDir); 81 | ScmTransaction transaction = plugin.getTransaction(); 82 | if (newStrategy == null) { 83 | if (oldStrategy != null) { 84 | // Delete old 85 | WeightedMessage message = oldStrategy.getCommitMessageFactory().getMessageWhenItemRenamed(item, oldFullName, newFullName); 86 | transaction.defineCommitMessage(message); 87 | transaction.registerPathForDeletion(JenkinsFilesHelper.buildPathRelativeToHudsonRoot(oldDir)); 88 | } 89 | } else { 90 | String newPathRelativeToRoot = JenkinsFilesHelper.buildPathRelativeToHudsonRoot(newDir); 91 | // Something moved to a place where we do cover it. 92 | WeightedMessage message = newStrategy.getCommitMessageFactory().getMessageWhenItemRenamed(item, oldFullName, newFullName); 93 | transaction.defineCommitMessage(message); 94 | transaction.registerRenamedPath(oldStrategy != null ? JenkinsFilesHelper.buildPathRelativeToHudsonRoot(oldDir) : null, newPathRelativeToRoot); 95 | } 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /src/main/java/hudson/plugins/scm_sync_configuration/extensions/ScmSyncConfigurationPageDecorator.java: -------------------------------------------------------------------------------- 1 | package hudson.plugins.scm_sync_configuration.extensions; 2 | 3 | import hudson.Extension; 4 | import hudson.model.PageDecorator; 5 | import hudson.plugins.scm_sync_configuration.ScmSyncConfigurationPlugin; 6 | 7 | import org.kohsuke.stapler.bind.JavaScriptMethod; 8 | 9 | @Extension 10 | public class ScmSyncConfigurationPageDecorator extends PageDecorator{ 11 | 12 | @SuppressWarnings("deprecation") // Super constructor is deprecated. Unsure if default constructor would work, though. 13 | public ScmSyncConfigurationPageDecorator(){ 14 | super(ScmSyncConfigurationPageDecorator.class); 15 | } 16 | 17 | public ScmSyncConfigurationPlugin getScmSyncConfigPlugin(){ 18 | return ScmSyncConfigurationPlugin.getInstance(); 19 | } 20 | 21 | @JavaScriptMethod 22 | public void purgeScmSyncConfigLogs() { 23 | getScmSyncConfigPlugin().purgeFailLogs(); 24 | } 25 | } -------------------------------------------------------------------------------- /src/main/java/hudson/plugins/scm_sync_configuration/extensions/ScmSyncConfigurationSaveableListener.java: -------------------------------------------------------------------------------- 1 | package hudson.plugins.scm_sync_configuration.extensions; 2 | 3 | import hudson.Extension; 4 | import hudson.XmlFile; 5 | import hudson.model.Saveable; 6 | import hudson.model.listeners.SaveableListener; 7 | import hudson.plugins.scm_sync_configuration.JenkinsFilesHelper; 8 | import hudson.plugins.scm_sync_configuration.ScmSyncConfigurationPlugin; 9 | import hudson.plugins.scm_sync_configuration.model.WeightedMessage; 10 | import hudson.plugins.scm_sync_configuration.strategies.ScmSyncStrategy; 11 | 12 | @Extension 13 | public class ScmSyncConfigurationSaveableListener extends SaveableListener{ 14 | 15 | @Override 16 | public void onChange(Saveable o, XmlFile file) { 17 | 18 | super.onChange(o, file); 19 | 20 | ScmSyncConfigurationPlugin plugin = ScmSyncConfigurationPlugin.getInstance(); 21 | if(plugin != null){ 22 | ScmSyncStrategy strategy = plugin.getStrategyForSaveable(o, file.getFile()); 23 | 24 | if(strategy != null){ 25 | WeightedMessage message = strategy.getCommitMessageFactory().getMessageWhenSaveableUpdated(o, file); 26 | plugin.getTransaction().defineCommitMessage(message); 27 | String path = JenkinsFilesHelper.buildPathRelativeToHudsonRoot(file.getFile()); 28 | plugin.getTransaction().registerPath(path); 29 | } 30 | } 31 | } 32 | } -------------------------------------------------------------------------------- /src/main/java/hudson/plugins/scm_sync_configuration/model/BotherTimeout.java: -------------------------------------------------------------------------------- 1 | package hudson.plugins.scm_sync_configuration.model; 2 | 3 | import java.util.Calendar; 4 | import java.util.Date; 5 | 6 | import org.apache.commons.lang.builder.HashCodeBuilder; 7 | 8 | public abstract class BotherTimeout { 9 | 10 | protected Date timeout; 11 | 12 | protected BotherTimeout(int _timeoutMinutesFromNow){ 13 | Calendar cal = Calendar.getInstance(); 14 | cal.add(Calendar.MINUTE, _timeoutMinutesFromNow); 15 | this.timeout = cal.getTime(); 16 | } 17 | 18 | public boolean isOutdated(){ 19 | return this.timeout.after(new Date()); 20 | } 21 | 22 | public abstract boolean matchesUrl(String currentUrl); 23 | 24 | public static class FACTORY { 25 | public static BotherTimeout createBotherTimeout(String type, int timeoutMinutesFromNow, String currentUrl){ 26 | if("thisConfig".equals(type)){ 27 | return new CurrentConfig(timeoutMinutesFromNow, currentUrl); 28 | } else if("anyConfigs".equals(type)){ 29 | return new EveryConfigs(timeoutMinutesFromNow); 30 | } else { 31 | throw new IllegalArgumentException("Invalid bother timeout type : "+String.valueOf(type)); 32 | } 33 | } 34 | } 35 | 36 | public static class EveryConfigs extends BotherTimeout { 37 | protected EveryConfigs(int _timeoutMinutesFromNow){ 38 | super(_timeoutMinutesFromNow); 39 | } 40 | public boolean matchesUrl(String currentUrl) { 41 | return true; 42 | } 43 | @Override 44 | public boolean equals(Object that) { 45 | if ( this == that ) return true; 46 | return that instanceof EveryConfigs; 47 | } 48 | @Override 49 | public int hashCode() { 50 | return new HashCodeBuilder(17, 23).toHashCode(); 51 | } 52 | } 53 | 54 | public static class CurrentConfig extends BotherTimeout { 55 | private String url; 56 | public CurrentConfig(int _timeoutMinutesFromNow, String _url){ 57 | super(_timeoutMinutesFromNow); 58 | this.url = _url; 59 | } 60 | public boolean matchesUrl(String currentUrl){ 61 | if(currentUrl==null) return false; 62 | return this.url.equals(currentUrl); 63 | } 64 | @Override 65 | public boolean equals(Object that) { 66 | if ( this == that ) return true; 67 | if ( !(that instanceof CurrentConfig) ) return false; 68 | return url.equals(((CurrentConfig)that).url); 69 | } 70 | @Override 71 | public int hashCode() { 72 | return new HashCodeBuilder(13, 17).append(url).toHashCode(); 73 | } 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /src/main/java/hudson/plugins/scm_sync_configuration/model/ChangeSet.java: -------------------------------------------------------------------------------- 1 | package hudson.plugins.scm_sync_configuration.model; 2 | 3 | import com.google.common.io.Files; 4 | import hudson.plugins.scm_sync_configuration.JenkinsFilesHelper; 5 | import hudson.plugins.scm_sync_configuration.exceptions.LoggableException; 6 | import hudson.plugins.scm_sync_configuration.utils.Checksums; 7 | 8 | import java.io.File; 9 | import java.io.IOException; 10 | import java.util.*; 11 | 12 | /** 13 | * @author fcamblor 14 | * POJO representing a Changeset built during a scm transaction 15 | */ 16 | public class ChangeSet { 17 | 18 | // Changeset commit message 19 | WeightedMessage message = null; 20 | // [Path, content in bytes] which are queued for addition/modification 21 | Map pathContents; 22 | // Paths which are queued for deletion 23 | List pathsToDelete; 24 | 25 | public ChangeSet(){ 26 | pathContents = new HashMap(); 27 | pathsToDelete = new ArrayList(); 28 | } 29 | 30 | public void registerPath(String path) { 31 | boolean contentAlreadyRegistered = false; 32 | File hudsonFile = JenkinsFilesHelper.buildFileFromPathRelativeToHudsonRoot(path); 33 | Path pathToRegister = new Path(hudsonFile); 34 | 35 | if(pathToRegister.isDirectory()){ 36 | pathContents.put(pathToRegister, new byte[0]); 37 | } else { 38 | // Verifying if path content is already in pathContent and, if this is the case, 39 | // look at checksums 40 | if(pathContents.containsKey(pathToRegister)){ 41 | try { 42 | contentAlreadyRegistered = Checksums.fileAndByteArrayContentAreEqual(pathToRegister.getHudsonFile(), pathContents.get(pathToRegister)); 43 | } catch (IOException e) { 44 | throw new LoggableException("Changeset path <"+path+"> registration failed", Checksums.class, "fileAndByteArrayContentAreEqual", e); 45 | } 46 | } 47 | 48 | if(!contentAlreadyRegistered){ 49 | try { 50 | pathContents.put(pathToRegister, Files.toByteArray(pathToRegister.getHudsonFile())); 51 | } catch (IOException e) { 52 | throw new LoggableException("Changeset path <"+path+"> registration failed", Files.class, "toByteArray", e); 53 | } 54 | } 55 | } 56 | } 57 | 58 | public void registerPathForDeletion(String path){ 59 | // We should determine if path is a directory by watching scm path (and not hudson path) because in most of time, 60 | // when we are here, directory is already deleted in hudson hierarchy... 61 | if(new Path(path).getScmFile().exists()) { 62 | boolean isDirectory = new Path(path).getScmFile().isDirectory(); 63 | pathsToDelete.add(new Path(path, isDirectory)); 64 | } 65 | } 66 | 67 | public boolean isEmpty(){ 68 | return pathContents.isEmpty() && pathsToDelete.isEmpty(); 69 | } 70 | 71 | public Map getPathContents(){ 72 | Map filteredPathContents = new HashMap(pathContents); 73 | 74 | // Avoiding ConcurrentModificationException... 75 | List filteredPaths = new ArrayList(); 76 | 77 | for(Path pathToAdd : filteredPathContents.keySet()){ 78 | for(Path pathToDelete : pathsToDelete){ 79 | // Removing paths being both in pathsToDelete and pathContents 80 | if(pathToDelete.equals(pathToAdd)){ 81 | filteredPaths.add(pathToAdd); 82 | } 83 | } 84 | } 85 | 86 | for(Path path : filteredPaths){ 87 | filteredPathContents.remove(path); 88 | } 89 | 90 | return filteredPathContents; 91 | } 92 | 93 | public List getPathsToDelete(){ 94 | return Collections.unmodifiableList(pathsToDelete); 95 | } 96 | 97 | public void defineMessage(WeightedMessage weightedMessage) { 98 | // Defining message only once ! 99 | if(this.message == null || weightedMessage.getWeight().compareTo(message.getWeight()) > 0){ 100 | this.message = weightedMessage; 101 | } 102 | } 103 | 104 | public String getMessage(){ 105 | return this.message.getMessage(); 106 | } 107 | 108 | @Override 109 | public String toString() { 110 | StringBuilder sb = new StringBuilder(); 111 | for(Path path : getPathContents().keySet()){ 112 | sb.append(String.format(" A %s%n", path.toString())); 113 | } 114 | for(Path path : getPathsToDelete()){ 115 | sb.append(String.format(" D %s%n", path.toString())); 116 | } 117 | return sb.toString(); 118 | } 119 | } 120 | -------------------------------------------------------------------------------- /src/main/java/hudson/plugins/scm_sync_configuration/model/Commit.java: -------------------------------------------------------------------------------- 1 | package hudson.plugins.scm_sync_configuration.model; 2 | 3 | import org.apache.commons.lang.StringUtils; 4 | import org.apache.commons.lang.WordUtils; 5 | 6 | import com.google.common.base.Strings; 7 | 8 | import hudson.model.User; 9 | 10 | /** 11 | * @author fcamblor 12 | * Commit is an aggregation of a changeset with a commit message 13 | * Note that commit message won't _always_ be the same as changeset.message since some additionnal contextual 14 | * informations will be provided. 15 | */ 16 | public class Commit { 17 | String message; 18 | ChangeSet changeset; 19 | ScmContext scmContext; 20 | User author; 21 | 22 | public Commit(ChangeSet changeset, User author, String userMessage, ScmContext scmContext) { 23 | this.message = createCommitMessage(scmContext, changeset.getMessage(), author, userMessage); 24 | this.changeset = changeset; 25 | this.scmContext = scmContext; 26 | this.author = author; 27 | } 28 | 29 | public String getMessage() { 30 | return message; 31 | } 32 | 33 | public ChangeSet getChangeset() { 34 | return changeset; 35 | } 36 | 37 | public ScmContext getScmContext(){ 38 | return scmContext; 39 | } 40 | 41 | private static String createCommitMessage(ScmContext context, String messagePrefix, User user, String userComment){ 42 | StringBuilder commitMessage = new StringBuilder(); 43 | if (user != null) { 44 | commitMessage.append(user.getId()).append(": "); 45 | } 46 | commitMessage.append(messagePrefix).append('\n'); 47 | if (user != null) { 48 | commitMessage.append('\n').append("Change performed by ").append(user.getDisplayName()).append('\n'); 49 | } 50 | if (userComment != null && !"".equals(userComment.trim())){ 51 | commitMessage.append('\n').append(userComment.trim()); 52 | } 53 | String message = commitMessage.toString(); 54 | 55 | if (!Strings.isNullOrEmpty(context.getCommitMessagePattern())) { 56 | message = context.getCommitMessagePattern().replaceAll("\\[message\\]", message.replaceAll("\\$", "\\\\\\$")); 57 | } 58 | return wrapText(message, 72); 59 | } 60 | 61 | private static String wrapText(String str, int lineLength) { 62 | if (str == null) { 63 | return null; 64 | } 65 | int i = 0; 66 | int max = str.length(); 67 | StringBuilder text = new StringBuilder(); 68 | while (i < max) { 69 | int next = str.indexOf('\n', i); 70 | if (next < 0) { 71 | next = max; 72 | } 73 | String line = StringUtils.stripEnd(str.substring(i, next), null); 74 | if (line.length() > lineLength) { 75 | line = WordUtils.wrap(line, lineLength, "\n", false); 76 | } 77 | text.append(line).append('\n'); 78 | i = next+1; 79 | } 80 | return text.toString(); 81 | } 82 | 83 | @Override 84 | public String toString() { 85 | StringBuilder sb = new StringBuilder(); 86 | sb.append(String.format("Commit %s : %n", super.toString())); 87 | sb.append(String.format(" Author : %s%n", String.valueOf(author))); 88 | sb.append(String.format(" Comment : %s%n", message)); 89 | sb.append(String.format(" Changeset : %n%s%n", changeset.toString())); 90 | return sb.toString(); 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /src/main/java/hudson/plugins/scm_sync_configuration/model/MessageWeight.java: -------------------------------------------------------------------------------- 1 | package hudson.plugins.scm_sync_configuration.model; 2 | 3 | /** 4 | * @author fcamblor 5 | * Message weight should be used to prioritize messages into a Scm Transaction 6 | */ 7 | public enum MessageWeight { 8 | MINIMAL, 9 | NORMAL, 10 | IMPORTANT, 11 | MORE_IMPORTANT; 12 | } 13 | -------------------------------------------------------------------------------- /src/main/java/hudson/plugins/scm_sync_configuration/model/Path.java: -------------------------------------------------------------------------------- 1 | package hudson.plugins.scm_sync_configuration.model; 2 | 3 | import hudson.plugins.scm_sync_configuration.JenkinsFilesHelper; 4 | import hudson.plugins.scm_sync_configuration.ScmSyncConfigurationBusiness; 5 | 6 | import java.io.File; 7 | 8 | /** 9 | * @author fcamblor 10 | * Paths allows to know if a given path is a directory or not, without using a File object since, 11 | * generally, Path will be relative to jenkins root 12 | */ 13 | public class Path { 14 | 15 | private final String path; 16 | private final boolean isDirectory; 17 | 18 | public Path(String path){ 19 | this(JenkinsFilesHelper.buildFileFromPathRelativeToHudsonRoot(path)); 20 | } 21 | 22 | public Path(File hudsonFile){ 23 | this(JenkinsFilesHelper.buildPathRelativeToHudsonRoot(hudsonFile), hudsonFile.isDirectory()); 24 | } 25 | 26 | public Path(String path, boolean isDirectory) { 27 | this.path = path.replace(File.separatorChar, '/'); // Make sure we use the system-independent separator. 28 | this.isDirectory = isDirectory; 29 | } 30 | 31 | public String getPath() { 32 | return path; 33 | } 34 | 35 | public File getHudsonFile(){ 36 | return JenkinsFilesHelper.buildFileFromPathRelativeToHudsonRoot(this.path); 37 | } 38 | 39 | public File getScmFile(){ 40 | // TODO: Externalize ScmSyncConfigurationBusiness.getCheckoutScmDirectoryAbsolutePath() 41 | // in another class ? 42 | return new File(ScmSyncConfigurationBusiness.getCheckoutScmDirectoryAbsolutePath(), getPath()); 43 | } 44 | 45 | public String getFirstNonExistingParentScmPath(){ 46 | File scmFile = getScmFile(); 47 | File latestNonExistingScmFile = null; 48 | File currentFile = scmFile; 49 | while(!currentFile.exists()){ 50 | latestNonExistingScmFile = currentFile; 51 | currentFile = currentFile.getParentFile(); 52 | } 53 | 54 | return latestNonExistingScmFile.getAbsolutePath().substring(ScmSyncConfigurationBusiness.getCheckoutScmDirectoryAbsolutePath().length()+1); 55 | } 56 | 57 | public boolean isDirectory() { 58 | return isDirectory; 59 | } 60 | 61 | public boolean contains(Path p){ 62 | if (this.isDirectory()) { 63 | String path = this.getPath(); 64 | if (!path.endsWith("/")) { 65 | path += '/'; 66 | } 67 | String otherPath = p.getPath(); 68 | if (p.isDirectory() && !otherPath.endsWith("/")) { 69 | otherPath += '/'; 70 | } 71 | return otherPath.startsWith(path); 72 | } 73 | return false; 74 | } 75 | 76 | @Override 77 | public boolean equals(Object o) { 78 | if (this == o) { 79 | return true; 80 | } 81 | if (!(o instanceof Path)) { 82 | return false; 83 | } 84 | 85 | Path path1 = (Path) o; 86 | 87 | if (isDirectory != path1.isDirectory) { 88 | return false; 89 | } 90 | if (path != null ? !path.equals(path1.path) : path1.path != null) { 91 | return false; 92 | } 93 | 94 | return true; 95 | } 96 | 97 | @Override 98 | public int hashCode() { 99 | int result = path != null ? path.hashCode() : 0; 100 | result = 31 * result + (isDirectory ? 1 : 0); 101 | return result; 102 | } 103 | 104 | @Override 105 | public String toString() { 106 | return getPath()+(isDirectory()?"/":""); 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /src/main/java/hudson/plugins/scm_sync_configuration/model/ScmContext.java: -------------------------------------------------------------------------------- 1 | package hudson.plugins.scm_sync_configuration.model; 2 | 3 | import org.apache.commons.lang.builder.ToStringBuilder; 4 | 5 | import hudson.plugins.scm_sync_configuration.scms.SCM; 6 | 7 | public class ScmContext { 8 | 9 | private String scmRepositoryUrl; 10 | private SCM scm; 11 | private String commitMessagePattern; 12 | 13 | public ScmContext(SCM _scm, String _scmRepositoryUrl){ 14 | this(_scm, _scmRepositoryUrl, "[message]"); 15 | } 16 | 17 | public ScmContext(SCM _scm, String _scmRepositoryUrl, String _commitMessagePattern){ 18 | this.scm = _scm; 19 | this.scmRepositoryUrl = _scmRepositoryUrl; 20 | this.commitMessagePattern = _commitMessagePattern; 21 | } 22 | 23 | public String getScmRepositoryUrl() { 24 | return scmRepositoryUrl; 25 | } 26 | 27 | public SCM getScm() { 28 | return scm; 29 | } 30 | 31 | public String getCommitMessagePattern(){ 32 | return commitMessagePattern; 33 | } 34 | 35 | @Override 36 | public String toString() { 37 | return new ToStringBuilder(this).append("scm", scm).append("scmRepositoryUrl", scmRepositoryUrl) 38 | .append("commitMessagePattern", commitMessagePattern).toString(); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/hudson/plugins/scm_sync_configuration/model/WeightedMessage.java: -------------------------------------------------------------------------------- 1 | package hudson.plugins.scm_sync_configuration.model; 2 | 3 | /** 4 | * @author fcamblor 5 | * WeightMessage is used to define a message with a weight 6 | * Weight will be used to prioritize commit messages into a ScmTransaction, in order to 7 | * have only the more important commit message kept during the transaction 8 | */ 9 | public class WeightedMessage { 10 | 11 | private final String message; 12 | private final MessageWeight weight; 13 | 14 | public WeightedMessage(String message, MessageWeight weight) { 15 | this.message = message; 16 | this.weight = weight; 17 | } 18 | 19 | public String getMessage() { 20 | return message; 21 | } 22 | 23 | public MessageWeight getWeight() { 24 | return weight; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/hudson/plugins/scm_sync_configuration/scms/SCMCredentialConfiguration.java: -------------------------------------------------------------------------------- 1 | package hudson.plugins.scm_sync_configuration.scms; 2 | 3 | public class SCMCredentialConfiguration { 4 | private String username; 5 | private String password; 6 | private String privateKey; 7 | private String passphrase; 8 | 9 | public SCMCredentialConfiguration(String _username, String _password, String _passPhrase, char[] _privateKey){ 10 | this.username = _username; 11 | this.password = _password; 12 | this.passphrase = _passPhrase; 13 | if(_privateKey!=null){ 14 | this.privateKey = String.valueOf(_privateKey); 15 | } 16 | } 17 | 18 | public SCMCredentialConfiguration(String _username, String _password){ 19 | this(_username, _password, null, null); 20 | } 21 | 22 | public SCMCredentialConfiguration(String _username){ 23 | this(_username, null, null, null); 24 | } 25 | 26 | public String getUsername() { 27 | return username; 28 | } 29 | 30 | public String getPassword() { 31 | return password; 32 | } 33 | 34 | public String getPrivateKey() { 35 | return privateKey; 36 | } 37 | 38 | public String getPassphrase() { 39 | return passphrase; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/hudson/plugins/scm_sync_configuration/scms/ScmSyncGitSCM.java: -------------------------------------------------------------------------------- 1 | package hudson.plugins.scm_sync_configuration.scms; 2 | 3 | import org.kohsuke.stapler.StaplerRequest; 4 | 5 | public class ScmSyncGitSCM extends SCM { 6 | 7 | private static final String SCM_URL_PREFIX="scm:git:"; 8 | 9 | ScmSyncGitSCM(){ 10 | super("Git", "git/config.jelly", "hudson.plugins.git.GitSCM", "/hudson/plugins/scm_sync_configuration/ScmSyncConfigurationPlugin/scms/git/url-help.jelly"); 11 | } 12 | 13 | @Override 14 | public String createScmUrlFromRequest(StaplerRequest req) { 15 | String repoURL = req.getParameter("gitRepositoryUrl"); 16 | if (repoURL == null) { 17 | return null; 18 | } else { 19 | return SCM_URL_PREFIX + repoURL.trim(); 20 | } 21 | } 22 | 23 | @Override 24 | public String extractScmUrlFrom(String scmUrl) { 25 | return scmUrl.substring(SCM_URL_PREFIX.length()); 26 | } 27 | 28 | @Override 29 | public SCMCredentialConfiguration extractScmCredentials(String scmUrl) { 30 | return null; 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/hudson/plugins/scm_sync_configuration/scms/ScmSyncNoSCM.java: -------------------------------------------------------------------------------- 1 | package hudson.plugins.scm_sync_configuration.scms; 2 | 3 | import org.kohsuke.stapler.StaplerRequest; 4 | 5 | 6 | public class ScmSyncNoSCM extends SCM { 7 | 8 | ScmSyncNoSCM(){ 9 | super("None", "none/config.jelly", null, "/hudson/plugins/scm_sync_configuration/ScmSyncConfigurationPlugin/scms/none/url-help.jelly"); 10 | } 11 | 12 | @Override 13 | public String createScmUrlFromRequest(StaplerRequest req) { 14 | return null; 15 | } 16 | 17 | @Override 18 | public String extractScmUrlFrom(String scmUrl) { 19 | return null; 20 | } 21 | 22 | @Override 23 | public SCMCredentialConfiguration extractScmCredentials( 24 | String scmRepositoryURL) { 25 | return null; 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/hudson/plugins/scm_sync_configuration/scms/customproviders/git/gitexe/ScmSyncGitExeScmProvider.java: -------------------------------------------------------------------------------- 1 | package hudson.plugins.scm_sync_configuration.scms.customproviders.git.gitexe; 2 | 3 | import org.apache.maven.scm.provider.git.command.GitCommand; 4 | import org.apache.maven.scm.provider.git.gitexe.GitExeScmProvider; 5 | 6 | /** 7 | * Try to fix those very broken maven scm git commands. We should really move to using the git-client plugin. 8 | */ 9 | public class ScmSyncGitExeScmProvider extends GitExeScmProvider { 10 | 11 | @Override 12 | protected GitCommand getCheckInCommand() { 13 | // Push to origin (fcamblor) 14 | // Handle quoted output from git, and fix relative path computations SCM-695, SCM-772 15 | return new ScmSyncGitCheckInCommand(); 16 | } 17 | 18 | @Override 19 | protected GitCommand getRemoveCommand() { 20 | // Include -- in git rm 21 | return new ScmSyncGitRemoveCommand(); 22 | } 23 | 24 | @Override 25 | protected GitCommand getStatusCommand() { 26 | // Handle quoted output from git, and fix relative path computations SCM-695, SCM-772 27 | return new ScmSyncGitStatusCommand(); 28 | } 29 | 30 | @Override 31 | protected GitCommand getAddCommand() { 32 | // Handle quoted output from git, and fix relative path computations SCM-695, SCM-772 33 | return new ScmSyncGitAddCommand(); 34 | } 35 | 36 | // TODO: we also use checkout and update. Those call git ls-files, which parses the result wrongly... 37 | // (doesn't account for the partial escaping done there for \t, \n, and \\ .) 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/hudson/plugins/scm_sync_configuration/scms/customproviders/git/gitexe/ScmSyncGitRemoveCommand.java: -------------------------------------------------------------------------------- 1 | package hudson.plugins.scm_sync_configuration.scms.customproviders.git.gitexe; 2 | 3 | import java.io.File; 4 | import java.util.List; 5 | 6 | import org.apache.maven.scm.ScmException; 7 | import org.apache.maven.scm.ScmFileSet; 8 | import org.apache.maven.scm.ScmResult; 9 | import org.apache.maven.scm.command.remove.RemoveScmResult; 10 | import org.apache.maven.scm.provider.ScmProviderRepository; 11 | import org.apache.maven.scm.provider.git.gitexe.command.GitCommandLineUtils; 12 | import org.apache.maven.scm.provider.git.gitexe.command.remove.GitRemoveCommand; 13 | import org.apache.maven.scm.provider.git.gitexe.command.remove.GitRemoveConsumer; 14 | import org.codehaus.plexus.util.cli.CommandLineUtils; 15 | import org.codehaus.plexus.util.cli.Commandline; 16 | 17 | /** 18 | * Yet another crappy hack to fix maven's gitexe implementation. It doesn't pass "--" to git rm, leading to failures if 19 | * a file starting with a dash is to be removed. Because of the poor design of that library using static methods galore, 20 | * we cannot just override the wrong method... 21 | */ 22 | public class ScmSyncGitRemoveCommand extends GitRemoveCommand { 23 | // Implementation copied from v1.9.1; single change in createCommandLine below. 24 | 25 | @Override 26 | protected ScmResult executeRemoveCommand(ScmProviderRepository repo, ScmFileSet fileSet, String message) 27 | throws ScmException { 28 | if (fileSet.getFileList().isEmpty()) { 29 | throw new ScmException("You must provide at least one file/directory to remove"); 30 | } 31 | 32 | Commandline cl = createCommandLine(fileSet.getBasedir(), fileSet.getFileList()); 33 | GitRemoveConsumer consumer = new GitRemoveConsumer(getLogger()); 34 | 35 | CommandLineUtils.StringStreamConsumer stderr = new CommandLineUtils.StringStreamConsumer(); 36 | 37 | int exitCode; 38 | 39 | exitCode = GitCommandLineUtils.execute(cl, consumer, stderr, getLogger()); 40 | if (exitCode != 0) { 41 | return new RemoveScmResult(cl.toString(), "The git command failed.", stderr.getOutput(), false); 42 | } 43 | 44 | return new RemoveScmResult(cl.toString(), consumer.getRemovedFiles()); 45 | } 46 | 47 | public static Commandline createCommandLine(File workingDirectory, List files) throws ScmException { 48 | Commandline cl = GitCommandLineUtils.getBaseGitCommandLine(workingDirectory, "rm"); 49 | 50 | for (File file : files) { 51 | if (file.isAbsolute()) { 52 | if (file.isDirectory()) { 53 | cl.createArg().setValue("-r"); 54 | break; 55 | } 56 | } else { 57 | File absFile = new File(workingDirectory, file.getPath()); 58 | if (absFile.isDirectory()) { 59 | cl.createArg().setValue("-r"); 60 | break; 61 | } 62 | } 63 | } 64 | 65 | cl.createArg().setValue("--"); // This is missing upstream. 66 | 67 | ScmSyncGitUtils.addTarget(cl, files); 68 | 69 | return cl; 70 | } 71 | 72 | } 73 | -------------------------------------------------------------------------------- /src/main/java/hudson/plugins/scm_sync_configuration/scms/customproviders/git/gitexe/ScmSyncGitStatusCommand.java: -------------------------------------------------------------------------------- 1 | package hudson.plugins.scm_sync_configuration.scms.customproviders.git.gitexe; 2 | 3 | import java.io.File; 4 | 5 | import org.apache.maven.scm.ScmException; 6 | import org.apache.maven.scm.ScmFileSet; 7 | import org.apache.maven.scm.command.status.StatusScmResult; 8 | import org.apache.maven.scm.provider.ScmProviderRepository; 9 | import org.apache.maven.scm.provider.git.gitexe.command.GitCommandLineUtils; 10 | import org.apache.maven.scm.provider.git.gitexe.command.status.GitStatusCommand; 11 | import org.apache.maven.scm.provider.git.repository.GitScmProviderRepository; 12 | import org.codehaus.plexus.util.cli.CommandLineUtils; 13 | import org.codehaus.plexus.util.cli.Commandline; 14 | 15 | public class ScmSyncGitStatusCommand extends GitStatusCommand { 16 | 17 | @Override 18 | protected StatusScmResult executeStatusCommand(ScmProviderRepository repo, ScmFileSet fileSet) throws ScmException { 19 | Commandline cl = createCommandLine( (GitScmProviderRepository) repo, fileSet ); 20 | File repoRootDirectory = ScmSyncGitUtils.getRepositoryRootDirectory(fileSet.getBasedir(), getLogger()); 21 | FixedGitStatusConsumer consumer = new FixedGitStatusConsumer(getLogger(), fileSet.getBasedir(), repoRootDirectory); 22 | CommandLineUtils.StringStreamConsumer stderr = new CommandLineUtils.StringStreamConsumer(); 23 | int exitCode = GitCommandLineUtils.execute( cl, consumer, stderr, getLogger() ); 24 | if (exitCode != 0) { 25 | if (getLogger().isInfoEnabled()) { 26 | getLogger().info( "nothing added to commit but untracked files present (use \"git add\" to track)" ); 27 | } 28 | } 29 | return new StatusScmResult( cl.toString(), consumer.getChangedFiles() ); 30 | } 31 | 32 | public static Commandline createCommandLine( GitScmProviderRepository repository, ScmFileSet fileSet ) 33 | { 34 | Commandline cl = GitCommandLineUtils.getBaseGitCommandLine( fileSet.getBasedir(), "status" ); 35 | cl.addArguments( new String[] { "--porcelain", "." } ); 36 | return cl; 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/hudson/plugins/scm_sync_configuration/strategies/ScmSyncStrategy.java: -------------------------------------------------------------------------------- 1 | package hudson.plugins.scm_sync_configuration.strategies; 2 | 3 | import hudson.XmlFile; 4 | import hudson.model.Item; 5 | import hudson.model.Saveable; 6 | import hudson.plugins.scm_sync_configuration.model.WeightedMessage; 7 | 8 | import java.io.File; 9 | import java.util.List; 10 | 11 | public interface ScmSyncStrategy { 12 | 13 | public static interface CommitMessageFactory { 14 | public WeightedMessage getMessageWhenSaveableUpdated(Saveable s, XmlFile file); 15 | public WeightedMessage getMessageWhenItemRenamed(Item item, String oldPath, String newPath); 16 | public WeightedMessage getMessageWhenItemDeleted(Item item); 17 | } 18 | 19 | /** 20 | * Is the given Saveable eligible for the current strategy ? 21 | * @param saveable A saveable which is saved 22 | * @param file Corresponding file to the given Saveable object 23 | * @return true if current Saveable instance matches with current ScmSyncStrategy target, 24 | * false otherwise 25 | */ 26 | boolean isSaveableApplicable(Saveable saveable, File file); 27 | 28 | /** 29 | * Determines whether the strategy might have applied to a deleted item. 30 | * 31 | * @param saveable that was deleted; still exists in Jenkins' model but has already been eradicated from disk 32 | * @param pathRelativeToRoot where the item resided 33 | * @param wasDirectory whether it was a directory 34 | * @return 35 | */ 36 | boolean mightHaveBeenApplicableToDeletedSaveable(Saveable saveable, String pathRelativeToRoot, boolean wasDirectory); 37 | 38 | /** 39 | * Is the given url eligible for the current strategy ? 40 | * @param url Current url, where hudson root url has been truncated 41 | * @return true if current url matches with current ScmSyncStrategy target, false otherwise 42 | */ 43 | boolean isCurrentUrlApplicable(String url); 44 | 45 | /** 46 | * Collects all files, from Jenkins' root directory, that match this strategy. 47 | * 48 | * @return the list of files matched. 49 | */ 50 | List collect(); 51 | 52 | /** 53 | * Collects all files in the given directory, which must be under Jenkins' root directory, that match this strategy. 54 | * 55 | * @param directory to search in 56 | * @return the list of files 57 | * @throws IllegalArgumentException if the given directory is not under Jenkins' root directory 58 | */ 59 | List collect(File directory); 60 | 61 | /** 62 | * @return List of sync'ed file includes brought by current strategy. Used only for informational purposes in the UI. 63 | */ 64 | List getSyncIncludes(); 65 | 66 | /** 67 | * @return A Factory intended to generate commit message depending on contexts 68 | */ 69 | CommitMessageFactory getCommitMessageFactory(); 70 | } 71 | -------------------------------------------------------------------------------- /src/main/java/hudson/plugins/scm_sync_configuration/strategies/impl/BasicPluginsConfigScmSyncStrategy.java: -------------------------------------------------------------------------------- 1 | package hudson.plugins.scm_sync_configuration.strategies.impl; 2 | 3 | import hudson.XmlFile; 4 | import hudson.model.Item; 5 | import hudson.model.Saveable; 6 | import hudson.plugins.scm_sync_configuration.model.MessageWeight; 7 | import hudson.plugins.scm_sync_configuration.model.WeightedMessage; 8 | import hudson.plugins.scm_sync_configuration.strategies.AbstractScmSyncStrategy; 9 | import hudson.plugins.scm_sync_configuration.strategies.model.ConfigurationEntityMatcher; 10 | import hudson.plugins.scm_sync_configuration.strategies.model.PageMatcher; 11 | import hudson.plugins.scm_sync_configuration.strategies.model.PatternsEntityMatcher; 12 | 13 | import java.util.Collections; 14 | 15 | public class BasicPluginsConfigScmSyncStrategy extends AbstractScmSyncStrategy { 16 | 17 | private static final String[] PATTERNS = new String[]{ 18 | "hudson*.xml", 19 | "jenkins*.xml", 20 | "scm-sync-configuration.xml" 21 | }; 22 | 23 | private static final ConfigurationEntityMatcher CONFIG_ENTITY_MATCHER = new PatternsEntityMatcher(PATTERNS); 24 | 25 | public BasicPluginsConfigScmSyncStrategy(){ 26 | super(CONFIG_ENTITY_MATCHER, Collections.emptyList()); 27 | } 28 | 29 | @Override 30 | public CommitMessageFactory getCommitMessageFactory(){ 31 | return new CommitMessageFactory(){ 32 | @Override 33 | public WeightedMessage getMessageWhenSaveableUpdated(Saveable s, XmlFile file) { 34 | return new WeightedMessage("Plugin configuration files updated", MessageWeight.MINIMAL); 35 | } 36 | @Override 37 | public WeightedMessage getMessageWhenItemRenamed(Item item, String oldPath, String newPath) { 38 | // It should never happen... but who cares how will behave *every* plugin in the jenkins land ? 39 | return new WeightedMessage("Plugin configuration files renamed", MessageWeight.MINIMAL); 40 | } 41 | @Override 42 | public WeightedMessage getMessageWhenItemDeleted(Item item) { 43 | // It should never happen... but who cares how will behave *every* plugin in the jenkins land ? 44 | return new WeightedMessage("Plugin configuration files deleted", MessageWeight.MINIMAL); 45 | } 46 | }; 47 | } 48 | 49 | @Override 50 | public boolean mightHaveBeenApplicableToDeletedSaveable(Saveable saveable, String pathRelativeToRoot, boolean wasDirectory) { 51 | return !wasDirectory && pathRelativeToRoot != null && CONFIG_ENTITY_MATCHER.matches(saveable, pathRelativeToRoot, false); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/main/java/hudson/plugins/scm_sync_configuration/strategies/impl/JenkinsConfigScmSyncStrategy.java: -------------------------------------------------------------------------------- 1 | package hudson.plugins.scm_sync_configuration.strategies.impl; 2 | 3 | import hudson.XmlFile; 4 | import hudson.model.Item; 5 | import hudson.model.Saveable; 6 | import hudson.plugins.scm_sync_configuration.model.MessageWeight; 7 | import hudson.plugins.scm_sync_configuration.model.WeightedMessage; 8 | import hudson.plugins.scm_sync_configuration.strategies.AbstractScmSyncStrategy; 9 | import hudson.plugins.scm_sync_configuration.strategies.model.ConfigurationEntityMatcher; 10 | import hudson.plugins.scm_sync_configuration.strategies.model.PageMatcher; 11 | import hudson.plugins.scm_sync_configuration.strategies.model.PatternsEntityMatcher; 12 | 13 | import java.util.List; 14 | 15 | import com.google.common.collect.ImmutableList; 16 | 17 | public class JenkinsConfigScmSyncStrategy extends AbstractScmSyncStrategy { 18 | 19 | private static final List PAGE_MATCHERS = ImmutableList.of( 20 | // Global configuration page 21 | new PageMatcher("^configure$", "form[name='config']"), 22 | // View configuration pages 23 | new PageMatcher("^(.+/)?view/[^/]+/configure$", "form[name='viewConfig']"), 24 | new PageMatcher("^newView$", "form[name='createView'],form[name='createItem']") 25 | ); 26 | 27 | private static final String[] PATTERNS = new String[]{ 28 | "config.xml" 29 | }; 30 | 31 | private static final ConfigurationEntityMatcher CONFIG_ENTITY_MATCHER = new PatternsEntityMatcher(PATTERNS); 32 | 33 | public JenkinsConfigScmSyncStrategy(){ 34 | super(CONFIG_ENTITY_MATCHER, PAGE_MATCHERS); 35 | } 36 | 37 | @Override 38 | public CommitMessageFactory getCommitMessageFactory(){ 39 | return new CommitMessageFactory(){ 40 | @Override 41 | public WeightedMessage getMessageWhenSaveableUpdated(Saveable s, XmlFile file) { 42 | return new WeightedMessage("Jenkins configuration files updated", MessageWeight.NORMAL); 43 | } 44 | @Override 45 | public WeightedMessage getMessageWhenItemRenamed(Item item, String oldPath, String newPath) { 46 | throw new IllegalStateException("Jenkins configuration files should never be renamed !"); 47 | } 48 | @Override 49 | public WeightedMessage getMessageWhenItemDeleted(Item item) { 50 | throw new IllegalStateException("Jenkins configuration files should never be deleted !"); 51 | } 52 | }; 53 | } 54 | 55 | @Override 56 | public boolean mightHaveBeenApplicableToDeletedSaveable(Saveable saveable, String pathRelativeToRoot, boolean wasDirectory) { 57 | // Uh-oh... Jenkins config should never be deleted. 58 | return false; 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/main/java/hudson/plugins/scm_sync_configuration/strategies/impl/JobConfigScmSyncStrategy.java: -------------------------------------------------------------------------------- 1 | package hudson.plugins.scm_sync_configuration.strategies.impl; 2 | 3 | import hudson.XmlFile; 4 | import hudson.model.Item; 5 | import hudson.model.Saveable; 6 | import hudson.plugins.scm_sync_configuration.model.MessageWeight; 7 | import hudson.plugins.scm_sync_configuration.model.WeightedMessage; 8 | import hudson.plugins.scm_sync_configuration.strategies.AbstractScmSyncStrategy; 9 | import hudson.plugins.scm_sync_configuration.strategies.model.ConfigurationEntityMatcher; 10 | import hudson.plugins.scm_sync_configuration.strategies.model.JobOrFolderConfigurationEntityMatcher; 11 | import hudson.plugins.scm_sync_configuration.strategies.model.PageMatcher; 12 | 13 | import java.util.Collections; 14 | 15 | public class JobConfigScmSyncStrategy extends AbstractScmSyncStrategy { 16 | 17 | private static final ConfigurationEntityMatcher CONFIG_MATCHER = new JobOrFolderConfigurationEntityMatcher(); 18 | 19 | public JobConfigScmSyncStrategy(){ 20 | super(CONFIG_MATCHER, Collections.singletonList(new PageMatcher("^(.*view/[^/]+/)?(job/[^/]+/)+configure$", "form[name='config']"))); 21 | } 22 | 23 | @Override 24 | public CommitMessageFactory getCommitMessageFactory(){ 25 | return new CommitMessageFactory(){ 26 | @Override 27 | public WeightedMessage getMessageWhenSaveableUpdated(Saveable s, XmlFile file) { 28 | return new WeightedMessage("Job ["+((Item)s).getName()+"] configuration updated", 29 | MessageWeight.IMPORTANT); 30 | } 31 | @Override 32 | public WeightedMessage getMessageWhenItemRenamed(Item item, String oldPath, String newPath) { 33 | return new WeightedMessage("Job ["+item.getName()+"] hierarchy renamed from ["+oldPath+"] to ["+newPath+"]", 34 | MessageWeight.MORE_IMPORTANT); 35 | } 36 | @Override 37 | public WeightedMessage getMessageWhenItemDeleted(Item item) { 38 | return new WeightedMessage("Job ["+item.getName()+"] hierarchy deleted", 39 | MessageWeight.MORE_IMPORTANT); 40 | } 41 | }; 42 | } 43 | 44 | @Override 45 | public boolean mightHaveBeenApplicableToDeletedSaveable(Saveable saveable, String pathRelativeFromRoot, boolean wasDirectory) { 46 | return CONFIG_MATCHER.matches(saveable, pathRelativeFromRoot, wasDirectory); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/main/java/hudson/plugins/scm_sync_configuration/strategies/impl/ManualIncludesScmSyncStrategy.java: -------------------------------------------------------------------------------- 1 | package hudson.plugins.scm_sync_configuration.strategies.impl; 2 | 3 | import hudson.model.Saveable; 4 | import hudson.plugins.scm_sync_configuration.ScmSyncConfigurationPlugin; 5 | import hudson.plugins.scm_sync_configuration.strategies.AbstractScmSyncStrategy; 6 | import hudson.plugins.scm_sync_configuration.strategies.model.ConfigurationEntityMatcher; 7 | import hudson.plugins.scm_sync_configuration.strategies.model.PageMatcher; 8 | import hudson.plugins.scm_sync_configuration.strategies.model.PatternsEntityMatcher; 9 | 10 | import java.util.Collections; 11 | import java.util.List; 12 | 13 | public class ManualIncludesScmSyncStrategy extends AbstractScmSyncStrategy { 14 | 15 | public ManualIncludesScmSyncStrategy(){ 16 | super(null, Collections.emptyList()); 17 | } 18 | 19 | @Override 20 | protected ConfigurationEntityMatcher createConfigEntityMatcher(){ 21 | String[] includes = new String[0]; 22 | List manualSynchronizationIncludes = ScmSyncConfigurationPlugin.getInstance().getManualSynchronizationIncludes(); 23 | if(manualSynchronizationIncludes != null){ 24 | includes = manualSynchronizationIncludes.toArray(new String[0]); 25 | } 26 | return new PatternsEntityMatcher(includes); 27 | } 28 | 29 | @Override 30 | public boolean mightHaveBeenApplicableToDeletedSaveable(Saveable saveable, String pathRelativeToRoot, boolean wasDirectory) { 31 | // Best we can do here. We'll double check later on in the transaction. 32 | return true; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/hudson/plugins/scm_sync_configuration/strategies/impl/UserConfigScmSyncStrategy.java: -------------------------------------------------------------------------------- 1 | package hudson.plugins.scm_sync_configuration.strategies.impl; 2 | 3 | import hudson.XmlFile; 4 | import hudson.model.Item; 5 | import hudson.model.Saveable; 6 | import hudson.model.User; 7 | import hudson.plugins.scm_sync_configuration.model.MessageWeight; 8 | import hudson.plugins.scm_sync_configuration.model.WeightedMessage; 9 | import hudson.plugins.scm_sync_configuration.strategies.AbstractScmSyncStrategy; 10 | import hudson.plugins.scm_sync_configuration.strategies.model.ClassAndFileConfigurationEntityMatcher; 11 | import hudson.plugins.scm_sync_configuration.strategies.model.ConfigurationEntityMatcher; 12 | import hudson.plugins.scm_sync_configuration.strategies.model.PageMatcher; 13 | 14 | import java.util.List; 15 | 16 | import com.google.common.collect.ImmutableList; 17 | 18 | public class UserConfigScmSyncStrategy extends AbstractScmSyncStrategy { 19 | 20 | // Don't miss to take into account view urls since we can configure a job through a view ! 21 | private static final List PAGE_MATCHERS = ImmutableList.of( 22 | new PageMatcher("^securityRealm/addUser$", "#main-panel form"), 23 | new PageMatcher("^securityRealm/user/[^/]+/configure$", "form[name='config']") 24 | ); 25 | 26 | // Only saving config.xml file located in user directory 27 | private static final String [] PATTERNS = new String[] { 28 | "users/*/config.xml" 29 | }; 30 | 31 | private static final ConfigurationEntityMatcher CONFIG_ENTITY_MATCHER = new ClassAndFileConfigurationEntityMatcher(User.class, PATTERNS); 32 | 33 | public UserConfigScmSyncStrategy(){ 34 | super(CONFIG_ENTITY_MATCHER, PAGE_MATCHERS); 35 | } 36 | 37 | @Override 38 | public CommitMessageFactory getCommitMessageFactory(){ 39 | return new CommitMessageFactory(){ 40 | @Override 41 | public WeightedMessage getMessageWhenSaveableUpdated(Saveable s, XmlFile file) { 42 | return new WeightedMessage("User ["+((User)s).getDisplayName()+"] configuration updated", 43 | MessageWeight.IMPORTANT); 44 | } 45 | @Override 46 | public WeightedMessage getMessageWhenItemRenamed(Item item, String oldPath, String newPath) { 47 | return new WeightedMessage("User ["+item.getName()+"] configuration renamed from ["+oldPath+"] to ["+newPath+"]", 48 | MessageWeight.MORE_IMPORTANT); 49 | } 50 | @Override 51 | public WeightedMessage getMessageWhenItemDeleted(Item item) { 52 | return new WeightedMessage("User ["+item.getName()+"] hierarchy deleted", 53 | MessageWeight.MORE_IMPORTANT); 54 | } 55 | }; 56 | } 57 | 58 | @Override 59 | public boolean mightHaveBeenApplicableToDeletedSaveable(Saveable saveable, String pathRelativeToRoot, boolean wasDirectory) { 60 | return CONFIG_ENTITY_MATCHER.matches(saveable, pathRelativeToRoot, wasDirectory); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/main/java/hudson/plugins/scm_sync_configuration/strategies/model/ClassAndFileConfigurationEntityMatcher.java: -------------------------------------------------------------------------------- 1 | package hudson.plugins.scm_sync_configuration.strategies.model; 2 | 3 | import hudson.model.Saveable; 4 | 5 | import java.io.File; 6 | 7 | public class ClassAndFileConfigurationEntityMatcher extends PatternsEntityMatcher { 8 | 9 | private final Class saveableClazz; 10 | 11 | public ClassAndFileConfigurationEntityMatcher(Class clazz, String[] patterns){ 12 | super(patterns); 13 | this.saveableClazz = clazz; 14 | } 15 | 16 | @Override 17 | public boolean matches(Saveable saveable, File file) { 18 | if (saveableClazz.isAssignableFrom(saveable.getClass())){ 19 | if (file == null) { 20 | return true; 21 | } else { 22 | return super.matches(saveable, file); 23 | } 24 | } 25 | 26 | return false; 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/hudson/plugins/scm_sync_configuration/strategies/model/ConfigurationEntityMatcher.java: -------------------------------------------------------------------------------- 1 | package hudson.plugins.scm_sync_configuration.strategies.model; 2 | 3 | import hudson.model.Saveable; 4 | 5 | import java.io.File; 6 | import java.util.List; 7 | 8 | import org.apache.tools.ant.types.selectors.FileSelector; 9 | 10 | /** 11 | * A matcher that matches specific files under $JENKINS_HOME. 12 | */ 13 | public interface ConfigurationEntityMatcher { 14 | 15 | /** 16 | * Determines whether the matcher matches a given combination of saveable and file. 17 | * 18 | * @param saveable the file belongs to 19 | * @param file that is to be matched 20 | * @return {@code true} on match, {@code false} otherwise 21 | */ 22 | public boolean matches(Saveable saveable, File file); 23 | 24 | /** 25 | * Determines whether the matcher would have matched a deleted file, of which we know only its path and possibly whether it was directory. 26 | * 27 | * @param saveable the file belonged to 28 | * @param pathRelativeToRoot of the file or directory (which Jenkins has already deleted) 29 | * @param isDirectory {@code true} if it's known that the path referred to a directory, {@code false} otherwise 30 | * @return {@code true} on match, {@code false} otherwise 31 | */ 32 | public boolean matches(Saveable saveable, String pathRelativeToRoot, boolean isDirectory); 33 | 34 | /** 35 | * Collects all files under the given rootDirectory that match, restricted by the given {@code link FileSelector}. 36 | * 37 | * @param rootDirectory to traverse 38 | * @param selector restricting the traversal 39 | * @return an array of all path names relative to the rootDirectory of all files that match. 40 | */ 41 | public String[] matchingFilesFrom(File rootDirectory, FileSelector selector); 42 | 43 | /** 44 | * All patterns this matcher matches; used only for informational purposes in the UI. 45 | * 46 | * @return A list of explanatory messages about the pattern the matcher matches. 47 | */ 48 | List getIncludes(); 49 | } 50 | -------------------------------------------------------------------------------- /src/main/java/hudson/plugins/scm_sync_configuration/strategies/model/PageMatcher.java: -------------------------------------------------------------------------------- 1 | package hudson.plugins.scm_sync_configuration.strategies.model; 2 | 3 | import java.util.regex.Pattern; 4 | 5 | public class PageMatcher { 6 | 7 | private Pattern urlRegex; 8 | private String targetFormSelector; 9 | 10 | public PageMatcher(String _urlRegexStr, String _targetFormSelector){ 11 | this.urlRegex = Pattern.compile(_urlRegexStr); 12 | this.targetFormSelector = _targetFormSelector; 13 | } 14 | 15 | public Pattern getUrlRegex() { 16 | return urlRegex; 17 | } 18 | 19 | public String getTargetFormSelector() { 20 | return targetFormSelector; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/hudson/plugins/scm_sync_configuration/strategies/model/PatternsEntityMatcher.java: -------------------------------------------------------------------------------- 1 | package hudson.plugins.scm_sync_configuration.strategies.model; 2 | 3 | import hudson.model.Saveable; 4 | import hudson.plugins.scm_sync_configuration.JenkinsFilesHelper; 5 | import hudson.plugins.scm_sync_configuration.ScmSyncConfigurationBusiness; 6 | 7 | import org.apache.tools.ant.DirectoryScanner; 8 | import org.apache.tools.ant.types.selectors.FileSelector; 9 | import org.springframework.util.AntPathMatcher; 10 | 11 | import java.io.File; 12 | import java.util.Arrays; 13 | import java.util.List; 14 | 15 | public class PatternsEntityMatcher implements ConfigurationEntityMatcher { 16 | 17 | private final String[] includesPatterns; 18 | 19 | private static String SCM_WORKING_DIRECTORY = ScmSyncConfigurationBusiness.getScmDirectoryName(); 20 | private static String WAR_DIRECTORY = "war"; 21 | 22 | public PatternsEntityMatcher(String[] includesPatterns){ 23 | this.includesPatterns = includesPatterns; 24 | } 25 | 26 | @Override 27 | public boolean matches(Saveable saveable, File file) { 28 | if (file == null) { 29 | return false; 30 | } 31 | return matches(saveable, JenkinsFilesHelper.buildPathRelativeToHudsonRoot(file), file.isDirectory()); 32 | } 33 | 34 | @Override 35 | public boolean matches(Saveable saveable, String pathRelativeToRoot, boolean isDirectory) { 36 | if (pathRelativeToRoot != null) { 37 | // Guard our own SCM workspace and the war directory. User-defined includes might inadvertently include those if they start with * or **! 38 | if (pathRelativeToRoot.equals(SCM_WORKING_DIRECTORY) || pathRelativeToRoot.startsWith(SCM_WORKING_DIRECTORY + '/')) { 39 | return false; 40 | } else if (pathRelativeToRoot.equals(WAR_DIRECTORY) || pathRelativeToRoot.startsWith(WAR_DIRECTORY + '/')) { 41 | return false; 42 | } 43 | AntPathMatcher matcher = new AntPathMatcher(); 44 | String directoryName = null; 45 | for (String pattern : includesPatterns) { 46 | if (matcher.match(pattern, pathRelativeToRoot)) { 47 | return true; 48 | } else if (isDirectory) { 49 | // pathRelativeFromRoot is be a directory, and the pattern end in a file name. In this case, we must claim a match. 50 | int i = pattern.lastIndexOf('/'); 51 | if (directoryName == null) { 52 | directoryName = pathRelativeToRoot.endsWith("/") ? pathRelativeToRoot.substring(0, pathRelativeToRoot.length() - 1) : pathRelativeToRoot; 53 | } 54 | if (i > 0 && matcher.match(pattern.substring(0, i), directoryName)) { 55 | return true; 56 | } 57 | } 58 | } 59 | } 60 | return false; 61 | } 62 | 63 | @Override 64 | public List getIncludes(){ 65 | return Arrays.asList(includesPatterns); 66 | } 67 | 68 | @Override 69 | public String[] matchingFilesFrom(File rootDirectory, FileSelector selector) { 70 | DirectoryScanner scanner = new DirectoryScanner(); 71 | scanner.setExcludes(new String[] { SCM_WORKING_DIRECTORY, SCM_WORKING_DIRECTORY + '/', WAR_DIRECTORY, WAR_DIRECTORY + '/'}); // Guard special directories 72 | scanner.setIncludes(includesPatterns); 73 | scanner.setBasedir(rootDirectory); 74 | if (selector != null) { 75 | scanner.setSelectors(new FileSelector[] { selector}); 76 | } 77 | scanner.scan(); 78 | return scanner.getIncludedFiles(); 79 | } 80 | 81 | } 82 | -------------------------------------------------------------------------------- /src/main/java/hudson/plugins/scm_sync_configuration/transactions/AtomicTransaction.java: -------------------------------------------------------------------------------- 1 | package hudson.plugins.scm_sync_configuration.transactions; 2 | 3 | /** 4 | * This ScmTransaction implementation should be aimed at commiting changes immediately 5 | * @author fcamblor 6 | */ 7 | public class AtomicTransaction extends ScmTransaction { 8 | 9 | public AtomicTransaction(boolean synchronousCommit){ 10 | super(synchronousCommit); 11 | } 12 | 13 | public AtomicTransaction(){ 14 | super(); 15 | } 16 | 17 | @Override 18 | public void registerPath(String path){ 19 | super.registerPath(path); 20 | // We should commit transaction after every change 21 | commit(); 22 | } 23 | 24 | @Override 25 | public void registerPathForDeletion(String path) { 26 | super.registerPathForDeletion(path); 27 | // We should commit transaction after every change 28 | commit(); 29 | } 30 | 31 | @Override 32 | public void registerRenamedPath(String oldPath, String newPath){ 33 | super.registerRenamedPath(oldPath, newPath); 34 | // We should commit transaction after every change 35 | commit(); 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/hudson/plugins/scm_sync_configuration/transactions/ScmTransaction.java: -------------------------------------------------------------------------------- 1 | package hudson.plugins.scm_sync_configuration.transactions; 2 | 3 | import java.io.File; 4 | import java.util.concurrent.Future; 5 | 6 | import hudson.plugins.scm_sync_configuration.JenkinsFilesHelper; 7 | import hudson.plugins.scm_sync_configuration.ScmSyncConfigurationPlugin; 8 | import hudson.plugins.scm_sync_configuration.model.ChangeSet; 9 | import hudson.plugins.scm_sync_configuration.model.WeightedMessage; 10 | 11 | /** 12 | * @author fcamblor 13 | */ 14 | public abstract class ScmTransaction { 15 | private final ChangeSet changeset; 16 | // Flag allowing to say if transaction will be asynchronous (default) or synchronous 17 | // Synchronous commit are useful during tests execution 18 | private final boolean synchronousCommit; 19 | 20 | protected ScmTransaction(){ 21 | this(false); 22 | } 23 | 24 | protected ScmTransaction(boolean synchronousCommit){ 25 | this.changeset = new ChangeSet(); 26 | this.synchronousCommit = synchronousCommit; 27 | } 28 | 29 | public void defineCommitMessage(WeightedMessage weightedMessage){ 30 | this.changeset.defineMessage(weightedMessage); 31 | } 32 | 33 | public void commit(){ 34 | Future future = ScmSyncConfigurationPlugin.getInstance().commitChangeset(changeset); 35 | if (synchronousCommit && future != null) { 36 | // Synchronous transactions should wait for the future to be fully processed 37 | try { 38 | future.get(); 39 | } catch (Exception e) { 40 | throw new RuntimeException(e); 41 | } 42 | } 43 | } 44 | 45 | public void registerPath(String path){ 46 | this.changeset.registerPath(path); 47 | } 48 | 49 | public void registerPathForDeletion(String path) { 50 | this.changeset.registerPathForDeletion(path); 51 | } 52 | 53 | public void registerRenamedPath(String oldPath, String newPath){ 54 | File newFile = JenkinsFilesHelper.buildFileFromPathRelativeToHudsonRoot(newPath); 55 | if (newFile.isDirectory()) { 56 | for (File f : ScmSyncConfigurationPlugin.getInstance().collectAllFilesForScm(newFile)) { 57 | String pathRelativeToRoot = JenkinsFilesHelper.buildPathRelativeToHudsonRoot(f); 58 | if (pathRelativeToRoot != null) { 59 | this.changeset.registerPath(pathRelativeToRoot); 60 | } 61 | } 62 | } else { 63 | this.changeset.registerPath(newPath); 64 | } 65 | if (oldPath != null) { 66 | this.changeset.registerPathForDeletion(oldPath); 67 | } 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /src/main/java/hudson/plugins/scm_sync_configuration/transactions/ThreadedTransaction.java: -------------------------------------------------------------------------------- 1 | package hudson.plugins.scm_sync_configuration.transactions; 2 | 3 | /** 4 | * This ScmTransaction implementation should be aimed at memorizing every changes made during a thread 5 | * transaction, then commiting changes in the end of the thread 6 | * @author fcamblor 7 | */ 8 | public class ThreadedTransaction extends ScmTransaction { 9 | 10 | public ThreadedTransaction(boolean synchronousCommit){ 11 | super(synchronousCommit); 12 | } 13 | 14 | public ThreadedTransaction(){ 15 | super(); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/hudson/plugins/scm_sync_configuration/utils/Checksums.java: -------------------------------------------------------------------------------- 1 | package hudson.plugins.scm_sync_configuration.utils; 2 | 3 | import com.google.common.io.ByteStreams; 4 | import com.google.common.io.Files; 5 | 6 | import java.io.File; 7 | import java.io.IOException; 8 | import java.util.zip.CRC32; 9 | import java.util.zip.Checksum; 10 | 11 | /** 12 | * @author fcamblor 13 | * Utility class allowing to provide easy access to jenkins files checksums 14 | */ 15 | public class Checksums { 16 | public static boolean fileAndByteArrayContentAreEqual(File file, byte[] content) throws IOException { 17 | if(!file.exists()){ 18 | return content == null || content.length == 0; 19 | } 20 | 21 | Checksum checksum = createChecksum(); 22 | long fileChecksum = Files.getChecksum(file, checksum); 23 | long contentChecksum = ByteStreams.getChecksum(ByteStreams.newInputStreamSupplier(content), checksum); 24 | return fileChecksum == contentChecksum; 25 | } 26 | 27 | private static Checksum createChecksum(){ 28 | return new CRC32(); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/hudson/plugins/scm_sync_configuration/xstream/migration/AbstractMigrator.java: -------------------------------------------------------------------------------- 1 | package hudson.plugins.scm_sync_configuration.xstream.migration; 2 | 3 | import hudson.plugins.scm_sync_configuration.scms.SCM; 4 | 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | import java.util.logging.Logger; 8 | 9 | import com.thoughtworks.xstream.converters.UnmarshallingContext; 10 | import com.thoughtworks.xstream.io.HierarchicalStreamReader; 11 | 12 | public abstract class AbstractMigrator implements ScmSyncConfigurationDataMigrator { 13 | 14 | public static final String SCM_REPOSITORY_URL_TAG = "scmRepositoryUrl"; 15 | public static final String SCM_TAG = "scm"; 16 | public static final String SCM_CLASS_ATTRIBUTE = "class"; 17 | public static final String SCM_NO_USER_COMMIT_MESSAGE = "noUserCommitMessage"; 18 | public static final String SCM_DISPLAY_STATUS = "displayStatus"; 19 | public static final String SCM_COMMIT_MESSAGE_PATTERN = "commitMessagePattern"; 20 | public static final String SCM_MANUAL_INCLUDES = "manualSynchronizationIncludes"; 21 | 22 | private static final Logger LOGGER = Logger.getLogger(AbstractMigrator.class.getName()); 23 | 24 | public TTO migrate(TFROM pojo){ 25 | TTO migratedPojo = createMigratedPojo(); 26 | 27 | migratedPojo.setScmRepositoryUrl( migrateScmRepositoryUrl(pojo.getScmRepositoryUrl()) ); 28 | migratedPojo.setScm( migrateScm(pojo.getScm()) ); 29 | 30 | return migratedPojo; 31 | } 32 | 33 | public TTO readScmSyncConfigurationPOJO( 34 | HierarchicalStreamReader reader, UnmarshallingContext context) { 35 | 36 | TTO pojo = createMigratedPojo(); 37 | 38 | String scmRepositoryUrl = null; 39 | String scmClassAttribute = null; 40 | String scmContent = null; 41 | boolean noUserCommitMessage = false; 42 | boolean displayStatus = true; 43 | String commitMessagePattern = "[message]"; 44 | List manualIncludes = null; 45 | 46 | while(reader.hasMoreChildren()){ 47 | reader.moveDown(); 48 | if(SCM_REPOSITORY_URL_TAG.equals(reader.getNodeName())){ 49 | scmRepositoryUrl = reader.getValue(); 50 | } else if(SCM_NO_USER_COMMIT_MESSAGE.equals(reader.getNodeName())){ 51 | noUserCommitMessage = Boolean.parseBoolean(reader.getValue()); 52 | } else if(SCM_DISPLAY_STATUS.equals(reader.getNodeName())){ 53 | displayStatus = Boolean.parseBoolean(reader.getValue()); 54 | } else if(SCM_TAG.equals(reader.getNodeName())){ 55 | scmClassAttribute = reader.getAttribute(SCM_CLASS_ATTRIBUTE); 56 | scmContent = reader.getValue(); 57 | } else if(SCM_COMMIT_MESSAGE_PATTERN.equals(reader.getNodeName())){ 58 | commitMessagePattern = reader.getValue(); 59 | } else if(SCM_MANUAL_INCLUDES.equals(reader.getNodeName())){ 60 | manualIncludes = new ArrayList(); 61 | while(reader.hasMoreChildren()){ 62 | reader.moveDown(); 63 | manualIncludes.add(reader.getValue()); 64 | reader.moveUp(); 65 | } 66 | } else { 67 | IllegalArgumentException iae = new IllegalArgumentException("Unknown tag : "+reader.getNodeName()); 68 | LOGGER.throwing(this.getClass().getName(), "readScmSyncConfigurationPOJO", iae); 69 | LOGGER.severe("Unknown tag : "+reader.getNodeName()); 70 | throw iae; 71 | } 72 | reader.moveUp(); 73 | } 74 | 75 | pojo.setScm(createSCMFrom(scmClassAttribute, scmContent)); 76 | pojo.setScmRepositoryUrl(scmRepositoryUrl); 77 | pojo.setNoUserCommitMessage(noUserCommitMessage); 78 | pojo.setDisplayStatus(displayStatus); 79 | pojo.setCommitMessagePattern(commitMessagePattern); 80 | pojo.setManualSynchronizationIncludes(manualIncludes); 81 | 82 | return pojo; 83 | } 84 | 85 | // Overridable 86 | protected String migrateScmRepositoryUrl(String scmRepositoryUrl){ 87 | if(scmRepositoryUrl == null){ 88 | return null; 89 | } else { 90 | return new String(scmRepositoryUrl); 91 | } 92 | } 93 | 94 | // Overridable 95 | protected SCM migrateScm(SCM scm){ 96 | if(scm == null){ 97 | return null; 98 | } else { 99 | return SCM.valueOf(scm.getClass().getName()); 100 | } 101 | } 102 | 103 | protected abstract TTO createMigratedPojo(); 104 | protected abstract SCM createSCMFrom(String clazz, String content); 105 | } 106 | -------------------------------------------------------------------------------- /src/main/java/hudson/plugins/scm_sync_configuration/xstream/migration/DefaultSSCPOJO.java: -------------------------------------------------------------------------------- 1 | package hudson.plugins.scm_sync_configuration.xstream.migration; 2 | 3 | import hudson.plugins.scm_sync_configuration.scms.SCM; 4 | 5 | import java.util.List; 6 | 7 | public class DefaultSSCPOJO implements ScmSyncConfigurationPOJO { 8 | 9 | private String scmRepositoryUrl; 10 | private SCM scm; 11 | private boolean noUserCommitMessage; 12 | private boolean displayStatus; 13 | private String commitMessagePattern; 14 | private List manualSynchronizationIncludes; 15 | 16 | public String getScmRepositoryUrl() { 17 | return scmRepositoryUrl; 18 | } 19 | public void setScmRepositoryUrl(String scmRepositoryUrl) { 20 | this.scmRepositoryUrl = scmRepositoryUrl; 21 | } 22 | public SCM getScm() { 23 | return scm; 24 | } 25 | public void setScm(SCM scm) { 26 | this.scm = scm; 27 | } 28 | public boolean isNoUserCommitMessage() { 29 | return noUserCommitMessage; 30 | } 31 | public void setNoUserCommitMessage(boolean noUserCommitMessage) { 32 | this.noUserCommitMessage = noUserCommitMessage; 33 | } 34 | public boolean isDisplayStatus() { 35 | return displayStatus; 36 | } 37 | public void setDisplayStatus(boolean displayStatus) { 38 | this.displayStatus = displayStatus; 39 | } 40 | 41 | public String getCommitMessagePattern() { 42 | return commitMessagePattern; 43 | } 44 | 45 | public void setCommitMessagePattern(String commitMessagePattern) { 46 | this.commitMessagePattern = commitMessagePattern; 47 | } 48 | 49 | public void setManualSynchronizationIncludes(List _manualSynchronizationIncludes){ 50 | this.manualSynchronizationIncludes = _manualSynchronizationIncludes; 51 | } 52 | 53 | public List getManualSynchronizationIncludes(){ 54 | return this.manualSynchronizationIncludes; 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/main/java/hudson/plugins/scm_sync_configuration/xstream/migration/ScmSyncConfigurationDataMigrator.java: -------------------------------------------------------------------------------- 1 | package hudson.plugins.scm_sync_configuration.xstream.migration; 2 | 3 | import com.thoughtworks.xstream.converters.UnmarshallingContext; 4 | import com.thoughtworks.xstream.io.HierarchicalStreamReader; 5 | 6 | /** 7 | * Migrator from old GlobalBuildStats POJO to later GlobalBuildStats POJO 8 | * @author fcamblor 9 | * @param 10 | * @param 11 | */ 12 | public interface ScmSyncConfigurationDataMigrator { 13 | public TTO migrate(TFROM pojo); 14 | public TTO readScmSyncConfigurationPOJO(HierarchicalStreamReader reader, UnmarshallingContext context); 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/hudson/plugins/scm_sync_configuration/xstream/migration/ScmSyncConfigurationPOJO.java: -------------------------------------------------------------------------------- 1 | package hudson.plugins.scm_sync_configuration.xstream.migration; 2 | 3 | import hudson.plugins.scm_sync_configuration.scms.SCM; 4 | 5 | import java.util.List; 6 | 7 | /** 8 | * Generic interface for ScmSyncConfiguration POJOs 9 | * @author fcamblor 10 | */ 11 | public interface ScmSyncConfigurationPOJO { 12 | public String getScmRepositoryUrl(); 13 | public void setScmRepositoryUrl(String scmRepositoryUrl); 14 | public SCM getScm(); 15 | public void setScm(SCM scm); 16 | public boolean isNoUserCommitMessage(); 17 | public void setNoUserCommitMessage(boolean noUserCommitMessage); 18 | public boolean isDisplayStatus(); 19 | public void setDisplayStatus(boolean displayStatus); 20 | public String getCommitMessagePattern(); 21 | public void setCommitMessagePattern(String commitMessagePattern); 22 | public List getManualSynchronizationIncludes(); 23 | public void setManualSynchronizationIncludes(List manualSynchronizationIncludes); 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/hudson/plugins/scm_sync_configuration/xstream/migration/ScmSyncConfigurationXStreamReader.java: -------------------------------------------------------------------------------- 1 | package hudson.plugins.scm_sync_configuration.xstream.migration; 2 | 3 | import com.thoughtworks.xstream.converters.UnmarshallingContext; 4 | import com.thoughtworks.xstream.io.HierarchicalStreamReader; 5 | 6 | /** 7 | * Behavior for ScmSyncConfiguration readers 8 | * @author fcamblor 9 | * @param 10 | */ 11 | public interface ScmSyncConfigurationXStreamReader { 12 | T readScmSyncConfigurationPOJO(HierarchicalStreamReader reader, UnmarshallingContext context); 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/hudson/plugins/scm_sync_configuration/xstream/migration/v0/InitialMigrator.java: -------------------------------------------------------------------------------- 1 | package hudson.plugins.scm_sync_configuration.xstream.migration.v0; 2 | 3 | import hudson.plugins.scm_sync_configuration.scms.SCM; 4 | import hudson.plugins.scm_sync_configuration.scms.ScmSyncNoSCM; 5 | import hudson.plugins.scm_sync_configuration.scms.ScmSyncSubversionSCM; 6 | import hudson.plugins.scm_sync_configuration.xstream.migration.AbstractMigrator; 7 | 8 | /** 9 | * Initial representation of scm-sync-configuration.xml file 10 | * @author fcamblor 11 | */ 12 | public class InitialMigrator extends AbstractMigrator { 13 | 14 | @Override 15 | protected V0ScmSyncConfigurationPOJO createMigratedPojo() { 16 | return new V0ScmSyncConfigurationPOJO(); 17 | } 18 | 19 | @Override 20 | public V0ScmSyncConfigurationPOJO migrate(V0ScmSyncConfigurationPOJO pojo) { 21 | throw new IllegalAccessError("migrate() method should never be called on InitialMigrator !"); 22 | } 23 | 24 | @Override 25 | protected SCM createSCMFrom(String classname, String content) { 26 | // No scm tag => no scm entered 27 | if(content == null){ 28 | return SCM.valueOf(ScmSyncNoSCM.class); 29 | } 30 | 31 | // Starting from here, scm tag was provided... 32 | 33 | // v0.0.2 of the plugin was representing SCM as an enum type 34 | // so "class" attribute was not present here 35 | if(classname == null){ 36 | // And the only SCM implementation in v0.0.2 was the subversion one 37 | return SCM.valueOf(ScmSyncSubversionSCM.class); 38 | // In v0.0.3 there wasn't any "version" attribute and the 39 | // SCM was not represented as an enum type anymore .. so the "class" attribute 40 | // will be present and will be useful to determine the SCM implementation to chose 41 | } else { 42 | // For backward compatibility 43 | if("hudson.plugins.scm_sync_configuration.scms.impl.ScmSyncSubversionSCM".equals(classname)){ 44 | classname = ScmSyncSubversionSCM.class.getName(); 45 | } else if("hudson.plugins.scm_sync_configuration.scms.impl.ScmSyncNoSCM".equals(classname)){ 46 | classname = ScmSyncNoSCM.class.getName(); 47 | } 48 | return SCM.valueOf(classname); 49 | } 50 | } 51 | 52 | } 53 | -------------------------------------------------------------------------------- /src/main/java/hudson/plugins/scm_sync_configuration/xstream/migration/v0/V0ScmSyncConfigurationPOJO.java: -------------------------------------------------------------------------------- 1 | package hudson.plugins.scm_sync_configuration.xstream.migration.v0; 2 | 3 | import hudson.plugins.scm_sync_configuration.xstream.migration.DefaultSSCPOJO; 4 | 5 | 6 | public class V0ScmSyncConfigurationPOJO extends DefaultSSCPOJO { 7 | 8 | } 9 | -------------------------------------------------------------------------------- /src/main/java/hudson/plugins/scm_sync_configuration/xstream/migration/v1/V0ToV1Migrator.java: -------------------------------------------------------------------------------- 1 | package hudson.plugins.scm_sync_configuration.xstream.migration.v1; 2 | 3 | import hudson.plugins.scm_sync_configuration.scms.SCM; 4 | import hudson.plugins.scm_sync_configuration.scms.ScmSyncNoSCM; 5 | import hudson.plugins.scm_sync_configuration.xstream.migration.AbstractMigrator; 6 | import hudson.plugins.scm_sync_configuration.xstream.migration.v0.V0ScmSyncConfigurationPOJO; 7 | 8 | /** 9 | * V1 Evolutions : 10 | * - Apparition of tag "version" valued to "1" in scm-sync-configuration root tag 11 | * - SCM implementation package moved from hudson.plugins.scm_sync_configuration.scms.impl to hudson.plugins.scm_sync_configuration.scms 12 | * @author fcamblor 13 | */ 14 | public class V0ToV1Migrator extends AbstractMigrator { 15 | 16 | @Override 17 | protected V1ScmSyncConfigurationPOJO createMigratedPojo() { 18 | return new V1ScmSyncConfigurationPOJO(); 19 | } 20 | 21 | @Override 22 | protected SCM createSCMFrom(String classname, String content) { 23 | if(content == null){ 24 | return SCM.valueOf(ScmSyncNoSCM.class); 25 | } else { 26 | return SCM.valueOf(classname); 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/hudson/plugins/scm_sync_configuration/xstream/migration/v1/V1ScmSyncConfigurationPOJO.java: -------------------------------------------------------------------------------- 1 | package hudson.plugins.scm_sync_configuration.xstream.migration.v1; 2 | 3 | import hudson.plugins.scm_sync_configuration.xstream.migration.DefaultSSCPOJO; 4 | 5 | 6 | public class V1ScmSyncConfigurationPOJO extends DefaultSSCPOJO { 7 | 8 | } 9 | -------------------------------------------------------------------------------- /src/main/resources/META-INF/plexus/components.xml: -------------------------------------------------------------------------------- 1 | 2 | 20 | 21 | 22 | 23 | 24 | org.apache.maven.scm.manager.ScmManager 25 | org.apache.maven.scm.manager.plexus.DefaultScmManager 26 | 27 | 28 | org.apache.maven.scm.provider.ScmProvider 29 | scmProviders 30 | 31 | 32 | 33 | 34 | 35 | org.apache.maven.scm.provider.ScmProvider 36 | svn 37 | org.apache.maven.scm.provider.svn.svnjava.SvnJavaScmProvider 38 | 39 | 40 | 41 | 42 | org.apache.maven.scm.provider.ScmProvider 43 | git 44 | hudson.plugins.scm_sync_configuration.scms.customproviders.git.gitexe.ScmSyncGitExeScmProvider 45 | 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /src/main/resources/hudson/plugins/scm_sync_configuration/Messages.properties: -------------------------------------------------------------------------------- 1 | ScmSyncConfigurationsPlugin.gitRepoUrlEmpty=Repository URL is required\! 2 | ScmSyncConfigurationsPlugin.gitRepoUrlInvalid=Please enter a valid repository URL. 3 | ScmSyncConfigurationsPlugin.gitRepoUrlInaccessible=Repository {0} is inaccessible. If you're sure it exists, verify that the OS user running Jenkins can actually access it. Check ssh keys, and verify that the OS user has user.name and user.email set. 4 | ScmSyncConfigurationsPlugin.gitRepoUrlWhitespaceWarning=Leading and trailing whitespace will be ignored. 5 | -------------------------------------------------------------------------------- /src/main/resources/hudson/plugins/scm_sync_configuration/ScmSyncConfigurationPlugin/config.jelly: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 |
49 |
50 |
51 | 52 | ${%Reload} 53 | 54 |
55 | 56 |
-------------------------------------------------------------------------------- /src/main/resources/hudson/plugins/scm_sync_configuration/ScmSyncConfigurationPlugin/config_fr.properties: -------------------------------------------------------------------------------- 1 | SCM\ Sync\ configuration=SCM Sync Configuration 2 | SCM=SCM 3 | Never\ bother\ me\ with\ commit\ messages=Ne jamais me d\u00E9ranger avec des messages de commit 4 | Display\ SCM\ Sync\ Status=Afficher le statut du SCM Sync 5 | Commit\ message\ pattern=Mod\u00E8le de message de commit 6 | Manual\ synchronization\ includes=Chemins synchronis\u00E9s manuellement 7 | Add\ new\ include=Ajouter un nouveau chemin 8 | Include=Chemin 9 | Delete\ include=Supprimer le chemin 10 | Reload\ config\ from\ SCM=Recharger la configuration depuis le SCM 11 | WARNING\ \:\ the\ Jenkins\ config\ will\ be\ reloaded\ from\ SCM=Attention : la configuration Jenkins va \u00EAtre recharg\u00E9e depuis le SCM 12 | Only\ file\ modifications\ are\ handled=Seules les modifications de fichier sont g\u00E9r\u00E9es 13 | File\ added\ or\ removed\ will\ not\ be\ handled=Les fichiers ajout\u00E9s ou supprim\u00E9s ne seront pas g\u00E9r\u00E9s 14 | Continue=Continuer 15 | Reload=Recharger 16 | -------------------------------------------------------------------------------- /src/main/resources/hudson/plugins/scm_sync_configuration/ScmSyncConfigurationPlugin/help/manualSynchronizationIncludes.jelly: -------------------------------------------------------------------------------- 1 | 2 |
3 | ${%List of ant-like includes allowing to specify additional files to synchronize with the repository}.
4 | ${%Includes should be case sensitive paths starting from your JENKINS_HOME directory, without / in the beginning; Use of wildcards} (${%* and **}) ${%is allowed}.
5 | ${%You can have a look at} ${%community shared includes in Jenkins wiki}, ${%feel free to share your owns on this page} !
6 | ${%Before creating new includes, you should be aware of some things} : 7 |
    8 |
  • 9 | ${%Avoid includes for big and updated-often files} : ${%otherwise, your jenkins instance will spend its CPU time to commit your file} 10 |
  • 11 |
  • 12 | ${%In order to be noticed at the right time, your files must be represented in Jenkins by a} Saveable, 13 | ${%most of them are, but who knows}... 14 |
  • 15 |
  • 16 | ${%Following includes are brought "out of the box" by scm-sync-configuration default includes} : 17 |
      18 | 19 |
    • ${include}
    • 20 |
      21 |
    22 |
  • 23 |
24 |
25 |
-------------------------------------------------------------------------------- /src/main/resources/hudson/plugins/scm_sync_configuration/ScmSyncConfigurationPlugin/help/manualSynchronizationIncludes_fr.properties: -------------------------------------------------------------------------------- 1 | List\ of\ ant-like\ includes\ allowing\ to\ specify\ additional\ files\ to\ synchronize\ with\ the\ repository=Liste de chemin \u00E0 la Ant, permettant de sp\u00E9cifier des fichiers suppl\u00E9mentaires qui seront synchronis\u00E9s avec le repository 2 | Includes\ should\ be\ case\ sensitive\ paths\ starting\ from\ your\ JENKINS_HOME\ directory,\ without\ /\ in\ the\ beginning;\ Use\ of\ wildcards=Les chemins doivent \u00EAtre sensibles \u00E0 la casse, bas\u00E9s depuis votre r\u00E9pertoire JENKINS_HOME, et ne d\u00E9marrant pas par un /; L''utilisation des wildcards 3 | *\ and\ **=* et ** 4 | is\ allowed=est autoris\u00E9 5 | You\ can\ have\ a\ look\ at=Vous pouvez jeter un oeil aux 6 | community\ shared\ includes\ in\ Jenkins\ wiki=chemin partag\u00E9s par la communaut\u00E9 dans le wiki Jenkins 7 | feel\ free\ to\ share\ your\ owns\ on\ this\ page=n''h\u00E9sitez pas \u00E0 partager les v\u00F4tres sur cette page 8 | Before\ creating\ new\ includes,\ you\ should\ be\ aware\ of\ some\ things=Avant de cr\u00E9er de nouveaux chemins, vous devriez \u00EAtre conscient de certaines contraintes 9 | Avoid\ includes\ for\ big\ and\ updated-often\ files=Evitez les chemins pour les gros fichiers ainsi que ceux mis \u00E0 jour souvent 10 | otherwise,\ your\ jenkins\ instance\ will\ spend\ its\ CPU\ time\ to\ commit\ your\ file=autrement, votre instance Jenkins va passer son temps CPU \u00E0 commiter votre fichier 11 | In\ order\ to\ be\ noticed\ at\ the\ right\ time,\ your\ files\ must\ be\ represented\ in\ Jenkins\ by\ a=Afin d''\u00EAtre notifi\u00E9 au bon moment, vos fichiers doivent correspondre, dans Jenkins, \u00E0 un 12 | most\ of\ them\ are,\ but\ who\ knows=la plupart le sont, mais qui sait 13 | Following\ includes\ are\ brought\ "out\ of\ the\ box"\ by\ scm-sync-configuration\ default\ includes=Les chemins suivants sont fournis par d\u00E9faut par le plugin scm-sync-configuration 14 | -------------------------------------------------------------------------------- /src/main/resources/hudson/plugins/scm_sync_configuration/ScmSyncConfigurationPlugin/scms/git/config.jelly: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /src/main/resources/hudson/plugins/scm_sync_configuration/ScmSyncConfigurationPlugin/scms/git/config_fr.properties: -------------------------------------------------------------------------------- 1 | Repository\ URL=URL du repository 2 | -------------------------------------------------------------------------------- /src/main/resources/hudson/plugins/scm_sync_configuration/ScmSyncConfigurationPlugin/scms/git/url-help.jelly: -------------------------------------------------------------------------------- 1 | 24 | 25 | 26 | 27 |
28 | ${%description.1}
29 | ${%description.2} 30 |
31 |
32 |
-------------------------------------------------------------------------------- /src/main/resources/hudson/plugins/scm_sync_configuration/ScmSyncConfigurationPlugin/scms/git/url-help.properties: -------------------------------------------------------------------------------- 1 | # The MIT License 2 | # 3 | # Copyright (c) 2004-2010, Sun Microsystems, Inc., Kohsuke Kawaguchi, Seiji Sogabe 4 | # 5 | # Permission is hereby granted, free of charge, to any person obtaining a copy 6 | # of this software and associated documentation files (the "Software"), to deal 7 | # in the Software without restriction, including without limitation the rights 8 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | # copies of the Software, and to permit persons to whom the Software is 10 | # furnished to do so, subject to the following conditions: 11 | # 12 | # The above copyright notice and this permission notice shall be included in 13 | # all copies or substantial portions of the Software. 14 | # 15 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | # THE SOFTWARE. 22 | 23 | description.1=Specify the git repository URL to synchronize your configuration files with, such as "git@github.com\:mycompany/jenkins-config.git" 24 | description.2=Note that, for the moment, you MUST reference your Git repository root 25 | -------------------------------------------------------------------------------- /src/main/resources/hudson/plugins/scm_sync_configuration/ScmSyncConfigurationPlugin/scms/git/url-help_fr.properties: -------------------------------------------------------------------------------- 1 | # The MIT License 2 | # 3 | # Copyright (c) 2004-2010, Sun Microsystems, Inc., Kohsuke Kawaguchi, Eric Lefevre-Ardant 4 | # 5 | # Permission is hereby granted, free of charge, to any person obtaining a copy 6 | # of this software and associated documentation files (the "Software"), to deal 7 | # in the Software without restriction, including without limitation the rights 8 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | # copies of the Software, and to permit persons to whom the Software is 10 | # furnished to do so, subject to the following conditions: 11 | # 12 | # The above copyright notice and this permission notice shall be included in 13 | # all copies or substantial portions of the Software. 14 | # 15 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | # THE SOFTWARE. 22 | 23 | description.1=Sp\u00E9cifiez l''url du repository Git vers lequel synchroniser vos fichiers de configuration, tel que "git@github.com\:mycompany/jenkins-config.git" 24 | description.2=A noter qu''il est pour le moment obligatoire de r\u00E9f\u00E9rencer la racine du repository 25 | -------------------------------------------------------------------------------- /src/main/resources/hudson/plugins/scm_sync_configuration/ScmSyncConfigurationPlugin/scms/none/config.jelly: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /src/main/resources/hudson/plugins/scm_sync_configuration/ScmSyncConfigurationPlugin/scms/svn/config.jelly: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/main/resources/hudson/plugins/scm_sync_configuration/ScmSyncConfigurationPlugin/scms/svn/config_fr.properties: -------------------------------------------------------------------------------- 1 | Repository\ URL=URL du repository 2 | -------------------------------------------------------------------------------- /src/main/resources/hudson/plugins/scm_sync_configuration/ScmSyncConfigurationPlugin/scms/svn/url-help.jelly: -------------------------------------------------------------------------------- 1 | 24 | 25 | 26 | 27 |
28 | ${%description.1} 29 |
30 | ${%description.2(rootURL)} 31 |
32 | ${%description.3} 33 |
34 |
35 |
-------------------------------------------------------------------------------- /src/main/resources/hudson/plugins/scm_sync_configuration/ScmSyncConfigurationPlugin/scms/svn/url-help.properties: -------------------------------------------------------------------------------- 1 | # The MIT License 2 | # 3 | # Copyright (c) 2004-2010, Sun Microsystems, Inc., Kohsuke Kawaguchi, Seiji Sogabe 4 | # 5 | # Permission is hereby granted, free of charge, to any person obtaining a copy 6 | # of this software and associated documentation files (the "Software"), to deal 7 | # in the Software without restriction, including without limitation the rights 8 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | # copies of the Software, and to permit persons to whom the Software is 10 | # furnished to do so, subject to the following conditions: 11 | # 12 | # The above copyright notice and this permission notice shall be included in 13 | # all copies or substantial portions of the Software. 14 | # 15 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | # THE SOFTWARE. 22 | 23 | description.1=Specify the subversion repository URL to synchronize your configuration files with, such as "http\://yourcompany.com/repos/hudson-config/" 24 | description.2=When you enter a URL, Jenkins automatically checks if it can access the repository If access requires authentication, it will ask you the necessary credentials. If you already have a working credential but would like to change it for other reasons, click this link and specify different credentials. 25 | description.3=Each time you enter a new repository URL, Jenkins will first synchronize all your configuration files with the repository. This process can take a while, depending on the amount of configuration files to synchronize. 26 | -------------------------------------------------------------------------------- /src/main/resources/hudson/plugins/scm_sync_configuration/ScmSyncConfigurationPlugin/scms/svn/url-help_fr.properties: -------------------------------------------------------------------------------- 1 | # The MIT License 2 | # 3 | # Copyright (c) 2004-2010, Sun Microsystems, Inc., Kohsuke Kawaguchi, Eric Lefevre-Ardant 4 | # 5 | # Permission is hereby granted, free of charge, to any person obtaining a copy 6 | # of this software and associated documentation files (the "Software"), to deal 7 | # in the Software without restriction, including without limitation the rights 8 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | # copies of the Software, and to permit persons to whom the Software is 10 | # furnished to do so, subject to the following conditions: 11 | # 12 | # The above copyright notice and this permission notice shall be included in 13 | # all copies or substantial portions of the Software. 14 | # 15 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | # THE SOFTWARE. 22 | 23 | description.1=Sp\u00E9cifiez l''URL du repository Subversion avec lequel synchronier vos fichiers de configuration, par exemple "http\://yourcompany.com/repos/hudson-config/" 24 | description.2=Quand vous entrez une URL, Jenkins v\u00E9rifie automatiquement s''il peut s''y connecter. Si l''acc\u00E8s n\u00E9cessite une authentification, il vous demandera les informations n\u00E9cessaires. Si vous disposez d\u00E9j\u00E0 d''informations d''identification qui marchent mais que vous voulez en changer, cliquez sur ce lien et renseignez des valeurs diff\u00E9rentes. 25 | description.3=A chaque fois que vous entrerez une nouvelle URL de repository, Jenkins commencera par synchroniser tous vos fichier de configuration avec le repository. Ce processus peut prendre plusieurs minutes, en fonction du nombre de fichier de configuration \u00E0 synchroniser. 26 | -------------------------------------------------------------------------------- /src/main/resources/hudson/plugins/scm_sync_configuration/extensions/ScmSyncConfigurationPageDecorator/footer.jelly: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 18 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 70 | 71 | 72 | 77 |
78 |
79 | 80 |
-------------------------------------------------------------------------------- /src/main/resources/hudson/plugins/scm_sync_configuration/reload.jelly: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 |

6 | ${%Config reloaded from} ${it.SCM.title}, url : ${it.scmUrl} 7 |

8 |

Modified files : ${it.filesModifiedByLastReload.size()}

9 |

10 |

    11 | 12 |
  • ${file}
  • 13 |
    14 |
15 |

16 |

Please reload Jenkins config from disk by clicking here

17 | 18 |
19 |
20 |
-------------------------------------------------------------------------------- /src/main/resources/index.jelly: -------------------------------------------------------------------------------- 1 |
2 | This plugin allows you to synchronize your hudson configuration files with an SCM, allowing you to specify a commit message every time a config file is modified. 3 |
-------------------------------------------------------------------------------- /src/main/webapp/help/commitMessagePattern-help.html: -------------------------------------------------------------------------------- 1 |
2 | Pattern of the message which will be commited.
3 | For example, if you need to add a prefix/suffix to every of your commit messages, 4 | you can do it by changing this message pattern.
5 | You can use following "special" strings in the pattern : 6 |
    7 |
  • `[message]` : Will be replaced by the generated commit message
  • 8 |
9 |

10 | For instance, defining a commit message pattern of "ISSUE-1234: [message]" will make following commit message :
11 | ISSUE-1234: Modification on file with following comment : Synchronization init 12 |
-------------------------------------------------------------------------------- /src/main/webapp/help/commitMessagePattern-help_fr.html: -------------------------------------------------------------------------------- 1 |
2 | Patron du message qui sera commité.
3 | Par exemple, si vous avez besoin d'ajouter un préfixe/suffixe à l'ensemble de vos messages de commit, 4 | vous pouvez le faire en changeant ce patron de message.
5 | Vous pouvez utiliser les chaînes "spéciales" suivantes dans le patron : 6 |
    7 |
  • `[message]` : Sera remplacé par le message généré pour le commit
  • 8 |
9 |

10 | Par exemple, en définissant un patron de commit à "ISSUE-1234: [message]", cela génèrera le message de commit suivant :
11 | ISSUE-1234: Modification on file with following comment : Synchronization init 12 |
-------------------------------------------------------------------------------- /src/main/webapp/help/displayStatus-help.html: -------------------------------------------------------------------------------- 1 |
2 | Displays a SCM Sync Configuration status health on the bottom of your Jenkins pages.
3 | It is generally useful to activate this in order to be aware of a synchronization problem 4 | (due, for instance, to repository credentials change) 5 |
-------------------------------------------------------------------------------- /src/main/webapp/help/displayStatus-help_fr.html: -------------------------------------------------------------------------------- 1 |
2 | Affiche un état de la dernière synchronisation avec le SCM en bas de chaque page de Jenkins.
3 | Il est généralement utile d'activer cela afin d'être alerté d'un problème de synchronisation 4 | (dû, par exemple, à un changement de credentials) 5 |
-------------------------------------------------------------------------------- /src/main/webapp/help/noUserCommitMessage-help.html: -------------------------------------------------------------------------------- 1 |
2 | If unchecked, everytime you change a synchronized configuration file via Jenkins UI, a 3 | prompt will be displayed allowing to specify a commit message for your modifications.
4 | By checking this checkbox, you will never be prompted for such a commit message. 5 |
-------------------------------------------------------------------------------- /src/main/webapp/help/noUserCommitMessage-help_fr.html: -------------------------------------------------------------------------------- 1 |
2 | Lorsque décoché, à chaque fois que vous modifierez un fichier de configuration synchronisé 3 | via l'UI de Jenkins, vous pourrez saisir un message de commit représentant vos modifications.
4 | En cochant cette case à cocher, vous n'aurez plus besoin de saisir ce message de commit. 5 |
-------------------------------------------------------------------------------- /src/main/webapp/help/reloadScmConfig-help.html: -------------------------------------------------------------------------------- 1 |
2 | Beware : Some of your Jenkins config files can be overriden by this reload.
3 | That is to say, if you want to get your repository configuration files back, you can do it by clicking this link.

4 | Following strategies will be applied : 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 31 | 32 | 33 | 34 | 35 | 38 | 39 | 40 |
Local (jenkins) fileRepository fileAction
XXXXXX (same as Jenkins one)Nothing
XXXYYY (different as Jenkins one)YYY will override XXX
XXXDoesn't exist 28 | Nothing (Jenkins file won't be removed)
29 | Note that it should never happen since as soon as you activate scm sync config, every of your config file should be commited to the repository 30 |
Doesn't existXXX 36 | XXX will be imported from repository
37 |
41 |
-------------------------------------------------------------------------------- /src/main/webapp/help/reloadScmConfig-help_fr.html: -------------------------------------------------------------------------------- 1 |
2 | Attention : Certaines de vos configurations Jenkins peuvent être écrasées par ce rechargement.
3 | En cliquant sur ce lien, vous rapatrierez la configuration de votre repository dans Jenkins.

4 | Les stratégies suivantes seront appliquées : 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 31 | 32 | 33 | 34 | 35 | 38 | 39 | 40 |
Fichier local (jenkins)Fichier du repositoryAction
XXXXXX (même contenu que celui de Jenkins)Rien
XXXYYY (contenu différent de celui de Jenkins)YYY écrasera XXX
XXXN'existe pas 28 | Rien (le fichier de Jenkins ne sera pas supprimé)
29 | Notez que ce cas ne devrait jamais arriver puisque dès que vous activez le plugin scm sync config, tous vos fichiers de configuration sont commités dans le repository 30 |
N'existe pasXXX 36 | XXX sera importé depuis le repository
37 |
41 |
-------------------------------------------------------------------------------- /src/main/webapp/help/scm-help.html: -------------------------------------------------------------------------------- 1 |
2 | Specify the repository where you want to sync jenkins config files to.
3 | If you select "None", SCM Sync configuration plugin won't be activated.
4 | Note that repository path must already exist in your repository (plugin won't create it for you). 5 |
-------------------------------------------------------------------------------- /src/main/webapp/help/scm-help_fr.html: -------------------------------------------------------------------------------- 1 |
2 | Spécifier le repository où vous souhaitez synchroniser les fichiers de configuration de Jenkins.
3 | Si vous sélectionnez "None", le plugin SCM Sync configuration ne sera pas activé.
4 | Notez que le chemin du repository doit exister dans votre repository (le plugin ne le créera pas pour vous). 5 |
-------------------------------------------------------------------------------- /src/test/java/hudson/plugins/scm_sync_configuration/basic/ScmSyncConfigurationBasicTest.java: -------------------------------------------------------------------------------- 1 | package hudson.plugins.scm_sync_configuration.basic; 2 | 3 | import static org.junit.Assert.assertEquals; 4 | import static org.junit.Assert.assertFalse; 5 | import static org.junit.Assert.assertNotNull; 6 | import static org.junit.Assert.assertNull; 7 | import static org.junit.Assert.assertTrue; 8 | import hudson.model.Hudson; 9 | import hudson.plugins.scm_sync_configuration.JenkinsFilesHelper; 10 | import hudson.plugins.scm_sync_configuration.util.ScmSyncConfigurationBaseTest; 11 | import hudson.plugins.test.utils.scms.ScmUnderTestSubversion; 12 | 13 | import java.io.File; 14 | 15 | import jenkins.model.Jenkins; 16 | 17 | import org.junit.Test; 18 | 19 | public class ScmSyncConfigurationBasicTest extends ScmSyncConfigurationBaseTest { 20 | 21 | public ScmSyncConfigurationBasicTest() { 22 | super(new ScmUnderTestSubversion()); 23 | } 24 | 25 | @Test 26 | public void shouldRetrieveMockedHudsonInstanceCorrectly() throws Throwable { 27 | Jenkins jenkins = Jenkins.getInstance(); 28 | assertNotNull("Jenkins instance must not be null", jenkins); 29 | assertFalse("Expected a mocked Jenkins instance", jenkins.getClass().equals(Jenkins.class) || jenkins.getClass().equals(Hudson.class)); 30 | } 31 | 32 | @Test 33 | public void shouldVerifyIfHudsonRootDirectoryExists() throws Throwable { 34 | Jenkins jenkins = Jenkins.getInstance(); 35 | File jenkinsRootDir = jenkins.getRootDir(); 36 | assertNotNull("Jenkins instance must not be null", jenkinsRootDir); 37 | assertTrue("$JENKINS_HOME must be an existing directory", jenkinsRootDir.isDirectory()); 38 | } 39 | 40 | @Test 41 | public void testPathesOutsideJenkisRoot () throws Exception { 42 | Jenkins jenkins = Jenkins.getInstance(); 43 | File rootDirectory = jenkins.getRootDir().getAbsoluteFile(); 44 | File parentDirectory = rootDirectory.getParentFile(); 45 | assertNull("File outside $JENKINS_HOME should return null", JenkinsFilesHelper.buildPathRelativeToHudsonRoot(parentDirectory)); 46 | assertNull("File outside $JENKINS_HOME should return null", JenkinsFilesHelper.buildPathRelativeToHudsonRoot(new File(parentDirectory, "foo.txt"))); 47 | } 48 | 49 | @Test 50 | public void testPathesInsideJenkisRoot () throws Exception { 51 | Jenkins jenkins = Jenkins.getInstance(); 52 | File rootDirectory = jenkins.getRootDir().getAbsoluteFile(); 53 | File pathUnderTest = new File(rootDirectory, "config.xml"); 54 | String result = JenkinsFilesHelper.buildPathRelativeToHudsonRoot(pathUnderTest); 55 | assertNotNull("File inside $JENKINS_HOME must not return null path", result); 56 | assertEquals("Path " + pathUnderTest + " should resolve properly", result, "config.xml"); 57 | pathUnderTest = new File(new File (rootDirectory, "someDir"), "foo.txt"); 58 | result = JenkinsFilesHelper.buildPathRelativeToHudsonRoot(pathUnderTest); 59 | assertNotNull("File inside $JENKINS_HOME must not return null path", result); 60 | assertEquals("Path " + pathUnderTest + " should resolve properly", result, "someDir/foo.txt"); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/test/java/hudson/plugins/scm_sync_configuration/data/CurrentVersionCompatibilityTest.java: -------------------------------------------------------------------------------- 1 | package hudson.plugins.scm_sync_configuration.data; 2 | 3 | import static org.hamcrest.CoreMatchers.equalTo; 4 | import static org.hamcrest.CoreMatchers.is; 5 | import static org.hamcrest.CoreMatchers.notNullValue; 6 | import static org.junit.Assert.assertThat; 7 | import static org.mockito.Matchers.notNull; 8 | import static org.powermock.api.mockito.PowerMockito.doNothing; 9 | import static org.powermock.api.mockito.PowerMockito.mockStatic; 10 | import hudson.XmlFile; 11 | import hudson.model.Saveable; 12 | import hudson.model.listeners.SaveableListener; 13 | import hudson.plugins.scm_sync_configuration.ScmSyncConfigurationPlugin; 14 | import hudson.plugins.scm_sync_configuration.scms.SCM; 15 | import hudson.plugins.scm_sync_configuration.scms.ScmSyncSubversionSCM; 16 | import hudson.plugins.scm_sync_configuration.util.ScmSyncConfigurationPluginBaseTest; 17 | import hudson.plugins.test.utils.PluginUtil; 18 | import hudson.plugins.test.utils.scms.ScmUnderTestSubversion; 19 | 20 | import org.junit.Test; 21 | import org.powermock.core.classloader.annotations.PrepareForTest; 22 | 23 | @PrepareForTest(SaveableListener.class) 24 | public class CurrentVersionCompatibilityTest extends ScmSyncConfigurationPluginBaseTest { 25 | 26 | public CurrentVersionCompatibilityTest() { 27 | super(new ScmUnderTestSubversion()); 28 | } 29 | 30 | protected String getHudsonRootBaseTemplate() { 31 | // Use default template directory... 32 | return super.getHudsonRootBaseTemplate(); 33 | } 34 | 35 | @Test 36 | public void shouldCurrentVersionPluginConfigurationFileLoadCorrectly() throws Throwable { 37 | ScmSyncConfigurationPlugin plugin = ScmSyncConfigurationPlugin.getInstance(); 38 | assertThat(plugin.getSCM(), is(notNullValue())); 39 | assertThat(plugin.getSCM().getId(), is(equalTo(ScmSyncSubversionSCM.class.getName()))); 40 | } 41 | 42 | @Test 43 | public void shouldCurrentVersionPluginConfigurationMigrationBeIdemPotent() throws Throwable { 44 | ScmSyncConfigurationPlugin plugin = ScmSyncConfigurationPlugin.getInstance(); 45 | 46 | // Plugin has been loaded : let's record scm & repository url 47 | String expectedRepositoryUrl = plugin.getScmRepositoryUrl(); 48 | SCM expectedScm = plugin.getSCM(); 49 | 50 | // Persisting data 51 | mockStatic(SaveableListener.class); 52 | doNothing().when(SaveableListener.class); SaveableListener.fireOnChange((Saveable)notNull(), (XmlFile)notNull()); 53 | plugin.save(); 54 | 55 | // Then reloading it... 56 | PluginUtil.loadPlugin(plugin); 57 | 58 | // Verifying repositoryUrl & SCM 59 | assertThat(plugin.getSCM().getId(), is(equalTo(expectedScm.getId()))); 60 | assertThat(plugin.getScmRepositoryUrl(), is(equalTo(expectedRepositoryUrl))); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/test/java/hudson/plugins/scm_sync_configuration/data/V0_0_2CompatibilityTest.java: -------------------------------------------------------------------------------- 1 | package hudson.plugins.scm_sync_configuration.data; 2 | 3 | import static org.hamcrest.CoreMatchers.equalTo; 4 | import static org.hamcrest.CoreMatchers.is; 5 | import static org.hamcrest.CoreMatchers.notNullValue; 6 | import static org.junit.Assert.assertThat; 7 | import static org.mockito.Matchers.notNull; 8 | import static org.powermock.api.mockito.PowerMockito.doNothing; 9 | import static org.powermock.api.mockito.PowerMockito.mockStatic; 10 | import hudson.XmlFile; 11 | import hudson.model.Saveable; 12 | import hudson.model.listeners.SaveableListener; 13 | import hudson.plugins.scm_sync_configuration.ScmSyncConfigurationPlugin; 14 | import hudson.plugins.scm_sync_configuration.scms.SCM; 15 | import hudson.plugins.scm_sync_configuration.scms.ScmSyncNoSCM; 16 | import hudson.plugins.scm_sync_configuration.scms.ScmSyncSubversionSCM; 17 | import hudson.plugins.scm_sync_configuration.util.ScmSyncConfigurationPluginBaseTest; 18 | import hudson.plugins.test.utils.PluginUtil; 19 | import hudson.plugins.test.utils.scms.ScmUnderTestSubversion; 20 | 21 | import org.junit.Test; 22 | import org.powermock.core.classloader.annotations.PrepareForTest; 23 | 24 | @PrepareForTest(SaveableListener.class) 25 | public class V0_0_2CompatibilityTest extends ScmSyncConfigurationPluginBaseTest { 26 | 27 | public V0_0_2CompatibilityTest() { 28 | super(new ScmUnderTestSubversion()); 29 | } 30 | 31 | protected String getHudsonRootBaseTemplate() { 32 | if("should0_0_2_pluginConfigurationFileShouldLoadCorrectly".equals(testName.getMethodName())){ 33 | return "hudsonRoot0.0.2BaseTemplate/"; 34 | } else if("should0_0_2_pluginConfigurationMigrationBeIdemPotent".equals(testName.getMethodName())){ 35 | return "hudsonRoot0.0.2BaseTemplate/"; 36 | } else if("should0_0_2_pluginEmptyConfigurationFileShouldLoadCorrectly".equals(testName.getMethodName())){ 37 | return "hudsonRoot0.0.2WithEmptyConfTemplate/"; 38 | } else { 39 | throw new IllegalArgumentException("Unsupported test name : "+testName); 40 | } 41 | } 42 | 43 | @Test 44 | // JENKINS-8453 related 45 | public void should0_0_2_pluginConfigurationFileShouldLoadCorrectly() throws Throwable { 46 | ScmSyncConfigurationPlugin plugin = ScmSyncConfigurationPlugin.getInstance(); 47 | assertThat(plugin.getSCM(), is(notNullValue())); 48 | assertThat(plugin.getSCM().getId(), is(equalTo(ScmSyncSubversionSCM.class.getName()))); 49 | assertThat(plugin.getScmRepositoryUrl(), is(equalTo("scm:svn:https://myrepo/synchronizedDirectory/"))); 50 | } 51 | 52 | @Test 53 | public void should0_0_2_pluginConfigurationMigrationBeIdemPotent() throws Throwable { 54 | ScmSyncConfigurationPlugin plugin = ScmSyncConfigurationPlugin.getInstance(); 55 | 56 | // Plugin has been loaded : let's record scm & repository url 57 | String expectedRepositoryUrl = plugin.getScmRepositoryUrl(); 58 | SCM expectedScm = plugin.getSCM(); 59 | 60 | // Persisting data 61 | mockStatic(SaveableListener.class); 62 | doNothing().when(SaveableListener.class); SaveableListener.fireOnChange((Saveable)notNull(), (XmlFile)notNull()); 63 | plugin.save(); 64 | 65 | // Then reloading it... 66 | PluginUtil.loadPlugin(plugin); 67 | 68 | // Verifying repositoryUrl & SCM 69 | assertThat(plugin.getSCM().getId(), is(equalTo(expectedScm.getId()))); 70 | assertThat(plugin.getScmRepositoryUrl(), is(equalTo(expectedRepositoryUrl))); 71 | } 72 | 73 | @Test 74 | public void should0_0_2_pluginEmptyConfigurationFileShouldLoadCorrectly() throws Throwable { 75 | ScmSyncConfigurationPlugin plugin = ScmSyncConfigurationPlugin.getInstance(); 76 | assertThat(plugin.getSCM(), is(notNullValue())); 77 | assertThat(plugin.getSCM().getId(), is(equalTo(ScmSyncNoSCM.class.getName()))); 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /src/test/java/hudson/plugins/scm_sync_configuration/data/V0_0_3CompatibilityTest.java: -------------------------------------------------------------------------------- 1 | package hudson.plugins.scm_sync_configuration.data; 2 | 3 | import static org.hamcrest.CoreMatchers.equalTo; 4 | import static org.hamcrest.CoreMatchers.is; 5 | import static org.hamcrest.CoreMatchers.notNullValue; 6 | import static org.junit.Assert.assertThat; 7 | import static org.mockito.Matchers.notNull; 8 | import static org.powermock.api.mockito.PowerMockito.doNothing; 9 | import static org.powermock.api.mockito.PowerMockito.mockStatic; 10 | import hudson.XmlFile; 11 | import hudson.model.Saveable; 12 | import hudson.model.listeners.SaveableListener; 13 | import hudson.plugins.scm_sync_configuration.ScmSyncConfigurationPlugin; 14 | import hudson.plugins.scm_sync_configuration.scms.SCM; 15 | import hudson.plugins.scm_sync_configuration.scms.ScmSyncSubversionSCM; 16 | import hudson.plugins.scm_sync_configuration.util.ScmSyncConfigurationPluginBaseTest; 17 | import hudson.plugins.test.utils.PluginUtil; 18 | import hudson.plugins.test.utils.scms.ScmUnderTestSubversion; 19 | 20 | import org.junit.Test; 21 | import org.powermock.core.classloader.annotations.PrepareForTest; 22 | 23 | @PrepareForTest(SaveableListener.class) 24 | public class V0_0_3CompatibilityTest extends ScmSyncConfigurationPluginBaseTest { 25 | 26 | public V0_0_3CompatibilityTest() { 27 | super(new ScmUnderTestSubversion()); 28 | } 29 | 30 | protected String getHudsonRootBaseTemplate() { 31 | return "hudsonRoot0.0.3BaseTemplate/"; 32 | } 33 | 34 | @Test 35 | // JENKINS-8453 related 36 | public void should0_0_3_pluginConfigurationFileShouldLoadCorrectly() throws Throwable { 37 | ScmSyncConfigurationPlugin plugin = ScmSyncConfigurationPlugin.getInstance(); 38 | assertThat(plugin.getSCM(), is(notNullValue())); 39 | assertThat(plugin.getSCM().getId(), is(equalTo(ScmSyncSubversionSCM.class.getName()))); 40 | } 41 | 42 | @Test 43 | public void should0_0_3_pluginConfigurationMigrationBeIdemPotent() throws Throwable { 44 | ScmSyncConfigurationPlugin plugin = ScmSyncConfigurationPlugin.getInstance(); 45 | 46 | // Plugin has been loaded : let's record scm & repository url 47 | String expectedRepositoryUrl = plugin.getScmRepositoryUrl(); 48 | SCM expectedScm = plugin.getSCM(); 49 | 50 | // Persisting data 51 | mockStatic(SaveableListener.class); 52 | doNothing().when(SaveableListener.class); SaveableListener.fireOnChange((Saveable)notNull(), (XmlFile)notNull()); 53 | plugin.save(); 54 | 55 | // Then reloading it... 56 | PluginUtil.loadPlugin(plugin); 57 | 58 | // Verifying repositoryUrl & SCM 59 | assertThat(plugin.getSCM().getId(), is(equalTo(expectedScm.getId()))); 60 | assertThat(plugin.getScmRepositoryUrl(), is(equalTo(expectedRepositoryUrl))); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/test/java/hudson/plugins/scm_sync_configuration/data/V0_0_4CompatibilityTest.java: -------------------------------------------------------------------------------- 1 | package hudson.plugins.scm_sync_configuration.data; 2 | 3 | import static org.hamcrest.CoreMatchers.equalTo; 4 | import static org.hamcrest.CoreMatchers.is; 5 | import static org.hamcrest.CoreMatchers.notNullValue; 6 | import static org.junit.Assert.assertThat; 7 | import hudson.plugins.scm_sync_configuration.ScmSyncConfigurationPlugin; 8 | import hudson.plugins.scm_sync_configuration.scms.ScmSyncNoSCM; 9 | import hudson.plugins.scm_sync_configuration.util.ScmSyncConfigurationPluginBaseTest; 10 | import hudson.plugins.test.utils.scms.ScmUnderTestSubversion; 11 | 12 | import org.junit.Test; 13 | 14 | public class V0_0_4CompatibilityTest extends ScmSyncConfigurationPluginBaseTest { 15 | 16 | public V0_0_4CompatibilityTest() { 17 | super(new ScmUnderTestSubversion()); 18 | } 19 | 20 | protected String getHudsonRootBaseTemplate() { 21 | return "hudsonRoot0.0.4WithEmptyConfTemplate/"; 22 | } 23 | 24 | @Test 25 | public void should0_0_4_pluginEmptyConfigurationFileShouldLoadCorrectly() throws Throwable { 26 | ScmSyncConfigurationPlugin plugin = ScmSyncConfigurationPlugin.getInstance(); 27 | assertThat(plugin.getSCM(), is(notNullValue())); 28 | assertThat(plugin.getSCM().getId(), is(equalTo(ScmSyncNoSCM.class.getName()))); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/test/java/hudson/plugins/scm_sync_configuration/repository/HudsonExtensionsGitTest.java: -------------------------------------------------------------------------------- 1 | package hudson.plugins.scm_sync_configuration.repository; 2 | 3 | import hudson.plugins.test.utils.scms.ScmUnderTestGit; 4 | 5 | public class HudsonExtensionsGitTest extends HudsonExtensionsTest { 6 | 7 | public HudsonExtensionsGitTest() { 8 | super(new ScmUnderTestGit()); 9 | } 10 | 11 | } 12 | -------------------------------------------------------------------------------- /src/test/java/hudson/plugins/scm_sync_configuration/repository/InitRepositoryGitTest.java: -------------------------------------------------------------------------------- 1 | package hudson.plugins.scm_sync_configuration.repository; 2 | 3 | import hudson.plugins.test.utils.scms.ScmUnderTestGit; 4 | 5 | 6 | 7 | public class InitRepositoryGitTest extends InitRepositoryTest { 8 | 9 | public InitRepositoryGitTest() { 10 | super(new ScmUnderTestGit()); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /src/test/java/hudson/plugins/scm_sync_configuration/repository/InitRepositorySubversionTest.java: -------------------------------------------------------------------------------- 1 | package hudson.plugins.scm_sync_configuration.repository; 2 | 3 | import hudson.plugins.test.utils.scms.ScmUnderTestSubversion; 4 | 5 | public class InitRepositorySubversionTest extends InitRepositoryTest { 6 | 7 | public InitRepositorySubversionTest() { 8 | super(new ScmUnderTestSubversion()); 9 | } 10 | 11 | } 12 | -------------------------------------------------------------------------------- /src/test/java/hudson/plugins/scm_sync_configuration/repository/InitRepositoryTest.java: -------------------------------------------------------------------------------- 1 | package hudson.plugins.scm_sync_configuration.repository; 2 | 3 | import hudson.plugins.scm_sync_configuration.ScmSyncConfigurationPlugin; 4 | import hudson.plugins.scm_sync_configuration.model.ScmContext; 5 | import hudson.plugins.scm_sync_configuration.scms.SCM; 6 | import hudson.plugins.scm_sync_configuration.util.ScmSyncConfigurationPluginBaseTest; 7 | import hudson.plugins.test.utils.scms.ScmUnderTest; 8 | import org.codehaus.plexus.util.FileUtils; 9 | import org.junit.Ignore; 10 | import org.junit.Test; 11 | import org.powermock.core.classloader.annotations.PrepareForTest; 12 | 13 | import java.io.File; 14 | 15 | import static org.hamcrest.CoreMatchers.*; 16 | import static org.junit.Assert.*; 17 | 18 | @PrepareForTest(SCM.class) 19 | public abstract class InitRepositoryTest extends ScmSyncConfigurationPluginBaseTest { 20 | 21 | protected InitRepositoryTest(ScmUnderTest scmUnderTest) { 22 | super(scmUnderTest); 23 | } 24 | 25 | @Test 26 | public void shouldNotInitializeAnyRepositoryWhenScmContextIsEmpty() throws Throwable { 27 | ScmContext emptyContext = new ScmContext(null, null); 28 | sscBusiness.init(emptyContext); 29 | assertThat(sscBusiness.scmCheckoutDirectorySettledUp(emptyContext), is(false)); 30 | 31 | emptyContext = new ScmContext(null, getSCMRepositoryURL()); 32 | sscBusiness.init(emptyContext); 33 | assertThat(sscBusiness.scmCheckoutDirectorySettledUp(emptyContext), is(false)); 34 | 35 | createSCMMock(null); 36 | assertThat(sscBusiness.scmCheckoutDirectorySettledUp(emptyContext), is(false)); 37 | 38 | assertStatusManagerIsNull(); 39 | } 40 | 41 | @Test 42 | @Ignore("Not yet implemented ! (it is difficult because svn list/log has not yet been implemented in svnjava impl") 43 | public void shouldInitializeLocalRepositoryWhenScmContextIsCorrentAndEvenIfScmDirectoryDoesntExist() throws Throwable { 44 | createSCMMock(); 45 | assertThat(sscBusiness.scmCheckoutDirectorySettledUp(scmContext), is(true)); 46 | } 47 | 48 | @Test 49 | public void shouldResetCheckoutConfigurationDirectoryWhenAsked() throws Throwable { 50 | // Initializing the repository... 51 | createSCMMock(); 52 | 53 | // After init, local checked out repository should exist 54 | assertThat(getCurrentScmSyncConfigurationCheckoutDirectory().exists(), is(true)); 55 | 56 | // Populating checkoutConfiguration directory .. 57 | File fileWhichShouldBeDeletedAfterReset = new File(getCurrentScmSyncConfigurationCheckoutDirectory().getAbsolutePath()+"/hello.txt"); 58 | assertThat(fileWhichShouldBeDeletedAfterReset.createNewFile(), is(true)); 59 | FileUtils.fileWrite(fileWhichShouldBeDeletedAfterReset.getAbsolutePath(), "Hello world !"); 60 | 61 | // Reseting the repository, without cleanup 62 | sscBusiness.initializeRepository(scmContext, false); 63 | assertThat(fileWhichShouldBeDeletedAfterReset.exists(), is(true)); 64 | 65 | // Reseting the repository with cleanup 66 | sscBusiness.initializeRepository(scmContext, true); 67 | assertThat(fileWhichShouldBeDeletedAfterReset.exists(), is(false)); 68 | 69 | assertStatusManagerIsOk(); 70 | } 71 | 72 | @Test 73 | public void shouldSynchronizeHudsonFiles() throws Throwable { 74 | // Initializing the repository... 75 | createSCMMock(); 76 | 77 | // Synchronizing hudson config files 78 | sscBusiness.synchronizeAllConfigs(ScmSyncConfigurationPlugin.AVAILABLE_STRATEGIES); 79 | 80 | verifyCurrentScmContentMatchesHierarchy("expected-scm-hierarchies/InitRepositoryTest.shouldSynchronizeHudsonFiles/"); 81 | 82 | assertStatusManagerIsOk(); 83 | } 84 | 85 | @Test 86 | public void shouldInitializeLocalRepositoryWhenScmContextIsCorrect() 87 | throws Throwable { 88 | createSCMMock(); 89 | assertThat(sscBusiness.scmCheckoutDirectorySettledUp(scmContext), is(true)); 90 | 91 | assertStatusManagerIsOk(); 92 | } 93 | 94 | } 95 | -------------------------------------------------------------------------------- /src/test/java/hudson/plugins/scm_sync_configuration/strategies/impl/JobConfigScmSyncStrategyTest.java: -------------------------------------------------------------------------------- 1 | package hudson.plugins.scm_sync_configuration.strategies.impl; 2 | 3 | import hudson.XmlFile; 4 | import hudson.model.Job; 5 | import hudson.plugins.scm_sync_configuration.ScmSyncConfigurationPlugin; 6 | import hudson.plugins.scm_sync_configuration.extensions.ScmSyncConfigurationSaveableListener; 7 | import hudson.plugins.scm_sync_configuration.util.ScmSyncConfigurationPluginBaseTest; 8 | import hudson.plugins.test.utils.scms.ScmUnderTestSubversion; 9 | import org.codehaus.plexus.PlexusContainerException; 10 | import org.codehaus.plexus.component.repository.exception.ComponentLookupException; 11 | import org.junit.Before; 12 | import org.junit.Test; 13 | import org.mockito.Mockito; 14 | 15 | import java.io.File; 16 | import java.io.IOException; 17 | 18 | import static org.mockito.Mockito.when; 19 | 20 | /** 21 | * @author fcamblor 22 | */ 23 | public class JobConfigScmSyncStrategyTest extends ScmSyncConfigurationPluginBaseTest { 24 | 25 | private ScmSyncConfigurationSaveableListener sscConfigurationSaveableListener; 26 | 27 | public JobConfigScmSyncStrategyTest() { 28 | super(new ScmUnderTestSubversion()); 29 | } 30 | 31 | @Before 32 | public void initObjectsUnderTests() throws Throwable{ 33 | this.sscConfigurationSaveableListener = new ScmSyncConfigurationSaveableListener(); 34 | } 35 | 36 | @Override 37 | protected String getHudsonRootBaseTemplate(){ 38 | return "jobConfigStrategyTemplate/"; 39 | } 40 | 41 | // Reproducing JENKINS-17545 42 | @Test 43 | public void shouldConfigInSubmodulesNotSynced() throws ComponentLookupException, PlexusContainerException, IOException { 44 | // Initializing the repository... 45 | createSCMMock(); 46 | 47 | // Synchronizing hudson config files 48 | sscBusiness.synchronizeAllConfigs(ScmSyncConfigurationPlugin.AVAILABLE_STRATEGIES); 49 | 50 | File subModuleConfigFile = new File(getCurrentHudsonRootDirectory() + "/jobs/fakeJob/modules/submodule/config.xml" ); 51 | 52 | // Creating fake new item 53 | Job mockedItem = Mockito.mock(Job.class); 54 | when(mockedItem.getRootDir()).thenReturn(subModuleConfigFile.getParentFile()); 55 | 56 | sscConfigurationSaveableListener.onChange(mockedItem, new XmlFile(subModuleConfigFile)); 57 | 58 | verifyCurrentScmContentMatchesHierarchy("expected-scm-hierarchies/JobConfigScmSyncStrategyTest.shouldConfigInSubmodulesNotSynced/"); 59 | 60 | assertStatusManagerIsOk(); 61 | } 62 | 63 | } 64 | -------------------------------------------------------------------------------- /src/test/java/hudson/plugins/scm_sync_configuration/util/ScmSyncConfigurationPluginBaseTest.java: -------------------------------------------------------------------------------- 1 | package hudson.plugins.scm_sync_configuration.util; 2 | 3 | import static org.hamcrest.CoreMatchers.notNullValue; 4 | import static org.hamcrest.CoreMatchers.nullValue; 5 | import static org.junit.Assert.assertThat; 6 | import hudson.plugins.scm_sync_configuration.ScmSyncConfigurationPlugin; 7 | import hudson.plugins.test.utils.scms.ScmUnderTest; 8 | 9 | // Class will start current ScmSyncConfigurationPlugin instance 10 | public abstract class ScmSyncConfigurationPluginBaseTest extends 11 | ScmSyncConfigurationBaseTest { 12 | 13 | protected ScmSyncConfigurationPluginBaseTest(ScmUnderTest scmUnderTest) { 14 | super(scmUnderTest); 15 | } 16 | 17 | public void setup() throws Throwable { 18 | super.setup(); 19 | 20 | // Let's start the plugin... 21 | ScmSyncConfigurationPlugin.getInstance().start(); 22 | } 23 | 24 | public void teardown() throws Throwable { 25 | // Stopping current plugin 26 | ScmSyncConfigurationPlugin.getInstance().stop(); 27 | 28 | super.teardown(); 29 | } 30 | 31 | protected void assertStatusManagerIsOk() { 32 | assertThat(sscBusiness.getScmSyncConfigurationStatusManager().getLastFail(), nullValue()); 33 | assertThat(sscBusiness.getScmSyncConfigurationStatusManager().getLastSuccess(), notNullValue()); 34 | } 35 | 36 | protected void assertStatusManagerIsNull() { 37 | assertThat(sscBusiness.getScmSyncConfigurationStatusManager().getLastFail(), nullValue()); 38 | assertThat(sscBusiness.getScmSyncConfigurationStatusManager().getLastSuccess(), nullValue()); 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /src/test/java/hudson/plugins/test/utils/DirectoryUtils.java: -------------------------------------------------------------------------------- 1 | package hudson.plugins.test.utils; 2 | 3 | import com.google.common.base.Predicate; 4 | import com.google.common.collect.Collections2; 5 | import org.apache.commons.io.FileUtils; 6 | 7 | import java.io.File; 8 | import java.io.IOException; 9 | import java.util.*; 10 | import java.util.logging.Logger; 11 | import java.util.regex.Pattern; 12 | 13 | public class DirectoryUtils { 14 | 15 | private static final Logger LOGGER = Logger.getLogger(DirectoryUtils.class.getName()); 16 | 17 | private static class FileComparator implements Comparator{ 18 | public int compare(File o1, File o2) { 19 | return o1.getName().compareTo(o2.getName()); 20 | } 21 | } 22 | private static final FileComparator FILE_COMPARATOR = new FileComparator(); 23 | 24 | public static List diffDirectories(File dir1, File dir2, final List excludePatterns, boolean recursive){ 25 | List diffs = new ArrayList(); 26 | 27 | if(!dir1.isDirectory() || !dir2.isDirectory()){ 28 | throw new IllegalArgumentException("dir1 & dir2 should be directories !"); 29 | } 30 | 31 | Predicate patternMatcherOnFilenamePredicate = new Predicate() { 32 | public boolean apply(File f) { 33 | for(Pattern pattern : excludePatterns) { 34 | if (pattern.matcher(f.getName()).matches()) { 35 | return false; 36 | } 37 | } 38 | return true; 39 | } 40 | }; 41 | 42 | List dir1Files = new ArrayList( Arrays.asList(dir1.listFiles()) ); 43 | List dir2Files = new ArrayList( Arrays.asList(dir2.listFiles()) ); 44 | 45 | Collections.sort(dir1Files, FILE_COMPARATOR); 46 | Collections.sort(dir2Files, FILE_COMPARATOR); 47 | 48 | Collection dir1FilesCollec = dir1Files; 49 | Collection dir2FilesCollec = dir2Files; 50 | if(excludePatterns != null){ 51 | dir1FilesCollec = Collections2.filter(dir1Files, patternMatcherOnFilenamePredicate); 52 | dir2FilesCollec = Collections2.filter(dir2Files, patternMatcherOnFilenamePredicate); 53 | } 54 | 55 | if(dir1FilesCollec.size() != dir2FilesCollec.size()){ 56 | diffs.add(String.format("Number of files in %s (%s) and %s (%s) differ !", dir1, dir1FilesCollec.size(), dir2, dir2FilesCollec.size())); 57 | return diffs; 58 | } 59 | 60 | 61 | Iterator dir1FileIter=dir1FilesCollec.iterator(); 62 | Iterator dir2FileIter=dir2FilesCollec.iterator(); 63 | for(int i=0; i content with <"+f2.getAbsolutePath()+"> content"); 81 | diffs.add("Error occured when comparing <"+f1.getAbsolutePath()+"> content with <"+f2.getAbsolutePath()+"> content"); 82 | } 83 | } 84 | if(recursive && f1.isDirectory()){ 85 | diffs.addAll(diffDirectories(f1, f2, excludePatterns, recursive)); 86 | } 87 | } 88 | 89 | return diffs; 90 | } 91 | 92 | } 93 | -------------------------------------------------------------------------------- /src/test/java/hudson/plugins/test/utils/PluginUtil.java: -------------------------------------------------------------------------------- 1 | package hudson.plugins.test.utils; 2 | 3 | import java.lang.reflect.InvocationTargetException; 4 | import java.lang.reflect.Method; 5 | 6 | import hudson.Plugin; 7 | 8 | public class PluginUtil { 9 | 10 | public static void loadPlugin(Plugin plugin) 11 | throws SecurityException, NoSuchMethodException, IllegalArgumentException, 12 | IllegalAccessException, InvocationTargetException { 13 | Method loadMethod = Plugin.class.getDeclaredMethod("load"); 14 | boolean loadMethodAccessibility = loadMethod.isAccessible(); 15 | loadMethod.setAccessible(true); 16 | loadMethod.invoke(plugin); 17 | loadMethod.setAccessible(loadMethodAccessibility); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/test/java/hudson/plugins/test/utils/scms/ScmUnderTest.java: -------------------------------------------------------------------------------- 1 | package hudson.plugins.test.utils.scms; 2 | 3 | import hudson.plugins.scm_sync_configuration.scms.SCM; 4 | 5 | import java.io.File; 6 | 7 | public interface ScmUnderTest { 8 | 9 | void initRepo(File path) throws Exception; 10 | 11 | String createUrl(String url); 12 | 13 | Class getClazz(); 14 | 15 | boolean useCredentials(); 16 | 17 | String getSuffixForTestFiles(); 18 | 19 | } 20 | -------------------------------------------------------------------------------- /src/test/java/hudson/plugins/test/utils/scms/ScmUnderTestGit.java: -------------------------------------------------------------------------------- 1 | package hudson.plugins.test.utils.scms; 2 | 3 | import hudson.plugins.scm_sync_configuration.scms.SCM; 4 | import hudson.plugins.scm_sync_configuration.scms.ScmSyncGitSCM; 5 | 6 | import java.io.File; 7 | 8 | public class ScmUnderTestGit implements ScmUnderTest { 9 | 10 | public void initRepo(File path) throws Exception { 11 | ProcessBuilder pb = new ProcessBuilder("git", "init", "--bare"); 12 | pb.directory(path); 13 | Process p = pb.start(); 14 | if (p.waitFor() != 0) { 15 | throw new Exception("Unable to init git repo in " + path.getAbsolutePath()); 16 | } 17 | } 18 | 19 | public String createUrl(String url) { 20 | return "scm:git:" + url; 21 | } 22 | 23 | public Class getClazz() { 24 | return ScmSyncGitSCM.class; 25 | } 26 | 27 | public boolean useCredentials() { 28 | return false; 29 | } 30 | 31 | public String getSuffixForTestFiles() { 32 | return ".git"; 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /src/test/java/hudson/plugins/test/utils/scms/ScmUnderTestSubversion.java: -------------------------------------------------------------------------------- 1 | package hudson.plugins.test.utils.scms; 2 | 3 | import hudson.plugins.scm_sync_configuration.scms.SCM; 4 | import hudson.plugins.scm_sync_configuration.scms.ScmSyncSubversionSCM; 5 | 6 | import java.io.File; 7 | 8 | import org.tmatesoft.svn.core.io.SVNRepositoryFactory; 9 | 10 | public class ScmUnderTestSubversion implements ScmUnderTest { 11 | 12 | public void initRepo(File path) throws Exception { 13 | SVNRepositoryFactory.createLocalRepository(path, true , false); 14 | } 15 | 16 | public String createUrl(String url) { 17 | return "scm:svn:file://" + url; 18 | } 19 | 20 | public Class getClazz() { 21 | return ScmSyncSubversionSCM.class; 22 | } 23 | 24 | public boolean useCredentials() { 25 | return true; 26 | } 27 | 28 | public String getSuffixForTestFiles() { 29 | return ".subversion"; 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /src/test/resources/HudsonExtensionsTest.shouldFileWhichHaveToBeInSCM/config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 1.339 4 | 2 5 | NORMAL 6 | true 7 | 8 | 9 | true 10 | 11 | Welcome ! 12 | 13 | 14 | 15 | 5 16 | 0 17 | 18 | 19 | 20 | All 21 | false 22 | false 23 | 24 | 25 | All 26 | 0 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /src/test/resources/HudsonExtensionsTest.shouldFileWhichHaveToBeInSCM/hudson.config.xml2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jenkinsci/scm-sync-configuration-plugin/16e5593cd1f866c68ec9a8d4a62db2c8e0bfe23b/src/test/resources/HudsonExtensionsTest.shouldFileWhichHaveToBeInSCM/hudson.config.xml2 -------------------------------------------------------------------------------- /src/test/resources/HudsonExtensionsTest.shouldFileWhichHaveToBeInSCM/hudson.scm.SubversionSCM.xml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jenkinsci/scm-sync-configuration-plugin/16e5593cd1f866c68ec9a8d4a62db2c8e0bfe23b/src/test/resources/HudsonExtensionsTest.shouldFileWhichHaveToBeInSCM/hudson.scm.SubversionSCM.xml -------------------------------------------------------------------------------- /src/test/resources/HudsonExtensionsTest.shouldFileWhichHaveToBeInSCM/jobs/config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | false 6 | 7 | 8 | true 9 | false 10 | false 11 | 12 | false 13 | true 14 | false 15 | false 16 | false 17 | false 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /src/test/resources/HudsonExtensionsTest.shouldFileWhichHaveToBeInSCM/jobs/myFolder/config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | false 6 | 7 | 8 | true 9 | false 10 | false 11 | 12 | false 13 | true 14 | false 15 | false 16 | false 17 | false 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /src/test/resources/HudsonExtensionsTest.shouldFileWhichHaveToBeInSCM/jobs/myFolder/jobs/myJob/config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | false 6 | 7 | 8 | true 9 | false 10 | false 11 | 12 | false 13 | true 14 | false 15 | false 16 | false 17 | false 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /src/test/resources/HudsonExtensionsTest.shouldFileWhichHaveToBeInSCM/jobs/myJob/config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | false 6 | 7 | 8 | true 9 | false 10 | false 11 | 12 | false 13 | true 14 | false 15 | false 16 | false 17 | false 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /src/test/resources/HudsonExtensionsTest.shouldFileWhichHaveToBeInSCM/jobs/myJob/config2.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | false 6 | 7 | 8 | true 9 | false 10 | false 11 | 12 | false 13 | true 14 | false 15 | false 16 | false 17 | false 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /src/test/resources/HudsonExtensionsTest.shouldFileWhichHaveToBeInSCM/nodeMonitors.xml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jenkinsci/scm-sync-configuration-plugin/16e5593cd1f866c68ec9a8d4a62db2c8e0bfe23b/src/test/resources/HudsonExtensionsTest.shouldFileWhichHaveToBeInSCM/nodeMonitors.xml -------------------------------------------------------------------------------- /src/test/resources/HudsonExtensionsTest.shouldFileWhichHaveToBeInSCM/scm-sync-configuration.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | scm:svn:https://myrepo/synchronizedDirectory/ 4 | 5 | -------------------------------------------------------------------------------- /src/test/resources/HudsonExtensionsTest.shouldFileWhichHaveToBeInSCM/toto/config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | false 6 | 7 | 8 | true 9 | false 10 | false 11 | 12 | false 13 | true 14 | false 15 | false 16 | false 17 | false 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /src/test/resources/HudsonExtensionsTest.shouldFileWhichHaveToBeInSCM/toto/hudson.config.xml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jenkinsci/scm-sync-configuration-plugin/16e5593cd1f866c68ec9a8d4a62db2c8e0bfe23b/src/test/resources/HudsonExtensionsTest.shouldFileWhichHaveToBeInSCM/toto/hudson.config.xml -------------------------------------------------------------------------------- /src/test/resources/expected-scm-hierarchies/HudsonExtensionsTest.shouldConfigModificationBeCorrectlyImpactedOnSCM/config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 1.339 4 | 2 5 | NORMAL 6 | true 7 | 8 | 9 | true 10 | 11 | Welcome ! 12 | 13 | 14 | 15 | 5 16 | 0 17 | 18 | 19 | 20 | All 21 | false 22 | false 23 | 24 | 25 | All 26 | 0 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /src/test/resources/expected-scm-hierarchies/HudsonExtensionsTest.shouldConfigModificationBeCorrectlyImpactedOnSCM/hudson.tasks.Shell.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | /bin/bash 5 | -------------------------------------------------------------------------------- /src/test/resources/expected-scm-hierarchies/HudsonExtensionsTest.shouldConfigModificationBeCorrectlyImpactedOnSCM/jobs/fakeJob/config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | false 6 | 7 | 8 | true 9 | false 10 | false 11 | 12 | false 13 | true 14 | false 15 | false 16 | false 17 | false 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /src/test/resources/expected-scm-hierarchies/HudsonExtensionsTest.shouldConfigModificationBeCorrectlyImpactedOnSCM/scm-sync-configuration.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | scm:svn:https://myrepo/synchronizedDirectory/ 4 | 5 | -------------------------------------------------------------------------------- /src/test/resources/expected-scm-hierarchies/HudsonExtensionsTest.shouldJobAddBeCorrectlyImpactedOnSCM/config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 1.339 4 | 2 5 | NORMAL 6 | true 7 | 8 | 9 | true 10 | 11 | Welcome ! 12 | 13 | 14 | 15 | 5 16 | 0 17 | 18 | 19 | 20 | All 21 | false 22 | false 23 | 24 | 25 | All 26 | 0 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /src/test/resources/expected-scm-hierarchies/HudsonExtensionsTest.shouldJobAddBeCorrectlyImpactedOnSCM/hudson.tasks.Shell.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | /bin/bash 5 | -------------------------------------------------------------------------------- /src/test/resources/expected-scm-hierarchies/HudsonExtensionsTest.shouldJobAddBeCorrectlyImpactedOnSCM/jobs/fakeJob/config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | false 6 | 7 | 8 | true 9 | false 10 | false 11 | 12 | false 13 | true 14 | false 15 | false 16 | false 17 | false 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /src/test/resources/expected-scm-hierarchies/HudsonExtensionsTest.shouldJobAddBeCorrectlyImpactedOnSCM/jobs/newFakeJob/config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | false 6 | 7 | 8 | true 9 | true 10 | false 11 | 12 | false 13 | true 14 | false 15 | true 16 | false 17 | false 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /src/test/resources/expected-scm-hierarchies/HudsonExtensionsTest.shouldJobAddBeCorrectlyImpactedOnSCM/scm-sync-configuration.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | scm:svn:https://myrepo/synchronizedDirectory/ 4 | 5 | -------------------------------------------------------------------------------- /src/test/resources/expected-scm-hierarchies/HudsonExtensionsTest.shouldJobDeleteBeCorrectlyImpactedOnSCM.git/config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 1.339 4 | 2 5 | NORMAL 6 | true 7 | 8 | 9 | true 10 | 11 | Welcome ! 12 | 13 | 14 | 15 | 5 16 | 0 17 | 18 | 19 | 20 | All 21 | false 22 | false 23 | 24 | 25 | All 26 | 0 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /src/test/resources/expected-scm-hierarchies/HudsonExtensionsTest.shouldJobDeleteBeCorrectlyImpactedOnSCM.git/hudson.tasks.Shell.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | /bin/bash 5 | -------------------------------------------------------------------------------- /src/test/resources/expected-scm-hierarchies/HudsonExtensionsTest.shouldJobDeleteBeCorrectlyImpactedOnSCM.git/scm-sync-configuration.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | scm:svn:https://myrepo/synchronizedDirectory/ 4 | 5 | -------------------------------------------------------------------------------- /src/test/resources/expected-scm-hierarchies/HudsonExtensionsTest.shouldJobDeleteBeCorrectlyImpactedOnSCM.subversion/config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 1.339 4 | 2 5 | NORMAL 6 | true 7 | 8 | 9 | true 10 | 11 | Welcome ! 12 | 13 | 14 | 15 | 5 16 | 0 17 | 18 | 19 | 20 | All 21 | false 22 | false 23 | 24 | 25 | All 26 | 0 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /src/test/resources/expected-scm-hierarchies/HudsonExtensionsTest.shouldJobDeleteBeCorrectlyImpactedOnSCM.subversion/hudson.tasks.Shell.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | /bin/bash 5 | -------------------------------------------------------------------------------- /src/test/resources/expected-scm-hierarchies/HudsonExtensionsTest.shouldJobDeleteBeCorrectlyImpactedOnSCM.subversion/jobs/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jenkinsci/scm-sync-configuration-plugin/16e5593cd1f866c68ec9a8d4a62db2c8e0bfe23b/src/test/resources/expected-scm-hierarchies/HudsonExtensionsTest.shouldJobDeleteBeCorrectlyImpactedOnSCM.subversion/jobs/.gitkeep -------------------------------------------------------------------------------- /src/test/resources/expected-scm-hierarchies/HudsonExtensionsTest.shouldJobDeleteBeCorrectlyImpactedOnSCM.subversion/scm-sync-configuration.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | scm:svn:https://myrepo/synchronizedDirectory/ 4 | 5 | -------------------------------------------------------------------------------- /src/test/resources/expected-scm-hierarchies/HudsonExtensionsTest.shouldJobDeleteWithTwoJobsBeCorrectlyImpactedOnSCM/config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 1.339 4 | 2 5 | NORMAL 6 | true 7 | 8 | 9 | true 10 | 11 | Welcome ! 12 | 13 | 14 | 15 | 5 16 | 0 17 | 18 | 19 | 20 | All 21 | false 22 | false 23 | 24 | 25 | All 26 | 0 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /src/test/resources/expected-scm-hierarchies/HudsonExtensionsTest.shouldJobDeleteWithTwoJobsBeCorrectlyImpactedOnSCM/hudson.tasks.Shell.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | /bin/bash 5 | -------------------------------------------------------------------------------- /src/test/resources/expected-scm-hierarchies/HudsonExtensionsTest.shouldJobDeleteWithTwoJobsBeCorrectlyImpactedOnSCM/jobs/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jenkinsci/scm-sync-configuration-plugin/16e5593cd1f866c68ec9a8d4a62db2c8e0bfe23b/src/test/resources/expected-scm-hierarchies/HudsonExtensionsTest.shouldJobDeleteWithTwoJobsBeCorrectlyImpactedOnSCM/jobs/.gitkeep -------------------------------------------------------------------------------- /src/test/resources/expected-scm-hierarchies/HudsonExtensionsTest.shouldJobDeleteWithTwoJobsBeCorrectlyImpactedOnSCM/jobs/newFakeJob/config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | MySecondJobs 5 | false 6 | 7 | 8 | true 9 | false 10 | false 11 | 12 | false 13 | true 14 | false 15 | false 16 | false 17 | false 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /src/test/resources/expected-scm-hierarchies/HudsonExtensionsTest.shouldJobDeleteWithTwoJobsBeCorrectlyImpactedOnSCM/scm-sync-configuration.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | scm:svn:https://myrepo/synchronizedDirectory/ 4 | 5 | -------------------------------------------------------------------------------- /src/test/resources/expected-scm-hierarchies/HudsonExtensionsTest.shouldJobModificationBeCorrectlyImpactedOnSCM/config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 1.339 4 | 2 5 | NORMAL 6 | true 7 | 8 | 9 | true 10 | 11 | Welcome ! 12 | 13 | 14 | 15 | 5 16 | 0 17 | 18 | 19 | 20 | All 21 | false 22 | false 23 | 24 | 25 | All 26 | 0 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /src/test/resources/expected-scm-hierarchies/HudsonExtensionsTest.shouldJobModificationBeCorrectlyImpactedOnSCM/hudson.tasks.Shell.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | /bin/bash 5 | -------------------------------------------------------------------------------- /src/test/resources/expected-scm-hierarchies/HudsonExtensionsTest.shouldJobModificationBeCorrectlyImpactedOnSCM/jobs/fakeJob/config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | My desc 5 | false 6 | 7 | 8 | true 9 | false 10 | false 11 | 12 | false 13 | true 14 | false 15 | false 16 | false 17 | false 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /src/test/resources/expected-scm-hierarchies/HudsonExtensionsTest.shouldJobModificationBeCorrectlyImpactedOnSCM/scm-sync-configuration.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | scm:svn:https://myrepo/synchronizedDirectory/ 4 | 5 | -------------------------------------------------------------------------------- /src/test/resources/expected-scm-hierarchies/HudsonExtensionsTest.shouldJobRenameBeCorrectlyImpactedOnSCM/config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 1.339 4 | 2 5 | NORMAL 6 | true 7 | 8 | 9 | true 10 | 11 | Welcome ! 12 | 13 | 14 | 15 | 5 16 | 0 17 | 18 | 19 | 20 | All 21 | false 22 | false 23 | 24 | 25 | All 26 | 0 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /src/test/resources/expected-scm-hierarchies/HudsonExtensionsTest.shouldJobRenameBeCorrectlyImpactedOnSCM/hudson.tasks.Shell.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | /bin/bash 5 | -------------------------------------------------------------------------------- /src/test/resources/expected-scm-hierarchies/HudsonExtensionsTest.shouldJobRenameBeCorrectlyImpactedOnSCM/jobs/newFakeJob/config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | false 6 | 7 | 8 | true 9 | false 10 | false 11 | 12 | false 13 | true 14 | false 15 | false 16 | false 17 | false 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /src/test/resources/expected-scm-hierarchies/HudsonExtensionsTest.shouldJobRenameBeCorrectlyImpactedOnSCM/scm-sync-configuration.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | scm:svn:https://myrepo/synchronizedDirectory/ 4 | 5 | -------------------------------------------------------------------------------- /src/test/resources/expected-scm-hierarchies/HudsonExtensionsTest.testAddJobNameStartingWithDash/config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 1.339 4 | 2 5 | NORMAL 6 | true 7 | 8 | 9 | true 10 | 11 | Welcome ! 12 | 13 | 14 | 15 | 5 16 | 0 17 | 18 | 19 | 20 | All 21 | false 22 | false 23 | 24 | 25 | All 26 | 0 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /src/test/resources/expected-scm-hierarchies/HudsonExtensionsTest.testAddJobNameStartingWithDash/hudson.tasks.Shell.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | /bin/bash 5 | -------------------------------------------------------------------------------- /src/test/resources/expected-scm-hierarchies/HudsonExtensionsTest.testAddJobNameStartingWithDash/jobs/-newFakeJob/config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | false 6 | 7 | 8 | true 9 | true 10 | false 11 | 12 | false 13 | true 14 | false 15 | true 16 | false 17 | false 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /src/test/resources/expected-scm-hierarchies/HudsonExtensionsTest.testAddJobNameStartingWithDash/jobs/fakeJob/config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | false 6 | 7 | 8 | true 9 | false 10 | false 11 | 12 | false 13 | true 14 | false 15 | false 16 | false 17 | false 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /src/test/resources/expected-scm-hierarchies/HudsonExtensionsTest.testAddJobNameStartingWithDash/scm-sync-configuration.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | scm:svn:https://myrepo/synchronizedDirectory/ 4 | 5 | -------------------------------------------------------------------------------- /src/test/resources/expected-scm-hierarchies/HudsonExtensionsTest.testAddJobNameWithBlanks/config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 1.339 4 | 2 5 | NORMAL 6 | true 7 | 8 | 9 | true 10 | 11 | Welcome ! 12 | 13 | 14 | 15 | 5 16 | 0 17 | 18 | 19 | 20 | All 21 | false 22 | false 23 | 24 | 25 | All 26 | 0 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /src/test/resources/expected-scm-hierarchies/HudsonExtensionsTest.testAddJobNameWithBlanks/hudson.tasks.Shell.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | /bin/bash 5 | -------------------------------------------------------------------------------- /src/test/resources/expected-scm-hierarchies/HudsonExtensionsTest.testAddJobNameWithBlanks/jobs/fakeJob/config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | false 6 | 7 | 8 | true 9 | false 10 | false 11 | 12 | false 13 | true 14 | false 15 | false 16 | false 17 | false 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /src/test/resources/expected-scm-hierarchies/HudsonExtensionsTest.testAddJobNameWithBlanks/jobs/new fake Job/config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | false 6 | 7 | 8 | true 9 | true 10 | false 11 | 12 | false 13 | true 14 | false 15 | true 16 | false 17 | false 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /src/test/resources/expected-scm-hierarchies/HudsonExtensionsTest.testAddJobNameWithBlanks/scm-sync-configuration.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | scm:svn:https://myrepo/synchronizedDirectory/ 4 | 5 | -------------------------------------------------------------------------------- /src/test/resources/expected-scm-hierarchies/InitRepositoryTest.shouldSynchronizeHudsonFiles/config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 1.339 4 | 2 5 | NORMAL 6 | true 7 | 8 | 9 | true 10 | 11 | Welcome ! 12 | 13 | 14 | 15 | 5 16 | 0 17 | 18 | 19 | 20 | All 21 | false 22 | false 23 | 24 | 25 | All 26 | 0 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /src/test/resources/expected-scm-hierarchies/InitRepositoryTest.shouldSynchronizeHudsonFiles/hudson.tasks.Shell.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | /bin/bash 5 | -------------------------------------------------------------------------------- /src/test/resources/expected-scm-hierarchies/InitRepositoryTest.shouldSynchronizeHudsonFiles/jobs/fakeJob/config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | false 6 | 7 | 8 | true 9 | false 10 | false 11 | 12 | false 13 | true 14 | false 15 | false 16 | false 17 | false 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /src/test/resources/expected-scm-hierarchies/InitRepositoryTest.shouldSynchronizeHudsonFiles/scm-sync-configuration.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | scm:svn:https://myrepo/synchronizedDirectory/ 4 | 5 | -------------------------------------------------------------------------------- /src/test/resources/expected-scm-hierarchies/JobConfigScmSyncStrategyTest.shouldConfigInSubmodulesNotSynced/config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 1.339 4 | 2 5 | NORMAL 6 | true 7 | 8 | 9 | true 10 | 11 | Welcome ! 12 | 13 | 14 | 15 | 5 16 | 0 17 | 18 | 19 | 20 | All 21 | false 22 | false 23 | 24 | 25 | All 26 | 0 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /src/test/resources/expected-scm-hierarchies/JobConfigScmSyncStrategyTest.shouldConfigInSubmodulesNotSynced/hudson.tasks.Shell.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | /bin/bash 5 | -------------------------------------------------------------------------------- /src/test/resources/expected-scm-hierarchies/JobConfigScmSyncStrategyTest.shouldConfigInSubmodulesNotSynced/jobs/fakeJob/config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | false 6 | 7 | 8 | true 9 | false 10 | false 11 | 12 | false 13 | true 14 | false 15 | false 16 | false 17 | false 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /src/test/resources/expected-scm-hierarchies/JobConfigScmSyncStrategyTest.shouldConfigInSubmodulesNotSynced/scm-sync-configuration.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | scm:svn:https://myrepo/synchronizedDirectory/ 4 | 5 | -------------------------------------------------------------------------------- /src/test/resources/hudsonRoot0.0.2BaseTemplate/config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 1.339 4 | 2 5 | NORMAL 6 | true 7 | 8 | 9 | true 10 | 11 | Welcome ! 12 | 13 | 14 | 15 | 5 16 | 0 17 | 18 | 19 | 20 | All 21 | false 22 | false 23 | 24 | 25 | All 26 | 0 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /src/test/resources/hudsonRoot0.0.2BaseTemplate/scm-sync-configuration.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | scm:svn:https://myrepo/synchronizedDirectory/ 4 | SUBVERSION 5 | 6 | -------------------------------------------------------------------------------- /src/test/resources/hudsonRoot0.0.2WithEmptyConfTemplate/config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 1.339 4 | 2 5 | NORMAL 6 | true 7 | 8 | 9 | true 10 | 11 | Welcome ! 12 | 13 | 14 | 15 | 5 16 | 0 17 | 18 | 19 | 20 | All 21 | false 22 | false 23 | 24 | 25 | All 26 | 0 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /src/test/resources/hudsonRoot0.0.2WithEmptyConfTemplate/scm-sync-configuration.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /src/test/resources/hudsonRoot0.0.3BaseTemplate/config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 1.339 4 | 2 5 | NORMAL 6 | true 7 | 8 | 9 | true 10 | 11 | Welcome ! 12 | 13 | 14 | 15 | 5 16 | 0 17 | 18 | 19 | 20 | All 21 | false 22 | false 23 | 24 | 25 | All 26 | 0 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /src/test/resources/hudsonRoot0.0.3BaseTemplate/scm-sync-configuration.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | scm:svn:https://myrepo/synchronizedDirectory/ 4 | 5 | -------------------------------------------------------------------------------- /src/test/resources/hudsonRoot0.0.4WithEmptyConfTemplate/config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 1.339 4 | 2 5 | NORMAL 6 | true 7 | 8 | 9 | true 10 | 11 | Welcome ! 12 | 13 | 14 | 15 | 5 16 | 0 17 | 18 | 19 | 20 | All 21 | false 22 | false 23 | 24 | 25 | All 26 | 0 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /src/test/resources/hudsonRoot0.0.4WithEmptyConfTemplate/scm-sync-configuration.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /src/test/resources/hudsonRootBaseTemplate/config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 1.339 4 | 2 5 | NORMAL 6 | true 7 | 8 | 9 | true 10 | 11 | Welcome ! 12 | 13 | 14 | 15 | 5 16 | 0 17 | 18 | 19 | 20 | All 21 | false 22 | false 23 | 24 | 25 | All 26 | 0 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /src/test/resources/hudsonRootBaseTemplate/hudson.tasks.Shell.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | /bin/bash 5 | -------------------------------------------------------------------------------- /src/test/resources/hudsonRootBaseTemplate/jobs/fakeJob/config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | false 6 | 7 | 8 | true 9 | false 10 | false 11 | 12 | false 13 | true 14 | false 15 | false 16 | false 17 | false 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /src/test/resources/hudsonRootBaseTemplate/scm-sync-configuration.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | scm:svn:https://myrepo/synchronizedDirectory/ 4 | 5 | -------------------------------------------------------------------------------- /src/test/resources/jobConfigStrategyTemplate/config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 1.339 4 | 2 5 | NORMAL 6 | true 7 | 8 | 9 | true 10 | 11 | Welcome ! 12 | 13 | 14 | 15 | 5 16 | 0 17 | 18 | 19 | 20 | All 21 | false 22 | false 23 | 24 | 25 | All 26 | 0 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /src/test/resources/jobConfigStrategyTemplate/hudson.tasks.Shell.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | /bin/bash 5 | -------------------------------------------------------------------------------- /src/test/resources/jobConfigStrategyTemplate/jobs/fakeJob/config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | false 6 | 7 | 8 | true 9 | false 10 | false 11 | 12 | false 13 | true 14 | false 15 | false 16 | false 17 | false 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /src/test/resources/jobConfigStrategyTemplate/jobs/fakeJob/modules/submodule/config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | false 6 | 7 | 8 | true 9 | false 10 | false 11 | 12 | false 13 | true 14 | false 15 | false 16 | false 17 | false 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /src/test/resources/jobConfigStrategyTemplate/scm-sync-configuration.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | scm:svn:https://myrepo/synchronizedDirectory/ 4 | 5 | --------------------------------------------------------------------------------