No description
  • Go 96.6%
  • Shell 2.3%
  • Makefile 1.1%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
Mark Ferrell e778e75f9c feat(pflag): add NoOptDefVal, ErrHelp, and ParseErrorsWhitelist field for cobra compatibility
Add three missing API surface items that cobra depends on:

- Flag.NoOptDefVal: default value used when a flag appears on the
  command line without an explicit value (e.g. --flag without =value).
- ErrHelp: sentinel error returned when -help is invoked, matching
  the upstream pflag and stdlib flag convention.
- FlagSet.ParseErrorsWhitelist: deprecated field mirroring
  ParseErrorsAllowlist, needed because cobra accesses it by field
  name. The parser now checks both fields.
2026-04-10 16:11:41 -07:00
.github refactor(pflag): rename pflags module to pflag 2026-04-10 13:58:34 -07:00
docs refactor(pflag): rename pflags module to pflag 2026-04-10 13:58:34 -07:00
example refactor(pflag): rename pflags module to pflag 2026-04-10 13:58:34 -07:00
goarg fix: bump goarg and pflag to latest optarg version 2026-04-10 16:02:49 -07:00
pflag feat(pflag): add NoOptDefVal, ErrHelp, and ParseErrorsWhitelist field for cobra compatibility 2026-04-10 16:11:41 -07:00
posix feat(goarg): add LongOnly and CaseSensitiveCommands config fields 2026-04-04 17:13:26 -07:00
scripts test: rationalize property tests and align coverage validation 2026-03-03 05:19:29 -08:00
.coveragerc fix(ci): resolve Go 1.23 compatibility issues in pre-commit workflow 2026-02-20 06:16:50 -08:00
.editorconfig Initial commit 2025-02-07 08:15:12 -08:00
.gitignore feat(specs): add comprehensive module dependencies and testing infrastructure 2026-02-20 06:14:21 -08:00
.golangci.yml fix: resolve all golangci-lint issues in core module 2026-04-02 15:16:31 -07:00
.markdownlint-cli2.yaml chore: update pre-commit config for all file types 2026-02-28 12:07:56 -08:00
.pre-commit-config.yaml fix: apply golangci-lint auto-fixes and replace go-fmt with goimports 2026-04-02 07:43:16 -07:00
.secrets.baseline chore(build): add comprehensive static checking to precommit hooks 2026-02-20 06:12:50 -08:00
abbreviation_property_test.go test: add 12 property-based tests for abbreviation matching 2026-04-05 06:59:55 -07:00
benchmark_test.go fix: apply golangci-lint auto-fixes and replace go-fmt with goimports 2026-04-02 07:43:16 -07:00
bytes_property_test.go test(optargs): add property tests for bytesHex and bytesBase64 2026-04-10 14:32:24 -07:00
command.go fix: apply golangci-lint auto-fixes and replace go-fmt with goimports 2026-04-02 07:43:16 -07:00
command_test.go style: fix mechanical lint issues in core module 2026-04-02 08:20:24 -07:00
CONTRIBUTING.md docs: rewrite README, CONTRIBUTING, COVERAGE; add example/ and posix/ Go programs 2026-02-28 10:28:33 -08:00
convert.go feat: add GNU-style abbreviation matching to findLongOpt 2026-04-05 06:49:34 -07:00
convert_test.go fix: apply golangci-lint auto-fixes and replace go-fmt with goimports 2026-04-02 07:43:16 -07:00
COVERAGE.md docs: rewrite README, CONTRIBUTING, COVERAGE; add example/ and posix/ Go programs 2026-02-28 10:28:33 -08:00
errors.go refactor: introduce typed errors in core parser 2026-04-04 07:23:53 -07:00
errors_test.go refactor: introduce typed errors in core parser 2026-04-04 07:23:53 -07:00
getopt.go style: apply goimports formatting fixes 2026-04-03 05:32:49 -07:00
getopt_test.go fix: resolve all golangci-lint issues in core module 2026-04-02 15:16:31 -07:00
go.mod Initial commit 2025-02-07 08:15:12 -08:00
handler_test.go chore: fix lint issues across all modules 2026-04-04 18:29:30 -07:00
helpers_test.go chore(goarg): add testing infrastructure and fix lint issues 2026-03-27 13:52:15 -07:00
LICENSE fix(ci): resolve Go 1.23 compatibility issues in pre-commit workflow 2026-02-20 06:16:50 -08:00
Makefile test: rationalize property tests and align coverage validation 2026-03-03 05:19:29 -08:00
misc.go perf(parser): eliminate hot-path overhead in option parsing 2026-03-27 17:40:13 -07:00
misc_test.go style: fix mechanical lint issues in core module 2026-04-02 08:20:24 -07:00
NOTES.md feat(parser): add strict subcommands mode 2026-03-27 15:30:27 -07:00
optargs_test.go test(optargs): inline single-use variables in TestMain 2026-03-01 10:15:31 -08:00
parser.go feat: add GNU-style abbreviation matching to findLongOpt 2026-04-05 06:49:34 -07:00
parser_test.go feat: add GNU-style abbreviation matching to findLongOpt 2026-04-05 06:49:34 -07:00
README.md refactor(pflag): rename pflags module to pflag 2026-04-10 13:58:34 -07:00
round_trip_test.go chore(goarg): add testing infrastructure and fix lint issues 2026-03-27 13:52:15 -07:00
slice_value_property_test.go test(optargs): add property tests for SliceValue Append/Replace/GetSlice 2026-04-10 14:55:01 -07:00
strict_subcommands_test.go feat(parser): add strict subcommands mode 2026-03-27 15:30:27 -07:00
typed_integration_test.go refactor(core): deduplicate typed values with generics, remove redundant tests 2026-03-30 10:28:51 -07:00
typed_maps.go fix: resolve all golangci-lint issues in core module 2026-04-02 15:16:31 -07:00
typed_maps_test.go refactor(core): deduplicate typed values with generics, remove redundant tests 2026-03-30 10:28:51 -07:00
typed_property_test.go fix: apply golangci-lint auto-fixes and replace go-fmt with goimports 2026-04-02 07:43:16 -07:00
typed_scalars.go feat(optargs): add bytesHex and bytesBase64 value types 2026-04-10 14:32:12 -07:00
typed_scalars_test.go refactor(core): deduplicate typed values with generics, remove redundant tests 2026-03-30 10:28:51 -07:00
typed_slices.go feat(optargs): add SliceValue interface and Append/Replace/GetSlice methods 2026-04-10 14:47:39 -07:00
typed_slices_test.go refactor(core): deduplicate typed values with generics, remove redundant tests 2026-03-30 10:28:51 -07:00
typed_special.go fix: resolve all golangci-lint issues in core module 2026-04-02 15:16:31 -07:00
typed_special_test.go fix: apply golangci-lint auto-fixes and replace go-fmt with goimports 2026-04-02 07:43:16 -07:00
typed_values.go feat(optargs): add bytesHex and bytesBase64 value types 2026-04-10 14:32:12 -07:00
typed_values_test.go fix: apply golangci-lint auto-fixes and replace go-fmt with goimports 2026-04-02 07:43:16 -07:00

