blob: c700421bb29c0b6854289650758b36c334ab43db [file] [log] [blame]
/*
* 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.ant;
import java.io.File;
import java.net.MalformedURLException;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import org.apache.ivy.Ivy;
import org.apache.ivy.core.LogOptions;
import org.apache.ivy.core.module.descriptor.DefaultExcludeRule;
import org.apache.ivy.core.module.descriptor.DefaultModuleDescriptor;
import org.apache.ivy.core.module.descriptor.DependencyDescriptor;
import org.apache.ivy.core.module.descriptor.ExtendsDescriptor;
import org.apache.ivy.core.module.descriptor.ModuleDescriptor;
import org.apache.ivy.core.module.id.ModuleRevisionId;
import org.apache.ivy.core.report.ResolveReport;
import org.apache.ivy.core.resolve.ResolveOptions;
import org.apache.ivy.core.resolve.ResolveProcessException;
import org.apache.ivy.core.settings.IvySettings;
import org.apache.ivy.util.Message;
import org.apache.ivy.util.filter.FilterHelper;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Project;
/**
* This task allow to call the Ivy dependency resolution from ant.
*/
public class IvyResolve extends IvyTask {
private File file = null;
private String conf = null;
private String organisation = null;
private String module = null;
private String branch = null;
private String revision = null;
private String pubdate = null;
private boolean inline = false;
private boolean haltOnFailure = true;
private boolean showProgress = true;
private boolean useCacheOnly = false;
private String type = null;
private boolean transitive = true;
private boolean refresh = false;
private boolean changing = false;
private Boolean keep = null;
private String failureProperty = null;
private boolean useOrigin = false;
private String resolveMode = null;
private String resolveId = null;
private String log = ResolveOptions.LOG_DEFAULT;
private boolean checkIfChanged = true; // for backward compatibility
private List<IvyDependency> dependencies = new ArrayList<IvyDependency>();
private List<IvyExclude> excludes = new ArrayList<IvyExclude>();
private List<IvyConflict> conflicts = new ArrayList<IvyConflict>();
public boolean isUseOrigin() {
return useOrigin;
}
public void setUseOrigin(boolean useOrigin) {
this.useOrigin = useOrigin;
}
public String getDate() {
return pubdate;
}
public void setDate(String pubdate) {
this.pubdate = pubdate;
}
public String getRevision() {
return revision;
}
public void setRevision(String revision) {
this.revision = revision;
}
public String getBranch() {
return branch;
}
public void setBranch(String branch) {
this.branch = branch;
}
public void setCache(File cache) {
cacheAttributeNotSupported();
}
public String getConf() {
return conf;
}
public void setConf(String conf) {
this.conf = conf;
}
public File getFile() {
return file;
}
public void setFile(File file) {
this.file = file;
}
public boolean isHaltonfailure() {
return haltOnFailure;
}
public void setHaltonfailure(boolean haltOnFailure) {
this.haltOnFailure = haltOnFailure;
}
public void setShowprogress(boolean show) {
this.showProgress = show;
}
public boolean isUseCacheOnly() {
return useCacheOnly;
}
public void setUseCacheOnly(boolean useCacheOnly) {
this.useCacheOnly = useCacheOnly;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public boolean isRefresh() {
return refresh;
}
public void setRefresh(boolean refresh) {
this.refresh = refresh;
}
public String getLog() {
return log;
}
public void setLog(String log) {
this.log = log;
}
/**
* @deprecated Use {@link #setFailureProperty(String)} instead
*/
@Deprecated
public void setFailurePropery(String failureProperty) {
log("The 'failurepropery' attribute is deprecated. "
+ "Please use the 'failureproperty' attribute instead", Project.MSG_WARN);
setFailureProperty(failureProperty);
}
public void setFailureProperty(String failureProperty) {
this.failureProperty = failureProperty;
}
public String getFailureProperty() {
return failureProperty;
}
public IvyDependency createDependency() {
IvyDependency dep = new IvyDependency();
dependencies.add(dep);
return dep;
}
public IvyExclude createExclude() {
IvyExclude ex = new IvyExclude();
excludes.add(ex);
return ex;
}
public IvyConflict createConflict() {
IvyConflict c = new IvyConflict();
conflicts.add(c);
return c;
}
@Override
protected void prepareTask() {
super.prepareTask();
Message.setShowProgress(showProgress);
}
@Override
public void doExecute() throws BuildException {
Ivy ivy = getIvyInstance();
IvySettings settings = ivy.getSettings();
try {
conf = getProperty(conf, settings, "ivy.configurations");
type = getProperty(type, settings, "ivy.resolve.default.type.filter");
String[] confs = splitConfs(conf);
boolean childs = !dependencies.isEmpty() || !excludes.isEmpty() || !conflicts.isEmpty();
ResolveReport report;
if (childs) {
if (isInline()) {
throw new BuildException("the inline mode is incompatible with child elements");
}
if (organisation != null) {
throw new BuildException("'organisation' is not allowed with child elements");
}
if (module != null) {
throw new BuildException("'module' is not allowed with child elements");
}
if (file != null) {
throw new BuildException("'file' not allowed with child elements");
}
if (!getAllowedLogOptions().contains(log)) {
throw new BuildException("invalid option for 'log': " + log
+ ". Available options are " + getAllowedLogOptions());
}
ModuleRevisionId mrid = ModuleRevisionId.newInstance("", "",
Ivy.getWorkingRevision());
DefaultModuleDescriptor md = DefaultModuleDescriptor.newBasicInstance(mrid, null);
for (IvyDependency dep : dependencies) {
DependencyDescriptor dd = dep.asDependencyDescriptor(md, "default", settings);
md.addDependency(dd);
}
for (IvyExclude exclude : excludes) {
DefaultExcludeRule rule = exclude.asRule(settings);
rule.addConfiguration("default");
md.addExcludeRule(rule);
}
for (IvyConflict conflict : conflicts) {
conflict.addConflict(md, settings);
}
report = ivy
.resolve(md, getResolveOptions(ivy, new String[] {"default"}, settings));
} else if (isInline()) {
if (organisation == null) {
throw new BuildException("'organisation' is required when using inline mode");
}
if (module == null) {
throw new BuildException("'module' is required when using inline mode");
}
if (file != null) {
throw new BuildException("'file' not allowed when using inline mode");
}
if (!getAllowedLogOptions().contains(log)) {
throw new BuildException("invalid option for 'log': " + log
+ ". Available options are " + getAllowedLogOptions());
}
for (int i = 0; i < confs.length; i++) {
if ("*".equals(confs[i])) {
confs[i] = "*(public)";
}
}
if (revision == null) {
revision = "latest.integration";
}
report = ivy.resolve(
ModuleRevisionId.newInstance(organisation, module, branch, revision),
getResolveOptions(ivy, confs, settings), changing);
} else {
if (organisation != null) {
throw new BuildException(
"'organisation' not allowed when not using 'org' attribute");
}
if (module != null) {
throw new BuildException("'module' not allowed when not using 'org' attribute");
}
if (file == null) {
file = getProject().resolveFile(getProperty(settings, "ivy.dep.file"));
}
report = ivy.resolve(file.toURI().toURL(), getResolveOptions(ivy, confs, settings));
}
if (report.hasError()) {
if (failureProperty != null) {
getProject().setProperty(failureProperty, "true");
}
if (isHaltonfailure()) {
throw new BuildException("resolve failed - see output for details");
}
}
setResolved(report, resolveId, isKeep());
confs = report.getConfigurations();
if (isKeep()) {
ModuleDescriptor md = report.getModuleDescriptor();
// put resolved infos in ant properties and ivy variables
// putting them in ivy variables is important to be able to change from one resolve
// call to the other
String mdOrg = md.getModuleRevisionId().getOrganisation();
String mdName = md.getModuleRevisionId().getName();
String mdRev = md.getResolvedModuleRevisionId().getRevision();
getProject().setProperty("ivy.organisation", mdOrg);
settings.setVariable("ivy.organisation", mdOrg);
getProject().setProperty("ivy.module", mdName);
settings.setVariable("ivy.module", mdName);
getProject().setProperty("ivy.revision", mdRev);
settings.setVariable("ivy.revision", mdRev);
for (int i = 0; i < md.getInheritedDescriptors().length; i++) {
ExtendsDescriptor parent = md.getInheritedDescriptors()[i];
String parentOrg = parent.getResolvedParentRevisionId().getOrganisation();
String parentModule = parent.getResolvedParentRevisionId().getName();
String parentRevision = parent.getResolvedParentRevisionId().getRevision();
String parentBranch = parent.getResolvedParentRevisionId().getBranch();
getProject().setProperty("ivy.parent[" + i + "].organisation", parentOrg);
settings.setVariable("ivy.parent[" + i + "].organisation", parentOrg);
getProject().setProperty("ivy.parent[" + i + "].module", parentModule);
settings.setVariable("ivy.parent[" + i + "].module", parentModule);
getProject().setProperty("ivy.parent[" + i + "].revision", parentRevision);
settings.setVariable("ivy.parent[" + i + "].revision", parentRevision);
if (parentBranch != null) {
getProject().setProperty("ivy.parent[" + i + "].branch", parentBranch);
settings.setVariable("ivy.parent[" + i + "].branch", parentBranch);
}
}
getProject().setProperty("ivy.parents.count",
String.valueOf(md.getInheritedDescriptors().length));
settings.setVariable("ivy.parents.count",
String.valueOf(md.getInheritedDescriptors().length));
Boolean hasChanged = null;
if (getCheckIfChanged()) {
hasChanged = Boolean.valueOf(report.hasChanged());
getProject().setProperty("ivy.deps.changed", hasChanged.toString());
settings.setVariable("ivy.deps.changed", hasChanged.toString());
}
getProject().setProperty("ivy.resolved.configurations", mergeConfs(confs));
settings.setVariable("ivy.resolved.configurations", mergeConfs(confs));
if (file != null) {
getProject().setProperty("ivy.resolved.file", file.getAbsolutePath());
settings.setVariable("ivy.resolved.file", file.getAbsolutePath());
}
if (resolveId != null) {
getProject().setProperty("ivy.organisation." + resolveId, mdOrg);
settings.setVariable("ivy.organisation." + resolveId, mdOrg);
getProject().setProperty("ivy.module." + resolveId, mdName);
settings.setVariable("ivy.module." + resolveId, mdName);
getProject().setProperty("ivy.revision." + resolveId, mdRev);
settings.setVariable("ivy.revision." + resolveId, mdRev);
if (getCheckIfChanged()) {
// hasChanged has already been set earlier
getProject().setProperty("ivy.deps.changed." + resolveId,
hasChanged.toString());
settings.setVariable("ivy.deps.changed." + resolveId, hasChanged.toString());
}
getProject().setProperty("ivy.resolved.configurations." + resolveId,
mergeConfs(confs));
settings.setVariable("ivy.resolved.configurations." + resolveId,
mergeConfs(confs));
if (file != null) {
getProject().setProperty("ivy.resolved.file." + resolveId,
file.getAbsolutePath());
settings.setVariable("ivy.resolved.file." + resolveId,
file.getAbsolutePath());
}
}
}
} catch (MalformedURLException e) {
throw new BuildException("unable to convert given ivy file to url: " + file + ": " + e,
e);
} catch (ParseException e) {
log(e.getMessage(), Project.MSG_ERR);
throw new BuildException("syntax errors in ivy file: " + e, e);
} catch (ResolveProcessException e) {
throw new BuildException("impossible to resolve dependencies:\n\t" + e.getMessage(), e);
} catch (Exception e) {
throw new BuildException("impossible to resolve dependencies:\n\t" + e, e);
}
}
protected Collection<String> getAllowedLogOptions() {
return Arrays.asList(LogOptions.LOG_DEFAULT, LogOptions.LOG_DOWNLOAD_ONLY,
LogOptions.LOG_QUIET);
}
private ResolveOptions getResolveOptions(Ivy ivy, String[] confs, IvySettings settings) {
if (useOrigin) {
settings.useDeprecatedUseOrigin();
}
return ((ResolveOptions) new ResolveOptions().setLog(log)).setConfs(confs)
.setValidate(doValidate(settings))
.setArtifactFilter(FilterHelper.getArtifactTypeFilter(type)).setRevision(revision)
.setDate(getPubDate(pubdate, null)).setUseCacheOnly(useCacheOnly)
.setRefresh(refresh).setTransitive(transitive).setResolveMode(resolveMode)
.setResolveId(resolveId).setCheckIfChanged(checkIfChanged);
}
public String getModule() {
return module;
}
public void setModule(String module) {
this.module = module;
}
public String getOrganisation() {
return organisation;
}
public void setOrganisation(String organisation) {
this.organisation = organisation;
}
public boolean isTransitive() {
return transitive;
}
public void setTransitive(boolean transitive) {
this.transitive = transitive;
}
public boolean isChanging() {
return changing;
}
public void setChanging(boolean changing) {
this.changing = changing;
}
public boolean isKeep() {
return keep == null ? organisation == null : keep.booleanValue();
}
public void setKeep(boolean keep) {
this.keep = Boolean.valueOf(keep);
}
public boolean isInline() {
return inline;
}
public void setInline(boolean inline) {
this.inline = inline;
}
public String getResolveId() {
return resolveId;
}
public void setResolveId(String resolveId) {
this.resolveId = resolveId;
}
public String getResolveMode() {
return resolveMode;
}
public void setResolveMode(String resolveMode) {
this.resolveMode = resolveMode;
}
public boolean getCheckIfChanged() {
return checkIfChanged;
}
public void setCheckIfChanged(boolean checkIfChanged) {
this.checkIfChanged = checkIfChanged;
}
}