Skip to content

Commit af2a89f

Browse files
authored
Merge branch 'main' into sortArgGroupSynopsis
2 parents 621c83f + cbba270 commit af2a89f

4 files changed

Lines changed: 55 additions & 25 deletions

File tree

.github/workflows/ci.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ jobs:
4646
id: test-results-nix
4747
if: ${{ always() && matrix.os == 'ubuntu-latest' }}
4848
with:
49-
junit_files: |
49+
files: |
5050
build/test-results/test/**/*.xml
5151
picocli-*/build/test-results/test/**/*.xml
5252
@@ -55,7 +55,7 @@ jobs:
5555
id: test-results
5656
if: ${{ always() && (matrix.os == 'macos-latest' || matrix.os == 'windows-latest') }}
5757
with:
58-
junit_files: |
58+
files: |
5959
build/test-results/test/**/*.xml
6060
picocli-*/build/test-results/test/**/*.xml
6161

picocli-codegen-tests-java9plus/src/test/java/picocli/annotation/processing/tests/Issue2407Test.java

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
import com.google.testing.compile.Compilation;
44
import com.google.testing.compile.JavaFileObjects;
5-
import org.junit.Ignore;
65
import org.junit.Test;
76

87
import javax.annotation.processing.Processor;
@@ -12,7 +11,6 @@
1211

