Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
cstamas committed Mar 21, 2024
1 parent f1af4ed commit a3018af
Show file tree
Hide file tree
Showing 9 changed files with 140 additions and 28 deletions.
45 changes: 45 additions & 0 deletions cli/src/main/java/eu/maveniverse/maven/toolbox/cli/Copy.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/*
* Copyright (c) 2023-2024 Maveniverse Org.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-v20.html
*/
package eu.maveniverse.maven.toolbox.cli;

import eu.maveniverse.maven.mima.context.Context;
import eu.maveniverse.maven.toolbox.shared.DirectorySink;
import eu.maveniverse.maven.toolbox.shared.ToolboxCommando;
import java.nio.file.Path;
import java.util.stream.Collectors;
import org.eclipse.aether.artifact.DefaultArtifact;
import picocli.CommandLine;

/**
* Resolves a given GAV and copies resulting artifact to target.
*/
@CommandLine.Command(name = "copy", description = "Resolves Maven Artifact and copies it to target")
public final class Copy extends ResolverCommandSupport {
@CommandLine.Parameters(index = "0", description = "The target", arity = "1")
private Path target;

@CommandLine.Parameters(index = "1..*", description = "The GAVs to resolve", arity = "1")
private java.util.List<String> gav;

@CommandLine.Option(
names = {"--boms"},
defaultValue = "",
split = ",",
description = "Comma separated list of BOMs to apply")
private java.util.List<String> boms;

@Override
protected boolean doCall(Context context) throws Exception {
Path targetPath = target.toAbsolutePath();
ToolboxCommando toolboxCommando = getToolboxCommando(context);
return toolboxCommando.copy(
gav.stream().map(DefaultArtifact::new).collect(Collectors.toList()),
DirectorySink.flat(output, targetPath),
output);
}
}
26 changes: 20 additions & 6 deletions cli/src/main/java/eu/maveniverse/maven/toolbox/cli/CopyAll.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,20 +11,25 @@
import eu.maveniverse.maven.toolbox.shared.DirectorySink;
import eu.maveniverse.maven.toolbox.shared.ResolutionScope;
import eu.maveniverse.maven.toolbox.shared.ToolboxCommando;
import eu.maveniverse.maven.toolbox.shared.ToolboxResolver;
import java.nio.file.Path;
import java.util.stream.Collectors;
import org.eclipse.aether.resolution.ArtifactDescriptorException;
import picocli.CommandLine;

