mirror of https://github.com/apache/ant-ivy
659 lines
29 KiB
Java
659 lines
29 KiB
Java
/*
|
|
* 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
|
|
*
|
|
* https://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;
|
|
|
|
import java.io.File;
|
|
import java.io.FileOutputStream;
|
|
import java.io.IOException;
|
|
import java.io.PrintWriter;
|
|
import java.lang.reflect.InvocationTargetException;
|
|
import java.lang.reflect.Method;
|
|
import java.net.MalformedURLException;
|
|
import java.net.URL;
|
|
import java.net.URLClassLoader;
|
|
import java.util.ArrayList;
|
|
import java.util.Arrays;
|
|
import java.util.Collection;
|
|
import java.util.Collections;
|
|
import java.util.LinkedHashSet;
|
|
import java.util.List;
|
|
import java.util.StringTokenizer;
|
|
|
|
import org.apache.ivy.core.cache.ResolutionCacheManager;
|
|
import org.apache.ivy.core.deliver.DeliverOptions;
|
|
import org.apache.ivy.core.module.descriptor.DefaultDependencyDescriptor;
|
|
import org.apache.ivy.core.module.descriptor.DefaultModuleDescriptor;
|
|
import org.apache.ivy.core.module.descriptor.ModuleDescriptor;
|
|
import org.apache.ivy.core.module.id.ModuleRevisionId;
|
|
import org.apache.ivy.core.publish.PublishOptions;
|
|
import org.apache.ivy.core.report.ArtifactDownloadReport;
|
|
import org.apache.ivy.core.report.ResolveReport;
|
|
import org.apache.ivy.core.resolve.ResolveOptions;
|
|
import org.apache.ivy.core.resolve.ResolveProcessException;
|
|
import org.apache.ivy.core.retrieve.RetrieveOptions;
|
|
import org.apache.ivy.core.settings.IvySettings;
|
|
import org.apache.ivy.plugins.parser.m2.PomModuleDescriptorWriter;
|
|
import org.apache.ivy.plugins.parser.m2.PomWriterOptions;
|
|
import org.apache.ivy.plugins.parser.xml.XmlModuleDescriptorWriter;
|
|
import org.apache.ivy.plugins.report.XmlReportParser;
|
|
import org.apache.ivy.util.DefaultMessageLogger;
|
|
import org.apache.ivy.util.Message;
|
|
import org.apache.ivy.util.PropertiesFile;
|
|
import org.apache.ivy.util.cli.CommandLine;
|
|
import org.apache.ivy.util.cli.CommandLineParser;
|
|
import org.apache.ivy.util.cli.OptionBuilder;
|
|
import org.apache.ivy.util.cli.ParseException;
|
|
import org.apache.ivy.util.filter.FilterHelper;
|
|
import org.apache.ivy.util.url.CredentialsStore;
|
|
import org.apache.ivy.util.url.TimeoutConstrainedURLHandler;
|
|
import org.apache.ivy.util.url.URLHandlerDispatcher;
|
|
import org.apache.ivy.util.url.URLHandlerRegistry;
|
|
|
|
/**
|
|
* Class used to launch ivy as a standalone tool.
|
|
* <p>
|
|
* Valid arguments can be obtained with the -? argument.
|
|
*/
|
|
public final class Main {
|
|
private static final int HELP_WIDTH = 80;
|
|
|
|
static CommandLineParser getParser() {
|
|
return new CommandLineParser()
|
|
.addCategory("settings options")
|
|
.addOption(
|
|
new OptionBuilder("settings").arg("settingsfile")
|
|
.description("use given file for settings").create())
|
|
.addOption(
|
|
new OptionBuilder("properties").arg("propertiesfile")
|
|
.description("use given file for properties not specified in settings").create())
|
|
.addOption(
|
|
new OptionBuilder("cache").arg("cachedir")
|
|
.description("use given directory for cache").create())
|
|
.addOption(
|
|
new OptionBuilder("novalidate").description(
|
|
"do not validate ivy files against xsd").create())
|
|
.addOption(
|
|
new OptionBuilder("m2compatible").description("use Maven 2 compatibility")
|
|
.create())
|
|
.addOption(
|
|
new OptionBuilder("conf").arg("settingsfile").deprecated()
|
|
.description("use given file for settings").create())
|
|
.addOption(
|
|
new OptionBuilder("useOrigin")
|
|
.deprecated()
|
|
.description(
|
|
"use original artifact location "
|
|
+ "with local resolvers instead of copying to the cache")
|
|
.create())
|
|
|
|
.addCategory("resolve options")
|
|
.addOption(
|
|
new OptionBuilder("ivy").arg("ivyfile")
|
|
.description("use given file as ivy file").create())
|
|
.addOption(
|
|
new OptionBuilder("refresh").description("refresh dynamic resolved revisions")
|
|
.create())
|
|
.addOption(
|
|
new OptionBuilder("dependency")
|
|
.arg("organisation")
|
|
.arg("module")
|
|
.arg("revision")
|
|
.description(
|
|
"use this instead of ivy file to do the rest "
|
|
+ "of the work with this as a dependency.").create())
|
|
.addOption(
|
|
new OptionBuilder("confs").arg("configurations").countArgs(false)
|
|
.description("resolve given configurations").create())
|
|
.addOption(
|
|
new OptionBuilder("types").arg("types").countArgs(false)
|
|
.description("accepted artifact types")
|
|
.create())
|
|
.addOption(
|
|
new OptionBuilder("mode").arg("resolvemode")
|
|
.description("the resolve mode to use").create())
|
|
.addOption(
|
|
new OptionBuilder("notransitive").description(
|
|
"do not resolve dependencies transitively").create())
|
|
|
|
.addCategory("retrieve options")
|
|
.addOption(
|
|
new OptionBuilder("retrieve").arg("retrievepattern")
|
|
.description("use given pattern as retrieve pattern").create())
|
|
.addOption(
|
|
new OptionBuilder("ivypattern").arg("pattern")
|
|
.description("use given pattern to copy the ivy files").create())
|
|
.addOption(
|
|
new OptionBuilder("sync").description("use sync mode for retrieve").create())
|
|
.addOption(
|
|
new OptionBuilder("symlink").description("create symbolic links").create())
|
|
.addOption(new OptionBuilder("overwriteMode").arg("overwriteMode")
|
|
.description("use given overwrite mode for retrieve")
|
|
.create())
|
|
.addCategory("cache path options")
|
|
.addOption(
|
|
new OptionBuilder("cachepath")
|
|
.arg("cachepathfile")
|
|
.description(
|
|
"outputs a classpath consisting of all dependencies in cache "
|
|
+ "(including transitive ones) "
|
|
+ "of the given ivy file to the given cachepathfile")
|
|
.create())
|
|
|
|
.addCategory("deliver options")
|
|
.addOption(
|
|
new OptionBuilder("deliverto").arg("ivypattern")
|
|
.description("use given pattern as resolved ivy file pattern").create())
|
|
|
|
.addCategory("publish options")
|
|
.addOption(
|
|
new OptionBuilder("publish").arg("resolvername")
|
|
.description("use given resolver to publish to").create())
|
|
.addOption(
|
|
new OptionBuilder("publishpattern").arg("artpattern")
|
|
.description("use given pattern to find artifacts to publish").create())
|
|
.addOption(
|
|
new OptionBuilder("revision").arg("revision")
|
|
.description("use given revision to publish the module").create())
|
|
.addOption(
|
|
new OptionBuilder("status").arg("status")
|
|
.description("use given status to publish the module").create())
|
|
.addOption(
|
|
new OptionBuilder("overwrite").description(
|
|
"overwrite files in the repository if they exist").create())
|
|
|
|
.addCategory("makepom options")
|
|
.addOption(new OptionBuilder("makepom").arg("pomfilepath")
|
|
.description("create a POM file for the module").create())
|
|
|
|
.addCategory("http auth options")
|
|
.addOption(
|
|
new OptionBuilder("realm").arg("realm")
|
|
.description("use given realm for HTTP AUTH").create())
|
|
.addOption(
|
|
new OptionBuilder("host").arg("host")
|
|
.description("use given host for HTTP AUTH").create())
|
|
.addOption(
|
|
new OptionBuilder("username").arg("username")
|
|
.description("use given username for HTTP AUTH").create())
|
|
.addOption(
|
|
new OptionBuilder("passwd").arg("passwd")
|
|
.description("use given password for HTTP AUTH").create())
|
|
|
|
.addCategory("launcher options")
|
|
.addOption(
|
|
new OptionBuilder("main").arg("main")
|
|
.description("the FQCN of the main class to launch").create())
|
|
.addOption(
|
|
new OptionBuilder("args").arg("args").countArgs(false)
|
|
.description("the arguments to give to the launched process").create())
|
|
.addOption(
|
|
new OptionBuilder("cp").arg("cp")
|
|
.description("extra classpath to use when launching process").create())
|
|
|
|
|
|
.addCategory("message options")
|
|
.addOption(
|
|
new OptionBuilder("debug").description("set message level to debug").create())
|
|
.addOption(
|
|
new OptionBuilder("verbose").description("set message level to verbose")
|
|
.create())
|
|
.addOption(
|
|
new OptionBuilder("warn").description("set message level to warn").create())
|
|
.addOption(
|
|
new OptionBuilder("error").description("set message level to error").create())
|
|
|
|
.addCategory("help options")
|
|
.addOption(new OptionBuilder("?").description("display this help").create())
|
|
.addOption(
|
|
new OptionBuilder("deprecated").description("show deprecated options").create())
|
|
.addOption(
|
|
new OptionBuilder("version").description("displays version information")
|
|
.create());
|
|
}
|
|
|
|
public static void main(String[] args) throws Exception {
|
|
try {
|
|
run(args, true);
|
|
System.exit(0);
|
|
} catch (ParseException ex) {
|
|
System.err.println(ex.getMessage());
|
|
System.exit(1);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* A method that allows to run embedded Ivy as if it were launched from CLI
|
|
* (e.g., for use with REPL in Java 9+).
|
|
*
|
|
* @param args an array of command line arguments
|
|
* @return null if asked for usage or version, or if anything fails during resolve, publish or
|
|
* launch; a ResolveReport on success
|
|
* @throws Exception if something goes wrong
|
|
*/
|
|
public static ResolveReport run(String[] args) throws Exception {
|
|
return run(args, false);
|
|
}
|
|
|
|
/*
|
|
* For backwards compatibility and testing
|
|
*/
|
|
static void run(CommandLineParser parser, String[] args) throws Exception {
|
|
if (Arrays.asList(args).contains("-?")) {
|
|
usage(parser, false);
|
|
return;
|
|
}
|
|
|
|
run(parser.parse(args), true);
|
|
}
|
|
|
|
private static ResolveReport run(String[] args, boolean isCli) throws Exception {
|
|
CommandLineParser parser = getParser();
|
|
|
|
// parse the command line arguments
|
|
CommandLine line;
|
|
try {
|
|
line = parser.parse(args);
|
|
} catch (ParseException pe) {
|
|
// display usage and and rethrow
|
|
usage(parser, false);
|
|
throw new ParseException(pe.getMessage());
|
|
}
|
|
|
|
if (line.hasOption("?")) {
|
|
usage(parser, line.hasOption("deprecated"));
|
|
return null;
|
|
}
|
|
|
|
return run(line, isCli);
|
|
}
|
|
|
|
@SuppressWarnings("deprecation")
|
|
private static ResolveReport run(CommandLine line, boolean isCli) throws Exception {
|
|
if (line.hasOption("version")) {
|
|
System.out.println("Apache Ivy " + Ivy.getIvyVersion() + " - " + Ivy.getIvyDate()
|
|
+ " :: " + Ivy.getIvyHomeURL());
|
|
return null;
|
|
}
|
|
|
|
boolean validate = !line.hasOption("novalidate");
|
|
|
|
Ivy ivy = Ivy.newInstance();
|
|
initMessage(line, ivy);
|
|
IvySettings settings = initSettings(line, ivy);
|
|
ivy.pushContext();
|
|
|
|
File cache = new File(settings.substitute(line.getOptionValue("cache", settings
|
|
.getDefaultCache().getAbsolutePath())));
|
|
|
|
if (line.hasOption("cache")) {
|
|
// override default cache path with user supplied cache path
|
|
settings.setDefaultCache(cache);
|
|
}
|
|
|
|
if (!cache.exists()) {
|
|
cache.mkdirs();
|
|
} else if (!cache.isDirectory()) {
|
|
error(cache + " is not a directory");
|
|
}
|
|
|
|
String[] confs;
|
|
if (line.hasOption("confs")) {
|
|
confs = line.getOptionValues("confs");
|
|
} else {
|
|
confs = new String[] {"*"};
|
|
}
|
|
|
|
File ivyfile;
|
|
if (line.hasOption("dependency")) {
|
|
String[] dep = line.getOptionValues("dependency");
|
|
ivyfile = File.createTempFile("ivy", ".xml");
|
|
ivyfile.deleteOnExit();
|
|
DefaultModuleDescriptor md = DefaultModuleDescriptor
|
|
.newDefaultInstance(ModuleRevisionId.newInstance(dep[0], dep[1] + "-caller",
|
|
"working"));
|
|
DefaultDependencyDescriptor dd = new DefaultDependencyDescriptor(md,
|
|
ModuleRevisionId.newInstance(dep[0], dep[1], dep[2]), false, false, true);
|
|
for (String conf : confs) {
|
|
dd.addDependencyConfiguration("default", conf);
|
|
}
|
|
md.addDependency(dd);
|
|
XmlModuleDescriptorWriter.write(md, ivyfile);
|
|
confs = new String[] {"default"};
|
|
} else {
|
|
ivyfile = new File(settings.substitute(line.getOptionValue("ivy", "ivy.xml")));
|
|
if (!ivyfile.exists()) {
|
|
error("ivy file not found: " + ivyfile);
|
|
} else if (ivyfile.isDirectory()) {
|
|
error("ivy file is not a file: " + ivyfile);
|
|
}
|
|
}
|
|
|
|
if (line.hasOption("useOrigin")) {
|
|
ivy.getSettings().useDeprecatedUseOrigin();
|
|
}
|
|
ResolveOptions resolveOptions = new ResolveOptions()
|
|
.setConfs(confs)
|
|
.setValidate(validate)
|
|
.setResolveMode(line.getOptionValue("mode"))
|
|
.setArtifactFilter(
|
|
FilterHelper.getArtifactTypeFilter(line.getOptionValues("types")));
|
|
if (line.hasOption("notransitive")) {
|
|
resolveOptions.setTransitive(false);
|
|
}
|
|
if (line.hasOption("refresh")) {
|
|
resolveOptions.setRefresh(true);
|
|
}
|
|
ResolveReport report = ivy.resolve(ivyfile.toURI().toURL(), resolveOptions);
|
|
if (report.hasError()) {
|
|
if (isCli) {
|
|
System.exit(1);
|
|
}
|
|
|
|
StringBuilder sb = new StringBuilder();
|
|
for (String problem : report.getAllProblemMessages()) {
|
|
if (sb.length() > 0) {
|
|
sb.append("\n");
|
|
}
|
|
sb.append(problem);
|
|
}
|
|
throw new ResolveProcessException(sb.toString());
|
|
}
|
|
ModuleDescriptor md = report.getModuleDescriptor();
|
|
|
|
if (confs.length == 1 && "*".equals(confs[0])) {
|
|
confs = md.getConfigurationsNames();
|
|
}
|
|
if (line.hasOption("retrieve")) {
|
|
String retrievePattern = settings.substitute(line.getOptionValue("retrieve"));
|
|
if (!retrievePattern.contains("[")) {
|
|
retrievePattern += "/lib/[conf]/[artifact].[ext]";
|
|
}
|
|
String ivyPattern = settings.substitute(line.getOptionValue("ivypattern"));
|
|
ivy.retrieve(
|
|
md.getModuleRevisionId(),
|
|
new RetrieveOptions()
|
|
.setConfs(confs)
|
|
.setSync(line.hasOption("sync"))
|
|
.setUseOrigin(line.hasOption("useOrigin"))
|
|
.setDestArtifactPattern(retrievePattern)
|
|
.setDestIvyPattern(ivyPattern)
|
|
.setOverwriteMode(line.getOptionValue("overwriteMode"))
|
|
.setArtifactFilter(
|
|
FilterHelper.getArtifactTypeFilter(line.getOptionValues("types")))
|
|
.setMakeSymlinks(line.hasOption("symlink"))
|
|
.setMakeSymlinksInMass(line.hasOption("symlinkmass")));
|
|
}
|
|
if (line.hasOption("cachepath")) {
|
|
outputCachePath(ivy, cache, md, confs,
|
|
line.getOptionValue("cachepath", "ivycachepath.txt"));
|
|
}
|
|
|
|
if (line.hasOption("revision")) {
|
|
ivy.deliver(
|
|
md.getResolvedModuleRevisionId(),
|
|
settings.substitute(line.getOptionValue("revision")),
|
|
settings.substitute(line.getOptionValue("deliverto", "ivy-[revision].xml")),
|
|
DeliverOptions.newInstance(settings)
|
|
.setStatus(settings.substitute(line.getOptionValue("status", "release")))
|
|
.setValidate(validate));
|
|
if (line.hasOption("publish")) {
|
|
ivy.publish(
|
|
md.getResolvedModuleRevisionId(),
|
|
Collections.singleton(settings.substitute(line.getOptionValue("publishpattern",
|
|
"distrib/[type]s/[artifact]-[revision].[ext]"))),
|
|
line.getOptionValue("publish"),
|
|
new PublishOptions()
|
|
.setPubrevision(settings.substitute(line.getOptionValue("revision")))
|
|
.setValidate(validate)
|
|
.setSrcIvyPattern(
|
|
settings.substitute(line.getOptionValue("deliverto",
|
|
"ivy-[revision].xml")))
|
|
.setOverwrite(line.hasOption("overwrite")));
|
|
}
|
|
}
|
|
if (line.hasOption("makepom")) {
|
|
final String pomFilePath = line.getOptionValue("makepom", "pom.xml");
|
|
final File pomFile = new File(pomFilePath);
|
|
PomModuleDescriptorWriter.write(md, pomFile, new PomWriterOptions());
|
|
Message.debug("Generated a pom file for module at " + pomFile);
|
|
}
|
|
if (line.hasOption("main")) {
|
|
// check if the option cp has been set
|
|
List<File> fileList = getExtraClasspathFileList(line);
|
|
|
|
// merge -args and left over args
|
|
String[] fargs = line.getOptionValues("args");
|
|
if (fargs == null) {
|
|
fargs = new String[0];
|
|
}
|
|
String[] extra = line.getLeftOverArgs();
|
|
if (extra == null) {
|
|
extra = new String[0];
|
|
}
|
|
String[] params = new String[fargs.length + extra.length];
|
|
System.arraycopy(fargs, 0, params, 0, fargs.length);
|
|
System.arraycopy(extra, 0, params, fargs.length, extra.length);
|
|
// invoke with given main class and merged params
|
|
invoke(ivy, cache, md, confs, fileList, line.getOptionValue("main"), params);
|
|
}
|
|
ivy.getLoggerEngine().popLogger();
|
|
ivy.popContext();
|
|
|
|
return report;
|
|
}
|
|
|
|
/**
|
|
* Parses the <code>cp</code> option from the command line, and returns a list of {@link File}.
|
|
* <p>
|
|
* All the files contained in the returned List exist, non existing files are simply skipped
|
|
* with a warning.
|
|
* </p>
|
|
*
|
|
* @param line
|
|
* the command line in which the cp option should be parsed
|
|
* @return a List of files to include as extra classpath entries, or <code>null</code> if no cp
|
|
* option was provided.
|
|
*/
|
|
private static List<File> getExtraClasspathFileList(CommandLine line) {
|
|
List<File> fileList = null;
|
|
if (line.hasOption("cp")) {
|
|
fileList = new ArrayList<>();
|
|
for (String cp : line.getOptionValues("cp")) {
|
|
StringTokenizer tokenizer = new StringTokenizer(cp, File.pathSeparator);
|
|
while (tokenizer.hasMoreTokens()) {
|
|
String token = tokenizer.nextToken();
|
|
File file = new File(token);
|
|
if (file.exists()) {
|
|
fileList.add(file);
|
|
} else {
|
|
Message.warn("Skipping extra classpath '" + file
|
|
+ "' as it does not exist.");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return fileList;
|
|
}
|
|
|
|
private static IvySettings initSettings(CommandLine line, Ivy ivy)
|
|
throws java.text.ParseException, IOException, ParseException {
|
|
IvySettings settings = ivy.getSettings();
|
|
settings.addAllVariables(System.getProperties());
|
|
if (line.hasOption("properties")) {
|
|
settings.addAllVariables(new PropertiesFile(new File(line.getOptionValue("properties")),
|
|
"additional properties"));
|
|
}
|
|
if (line.hasOption("m2compatible")) {
|
|
settings.setVariable("ivy.default.configuration.m2compatible", "true");
|
|
}
|
|
|
|
configureURLHandler(line.getOptionValue("realm", null), line.getOptionValue("host", null),
|
|
line.getOptionValue("username", null), line.getOptionValue("passwd", null));
|
|
|
|
String settingsPath = line.getOptionValue("settings", "");
|
|
if ("".equals(settingsPath)) {
|
|
settingsPath = line.getOptionValue("conf", "");
|
|
if (!"".equals(settingsPath)) {
|
|
Message.deprecated("-conf is deprecated, use -settings instead");
|
|
}
|
|
}
|
|
if ("".equals(settingsPath)) {
|
|
ivy.configureDefault();
|
|
} else {
|
|
File conffile = new File(settingsPath);
|
|
if (!conffile.exists()) {
|
|
error("ivy configuration file not found: " + conffile);
|
|
} else if (conffile.isDirectory()) {
|
|
error("ivy configuration file is not a file: " + conffile);
|
|
}
|
|
ivy.configure(conffile);
|
|
}
|
|
return settings;
|
|
}
|
|
|
|
private static void initMessage(CommandLine line, Ivy ivy) {
|
|
if (line.hasOption("debug")) {
|
|
ivy.getLoggerEngine().pushLogger(new DefaultMessageLogger(Message.MSG_DEBUG));
|
|
} else if (line.hasOption("verbose")) {
|
|
ivy.getLoggerEngine().pushLogger(new DefaultMessageLogger(Message.MSG_VERBOSE));
|
|
} else if (line.hasOption("warn")) {
|
|
ivy.getLoggerEngine().pushLogger(new DefaultMessageLogger(Message.MSG_WARN));
|
|
} else if (line.hasOption("error")) {
|
|
ivy.getLoggerEngine().pushLogger(new DefaultMessageLogger(Message.MSG_ERR));
|
|
} else {
|
|
ivy.getLoggerEngine().pushLogger(new DefaultMessageLogger(Message.MSG_INFO));
|
|
}
|
|
}
|
|
|
|
private static void outputCachePath(Ivy ivy, File cache, ModuleDescriptor md, String[] confs,
|
|
String outFile) {
|
|
try {
|
|
StringBuilder buf = new StringBuilder();
|
|
Collection<ArtifactDownloadReport> all = new LinkedHashSet<>();
|
|
ResolutionCacheManager cacheMgr = ivy.getResolutionCacheManager();
|
|
XmlReportParser parser = new XmlReportParser();
|
|
for (String conf : confs) {
|
|
String resolveId = ResolveOptions.getDefaultResolveId(md);
|
|
File report = cacheMgr.getConfigurationResolveReportInCache(resolveId, conf);
|
|
parser.parse(report);
|
|
|
|
all.addAll(Arrays.asList(parser.getArtifactReports()));
|
|
}
|
|
for (ArtifactDownloadReport artifact : all) {
|
|
if (artifact.getLocalFile() != null) {
|
|
buf.append(artifact.getLocalFile().getCanonicalPath());
|
|
buf.append(File.pathSeparator);
|
|
}
|
|
}
|
|
|
|
PrintWriter writer = new PrintWriter(new FileOutputStream(outFile));
|
|
if (buf.length() > 0) {
|
|
buf.setLength(buf.length() - File.pathSeparator.length());
|
|
writer.println(buf);
|
|
}
|
|
writer.close();
|
|
System.out.println("cachepath output to " + outFile);
|
|
|
|
} catch (Exception ex) {
|
|
throw new RuntimeException("impossible to build ivy cache path: " + ex.getMessage(), ex);
|
|
}
|
|
}
|
|
|
|
@SuppressWarnings("resource")
|
|
private static void invoke(Ivy ivy, File cache, ModuleDescriptor md, String[] confs,
|
|
List<File> fileList, String mainclass, String[] args) {
|
|
List<URL> urls = new ArrayList<>();
|
|
|
|
// Add option cp (extra classpath) urls
|
|
if (fileList != null && fileList.size() > 0) {
|
|
for (File file : fileList) {
|
|
try {
|
|
urls.add(file.toURI().toURL());
|
|
} catch (MalformedURLException e) {
|
|
// Should not happen, just ignore.
|
|
}
|
|
}
|
|
}
|
|
|
|
try {
|
|
Collection<ArtifactDownloadReport> all = new LinkedHashSet<>();
|
|
ResolutionCacheManager cacheMgr = ivy.getResolutionCacheManager();
|
|
XmlReportParser parser = new XmlReportParser();
|
|
for (String conf : confs) {
|
|
String resolveId = ResolveOptions.getDefaultResolveId(md);
|
|
File report = cacheMgr.getConfigurationResolveReportInCache(resolveId, conf);
|
|
parser.parse(report);
|
|
|
|
all.addAll(Arrays.asList(parser.getArtifactReports()));
|
|
}
|
|
for (ArtifactDownloadReport artifact : all) {
|
|
if (artifact.getLocalFile() != null) {
|
|
urls.add(artifact.getLocalFile().toURI().toURL());
|
|
}
|
|
}
|
|
} catch (Exception ex) {
|
|
throw new RuntimeException("impossible to build ivy cache path: " + ex.getMessage(), ex);
|
|
}
|
|
|
|
URLClassLoader classLoader = new URLClassLoader(urls.toArray(new URL[urls.size()]),
|
|
Main.class.getClassLoader().getParent());
|
|
|
|
try {
|
|
Class<?> c = classLoader.loadClass(mainclass);
|
|
|
|
Method mainMethod = c.getMethod("main", String[].class);
|
|
|
|
Thread.currentThread().setContextClassLoader(classLoader);
|
|
mainMethod.invoke(null, new Object[] {(args == null ? new String[0] : args)});
|
|
} catch (ClassNotFoundException cnfe) {
|
|
throw new RuntimeException("Could not find class: " + mainclass, cnfe);
|
|
} catch (SecurityException | NoSuchMethodException e) {
|
|
throw new RuntimeException("Could not find main method: " + mainclass, e);
|
|
} catch (IllegalAccessException e) {
|
|
throw new RuntimeException("No permissions to invoke main method: " + mainclass, e);
|
|
} catch (InvocationTargetException e) {
|
|
throw new RuntimeException("Unexpected exception invoking main method: " + mainclass, e);
|
|
}
|
|
}
|
|
|
|
private static void configureURLHandler(String realm, String host, String username,
|
|
String passwd) {
|
|
CredentialsStore.INSTANCE.addCredentials(realm, host, username, passwd);
|
|
|
|
URLHandlerDispatcher dispatcher = new URLHandlerDispatcher();
|
|
TimeoutConstrainedURLHandler httpHandler = URLHandlerRegistry.getHttp();
|
|
dispatcher.setDownloader("http", httpHandler);
|
|
dispatcher.setDownloader("https", httpHandler);
|
|
URLHandlerRegistry.setDefault(dispatcher);
|
|
}
|
|
|
|
private static void error(String msg) throws ParseException {
|
|
throw new ParseException(msg);
|
|
}
|
|
|
|
private static void usage(CommandLineParser parser, boolean showDeprecated) {
|
|
// automatically generate the help statement
|
|
PrintWriter pw = new PrintWriter(System.out);
|
|
parser.printHelp(pw, HELP_WIDTH, "ivy", showDeprecated);
|
|
pw.flush();
|
|
}
|
|
|
|
private Main() {
|
|
}
|
|
}
|