Updated new packager resolver to use Ant API instead of command-line and updated the packager-stylesheet to make it work on windows (IVY-829)

git-svn-id: https://svn.apache.org/repos/asf/ant/ivy/core/trunk@678326 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Maarten Coene 2008-07-20 21:45:02 +00:00
parent 2667a06a31
commit dce2f45c16
8 changed files with 66 additions and 157 deletions

View File

@ -41,17 +41,19 @@
<artifact name="ivy" type="source" ext="jar" conf="source"/>
</publications>
<dependencies>
<dependency org="ant" name="ant" rev="1.6" conf="default,ant->default"/>
<dependency org="ant" name="ant" rev="1.6.2" conf="default,ant->default"/>
<dependency org="ant" name="ant-nodeps" rev="1.6.2" conf="default"/>
<dependency org="ant" name="ant-trax" rev="1.6.2" conf="default"/>
<dependency org="commons-httpclient" name="commons-httpclient" rev="3.0" conf="default,httpclient->runtime,master" />
<dependency org="oro" name="oro" rev="2.0.8" conf="default,oro->default"/>
<dependency org="commons-vfs" name="commons-vfs" rev="1.0" conf="default,vfs->default" />
<dependency org="com.jcraft" name="jsch" rev="0.1.25" conf="default,sftp->default" />
<dependency org="com.jcraft" name="jsch" rev="0.1.31" conf="default,sftp->default" />
<!-- Test dependencies -->
<dependency org="junit" name="junit" rev="3.8.2" conf="test->default" />
<dependency org="commons-lang" name="commons-lang" rev="[1.0,3.0[" conf="test->default" />
<dependency org="org.apache.ant" name="ant-testutil" rev="1.7.0" conf="test->default" transitive="false" />
<dependency org="ant" name="ant-launcher" rev="1.6" conf="test->default" transitive="false"/>
<dependency org="ant" name="ant-launcher" rev="1.6.2" conf="test->default" transitive="false"/>
<!-- This dependency is necessary for having validation in junit tests when running with JDK1.4 -->
<dependency org="xerces" name="xercesImpl" rev="2.6.2" conf="test->default" />

View File