OptArgs

Build Coverage Go Reference License: MIT

A Go implementation of POSIX getopt(3), GNU getopt_long(3), and getopt_long_only(3) with native subcommand support.

OptArgs Core is the foundation for API-compatible wrapper modules that serve as drop-in replacements for popular Go argument parsing libraries.

Design

OptArgs is a general-purpose, unopinionated parser that faithfully implements GNU/POSIX getopt(3), getopt_long(3), and getopt_long_only(3) behavior. It exposes the full API surface needed to construct opinionated parsers on top — goarg and pflag are two such compatibility layers, each matching the API conventions of their upstream counterparts while gaining the correctness and features of the core engine.

Features

  • Full POSIX getopt(3) compliance: short options, compaction, -- termination, POSIXLY_CORRECT
  • GNU getopt_long(3): --option=value, --option value, abbreviation matching, case-insensitive
  • GNU getopt_long_only(3): single-dash long options with short option fallback
  • Advanced handling: -W extension, option redefinition, negative arguments
  • Native subcommand dispatch via AddCmd() with option inheritance through the parent chain
  • Iterator-based processing (Options() returns iter.Seq2[Option, error])
  • Verbose and silent error modes, both working through subcommand chains
  • Zero dependencies

Compatibility Modules

Module Upstream Description
goarg alexflint/go-arg API-compatible drop-in replacement using struct tags
pflag spf13/pflag API-compatible drop-in replacement using flag methods

Install

go get github.com/major0/optargs

Requires Go 1.23+.

Usage

GetOpt (POSIX short options)

package main

import (
    "fmt"
    "github.com/major0/optargs"
)

func main() {
    p, _ := optargs.GetOpt(os.Args[1:], "vf:o::")
    for opt, err := range p.Options() {
        if err != nil {
            fmt.Fprintf(os.Stderr, "%v\n", err)
            continue
        }
        switch opt.Name {
        case "v":
            fmt.Println("verbose")
        case "f":
            fmt.Println("file:", opt.Arg)
        case "o":
            fmt.Println("output:", opt.Arg)
        }
    }
}

GetOptLong (GNU long options)

p, _ := optargs.GetOptLong(os.Args[1:], "vf:", []optargs.Flag{
    {Name: "verbose", HasArg: optargs.NoArgument},
    {Name: "file",    HasArg: optargs.RequiredArgument},
    {Name: "output",  HasArg: optargs.OptionalArgument},
})
for opt, err := range p.Options() {
    // ...
}

GetOptLongOnly (single-dash long options)

p, _ := optargs.GetOptLongOnly(os.Args[1:], "vf:", []optargs.Flag{
    {Name: "verbose", HasArg: optargs.NoArgument},
    {Name: "file",    HasArg: optargs.RequiredArgument},
})
// -verbose tries long match first, falls back to short options via optstring

Subcommands

root, _ := optargs.GetOptLong(os.Args[1:], "v", []optargs.Flag{
    {Name: "verbose", HasArg: optargs.NoArgument},
})

serve, _ := optargs.GetOptLong([]string{}, "p:", []optargs.Flag{
    {Name: "port", HasArg: optargs.RequiredArgument},
})
root.AddCmd("serve", serve)

// Root iteration dispatches to child when "serve" is encountered.
// Child inherits parent options via parent-chain walk.
for opt, err := range root.Options() { /* root options */ }
for opt, err := range serve.Options() { /* serve options + inherited */ }

Strict Subcommands

By default, child parsers inherit parent options — unknown options in a subcommand are resolved by walking the parent chain. To disable this (POSIX-strict behavior where each command owns its own options):

root.SetStrictSubcommands(true)
root.AddCmd("serve", serve) // serve will NOT inherit root's options

This is automatically enabled when POSIXLY_CORRECT is set or when the optstring starts with +.

Optstring Syntax

Prefix Behavior
: Silent error mode — suppress error logging
+ POSIXLY_CORRECT — stop at first non-option
- Treat non-options as argument to option \x01
Suffix Meaning
f No argument
f: Required argument
f:: Optional argument
W; GNU -W word extension

Examples

  • example/ — vanilla GetOpt, GetOptLong, GetOptLongOnly usage
  • posix/ — obscure POSIX/GNU patterns: subcommand dispatch, silent error mode, POSIXLY_CORRECT

Contributing

See CONTRIBUTING.md.

License

MIT