A workspace resolver for Ant.

The code is inspired from IvyDE’s one. Work in progress.
This commit is contained in:
Nicolas Lalevée 2014-12-21 16:10:34 +01:00 committed by Nicolas Lalevée
parent 83fcd3e1e2
commit f6322b7fb7
20 changed files with 1068 additions and 7 deletions

View File

@ -0,0 +1,231 @@
/*
* 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.net.URISyntaxException;
import java.net.URL;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import org.apache.ivy.core.module.descriptor.Artifact;
import org.apache.ivy.core.module.descriptor.DefaultArtifact;
import org.apache.ivy.core.module.descriptor.DependencyDescriptor;
import org.apache.ivy.core.module.descriptor.ModuleDescriptor;
import org.apache.ivy.core.report.ArtifactDownloadReport;
import org.apache.ivy.core.report.DownloadReport;
import org.apache.ivy.core.report.DownloadStatus;
import org.apache.ivy.core.resolve.DownloadOptions;
import org.apache.ivy.core.resolve.ResolveData;
import org.apache.ivy.core.resolve.ResolvedModuleRevision;
import org.apache.ivy.plugins.parser.ModuleDescriptorParserRegistry;
import org.apache.ivy.plugins.resolver.AbstractWorkspaceResolver;
import org.apache.ivy.util.Message;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.types.DataType;
import org.apache.tools.ant.types.ResourceCollection;
import org.apache.tools.ant.types.resources.FileResource;
public class AntWorkspaceResolver extends DataType {
public static final class WorkspaceArtifact {
private String name;
private String type;
private String ext;
private String path;
public void setName(String name) {
this.name = name;
}
public void setType(String type) {
this.type = type;
}
public void setExt(String ext) {
this.ext = ext;
}
public void setPath(String path) {
this.path = path;
}
}
private List<ResourceCollection> allResources = new ArrayList<ResourceCollection>();
private boolean haltOnError = true;
private Resolver resolver;
private String name;
private List<WorkspaceArtifact> artifacts = new ArrayList<WorkspaceArtifact>();
public void setName(String name) {
this.name = name;
}
public void setHaltonerror(boolean haltOnError) {
this.haltOnError = haltOnError;
}
public void addResourceCollection(ResourceCollection resources) {
if (!resources.isFilesystemOnly()) {
throw new BuildException("Only filesystem resource collection is supported");
}
allResources.add(resources);
}
public WorkspaceArtifact createArtifact() {
WorkspaceArtifact a = new WorkspaceArtifact();
artifacts.add(a);
return a;
}
public Resolver getResolver() {
if (resolver == null) {
if (name == null) {
throw new BuildException("A name is required");
}
resolver = new Resolver();
resolver.setName(name);
}
return resolver;
}
private String getProjectName(File ivyFile) {
return ivyFile.getParentFile().getName();
}
private class Resolver extends AbstractWorkspaceResolver {
private Map<ModuleDescriptor, File> md2IvyFile;
private synchronized Map<ModuleDescriptor, File> getModuleDescriptors() {
if (md2IvyFile == null) {
md2IvyFile = new HashMap<ModuleDescriptor, File>();
for (ResourceCollection resources : allResources) {
for (Iterator it = resources.iterator(); it.hasNext();) {
File ivyFile = ((FileResource) it.next()).getFile();
try {
ModuleDescriptor md = ModuleDescriptorParserRegistry.getInstance()
.parseDescriptor(getParserSettings(), ivyFile.toURI().toURL(),
isValidate());
md2IvyFile.put(md, ivyFile);
Message.debug("Add " + md.getModuleRevisionId().getModuleId());
} catch (Exception ex) {
if (haltOnError) {
throw new BuildException("impossible to parse ivy file " + ivyFile
+ " exception=" + ex, ex);
} else {
Message.warn("impossible to parse ivy file " + ivyFile
+ " exception=" + ex.getMessage());
}
}
}
}
}
return md2IvyFile;
}
public ResolvedModuleRevision getDependency(DependencyDescriptor dd, ResolveData data)
throws ParseException {
Map<ModuleDescriptor, File> mds = getModuleDescriptors();
for (Entry<ModuleDescriptor, File> md : mds.entrySet()) {
ResolvedModuleRevision rmr = checkCandidate(dd, md.getKey(),
getProjectName(md.getValue()));
if (rmr != null) {
return rmr;
}
}
return null;
}
@Override
protected List<Artifact> createWorkspaceArtifacts(ModuleDescriptor md) {
List<Artifact> res = new ArrayList<Artifact>();
for (WorkspaceArtifact wa : artifacts) {
String name = wa.name;
String type = wa.type;
String ext = wa.ext;
String path = wa.path;
if (name == null) {
name = md.getModuleRevisionId().getName();
}
if (type == null) {
type = "jar";
}
if (ext == null) {
ext = "jar";
}
if (path == null) {
path = "target" + File.separator + "dist" + File.separator + type + "s"
+ File.separator + name + "." + ext;
}
URL url;
File ivyFile = md2IvyFile.get(md);
File artifactFile = new File(ivyFile.getParentFile(), path);
try {
url = artifactFile.toURI().toURL();
} catch (MalformedURLException e) {
throw new RuntimeException("Unsupported file path : " + artifactFile, e);
}
res.add(new DefaultArtifact(md.getModuleRevisionId(), new Date(), name, type, ext,
url, null));
}
return res;
}
public DownloadReport download(Artifact[] artifacts, DownloadOptions options) {
// Not much to do here - downloads are not required for workspace projects.
DownloadReport dr = new DownloadReport();
for (int i = 0; i < artifacts.length; i++) {
ArtifactDownloadReport adr = new ArtifactDownloadReport(artifacts[i]);
dr.addArtifactReport(adr);
adr.setDownloadStatus(DownloadStatus.NO);
adr.setSize(0);
URL url = artifacts[i].getUrl();
File f;
try {
f = new File(url.toURI());
} catch (URISyntaxException e) {
f = new File(url.getPath());
}
adr.setLocalFile(f);
Message.verbose("\t[IN WORKSPACE] " + artifacts[i]);
}
return dr;
}
}
}

View File

@ -102,6 +102,8 @@ public class IvyAntSettings extends DataType {
private boolean autoRegistered = false;
private AntWorkspaceResolver antWorkspaceResolver;
/**
* Returns the default ivy settings of this classloader. If it doesn't exist yet, a new one is
* created using the given project to back the VariableContainer.
@ -275,6 +277,10 @@ public class IvyAntSettings extends DataType {
defineDefaultSettingFile(ivyAntVariableContainer, task);
}
if (antWorkspaceResolver != null) {
settings.addConfigured(antWorkspaceResolver.getResolver());
}
Ivy ivy = Ivy.newInstance(settings);
try {
ivy.pushContext();
@ -388,4 +394,7 @@ public class IvyAntSettings extends DataType {
URLHandlerRegistry.setDefault(dispatcher);
}
public void addConfiguredWorkspaceResolver(AntWorkspaceResolver antWorkspaceResolver) {
this.antWorkspaceResolver = antWorkspaceResolver;
}
}

View File

@ -130,6 +130,11 @@ public class IvyConfigure extends Task {
settings.setPasswd(passwd);
}
public void addConfiguredWorkspaceResolver(AntWorkspaceResolver resolver) {
settings.addConfiguredWorkspaceResolver(resolver);
}
@Override
public void execute() throws BuildException {
String settingsId = settings.getId();
Object otherRef = getProject().getReference(settingsId);

View File

@ -49,4 +49,5 @@
<taskdef name="fixdeps" classname="org.apache.ivy.ant.FixDepsTask" />
<taskdef name="dependencytree" classname="org.apache.ivy.ant.IvyDependencyTree"/>
<taskdef name="checkdepsupdate" classname="org.apache.ivy.ant.IvyDependencyUpdateChecker"/>
<typedef name="workspaceresolver" classname="org.apache.ivy.ant.AntWorkspaceResolver" />
</antlib>

View File

@ -0,0 +1,42 @@
/*
* 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.core.module.descriptor;
import java.util.Date;
import org.apache.ivy.core.module.id.ModuleRevisionId;
import org.apache.ivy.plugins.parser.ModuleDescriptorParser;
import org.apache.ivy.plugins.repository.Resource;
public class DefaultWorkspaceModuleDescriptor extends DefaultModuleDescriptor implements
WorkspaceModuleDescriptor {
public DefaultWorkspaceModuleDescriptor(ModuleDescriptorParser parser, Resource res) {
super(parser, res);
}
public DefaultWorkspaceModuleDescriptor(ModuleRevisionId id, String status, Date pubDate) {
super(id, status, pubDate);
}
public DefaultWorkspaceModuleDescriptor(ModuleRevisionId id, String status, Date pubDate,
boolean isDefault) {
super(id, status, pubDate, isDefault);
}
}

View File

@ -0,0 +1,26 @@
/*
* 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.core.module.descriptor;
/**
* Marker interface for module descriptor of a module in a workspace, then having special semantics,
* like artifacts declared by the resolver rather than the descriptor
*/
public interface WorkspaceModuleDescriptor extends ModuleDescriptor {
}