@ -29,6 +29,7 @@ org/apache/ivy/plugins/resolver/SFTPResolver.java
org/apache/ivy/plugins/resolver/SshResolver.java
org/apache/ivy/plugins/resolver/VfsResolver.java
org/apache/ivy/plugins/resolver/VsftpResolver.java
org/apache/ivy/plugins/resolver/packager/*.java
org/apache/ivy/util/url/HttpClientHandler.java
#This section defines the resources to copy for ivy-optional.jar

View File

@ -17,19 +17,22 @@
*/
package org.apache.ivy.plugins.resolver.packager;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import org.apache.ivy.core.IvyPatternHelper;
import org.apache.ivy.core.module.descriptor.Artifact;
import org.apache.ivy.core.module.id.ModuleRevisionId;
import org.apache.ivy.plugins.repository.Resource;
import org.apache.ivy.plugins.resolver.util.ResolvedResource;
import org.apache.ivy.util.FileUtil;
import org.apache.ivy.util.Message;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.BuildLogger;
import org.apache.tools.ant.DefaultLogger;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.ProjectHelper;
/**
* Represents one entry in the cache of a {@link PackagerResolver}.
@ -68,8 +71,7 @@ public class PackagerCacheEntry {
* @param packagerXML packager XML input stream
* @throws IllegalStateException if this entry has already been built
*/
public synchronized void build(InputStream packagerXML) throws IOException {
public synchronized void build(Resource packagerResource) throws IOException {
// Sanity check
if (this.built) {
throw new IllegalStateException("build in directory `"
@ -89,6 +91,7 @@ public class PackagerCacheEntry {
}
// Write out packager XML
InputStream packagerXML = packagerResource.openStream();
saveFile("packager.xml", packagerXML);
// Write packager XSLT
@ -97,45 +100,49 @@ public class PackagerCacheEntry {
// Write packager XSD
saveFile("packager-1.0.xsd");
// Write master ant build file
// Write master Ant build file
saveFile("build.xml");
// Create new process argument list
ArrayList paramList = new ArrayList();
paramList.add("ant");
if (this.verbose) {
paramList.add("-verbose");
}
if (this.quiet) {
paramList.add("-quiet");
}
paramList.add("-Divy.packager.organisation=" + this.mr.getModuleId().getOrganisation());
paramList.add("-Divy.packager.module=" + this.mr.getModuleId().getName());
paramList.add("-Divy.packager.revision=" + this.mr.getRevision());
paramList.add("-Divy.packager.branch=" + this.mr.getBranch());
// Execute the Ant build file
Project project = new Project();
project.init();
project.setUserProperty("ant.file" , new File(dir, "build.xml").getAbsolutePath());
ProjectHelper.configureProject(project, new File(dir, "build.xml"));
project.setBaseDir(dir);
// Configure logging verbosity
BuildLogger logger = new DefaultLogger();
logger.setMessageOutputLevel(this.verbose ? Project.MSG_VERBOSE :
this.quiet ? Project.MSG_WARN : Project.MSG_INFO);
logger.setOutputPrintStream(System.out);
logger.setErrorPrintStream(System.err);
project.addBuildListener(logger);
// Set properties
project.setUserProperty("ivy.packager.organisation", "" + this.mr.getModuleId().getOrganisation());
project.setUserProperty("ivy.packager.module", "" + this.mr.getModuleId().getName());
project.setUserProperty("ivy.packager.revision", "" + this.mr.getRevision());
project.setUserProperty("ivy.packager.branch", "" + this.mr.getBranch());
if (this.resourceCache != null) {
paramList.add("-Divy.packager.resourceCache=" + this.resourceCache.getCanonicalPath());
project.setUserProperty("ivy.packager.resourceCache", "" + this.resourceCache.getCanonicalPath());
}
if (this.resourceURL != null) {
paramList.add("-Divy.packager.resourceURL=" + getResourceURL());
project.setUserProperty("ivy.packager.resourceURL", "" + getResourceURL());
}
if (this.validate) {
paramList.add("-Divy.packager.validate=true");
project.setUserProperty("ivy.packager.validate", "true");
}
String[] params = (String[]) paramList.toArray(new String[paramList.size()]);
// Run ant
SubProcess proc = new SubProcess(params, null, this.dir);
int result;
// Execute task
Message.verbose("performing packager resolver build in " + this.dir);
try {
result = proc.run();
} catch (InterruptedException e) {
throw new RuntimeException(e);
project.executeTarget("build");
this.built = true;
} catch (BuildException e) {
e.printStackTrace(System.out);
Message.verbose("packager resolver build failed: " + e);
throw e;
}
if (result != 0) {
throw new IOException("build in directory `" + this.dir + "' failed");
}
this.built = true;
}
/**
@ -166,11 +173,7 @@ public class PackagerCacheEntry {
}
protected void saveFile(String name, InputStream input) throws IOException {
OutputStream out = new BufferedOutputStream(
new FileOutputStream(new File(this.dir, name)));
SubProcess.relayStream(input, out);
input.close();
out.close();
FileUtil.copy(input, new File(this.dir, name), null);
}
protected void saveFile(String name) throws IOException {

View File

@ -55,7 +55,7 @@ public class PackagerResolver extends URLResolver {
private boolean preserve;
private boolean verbose;
private boolean quiet;
public PackagerResolver() {
Runtime.getRuntime().addShutdownHook(new Thread() {
public void run() {
@ -63,7 +63,7 @@ public class PackagerResolver extends URLResolver {
}
});
}
protected synchronized void clearCache() {
if (this.preserve) {
return;
@ -190,7 +190,7 @@ public class PackagerResolver extends URLResolver {
entry = new PackagerCacheEntry(mr, this.buildRoot, this.resourceCache,
this.resourceURL, this.validate, this.preserve, this.verbose, this.quiet);
try {
entry.build(packager.getResource().openStream());
entry.build(packager.getResource());
} catch (IOException e) {
throw new RuntimeException("can't build artifact " + artifact, e);
}

View File

@ -1,106 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package org.apache.ivy.plugins.resolver.packager;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
/**
* Simple utility class for executing subprocesses. Handles I/O streams
* by closing standard input and relaying standard output and error.
*/
public class SubProcess {
private static final int BUFSIZE = 1024;
private final String[] cmd;
private final String[] env;
private final File dir;
/**
* Constructor.
*
* @param cmd command parameters
* @param env command environment
* @param dir command working directory
* @see Runtime.exec(String[], String[], File)
*/
public SubProcess(String[] cmd, String[] env, File dir) {
this.cmd = cmd;
this.env = env;
this.dir = dir;
}
/**
* Execute the process and wait for it to complete.
*
* @return exit value from process
*/
public int run() throws IOException, InterruptedException {
Process proc = Runtime.getRuntime().exec(this.cmd, this.env, this.dir);
proc.getOutputStream().close();
Thread relay1 = startRelay(proc.getInputStream(), System.out);
Thread relay2 = startRelay(proc.getErrorStream(), System.err);
int result;
relay1.join();
relay2.join();
return proc.waitFor();
}
/**
* Create and start a separate thread that copies input to output and closes
* the input when done.
*
* @param in input stream to read from
* @param out output stream to copy to
* @return thread doing the work
*/
public static Thread startRelay(final InputStream in, final OutputStream out) {
Thread thread = new Thread() {
public void run() {
try {
relayStream(in, out);
in.close();
} catch (IOException e) {
return;
}
}
};
thread.setDaemon(true);
thread.start();
return thread;
}
/**
* Copy from input to output. Does not close either stream when finished.
*
* @param in input stream to read from
* @param out output stream to copy to
*/
public static void relayStream(InputStream in, OutputStream out) throws IOException {
byte[] buf = new byte[BUFSIZE];
int r;
while ((r = in.read(buf)) != -1) {
out.write(buf, 0, r);
}
out.flush();
}
}

View File

@ -126,7 +126,7 @@
<path location="{$groupId}"/>
<mapper type="unpackage" to="*">
<xsl:attribute name="from">
<xsl:value-of select="'${basedir}/*'"/>
<xsl:value-of select="'${basedir}${file.separator}*'"/>
</xsl:attribute>
</mapper>
</pathconvert>

View File

@ -35,8 +35,11 @@ import org.apache.ivy.core.resolve.ResolveOptions;
import org.apache.ivy.core.resolve.ResolvedModuleRevision;
import org.apache.ivy.core.settings.IvySettings;
import org.apache.ivy.core.sort.SortEngine;
import org.apache.ivy.plugins.resolver.packager.PackagerProperty;
import org.apache.ivy.plugins.resolver.packager.PackagerResolver;
import org.apache.ivy.util.DefaultMessageLogger;
import org.apache.ivy.util.FileUtil;
import org.apache.ivy.util.Message;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.taskdefs.Copy;
import org.apache.tools.ant.types.FileSet;
@ -61,7 +64,9 @@ public class PackagerResolverTest extends AbstractDependencyResolverTest {
private File _websitedir;
protected void setUp() throws Exception {
_settings = new IvySettings();
Message.setDefaultLogger(new DefaultMessageLogger(99));
_engine = new ResolveEngine(_settings, new EventManager(), new SortEngine(_settings));
_cache = new File("build/cache");
_data = new ResolveData(_engine, new ResolveOptions());
@ -104,12 +109,15 @@ public class PackagerResolverTest extends AbstractDependencyResolverTest {
resolver.setSettings(_settings);
File repoRoot = new File("test/repositories/packager/repo");
resolver.addIvyPattern(
"" + new File(repoRoot, "[organisation]/[module]/[revision]/ivy.xml").toURL());
"" + new File(repoRoot, "[organisation]/[module]/[revision]/ivy.xml").getAbsoluteFile().toURL().toExternalForm());
resolver.setPackagerPattern(
"" + new File(repoRoot, "[organisation]/[module]/[revision]/packager.xml").toURL());
"" + new File(repoRoot, "[organisation]/[module]/[revision]/packager.xml").getAbsoluteFile().toURL().toExternalForm());
resolver.setBuildRoot(_builddir.getAbsolutePath());
resolver.setResourceCache(_cachedir.getAbsolutePath());
resolver.setPreserveBuildDirectories(true);
resolver.setVerbose(true);
System.setProperty("packager.website.url", new File("test/repositories/packager/website").getAbsoluteFile().toURL().toExternalForm());
resolver.setName("packager");
assertEquals("packager", resolver.getName());
@ -132,6 +140,7 @@ public class PackagerResolverTest extends AbstractDependencyResolverTest {
assertEquals(1, report.getArtifactsReports().length);
ArtifactDownloadReport ar = report.getArtifactReport(artifact);
System.out.println("downloaddetails: " + ar.getDownloadDetails());
assertNotNull(ar);
assertEquals(artifact, ar.getArtifact());

View File

@ -21,12 +21,12 @@
<property name="version" value="${ivy.packager.revision}"/>
<property name="archive" value="${name}-${version}"/>
<resource dest="extract" url="file://${user.dir}/../../../../website/dist/${archive}.tar.gz"
<resource dest="extract" url="${packager.website.url}/dist/${archive}.tar.gz"
sha1="40c80c1c5d7db0038f396f2393885d2e8c74270d">
<include name="${archive}/${name}.jar"/>
</resource>
<m2resource repo="file://${user.dir}/../../../../website/m2repo" groupId="org.apache.ivy" artifactId="foobar">
<m2resource repo="${packager.website.url}/m2repo" groupId="org.apache.ivy" artifactId="foobar">
<artifact classifier="janfu" sha1="da39a3ee5e6b4b0d3255bfef95601890afd80709" tofile="artifacts/jars/foobar-janfu.jar"/>
</m2resource>