commit dba92d5ad3f0a327a0859aa9761b55ca6c7ec4f2
parent 3b4821d79893d224c913cde00ad30af47ed11431
Author: Jack Mordaunt <jackmordaunt.dev@gmail.com>
Date: Wed, 16 Sep 2026 21:44:44 -0400
cmd/icnsify: use the standard flag package
pflag is small, but once the CLI shares the library's module every dependency
appears in library consumers' module graphs. The standard package already
accepts both -input and --input, and registering a short alias per option
preserves the existing -i, -o and -r spellings.
Diffstat:
3 files changed, 54 insertions(+), 33 deletions(-)
diff --git a/cmd/icnsify/doc.go b/cmd/icnsify/doc.go
@@ -1,21 +1,52 @@
package main
import (
+ "flag"
"fmt"
-
- "github.com/spf13/pflag"
+ "strconv"
)
+// version is stamped by goreleaser at build time.
var version = "master"
-func usage() {
- fmt.Printf("\n")
- pflag.Usage()
- fmt.Printf(`
-You can also pipe to stdin and from stdout.
-The pipes will be detected automatically, and both --input and --output will be ignored.
+// option records a flag registered under a long and a short name so usage
+// can list each one once, GNU style, instead of twice as PrintDefaults would.
+type option struct {
+ long, short string
+ def, usage string
+}
- cat icon.png | icnsify > icon.icns
+var options []option
+
+// stringFlag registers a string option reachable as --long or -short.
+func stringFlag(p *string, long, short, def, usage string) {
+ flag.StringVar(p, long, def, usage)
+ flag.StringVar(p, short, def, usage)
+ options = append(options, option{long: long, short: short, def: def, usage: usage})
+}
+
+// intFlag registers an integer option reachable as --long or -short.
+func intFlag(p *int, long, short string, def int, usage string) {
+ flag.IntVar(p, long, def, usage)
+ flag.IntVar(p, short, def, usage)
+ options = append(options, option{long: long, short: short, def: strconv.Itoa(def), usage: usage})
+}
+
+func usage() {
+ w := flag.CommandLine.Output()
+ fmt.Fprintf(w, "icnsify %s\n\nUsage: icnsify [-i input] [-o output] [-r quality]\n\nOptions:\n", version)
+ for _, o := range options {
+ fmt.Fprintf(w, " -%s, --%s\n %s", o.short, o.long, o.usage)
+ if o.def != "" && o.def != "0" {
+ fmt.Fprintf(w, " (default %s)", o.def)
+ }
+ fmt.Fprintln(w)
+ }
+ fmt.Fprint(w, `
+You can also pipe to stdin and from stdout. Pipes are detected automatically
+when --input is not given, and --output is then ignored.
+ cat icon.png | icnsify > icon.icns
+ cat icon.icns | icnsify > icon.png
`)
}
diff --git a/cmd/icnsify/go.mod b/cmd/icnsify/go.mod
@@ -4,7 +4,6 @@ go 1.21.5
require (
github.com/jackmordaunt/icns/v4 v4.0.0
- github.com/spf13/pflag v1.0.5
)
require (
diff --git a/cmd/icnsify/main.go b/cmd/icnsify/main.go
@@ -3,6 +3,7 @@ package main
import (
"bytes"
"errors"
+ "flag"
"fmt"
"image"
"image/jpeg"
@@ -14,8 +15,6 @@ import (
"strings"
"github.com/jackmordaunt/icns/v4"
-
- "github.com/spf13/pflag"
)
// errUsage signals that no work was requested; usage has been printed.
@@ -32,26 +31,18 @@ func main() {
func run() error {
var (
- inputPath = pflag.StringP(
- "input",
- "i",
- "",
- "Input image for conversion to icns from jpg|png or visa versa.",
- )
- outputPath = pflag.StringP(
- "output",
- "o",
- "",
- "Output path, defaults to <path/to/image>.(icns|png) depending on input.",
- )
- resize = pflag.IntP(
- "resize",
- "r",
- 5,
- "Quality of resize algorithm. Values range from 0 to 5, fastest to slowest execution time. Defaults to slowest for best quality.",
- )
+ inputPath string
+ outputPath string
+ resize int
)
- pflag.Parse()
+ stringFlag(&inputPath, "input", "i", "",
+ "Input image for conversion to icns from jpg|png or vice versa.")
+ stringFlag(&outputPath, "output", "o", "",
+ "Output path, defaults to <path/to/image>.(icns|png) depending on input.")
+ intFlag(&resize, "resize", "r", 5,
+ "Quality of resize algorithm, 0 to 5 from fastest to slowest.")
+ flag.Usage = usage
+ flag.Parse()
var (
input io.Reader
@@ -60,13 +51,13 @@ func run() error {
// An explicit --input wins; otherwise a non-terminal stdin means we are
// part of a pipeline and both paths are ignored.
piping := false
- if *inputPath == "" {
+ if inputPath == "" {
var err error
if piping, err = stdinIsPipe(); err != nil {
return err
}
}
- in, out, algorithm := sanitiseInputs(*inputPath, *outputPath, *resize)
+ in, out, algorithm := sanitiseInputs(inputPath, outputPath, resize)
if piping {
input, output = os.Stdin, os.Stdout
} else {