Skip to content

Commit

Permalink
[MNG-8437] mvnsh (#1982)
Browse files Browse the repository at this point in the history
Maven shell

Changes:
* (unrelated) contains fix for property handling in embedded executor and in lookup invoker
* pulled `-o` (offline) option to "generic" Options from MavenOptions
* introduce mvnsh (scripts, options, CLIng main class)
* simplified invokers (only one context needed for maven now)
* invokers made "reentrant", it all depends HOW context is created

Related PRs:
* mvnd changes apache/maven-mvnd#1228

---

https://issues.apache.org/jira/browse/MNG-8437
  • Loading branch information
cstamas authored Dec 17, 2024
1 parent d9dcac8 commit 49825e6
Show file tree
Hide file tree
Showing 44 changed files with 1,295 additions and 663 deletions.
1 change: 1 addition & 0 deletions apache-maven/src/assembly/component.xml
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ under the License.
<includes>
<include>mvn</include>
<include>mvnenc</include>
<include>mvnsh</include>
<include>mvnDebug</include>
<include>mvnencDebug</include>
<!-- This is so that CI systems can periodically run the profiler -->
Expand Down
3 changes: 3 additions & 0 deletions apache-maven/src/assembly/maven/bin/mvn
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,9 @@ handle_args() {
--enc)
MAVEN_MAIN_CLASS="org.apache.maven.cling.MavenEncCling"
;;
--shell)
MAVEN_MAIN_CLASS="org.apache.maven.cling.MavenShellCling"
;;
*)
;;
esac
Expand Down
2 changes: 2 additions & 0 deletions apache-maven/src/assembly/maven/bin/mvn.cmd
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,8 @@ if "%~1"=="--debug" (
set "MAVEN_OPTS=-agentpath:%YJPLIB%=onexit=snapshot,onexit=memory,tracing,onlylocal %MAVEN_OPTS%"
) else if "%~1"=="--enc" (
set "MAVEN_MAIN_CLASS=org.apache.maven.cling.MavenEncCling"
) else if "%~1"=="--shell" (
set "MAVEN_MAIN_CLASS=org.apache.maven.cling.MavenShellCling"
)
exit /b 0

Expand Down
30 changes: 30 additions & 0 deletions apache-maven/src/assembly/maven/bin/mvnsh
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#!/bin/sh

# 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.

# -----------------------------------------------------------------------------
# Apache Maven Encrypt Script
#
# Environment Variable Prerequisites
#
# JAVA_HOME (Optional) Points to a Java installation.
# MAVEN_OPTS (Optional) Java runtime options used when Maven is executed.
# MAVEN_SKIP_RC (Optional) Flag to disable loading of mavenrc files.
# -----------------------------------------------------------------------------

"`dirname "$0"`/mvn" --shell "$@"
39 changes: 39 additions & 0 deletions apache-maven/src/assembly/maven/bin/mvnsh.cmd
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
@REM Licensed to the Apache Software Foundation (ASF) under one
@REM or more contributor license agreements. See the NOTICE file
@REM distributed with this work for additional information
@REM regarding copyright ownership. The ASF licenses this file
@REM to you under the Apache License, Version 2.0 (the
@REM "License"); you may not use this file except in compliance
@REM with the License. You may obtain a copy of the License at
@REM
@REM http://www.apache.org/licenses/LICENSE-2.0
@REM
@REM Unless required by applicable law or agreed to in writing,
@REM software distributed under the License is distributed on an
@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
@REM KIND, either express or implied. See the License for the
@REM specific language governing permissions and limitations
@REM under the License.

@REM -----------------------------------------------------------------------------
@REM Apache Maven Encrypt Script
@REM
@REM Environment Variable Prerequisites
@REM
@REM JAVA_HOME (Optional) Points to a Java installation.
@REM MAVEN_BATCH_ECHO (Optional) Set to 'on' to enable the echoing of the batch commands.
@REM MAVEN_BATCH_PAUSE (Optional) set to 'on' to wait for a key stroke before ending.
@REM MAVEN_OPTS (Optional) Java runtime options used when Maven is executed.
@REM MAVEN_SKIP_RC (Optional) Flag to disable loading of mavenrc files.
@REM -----------------------------------------------------------------------------

@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'
@echo off
@REM set title of command window
title %0
@REM enable echoing by setting MAVEN_BATCH_ECHO to 'on'
@if "%MAVEN_BATCH_ECHO%"=="on" echo %MAVEN_BATCH_ECHO%

