diff --git a/.asf.yaml b/.asf.yaml
new file mode 100644
index 000000000..98ad8cee6
--- /dev/null
+++ b/.asf.yaml
@@ -0,0 +1,30 @@
+# 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
+#
+# https://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.
+
+github:
+ description: Apache Commons CLI
+ homepage: http://commons.apache.org/cli/
+
+notifications:
+ commits: commits@commons.apache.org
+ issues: issues@commons.apache.org
+ pullrequests: issues@commons.apache.org
+ jira_options: link label
+ jobs: notifications@commons.apache.org
+ # commits_bot_dependabot: dependabot@commons.apache.org
+ issues_bot_dependabot: dependabot@commons.apache.org
+ pullrequests_bot_dependabot: dependabot@commons.apache.org
+ issues_bot_codecov-commenter: notifications@commons.apache.org
+ pullrequests_bot_codecov-commenter: notifications@commons.apache.org
diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 000000000..4f9cffcea
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1,17 @@
+# 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
+#
+# https://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.
+
+* text=auto
+*.patch -text
diff --git a/.github/GH-ROBOTS.txt b/.github/GH-ROBOTS.txt
new file mode 100644
index 000000000..64a88674f
--- /dev/null
+++ b/.github/GH-ROBOTS.txt
@@ -0,0 +1,19 @@
+# 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
+#
+# https://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.
+
+# Keeps on creating FUD PRs in test code
+# Does not follow Apache disclosure policies
+User-agent: JLLeitschuh/security-research
+Disallow: *
diff --git a/.github/dependabot.yml b/.github/dependabot.yml
new file mode 100644
index 000000000..90ec55f74
--- /dev/null
+++ b/.github/dependabot.yml
@@ -0,0 +1,25 @@
+# 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
+#
+# https://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.
+
+version: 2
+updates:
+ - package-ecosystem: "maven"
+ directory: "/"
+ schedule:
+ interval: "quarterly"
+ - package-ecosystem: "github-actions"
+ directory: "/"
+ schedule:
+ interval: "quarterly"
diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md
new file mode 100644
index 000000000..9ff35c83e
--- /dev/null
+++ b/.github/pull_request_template.md
@@ -0,0 +1,30 @@
+
+
+Thanks for your contribution to [Apache Commons](https://commons.apache.org/)! Your help is appreciated!
+
+Before you push a pull request, review this list:
+
+- [ ] Read the [contribution guidelines](CONTRIBUTING.md) for this project.
+- [ ] Read the [ASF Generative Tooling Guidance](https://www.apache.org/legal/generative-tooling.html) if you use Artificial Intelligence (AI).
+- [ ] I used AI to create any part of, or all of, this pull request. Which AI tool was used to create this pull request, and to what extent did it contribute?
+- [ ] Run a successful build using the default [Maven](https://maven.apache.org/) goal with `mvn`; that's `mvn` on the command line by itself.
+- [ ] Write unit tests that match behavioral changes, where the tests fail if the changes to the runtime are not applied. This may not always be possible, but it is a best practice.
+- [ ] Write a pull request description that is detailed enough to understand what the pull request does, how, and why.
+- [ ] Each commit in the pull request should have a meaningful subject line and body. Note that a maintainer may squash commits during the merge process.
diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml
new file mode 100644
index 000000000..b7b7fdf05
--- /dev/null
+++ b/.github/workflows/codeql-analysis.yml
@@ -0,0 +1,86 @@
+# 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
+#
+# https://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.
+
+name: "CodeQL"
+
+on:
+ push:
+ branches: [ master ]
+ pull_request:
+ # The branches below must be a subset of the branches above
+ branches: [ master ]
+ schedule:
+ - cron: '33 9 * * 4'
+
+permissions:
+ contents: read
+
+jobs:
+ analyze:
+ name: Analyze
+ runs-on: ubuntu-latest
+ permissions:
+ actions: read
+ contents: read
+ security-events: write
+
+ strategy:
+ max-parallel: 20
+ fail-fast: false
+ matrix:
+ language: [ 'java' ]
+ # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ]
+ # Learn more about CodeQL language support at https://git.io/codeql-language-support
+
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
+ with:
+ persist-credentials: false
+ - uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae #v5.0.5
+ with:
+ path: ~/.m2/repository
+ key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
+ restore-keys: |
+ ${{ runner.os }}-maven-
+
+ # Initializes the CodeQL tools for scanning.
+ - name: Initialize CodeQL
+ uses: github/codeql-action/init@95e58e9a2cdfd71adc6e0353d5c52f41a045d225 # v4.35.2
+ with:
+ languages: ${{ matrix.language }}
+ # If you wish to specify custom queries, you can do so here or in a config file.
+ # By default, queries listed here will override any specified in a config file.
+ # Prefix the list here with "+" to use these queries and those in the config file.
+ # queries: ./path/to/local/query, your-org/your-repo/queries@main
+
+ # Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
+ # If this step fails, then you should remove it and run the build manually (see below)
+ - name: Autobuild
+ uses: github/codeql-action/autobuild@95e58e9a2cdfd71adc6e0353d5c52f41a045d225 # v4.35.2
+
+ # ℹ️ Command-line programs to run using the OS shell.
+ # 📚 https://git.io/JvXDl
+
+ # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
+ # and modify them (or add more) to build your code if your project
+ # uses a compiled language
+
+ #- run: |
+ # make bootstrap
+ # make release
+
+ - name: Perform CodeQL Analysis
+ uses: github/codeql-action/analyze@95e58e9a2cdfd71adc6e0353d5c52f41a045d225 # v4.35.2
diff --git a/.github/workflows/dependency-review.yml b/.github/workflows/dependency-review.yml
new file mode 100644
index 000000000..f0d8ca94e
--- /dev/null
+++ b/.github/workflows/dependency-review.yml
@@ -0,0 +1,31 @@
+# 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
+#
+# https://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.
+
+name: 'Dependency Review'
+on: [pull_request]
+
+permissions:
+ contents: read
+
+jobs:
+ dependency-review:
+ runs-on: ubuntu-latest
+ steps:
+ - name: 'Checkout Repository'
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
+ - name: 'Dependency Review PR'
+ uses: actions/dependency-review-action@2031cfc080254a8a887f58cffee85186f0e49e48 # v4.9.0
diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml
new file mode 100644
index 000000000..0ac859b4a
--- /dev/null
+++ b/.github/workflows/maven.yml
@@ -0,0 +1,59 @@
+# 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
+#
+# https://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.
+
+name: Java CI
+
+on:
+ push:
+ branches:
+ - 'master'
+ pull_request: {}
+
+permissions:
+ contents: read
+
+jobs:
+ build:
+
+ runs-on: ubuntu-latest
+ continue-on-error: ${{ matrix.experimental }}
+ strategy:
+ max-parallel: 20
+ matrix:
+ java: [ 8, 11, 17, 21, 25 ]
+ experimental: [false]
+ include:
+ - java: 26-ea
+ experimental: true
+# - java: 27-ea
+# experimental: true
+
+ steps:
+ - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
+ with:
+ persist-credentials: false
+ - uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae #v5.0.5
+ with:
+ path: ~/.m2/repository
+ key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
+ restore-keys: |
+ ${{ runner.os }}-maven-
+ - name: Set up JDK ${{ matrix.java }}
+ uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 # v5.2.0
+ with:
+ distribution: 'temurin'
+ java-version: ${{ matrix.java }}
+ - name: Build with Maven
+ run: mvn --errors --show-version --batch-mode --no-transfer-progress
diff --git a/.github/workflows/scorecards-analysis.yml b/.github/workflows/scorecards-analysis.yml
new file mode 100644
index 000000000..16e37f605
--- /dev/null
+++ b/.github/workflows/scorecards-analysis.yml
@@ -0,0 +1,69 @@
+# 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
+#
+# https://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.
+
+name: "Scorecards supply-chain security"
+
+on:
+ branch_protection_rule:
+ schedule:
+ - cron: "30 1 * * 6" # Weekly on Saturdays
+ push:
+ branches: [ "master" ]
+
+permissions: read-all
+
+jobs:
+
+ analysis:
+
+ name: "Scorecards analysis"
+ runs-on: ubuntu-latest
+ permissions:
+ # Needed to upload the results to the code-scanning dashboard.
+ security-events: write
+ actions: read
+ id-token: write # This is required for requesting the JWT
+ contents: read # This is required for actions/checkout
+
+ steps:
+
+ - name: "Checkout code"
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # 6.0.2
+ with:
+ persist-credentials: false
+
+ - name: "Run analysis"
+ uses: ossf/scorecard-action@4eaacf0543bb3f2c246792bd56e8cdeffafb205a # 2.4.3
+ with:
+ results_file: results.sarif
+ results_format: sarif
+ # A read-only PAT token, which is sufficient for the action to function.
+ # The relevant discussion: https://github.com/ossf/scorecard-action/issues/188
+ repo_token: ${{ secrets.GITHUB_TOKEN }}
+ # Publish the results for public repositories to enable scorecard badges.
+ # For more details: https://github.com/ossf/scorecard-action#publishing-results
+ publish_results: true
+
+ - name: "Upload artifact"
+ uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
+ with:
+ name: SARIF file
+ path: results.sarif
+ retention-days: 5
+
+ - name: "Upload to code-scanning"
+ uses: github/codeql-action/upload-sarif@95e58e9a2cdfd71adc6e0353d5c52f41a045d225 # v4.35.2
+ with:
+ sarif_file: results.sarif
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 000000000..5a3aaa1b2
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,29 @@
+### https://raw.github.com/github/gitignore/f2ce448f2ba7a092da05482ceca99209127c0884/maven.gitignore
+
+target/
+pom.xml.tag
+pom.xml.releaseBackup
+pom.xml.versionsBackup
+pom.xml.next
+release.properties
+dependency-reduced-pom.xml
+buildNumber.properties
+.mvn/timing.properties
+
+# Exclude maven wrapper
+!/.mvn/wrapper/maven-wrapper.jar
+
+site-content
+/.classpath
+/.project
+/.settings/
+
+### IntelliJ IDEA ###
+.idea/
+*.iws
+*.ipr
+*.iml
+
+# NetBeans files
+nb-configuration.xml
+nbactions.xml
diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md
new file mode 100644
index 000000000..b4342f33c
--- /dev/null
+++ b/CODE_OF_CONDUCT.md
@@ -0,0 +1,17 @@
+
+The Apache code of conduct page is [https://www.apache.org/foundation/policies/conduct.html](https://www.apache.org/foundation/policies/conduct.html).
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
new file mode 100644
index 000000000..e4440b2a2
--- /dev/null
+++ b/CONTRIBUTING.md
@@ -0,0 +1,116 @@
+
+
+Contributing to Apache Commons CLI
+======================
+
+Have you found a bug or have an idea for a cool new feature? Contributing code is a great way to give something back to the open-source community.
+Before you dig right into the code, we need contributors to follow a few guidelines to have a chance of keeping on top of things.
+
+Getting Started
+---------------
+
++ Make sure you have a [JIRA account](https://issues.apache.org/jira/).
++ Make sure you have a [GitHub account](https://github.com/signup/free). This is not essential, but makes providing patches much easier.
++ If you're planning to implement a new feature it makes sense to discuss your changes on the [dev list](https://commons.apache.org/mail-lists.html) first. This way you can make sure you're not wasting your time on something that isn't considered to be in Apache Commons CLI's scope.
++ Submit a [Jira Ticket][jira] for your issue, assuming one does not already exist.
+ + Clearly describe the issue including steps to reproduce when it is a bug.
+ + Make sure you fill in the earliest version that you know has the issue.
++ Find the corresponding [repository on GitHub](https://github.com/apache/?query=commons-),
+[fork](https://help.github.com/articles/fork-a-repo/) and check out your forked repository. If you don't have a GitHub account, you can still clone the Commons repository.
+
+Making Changes
+--------------
+
++ Create a _topic branch_ for your isolated work.
+ * Usually you should base your branch from the `master` branch.
+ * A good topic branch name can be the JIRA bug ID plus a keyword, e.g. `CLI-123-InputStream`.
+ * If you have submitted multiple JIRA issues, try to maintain separate branches and pull requests.
++ Make commits of logical units.
+ * Make sure your commit messages are meaningful and in the proper format. Your commit message should contain the key of the JIRA issue.
+ * For example, `[CLI-123] Close input stream sooner`
++ Respect the original code style:
+ + Only use spaces for indentation; you can check for unnecessary whitespace with `git diff` before committing.
+ + Create minimal diffs - disable _On Save_ actions like _Reformat Source Code_ or _Organize Imports_. If you feel the source code should be reformatted create a separate PR for this change first.
++ Write unit tests that match behavioral changes, where the tests fail if the changes to the runtime are not applied. This may not always be possible but is a best-practice.
+Unit tests are typically in the `src/test/java` directory.
++ Run a successful build using the default [Maven](https://maven.apache.org/) goal with `mvn`; that's `mvn` on the command line by itself.
++ Write a pull request description that is detailed enough to understand what the pull request does, how, and why.
++ Each commit in the pull request should have a meaningful subject line and body. Note that commits might be squashed by a maintainer on merge.
+
+
+Making Trivial Changes
+----------------------
+
+The JIRA tickets are used to generate the changelog for the next release.
+
+For changes of a trivial nature to comments and documentation, it is not always necessary to create a new ticket in JIRA.
+In this case, it is appropriate to start the first line of a commit with '[doc]' or '[javadoc]' instead of a ticket number.
+
+
+Submitting Changes
+------------------
+
++ Sign and submit the Apache [Contributor License Agreement][cla] if you haven't already.
+ * Note that small patches & typical bug fixes do not require a CLA as
+ clause 5 of the [Apache License](https://www.apache.org/licenses/LICENSE-2.0.html#contributions)
+ covers them.
++ Push your changes to a topic branch in your fork of the repository.
++ Submit a _Pull Request_ to the corresponding repository in the `apache` organization.
+ * Verify _Files Changed_ shows only your intended changes and does not
+ include additional files like `target/*.class`
++ Update your JIRA ticket and include a link to the pull request in the ticket.
+
+If you prefer to not use GitHub, then you can instead use
+`git format-patch` (or `svn diff`) and attach the patch file to the JIRA issue.
+
+
+Additional Resources
+--------------------
+
++ [Contributing patches](https://commons.apache.org/patches.html)
++ [Apache Commons CLI JIRA project page][jira]
++ [Contributor License Agreement][cla]
++ [General GitHub documentation](https://help.github.com/)
++ [GitHub pull request documentation](https://help.github.com/articles/creating-a-pull-request/)
++ [Apache Commons Twitter Account](https://twitter.com/ApacheCommons)
+
+[cla]:https://www.apache.org/licenses/#clas
+[jira]:https://issues.apache.org/jira/browse/CLI
diff --git a/LICENSE.txt b/LICENSE.txt
index 57bc88a15..4fa588fe1 100644
--- a/LICENSE.txt
+++ b/LICENSE.txt
@@ -192,7 +192,7 @@
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
+ https://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,
diff --git a/NOTICE.txt b/NOTICE.txt
index 72eb32a90..a8fd7fbae 100644
--- a/NOTICE.txt
+++ b/NOTICE.txt
@@ -1,5 +1,5 @@
Apache Commons CLI
-Copyright 2001-2009 The Apache Software Foundation
+Copyright 2002-2026 The Apache Software Foundation
-This product includes software developed by
-The Apache Software Foundation (http://www.apache.org/).
+This product includes software developed at
+The Apache Software Foundation (https://www.apache.org/).
diff --git a/README.md b/README.md
new file mode 100644
index 000000000..c241c798b
--- /dev/null
+++ b/README.md
@@ -0,0 +1,119 @@
+
+
+Apache Commons CLI
+===================
+
+[](https://github.com/apache/commons-cli/actions/workflows/maven.yml)
+[](https://search.maven.org/artifact/commons-cli/commons-cli)
+[](https://javadoc.io/doc/commons-cli/commons-cli/1.11.0)
+[](https://github.com/apache/commons-cli/actions/workflows/codeql-analysis.yml)
+[](https://api.securityscorecards.dev/projects/github.com/apache/commons-cli)
+
+Apache Commons CLI provides a simple API for presenting, processing, and validating a Command Line Interface.
+
+Documentation
+-------------
+
+More information can be found on the [Apache Commons CLI homepage](https://commons.apache.org/proper/commons-cli).
+The [Javadoc](https://commons.apache.org/proper/commons-cli/apidocs) can be browsed.
+Questions related to the usage of Apache Commons CLI should be posted to the [user mailing list](https://commons.apache.org/mail-lists.html).
+
+Getting the latest release
+--------------------------
+You can download source and binaries from our [download page](https://commons.apache.org/proper/commons-cli/download_cli.cgi).
+
+Alternatively, you can pull it from the central Maven repositories:
+
+```xml
+
arguments String array.
- */
- protected String[] flatten(Options options, String[] arguments, boolean stopAtNonOption)
- {
- init();
- this.options = options;
-
- // an iterator for the command line tokens
- Iterator iter = Arrays.asList(arguments).iterator();
-
- // process each command line token
- while (iter.hasNext())
- {
- // get the next command line token
- String token = (String) iter.next();
-
- // handle long option --foo or --foo=bar
- if (token.startsWith("--"))
- {
- int pos = token.indexOf('=');
- String opt = pos == -1 ? token : token.substring(0, pos); // --foo
-
- if (!options.hasOption(opt))
- {
- processNonOptionToken(token, stopAtNonOption);
- }
- else
- {
- currentOption = options.getOption(opt);
-
- tokens.add(opt);
- if (pos != -1)
- {
- tokens.add(token.substring(pos + 1));
- }
- }
- }
-
- // single hyphen
- else if ("-".equals(token))
- {
- tokens.add(token);
- }
- else if (token.startsWith("-"))
- {
- if (token.length() == 2 || options.hasOption(token))
- {
- processOptionToken(token, stopAtNonOption);
- }
- // requires bursting
- else
- {
- burstToken(token, stopAtNonOption);
- }
- }
- else
- {
- processNonOptionToken(token, stopAtNonOption);
- }
-
- gobble(iter);
- }
-
- return (String[]) tokens.toArray(new String[tokens.size()]);
- }
-
- /**
- * Adds the remaining tokens to the processed tokens list.
- *
- * @param iter An iterator over the remaining tokens
- */
- private void gobble(Iterator iter)
- {
- if (eatTheRest)
- {
- while (iter.hasNext())
- {
- tokens.add(iter.next());
- }
- }
- }
-
- /**
- * Add the special token "--" and the current value
- * to the processed tokens list. Then add all the remaining
- * argument values to the processed tokens list.
- *
- * @param value The current token
- */
- private void processNonOptionToken(String value, boolean stopAtNonOption)
- {
- if (stopAtNonOption && (currentOption == null || !currentOption.hasArg()))
- {
- eatTheRest = true;
- tokens.add("--");
- }
-
- tokens.add(value);
- }
-
- /**
- * If an {@link Option} exists for token then
- * add the token to the processed list.
If an {@link Option} does not exist and stopAtNonOption
- * is set then add the remaining tokens to the processed tokens list
- * directly.
token into its constituent parts
- * using the following algorithm.
- *
- * stopAtNonOption IS set then add the special token
- * "--" followed by the remaining characters and also
- * the remaining tokens directly to the processed tokens list.stopAtNonOption IS NOT set then add that
- * character prepended with "-".Object of type obj
- * with the value of str.
- *
- * @param str the command line value
- * @param obj the type of argument
- * @return The instance of obj initialised with
- * the value of str.
- */
- public static Object createValue(String str, Object obj)
- throws ParseException
- {
- return createValue(str, (Class) obj);
- }
-
- /**
- * Returns the Object of type clazz
- * with the value of str.
- *
- * @param str the command line value
- * @param clazz the type of argument
- * @return The instance of clazz initialised with
- * the value of str.
- */
- public static Object createValue(String str, Class clazz)
- throws ParseException
- {
- if (PatternOptionBuilder.STRING_VALUE == clazz)
- {
- return str;
- }
- else if (PatternOptionBuilder.OBJECT_VALUE == clazz)
- {
- return createObject(str);
- }
- else if (PatternOptionBuilder.NUMBER_VALUE == clazz)
- {
- return createNumber(str);
- }
- else if (PatternOptionBuilder.DATE_VALUE == clazz)
- {
- return createDate(str);
- }
- else if (PatternOptionBuilder.CLASS_VALUE == clazz)
- {
- return createClass(str);
- }
- else if (PatternOptionBuilder.FILE_VALUE == clazz)
- {
- return createFile(str);
- }
- else if (PatternOptionBuilder.EXISTING_FILE_VALUE == clazz)
- {
- return createFile(str);
- }
- else if (PatternOptionBuilder.FILES_VALUE == clazz)
- {
- return createFiles(str);
- }
- else if (PatternOptionBuilder.URL_VALUE == clazz)
- {
- return createURL(str);
- }
- else
- {
- return null;
- }
- }
-
- /**
- * Create an Object from the classname and empty constructor.
- *
- * @param classname the argument value
- * @return the initialised object, or null if it couldn't create
- * the Object.
- */
- public static Object createObject(String classname)
- throws ParseException
- {
- Class cl = null;
-
- try
- {
- cl = Class.forName(classname);
- }
- catch (ClassNotFoundException cnfe)
- {
- throw new ParseException("Unable to find the class: " + classname);
- }
-
- Object instance = null;
-
- try
- {
- instance = cl.newInstance();
- }
- catch (Exception e)
- {
- throw new ParseException(e.getClass().getName() + "; Unable to create an instance of: " + classname);
- }
-
- return instance;
- }
-
- /**
- * Create a number from a String. If a . is present, it creates a
- * Double, otherwise a Long.
- *
- * @param str the value
- * @return the number represented by str, if str
- * is not a number, null is returned.
- */
- public static Number createNumber(String str)
- throws ParseException
- {
- try
- {
- if (str.indexOf('.') != -1)
- {
- return Double.valueOf(str);
- }
- else
- {
- return Long.valueOf(str);
- }
- }
- catch (NumberFormatException e)
- {
- throw new ParseException(e.getMessage());
- }
- }
-
- /**
- * Returns the class whose name is classname.
- *
- * @param classname the class name
- * @return The class if it is found, otherwise return null
- */
- public static Class createClass(String classname)
- throws ParseException
- {
- try
- {
- return Class.forName(classname);
- }
- catch (ClassNotFoundException e)
- {
- throw new ParseException("Unable to find the class: " + classname);
- }
- }
-
- /**
- * Returns the date represented by str.
- *
- * @param str the date string
- * @return The date if str is a valid date string,
- * otherwise return null.
- */
- public static Date createDate(String str)
- throws ParseException
- {
- throw new UnsupportedOperationException("Not yet implemented");
- }
-
- /**
- * Returns the URL represented by str.
- *
- * @param str the URL string
- * @return The URL is str is well-formed, otherwise
- * return null.
- */
- public static URL createURL(String str)
- throws ParseException
- {
- try
- {
- return new URL(str);
- }
- catch (MalformedURLException e)
- {
- throw new ParseException("Unable to parse the URL: " + str);
- }
- }
-
- /**
- * Returns the File represented by str.
- *
- * @param str the File location
- * @return The file represented by str.
- */
- public static File createFile(String str)
- throws ParseException
- {
- return new File(str);
- }
-
- /**
- * Returns the File[] represented by str.
- *
- * @param str the paths to the files
- * @return The File[] represented by str.
- */
- public static File[] createFiles(String str)
- throws ParseException
- {
- // to implement/port:
- // return FileW.findFiles(str);
- throw new UnsupportedOperationException("Not yet implemented");
- }
-}
diff --git a/src/java/org/apache/commons/cli/UnrecognizedOptionException.java b/src/java/org/apache/commons/cli/UnrecognizedOptionException.java
deleted file mode 100644
index bf08eb498..000000000
--- a/src/java/org/apache/commons/cli/UnrecognizedOptionException.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/**
- * 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.commons.cli;
-
-/**
- * Exception thrown during parsing signalling an unrecognized
- * option was seen.
- *
- * @author bob mcwhiter (bob @ werken.com)
- * @version $Revision$, $Date$
- */
-public class UnrecognizedOptionException extends ParseException
-{
- /** The unrecognized option */
- private String option;
-
- /**
- * Construct a new UnrecognizedArgumentException
- * with the specified detail message.
- *
- * @param message the detail message
- */
- public UnrecognizedOptionException(String message)
- {
- super(message);
- }
-
- /**
- * Construct a new UnrecognizedArgumentException
- * with the specified option and detail message.
- *
- * @param message the detail message
- * @param option the unrecognized option
- * @since 1.2
- */
- public UnrecognizedOptionException(String message, String option)
- {
- this(message);
- this.option = option;
- }
-
- /**
- * Returns the unrecognized option.
- *
- * @return the related option
- * @since 1.2
- */
- public String getOption()
- {
- return option;
- }
-}
diff --git a/src/java/org/apache/commons/cli/Util.java b/src/java/org/apache/commons/cli/Util.java
deleted file mode 100644
index c147b9555..000000000
--- a/src/java/org/apache/commons/cli/Util.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/**
- * 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.commons.cli;
-
-/**
- * Contains useful helper methods for classes within this package.
- *
- * @author John Keyes (john at integralsource.com)
- * @version $Revision$, $Date$
- */
-class Util
-{
- /**
- * Remove the hyphens from the begining of str and
- * return the new String.
- *
- * @param str The string from which the hyphens should be removed.
- *
- * @return the new String.
- */
- static String stripLeadingHyphens(String str)
- {
- if (str == null)
- {
- return null;
- }
- if (str.startsWith("--"))
- {
- return str.substring(2, str.length());
- }
- else if (str.startsWith("-"))
- {
- return str.substring(1, str.length());
- }
-
- return str;
- }
-
- /**
- * Remove the leading and trailing quotes from str.
- * E.g. if str is '"one two"', then 'one two' is returned.
- *
- * @param str The string from which the leading and trailing quotes
- * should be removed.
- *
- * @return The string without the leading and trailing quotes.
- */
- static String stripLeadingAndTrailingQuotes(String str)
- {
- if (str.startsWith("\""))
- {
- str = str.substring(1, str.length());
- }
- if (str.endsWith("\""))
- {
- str = str.substring(0, str.length() - 1);
- }
- return str;
- }
-}
diff --git a/src/java/org/apache/commons/cli/overview.html b/src/java/org/apache/commons/cli/overview.html
deleted file mode 100644
index eec9ce72c..000000000
--- a/src/java/org/apache/commons/cli/overview.html
+++ /dev/null
@@ -1,43 +0,0 @@
-
-
-
- Commons CLI -- version 1.2
- -The commons-cli package aides in parsing command-line arguments.
- -Allow command-line arguments to be parsed against a descriptor of - valid options (long and short), potentially with arguments.
- -command-line arguments may be of the typical String[]
- form, but also may be a java.util.List. Indexes allow
- for parsing only a portion of the command-line. Also, functionality
- for parsing the command-line in phases is built in, allowing for
- 'cvs-style' command-lines, where some global options are specified
- before a 'command' argument, and command-specific options are
- specified after the command argument:
-
-
-
-
-
-
- myApp -p <port> command -p <printer>
-
-
The homepage for the project is - Apache Commons/ - diff --git a/src/java/org/apache/commons/cli/package.html b/src/java/org/apache/commons/cli/package.html deleted file mode 100644 index 20ebdde95..000000000 --- a/src/java/org/apache/commons/cli/package.html +++ /dev/null @@ -1,21 +0,0 @@ - -
- - Commons CLI 1.2 - - diff --git a/src/main/java/org/apache/commons/cli/AlreadySelectedException.java b/src/main/java/org/apache/commons/cli/AlreadySelectedException.java new file mode 100644 index 000000000..7603eac5e --- /dev/null +++ b/src/main/java/org/apache/commons/cli/AlreadySelectedException.java @@ -0,0 +1,82 @@ +/* + 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 + + https://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.commons.cli; + +/** + * Thrown when more than one option in an option group has been provided. + */ +public class AlreadySelectedException extends ParseException { + + /** + * This exception {@code serialVersionUID}. + */ + private static final long serialVersionUID = 3674381532418544760L; + + /** The option group selected. */ + private final OptionGroup optionGroup; + + /** The option that triggered the exception. */ + private final Option option; + + /** + * Constructs a new {@code AlreadySelectedException} for the specified option group. + * + * @param optionGroup the option group already selected. + * @param option the option that triggered the exception. + * @since 1.2 + */ + public AlreadySelectedException(final OptionGroup optionGroup, final Option option) { + this(String.format("The option '%s' was specified but an option from this group has already been selected: '%s'", option.getKey(), + optionGroup.getSelected()), optionGroup, option); + } + + /** + * Constructs a new {@code AlreadySelectedException} with the specified detail message. + * + * @param message the detail message. + */ + public AlreadySelectedException(final String message) { + this(message, null, null); + } + + private AlreadySelectedException(final String message, final OptionGroup optionGroup, final Option option) { + super(message); + this.optionGroup = optionGroup; + this.option = option; + } + + /** + * Gets the option that was added to the group and triggered the exception. + * + * @return the related option. + * @since 1.2 + */ + public Option getOption() { + return option; + } + + /** + * Gets the option group where another option has been selected. + * + * @return the related option group. + * @since 1.2 + */ + public OptionGroup getOptionGroup() { + return optionGroup; + } +} diff --git a/src/main/java/org/apache/commons/cli/AmbiguousOptionException.java b/src/main/java/org/apache/commons/cli/AmbiguousOptionException.java new file mode 100644 index 000000000..86cefd19a --- /dev/null +++ b/src/main/java/org/apache/commons/cli/AmbiguousOptionException.java @@ -0,0 +1,81 @@ +/* + 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 + + https://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.commons.cli; + +import java.util.Collection; +import java.util.Iterator; + +/** + * Exception thrown when an option can't be identified from a partial name. + * + * @since 1.3 + */ +public class AmbiguousOptionException extends UnrecognizedOptionException { + + /** + * This exception {@code serialVersionUID}. + */ + private static final long serialVersionUID = 5829816121277947229L; + + /** + * Build the exception message from the specified list of options. + * + * @param option + * @param matchingOptions + * @return + */ + private static String createMessage(final String option, final Collection+ * A simple implementation of {@link Parser}'s abstract {@link Parser#flatten(Options, String[], boolean) flatten} + * method. + *
+ * + *+ * Note: {@code options} and {@code stopAtNonOption} are not used in this {@code flatten} method. + *
+ * + * @param options The command line {@link Options}. + * @param arguments The command line arguments to be parsed. + * @param stopAtNonOption Specifies whether to stop flattening when an non option is found. + * @return The {@code arguments} String array. + */ + @Override + protected String[] flatten(@SuppressWarnings("unused") final Options options, final String[] arguments, + @SuppressWarnings("unused") final boolean stopAtNonOption) { + // just echo the arguments + return arguments; + } +} diff --git a/src/main/java/org/apache/commons/cli/Char.java b/src/main/java/org/apache/commons/cli/Char.java new file mode 100644 index 000000000..9b6e5e2ab --- /dev/null +++ b/src/main/java/org/apache/commons/cli/Char.java @@ -0,0 +1,46 @@ +/* + 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 + + https://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.commons.cli; + +/** + * Package-private character constants. + */ +final class Char { + + /** Apostrophe */ + static final char APOS = '\''; + + /** Carriage return. */ + static final char CR = '\r'; + + /** Equal sign. */ + static final char EQUAL = '='; + + /** Line feed. */ + static final char LF = '\n'; + + /** Space. */ + static final char SP = ' '; + + /** Tab. */ + static final char TAB = '\t'; + + private Char() { + // empty + } +} diff --git a/src/main/java/org/apache/commons/cli/CommandLine.java b/src/main/java/org/apache/commons/cli/CommandLine.java new file mode 100644 index 000000000..d0ca1fc5a --- /dev/null +++ b/src/main/java/org/apache/commons/cli/CommandLine.java @@ -0,0 +1,1044 @@ +/* + 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 + + https://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.commons.cli; + +import java.io.Serializable; +import java.lang.reflect.Array; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.Objects; +import java.util.Properties; +import java.util.function.Consumer; +import java.util.function.Supplier; + +/** + * Represents list of arguments parsed against a {@link Options} descriptor. + *+ * It allows querying of a boolean {@link #hasOption(String optionName)}, in addition to retrieving the + * {@link #getOptionValue(String optionName)} for options requiring arguments. + *
+ *+ * Additionally, any left-over or unrecognized arguments, are available for further processing. + *
+ */ +public class CommandLine implements Serializable { + + /** + * A nested builder class to create {@code CommandLine} instance using descriptive methods. + * + * @since 1.4 + */ + public static final class Builder implements Supplier