From f9e51f56a5d4115d00af10bc1404217805f89455 Mon Sep 17 00:00:00 2001 From: grperry Date: Sun, 18 Mar 2018 15:07:09 -0700 Subject: [PATCH 1/8] re-use standalone ivy interface for programmatic one --- src/java/org/apache/ivy/Main.java | 1194 +++++++++++++++-------------- 1 file changed, 603 insertions(+), 591 deletions(-) diff --git a/src/java/org/apache/ivy/Main.java b/src/java/org/apache/ivy/Main.java index a274e64f2..3e4853a4b 100644 --- a/src/java/org/apache/ivy/Main.java +++ b/src/java/org/apache/ivy/Main.java @@ -1,591 +1,603 @@ -/* - * 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; - -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.Iterator; -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.retrieve.RetrieveOptions; -import org.apache.ivy.core.settings.IvySettings; -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.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.URLHandler; -import org.apache.ivy.util.url.URLHandlerDispatcher; -import org.apache.ivy.util.url.URLHandlerRegistry; - -/** - * Class used to launch ivy as a standalone tool. - *

- * 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("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 maven2 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("comma separated list of 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()) - - .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("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 { - CommandLineParser parser = getParser(); - try { - run(parser, args); - System.exit(0); - } catch (ParseException ex) { - System.err.println(ex.getMessage()); - usage(parser, false); - System.exit(1); - } - } - - static void run(CommandLineParser parser, String[] args) throws Exception { - // parse the command line arguments - CommandLine line = parser.parse(args); - - if (line.hasOption("?")) { - usage(parser, line.hasOption("deprecated")); - return; - } - - if (line.hasOption("version")) { - System.out.println("Apache Ivy " + Ivy.getIvyVersion() + " - " + Ivy.getIvyDate() - + " :: " + Ivy.getIvyHomeURL()); - return; - } - - boolean validate = line.hasOption("novalidate") ? false : true; - - 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 (int i = 0; i < confs.length; i++) { - dd.addDependencyConfiguration("default", confs[i]); - } - 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()) { - System.exit(1); - } - 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.indexOf("[") == -1) { - retrievePattern = retrievePattern + "/lib/[conf]/[artifact].[ext]"; - } - String ivyPattern = settings.substitute(line.getOptionValue("ivypattern")); - ivy.retrieve( - md.getModuleRevisionId(), - retrievePattern, - new RetrieveOptions() - .setConfs(confs) - .setSync(line.hasOption("sync")) - .setUseOrigin(line.hasOption("useOrigin")) - .setDestIvyPattern(ivyPattern) - .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("main")) { - // check if the option cp has been set - List 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(); - } - - /** - * Parses the cp option from the command line, and returns a list of {@link File}. - *

- * All the files contained in the returned List exist, non existing files are simply skipped - * with a warning. - *

- * - * @param line - * the command line in which the cp option shold be parsed - * @return a List of files to include as extra classpath entries, or null if no cp - * option was provided. - */ - private static List/* */getExtraClasspathFileList(CommandLine line) { - List fileList = null; - if (line.hasOption("cp")) { - fileList = new ArrayList/* */(); - String[] cpArray = line.getOptionValues("cp"); - for (int index = 0; index < cpArray.length; index++) { - StringTokenizer tokenizer = new StringTokenizer(cpArray[index], - System.getProperty("path.separator")); - 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("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 { - String pathSeparator = System.getProperty("path.separator"); - StringBuffer buf = new StringBuffer(); - Collection all = new LinkedHashSet(); - ResolutionCacheManager cacheMgr = ivy.getResolutionCacheManager(); - XmlReportParser parser = new XmlReportParser(); - for (int i = 0; i < confs.length; i++) { - String resolveId = ResolveOptions.getDefaultResolveId(md); - File report = cacheMgr.getConfigurationResolveReportInCache(resolveId, confs[i]); - parser.parse(report); - - all.addAll(Arrays.asList(parser.getArtifactReports())); - } - for (Iterator iter = all.iterator(); iter.hasNext();) { - ArtifactDownloadReport artifact = (ArtifactDownloadReport) iter.next(); - if (artifact.getLocalFile() != null) { - buf.append(artifact.getLocalFile().getCanonicalPath()); - buf.append(pathSeparator); - } - } - - PrintWriter writer = new PrintWriter(new FileOutputStream(outFile)); - if (buf.length() > 0) { - writer.println(buf.substring(0, buf.length() - pathSeparator.length())); - } - writer.close(); - System.out.println("cachepath output to " + outFile); - - } catch (Exception ex) { - throw new RuntimeException("impossible to build ivy cache path: " + ex.getMessage(), ex); - } - } - - private static void invoke(Ivy ivy, File cache, ModuleDescriptor md, String[] confs, - List fileList, String mainclass, String[] args) { - List urls = new ArrayList(); - - // Add option cp (extra classpath) urls - if (fileList != null && fileList.size() > 0) { - for (Iterator iter = fileList.iterator(); iter.hasNext();) { - File file = (File) iter.next(); - try { - urls.add(file.toURI().toURL()); - } catch (MalformedURLException e) { - // Should not happen, just ignore. - } - } - } - - try { - Collection all = new LinkedHashSet(); - ResolutionCacheManager cacheMgr = ivy.getResolutionCacheManager(); - XmlReportParser parser = new XmlReportParser(); - for (int i = 0; i < confs.length; i++) { - String resolveId = ResolveOptions.getDefaultResolveId(md); - File report = cacheMgr.getConfigurationResolveReportInCache(resolveId, confs[i]); - parser.parse(report); - - all.addAll(Arrays.asList(parser.getArtifactReports())); - } - for (Iterator iter = all.iterator(); iter.hasNext();) { - ArtifactDownloadReport artifact = (ArtifactDownloadReport) iter.next(); - - 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((URL[]) urls.toArray(new URL[urls.size()]), - Main.class.getClassLoader()); - - try { - Class c = classLoader.loadClass(mainclass); - - Method mainMethod = c.getMethod("main", new Class[] {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 e) { - throw new RuntimeException("Could not find main method: " + mainclass, e); - } catch (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(); - URLHandler 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() { - } -} +/* + * 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; + +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.Iterator; +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.retrieve.RetrieveOptions; +import org.apache.ivy.core.settings.IvySettings; +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.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.URLHandler; +import org.apache.ivy.util.url.URLHandlerDispatcher; +import org.apache.ivy.util.url.URLHandlerRegistry; + +/** + * Class used to launch ivy as a standalone tool. + *

+ * 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("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("noterminate").description( + "do not terminate - for programmatic use").create()) + .addOption( + new OptionBuilder("m2compatible").description("use maven2 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("comma separated list of 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()) + + .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("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 { + CommandLineParser parser = getParser(); + try { + run(parser, args); + System.exit(0); + } catch (ParseException ex) { + System.err.println(ex.getMessage()); + usage(parser, false); + System.exit(1); + } + } + + // FIXME - promot upstream - enhancement request + public static ResolveReport run(String[] args) throws Exception { + CommandLineParser parser = getParser(); + return run(parser, args); + } + + // FIXME - promot upstream - enhancement request + static ResolveReport run(CommandLineParser parser, String[] args) throws Exception { + // parse the command line arguments + CommandLine line = parser.parse(args); + + if (line.hasOption("?")) { + usage(parser, line.hasOption("deprecated")); + return null; + } + + if (line.hasOption("version")) { + System.out.println("Apache Ivy " + Ivy.getIvyVersion() + " - " + Ivy.getIvyDate() + + " :: " + Ivy.getIvyHomeURL()); + return null; + } + + boolean validate = line.hasOption("novalidate") ? false : true; + + 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 (int i = 0; i < confs.length; i++) { + dd.addDependencyConfiguration("default", confs[i]); + } + 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() && !line.hasOption("noterminate")) { + System.exit(1); + } + 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.indexOf("[") == -1) { + retrievePattern = retrievePattern + "/lib/[conf]/[artifact].[ext]"; + } + String ivyPattern = settings.substitute(line.getOptionValue("ivypattern")); + ivy.retrieve( + md.getModuleRevisionId(), + retrievePattern, + new RetrieveOptions() + .setConfs(confs) + .setSync(line.hasOption("sync")) + .setUseOrigin(line.hasOption("useOrigin")) + .setDestIvyPattern(ivyPattern) + .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("main")) { + // check if the option cp has been set + List 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 cp option from the command line, and returns a list of {@link File}. + *

+ * All the files contained in the returned List exist, non existing files are simply skipped + * with a warning. + *

+ * + * @param line + * the command line in which the cp option shold be parsed + * @return a List of files to include as extra classpath entries, or null if no cp + * option was provided. + */ + private static List/* */getExtraClasspathFileList(CommandLine line) { + List fileList = null; + if (line.hasOption("cp")) { + fileList = new ArrayList/* */(); + String[] cpArray = line.getOptionValues("cp"); + for (int index = 0; index < cpArray.length; index++) { + StringTokenizer tokenizer = new StringTokenizer(cpArray[index], + System.getProperty("path.separator")); + 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("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 { + String pathSeparator = System.getProperty("path.separator"); + StringBuffer buf = new StringBuffer(); + Collection all = new LinkedHashSet(); + ResolutionCacheManager cacheMgr = ivy.getResolutionCacheManager(); + XmlReportParser parser = new XmlReportParser(); + for (int i = 0; i < confs.length; i++) { + String resolveId = ResolveOptions.getDefaultResolveId(md); + File report = cacheMgr.getConfigurationResolveReportInCache(resolveId, confs[i]); + parser.parse(report); + + all.addAll(Arrays.asList(parser.getArtifactReports())); + } + for (Iterator iter = all.iterator(); iter.hasNext();) { + ArtifactDownloadReport artifact = (ArtifactDownloadReport) iter.next(); + if (artifact.getLocalFile() != null) { + buf.append(artifact.getLocalFile().getCanonicalPath()); + buf.append(pathSeparator); + } + } + + PrintWriter writer = new PrintWriter(new FileOutputStream(outFile)); + if (buf.length() > 0) { + writer.println(buf.substring(0, buf.length() - pathSeparator.length())); + } + writer.close(); + System.out.println("cachepath output to " + outFile); + + } catch (Exception ex) { + throw new RuntimeException("impossible to build ivy cache path: " + ex.getMessage(), ex); + } + } + + private static void invoke(Ivy ivy, File cache, ModuleDescriptor md, String[] confs, + List fileList, String mainclass, String[] args) { + List urls = new ArrayList(); + + // Add option cp (extra classpath) urls + if (fileList != null && fileList.size() > 0) { + for (Iterator iter = fileList.iterator(); iter.hasNext();) { + File file = (File) iter.next(); + try { + urls.add(file.toURI().toURL()); + } catch (MalformedURLException e) { + // Should not happen, just ignore. + } + } + } + + try { + Collection all = new LinkedHashSet(); + ResolutionCacheManager cacheMgr = ivy.getResolutionCacheManager(); + XmlReportParser parser = new XmlReportParser(); + for (int i = 0; i < confs.length; i++) { + String resolveId = ResolveOptions.getDefaultResolveId(md); + File report = cacheMgr.getConfigurationResolveReportInCache(resolveId, confs[i]); + parser.parse(report); + + all.addAll(Arrays.asList(parser.getArtifactReports())); + } + for (Iterator iter = all.iterator(); iter.hasNext();) { + ArtifactDownloadReport artifact = (ArtifactDownloadReport) iter.next(); + + 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((URL[]) urls.toArray(new URL[urls.size()]), + Main.class.getClassLoader()); + + try { + Class c = classLoader.loadClass(mainclass); + + Method mainMethod = c.getMethod("main", new Class[] {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 e) { + throw new RuntimeException("Could not find main method: " + mainclass, e); + } catch (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(); + URLHandler 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() { + } +} From 8f473734f05eb99568db4c5675f7b892337852b0 Mon Sep 17 00:00:00 2001 From: grperry Date: Sun, 18 Mar 2018 15:26:50 -0700 Subject: [PATCH 2/8] backed out windows crlf --- src/java/org/apache/ivy/Main.java | 1206 ++++++++++++++--------------- 1 file changed, 603 insertions(+), 603 deletions(-) diff --git a/src/java/org/apache/ivy/Main.java b/src/java/org/apache/ivy/Main.java index 3e4853a4b..3dd1e141b 100644 --- a/src/java/org/apache/ivy/Main.java +++ b/src/java/org/apache/ivy/Main.java @@ -1,603 +1,603 @@ -/* - * 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; - -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.Iterator; -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.retrieve.RetrieveOptions; -import org.apache.ivy.core.settings.IvySettings; -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.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.URLHandler; -import org.apache.ivy.util.url.URLHandlerDispatcher; -import org.apache.ivy.util.url.URLHandlerRegistry; - -/** - * Class used to launch ivy as a standalone tool. - *

- * 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("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("noterminate").description( - "do not terminate - for programmatic use").create()) - .addOption( - new OptionBuilder("m2compatible").description("use maven2 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("comma separated list of 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()) - - .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("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 { - CommandLineParser parser = getParser(); - try { - run(parser, args); - System.exit(0); - } catch (ParseException ex) { - System.err.println(ex.getMessage()); - usage(parser, false); - System.exit(1); - } - } - - // FIXME - promot upstream - enhancement request - public static ResolveReport run(String[] args) throws Exception { - CommandLineParser parser = getParser(); - return run(parser, args); - } - - // FIXME - promot upstream - enhancement request - static ResolveReport run(CommandLineParser parser, String[] args) throws Exception { - // parse the command line arguments - CommandLine line = parser.parse(args); - - if (line.hasOption("?")) { - usage(parser, line.hasOption("deprecated")); - return null; - } - - if (line.hasOption("version")) { - System.out.println("Apache Ivy " + Ivy.getIvyVersion() + " - " + Ivy.getIvyDate() - + " :: " + Ivy.getIvyHomeURL()); - return null; - } - - boolean validate = line.hasOption("novalidate") ? false : true; - - 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 (int i = 0; i < confs.length; i++) { - dd.addDependencyConfiguration("default", confs[i]); - } - 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() && !line.hasOption("noterminate")) { - System.exit(1); - } - 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.indexOf("[") == -1) { - retrievePattern = retrievePattern + "/lib/[conf]/[artifact].[ext]"; - } - String ivyPattern = settings.substitute(line.getOptionValue("ivypattern")); - ivy.retrieve( - md.getModuleRevisionId(), - retrievePattern, - new RetrieveOptions() - .setConfs(confs) - .setSync(line.hasOption("sync")) - .setUseOrigin(line.hasOption("useOrigin")) - .setDestIvyPattern(ivyPattern) - .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("main")) { - // check if the option cp has been set - List 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 cp option from the command line, and returns a list of {@link File}. - *

- * All the files contained in the returned List exist, non existing files are simply skipped - * with a warning. - *

- * - * @param line - * the command line in which the cp option shold be parsed - * @return a List of files to include as extra classpath entries, or null if no cp - * option was provided. - */ - private static List/* */getExtraClasspathFileList(CommandLine line) { - List fileList = null; - if (line.hasOption("cp")) { - fileList = new ArrayList/* */(); - String[] cpArray = line.getOptionValues("cp"); - for (int index = 0; index < cpArray.length; index++) { - StringTokenizer tokenizer = new StringTokenizer(cpArray[index], - System.getProperty("path.separator")); - 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("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 { - String pathSeparator = System.getProperty("path.separator"); - StringBuffer buf = new StringBuffer(); - Collection all = new LinkedHashSet(); - ResolutionCacheManager cacheMgr = ivy.getResolutionCacheManager(); - XmlReportParser parser = new XmlReportParser(); - for (int i = 0; i < confs.length; i++) { - String resolveId = ResolveOptions.getDefaultResolveId(md); - File report = cacheMgr.getConfigurationResolveReportInCache(resolveId, confs[i]); - parser.parse(report); - - all.addAll(Arrays.asList(parser.getArtifactReports())); - } - for (Iterator iter = all.iterator(); iter.hasNext();) { - ArtifactDownloadReport artifact = (ArtifactDownloadReport) iter.next(); - if (artifact.getLocalFile() != null) { - buf.append(artifact.getLocalFile().getCanonicalPath()); - buf.append(pathSeparator); - } - } - - PrintWriter writer = new PrintWriter(new FileOutputStream(outFile)); - if (buf.length() > 0) { - writer.println(buf.substring(0, buf.length() - pathSeparator.length())); - } - writer.close(); - System.out.println("cachepath output to " + outFile); - - } catch (Exception ex) { - throw new RuntimeException("impossible to build ivy cache path: " + ex.getMessage(), ex); - } - } - - private static void invoke(Ivy ivy, File cache, ModuleDescriptor md, String[] confs, - List fileList, String mainclass, String[] args) { - List urls = new ArrayList(); - - // Add option cp (extra classpath) urls - if (fileList != null && fileList.size() > 0) { - for (Iterator iter = fileList.iterator(); iter.hasNext();) { - File file = (File) iter.next(); - try { - urls.add(file.toURI().toURL()); - } catch (MalformedURLException e) { - // Should not happen, just ignore. - } - } - } - - try { - Collection all = new LinkedHashSet(); - ResolutionCacheManager cacheMgr = ivy.getResolutionCacheManager(); - XmlReportParser parser = new XmlReportParser(); - for (int i = 0; i < confs.length; i++) { - String resolveId = ResolveOptions.getDefaultResolveId(md); - File report = cacheMgr.getConfigurationResolveReportInCache(resolveId, confs[i]); - parser.parse(report); - - all.addAll(Arrays.asList(parser.getArtifactReports())); - } - for (Iterator iter = all.iterator(); iter.hasNext();) { - ArtifactDownloadReport artifact = (ArtifactDownloadReport) iter.next(); - - 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((URL[]) urls.toArray(new URL[urls.size()]), - Main.class.getClassLoader()); - - try { - Class c = classLoader.loadClass(mainclass); - - Method mainMethod = c.getMethod("main", new Class[] {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 e) { - throw new RuntimeException("Could not find main method: " + mainclass, e); - } catch (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(); - URLHandler 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() { - } -} +/* + * 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; + +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.Iterator; +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.retrieve.RetrieveOptions; +import org.apache.ivy.core.settings.IvySettings; +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.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.URLHandler; +import org.apache.ivy.util.url.URLHandlerDispatcher; +import org.apache.ivy.util.url.URLHandlerRegistry; + +/** + * Class used to launch ivy as a standalone tool. + *

+ * 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("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("noterminate").description( + "do not terminate - for programmatic use").create()) + .addOption( + new OptionBuilder("m2compatible").description("use maven2 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("comma separated list of 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()) + + .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("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 { + CommandLineParser parser = getParser(); + try { + run(parser, args); + System.exit(0); + } catch (ParseException ex) { + System.err.println(ex.getMessage()); + usage(parser, false); + System.exit(1); + } + } + + // FIXME - promot upstream - enhancement request + public static ResolveReport run(String[] args) throws Exception { + CommandLineParser parser = getParser(); + return run(parser, args); + } + + // FIXME - promot upstream - enhancement request + static ResolveReport run(CommandLineParser parser, String[] args) throws Exception { + // parse the command line arguments + CommandLine line = parser.parse(args); + + if (line.hasOption("?")) { + usage(parser, line.hasOption("deprecated")); + return null; + } + + if (line.hasOption("version")) { + System.out.println("Apache Ivy " + Ivy.getIvyVersion() + " - " + Ivy.getIvyDate() + + " :: " + Ivy.getIvyHomeURL()); + return null; + } + + boolean validate = line.hasOption("novalidate") ? false : true; + + 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 (int i = 0; i < confs.length; i++) { + dd.addDependencyConfiguration("default", confs[i]); + } + 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() && !line.hasOption("noterminate")) { + System.exit(1); + } + 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.indexOf("[") == -1) { + retrievePattern = retrievePattern + "/lib/[conf]/[artifact].[ext]"; + } + String ivyPattern = settings.substitute(line.getOptionValue("ivypattern")); + ivy.retrieve( + md.getModuleRevisionId(), + retrievePattern, + new RetrieveOptions() + .setConfs(confs) + .setSync(line.hasOption("sync")) + .setUseOrigin(line.hasOption("useOrigin")) + .setDestIvyPattern(ivyPattern) + .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("main")) { + // check if the option cp has been set + List 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 cp option from the command line, and returns a list of {@link File}. + *

+ * All the files contained in the returned List exist, non existing files are simply skipped + * with a warning. + *

+ * + * @param line + * the command line in which the cp option shold be parsed + * @return a List of files to include as extra classpath entries, or null if no cp + * option was provided. + */ + private static List/* */getExtraClasspathFileList(CommandLine line) { + List fileList = null; + if (line.hasOption("cp")) { + fileList = new ArrayList/* */(); + String[] cpArray = line.getOptionValues("cp"); + for (int index = 0; index < cpArray.length; index++) { + StringTokenizer tokenizer = new StringTokenizer(cpArray[index], + System.getProperty("path.separator")); + 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("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 { + String pathSeparator = System.getProperty("path.separator"); + StringBuffer buf = new StringBuffer(); + Collection all = new LinkedHashSet(); + ResolutionCacheManager cacheMgr = ivy.getResolutionCacheManager(); + XmlReportParser parser = new XmlReportParser(); + for (int i = 0; i < confs.length; i++) { + String resolveId = ResolveOptions.getDefaultResolveId(md); + File report = cacheMgr.getConfigurationResolveReportInCache(resolveId, confs[i]); + parser.parse(report); + + all.addAll(Arrays.asList(parser.getArtifactReports())); + } + for (Iterator iter = all.iterator(); iter.hasNext();) { + ArtifactDownloadReport artifact = (ArtifactDownloadReport) iter.next(); + if (artifact.getLocalFile() != null) { + buf.append(artifact.getLocalFile().getCanonicalPath()); + buf.append(pathSeparator); + } + } + + PrintWriter writer = new PrintWriter(new FileOutputStream(outFile)); + if (buf.length() > 0) { + writer.println(buf.substring(0, buf.length() - pathSeparator.length())); + } + writer.close(); + System.out.println("cachepath output to " + outFile); + + } catch (Exception ex) { + throw new RuntimeException("impossible to build ivy cache path: " + ex.getMessage(), ex); + } + } + + private static void invoke(Ivy ivy, File cache, ModuleDescriptor md, String[] confs, + List fileList, String mainclass, String[] args) { + List urls = new ArrayList(); + + // Add option cp (extra classpath) urls + if (fileList != null && fileList.size() > 0) { + for (Iterator iter = fileList.iterator(); iter.hasNext();) { + File file = (File) iter.next(); + try { + urls.add(file.toURI().toURL()); + } catch (MalformedURLException e) { + // Should not happen, just ignore. + } + } + } + + try { + Collection all = new LinkedHashSet(); + ResolutionCacheManager cacheMgr = ivy.getResolutionCacheManager(); + XmlReportParser parser = new XmlReportParser(); + for (int i = 0; i < confs.length; i++) { + String resolveId = ResolveOptions.getDefaultResolveId(md); + File report = cacheMgr.getConfigurationResolveReportInCache(resolveId, confs[i]); + parser.parse(report); + + all.addAll(Arrays.asList(parser.getArtifactReports())); + } + for (Iterator iter = all.iterator(); iter.hasNext();) { + ArtifactDownloadReport artifact = (ArtifactDownloadReport) iter.next(); + + 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((URL[]) urls.toArray(new URL[urls.size()]), + Main.class.getClassLoader()); + + try { + Class c = classLoader.loadClass(mainclass); + + Method mainMethod = c.getMethod("main", new Class[] {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 e) { + throw new RuntimeException("Could not find main method: " + mainclass, e); + } catch (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(); + URLHandler 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() { + } +} From 07d1bf1197d81da1c43b1214f3036c092d410d39 Mon Sep 17 00:00:00 2001 From: grperry Date: Mon, 19 Mar 2018 06:57:00 -0700 Subject: [PATCH 3/8] classifier fix --- .../parser/m2/PomModuleDescriptorBuilder.java | 35 +++++++++++++++++-- test/.gitignore | 1 + 2 files changed, 33 insertions(+), 3 deletions(-) create mode 100644 test/.gitignore diff --git a/src/java/org/apache/ivy/plugins/parser/m2/PomModuleDescriptorBuilder.java b/src/java/org/apache/ivy/plugins/parser/m2/PomModuleDescriptorBuilder.java index 40a007a9e..4703579c2 100644 --- a/src/java/org/apache/ivy/plugins/parser/m2/PomModuleDescriptorBuilder.java +++ b/src/java/org/apache/ivy/plugins/parser/m2/PomModuleDescriptorBuilder.java @@ -40,6 +40,7 @@ import org.apache.ivy.core.module.descriptor.DefaultDependencyDescriptor; import org.apache.ivy.core.module.descriptor.DefaultExcludeRule; import org.apache.ivy.core.module.descriptor.DefaultModuleDescriptor; +import org.apache.ivy.core.module.descriptor.DependencyArtifactDescriptor; import org.apache.ivy.core.module.descriptor.DependencyDescriptor; import org.apache.ivy.core.module.descriptor.ExtraInfoHolder; import org.apache.ivy.core.module.descriptor.License; @@ -292,12 +293,38 @@ public void addDependency(Resource res, PomDependencyData dep) { return; } - DefaultDependencyDescriptor dd = new PomDependencyDescriptor(dep, ivyModuleDescriptor, - moduleRevId); + // Add "new" dependency, or add new artifact to "existing" dependency + // https://issues.apache.org/jira/browse/IVY-1576 + DefaultDependencyDescriptor dd = null; + DependencyDescriptor[] existingDeps = ivyModuleDescriptor.getDependencies(); + + for (int i = 0; i < existingDeps.length; ++i) { + DependencyDescriptor ddt = existingDeps[i]; + ModuleRevisionId existingModuleId = ddt.getDependencyRevisionId(); + + if (existingModuleId.equals(moduleRevId)) { + // dd = ivyModuleDescriptor.getDependency(mRevId); + dd = (DefaultDependencyDescriptor)ddt; + break; + } + } + + if (dd == null) { + // dependency not found create new one + dd = new PomDependencyDescriptor(dep, ivyModuleDescriptor, moduleRevId); + } + scope = (scope == null || scope.length() == 0) ? getDefaultScope(dep) : scope; ConfMapper mapping = (ConfMapper) MAVEN2_CONF_MAPPING.get(scope); mapping.addMappingConfs(dd, dep.isOptional()); Map extraAtt = new HashMap(); + + // If classifier is not null, then potentially its another artifact associated with "this" dependency descriptior. + // The way this is processed however a "new" dependency descriptor comes up and therein lies the problem + // as 3 artifacts have the same dependency descriptor and the 'resolution' will only solve for 1 dependency - although there are + // 3 actual artifacts. So, we should check to see if the DefaultDependencyDescriptor already exists from the + // ivyModuleDescriptor. If it does we add the new artifact with the different classifier value .. + if ((dep.getClassifier() != null) || ((dep.getType() != null) && !"jar".equals(dep.getType()))) { String type = "jar"; @@ -306,6 +333,8 @@ public void addDependency(Resource res, PomDependencyData dep) { } String ext = type; + Message.info(" found classifier : " + dep.getClassifier()); + // if type is 'test-jar', the extension is 'jar' and the classifier is 'tests' // Cfr. http://maven.apache.org/guides/mini/guide-attached-tests.html if ("test-jar".equals(type)) { @@ -708,7 +737,7 @@ private PomDependencyDescriptor(PomDependencyData pomDependencyData, /** * Get PomDependencyData. - * + * * @return PomDependencyData */ public PomDependencyData getPomDependencyData() { diff --git a/test/.gitignore b/test/.gitignore new file mode 100644 index 000000000..9480c586b --- /dev/null +++ b/test/.gitignore @@ -0,0 +1 @@ +/repositories/ From 2f15774dbe6b8fd501fa01a486ce658246cc5d40 Mon Sep 17 00:00:00 2001 From: grperry Date: Wed, 21 Mar 2018 04:37:41 -0700 Subject: [PATCH 4/8] twogee Main update --- src/java/org/apache/ivy/Main.java | 273 ++++++++++++++---------------- 1 file changed, 123 insertions(+), 150 deletions(-) diff --git a/src/java/org/apache/ivy/Main.java b/src/java/org/apache/ivy/Main.java index 3dd1e141b..99977a032 100644 --- a/src/java/org/apache/ivy/Main.java +++ b/src/java/org/apache/ivy/Main.java @@ -70,138 +70,97 @@ 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("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("noterminate").description( - "do not terminate - for programmatic use").create()) - .addOption( - new OptionBuilder("m2compatible").description("use maven2 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()) + return new CommandLineParser().addCategory("settings options") + .addOption(new OptionBuilder("settings").arg("settingsfile") + .description("use given file for 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 maven2 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("comma separated list of 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()) + .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("comma separated list of 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("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()) .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()) + .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()) + .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()) + .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("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()) + .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()) + .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("verbose").description("set message level to verbose") + .create()) .addOption( new OptionBuilder("warn").description("set message level to warn").create()) .addOption( @@ -211,9 +170,8 @@ static CommandLineParser getParser() { .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()); + .addOption(new OptionBuilder("version").description("displays version information") + .create()); } public static void main(String[] args) throws Exception { @@ -228,22 +186,46 @@ public static void main(String[] args) throws Exception { } } - // FIXME - promot upstream - enhancement request public static ResolveReport run(String[] args) throws Exception { - CommandLineParser parser = getParser(); - return run(parser, args); + return run(args, false); } - // FIXME - promot upstream - enhancement request - static ResolveReport run(CommandLineParser parser, String[] args) throws Exception { + /* + * 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 = parser.parse(args); + 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); + } + + // FIXME - promot upstream - enhancement request + static ResolveReport run(CommandLine line, boolean isCli) throws Exception { + if (line.hasOption("version")) { System.out.println("Apache Ivy " + Ivy.getIvyVersion() + " - " + Ivy.getIvyDate() + " :: " + Ivy.getIvyHomeURL()); @@ -257,8 +239,8 @@ static ResolveReport run(CommandLineParser parser, String[] args) throws Excepti IvySettings settings = initSettings(line, ivy); ivy.pushContext(); - File cache = new File(settings.substitute(line.getOptionValue("cache", settings - .getDefaultCache().getAbsolutePath()))); + 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 @@ -283,9 +265,8 @@ static ResolveReport run(CommandLineParser parser, String[] args) throws Excepti String[] dep = line.getOptionValues("dependency"); ivyfile = File.createTempFile("ivy", ".xml"); ivyfile.deleteOnExit(); - DefaultModuleDescriptor md = DefaultModuleDescriptor - .newDefaultInstance(ModuleRevisionId.newInstance(dep[0], dep[1] + "-caller", - "working")); + 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 (int i = 0; i < confs.length; i++) { @@ -306,11 +287,8 @@ static ResolveReport run(CommandLineParser parser, String[] args) throws Excepti if (line.hasOption("useOrigin")) { ivy.getSettings().useDeprecatedUseOrigin(); } - ResolveOptions resolveOptions = new ResolveOptions() - .setConfs(confs) - .setValidate(validate) - .setResolveMode(line.getOptionValue("mode")) - .setArtifactFilter( + 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); @@ -333,14 +311,9 @@ static ResolveReport run(CommandLineParser parser, String[] args) throws Excepti retrievePattern = retrievePattern + "/lib/[conf]/[artifact].[ext]"; } String ivyPattern = settings.substitute(line.getOptionValue("ivypattern")); - ivy.retrieve( - md.getModuleRevisionId(), - retrievePattern, - new RetrieveOptions() - .setConfs(confs) - .setSync(line.hasOption("sync")) - .setUseOrigin(line.hasOption("useOrigin")) - .setDestIvyPattern(ivyPattern) + ivy.retrieve(md.getModuleRevisionId(), retrievePattern, + new RetrieveOptions().setConfs(confs).setSync(line.hasOption("sync")) + .setUseOrigin(line.hasOption("useOrigin")).setDestIvyPattern(ivyPattern) .setArtifactFilter( FilterHelper.getArtifactTypeFilter(line.getOptionValues("types"))) .setMakeSymlinks(line.hasOption("symlink")) @@ -352,25 +325,22 @@ static ResolveReport run(CommandLineParser parser, String[] args) throws Excepti } if (line.hasOption("revision")) { - ivy.deliver( - md.getResolvedModuleRevisionId(), + 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(), + 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"))) + .setSrcIvyPattern(settings.substitute( + line.getOptionValue("deliverto", "ivy-[revision].xml"))) .setOverwrite(line.hasOption("overwrite"))); } } @@ -411,7 +381,7 @@ static ResolveReport run(CommandLineParser parser, String[] args) throws Excepti * @return a List of files to include as extra classpath entries, or null if no cp * option was provided. */ - private static List/* */getExtraClasspathFileList(CommandLine line) { + private static List/* */ getExtraClasspathFileList(CommandLine line) { List fileList = null; if (line.hasOption("cp")) { fileList = new ArrayList/* */(); @@ -425,8 +395,8 @@ static ResolveReport run(CommandLineParser parser, String[] args) throws Excepti if (file.exists()) { fileList.add(file); } else { - Message.warn("Skipping extra classpath '" + file - + "' as it does not exist."); + Message.warn( + "Skipping extra classpath '" + file + "' as it does not exist."); } } } @@ -511,7 +481,8 @@ private static void outputCachePath(Ivy ivy, File cache, ModuleDescriptor md, St System.out.println("cachepath output to " + outFile); } catch (Exception ex) { - throw new RuntimeException("impossible to build ivy cache path: " + ex.getMessage(), ex); + throw new RuntimeException("impossible to build ivy cache path: " + ex.getMessage(), + ex); } } @@ -550,7 +521,8 @@ private static void invoke(Ivy ivy, File cache, ModuleDescriptor md, String[] co } } } catch (Exception ex) { - throw new RuntimeException("impossible to build ivy cache path: " + ex.getMessage(), ex); + throw new RuntimeException("impossible to build ivy cache path: " + ex.getMessage(), + ex); } URLClassLoader classLoader = new URLClassLoader((URL[]) urls.toArray(new URL[urls.size()]), @@ -572,7 +544,8 @@ private static void invoke(Ivy ivy, File cache, ModuleDescriptor md, String[] co } 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); + throw new RuntimeException("Unexpected exception invoking main method: " + mainclass, + e); } } From c9c5fcaba0a5b4d6dc63849aa5892b956da1f71c Mon Sep 17 00:00:00 2001 From: GRPERRY Date: Tue, 27 Mar 2018 07:13:18 -0700 Subject: [PATCH 5/8] POM Builder adding default / master artifact for each dependency --- .../parser/m2/PomModuleDescriptorBuilder.java | 139 ++++++++++-------- 1 file changed, 79 insertions(+), 60 deletions(-) diff --git a/src/java/org/apache/ivy/plugins/parser/m2/PomModuleDescriptorBuilder.java b/src/java/org/apache/ivy/plugins/parser/m2/PomModuleDescriptorBuilder.java index 4703579c2..dba479709 100644 --- a/src/java/org/apache/ivy/plugins/parser/m2/PomModuleDescriptorBuilder.java +++ b/src/java/org/apache/ivy/plugins/parser/m2/PomModuleDescriptorBuilder.java @@ -40,7 +40,6 @@ import org.apache.ivy.core.module.descriptor.DefaultDependencyDescriptor; import org.apache.ivy.core.module.descriptor.DefaultExcludeRule; import org.apache.ivy.core.module.descriptor.DefaultModuleDescriptor; -import org.apache.ivy.core.module.descriptor.DependencyArtifactDescriptor; import org.apache.ivy.core.module.descriptor.DependencyDescriptor; import org.apache.ivy.core.module.descriptor.ExtraInfoHolder; import org.apache.ivy.core.module.descriptor.License; @@ -73,14 +72,13 @@ public class PomModuleDescriptorBuilder { new String[] {"runtime", "master"}, true, null), new Configuration("master", Visibility.PUBLIC, "contains only the artifact published by this module itself, " - + "with no transitive dependencies", new String[0], true, null), + + "with no transitive dependencies", + new String[0], true, null), new Configuration("compile", Visibility.PUBLIC, "this is the default scope, used if none is specified. " + "Compile dependencies are available in all classpaths.", new String[0], true, null), - new Configuration( - "provided", - Visibility.PUBLIC, + new Configuration("provided", Visibility.PUBLIC, "this is much like compile, but indicates you expect the JDK or a container " + "to provide it. " + "It is only available on the compilation classpath, and is not transitive.", @@ -88,20 +86,18 @@ public class PomModuleDescriptorBuilder { new Configuration("runtime", Visibility.PUBLIC, "this scope indicates that the dependency is not required for compilation, " + "but is for execution. It is in the runtime and test classpaths, " - + "but not the compile classpath.", new String[] {"compile"}, true, - null), - new Configuration( - "test", - Visibility.PRIVATE, + + "but not the compile classpath.", + new String[] {"compile"}, true, null), + new Configuration("test", Visibility.PRIVATE, "this scope indicates that the dependency is not required for normal use of " + "the application, and is only available for the test compilation and " - + "execution phases.", new String[] {"runtime"}, true, null), - new Configuration( - "system", - Visibility.PUBLIC, + + "execution phases.", + new String[] {"runtime"}, true, null), + new Configuration("system", Visibility.PUBLIC, "this scope is similar to provided except that you have to provide the JAR " + "which contains it explicitly. The artifact is always available and is not " - + "looked up in a repository.", new String[0], true, null), + + "looked up in a repository.", + new String[0], true, null), new Configuration("sources", Visibility.PUBLIC, "this configuration contains the source artifact of this module, if any.", new String[0], true, null), @@ -119,9 +115,9 @@ public class PomModuleDescriptorBuilder { private static final String EXTRA_INFO_DELIMITER = "__"; - private static final Collection/* */JAR_PACKAGINGS = Arrays.asList(new String[] { - "ejb", "bundle", "maven-plugin", "eclipse-plugin", "jbi-component", - "jbi-shared-library", "orbit", "hk2-jar"}); + private static final Collection/* */ JAR_PACKAGINGS = Arrays + .asList(new String[] {"ejb", "bundle", "maven-plugin", "eclipse-plugin", + "jbi-component", "jbi-shared-library", "orbit", "hk2-jar"}); static interface ConfMapper { public void addMappingConfs(DefaultDependencyDescriptor dd, boolean isOptional); @@ -299,19 +295,19 @@ public void addDependency(Resource res, PomDependencyData dep) { DependencyDescriptor[] existingDeps = ivyModuleDescriptor.getDependencies(); for (int i = 0; i < existingDeps.length; ++i) { - DependencyDescriptor ddt = existingDeps[i]; - ModuleRevisionId existingModuleId = ddt.getDependencyRevisionId(); + DependencyDescriptor ddt = existingDeps[i]; + ModuleRevisionId existingModuleId = ddt.getDependencyRevisionId(); - if (existingModuleId.equals(moduleRevId)) { - // dd = ivyModuleDescriptor.getDependency(mRevId); - dd = (DefaultDependencyDescriptor)ddt; - break; - } + if (existingModuleId.equals(moduleRevId)) { + // dd = ivyModuleDescriptor.getDependency(mRevId); + dd = (DefaultDependencyDescriptor) ddt; + break; + } } if (dd == null) { - // dependency not found create new one - dd = new PomDependencyDescriptor(dep, ivyModuleDescriptor, moduleRevId); + // dependency not found create new one + dd = new PomDependencyDescriptor(dep, ivyModuleDescriptor, moduleRevId); } scope = (scope == null || scope.length() == 0) ? getDefaultScope(dep) : scope; @@ -319,12 +315,17 @@ public void addDependency(Resource res, PomDependencyData dep) { mapping.addMappingConfs(dd, dep.isOptional()); Map extraAtt = new HashMap(); - // If classifier is not null, then potentially its another artifact associated with "this" dependency descriptior. - // The way this is processed however a "new" dependency descriptor comes up and therein lies the problem - // as 3 artifacts have the same dependency descriptor and the 'resolution' will only solve for 1 dependency - although there are - // 3 actual artifacts. So, we should check to see if the DefaultDependencyDescriptor already exists from the - // ivyModuleDescriptor. If it does we add the new artifact with the different classifier value .. - + // If classifier is not null, then potentially its another artifact associated with "this" + // dependency descriptior. + // The way this is processed however a "new" dependency descriptor comes up and therein lies + // the problem + // as 3 artifacts have the same dependency descriptor and the 'resolution' will only solve + // for 1 dependency - although there are + // 3 actual artifacts. So, we should check to see if the DefaultDependencyDescriptor already + // exists from the + // ivyModuleDescriptor. If it does we add the new artifact with the different classifier + // value .. + Message.info(dd.toString()); if ((dep.getClassifier() != null) || ((dep.getType() != null) && !"jar".equals(dep.getType()))) { String type = "jar"; @@ -355,13 +356,28 @@ public void addDependency(Resource res, PomDependencyData dep) { // compared to how m2 behave with classifiers String optionalizedScope = dep.isOptional() ? "optional" : scope; dd.addDependencyArtifact(optionalizedScope, depArtifact); + } else { + // non-classifier "default"/master artifact + // add it ? + + String type = "jar"; + if (dep.getType() != null) { + type = dep.getType(); + } + String ext = type; + + Message.info(" found master : " + dep); + String optionalizedScope = dep.isOptional() ? "optional" : scope; + DefaultDependencyArtifactDescriptor depArtifact = new DefaultDependencyArtifactDescriptor( + dd, dd.getDependencyId().getName(), type, ext, null, extraAtt); + dd.addDependencyArtifact(optionalizedScope, depArtifact); } // experimentation shows the following, excluded modules are // inherited from parent POMs if either of the following is true: // the element is missing or the element // is present, but empty. - List /* */excluded = dep.getExcludedModules(); + List /* */ excluded = dep.getExcludedModules(); if (excluded.isEmpty()) { excluded = getDependencyMgtExclusions(ivyModuleDescriptor, dep.getGroupId(), dep.getArtifactId()); @@ -370,13 +386,16 @@ public void addDependency(Resource res, PomDependencyData dep) { ModuleId excludedModule = (ModuleId) itExcl.next(); String[] confs = dd.getModuleConfigurations(); for (int k = 0; k < confs.length; k++) { - dd.addExcludeRule(confs[k], new DefaultExcludeRule(new ArtifactId(excludedModule, - PatternMatcher.ANY_EXPRESSION, PatternMatcher.ANY_EXPRESSION, - PatternMatcher.ANY_EXPRESSION), ExactPatternMatcher.INSTANCE, null)); + dd.addExcludeRule(confs[k], + new DefaultExcludeRule( + new ArtifactId(excludedModule, PatternMatcher.ANY_EXPRESSION, + PatternMatcher.ANY_EXPRESSION, PatternMatcher.ANY_EXPRESSION), + ExactPatternMatcher.INSTANCE, null)); } } ivyModuleDescriptor.addDependency(dd); + Message.info("added dependency " + dd.toString()); } public void addDependency(DependencyDescriptor descriptor) { @@ -409,10 +428,8 @@ public void addDependencyMgt(PomDependencyMgt dep) { int index = 0; for (final Iterator iter = dep.getExcludedModules().iterator(); iter.hasNext();) { final ModuleId excludedModule = (ModuleId) iter.next(); - overwriteExtraInfoIfExists( - exclusionPrefix + index, - excludedModule.getOrganisation() + EXTRA_INFO_DELIMITER - + excludedModule.getName()); + overwriteExtraInfoIfExists(exclusionPrefix + index, excludedModule.getOrganisation() + + EXTRA_INFO_DELIMITER + excludedModule.getName()); index += 1; } } @@ -442,7 +459,7 @@ public void addPlugin(PomDependencyMgt plugin) { extraInfoByTagName.setContent(pluginExtraInfo); } - public static List /* */getPlugins(ModuleDescriptor md) { + public static List /* */ getPlugins(ModuleDescriptor md) { List result = new ArrayList(); String plugins = md.getExtraInfoContentByTagName("m:maven.plugins"); if (plugins == null) { @@ -486,7 +503,7 @@ public String getScope() { return null; } - public List /* */getExcludedModules() { + public List /* */ getExcludedModules() { return Collections.EMPTY_LIST; // probably not used? } } @@ -494,8 +511,8 @@ public String getScope() { private String getDefaultVersion(PomDependencyData dep) { ModuleId moduleId = ModuleId.newInstance(dep.getGroupId(), dep.getArtifactId()); if (ivyModuleDescriptor.getDependencyManagementMap().containsKey(moduleId)) { - return ((PomDependencyMgt) ivyModuleDescriptor.getDependencyManagementMap().get( - moduleId)).getVersion(); + return ((PomDependencyMgt) ivyModuleDescriptor.getDependencyManagementMap() + .get(moduleId)).getVersion(); } String key = getDependencyMgtExtraInfoKeyForVersion(dep.getGroupId(), dep.getArtifactId()); return ivyModuleDescriptor.getExtraInfoContentByTagName(key); @@ -505,10 +522,11 @@ private String getDefaultScope(PomDependencyData dep) { String result; ModuleId moduleId = ModuleId.newInstance(dep.getGroupId(), dep.getArtifactId()); if (ivyModuleDescriptor.getDependencyManagementMap().containsKey(moduleId)) { - result = ((PomDependencyMgt) ivyModuleDescriptor.getDependencyManagementMap().get( - moduleId)).getScope(); + result = ((PomDependencyMgt) ivyModuleDescriptor.getDependencyManagementMap() + .get(moduleId)).getScope(); } else { - String key = getDependencyMgtExtraInfoKeyForScope(dep.getGroupId(), dep.getArtifactId()); + String key = getDependencyMgtExtraInfoKeyForScope(dep.getGroupId(), + dep.getArtifactId()); result = ivyModuleDescriptor.getExtraInfoContentByTagName(key); } if ((result == null) || !MAVEN2_CONF_MAPPING.containsKey(result)) { @@ -517,7 +535,8 @@ private String getDefaultScope(PomDependencyData dep) { return result; } - private static String getDependencyMgtExtraInfoKeyForVersion(String groupId, String artifaceId) { + private static String getDependencyMgtExtraInfoKeyForVersion(String groupId, + String artifaceId) { return DEPENDENCY_MANAGEMENT + EXTRA_INFO_DELIMITER + groupId + EXTRA_INFO_DELIMITER + artifaceId + EXTRA_INFO_DELIMITER + "version"; } @@ -537,7 +556,7 @@ private static String getDependencyMgtExtraInfoPrefixForExclusion(String groupId + artifaceId + EXTRA_INFO_DELIMITER + "exclusion_"; } - private static List /* */getDependencyMgtExclusions(ModuleDescriptor descriptor, + private static List /* */ getDependencyMgtExclusions(ModuleDescriptor descriptor, String groupId, String artifactId) { if (descriptor instanceof PomModuleDescriptor) { PomDependencyMgt dependencyMgt = (PomDependencyMgt) ((PomModuleDescriptor) descriptor) @@ -547,15 +566,15 @@ private static String getDependencyMgtExtraInfoPrefixForExclusion(String groupId } } String exclusionPrefix = getDependencyMgtExtraInfoPrefixForExclusion(groupId, artifactId); - List /* */exclusionIds = new LinkedList /* */(); + List /* */ exclusionIds = new LinkedList /* */(); for (ExtraInfoHolder extraInfoHolder : descriptor.getExtraInfos()) { String key = extraInfoHolder.getName(); if (key.startsWith(exclusionPrefix)) { String fullExclusion = extraInfoHolder.getContent(); String[] exclusionParts = fullExclusion.split(EXTRA_INFO_DELIMITER); if (exclusionParts.length != 2) { - Message.error(WRONG_NUMBER_OF_PARTS_MSG + exclusionParts.length + " : " - + fullExclusion); + Message.error( + WRONG_NUMBER_OF_PARTS_MSG + exclusionParts.length + " : " + fullExclusion); continue; } exclusionIds.add(ModuleId.newInstance(exclusionParts[0], exclusionParts[1])); @@ -565,7 +584,7 @@ private static String getDependencyMgtExtraInfoPrefixForExclusion(String groupId } public static Map/* */ - getDependencyManagementMap(ModuleDescriptor md) { + getDependencyManagementMap(ModuleDescriptor md) { Map ret = new LinkedHashMap(); if (md instanceof PomModuleDescriptor) { for (final Iterator iterator = ((PomModuleDescriptor) md).getDependencyManagementMap() @@ -615,7 +634,7 @@ public static List getDependencyManagements(ModuleDescriptor md) { String version = md.getExtraInfoContentByTagName(versionKey); String scope = md.getExtraInfoContentByTagName(scopeKey); - List /* */exclusions = getDependencyMgtExclusions(md, parts[1], + List /* */ exclusions = getDependencyMgtExclusions(md, parts[1], parts[2]); result.add(new DefaultPomDependencyMgt(parts[1], parts[2], version, scope, exclusions)); @@ -667,8 +686,8 @@ public static Map extractPomProperties(Map extraInfo) { for (Iterator it = extraInfo.entrySet().iterator(); it.hasNext();) { Map.Entry extraInfoEntry = (Map.Entry) it.next(); if (((String) extraInfoEntry.getKey()).startsWith(PROPERTIES)) { - String prop = ((String) extraInfoEntry.getKey()).substring(PROPERTIES.length() - + EXTRA_INFO_DELIMITER.length()); + String prop = ((String) extraInfoEntry.getKey()) + .substring(PROPERTIES.length() + EXTRA_INFO_DELIMITER.length()); r.put(prop, extraInfoEntry.getValue()); } } @@ -679,8 +698,8 @@ public static Map extractPomProperties(List extraInfos) { Map r = new HashMap(); for (ExtraInfoHolder extraInfoHolder : extraInfos) { if ((extraInfoHolder.getName()).startsWith(PROPERTIES)) { - String prop = (extraInfoHolder.getName()).substring(PROPERTIES.length() - + EXTRA_INFO_DELIMITER.length()); + String prop = (extraInfoHolder.getName()) + .substring(PROPERTIES.length() + EXTRA_INFO_DELIMITER.length()); r.put(prop, extraInfoHolder.getContent()); } } @@ -746,7 +765,7 @@ public PomDependencyData getPomDependencyData() { } public static class PomModuleDescriptor extends DefaultModuleDescriptor { - private final Map/* */dependencyManagementMap = new HashMap(); + private final Map/* */ dependencyManagementMap = new HashMap(); public PomModuleDescriptor(ModuleDescriptorParser parser, Resource res) { super(parser, res); From 9d014972c78f8cade3a3d18075bf4e2022765d58 Mon Sep 17 00:00:00 2001 From: GRPERRY Date: Wed, 28 Mar 2018 07:49:11 -0700 Subject: [PATCH 6/8] xooki - whatever that is .. --- doc/xooki | 1 - 1 file changed, 1 deletion(-) delete mode 160000 doc/xooki diff --git a/doc/xooki b/doc/xooki deleted file mode 160000 index 38eff00e6..000000000 --- a/doc/xooki +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 38eff00e65ec74803838b52a111cab542cb80bca From d06e3bcf41e94bf12daef06b0c066e9e05e10663 Mon Sep 17 00:00:00 2001 From: gperry Date: Mon, 9 Apr 2018 07:11:05 -0700 Subject: [PATCH 7/8] Main.setLogger - fix for setting an external logger --- src/java/org/apache/ivy/Main.java | 35 +++++++++++++++++++++++-------- 1 file changed, 26 insertions(+), 9 deletions(-) diff --git a/src/java/org/apache/ivy/Main.java b/src/java/org/apache/ivy/Main.java index 99977a032..cad034f7c 100644 --- a/src/java/org/apache/ivy/Main.java +++ b/src/java/org/apache/ivy/Main.java @@ -49,6 +49,7 @@ import org.apache.ivy.core.settings.IvySettings; import org.apache.ivy.plugins.parser.xml.XmlModuleDescriptorWriter; import org.apache.ivy.plugins.report.XmlReportParser; +import org.apache.ivy.util.AbstractMessageLogger; import org.apache.ivy.util.DefaultMessageLogger; import org.apache.ivy.util.Message; import org.apache.ivy.util.cli.CommandLine; @@ -69,6 +70,8 @@ public final class Main { private static final int HELP_WIDTH = 80; + private static AbstractMessageLogger externalLogger = null; + static CommandLineParser getParser() { return new CommandLineParser().addCategory("settings options") .addOption(new OptionBuilder("settings").arg("settingsfile") @@ -437,16 +440,20 @@ private static IvySettings initSettings(CommandLine line, Ivy ivy) } 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)); + if (externalLogger != null) { + ivy.getLoggerEngine().pushLogger(externalLogger); } else { - ivy.getLoggerEngine().pushLogger(new DefaultMessageLogger(Message.MSG_INFO)); + 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)); + } } } @@ -573,4 +580,14 @@ private static void usage(CommandLineParser parser, boolean showDeprecated) { private Main() { } + + /** + * setLogger will send logging to an 'externally' defined logger + * + * @param logger + */ + public static void setLogger(AbstractMessageLogger logger) { + externalLogger = logger; + } + } From dc4e5daf7595f173ddf52e49da91a00b14cb188c Mon Sep 17 00:00:00 2001 From: GroG Date: Sun, 29 Sep 2019 15:35:58 -0700 Subject: [PATCH 8/8] if not cli do not exit --- src/java/org/apache/ivy/Main.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/java/org/apache/ivy/Main.java b/src/java/org/apache/ivy/Main.java index cad034f7c..94c04aca1 100644 --- a/src/java/org/apache/ivy/Main.java +++ b/src/java/org/apache/ivy/Main.java @@ -300,7 +300,7 @@ static ResolveReport run(CommandLine line, boolean isCli) throws Exception { resolveOptions.setRefresh(true); } ResolveReport report = ivy.resolve(ivyfile.toURI().toURL(), resolveOptions); - if (report.hasError() && !line.hasOption("noterminate")) { + if (report.hasError() && isCli) { System.exit(1); } ModuleDescriptor md = report.getModuleDescriptor();