View File

@ -27,6 +27,7 @@ import java.util.Set;
import org.apache.ivy.core.module.descriptor.DependencyArtifactDescriptor;
import org.apache.ivy.core.module.descriptor.DependencyDescriptor;
import org.apache.ivy.core.module.descriptor.IncludeRule;
import org.apache.ivy.core.module.descriptor.WorkspaceModuleDescriptor;
/**
* Class collecting usage data for an IvyNode.
@ -219,6 +220,10 @@ public class IvyNodeUsage {
}
protected Set<DependencyArtifactDescriptor> getDependencyArtifactsSet(String rootModuleConf) {
if (node.getDescriptor() instanceof WorkspaceModuleDescriptor) {
// for a module in the "workspace" artifacts will be actually declared by the resolver
return null;
}
Collection<Depender> dependersInConf = dependers.get(rootModuleConf);
if (dependersInConf == null) {
return null;

View File

@ -76,6 +76,7 @@ import org.apache.ivy.plugins.latest.LatestLexicographicStrategy;
import org.apache.ivy.plugins.latest.LatestRevisionStrategy;
import org.apache.ivy.plugins.latest.LatestStrategy;
import org.apache.ivy.plugins.latest.LatestTimeStrategy;
import org.apache.ivy.plugins.latest.WorkspaceLatestStrategy;
import org.apache.ivy.plugins.lock.CreateFileLockStrategy;
import org.apache.ivy.plugins.lock.LockStrategy;
import org.apache.ivy.plugins.lock.NIOFileLockStrategy;
@ -92,10 +93,12 @@ import org.apache.ivy.plugins.parser.ParserSettings;
import org.apache.ivy.plugins.report.LogReportOutputter;
import org.apache.ivy.plugins.report.ReportOutputter;
import org.apache.ivy.plugins.report.XmlReportOutputter;
import org.apache.ivy.plugins.resolver.AbstractWorkspaceResolver;
import org.apache.ivy.plugins.resolver.ChainResolver;
import org.apache.ivy.plugins.resolver.DependencyResolver;
import org.apache.ivy.plugins.resolver.DualResolver;
import org.apache.ivy.plugins.resolver.ResolverSettings;
import org.apache.ivy.plugins.resolver.WorkspaceChainResolver;
import org.apache.ivy.plugins.signer.SignatureGenerator;
import org.apache.ivy.plugins.trigger.Trigger;
import org.apache.ivy.plugins.version.ChainVersionMatcher;
@ -207,6 +210,8 @@ public class IvySettings implements SortEngineSettings, PublishEngineSettings, P
private PackingRegistry packingRegistry = new PackingRegistry();
private AbstractWorkspaceResolver workspaceResolver;
public IvySettings() {
this(new IvyVariableContainerImpl());
}
@ -879,9 +884,20 @@ public class IvySettings implements SortEngineSettings, PublishEngineSettings, P
dictatorResolver = resolver;
}
private DependencyResolver getDictatorResolver() {
if (dictatorResolver == null) {
return null;
}
if (workspaceResolver != null && !(dictatorResolver instanceof WorkspaceChainResolver)) {
dictatorResolver = new WorkspaceChainResolver(this, dictatorResolver, workspaceResolver);
}
return dictatorResolver;
}
public synchronized DependencyResolver getResolver(ModuleRevisionId mrid) {
if (dictatorResolver != null) {
return dictatorResolver;
DependencyResolver r = getDictatorResolver();
if (r != null) {
return r;
}
String resolverName = getResolverName(mrid);
return getResolver(resolverName);
@ -892,23 +908,32 @@ public class IvySettings implements SortEngineSettings, PublishEngineSettings, P
}
public synchronized DependencyResolver getResolver(String resolverName) {
if (dictatorResolver != null) {
return dictatorResolver;
DependencyResolver r = getDictatorResolver();
if (r != null) {
return r;
}
DependencyResolver resolver = resolversMap.get(resolverName);
if (resolver == null) {
Message.error("unknown resolver " + resolverName);
}
if (workspaceResolver != null && !(resolver instanceof WorkspaceChainResolver)) {
resolver = new WorkspaceChainResolver(this, resolver, workspaceResolver);
resolversMap.put(resolverName, resolver);
}
return resolver;
}
public synchronized DependencyResolver getDefaultResolver() {
if (dictatorResolver != null) {
return dictatorResolver;
DependencyResolver r = getDictatorResolver();
if (r != null) {
return r;
}
if (defaultResolver == null) {
defaultResolver = resolversMap.get(defaultResolverName);
}
if (workspaceResolver != null && !(defaultResolver instanceof WorkspaceChainResolver)) {
defaultResolver = new WorkspaceChainResolver(this, defaultResolver, workspaceResolver);
}
return defaultResolver;
}
@ -997,7 +1022,12 @@ public class IvySettings implements SortEngineSettings, PublishEngineSettings, P
if ("default".equals(name)) {
return getDefaultLatestStrategy();
}
return latestStrategies.get(name);
LatestStrategy strategy = latestStrategies.get(name);
if (workspaceResolver != null && !(strategy instanceof WorkspaceLatestStrategy)) {
strategy = new WorkspaceLatestStrategy(strategy);
latestStrategies.put(name, strategy);
}
return strategy;
}
public synchronized void addLatestStrategy(String name, LatestStrategy latest) {
@ -1224,6 +1254,10 @@ public class IvySettings implements SortEngineSettings, PublishEngineSettings, P
if (defaultLatestStrategy == null) {
defaultLatestStrategy = new LatestRevisionStrategy();
}
if (workspaceResolver != null
&& !(defaultLatestStrategy instanceof WorkspaceLatestStrategy)) {
defaultLatestStrategy = new WorkspaceLatestStrategy(defaultLatestStrategy);
}
return defaultLatestStrategy;
}
@ -1500,4 +1534,20 @@ public class IvySettings implements SortEngineSettings, PublishEngineSettings, P
public PackingRegistry getPackingRegistry() {
return packingRegistry;
}
public void addConfigured(AbstractWorkspaceResolver workspaceResolver) {
this.workspaceResolver = workspaceResolver;
if (workspaceResolver != null) {
workspaceResolver.setSettings(this);
DefaultRepositoryCacheManager cacheManager = new DefaultRepositoryCacheManager();
String cacheName = "workspace-resolver-cache-" + workspaceResolver.getName();
cacheManager.setBasedir(new File(getDefaultCache(), cacheName));
cacheManager.setCheckmodified(true);
cacheManager.setUseOrigin(true);
cacheManager.setName(cacheName);
addRepositoryCacheManager(cacheManager);
workspaceResolver.setCache(cacheName);
}
}
}

View File

@ -0,0 +1,57 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package org.apache.ivy.plugins.latest;
import java.util.ArrayList;
import java.util.List;
/**
* A strategy which delegate to another strategy, unless for the latest and working revisions which
* are considered as superior to any other revision. < br/>
* NB : it is for internal usage of Ivy only!
*/
public class WorkspaceLatestStrategy extends AbstractLatestStrategy {
private LatestStrategy delegate;
public WorkspaceLatestStrategy(LatestStrategy delegate) {
this.delegate = delegate;
setName("workspace-" + delegate.getName());
}
public List<ArtifactInfo> sort(ArtifactInfo[] infos) {
List<ArtifactInfo> sorted = delegate.sort(infos);
List<ArtifactInfo> head = new ArrayList<ArtifactInfo>();
List<ArtifactInfo> tail = new ArrayList<ArtifactInfo>();
for (ArtifactInfo ai : sorted) {
String rev = ai.getRevision();
boolean latestRev = rev.startsWith("latest") || rev.startsWith("working");
if (latestRev) {
head.add(ai);
} else {
tail.add(ai);
}
}
head.addAll(tail);
return head;
}
}

