While building a simple QR code generator CLI in Go, I ran into something interesting with the standard flag package.
Consider executing a simple binary in your terminal:
./myBinary -p itemThis works as expected.
But:
./myBinary item -pThe -p flag won't be parsed because Go's flag package stops parsing flags once it encounters a positional argument.
I first encountered this behavior while working on that task tracker tool. I wrote a function to brute-force my way around it, but never took the time to understand why it happened.
This time, I did some research and learned that Go's built-in flag parser follows POSIX-style conventions. In simple terms, it expects flags to appear before positional arguments.
Now I understand why it works that way, but I wanted my CLI to behave more like the tools I regularly use.
I mean, both of these work with Git:
git push -f origin main
git push origin main -fSo I built go-os-input-parser.
It's a small, zero-dependency package that separates command-line inputs from flags regardless of where they appear.
For example:
./myBinary item1 -p item2 --config=default.jsonThe parser can give you:
Inputs: [item1 item2]
Print: true
Config: default.jsonYou define the flags you want to support, including either or both their short and long forms, and also pass in os.Args[1:]:
inputs := parser.ParseInput(
os.Args[1:],
[]parser.AllowedBoolTag{
{
Short: "p",
Long: "print",
Container: &print,
},
},
[]parser.AllowedStringTag{
{
Short: "c",
Long: "config",
Container: &config,
},
},
)I know there are larger Go CLI libraries like pflag and Cobra, and this might look like reinventing the wheel. But after running into this problem for the second time, I decided to use it as a fun excuse to practice more Go.
I also used this project to improve my testing and documentation. I had an AI agent review the code, point out flaws I had missed, and help me write better unit tests and documentation.
In the end, it's a small project, but a useful go exercise
Here's the github repo: https://github.com/orashus/go-os-input-parser