Replace positional CLI path with a repeatable -path flag

This commit is contained in:
lilleman
2026-06-09 00:47:01 +02:00
parent 862c5f8a23
commit 889b1fbf8b
3 changed files with 96 additions and 51 deletions
+33 -20
View File
@@ -1,10 +1,11 @@
// Command fakes prints one fake value from one or more data directories.
// Command fakes prints fake values from one or more data directories.
//
// fakes ./data/sv_SE person # a full person
// fakes ./data/sv_SE person.last # just the surname (dotted path)
// fakes ./data sv_SE.person # point at the tree, address by folder
// fakes ./data/sv_SE ./mydata person # layer custom data; last dir wins
// fakes -seed 42 ./data/sv_SE address
// fakes -path person ./data/sv_SE # a full person
// fakes -path person.last ./data/sv_SE # just the surname (dotted path)
// fakes -path sv_SE.person ./data # point at the tree, address by folder
// fakes -path person -path address ./data/sv_SE # several paths, one per line
// fakes -path person ./data/sv_SE ./mydata # layer custom data; last dir wins
// fakes -seed 42 -path address ./data/sv_SE
//
// It is a thin CLI over the fakes library: New(dirs) then Fake(path).
package main
@@ -19,13 +20,20 @@ import (
"github.com/Timewave-AB/fakes"
)
const usage = `Usage: fakes [-seed N] [-repeat N] [-separator S] <data-dir>... <path>
const usage = `Usage: fakes -path P [-path P]... [-seed N] [-repeat N] [-separator S] <data-dir>...
-path P a category, or a dotted path into one (person, person.last); repeatable
<data-dir> one or more data directories, e.g. ./data/sv_SE (last wins on clash)
<path> a category, or a dotted path into one (person, person.last)
-seed N seed for reproducible output
-repeat N render the path N times (default 1)
-separator S string between repeated values (default newline)`
-repeat N render each path N times (default 1)
-separator S string between emitted values (default newline)`
// stringList collects a repeatable string flag, preserving order.
type stringList []string
func (s *stringList) String() string { return strings.Join(*s, ",") }
func (s *stringList) Set(v string) error { *s = append(*s, v); return nil }
func main() { os.Exit(run(os.Args[1:], os.Stdout, os.Stderr)) }
@@ -36,12 +44,14 @@ func run(args []string, stdout, stderr io.Writer) int {
fs.SetOutput(stderr)
fs.Usage = func() { fmt.Fprintln(stderr, usage) }
seed := fs.Uint64("seed", 0, "seed for reproducible output")
repeat := fs.Int("repeat", 1, "render the path this many times")
sep := fs.String("separator", "\n", "string between repeated values")
repeat := fs.Int("repeat", 1, "render each path this many times")
sep := fs.String("separator", "\n", "string between emitted values")
var paths stringList
fs.Var(&paths, "path", "a category or dotted path to render (repeatable)")
if err := fs.Parse(args); err != nil {
return 2
}
if fs.NArg() < 2 {
if len(paths) == 0 || fs.NArg() < 1 {
fs.Usage()
return 2
}
@@ -57,17 +67,20 @@ func run(args []string, stdout, stderr io.Writer) int {
}
})
dirs, path := fs.Args()[:fs.NArg()-1], fs.Arg(fs.NArg()-1)
f, err := fakes.New(dirs, opts...)
f, err := fakes.New(fs.Args(), opts...)
if err != nil {
fmt.Fprintln(stderr, err)
return 1
}
vals := make([]string, *repeat)
for i := range vals {
if vals[i], err = f.Fake(path); err != nil {
fmt.Fprintln(stderr, err)
return 1
vals := make([]string, 0, *repeat*len(paths))
for range *repeat {
for _, p := range paths {
v, err := f.Fake(p)
if err != nil {
fmt.Fprintln(stderr, err)
return 1
}
vals = append(vals, v)
}
}
fmt.Fprintln(stdout, strings.Join(vals, *sep))