View File

@ -0,0 +1,239 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package org.apache.ivy.plugins.resolver;
import java.io.File;
import java.io.IOException;
import java.text.ParseException;
import java.util.List;
import org.apache.ivy.Ivy;
import org.apache.ivy.core.module.descriptor.Artifact;
import org.apache.ivy.core.module.descriptor.Configuration;
import org.apache.ivy.core.module.descriptor.DefaultArtifact;
import org.apache.ivy.core.module.descriptor.DefaultWorkspaceModuleDescriptor;
import org.apache.ivy.core.module.descriptor.DependencyDescriptor;
import org.apache.ivy.core.module.descriptor.ExcludeRule;
import org.apache.ivy.core.module.descriptor.License;
import org.apache.ivy.core.module.descriptor.ModuleDescriptor;
import org.apache.ivy.core.module.descriptor.WorkspaceModuleDescriptor;
import org.apache.ivy.core.module.id.ModuleId;
import org.apache.ivy.core.module.id.ModuleRevisionId;
import org.apache.ivy.core.report.DownloadStatus;
import org.apache.ivy.core.report.MetadataArtifactDownloadReport;
import org.apache.ivy.core.resolve.ResolveData;
import org.apache.ivy.core.resolve.ResolvedModuleRevision;
import org.apache.ivy.osgi.core.BundleInfo;
import org.apache.ivy.osgi.core.ManifestHeaderElement;
import org.apache.ivy.osgi.core.ManifestHeaderValue;
import org.apache.ivy.plugins.resolver.util.ResolvedResource;
import org.apache.ivy.plugins.version.VersionMatcher;
import org.apache.ivy.util.Message;
public abstract class AbstractWorkspaceResolver extends AbstractResolver {
private boolean ignoreBranch;
private boolean ignoreVersion;
public void setIgnoreBranch(boolean ignoreBranch) {
this.ignoreBranch = ignoreBranch;
}
public void setIgnoreVersion(boolean ignoreVersion) {
this.ignoreVersion = ignoreVersion;
}
protected ResolvedModuleRevision checkCandidate(DependencyDescriptor dd, ModuleDescriptor md,
String workspaceModuleName) {
if (workspaceModuleName == null) {
workspaceModuleName = dd.getDependencyId().toString();
}
ModuleRevisionId dependencyMrid = dd.getDependencyRevisionId();
String org = dependencyMrid.getModuleId().getOrganisation();
String module = dependencyMrid.getModuleId().getName();
VersionMatcher versionMatcher = getSettings().getVersionMatcher();
ModuleRevisionId candidateMrid = md.getModuleRevisionId();
// search a match on the organization and the module name
if (org.equals(BundleInfo.BUNDLE_TYPE)) {
// looking for an OSGi bundle via its symbolic name
String sn = md.getExtraInfoContentByTagName("Bundle-SymbolicName");
if (sn == null || !module.equals(sn)) {
// not found, skip to next
return null;
}
} else if (org.equals(BundleInfo.PACKAGE_TYPE)) {
// looking for an OSGi bundle via its exported package
String exportedPackages = md.getExtraInfoContentByTagName("Export-Package");
if (exportedPackages == null) {
// not found, skip to next
return null;
}
boolean found = false;
String version = null;
ManifestHeaderValue exportElements;
try {
exportElements = new ManifestHeaderValue(exportedPackages);
} catch (ParseException e) {
// wrong OSGi header: skip it
return null;
}
for (ManifestHeaderElement exportElement : exportElements.getElements()) {
if (exportElement.getValues().contains(module)) {
found = true;
version = exportElement.getAttributes().get("version");
break;
}
}
if (!found) {
// not found, skip to next
return null;
}
if (version == null) {
// no version means anything can match. Let's trick the version matcher by
// setting the exact expected version
version = dependencyMrid.getRevision();
}
md.setResolvedModuleRevisionId(ModuleRevisionId.newInstance(org, module, version));
} else {
if (!candidateMrid.getModuleId().equals(dependencyMrid.getModuleId())) {
// it doesn't match org#module, skip to next
return null;
}
}
Message.verbose("Workspace resolver found potential matching workspace module "
+ workspaceModuleName + " with module " + candidateMrid + " for module "
+ dependencyMrid);
if (!ignoreBranch) {
ModuleId mid = dependencyMrid.getModuleId();
String defaultBranch = getSettings().getDefaultBranch(mid);
String dependencyBranch = dependencyMrid.getBranch();
String candidateBranch = candidateMrid.getBranch();
if (dependencyBranch == null) {
dependencyBranch = defaultBranch;
}
if (candidateBranch == null) {
candidateBranch = defaultBranch;
}
if (dependencyBranch != candidateBranch) {
// Both cannot be null
if (dependencyBranch == null || candidateBranch == null) {
Message.verbose("\t\trejected since branches doesn't match (one is set, the other isn't)");
return null;
}
if (!dependencyBranch.equals(candidateBranch)) {
Message.verbose("\t\trejected since branches doesn't match");
return null;
}
}
}
// Found one; check if it is for the module we need
if (!ignoreVersion
&& !md.getModuleRevisionId().getRevision().equals(Ivy.getWorkingRevision())
&& !versionMatcher.accept(dd.getDependencyRevisionId(), md)) {
Message.verbose("\t\treject as version didn't match");
return null;
}
if (ignoreVersion) {
Message.verbose("\t\tmatched (version are ignored)");
} else {
Message.verbose("\t\tversion matched");
}
WorkspaceModuleDescriptor workspaceMd = createWorkspaceMd(md);
Artifact mdaf = md.getMetadataArtifact();
if (mdaf == null) {
mdaf = new DefaultArtifact(md.getModuleRevisionId(), md.getPublicationDate(),
workspaceModuleName, "ivy", "");
}
MetadataArtifactDownloadReport madr = new MetadataArtifactDownloadReport(mdaf);
madr.setDownloadStatus(DownloadStatus.SUCCESSFUL);
madr.setSearched(true);
return new ResolvedModuleRevision(this, this, workspaceMd, madr);
}
protected WorkspaceModuleDescriptor createWorkspaceMd(ModuleDescriptor md) {
DefaultWorkspaceModuleDescriptor newMd = new DefaultWorkspaceModuleDescriptor(
md.getModuleRevisionId(), "release", null, true);
newMd.addConfiguration(new Configuration(ModuleDescriptor.DEFAULT_CONFIGURATION));
newMd.setLastModified(System.currentTimeMillis());
newMd.setDescription(md.getDescription());
newMd.setHomePage(md.getHomePage());
newMd.setLastModified(md.getLastModified());
newMd.setPublicationDate(md.getPublicationDate());
newMd.setResolvedPublicationDate(md.getResolvedPublicationDate());
newMd.setStatus(md.getStatus());
List<Artifact> artifacts = createWorkspaceArtifacts(md);
Configuration[] allConfs = md.getConfigurations();
for (Artifact af : artifacts) {
if (allConfs.length == 0) {
newMd.addArtifact(ModuleDescriptor.DEFAULT_CONFIGURATION, af);
} else {
for (int k = 0; k < allConfs.length; k++) {
newMd.addConfiguration(allConfs[k]);
newMd.addArtifact(allConfs[k].getName(), af);
}
}
}
DependencyDescriptor[] dependencies = md.getDependencies();
for (int k = 0; k < dependencies.length; k++) {
newMd.addDependency(dependencies[k]);
}
ExcludeRule[] allExcludeRules = md.getAllExcludeRules();
for (int k = 0; k < allExcludeRules.length; k++) {
newMd.addExcludeRule(allExcludeRules[k]);
}
newMd.getExtraInfos().addAll(md.getExtraInfos());
License[] licenses = md.getLicenses();
for (int k = 0; k < licenses.length; k++) {
newMd.addLicense(licenses[k]);
}
return newMd;
}
abstract protected List<Artifact> createWorkspaceArtifacts(ModuleDescriptor md);
public void publish(Artifact artifact, File src, boolean overwrite) throws IOException {
throw new UnsupportedOperationException("publish not supported by " + getName());
}
public ResolvedResource findIvyFileRef(DependencyDescriptor dd, ResolveData data) {
return null;
}
}

