From 416efefbcf991abd27d094aaa78e47cd37c19baf Mon Sep 17 00:00:00 2001 From: Eric Kesseler Date: Mon, 8 Jun 2015 13:46:32 +0200 Subject: [PATCH 1/2] JENKINS-5347 Fixed - Added use commit times on files --- src/main/java/hudson/scm/SubversionSCM.java | 24 +++++++++- .../hudson/scm/SubversionSCM/config.jelly | 3 ++ .../SubversionSCM/help-usingCommitTimes.html | 8 ++++ .../java/hudson/scm/SubversionSCMTest.java | 45 ++++++++++++++++++- 4 files changed, 77 insertions(+), 3 deletions(-) create mode 100644 src/main/resources/hudson/scm/SubversionSCM/help-usingCommitTimes.html diff --git a/src/main/java/hudson/scm/SubversionSCM.java b/src/main/java/hudson/scm/SubversionSCM.java index 0012c95eb..1941820ea 100755 --- a/src/main/java/hudson/scm/SubversionSCM.java +++ b/src/main/java/hudson/scm/SubversionSCM.java @@ -244,6 +244,7 @@ public class SubversionSCM extends SCM implements Serializable { private boolean ignoreDirPropChanges; private boolean filterChangelog; + private boolean useCommitTimes; /** * A cache of the svn:externals (keyed by project). @@ -334,7 +335,13 @@ public SubversionSCM(List locations, WorkspaceUpdater workspaceU public SubversionSCM(List locations, WorkspaceUpdater workspaceUpdater, SubversionRepositoryBrowser browser, String excludedRegions, String excludedUsers, String excludedRevprop, String excludedCommitMessages, String includedRegions, boolean ignoreDirPropChanges) { - this(locations, workspaceUpdater, browser, excludedRegions, excludedUsers, excludedRevprop, excludedCommitMessages, includedRegions, ignoreDirPropChanges, false, null); + this(locations, workspaceUpdater, browser, excludedRegions, excludedUsers, excludedRevprop, excludedCommitMessages, includedRegions, ignoreDirPropChanges, false, null, false); + } + + public SubversionSCM(List locations, WorkspaceUpdater workspaceUpdater, + SubversionRepositoryBrowser browser, String excludedRegions, String excludedUsers, String excludedRevprop, String excludedCommitMessages, + String includedRegions, boolean ignoreDirPropChanges, boolean useCommitTimes) { + this(locations, workspaceUpdater, browser, excludedRegions, excludedUsers, excludedRevprop, excludedCommitMessages, includedRegions, ignoreDirPropChanges, false, null, useCommitTimes); } @DataBoundConstructor @@ -342,7 +349,8 @@ public SubversionSCM(List locations, WorkspaceUpdater workspaceU SubversionRepositoryBrowser browser, String excludedRegions, String excludedUsers, String excludedRevprop, String excludedCommitMessages, String includedRegions, boolean ignoreDirPropChanges, boolean filterChangelog, - List additionalCredentials) { + List additionalCredentials, boolean useCommitTimes) { + this.useCommitTimes = useCommitTimes; for (Iterator itr = locations.iterator(); itr.hasNext(); ) { ModuleLocation ml = itr.next(); String remote = Util.fixEmptyAndTrim(ml.remote); @@ -664,6 +672,11 @@ public boolean isIgnoreDirPropChanges() { public boolean isFilterChangelog() { return filterChangelog; } + + @Exported + public boolean isUsingCommitTimes() { + return useCommitTimes; + } /** * Sets the SVN_REVISION_n and SVN_URL_n environment variables during the build. @@ -947,6 +960,7 @@ private synchronized Map> getProjectExternalsCache() { */ private static class CheckOutTask extends UpdateTask implements FileCallable> { private final UpdateTask task; + private final boolean isUsingCommitTimes; public CheckOutTask(Run build, SubversionSCM parent, ModuleLocation location, Date timestamp, TaskListener listener, EnvVars env) { this.authProvider = parent.createAuthenticationProvider(build.getParent(), location); @@ -955,6 +969,7 @@ public CheckOutTask(Run build, SubversionSCM parent, ModuleLocation locati this.location = location; this.revisions = build.getAction(RevisionParameterAction.class); this.task = parent.getWorkspaceUpdater().createTask(); + this.isUsingCommitTimes = parent.isUsingCommitTimes(); } public Set getUnauthenticatedRealms() { @@ -966,6 +981,11 @@ public Set getUnauthenticatedRealms() { public List invoke(File ws, VirtualChannel channel) throws IOException { clientManager = createClientManager(authProvider); + DefaultSVNOptions defaultSVNOptions = createDefaultSVNOptions(); + if (isUsingCommitTimes) { + defaultSVNOptions.setUseCommitTimes(isUsingCommitTimes); + } + clientManager = new SvnClientManager(SVNClientManager.newInstance(defaultSVNOptions, createSvnAuthenticationManager(authProvider))); manager = clientManager.getCore(); this.ws = ws; try { diff --git a/src/main/resources/hudson/scm/SubversionSCM/config.jelly b/src/main/resources/hudson/scm/SubversionSCM/config.jelly index 25ce742f7..60c2ae498 100644 --- a/src/main/resources/hudson/scm/SubversionSCM/config.jelly +++ b/src/main/resources/hudson/scm/SubversionSCM/config.jelly @@ -56,5 +56,8 @@ THE SOFTWARE. + + + diff --git a/src/main/resources/hudson/scm/SubversionSCM/help-usingCommitTimes.html b/src/main/resources/hudson/scm/SubversionSCM/help-usingCommitTimes.html new file mode 100644 index 000000000..3a76034cb --- /dev/null +++ b/src/main/resources/hudson/scm/SubversionSCM/help-usingCommitTimes.html @@ -0,0 +1,8 @@ +
+

If set Jenkins will set the file timestamps to the last commit time (of each file) when doing a checkout or an update. Otherwise Jenkins will set the current date as the timestamp of each file.

+

+ Normally the working copy files have timestamps that reflect the last time they were touched by any process. This is generally convenient for most build systems as they look at timestamps as a way of deciding which files need to be recompiled. + In other situations, however, it's sometimes nice for the working copy files to have timestamps that reflect the last time they were changed in the repository. The svn export command always places these 'last-commit timestamps' on trees that it produces. + See SVN Red Book for more information. +

+
\ No newline at end of file diff --git a/src/test/java/hudson/scm/SubversionSCMTest.java b/src/test/java/hudson/scm/SubversionSCMTest.java index 72ff5d80d..f14b5ad65 100644 --- a/src/test/java/hudson/scm/SubversionSCMTest.java +++ b/src/test/java/hudson/scm/SubversionSCMTest.java @@ -74,6 +74,9 @@ import static hudson.scm.SubversionSCM.compareSVNAuthentications; import static org.jvnet.hudson.test.recipes.PresetData.DataSet.ANONYMOUS_READONLY; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.not; +import static org.junit.Assert.assertThat; /** * @author Kohsuke Kawaguchi @@ -885,7 +888,7 @@ private void verifyChangelogFilter(boolean shouldFilterLog) throws Exception, File repo = new CopyExisting(getClass().getResource("JENKINS-10449.zip")).allocate(); SubversionSCM scm = new SubversionSCM(ModuleLocation.parse(new String[]{"file://" + repo.toURI().toURL().getPath()}, new String[]{"."},null,null), - new UpdateUpdater(), null, "/z.*", "", "", "", "", false, shouldFilterLog, null); + new UpdateUpdater(), null, "/z.*", "", "", "", "", false, shouldFilterLog, null, false); FreeStyleProject p = createFreeStyleProject(String.format("testFilterChangelog-%s", shouldFilterLog)); p.setScm(scm); @@ -1706,4 +1709,44 @@ private void invokeTestPollingExternalsForFile() throws Exception { // should detect change assertTrue(p.poll(StreamTaskListener.fromStdout()).hasChanges()); } + + /** + * Test related to https://issues.jenkins-ci.org/browse/JENKINS-5347 + * + * @throws Throwable + */ + public void testUseCommitTimes() throws Throwable { + // Given a subversion workspace where the commit times should be used + // When the workspace is checked out + // Then verify that the last modified time stamp of the format file is 2010-12-31 + + FreeStyleProject p = createFreeStyleProject(); + File repo = new CopyExisting(getClass().getResource("small.zip")).allocate(); + SubversionSCM scm = new SubversionSCM(ModuleLocation.parse(new String[]{"file://" + repo.toURI().toURL().getPath()}, + new String[]{"."}, null, null), new UpdateUpdater(), null, "/z.*", "", "", "", "", false, false, null, true); + p.setScm(scm); + FreeStyleBuild b = assertBuildStatusSuccess(p.scheduleBuild2(0, new Cause.UserIdCause()).get()); + // Using long matching to prevent Timezone issues, divided by 1000 as some OS does not return the exact milliseconds + assertThat(b.getWorkspace().child("b").lastModified() / 1000, is(1293845528l)); + } + + /** + * Test related to https://issues.jenkins-ci.org/browse/JENKINS-5347 + * + * @throws Throwable + */ + public void testNotUseCommitTimes() throws Throwable { + // Given a subversion workspace where the commit times should NOT be used + // When the workspace is checked out + // Then verify that the last modified time stamp of the format file NOT is 2011-01-01 + + FreeStyleProject p = createFreeStyleProject(); + File repo = new CopyExisting(getClass().getResource("small.zip")).allocate(); + SubversionSCM scm = new SubversionSCM(ModuleLocation.parse(new String[]{"file://" + repo.toURI().toURL().getPath()}, + new String[]{"."}, null, null), new UpdateUpdater(), null, "/z.*", "", "", "", "", false, false, null, false); + p.setScm(scm); + FreeStyleBuild b = assertBuildStatusSuccess(p.scheduleBuild2(0, new Cause.UserIdCause()).get()); + // Using long matching to prevent Timezone issues, divided by 1000 as some OS does not return the exact milliseconds + assertThat(b.getWorkspace().child("b").lastModified() / 1000, not(is(1293845528l))); + } } From d91475a73f1a8fa101ac6a35f16bdf783343f234 Mon Sep 17 00:00:00 2001 From: Eric Kesseler Date: Mon, 11 Jan 2016 10:18:07 +0100 Subject: [PATCH 2/2] JENKINS-5347 Fixed - Added use commit times on files - use @Issue Annotation --- src/test/java/hudson/scm/SubversionSCMTest.java | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/test/java/hudson/scm/SubversionSCMTest.java b/src/test/java/hudson/scm/SubversionSCMTest.java index 2bfb2c096..c01dfc97d 100644 --- a/src/test/java/hudson/scm/SubversionSCMTest.java +++ b/src/test/java/hudson/scm/SubversionSCMTest.java @@ -51,6 +51,7 @@ import org.dom4j.io.DOMReader; import org.junit.Test; import org.jvnet.hudson.test.*; +import org.jvnet.hudson.test.Issue; import org.jvnet.hudson.test.HudsonHomeLoader.CopyExisting; import org.jvnet.hudson.test.recipes.PresetData; import org.tmatesoft.svn.core.*; @@ -61,7 +62,6 @@ import org.tmatesoft.svn.core.wc.SVNCommitClient; import org.tmatesoft.svn.core.wc.SVNRevision; import org.tmatesoft.svn.core.wc.SVNStatus; -import org.tmatesoft.svn.core.wc.SVNWCUtil; import java.io.*; import java.net.MalformedURLException; @@ -73,10 +73,9 @@ import java.util.concurrent.Future; import static hudson.scm.SubversionSCM.compareSVNAuthentications; -import static org.jvnet.hudson.test.recipes.PresetData.DataSet.ANONYMOUS_READONLY; -import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.not; import static org.junit.Assert.assertThat; +import static org.jvnet.hudson.test.recipes.PresetData.DataSet.ANONYMOUS_READONLY; /** * @author Kohsuke Kawaguchi @@ -1711,10 +1710,11 @@ private void invokeTestPollingExternalsForFile() throws Exception { } /** - * Test related to https://issues.jenkins-ci.org/browse/JENKINS-5347 + * Test using commit times * * @throws Throwable */ + @Issue("JENKINS-5347") public void testUseCommitTimes() throws Throwable { // Given a subversion workspace where the commit times should be used // When the workspace is checked out @@ -1731,10 +1731,11 @@ public void testUseCommitTimes() throws Throwable { } /** - * Test related to https://issues.jenkins-ci.org/browse/JENKINS-5347 + * Test not using commit times * * @throws Throwable */ + @Issue("JENKINS-5347") public void testNotUseCommitTimes() throws Throwable { // Given a subversion workspace where the commit times should NOT be used // When the workspace is checked out