diff options
author | Amadornes <amadornes@gmail.com> | 2018-07-02 07:12:27 +0200 |
---|---|---|
committer | Amadornes <amadornes@gmail.com> | 2018-07-02 07:12:27 +0200 |
commit | 92b2a6669392bd410e9a60749656a49f3e309cc0 (patch) | |
tree | cae858e8f371018771f84afeef6ae059d8910e0d /src/gradlecomp/java/com/amadornes/artifactural/gradle/DependencyResolver.java | |
parent | 4ffefc5676def5855d91dffa0d089fe5402364fa (diff) | |
download | Artifactural-92b2a6669392bd410e9a60749656a49f3e309cc0.tar.gz Artifactural-92b2a6669392bd410e9a60749656a49f3e309cc0.tar.bz2 Artifactural-92b2a6669392bd410e9a60749656a49f3e309cc0.zip |
Initial (untested) version of Artifactural
Diffstat (limited to 'src/gradlecomp/java/com/amadornes/artifactural/gradle/DependencyResolver.java')
-rw-r--r-- | src/gradlecomp/java/com/amadornes/artifactural/gradle/DependencyResolver.java | 83 |
1 files changed, 83 insertions, 0 deletions
diff --git a/src/gradlecomp/java/com/amadornes/artifactural/gradle/DependencyResolver.java b/src/gradlecomp/java/com/amadornes/artifactural/gradle/DependencyResolver.java new file mode 100644 index 0000000..12364d7 --- /dev/null +++ b/src/gradlecomp/java/com/amadornes/artifactural/gradle/DependencyResolver.java @@ -0,0 +1,83 @@ +package com.amadornes.artifactural.gradle; + +import org.gradle.api.Project; +import org.gradle.api.artifacts.*; +import org.gradle.internal.impldep.com.google.common.cache.Cache; +import org.gradle.internal.impldep.com.google.common.cache.CacheBuilder; + +import java.io.File; +import java.util.Set; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; + +public class DependencyResolver { + + private final Project project; + private final AtomicInteger counter = new AtomicInteger(0); + private final Cache<String, CompletableFuture<Set<File>>> resolved = CacheBuilder.newBuilder().expireAfterWrite(30, TimeUnit.MINUTES).build(); + + public DependencyResolver(Project project) { + this.project = project; + } + + /** + * Resolves a dependency, downloading the file and its transitives + * if not cached and returns the set of files. + */ + public Set<File> resolveDependency(Dependency dependency) { + if (dependency instanceof FileCollectionDependency) { + return ((FileCollectionDependency) dependency).getFiles().getFiles(); + } + String name = dependency.getGroup() + ":" + dependency.getName() + ":" + dependency.getVersion(); + if (dependency instanceof ModuleDependency) { + Set<DependencyArtifact> artifacts = ((ModuleDependency) dependency).getArtifacts(); + if (!artifacts.isEmpty()) { + DependencyArtifact artifact = artifacts.iterator().next(); + name += ":" + artifact.getClassifier() + "@" + artifact.getExtension(); + } + } + + // If this dep is being resolved on another thread, let it do it + CompletableFuture<Set<File>> future; + boolean found = true; + synchronized (resolved) { + future = resolved.getIfPresent(name); + if (future == null) { + resolved.put(name, future = new CompletableFuture<>()); + found = false; + } + } + + if (found) { + try { + return future.get(); + } catch (InterruptedException | ExecutionException ex) { + throw new RuntimeException(ex); + } + } + + // No other thread is resolving this dep and we've claimed it, so let's go! + int currentID = counter.getAndIncrement(); + Configuration cfg = project.getConfigurations().maybeCreate("resolve_dep_" + currentID); + cfg.getDependencies().add(dependency); + Set<File> files = cfg.resolve(); + project.getConfigurations().remove(cfg); + future.complete(files); + return files; + } + + /** + * Resolves a dependency, downloading the file and its transitives + * if not cached and returns the set of files. + */ + public Set<File> resolveDependency(Object dependency, boolean transitive) { + Dependency dep = project.getDependencies().create(dependency); + if (dep instanceof ClientModule) { + dep = ((ClientModule) dep).copy().setTransitive(transitive); + } + return resolveDependency(dep); + } + +} |