/**
* Resolves transitively a given GAV and copies resulting artifacts to target.
*/
@CommandLine.Command(name = "copyAll", description = "Resolves Maven Artifact and copies them to target")
@CommandLine.Command(
name = "copyAll",
description = "Resolves Maven Artifact transitively and copies all of them to target")
public final class CopyAll extends ResolverCommandSupport {
@CommandLine.Parameters(index = "0", description = "The GAV to resolve", arity = "1")
private String gav;

@CommandLine.Parameters(index = "1", description = "The target", arity = "1")
@CommandLine.Parameters(index = "0", description = "The target", arity = "1")
private Path target;

@CommandLine.Parameters(index = "1..*", description = "The GAVs to resolve", arity = "1")
private java.util.List<String> gav;

@CommandLine.Option(
names = {"--resolutionScope"},
defaultValue = "runtime",
Expand All @@ -42,9 +47,18 @@ public final class CopyAll extends ResolverCommandSupport {
protected boolean doCall(Context context) throws Exception {
Path targetPath = target.toAbsolutePath();
ToolboxCommando toolboxCommando = getToolboxCommando(context);
ToolboxResolver toolboxResolver = toolboxCommando.toolboxResolver();
return toolboxCommando.copyAll(
ResolutionScope.parse(resolutionScope),
toolboxCommando.toolboxResolver().loadGav(gav, boms),
gav.stream()
.map(g -> {
try {
return toolboxResolver.loadGav(g, boms);
} catch (ArtifactDescriptorException e) {
throw new RuntimeException(e);
}
})
.collect(Collectors.toList()),
DirectorySink.flat(output, targetPath),
output);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
name = "toolbox",
subcommands = {
Classpath.class,
Copy.class,
CopyAll.class,
Deploy.class,
DeployRecorded.class,
Expand Down
Binary file removed foo/hamcrest-core-1.3.jar
Binary file not shown.
Binary file removed foo/junit-4.13.2.jar
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,16 @@
* Construction to accept collection of artifacts, for example like a filesystem directory.
*/
public final class DirectorySink implements Consumer<Collection<Artifact>> {

/**
* Creates plain "flat" directory sink that accepts all artifacts and writes them out having filenames as
* "A[-C]-V.E" and prevents overwrite (what you usually want).
* <p>
* This means that if your set of artifacts have artifacts will different groupIDs but same artifactIDs, this sink
* will fail to prevent overwrite.
*/
public static DirectorySink flat(Output output, Path path) throws IOException {
return new DirectorySink(output, path);
return new DirectorySink(
output, path, ArtifactMatcher.unique(), ArtifactMapper.identity(), ArtifactNameMapper.ACVE(), false);
}

private final Output output;
Expand All @@ -39,20 +46,39 @@ public static DirectorySink flat(Output output, Path path) throws IOException {
private final boolean allowOverwrite;
private final HashSet<Path> writtenPaths;

private DirectorySink(Output output, Path directory) throws IOException {
/**
* Creates a directory sink.
*
* @param output The output.
* @param directory The directory, if not existing, will be created.
* @param artifactMatcher The matcher, that decides is this sink accepting artifact or not.
* @param artifactMapper The artifact mapper, that may re-map artifact.
* @param artifactNameMapper The artifact name mapper, that decides what file name will be of the artifact.
* @param allowOverwrite Does sink allow overwrites. Tip: you usually do not want to allow, as that means you have
* some mismatch in name mapping or alike.
* @throws IOException In case of IO problem.
*/
private DirectorySink(
Output output,
Path directory,
ArtifactMatcher artifactMatcher,
ArtifactMapper artifactMapper,
ArtifactNameMapper artifactNameMapper,
boolean allowOverwrite)
throws IOException {
this.output = requireNonNull(output, "output");
this.directory = requireNonNull(directory, "directory");
this.directory = requireNonNull(directory, "directory").toAbsolutePath();
if (Files.exists(directory) && !Files.isDirectory(directory)) {
throw new IllegalArgumentException("directory must not exists, or be a directory");
throw new IllegalArgumentException("directory must not exists, or must be a directory");
}
if (!Files.exists(directory)) {
Files.createDirectories(directory);
}

this.artifactMatcher = ArtifactMatcher.any();
this.artifactMapper = ArtifactMapper.identity();
this.artifactNameMapper = ArtifactNameMapper.ACVE();
this.allowOverwrite = false;
this.artifactMatcher = requireNonNull(artifactMatcher, "artifactMatcher");
this.artifactMapper = requireNonNull(artifactMapper, "artifactMapper");
this.artifactNameMapper = requireNonNull(artifactNameMapper, "artifactNameMapper");
this.allowOverwrite = allowOverwrite;
this.writtenPaths = new HashSet<>();
}

Expand All @@ -77,7 +103,7 @@ private void accept(Artifact artifact) throws IOException {
output.verbose(" mapped to name {}", name);
Path target = directory.resolve(name);
if (!writtenPaths.add(target) && !allowOverwrite) {
throw new IOException("Overwrite prevented: check mappings");
throw new IOException("Overwrite prevented; check mappings");
}
output.verbose(" copied to file {}", target);
Files.copy(
Expand All @@ -89,7 +115,7 @@ private void accept(Artifact artifact) throws IOException {
}

private void cleanup(Collection<Artifact> artifacts, IOException e) {
output.error("IO error happened, cleaning up", e);
output.error("IO error, cleaning up: {}", e.getMessage(), e);
writtenPaths.forEach(p -> {
try {
Files.deleteIfExists(p);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,9 +75,11 @@ static void unset(Context context) {

boolean classpath(ResolutionScope resolutionScope, ResolutionRoot resolutionRoot, Output output);

boolean copy(Collection<Artifact> artifacts, Consumer<Collection<Artifact>> consumer, Output output);

boolean copyAll(
ResolutionScope resolutionScope,
ResolutionRoot resolutionRoot,
Collection<ResolutionRoot> resolutionRoots,
Consumer<Collection<Artifact>> consumer,
Output output);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.Objects;
import java.util.function.Predicate;
import org.eclipse.aether.artifact.Artifact;
Expand Down Expand Up @@ -83,6 +84,11 @@ static ArtifactMatcher any() {
return a -> true;
}

static ArtifactMatcher unique() {
HashSet<Artifact> artifacts = new HashSet<>();
return artifacts::add;
}

private static boolean isAny(String str) {
return "*".equals(str);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Properties;
Expand Down Expand Up @@ -202,6 +203,7 @@ public boolean dump(boolean verbose, Output output) {
@Override
public boolean classpath(ResolutionScope resolutionScope, ResolutionRoot resolutionRoot, Output output) {
try {
output.verbose("Resolving {}", resolutionRoot.getArtifact());
DependencyResult dependencyResult = toolboxResolver.resolve(
resolutionScope,
resolutionRoot.getArtifact(),
Expand All @@ -220,22 +222,38 @@ public boolean classpath(ResolutionScope resolutionScope, ResolutionRoot resolut
}
}

@Override
public boolean copy(Collection<Artifact> artifacts, Consumer<Collection<Artifact>> consumer, Output output) {
try {
output.verbose("Resolving {}", artifacts);
List<ArtifactResult> resolveResult = toolboxResolver.resolveArtifacts(artifacts);
consumer.accept(
resolveResult.stream().map(ArtifactResult::getArtifact).collect(Collectors.toList()));
return true;
} catch (Exception e) {
throw new RuntimeException(e);
}
}

@Override
public boolean copyAll(
ResolutionScope resolutionScope,
ResolutionRoot resolutionRoot,
Collection<ResolutionRoot> resolutionRoots,
Consumer<Collection<Artifact>> consumer,
Output output) {
try {
DependencyResult dependencyResult = toolboxResolver.resolve(
resolutionScope,
resolutionRoot.getArtifact(),
resolutionRoot.getDependencies(),
resolutionRoot.getManagedDependencies());

consumer.accept(dependencyResult.getArtifactResults().stream()
.map(ArtifactResult::getArtifact)
.collect(Collectors.toList()));
ArrayList<ArtifactResult> artifactResults = new ArrayList<>();
for (ResolutionRoot resolutionRoot : resolutionRoots) {
output.verbose("Resolving {}", resolutionRoot.getArtifact());
DependencyResult dependencyResult = toolboxResolver.resolve(
resolutionScope,
resolutionRoot.getArtifact(),
resolutionRoot.getDependencies(),
resolutionRoot.getManagedDependencies());
artifactResults.addAll(dependencyResult.getArtifactResults());
}
consumer.accept(
artifactResults.stream().map(ArtifactResult::getArtifact).collect(Collectors.toList()));
return true;
} catch (Exception e) {
throw new RuntimeException(e);
Expand Down

0 comments on commit a3018af

Please sign in to comment.