Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,11 @@
import eu.maveniverse.maven.mima.context.Runtimes;
import eu.maveniverse.maven.mima.runtime.standalonestatic.StandaloneStaticRuntime;
import eu.maveniverse.maven.toolbox.plugin.CLI;
import eu.maveniverse.maven.toolbox.plugin.ContextMapAware;
import eu.maveniverse.maven.toolbox.plugin.CwdAware;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import javax.inject.Named;
import javax.inject.Singleton;
import org.apache.maven.cling.invoker.LookupContext;
Expand All @@ -25,6 +29,9 @@
@Named("toolbox")
@Singleton
public class ToolboxShellCommandRegistryFactory implements ShellCommandRegistryFactory {
// shared context for all mvnsh commands
private final Map<Object, Object> contextMap = Collections.synchronizedMap(new HashMap<>());

@Override
public CommandRegistry createShellCommandRegistry(LookupContext lookupContext) {
Runtimes.INSTANCE.registerRuntime(new StandaloneStaticRuntime());
Expand All @@ -36,6 +43,9 @@ public <K> K create(Class<K> clazz) throws Exception {
if (result instanceof CwdAware cwdAware) {
cwdAware.setCwd(lookupContext.cwd.get());
}
if (result instanceof ContextMapAware contextMapAware) {
contextMapAware.setContextMap(contextMap);
}
return result;
}
};
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/*
* 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.plugin;

import java.util.Map;
import java.util.Optional;

public interface ContextMapAware {
/**
* Sets context. The map must be non-null.
*/
void setContextMap(Map<Object, Object> context);

/**
* Returns context, if set.
*/
Optional<Map<Object, Object>> getContextMap();
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import static java.util.Objects.requireNonNull;

import java.nio.file.Path;
import java.util.Optional;

public interface CwdAware {
/**
Expand All @@ -18,15 +19,15 @@ public interface CwdAware {
void setCwd(Path cwd);

/**
* Returns CWD; a non-null path that points to existing directory.
* Returns CWD, if set; a non-null path that points to existing directory.
*/
Path getCwd();
Optional<Path> getCwd();

/**
* Resolves against CWD.
* Resolves against CWD, if set.
*/
default Path resolve(Path path) {
requireNonNull(path, "path");
return getCwd().resolve(path).normalize().toAbsolutePath();
return getCwd().orElseThrow().resolve(path).normalize().toAbsolutePath();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.Callable;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Supplier;
Expand All @@ -39,7 +40,7 @@
* Support class for all Mojos and Commands.
*/
public abstract class MojoSupport extends AbstractMojo
implements Callable<Integer>, CwdAware, CommandLine.IVersionProvider {
implements Callable<Integer>, CwdAware, ContextMapAware, CommandLine.IVersionProvider {

// CLI

Expand Down Expand Up @@ -137,26 +138,39 @@ public void setCwd(Path cwd) {
}

@Override
public Path getCwd() {
return cwd;
public Optional<Path> getCwd() {
return Optional.of(cwd);
}

private static final AtomicReference<Map<Object, Object>> CONTEXT = new AtomicReference<>(null);
private final AtomicReference<Map<Object, Object>> contextMapRef = new AtomicReference<>(null);

@Override
public void setContextMap(Map<Object, Object> context) {
requireNonNull(context, "context map");
if (!contextMapRef.compareAndSet(null, context)) {
throw new IllegalStateException("context map already set");
}
}

@Override
public Optional<Map<Object, Object>> getContextMap() {
return Optional.ofNullable(contextMapRef.get());
}

protected <T> T getOrCreate(Class<T> key, Supplier<T> supplier) {
return (T) CONTEXT.get().computeIfAbsent(key, k -> supplier.get());
return (T) contextMapRef.get().computeIfAbsent(key, k -> supplier.get());
}

protected <T> T get(Class<T> key) {
return (T) requireNonNull(CONTEXT.get().get(key), "key is not present");
return (T) requireNonNull(contextMapRef.get().get(key), "key is not present");
}

protected <T> void set(Class<T> key, T value) {
requireNonNull(key, "key");
if (value == null) {
CONTEXT.get().remove(key);
contextMapRef.get().remove(key);
} else {
CONTEXT.get().put(key, value);
contextMapRef.get().put(key, value);
}
}

Expand Down Expand Up @@ -263,11 +277,12 @@ public final Integer call() {
} else if (debug) {
System.setProperty("org.slf4j.simpleLogger.defaultLogLevel", "DEBUG");
}
boolean seeded = CONTEXT.compareAndSet(null, new HashMap<>());
boolean seeded = contextMapRef.compareAndSet(null, new HashMap<>());
getOrCreate(Runtime.class, Runtimes.INSTANCE::getRuntime);
getOrCreate(Context.class, () -> get(Runtime.class).create(createCLIContextOverrides()));
getOrCreate(Output.class, () -> OutputFactory.createCliOutput(batch, errors, verbosity));
ToolboxCommando commando = ToolboxCommando.create(getOutput(), getContext());
ToolboxCommando commando =
getOrCreate(ToolboxCommando.class, () -> ToolboxCommando.create(getOutput(), getContext()));
ToolboxCommando customized = null;
if (extraRepositories != null) {
customized = commando.withContextOverrides(getContext().contextOverrides().toBuilder()
Expand Down Expand Up @@ -314,7 +329,7 @@ public final Integer call() {
} catch (Exception e) {
e.printStackTrace(System.err);
}
CONTEXT.set(null);
contextMapRef.set(null);
}
}
}
Expand Down Expand Up @@ -350,7 +365,7 @@ public final Integer call() {
*/
@Override
public final void execute() throws MojoExecutionException, MojoFailureException {
boolean seeded = CONTEXT.compareAndSet(null, new HashMap<>());
boolean seeded = contextMapRef.compareAndSet(null, new HashMap<>());
getOrCreate(Runtime.class, Runtimes.INSTANCE::getRuntime);
getOrCreate(Context.class, () -> get(Runtime.class).create(createMojoContextOverrides()));
if (forceStdout) {
Expand All @@ -359,7 +374,8 @@ public final void execute() throws MojoExecutionException, MojoFailureException
getOrCreate(
Output.class, () -> OutputFactory.createMojoOutput(!mojoInteractiveMode, mojoErrors, verbosity));
}
ToolboxCommando commando = ToolboxCommando.create(getOutput(), getContext());
ToolboxCommando commando =
getOrCreate(ToolboxCommando.class, () -> ToolboxCommando.create(getOutput(), getContext()));
ToolboxCommando customized = null;
if (extraRepositories != null) {
customized = commando.withContextOverrides(getContext().contextOverrides().toBuilder()
Expand Down Expand Up @@ -398,7 +414,7 @@ public final void execute() throws MojoExecutionException, MojoFailureException
} catch (Exception e) {
getLog().error(e);
}
CONTEXT.set(null);
contextMapRef.set(null);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@

import eu.maveniverse.maven.mima.context.Context;
import eu.maveniverse.maven.toolbox.plugin.CLI;
import eu.maveniverse.maven.toolbox.plugin.ContextMapAware;
import eu.maveniverse.maven.toolbox.plugin.CwdAware;
import eu.maveniverse.maven.toolbox.plugin.GavMojoSupport;
import eu.maveniverse.maven.toolbox.shared.Result;
import eu.maveniverse.maven.toolbox.shared.output.Output;
Expand Down Expand Up @@ -56,7 +58,21 @@ public Result<String> doExecute() throws Exception {
builtins.alias("zle", "widget");
builtins.alias("bindkey", "keymap");
// set up picocli commands
CommandLine cmd = new CommandLine(new CLI());
PicocliCommands.PicocliCommandsFactory factory = new PicocliCommands.PicocliCommandsFactory() {
@Override
public <K> K create(Class<K> clazz) throws Exception {
K result = super.create(clazz);
if (result instanceof CwdAware cwdAware) {
cwdAware.setCwd(getCwd().orElseThrow()); // must be set on "this"
}
if (result instanceof ContextMapAware contextMapAware) {
contextMapAware.setContextMap(getContextMap().orElseThrow()); // must be set on "this"
}
return result;
}
};

CommandLine cmd = new CommandLine(new CLI(), factory);
PicocliCommands picocliCommands = new PicocliCommands(cmd);
picocliCommands.name("Maveniverse Toolbox");
Parser parser = new DefaultParser();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
*/
public abstract class HelloMojoSupport extends GavMojoSupport {
protected Path getRootPom() {
return getCwd().resolve("pom.xml");
return resolve(Path.of("pom.xml"));
}

/**
Expand Down
Loading