View File

@ -0,0 +1,37 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package org.apache.ivy.plugins.resolver;
import org.apache.ivy.core.settings.IvySettings;
/**
* Resolver which decorate normal resolver so that the workspace resolver can hijack the resolve
* process <br />
* NB : it is for internal usage of Ivy only!
*/
public class WorkspaceChainResolver extends ChainResolver {
public WorkspaceChainResolver(IvySettings settings, DependencyResolver delegate,
AbstractWorkspaceResolver workspaceResolver) {
setName("workspace-chain-" + delegate.getName());
setSettings(settings);
setReturnFirst(true);
add(workspaceResolver);
add(delegate);
}
}

View File

@ -0,0 +1,213 @@
/*
* 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 junit.framework.TestCase;
import org.apache.ivy.ant.AntWorkspaceResolver.WorkspaceArtifact;
import org.apache.ivy.core.module.id.ModuleRevisionId;
import org.apache.ivy.core.report.DownloadStatus;
import org.apache.ivy.core.report.ResolveReport;
import org.apache.tools.ant.DefaultLogger;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.taskdefs.Delete;
import org.apache.tools.ant.types.FileSet;
import org.apache.tools.ant.types.Path;
public class AntBuildResolverTest extends TestCase {
private static final ModuleRevisionId MRID_MODULE1 = ModuleRevisionId.newInstance("org.acme",
"module1", "1.1");
private static final ModuleRevisionId MRID_PROJECT1 = ModuleRevisionId.newInstance(
"org.apache.ivy.test", "project1", "0.1");
private File cache;
private Project project;
private IvyConfigure configure;
private WorkspaceArtifact wa;
@Override
protected void setUp() throws Exception {
createCache();
project = new Project();
DefaultLogger logger = new DefaultLogger();
logger.setMessageOutputLevel(Project.MSG_INFO);
logger.setOutputPrintStream(System.out);
logger.setErrorPrintStream(System.err);
project.addBuildListener(logger);
project.setProperty("ivy.cache.dir", cache.getAbsolutePath());
AntWorkspaceResolver antWorkspaceResolver = new AntWorkspaceResolver();
antWorkspaceResolver.setName("test-workspace");
wa = antWorkspaceResolver.createArtifact();
FileSet fileset = new FileSet();
fileset.setProject(project);
fileset.setDir(new File("test/workspace"));
fileset.setIncludes("*/ivy.xml");
antWorkspaceResolver.addResourceCollection(fileset);
antWorkspaceResolver.setProject(project);
configure = new IvyConfigure();
configure.setProject(project);
configure.setFile(new File("test/workspace/ivysettings.xml"));
configure.addConfiguredWorkspaceResolver(antWorkspaceResolver);
configure.execute();
}
private void createCache() {
cache = new File("build/cache");
cache.mkdirs();
}
@Override
protected void tearDown() throws Exception {
cleanCache();
}
private void cleanCache() {
Delete del = new Delete();
del.setProject(new Project());
del.setDir(cache);
del.execute();
}
public void testNoProject() throws Exception {
IvyResolve resolve = new IvyResolve();
resolve.setProject(project);
resolve.setFile(new File("test/workspace/project1/ivy.xml"));
resolve.setKeep(true);
resolve.execute();
ResolveReport report = (ResolveReport) project.getReference("ivy.resolved.report");
assertEquals(1, report.getDependencies().size());
assertEquals(MRID_MODULE1, report.getDependencies().get(0).getResolvedId());
}
public void testProject() throws Exception {
IvyResolve resolve = new IvyResolve();
resolve.setProject(project);
resolve.setFile(new File("test/workspace/project2/ivy.xml"));
resolve.setKeep(true);
resolve.execute();
ResolveReport report = (ResolveReport) project.getReference("ivy.resolved.report");
assertEquals(2, report.getDependencies().size());
assertEquals(MRID_PROJECT1, report.getDependencies().get(0).getResolvedId());
assertEquals(MRID_MODULE1, report.getDependencies().get(1).getResolvedId());
assertEquals(1, report.getArtifactsReports(MRID_PROJECT1).length);
assertEquals(DownloadStatus.NO,
report.getArtifactsReports(MRID_PROJECT1)[0].getDownloadStatus());
assertEquals(new File("test/workspace/project1/target/dist/jars/project1.jar").toURI()
.toURL(), report.getArtifactsReports(MRID_PROJECT1)[0].getArtifact().getUrl());
assertEquals(
new File("test/workspace/project1/target/dist/jars/project1.jar").getAbsoluteFile(),
report.getArtifactsReports(MRID_PROJECT1)[0].getLocalFile());
}
public void testProjectFolder() throws Exception {
wa.setPath("target/classes");
IvyResolve resolve = new IvyResolve();
resolve.setProject(project);
resolve.setFile(new File("test/workspace/project2/ivy.xml"));
resolve.setKeep(true);
resolve.execute();
ResolveReport report = (ResolveReport) project.getReference("ivy.resolved.report");
assertEquals(2, report.getDependencies().size());
assertEquals(MRID_PROJECT1, report.getDependencies().get(0).getResolvedId());
assertEquals(MRID_MODULE1, report.getDependencies().get(1).getResolvedId());
assertEquals(1, report.getArtifactsReports(MRID_PROJECT1).length);
assertEquals(DownloadStatus.NO,
report.getArtifactsReports(MRID_PROJECT1)[0].getDownloadStatus());
assertEquals(new File("test/workspace/project1/target/classes").toURI().toURL(),
report.getArtifactsReports(MRID_PROJECT1)[0].getArtifact().getUrl());
assertEquals(new File("test/workspace/project1/target/classes").getAbsoluteFile(),
report.getArtifactsReports(MRID_PROJECT1)[0].getLocalFile());
}
public void testDependencyArtifact() throws Exception {
IvyResolve resolve = new IvyResolve();
resolve.setProject(project);
resolve.setFile(new File("test/workspace/project3/ivy.xml"));
resolve.setKeep(true);
resolve.execute();
ResolveReport report = (ResolveReport) project.getReference("ivy.resolved.report");
assertEquals(2, report.getDependencies().size());
assertEquals(MRID_PROJECT1, report.getDependencies().get(0).getResolvedId());
assertEquals(MRID_MODULE1, report.getDependencies().get(1).getResolvedId());
assertEquals(1, report.getArtifactsReports(MRID_PROJECT1).length);
assertEquals(DownloadStatus.NO,
report.getArtifactsReports(MRID_PROJECT1)[0].getDownloadStatus());
assertEquals(new File("test/workspace/project1/target/dist/jars/project1.jar").toURI()
.toURL(), report.getArtifactsReports(MRID_PROJECT1)[0].getArtifact().getUrl());
assertEquals(
new File("test/workspace/project1/target/dist/jars/project1.jar").getAbsoluteFile(),
report.getArtifactsReports(MRID_PROJECT1)[0].getLocalFile());
}
public void testCachePath() throws Exception {
IvyResolve resolve = new IvyResolve();
resolve.setProject(project);
resolve.setFile(new File("test/workspace/project2/ivy.xml"));
resolve.setKeep(true);
resolve.execute();
IvyCachePath cachePath = new IvyCachePath();
cachePath.setProject(project);
cachePath.setPathid("test.cachepath.id");
cachePath.execute();
Path path = (Path) project.getReference("test.cachepath.id");
assertEquals(2, path.size());
assertEquals(
new File("test/workspace/project1/target/dist/jars/project1.jar").getAbsolutePath(),
path.list()[0]);
assertEquals(new File(cache, "org.acme/module1/jars/module1-1.1.jar").getAbsolutePath(),
path.list()[1]);
}
public void testCachePathFolder() throws Exception {
wa.setPath("target/classes");
IvyResolve resolve = new IvyResolve();
resolve.setProject(project);
resolve.setFile(new File("test/workspace/project2/ivy.xml"));
resolve.setKeep(true);
resolve.execute();
IvyCachePath cachePath = new IvyCachePath();
cachePath.setProject(project);
cachePath.setPathid("test.cachepath.id");
cachePath.execute();
Path path = (Path) project.getReference("test.cachepath.id");
assertEquals(2, path.size());
assertEquals(new File("test/workspace/project1/target/classes").getAbsolutePath(),
path.list()[0]);
assertEquals(new File(cache, "org.acme/module1/jars/module1-1.1.jar").getAbsolutePath(),
path.list()[1]);
}
}

