mirror of https://github.com/apache/ant-ivy
readonly and overwrite handling during publish (IVY-83)
git-svn-id: https://svn.apache.org/repos/asf/incubator/ivy/trunk@484047 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
d63734290b
commit
7900db0c33
|
|
@ -1,3 +1,5 @@
|
|||
- NEW: overwrite attribute in the publish task now let force overwrite of read only files (IVY-83)
|
||||
- IMPROVE: better error message when publish fails due to readonly destination (IVY-83)
|
||||
- FIX: raise a clean error when a cyclic variable definition is found (IVY-75)
|
||||
- FIX: reinitiliase ant project instance at each new task to avoid using a bad ant project instance in some ide (like netbeans) (IVY-87)
|
||||
- FIX: ivy is now able to use simple ivy files in cache (doesn't need resolver info, use default one if no resolver is given) (IVY-86)
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ public interface DependencyResolver {
|
|||
ResolvedModuleRevision getDependency(DependencyDescriptor dd, ResolveData data) throws ParseException;
|
||||
DownloadReport download(Artifact[] artifacts, Ivy ivy, File cache);
|
||||
boolean exists(Artifact artifact);
|
||||
void publish(Artifact artifact, File src) throws IOException;
|
||||
void publish(Artifact artifact, File src, boolean overwrite) throws IOException;
|
||||
|
||||
/**
|
||||
* Reports last resolve failure as Messages
|
||||
|
|
|
|||
|
|
@ -1220,7 +1220,19 @@ public class Ivy implements TransferListener {
|
|||
* @return a collection of missing artifacts (those that are not published)
|
||||
* @throws ParseException
|
||||
*/
|
||||
public Collection publish(ModuleRevisionId mrid, String pubrevision, File cache, String srcArtifactPattern, String resolverName, String srcIvyPattern, boolean validate) throws IOException {
|
||||
public Collection publish(ModuleRevisionId mrid, String pubrevision, File cache, String srcArtifactPattern, String resolverName, String srcIvyPattern, boolean validate) throws IOException {
|
||||
return publish(mrid, pubrevision, cache, srcArtifactPattern, resolverName, srcIvyPattern, validate, false);
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param pubrevision
|
||||
* @param resolverName the name of a resolver to use for publication
|
||||
* @param srcArtifactPattern a pattern to find artifacts to publish with the given resolver
|
||||
* @param srcIvyPattern a pattern to find ivy file to publish, null if ivy file should not be published
|
||||
* @return a collection of missing artifacts (those that are not published)
|
||||
* @throws ParseException
|
||||
*/
|
||||
public Collection publish(ModuleRevisionId mrid, String pubrevision, File cache, String srcArtifactPattern, String resolverName, String srcIvyPattern, boolean validate, boolean overwrite) throws IOException {
|
||||
Message.info(":: publishing :: "+mrid);
|
||||
Message.verbose("\tvalidate = "+validate);
|
||||
long start = System.currentTimeMillis();
|
||||
|
|
@ -1261,13 +1273,13 @@ public class Ivy implements TransferListener {
|
|||
for (Iterator iter = artifactsSet.iterator(); iter.hasNext();) {
|
||||
Artifact artifact = (Artifact) iter.next();
|
||||
// 1) copy the artifact using src pattern and resolver
|
||||
if (!publish(artifact, srcArtifactPattern, resolver)) {
|
||||
if (!publish(artifact, srcArtifactPattern, resolver, overwrite)) {
|
||||
missing.add(artifact);
|
||||
}
|
||||
}
|
||||
if (srcIvyPattern != null) {
|
||||
Artifact artifact = new MDArtifact(md, "ivy", "ivy", "xml");
|
||||
if (!publish(artifact, srcIvyPattern, resolver)) {
|
||||
if (!publish(artifact, srcIvyPattern, resolver, overwrite)) {
|
||||
missing.add(artifact);
|
||||
}
|
||||
}
|
||||
|
|
@ -1275,17 +1287,14 @@ public class Ivy implements TransferListener {
|
|||
return missing;
|
||||
}
|
||||
|
||||
private boolean publish(Artifact artifact, String srcArtifactPattern, DependencyResolver resolver) {
|
||||
private boolean publish(Artifact artifact, String srcArtifactPattern, DependencyResolver resolver, boolean overwrite) throws IOException {
|
||||
File src = new File(IvyPatternHelper.substitute(srcArtifactPattern, artifact));
|
||||
if (src.exists()) {
|
||||
try {
|
||||
resolver.publish(artifact, src);
|
||||
return true;
|
||||
} catch (Exception ex) {
|
||||
Message.error("impossible to publish "+artifact+" with "+resolver.getName()+": "+ex.getMessage());
|
||||
}
|
||||
resolver.publish(artifact, src, overwrite);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@ public class IvyPublish extends IvyTask {
|
|||
private boolean _publishivy = true;
|
||||
private boolean _warnonmissing = true;
|
||||
private boolean _haltonmissing = true;
|
||||
private boolean _overwrite = false;
|
||||
|
||||
public File getCache() {
|
||||
return _cache;
|
||||
|
|
@ -183,7 +184,7 @@ public class IvyPublish extends IvyTask {
|
|||
deliver.execute();
|
||||
}
|
||||
|
||||
Collection missing = ivy.publish(mrid, _pubRevision, _cache, _artifactspattern, _publishResolverName, _publishivy?_srcivypattern:null, doValidate(ivy));
|
||||
Collection missing = ivy.publish(mrid, _pubRevision, _cache, _artifactspattern, _publishResolverName, _publishivy?_srcivypattern:null, doValidate(ivy), _overwrite);
|
||||
if (_warnonmissing) {
|
||||
for (Iterator iter = missing.iterator(); iter.hasNext();) {
|
||||
Artifact artifact = (Artifact)iter.next();
|
||||
|
|
@ -237,4 +238,10 @@ public class IvyPublish extends IvyTask {
|
|||
public void setHaltonmissing(boolean haltonmissing) {
|
||||
_haltonmissing = haltonmissing;
|
||||
}
|
||||
public boolean isOverwrite() {
|
||||
return _overwrite;
|
||||
}
|
||||
public void setOverwrite(boolean overwrite) {
|
||||
_overwrite = overwrite;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ import java.util.List;
|
|||
public interface Repository {
|
||||
Resource getResource(String source) throws IOException;
|
||||
void get(String source, File destination) throws IOException;
|
||||
void put(File source, String destination) throws IOException;
|
||||
void put(File source, String destination, boolean overwrite) throws IOException;
|
||||
/**
|
||||
* Returns the list of all resources names that can be found in the given
|
||||
* parent.
|
||||
|
|
|
|||
|
|
@ -46,17 +46,17 @@ public class FileRepository extends AbstractRepository {
|
|||
|
||||
public void get(String source, File destination) throws IOException {
|
||||
fireTransferInitiated(getResource(source), TransferEvent.REQUEST_GET);
|
||||
copy(getFile(source), destination);
|
||||
copy(getFile(source), destination, true);
|
||||
}
|
||||
|
||||
public void put(File source, String destination) throws IOException {
|
||||
public void put(File source, String destination, boolean overwrite) throws IOException {
|
||||
fireTransferInitiated(getResource(destination), TransferEvent.REQUEST_PUT);
|
||||
copy(source, getFile(destination));
|
||||
copy(source, getFile(destination), overwrite);
|
||||
}
|
||||
|
||||
private void copy(File src, File destination) throws IOException {
|
||||
private void copy(File src, File destination, boolean overwrite) throws IOException {
|
||||
try {
|
||||
FileUtil.copy(src, destination, _progress);
|
||||
FileUtil.copy(src, destination, _progress, overwrite);
|
||||
} catch (IOException ex) {
|
||||
fireTransferError(ex);
|
||||
throw ex;
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ public class URLRepository extends AbstractRepository {
|
|||
}
|
||||
}
|
||||
|
||||
public void put(File source, String destination) throws IOException {
|
||||
public void put(File source, String destination, boolean overwrite) throws IOException {
|
||||
throw new UnsupportedOperationException("URL repository is not able to put files for the moment");
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -103,9 +103,9 @@ public class CacheResolver extends FileSystemResolver {
|
|||
ensureConfigured();
|
||||
return super.exists(artifact);
|
||||
}
|
||||
public void publish(Artifact artifact, File src) throws IOException {
|
||||
public void publish(Artifact artifact, File src, boolean overwrite) throws IOException {
|
||||
ensureConfigured();
|
||||
super.publish(artifact, src);
|
||||
super.publish(artifact, src, overwrite);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -99,11 +99,11 @@ public class ChainResolver extends AbstractResolver {
|
|||
public List getResolvers() {
|
||||
return _chain;
|
||||
}
|
||||
public void publish(Artifact artifact, File src) throws IOException {
|
||||
public void publish(Artifact artifact, File src, boolean overwrite) throws IOException {
|
||||
if (_chain.isEmpty()) {
|
||||
throw new IllegalStateException("invalid chain resolver with no sub resolver");
|
||||
}
|
||||
((DependencyResolver)_chain.get(0)).publish(artifact, src);
|
||||
((DependencyResolver)_chain.get(0)).publish(artifact, src, overwrite);
|
||||
}
|
||||
public boolean isReturnFirst() {
|
||||
return _returnFirst;
|
||||
|
|
|
|||
|
|
@ -117,11 +117,11 @@ public class DualResolver extends AbstractResolver {
|
|||
public void setIvyResolver(DependencyResolver ivyResolver) {
|
||||
_ivyResolver = ivyResolver;
|
||||
}
|
||||
public void publish(Artifact artifact, File src) throws IOException {
|
||||
public void publish(Artifact artifact, File src, boolean overwrite) throws IOException {
|
||||
if ("ivy".equals(artifact.getType())) {
|
||||
_ivyResolver.publish(artifact, src);
|
||||
_ivyResolver.publish(artifact, src, overwrite);
|
||||
} else {
|
||||
_artifactResolver.publish(artifact, src);
|
||||
_artifactResolver.publish(artifact, src, overwrite);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -113,7 +113,7 @@ public class RepositoryResolver extends AbstractResourceResolver {
|
|||
return ivyTempFile.length();
|
||||
}
|
||||
|
||||
public void publish(Artifact artifact, File src) throws IOException {
|
||||
public void publish(Artifact artifact, File src, boolean overwrite) throws IOException {
|
||||
String destPattern;
|
||||
if ("ivy".equals(artifact.getType()) && !getIvyPatterns().isEmpty()) {
|
||||
destPattern = (String)getIvyPatterns().get(0);
|
||||
|
|
@ -121,7 +121,7 @@ public class RepositoryResolver extends AbstractResourceResolver {
|
|||
destPattern = (String)getArtifactPatterns().get(0);
|
||||
}
|
||||
String dest = IvyPatternHelper.substitute(destPattern, artifact);
|
||||
_repository.put(src, dest);
|
||||
_repository.put(src, dest, overwrite);
|
||||
Message.info("\tpublished "+artifact.getName()+" to "+dest);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -25,6 +25,16 @@ public class FileUtil {
|
|||
// 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;
|
||||
public static void copy(File src, File dest, CopyProgressListener l) throws IOException {
|
||||
copy(src, dest, l, false);
|
||||
}
|
||||
public static void copy(File src, File dest, CopyProgressListener l, boolean overwrite) throws IOException {
|
||||
if (dest.exists() && !dest.canWrite()) {
|
||||
if (overwrite && dest.isFile()) {
|
||||
dest.delete();
|
||||
} else {
|
||||
throw new IOException("impossible to copy: destination is not writable: "+dest);
|
||||
}
|
||||
}
|
||||
copy(new FileInputStream(src), dest, l);
|
||||
dest.setLastModified(src.lastModified());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,12 +5,15 @@
|
|||
*/
|
||||
package fr.jayasoft.ivy.ant;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileReader;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.apache.tools.ant.Project;
|
||||
import org.apache.tools.ant.taskdefs.Delete;
|
||||
import org.apache.tools.ant.taskdefs.Echo;
|
||||
|
||||
import fr.jayasoft.ivy.Ivy;
|
||||
import fr.jayasoft.ivy.ModuleDescriptor;
|
||||
|
|
@ -91,4 +94,82 @@ public class IvyPublishTest extends TestCase {
|
|||
assertEquals("1.2", md.getModuleRevisionId().getRevision());
|
||||
}
|
||||
|
||||
public void testReadonly() throws Exception {
|
||||
_project.setProperty("ivy.dep.file", "test/java/fr/jayasoft/ivy/ant/ivy-simple.xml");
|
||||
IvyResolve res = new IvyResolve();
|
||||
res.setProject(_project);
|
||||
res.execute();
|
||||
|
||||
_publish.setPubrevision("1.2");
|
||||
_publish.setResolver("1");
|
||||
File art = new File("build/test/publish/resolve-simple-1.2.jar");
|
||||
FileUtil.copy(new File("test/repositories/1/org1/mod1.1/jars/mod1.1-1.0.jar"), art, null);
|
||||
|
||||
Echo echo = new Echo();
|
||||
echo.setProject(_project);
|
||||
echo.setMessage("new version");
|
||||
echo.setFile(art);
|
||||
echo.execute();
|
||||
|
||||
File dest = new File("test/repositories/1/jayasoft/resolve-simple/jars/resolve-simple-1.2.jar");
|
||||
FileUtil.copy(new File("test/repositories/1/org1/mod1.1/jars/mod1.1-1.0.jar"),
|
||||
dest, null);
|
||||
|
||||
echo = new Echo();
|
||||
echo.setProject(_project);
|
||||
echo.setMessage("old version");
|
||||
echo.setFile(dest);
|
||||
echo.execute();
|
||||
|
||||
dest.setReadOnly();
|
||||
|
||||
try {
|
||||
_publish.execute();
|
||||
fail("by default, publish should fail when a readonly artifact already exist");
|
||||
} catch (Exception ex) {
|
||||
assertTrue(dest.exists());
|
||||
BufferedReader reader = new BufferedReader(new FileReader(dest));
|
||||
assertEquals("old version", reader.readLine());
|
||||
reader.close();
|
||||
}
|
||||
}
|
||||
|
||||
public void testOverwrite() throws Exception {
|
||||
_project.setProperty("ivy.dep.file", "test/java/fr/jayasoft/ivy/ant/ivy-simple.xml");
|
||||
IvyResolve res = new IvyResolve();
|
||||
res.setProject(_project);
|
||||
res.execute();
|
||||
|
||||
_publish.setPubrevision("1.2");
|
||||
_publish.setResolver("1");
|
||||
File art = new File("build/test/publish/resolve-simple-1.2.jar");
|
||||
FileUtil.copy(new File("test/repositories/1/org1/mod1.1/jars/mod1.1-1.0.jar"), art, null);
|
||||
|
||||
Echo echo = new Echo();
|
||||
echo.setProject(_project);
|
||||
echo.setMessage("new version");
|
||||
echo.setFile(art);
|
||||
echo.execute();
|
||||
|
||||
File dest = new File("test/repositories/1/jayasoft/resolve-simple/jars/resolve-simple-1.2.jar");
|
||||
FileUtil.copy(new File("test/repositories/1/org1/mod1.1/jars/mod1.1-1.0.jar"),
|
||||
dest, null);
|
||||
|
||||
echo = new Echo();
|
||||
echo.setProject(_project);
|
||||
echo.setMessage("old version");
|
||||
echo.setFile(dest);
|
||||
echo.execute();
|
||||
|
||||
dest.setReadOnly();
|
||||
|
||||
|
||||
_publish.setOverwrite(true);
|
||||
_publish.execute();
|
||||
assertTrue(dest.exists());
|
||||
BufferedReader reader = new BufferedReader(new FileReader(dest));
|
||||
assertEquals("new version", reader.readLine());
|
||||
reader.close();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -342,8 +342,8 @@ public class FileSystemResolverTest extends TestCase {
|
|||
Artifact ivyArtifact = new DefaultArtifact(mrid, new Date(), "ivy", "ivy", "xml");
|
||||
Artifact artifact = new DefaultArtifact(mrid, new Date(), "myartifact", "mytype", "myext");
|
||||
File src = new File("test/repositories/ivyconf.xml");
|
||||
resolver.publish(ivyArtifact, src);
|
||||
resolver.publish(artifact, src);
|
||||
resolver.publish(ivyArtifact, src, false);
|
||||
resolver.publish(artifact, src, false);
|
||||
|
||||
assertTrue(new File("test/repositories/1/myorg/mymodule/myrevision/ivy.xml").exists());
|
||||
assertTrue(new File("test/repositories/1/myorg/mymodule/mytypes/myartifact-myrevision.myext").exists());
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ public class MockResolver extends AbstractResolver {
|
|||
public DownloadReport download(Artifact[] artifacts, Ivy ivy, File cache) {
|
||||
return null;
|
||||
}
|
||||
public void publish(Artifact artifact, File src) throws IOException {
|
||||
public void publish(Artifact artifact, File src, boolean overwrite) throws IOException {
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue