diff --git a/RELEASE-NOTES.md b/RELEASE-NOTES.md index e1e1874ec..bdf6479cf 100644 --- a/RELEASE-NOTES.md +++ b/RELEASE-NOTES.md @@ -1,5 +1,37 @@ # picocli Release Notes +# Picocli 3.0.2 +The picocli community is pleased to announce picocli 3.0.2. + +This release fixes a bug for programmatic configuration. + +This is the thirty-first public release. +Picocli follows [semantic versioning](http://semver.org/). + +## Table of Contents +* [New and noteworthy](#3.0.2-new) +* [Promoted features](#3.0.2-promoted) +* [Fixed issues](#3.0.2-fixes) +* [Deprecations](#3.0.2-deprecated) +* [Potential breaking changes](#3.0.2-breaking-changes) + +## New and Noteworthy + +## Promoted Features +Promoted features are features that were incubating in previous versions of picocli but are now supported and subject to backwards compatibility. + +No features have been promoted in this picocli release. + +## Fixed issues +- [#381] Bugfix: Prevent NPE when adding programmatically created subcommands to CommandLine. Thanks to [Mikusch](https://github.com/Mikusch) for the bug report. + +## Deprecations +No features were deprecated in this release. + +## Potential breaking changes +This release has no breaking changes. + + # Picocli 3.0.1 The picocli community is pleased to announce picocli 3.0.1. diff --git a/src/main/java/picocli/CommandLine.java b/src/main/java/picocli/CommandLine.java index fbb504a2f..72582f63a 100644 --- a/src/main/java/picocli/CommandLine.java +++ b/src/main/java/picocli/CommandLine.java @@ -4171,6 +4171,7 @@ private static void initSubcommands(Command cmd, CommandSpec parent, IFactory fa } } static void initParentCommand(Object subcommand, Object parent) { + if (subcommand == null) { return; } try { Class cls = subcommand.getClass(); while (cls != null) { diff --git a/src/test/java/picocli/CommandLineModelTest.java b/src/test/java/picocli/CommandLineModelTest.java index d41312839..e60401990 100644 --- a/src/test/java/picocli/CommandLineModelTest.java +++ b/src/test/java/picocli/CommandLineModelTest.java @@ -1572,4 +1572,24 @@ public T set(T value) throws Exception { assertEquals(null, values.get(0)); assertEquals("2", values.get(1)); } + + @Test + public void test381_NPE_whenAddingSubcommand() { + CommandSpec toplevel = CommandSpec.create(); + toplevel.addOption(OptionSpec.builder("-o").description("o option").build()); + + CommandSpec sub = CommandSpec.create(); + sub.addOption(OptionSpec.builder("-x").description("x option").build()); + + CommandLine commandLine = new CommandLine(toplevel); + commandLine.addSubcommand("sub", sub); // NPE here + commandLine.usage(System.out); + + String expected = String.format("" + + "Usage:
[-o] [COMMAND]%n" + + " -o o option%n" + + "Commands:%n" + + " sub%n"); + assertEquals(expected, systemOutRule.getLog()); + } }