Author: maartenc
Date: Mon Dec 25 15:47:55 2006
New Revision: 490200
URL: http://svn.apache.org/viewvc?view=rev&rev=490200
Log:
IVY-353: ivy:retrieve should be able to create symlinks
Modified:
incubator/ivy/trunk/CHANGES.txt
incubator/ivy/trunk/src/java/fr/jayasoft/ivy/Ivy.java
incubator/ivy/trunk/src/java/fr/jayasoft/ivy/ant/IvyRetrieve.java
incubator/ivy/trunk/src/java/fr/jayasoft/ivy/util/FileUtil.java
incubator/ivy/trunk/test/java/fr/jayasoft/ivy/RetrieveTest.java
Modified: incubator/ivy/trunk/CHANGES.txt
URL:
http://svn.apache.org/viewvc/incubator/ivy/trunk/CHANGES.txt?view=diff&rev=490200&r1=490199&r2=490200
==============================================================================
--- incubator/ivy/trunk/CHANGES.txt (original)
+++ incubator/ivy/trunk/CHANGES.txt Mon Dec 25 15:47:55 2006
@@ -5,6 +5,10 @@
for detailed view of each issue, please consult http://jira.jayasoft.org/
+ version in SVN
+=====================================
+- IMPROVE: ivy:retrieve should be able to create symlinks (IVY-353) (thanks to
John Williams)
+
version 1.4.1 - 2006-11-09
=====================================
- IMPROVE: ability to rebuild all dependent projects from a leaf (IVY-101)
Modified: incubator/ivy/trunk/src/java/fr/jayasoft/ivy/Ivy.java
URL:
http://svn.apache.org/viewvc/incubator/ivy/trunk/src/java/fr/jayasoft/ivy/Ivy.java?view=diff&rev=490200&r1=490199&r2=490200
==============================================================================
--- incubator/ivy/trunk/src/java/fr/jayasoft/ivy/Ivy.java (original)
+++ incubator/ivy/trunk/src/java/fr/jayasoft/ivy/Ivy.java Mon Dec 25 15:47:55
2006
@@ -1914,6 +1914,9 @@
return retrieve(moduleId, confs, cache, destFilePattern,
destIvyPattern, artifactFilter, false, false);
}
public int retrieve(ModuleId moduleId, String[] confs, final File cache,
String destFilePattern, String destIvyPattern, Filter artifactFilter, boolean
sync, boolean useOrigin) {
+ return retrieve(moduleId, confs, cache, destFilePattern,
destIvyPattern, artifactFilter, sync, useOrigin, false);
+ }
+ public int retrieve(ModuleId moduleId, String[] confs, final File cache,
String destFilePattern, String destIvyPattern, Filter artifactFilter, boolean
sync, boolean useOrigin, boolean makeSymlinks) {
if (artifactFilter == null) {
artifactFilter = FilterHelper.NO_FILTER;
}
@@ -1956,7 +1959,11 @@
File destFile = new File((String)it2.next());
if (!_checkUpToDate || !upToDate(archive, destFile)) {
Message.verbose("\t\tto "+destFile);
- FileUtil.copy(archive, destFile, null);
+ if (makeSymlinks) {
+ FileUtil.symlink(archive, destFile, null, false);
+ } else {
+ FileUtil.copy(archive, destFile, null);
+ }
targetsCopied++;
} else {
Message.verbose("\t\tto "+destFile+" [NOT REQUIRED]");
Modified: incubator/ivy/trunk/src/java/fr/jayasoft/ivy/ant/IvyRetrieve.java
URL:
http://svn.apache.org/viewvc/incubator/ivy/trunk/src/java/fr/jayasoft/ivy/ant/IvyRetrieve.java?view=diff&rev=490200&r1=490199&r2=490200
==============================================================================
--- incubator/ivy/trunk/src/java/fr/jayasoft/ivy/ant/IvyRetrieve.java (original)
+++ incubator/ivy/trunk/src/java/fr/jayasoft/ivy/ant/IvyRetrieve.java Mon Dec
25 15:47:55 2006
@@ -19,6 +19,7 @@
private String _pattern;
private String _ivypattern = null;
private boolean _sync = false;
+ private boolean _symlink = false;
public String getPattern() {
return _pattern;
@@ -33,7 +34,7 @@
_pattern = getProperty(_pattern, getIvyInstance(),
"ivy.retrieve.pattern");
try {
Filter artifactFilter = getArtifactFilter();
- int targetsCopied =
getIvyInstance().retrieve(getResolvedModuleId(), splitConfs(getConf()),
getCache(), _pattern, _ivypattern, artifactFilter, _sync, isUseOrigin());
+ int targetsCopied =
getIvyInstance().retrieve(getResolvedModuleId(), splitConfs(getConf()),
getCache(), _pattern, _ivypattern, artifactFilter, _sync, isUseOrigin(),
_symlink);
boolean haveTargetsBeenCopied = targetsCopied > 0;
getProject().setProperty("ivy.nb.targets.copied",
String.valueOf(targetsCopied));
getProject().setProperty("ivy.targets.copied",
String.valueOf(haveTargetsBeenCopied));
@@ -53,5 +54,11 @@
public void setSync(boolean sync) {
_sync = sync;
}
-
+
+ /**
+ * Option to create symlinks instead of copying.
+ */
+ public void setSymlink(boolean symlink) {
+ _symlink = symlink;
+ }
}
Modified: incubator/ivy/trunk/src/java/fr/jayasoft/ivy/util/FileUtil.java
URL:
http://svn.apache.org/viewvc/incubator/ivy/trunk/src/java/fr/jayasoft/ivy/util/FileUtil.java?view=diff&rev=490200&r1=490199&r2=490200
==============================================================================
--- incubator/ivy/trunk/src/java/fr/jayasoft/ivy/util/FileUtil.java (original)
+++ incubator/ivy/trunk/src/java/fr/jayasoft/ivy/util/FileUtil.java Mon Dec 25
15:47:55 2006
@@ -11,6 +11,9 @@
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.PrintWriter;
+import java.io.StringWriter;
import java.io.OutputStream;
import java.net.URL;
import java.util.ArrayList;
@@ -20,6 +23,7 @@
import fr.jayasoft.ivy.url.URLHandlerRegistry;
+
/**
* @author x.hanin
*
@@ -27,7 +31,53 @@
public class FileUtil {
// tried some other values with empty files... seems to be the best one
(512 * 1024 is very bad)
// 8 * 1024 is also the size used by ant in its FileUtils... maybe they've
done more study about it ;-)
- private static final int BUFFER_SIZE = 8 * 1024;
+ private static final int BUFFER_SIZE = 8 * 1024;
+
+ public static void symlink(File src, File dest, CopyProgressListener l,
boolean overwrite) throws IOException {
+ try {
+ if (dest.exists()) {
+ if (!dest.isFile()) {
+ throw new IOException("impossible to copy: destination is
not a file: "+dest);
+ }
+ if (!overwrite) {
+ Message.verbose(dest+" already exists, nothing done");
+ return;
+ }
+ }
+ if (dest.getParentFile() != null) {
+ dest.getParentFile().mkdirs();
+ }
+
+ Runtime runtime = Runtime.getRuntime();
+ Process process = runtime.exec("ln", new String[] {"-s", "-f",
src.getAbsolutePath(), dest.getPath()});
+
+ if (process.waitFor() != 0) {
+ InputStream errorStream = process.getErrorStream();
+ InputStreamReader isr = new InputStreamReader(errorStream);
+ BufferedReader br = new BufferedReader(isr);
+
+ StringBuffer error = new StringBuffer();
+ String line;
+ while ((line = br.readLine()) != null) {
+ error.append(line);
+ error.append('\n');
+ }
+
+ throw new IOException("error symlinking " + src + " to " +
dest + ":\n" + error);
+ }
+ }
+ catch (IOException x) {
+ Message.verbose("symlink failed; falling back to copy");
+ StringWriter buffer = new StringWriter();
+ x.printStackTrace(new PrintWriter(buffer));
+ Message.debug(buffer.toString());
+ copy(src, dest, l, overwrite);
+ }
+ catch (InterruptedException x) {
+ Thread.currentThread().interrupt();
+ }
+ }
+
public static void copy(File src, File dest, CopyProgressListener l)
throws IOException {
copy(src, dest, l, false);
}
Modified: incubator/ivy/trunk/test/java/fr/jayasoft/ivy/RetrieveTest.java
URL:
http://svn.apache.org/viewvc/incubator/ivy/trunk/test/java/fr/jayasoft/ivy/RetrieveTest.java?view=diff&rev=490200&r1=490199&r2=490200
==============================================================================
--- incubator/ivy/trunk/test/java/fr/jayasoft/ivy/RetrieveTest.java (original)
+++ incubator/ivy/trunk/test/java/fr/jayasoft/ivy/RetrieveTest.java Mon Dec 25
15:47:55 2006
@@ -6,10 +6,12 @@
package fr.jayasoft.ivy;
import java.io.File;
+import java.io.IOException;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.taskdefs.Delete;
+import fr.jayasoft.ivy.filter.FilterHelper;
import fr.jayasoft.ivy.report.ResolveReport;
import fr.jayasoft.ivy.util.IvyPatternHelper;
@@ -63,6 +65,43 @@
pattern =
"build/test/retrieve/[module]/[conf]/[type]s/[artifact]-[revision].[ext]";
_ivy.retrieve(md.getModuleRevisionId().getModuleId(),
md.getConfigurationsNames(), _cache, pattern);
assertTrue(new File(IvyPatternHelper.substitute(pattern, "org1",
"mod1.2", "2.0", "mod1.2", "jar", "jar", "default")).exists());
+ }
+
+ public void testRetrieveWithSymlinks() throws Exception {
+ // mod1.1 depends on mod1.2
+ ResolveReport report = _ivy.resolve(new
File("test/repositories/1/org1/mod1.1/ivys/ivy-1.0.xml").toURL(),
+ null, new String[] {"*"}, _cache, null, true);
+ assertNotNull(report);
+ ModuleDescriptor md = report.getModuleDescriptor();
+ assertNotNull(md);
+
+ String pattern =
"build/test/retrieve/[module]/[conf]/[artifact]-[revision].[ext]";
+ _ivy.retrieve(md.getModuleRevisionId().getModuleId(),
md.getConfigurationsNames(), _cache, pattern, null, FilterHelper.NO_FILTER,
false, false, true);
+ assertLink(IvyPatternHelper.substitute(pattern, "org1", "mod1.2",
"2.0", "mod1.2", "jar", "jar", "default"));
+
+ pattern =
"build/test/retrieve/[module]/[conf]/[type]s/[artifact]-[revision].[ext]";
+ _ivy.retrieve(md.getModuleRevisionId().getModuleId(),
md.getConfigurationsNames(), _cache, pattern, null, FilterHelper.NO_FILTER,
false, false, true);
+ assertLink(IvyPatternHelper.substitute(pattern, "org1", "mod1.2",
"2.0", "mod1.2", "jar", "jar", "default"));
+ }
+
+ private void assertLink(String filename) throws IOException {
+ // if the OS is known to support symlink, check that the file is a
symlink,
+ // otherwise just check the file exist.
+
+ File file = new File(filename);
+ assertTrue("The file " + filename + " doesn't exist", file.exists());
+
+ String os = System.getProperty("os.name");
+ if (os.equals("Linux") ||
+ os.equals("Solaris") ||
+ os.equals("FreeBSD")) {
+ // these OS should support symnlink, so check that the file is
actually a symlink.
+ // this is done be checking that the canonical path is
different from the absolute
+ // path.
+ File absFile = file.getAbsoluteFile();
+ File canFile = file.getCanonicalFile();
+ assertFalse("The file " + filename + " isn't a symlink",
absFile.equals(canFile));
+ }
}
public void testRetrieveWithVariable() throws Exception {