1312
public class Issue2407Test
1413
{
15-
@Ignore("https://github.com/remkop/picocli/issues/2407")
1614
@Test
1715
public void testIssue2407() {
1816
Processor processor = new AnnotatedCommandSourceGeneratorProcessor();

picocli-codegen/src/main/java/picocli/codegen/annotation/processing/AbstractCommandSpecProcessor.java

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -522,7 +522,12 @@ public ArgGroupSpec.Builder visitExecutable(ExecutableElement e, Void aVoid) {
522522

523523
DeclaredType declaredType = getDeclaredTypeForArgGroupVarOrMethod(element, this);
524524
if (declaredType != null) {
525-
context.argGroupElementsByType.put(declaredType, builder);
525+
List<ArgGroupSpec.Builder> existingBuilders = context.argGroupElementsByType.get(declaredType);
526+
if (existingBuilders == null) {
527+
existingBuilders = new ArrayList<ArgGroupSpec.Builder>();
528+
context.argGroupElementsByType.put(declaredType, existingBuilders);
529+
}
530+
existingBuilders.add(builder);
526531
processEnclosedElements(context, roundEnv, declaredType.asElement().getEnclosedElements());
527532
}
528533
}
@@ -638,7 +643,12 @@ private void buildOptionsAndPositionalsFromMethodParameters(ExecutableElement me
638643

639644
DeclaredType declaredType = getDeclaredTypeForArgGroupVarOrMethod(variable, this);
640645
if (declaredType != null) {
641-
context.argGroupElementsByType.put(declaredType, builder);
646+
List<ArgGroupSpec.Builder> existingBuilders = context.argGroupElementsByType.get(declaredType);
647+
if (existingBuilders == null) {
648+
existingBuilders = new ArrayList<ArgGroupSpec.Builder>();
649+
context.argGroupElementsByType.put(declaredType, existingBuilders);
650+
}
651+
existingBuilders.add(builder);
642652
}
643653

644654
} else if (!isMixin) { // params without any annotation are also positional
@@ -859,7 +869,7 @@ static class Context {
859869
Map<Element, OptionSpec.Builder> options = new LinkedHashMap<Element, OptionSpec.Builder>();
860870
Map<Element, PositionalParamSpec.Builder> parameters = new LinkedHashMap<Element, PositionalParamSpec.Builder>();
861871
Map<Element, ArgGroupSpec.Builder> argGroupElementsByVar = new LinkedHashMap<Element, ArgGroupSpec.Builder>();
862-
Map<DeclaredType, ArgGroupSpec.Builder> argGroupElementsByType = new LinkedHashMap<DeclaredType, ArgGroupSpec.Builder>();
872+
Map<DeclaredType, List<ArgGroupSpec.Builder>> argGroupElementsByType = new LinkedHashMap<DeclaredType, List<ArgGroupSpec.Builder>>();
863873
Map<CommandSpec, Set<MixinInfo>> mixinInfoMap = new IdentityHashMap<CommandSpec, Set<MixinInfo>>();
864874
Map<Element, IAnnotatedElement> parentCommandElements = new LinkedHashMap<Element, IAnnotatedElement>();
865875
Map<Element, IAnnotatedElement> specElements = new LinkedHashMap<Element, IAnnotatedElement>();
@@ -882,10 +892,12 @@ private void connectModel(AbstractCommandSpecProcessor proc) {
882892

883893
for (Map.Entry<Element, OptionSpec.Builder> option : options.entrySet()) {
884894
TypeMirror typeMirror = option.getKey().getEnclosingElement().asType();
885-
ArgGroupSpec.Builder group = argGroupElementsByType.get(typeMirror);
886-
if (group != null) {
887-
logger.fine("Building OptionSpec for " + option + " in arg group " + group);
888-
group.addArg(option.getValue().build());
895+
List<ArgGroupSpec.Builder> groups = argGroupElementsByType.get(typeMirror);
896+
if (groups != null && !groups.isEmpty()) {
897+
for (ArgGroupSpec.Builder group : groups) {
898+
logger.fine("Building OptionSpec for " + option + " in arg group " + group);
899+
group.addArg(option.getValue().build());
900+
}
889901
} else {
890902
CommandSpec commandSpec = getOrCreateCommandSpecForArg(option.getKey(), commands);
891903
logger.fine("Building OptionSpec for " + option + " in spec " + commandSpec);
@@ -894,10 +906,12 @@ private void connectModel(AbstractCommandSpecProcessor proc) {
894906
}
895907
for (Map.Entry<Element, PositionalParamSpec.Builder> parameter : parameters.entrySet()) {
896908
TypeMirror typeMirror = parameter.getKey().getEnclosingElement().asType();
897-
ArgGroupSpec.Builder group = argGroupElementsByType.get(typeMirror);
898-
if (group != null) {
899-
logger.fine("Building PositionalParamSpec for " + parameter + " in arg group " + group);
900-
group.addArg(parameter.getValue().build());
909+
List<ArgGroupSpec.Builder> groups = argGroupElementsByType.get(typeMirror);
910+
if (groups != null && !groups.isEmpty()) {
911+
for (ArgGroupSpec.Builder group : groups) {
912+
logger.fine("Building PositionalParamSpec for " + parameter + " in arg group " + group);
913+
group.addArg(parameter.getValue().build());
914+
}
901915
} else {
902916
CommandSpec commandSpec = getOrCreateCommandSpecForArg(parameter.getKey(), commands);
903917
logger.fine("Building PositionalParamSpec for " + parameter);

src/main/java/picocli/CommandLine.java

Lines changed: 28 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -17969,29 +17969,47 @@ static boolean isJansiConsoleInstalled() {
1796917969
if (jansiInstalled == null) { jansiInstalled = calcIsJansiConsoleInstalled(); }
1797017970
return jansiInstalled;
1797117971
}
17972-
/** Returns {@code false} if system property {@code org.fusesource.jansi.Ansi.disable} is set to {@code "true"}
17973-
* (case-insensitive); otherwise, returns {@code false} if the Jansi library is in the classpath but has been disabled
17974-
* (either via system property {@code org.fusesource.jansi.Ansi.disable} or via a Jansi API call);
17972+
/** Returns {@code false} if either system properties {@code org.fusesource.jansi.Ansi.disable}
17973+
* or {@code org.jline.jansi.Ansi.disable} are set to {@code "true"} (case-insensitive);
17974+
* otherwise, returns {@code false} if the Jansi library is in the classpath but has been disabled
17975+
* (either via the aforementioned system properties or via a Jansi API call);
1797517976
* otherwise, returns {@code true} if the Jansi library is in the classpath and has been installed.
1797617977
*/
1797717978
static boolean calcIsJansiConsoleInstalled() {
1797817979
try {
1797917980
// first check if JANSI was explicitly disabled _without loading any JANSI classes_:
1798017981
// see https://github.com/remkop/picocli/issues/1106
17981-
if (Boolean.getBoolean("org.fusesource.jansi.Ansi.disable")) {
17982+
if (Boolean.getBoolean("org.jline.jansi.Ansi.disable") ||
17983+
Boolean.getBoolean("org.fusesource.jansi.Ansi.disable")) {
1798217984
return false;
1798317985
}
17984-
// the Ansi class internally also checks system property "org.fusesource.jansi.Ansi.disable"
17986+
// the Ansi class internally also checks system property "org.jline.jansi.Ansi.disable"
1798517987
// but may also have been set with Ansi.setEnabled or a custom detector
17986-
Class<?> ansi = Class.forName("org.fusesource.jansi.Ansi");
17988+
Class<?> ansi;
17989+
try {
17990+
// Try to support both the original jansi library and the newer jline jansi
17991+
ansi = Class.forName("org.fusesource.jansi.Ansi");
17992+
} catch (ClassNotFoundException e) {
17993+
ansi = Class.forName("org.jline.jansi.Ansi");
17994+
}
1798717995
Boolean enabled = (Boolean) ansi.getDeclaredMethod("isEnabled").invoke(null);
1798817996
if (!enabled) {
1798917997
return false;
1799017998
}
17991-
// loading this class will load the native library org.fusesource.jansi.internal.CLibrary
17992-
Class<?> ansiConsole = Class.forName("org.fusesource.jansi.AnsiConsole");
17993-
Field out = ansiConsole.getField("out");
17994-
return out.get(null) == System.out;
17999+
// loading this class will load the native library org.jline.jansi.internal.CLibrary
18000+
Class<?> ansiConsole;
18001+
try {
18002+
ansiConsole = Class.forName("org.fusesource.jansi.AnsiConsole");
18003+
} catch (ClassNotFoundException e) {
18004+
ansiConsole = Class.forName("org.jline.jansi.AnsiConsole");
18005+
}
18006+
try {
18007+
return (Boolean) ansiConsole.getDeclaredMethod("isInstalled").invoke(null);
18008+
} catch (Exception e) {
18009+
// isInstalled was "only" added in 2.1.0, try to support older jansi
18010+
Field out = ansiConsole.getField("out");
18011+
return out.get(null) == System.out;
18012+
}
1799518013
} catch (Exception reflectionFailed) {
1799618014
return false;
1799718015
}

0 commit comments

Comments
 (0)