View File

@ -0,0 +1,30 @@
<!--
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.
-->
<ivysettings>
<settings defaultResolver="repo" />
<resolvers>
<filesystem name="repo">
<ivy pattern="${ivy.settings.dir}/repo/[organisation]/[module]/[revision]/[artifact].[ext]" />
<artifact pattern="${ivy.settings.dir}/repo/[organisation]/[module]/[revision]/[artifact].[ext]" />
</filesystem>
</resolvers>
</ivysettings>

View File

@ -0,0 +1,24 @@
<!--
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.
-->
<ivy-module version="2.0">
<info organisation="org.apache.ivy.test" module="project1" revision="0.1" />
<dependencies>
<dependency org="org.acme" name="module1" rev="1.1" />
</dependencies>
</ivy-module>

View File

@ -0,0 +1,24 @@
<!--
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.
-->
<ivy-module version="2.0">
<info organisation="org.apache.ivy.test" module="project2" />
<dependencies>
<dependency org="org.apache.ivy.test" name="project1" rev="latest.integration" />
</dependencies>
</ivy-module>

View File

@ -0,0 +1,26 @@
<!--
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.
-->
<ivy-module version="2.0">
<info organisation="org.apache.ivy.test" module="project3" />
<dependencies>
<dependency org="org.apache.ivy.test" name="project1" rev="latest.integration">
<artifact name="test" type="jar" ext="jar" />
</dependency>
</dependencies>
</ivy-module>

View File

@ -0,0 +1,21 @@
<!--
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.
-->
<ivy-module version="2.0">
<info organisation="org.acme" module="module1" revision="1.1" />
</ivy-module>

View File

@ -0,0 +1,21 @@
<!--
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.
-->
<ivy-module version="2.0">
<info organisation="org.acme" module="module2" revision="1.2" />
</ivy-module>