@setlocal

@call "%~dp0"mvn.cmd --shell %*
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,14 @@ public interface Options {
@Nonnull
Optional<String> color();

/**
* Indicates whether Maven should operate in offline mode.
*
* @return an {@link Optional} containing true if offline mode is enabled, false if disabled, or empty if not specified
*/
@Nonnull
Optional<Boolean> offline();

/**
* Indicates whether to show help information.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,34 @@ static Builder mvnenc(
return builder(Tools.MVNENC_CMD, Tools.MVNENC_NAME, args, logger, messageBuilderFactory);
}

/**
* Creates a new Builder instance for constructing a Maven Shell Tool ParserRequest.
*
* @param args the command-line arguments
* @param logger the logger to be used during parsing
* @param messageBuilderFactory the factory for creating message builders
* @return a new Builder instance
*/
@Nonnull
static Builder mvnsh(
@Nonnull String[] args, @Nonnull Logger logger, @Nonnull MessageBuilderFactory messageBuilderFactory) {
return mvnsh(Arrays.asList(args), logger, messageBuilderFactory);
}

/**
* Creates a new Builder instance for constructing a Maven Shell Tool ParserRequest.
*
* @param args the command-line arguments
* @param logger the logger to be used during parsing
* @param messageBuilderFactory the factory for creating message builders
* @return a new Builder instance
*/
@Nonnull
static Builder mvnsh(
@Nonnull List<String> args, @Nonnull Logger logger, @Nonnull MessageBuilderFactory messageBuilderFactory) {
return builder(Tools.MVNSHELL_CMD, Tools.MVNSHELL_NAME, args, logger, messageBuilderFactory);
}

/**
* Creates a new Builder instance for constructing a ParserRequest.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,4 +36,7 @@ private Tools() {}

public static final String MVNENC_CMD = "mvnenc";
public static final String MVNENC_NAME = "Maven Password Encrypting Tool";

public static final String MVNSHELL_CMD = "mvnsh";
public static final String MVNSHELL_NAME = "Maven Shell Tool";
}
Original file line number Diff line number Diff line change
Expand Up @@ -48,14 +48,6 @@ public interface MavenOptions extends Options {
@Nonnull
Optional<String> alternatePomFile();

/**
* Indicates whether Maven should operate in offline mode.
*
* @return an {@link Optional} containing true if offline mode is enabled, false if disabled, or empty if not specified
*/
@Nonnull
Optional<Boolean> offline();

/**
* Indicates whether Maven should operate in non-recursive mode (i.e., not build child modules).
*
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/*
* 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.maven.api.cli.mvnsh;

import java.util.Collection;
import java.util.Map;

import org.apache.maven.api.annotations.Experimental;
import org.apache.maven.api.annotations.Nonnull;
import org.apache.maven.api.cli.Options;

/**
* Defines the options specific to the Maven Shell tool.
* This interface extends the general {@link Options} interface, adding shell-specific configuration options.
*
* @since 4.0.0
*/
@Experimental
public interface ShellOptions extends Options {
/**
* Returns a new instance of ShellOptions with values interpolated using the given properties.
*
* @param properties a collection of property maps to use for interpolation
* @return a new EncryptOptions instance with interpolated values
*/
@Nonnull
ShellOptions interpolate(Collection<Map<String, String>> properties);
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@
import org.apache.maven.api.cli.ParserRequest;
import org.apache.maven.cling.invoker.ProtoLogger;
import org.apache.maven.cling.invoker.ProtoLookup;
import org.apache.maven.cling.invoker.mvn.MavenInvoker;
import org.apache.maven.cling.invoker.mvn.MavenParser;
import org.apache.maven.cling.invoker.mvn.local.LocalMavenInvoker;
import org.apache.maven.jline.JLineMessageBuilderFactory;
import org.codehaus.plexus.classworlds.ClassWorld;

Expand Down Expand Up @@ -61,7 +61,7 @@ public MavenCling(ClassWorld classWorld) {

@Override
protected Invoker createInvoker() {
return new LocalMavenInvoker(
return new MavenInvoker(
ProtoLookup.builder().addMapping(ClassWorld.class, classWorld).build());
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
/*
* 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.maven.cling;

import java.io.IOException;

import org.apache.maven.api.cli.Invoker;
import org.apache.maven.api.cli.InvokerRequest;
import org.apache.maven.api.cli.ParserException;
import org.apache.maven.api.cli.ParserRequest;
import org.apache.maven.cling.invoker.ProtoLogger;
import org.apache.maven.cling.invoker.ProtoLookup;
import org.apache.maven.cling.invoker.mvnsh.ShellInvoker;
import org.apache.maven.cling.invoker.mvnsh.ShellParser;
import org.apache.maven.jline.JLineMessageBuilderFactory;
import org.codehaus.plexus.classworlds.ClassWorld;

/**
* Maven shell.
*/
public class MavenShellCling extends ClingSupport {
/**
* "Normal" Java entry point. Note: Maven uses ClassWorld Launcher and this entry point is NOT used under normal
* circumstances.
*/
public static void main(String[] args) throws IOException {
int exitCode = new MavenShellCling().run(args);
System.exit(exitCode);
}

/**
* ClassWorld Launcher "enhanced" entry point: returning exitCode and accepts Class World.
*/
public static int main(String[] args, ClassWorld world) throws IOException {
return new MavenShellCling(world).run(args);
}

public MavenShellCling() {
super();
}

public MavenShellCling(ClassWorld classWorld) {
super(classWorld);
}

@Override
protected Invoker createInvoker() {
return new ShellInvoker(
ProtoLookup.builder().addMapping(ClassWorld.class, classWorld).build());
}

@Override
protected InvokerRequest parseArguments(String[] args) throws ParserException, IOException {
return new ShellParser()
.parseInvocation(ParserRequest.mvnsh(args, new ProtoLogger(), new JLineMessageBuilderFactory())
.build());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,6 @@
*/
package org.apache.maven.cling.extensions;

import javax.inject.Inject;
import javax.inject.Named;

import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Collections;
Expand All @@ -33,7 +30,10 @@
import org.apache.maven.RepositoryUtils;
import org.apache.maven.api.Service;
import org.apache.maven.api.Session;
import org.apache.maven.api.annotations.Nullable;
import org.apache.maven.api.cli.extensions.CoreExtension;
import org.apache.maven.api.di.Inject;
import org.apache.maven.api.di.Named;
import org.apache.maven.api.model.Plugin;
import org.apache.maven.api.services.ArtifactCoordinatesFactory;
import org.apache.maven.api.services.ArtifactManager;
Expand Down Expand Up @@ -80,7 +80,6 @@
import org.eclipse.aether.resolution.DependencyResult;
import org.eclipse.aether.util.filter.ExclusionsDependencyFilter;
import org.eclipse.aether.util.version.GenericVersionScheme;
import org.eclipse.sisu.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,14 @@ public Optional<String> color() {
return Optional.empty();
}

@Override
public Optional<Boolean> offline() {
if (commandLine.hasOption(CLIManager.OFFLINE)) {
return Optional.of(Boolean.TRUE);
}
return Optional.empty();
}

@Override
public Optional<Boolean> help() {
if (commandLine.hasOption(CLIManager.HELP)) {
Expand Down Expand Up @@ -267,11 +275,13 @@ protected static class CLIManager {
public static final String LOG_FILE = "l";
public static final String RAW_STREAMS = "raw-streams";
public static final String COLOR = "color";
public static final String OFFLINE = "o";
public static final String HELP = "h";

// parameters handled by script
public static final String DEBUG = "debug";
public static final String ENC = "enc";
public static final String SHELL = "shell";
public static final String YJP = "yjp";

// deprecated ones
Expand Down Expand Up @@ -378,6 +388,10 @@ protected void prepareOptions(org.apache.commons.cli.Options options) {
.optionalArg(true)
.desc("Defines the color mode of the output. Supported are 'auto', 'always', 'never'.")
.build());
options.addOption(Option.builder(OFFLINE)
.longOpt("offline")
.desc("Work offline")
.build());

// Parameters handled by script
options.addOption(Option.builder()
Expand All @@ -388,6 +402,10 @@ protected void prepareOptions(org.apache.commons.cli.Options options) {
.longOpt(ENC)
.desc("Launch the Maven Encryption tool (script option).")
.build());
options.addOption(Option.builder()
.longOpt(SHELL)
.desc("Launch the Maven Shell tool (script option).")
.build());
options.addOption(Option.builder()
.longOpt(YJP)
.desc("Launch the JVM with Yourkit profiler (script option).")
Expand Down
Loading

0 comments on commit 49825e6

Please sign in to comment.