Skip to content

Commit 9b3a536

Browse files
committed
feat: added --cache/-c for setting cache folder
This as an alternative to the `JPM_CACHE` environment variable.
1 parent 2d437e9 commit 9b3a536

4 files changed

Lines changed: 109 additions & 39 deletions

File tree

src/main/java/org/codejive/jpm/Jpm.java

Lines changed: 56 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,14 @@ public class Jpm {
1515
private final Path directory;
1616
private final boolean noLinks;
1717
private final Path appFile;
18+
private final Path cacheDir;
1819
private final boolean verbose;
1920

20-
private Jpm(Path directory, boolean noLinks, Path appFile, boolean verbose) {
21+
private Jpm(Path directory, boolean noLinks, Path appFile, Path cacheDir, boolean verbose) {
2122
this.directory = directory;
2223
this.noLinks = noLinks;
2324
this.appFile = appFile;
25+
this.cacheDir = cacheDir;
2426
this.verbose = verbose;
2527
}
2628

@@ -38,6 +40,7 @@ public static class Builder {
3840
private Path directory;
3941
private boolean noLinks;
4042
private Path appFile;
43+
private Path cacheDir;
4144
private boolean verbose;
4245

4346
private Builder() {}
@@ -75,6 +78,17 @@ public Builder appFile(Path appFile) {
7578
return this;
7679
}
7780

81+
/**
82+
* Set the cache directory to use for downloaded artifacts.
83+
*
84+
* @param cacheDir The cache directory.
85+
* @return The builder instance for chaining.
86+
*/
87+
public Builder cacheDir(Path cacheDir) {
88+
this.cacheDir = cacheDir;
89+
return this;
90+
}
91+
7892
/**
7993
* Set whether to enable verbose output or not.
8094
*
@@ -92,7 +106,7 @@ public Builder verbose(boolean verbose) {
92106
* @return A {@link Jpm} instance.
93107
*/
94108
public Jpm build() {
95-
return new Jpm(directory, noLinks, appFile, verbose);
109+
return new Jpm(directory, noLinks, appFile, cacheDir, verbose);
96110
}
97111
}
98112

@@ -122,7 +136,7 @@ public SyncResult copy(String[] artifactNames, boolean sync)
122136
*/
123137
public SyncResult copy(String[] artifactNames, Map<String, String> repos, boolean sync)
124138
throws IOException, DependencyResolutionException {
125-
List<Path> files = Resolver.create(artifactNames, repos).resolvePaths();
139+
List<Path> files = Resolver.create(artifactNames, repos, cacheDir).resolvePaths();
126140
return FileUtils.syncArtifacts(files, directory, noLinks, !sync);
127141
}
128142

@@ -197,7 +211,7 @@ public SyncResult install(String[] artifactNames, Map<String, String> extraRepos
197211
String[] artifacts = getArtifacts(artifactNames, appInfo);
198212
Map<String, String> repos = getRepositories(extraRepos, appInfo);
199213
if (artifacts.length > 0) {
200-
List<Path> files = Resolver.create(artifacts, repos).resolvePaths();
214+
List<Path> files = Resolver.create(artifacts, repos, cacheDir).resolvePaths();
201215
SyncResult stats = FileUtils.syncArtifacts(files, directory, noLinks, true);
202216
if (artifactNames.length > 0) {
203217
appInfo.dependencies().addAll(Arrays.asList(artifactNames));
@@ -240,7 +254,7 @@ public List<Path> path(String[] artifactNames, Map<String, String> extraRepos)
240254
String[] deps = getArtifacts(artifactNames, appInfo);
241255
Map<String, String> repos = getRepositories(extraRepos, appInfo);
242256
if (deps.length > 0) {
243-
List<Path> files = Resolver.create(deps, repos).resolvePaths();
257+
List<Path> files = Resolver.create(deps, repos, cacheDir).resolvePaths();
244258
if (artifactNames.length > 0) {
245259
return files;
246260
} else {
@@ -280,6 +294,23 @@ private Map<String, String> getRepositories(Map<String, String> extraRepos, AppI
280294
*/
281295
public int executeAction(String actionName, List<String> args)
282296
throws IOException, DependencyResolutionException, InterruptedException {
297+
return executeAction(actionName, args, Collections.emptyMap());
298+
}
299+
300+
/**
301+
* Executes an action defined in app.yml file.
302+
*
303+
* @param actionName The name of the action to execute
304+
* @param args A list of additional arguments to pass to the action command
305+
* @param extraRepos A map of additional repository names to URLs where artifacts can be found.
306+
* @return An integer containing the exit result of the action
307+
* @throws IllegalArgumentException If the action name is not provided or not found
308+
* @throws IOException If an error occurred during the operation
309+
* @throws DependencyResolutionException If an error occurred during dependency resolution
310+
* @throws InterruptedException If the action execution was interrupted
311+
*/
312+
public int executeAction(String actionName, List<String> args, Map<String, String> extraRepos)
313+
throws IOException, DependencyResolutionException, InterruptedException {
283314
AppInfo appInfo = readAppInfo();
284315

285316
// Get the action command
@@ -299,7 +330,7 @@ public int executeAction(String actionName, List<String> args)
299330
.collect(Collectors.joining(" ", " ", ""));
300331
}
301332

302-
return executeCommand(command);
333+
return executeCommand(command, extraRepos);
303334
}
304335

305336
/**
@@ -324,10 +355,28 @@ public List<String> listActions() throws IOException {
324355
*/
325356
public int executeCommand(String command)
326357
throws IOException, DependencyResolutionException, InterruptedException {
358+
return executeCommand(command, Collections.emptyMap());
359+
}
360+
361+
/**
362+
* Executes an action defined in app.yml file.
363+
*
364+
* @param command The command to execute
365+
* @param extraRepos A map of additional repository names to URLs where artifacts can be found.
366+
* @return An integer containing the exit result of the action
367+
* @throws IOException If an error occurred during the operation
368+
* @throws DependencyResolutionException If an error occurred during dependency resolution
369+
* @throws InterruptedException If the action execution was interrupted
370+
*/
371+
public int executeCommand(String command, Map<String, String> extraRepos)
372+
throws IOException, DependencyResolutionException, InterruptedException {
327373
// Get the classpath for variable substitution only if needed
328374
List<Path> classpath = Collections.emptyList();
329375
if (command.contains("{{deps}}")) {
330-
classpath = this.path(new String[0]); // Empty array means use dependencies from app.yml
376+
classpath =
377+
this.path(
378+
new String[0],
379+
extraRepos); // Empty array means use dependencies from app.yml
331380
}
332381

333382
return ScriptUtils.executeScript(command, classpath, verbose);

src/main/java/org/codejive/jpm/Main.java

Lines changed: 36 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -88,8 +88,9 @@ static class Copy implements Callable<Integer> {
8888
public Integer call() throws Exception {
8989
SyncResult stats =
9090
Jpm.builder()
91-
.directory(artifactsMixin.depsMixin.directory)
92-
.noLinks(artifactsMixin.depsMixin.noLinks)
91+
.directory(artifactsMixin.directory)
92+
.noLinks(artifactsMixin.noLinks)
93+
.cacheDir(artifactsMixin.cacheDir)
9394
.build()
9495
.copy(
9596
artifactsMixin.artifactNames,
@@ -162,9 +163,12 @@ public Integer call() throws Exception {
162163
Jpm.builder()
163164
.directory(depsMixin.directory)
164165
.noLinks(depsMixin.noLinks)
166+
.cacheDir(depsMixin.cacheDir)
165167
.appFile(appInfoFileMixin.appInfoFile)
166168
.build()
167-
.install(new String[] {selectedArtifact});
169+
.install(
170+
new String[] {selectedArtifact},
171+
depsMixin.getRepositoryMap());
168172
if (!quietMixin.quiet) {
169173
printStats(stats);
170174
}
@@ -173,9 +177,13 @@ public Integer call() throws Exception {
173177
Jpm.builder()
174178
.directory(depsMixin.directory)
175179
.noLinks(depsMixin.noLinks)
180+
.cacheDir(depsMixin.cacheDir)
176181
.appFile(appInfoFileMixin.appInfoFile)
177182
.build()
178-
.copy(new String[] {selectedArtifact}, false);
183+
.copy(
184+
new String[] {selectedArtifact},
185+
depsMixin.getRepositoryMap(),
186+
false);
179187
if (!quietMixin.quiet) {
180188
printStats(stats);
181189
}
@@ -211,6 +219,7 @@ String[] search(String artifactPattern) {
211219
return Jpm.builder()
212220
.directory(depsMixin.directory)
213221
.noLinks(depsMixin.noLinks)
222+
.cacheDir(depsMixin.cacheDir)
214223
.appFile(appInfoFileMixin.appInfoFile)
215224
.build()
216225
.search(artifactPattern, Math.min(max, 200), backend);
@@ -309,8 +318,9 @@ static class Install implements Callable<Integer> {
309318
public Integer call() throws Exception {
310319
SyncResult stats =
311320
Jpm.builder()
312-
.directory(optionalArtifactsMixin.depsMixin.directory)
313-
.noLinks(optionalArtifactsMixin.depsMixin.noLinks)
321+
.directory(optionalArtifactsMixin.directory)
322+
.noLinks(optionalArtifactsMixin.noLinks)
323+
.cacheDir(optionalArtifactsMixin.cacheDir)
314324
.appFile(appInfoFileMixin.appInfoFile)
315325
.build()
316326
.install(
@@ -339,8 +349,9 @@ static class PrintPath implements Callable<Integer> {
339349
public Integer call() throws Exception {
340350
List<Path> files =
341351
Jpm.builder()
342-
.directory(optionalArtifactsMixin.depsMixin.directory)
343-
.noLinks(optionalArtifactsMixin.depsMixin.noLinks)
352+
.directory(optionalArtifactsMixin.directory)
353+
.noLinks(optionalArtifactsMixin.noLinks)
354+
.cacheDir(optionalArtifactsMixin.cacheDir)
344355
.appFile(appInfoFileMixin.appInfoFile)
345356
.build()
346357
.path(
@@ -386,6 +397,7 @@ static class Exec implements Callable<Integer> {
386397
@Mixin VerboseMixin verboseMixin;
387398
@Mixin DepsMixin depsMixin;
388399
@Mixin QuietMixin quietMixin;
400+
@Mixin AppInfoFileMixin appInfoFileMixin;
389401

390402
@Parameters(paramLabel = "command", description = "The command to execute", arity = "0..*")
391403
private List<String> command;
@@ -397,9 +409,11 @@ public Integer call() throws Exception {
397409
return Jpm.builder()
398410
.directory(depsMixin.directory)
399411
.noLinks(depsMixin.noLinks)
412+
.cacheDir(depsMixin.cacheDir)
413+
.appFile(appInfoFileMixin.appInfoFile)
400414
.verbose(!quietMixin.quiet)
401415
.build()
402-
.executeCommand(cmd);
416+
.executeCommand(cmd, depsMixin.getRepositoryMap());
403417
} catch (Exception e) {
404418
System.err.println(e.getMessage());
405419
return 1;
@@ -454,6 +468,7 @@ public Integer call() throws Exception {
454468
Jpm.builder()
455469
.directory(depsMixin.directory)
456470
.noLinks(depsMixin.noLinks)
471+
.cacheDir(depsMixin.cacheDir)
457472
.appFile(appInfoFileMixin.appInfoFile)
458473
.build()
459474
.listActions();
@@ -499,10 +514,11 @@ public Integer call() throws Exception {
499514
Jpm.builder()
500515
.directory(depsMixin.directory)
501516
.noLinks(depsMixin.noLinks)
517+
.cacheDir(depsMixin.cacheDir)
502518
.appFile(appInfoFileMixin.appInfoFile)
503519
.verbose(!quietMixin.quiet)
504520
.build()
505-
.executeAction(action, args);
521+
.executeAction(action, args, depsMixin.getRepositoryMap());
506522
if (exitCode != 0) {
507523
return exitCode;
508524
}
@@ -532,9 +548,10 @@ public Integer call() throws Exception {
532548
return Jpm.builder()
533549
.directory(depsMixin.directory)
534550
.noLinks(depsMixin.noLinks)
551+
.cacheDir(depsMixin.cacheDir)
535552
.appFile(appInfoFileMixin.appInfoFile)
536553
.build()
537-
.executeAction(actionName(), args);
554+
.executeAction(actionName(), args, depsMixin.getRepositoryMap());
538555
} catch (Exception e) {
539556
System.err.println(e.getMessage());
540557
return 1;
@@ -594,17 +611,19 @@ static class DepsMixin {
594611
description = "Always copy artifacts, don't try to create symlinks",
595612
defaultValue = "false")
596613
boolean noLinks;
597-
}
598-
599-
static class BaseArtifactsMixin {
600-
@Mixin DepsMixin depsMixin;
601614

602615
@Option(
603616
names = {"-r", "--repo"},
604617
description =
605618
"URL to additional repository to use when resolving artifacts. Can be preceded by a name and an equals sign, e.g. -r myrepo=https://my.repo.com/maven2. When needing to pass user and password you can set JPM_REPO_<name>_USER and JPM_REPO_<name>_PASSWORD environment variables.")
606619
List<String> repositories = new ArrayList<>();
607620

621+
@Option(
622+
names = {"-c", "--cache"},
623+
description =
624+
"Directory where downloaded artifacts will be cached (default: value of JPM_CACHE environment variable; whatever is set in Maven's settings.xml or $HOME/.m2/repository")
625+
Path cacheDir;
626+
608627
Map<String, String> getRepositoryMap() {
609628
Map<String, String> repoMap = new HashMap<>();
610629
for (String repo : repositories) {
@@ -634,7 +653,7 @@ Map<String, String> getRepositoryMap() {
634653
}
635654
}
636655

637-
static class ArtifactsMixin extends BaseArtifactsMixin {
656+
static class ArtifactsMixin extends DepsMixin {
638657
@Parameters(
639658
paramLabel = "artifacts",
640659
description =
@@ -643,7 +662,7 @@ static class ArtifactsMixin extends BaseArtifactsMixin {
643662
private String[] artifactNames = {};
644663
}
645664

646-
static class OptionalArtifactsMixin extends BaseArtifactsMixin {
665+
static class OptionalArtifactsMixin extends DepsMixin {
647666
@Parameters(
648667
paramLabel = "artifacts",
649668
description =

src/main/java/org/codejive/jpm/util/Resolver.java

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -24,21 +24,24 @@
2424
public class Resolver {
2525
private final List<Artifact> artifacts;
2626
private final List<RemoteRepository> repositories;
27+
private final Path cacheDir;
2728

2829
private List<ArtifactResult> resolvedArtifacts;
2930

30-
public static Resolver create(String[] artifactNames, Map<String, String> repositories) {
31-
return new Resolver(artifactNames, repositories);
31+
public static Resolver create(
32+
String[] artifactNames, Map<String, String> repositories, Path cacheDir) {
33+
return new Resolver(artifactNames, repositories, cacheDir);
3234
}
3335

34-
private Resolver(String[] artifactNames, Map<String, String> repos) {
36+
private Resolver(String[] artifactNames, Map<String, String> repos, Path cacheDir) {
3537
artifacts = parseArtifacts(artifactNames);
3638
repositories = parseRepositories(repos);
39+
this.cacheDir = cacheDir;
3740
}
3841

3942
public List<ArtifactResult> resolve() throws DependencyResolutionException {
4043
if (resolvedArtifacts == null) {
41-
resolvedArtifacts = resolveArtifacts(artifacts, repositories);
44+
resolvedArtifacts = resolveArtifacts(artifacts, repositories, cacheDir);
4245
}
4346
return resolvedArtifacts;
4447
}
@@ -58,7 +61,7 @@ public List<Path> resolvePaths() throws DependencyResolutionException {
5861
* @throws DependencyResolutionException if an error occurs while resolving the artifacts
5962
*/
6063
public static List<ArtifactResult> resolveArtifacts(
61-
List<Artifact> artifacts, List<RemoteRepository> repositories)
64+
List<Artifact> artifacts, List<RemoteRepository> repositories, Path cacheDir)
6265
throws DependencyResolutionException {
6366
List<Dependency> dependencies =
6467
artifacts.stream()
@@ -67,8 +70,7 @@ public static List<ArtifactResult> resolveArtifacts(
6770
ContextOverrides.Builder ctxb =
6871
ContextOverrides.create()
6972
.withUserSettings(true)
70-
.withLocalRepositoryOverride(
71-
FileUtils.safePath(System.getenv("JPM_CACHE")));
73+
.withLocalRepositoryOverride(cacheDir);
7274
if (repositories != null && !repositories.isEmpty()) {
7375
ctxb.repositories(repositories);
7476
}

0 commit comments

Comments
 (0)