docs, config and tools testing
This commit is contained in:
parent
60acf6e820
commit
6e3e3dd5aa
@ -78,17 +78,12 @@ func unescapeConfig(s string) string {
|
|||||||
|
|
||||||
return []rune{r}, false
|
return []rune{r}, false
|
||||||
},
|
},
|
||||||
func(escaped bool) []rune {
|
nil,
|
||||||
if escaped {
|
|
||||||
return []rune{'\\'}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
},
|
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
w.Write([]byte(s))
|
w.Write([]byte(s))
|
||||||
|
w.Flush()
|
||||||
return b.String()
|
return b.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -114,7 +114,7 @@ func TestConfig(t *testing.T) {
|
|||||||
)
|
)
|
||||||
|
|
||||||
t.Run(
|
t.Run(
|
||||||
"discard in previous same doc",
|
"discard in previous and same doc",
|
||||||
testExec(
|
testExec(
|
||||||
testCase{
|
testCase{
|
||||||
impl: fm,
|
impl: fm,
|
||||||
@ -126,12 +126,18 @@ func TestConfig(t *testing.T) {
|
|||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
// check the syntax for tests
|
t.Run(
|
||||||
// - white space ignored
|
"discard multiple values",
|
||||||
// - comment line
|
testExec(
|
||||||
// - comment at the end of an entry
|
testCase{
|
||||||
// - invalid key
|
impl: fm,
|
||||||
// check the code for tests
|
mergeConf: []string{"one=bar\none=baz\nsecond-var=baz", "one\nsecond-var=qux\nsecond-var"},
|
||||||
|
command: "foo",
|
||||||
|
},
|
||||||
|
"",
|
||||||
|
";",
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
t.Run("white space ignored", testExec(testCase{impl: fm, conf: "one = bar ", command: "foo"}, "", "bar;"))
|
t.Run("white space ignored", testExec(testCase{impl: fm, conf: "one = bar ", command: "foo"}, "", "bar;"))
|
||||||
t.Run(
|
t.Run(
|
||||||
@ -148,4 +154,77 @@ func TestConfig(t *testing.T) {
|
|||||||
)
|
)
|
||||||
|
|
||||||
t.Run("invald key", testExec(testCase{impl: fm, conf: "one two = bar", command: "foo"}, "parse failed", ""))
|
t.Run("invald key", testExec(testCase{impl: fm, conf: "one two = bar", command: "foo"}, "parse failed", ""))
|
||||||
|
t.Run(
|
||||||
|
"config file",
|
||||||
|
testExec(
|
||||||
|
testCase{
|
||||||
|
impl: fm,
|
||||||
|
mergeConfTyped: []Config{ConfigFile("./internal/tests/testconfig.ini")},
|
||||||
|
command: "foo",
|
||||||
|
},
|
||||||
|
"",
|
||||||
|
"42;",
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
t.Run(
|
||||||
|
"config file error",
|
||||||
|
testExec(
|
||||||
|
testCase{
|
||||||
|
impl: fm,
|
||||||
|
mergeConfTyped: []Config{ConfigFile("./internal/tests/testconfig-noexist.ini")},
|
||||||
|
command: "foo",
|
||||||
|
},
|
||||||
|
"file",
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
t.Run(
|
||||||
|
"config file error optional",
|
||||||
|
testExec(
|
||||||
|
testCase{
|
||||||
|
impl: fm,
|
||||||
|
mergeConfTyped: []Config{OptionalConfig(ConfigFile("./internal/tests/testconfig-noexist.ini"))},
|
||||||
|
command: "foo",
|
||||||
|
},
|
||||||
|
"",
|
||||||
|
";",
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
t.Run(
|
||||||
|
"config from option",
|
||||||
|
testExec(
|
||||||
|
testCase{
|
||||||
|
impl: fm,
|
||||||
|
mergeConfTyped: []Config{ConfigFromOption()},
|
||||||
|
command: "foo --second-var bar --config ./internal/tests/testconfig.ini",
|
||||||
|
},
|
||||||
|
"",
|
||||||
|
"42;bar",
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
t.Run(
|
||||||
|
"config from option shadowed",
|
||||||
|
testExec(
|
||||||
|
testCase{
|
||||||
|
impl: func(struct{ Config int }) {},
|
||||||
|
mergeConfTyped: []Config{ConfigFromOption()},
|
||||||
|
command: "foo --config ./internal/tests/testconfig.ini",
|
||||||
|
},
|
||||||
|
"option reserved",
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
t.Run(
|
||||||
|
"dangling backslash",
|
||||||
|
testExec(
|
||||||
|
testCase{
|
||||||
|
impl: fm,
|
||||||
|
conf: "one = foo\\",
|
||||||
|
},
|
||||||
|
"parse failed",
|
||||||
|
),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -9,13 +9,13 @@ import "code.squareroundforest.org/arpio/docreflect"
|
|||||||
func init() {
|
func init() {
|
||||||
docreflect.Register("code.squareroundforest.org/arpio/wand/tools", "")
|
docreflect.Register("code.squareroundforest.org/arpio/wand/tools", "")
|
||||||
docreflect.Register("code.squareroundforest.org/arpio/wand/tools.Docreflect", "\nfunc(out, packageName, gopaths)")
|
docreflect.Register("code.squareroundforest.org/arpio/wand/tools.Docreflect", "\nfunc(out, packageName, gopaths)")
|
||||||
docreflect.Register("code.squareroundforest.org/arpio/wand/tools.Exec", "\nfunc(o, stdin, args)")
|
docreflect.Register("code.squareroundforest.org/arpio/wand/tools.Exec", "\nfunc(o, stdin, stdout, args)")
|
||||||
docreflect.Register("code.squareroundforest.org/arpio/wand/tools.ExecOptions", "")
|
docreflect.Register("code.squareroundforest.org/arpio/wand/tools.ExecOptions", "")
|
||||||
docreflect.Register("code.squareroundforest.org/arpio/wand/tools.ExecOptions.CacheDir", "")
|
docreflect.Register("code.squareroundforest.org/arpio/wand/tools.ExecOptions.CacheDir", "")
|
||||||
docreflect.Register("code.squareroundforest.org/arpio/wand/tools.ExecOptions.ClearCache", "")
|
docreflect.Register("code.squareroundforest.org/arpio/wand/tools.ExecOptions.ClearCache", "")
|
||||||
docreflect.Register("code.squareroundforest.org/arpio/wand/tools.ExecOptions.Import", "")
|
docreflect.Register("code.squareroundforest.org/arpio/wand/tools.ExecOptions.Import", "")
|
||||||
docreflect.Register("code.squareroundforest.org/arpio/wand/tools.ExecOptions.InlineImport", "")
|
|
||||||
docreflect.Register("code.squareroundforest.org/arpio/wand/tools.ExecOptions.NoCache", "")
|
docreflect.Register("code.squareroundforest.org/arpio/wand/tools.ExecOptions.NoCache", "")
|
||||||
|
docreflect.Register("code.squareroundforest.org/arpio/wand/tools.ExecOptions.ReplaceModule", "")
|
||||||
docreflect.Register("code.squareroundforest.org/arpio/wand/tools.Man", "\nfunc(out, o, commandDir)")
|
docreflect.Register("code.squareroundforest.org/arpio/wand/tools.Man", "\nfunc(out, o, commandDir)")
|
||||||
docreflect.Register("code.squareroundforest.org/arpio/wand/tools.ManOptions", "")
|
docreflect.Register("code.squareroundforest.org/arpio/wand/tools.ManOptions", "")
|
||||||
docreflect.Register("code.squareroundforest.org/arpio/wand/tools.ManOptions.DateString", "")
|
docreflect.Register("code.squareroundforest.org/arpio/wand/tools.ManOptions.DateString", "")
|
||||||
@ -25,11 +25,12 @@ func init() {
|
|||||||
docreflect.Register("code.squareroundforest.org/arpio/wand/tools.MarkdownOptions.Level", "")
|
docreflect.Register("code.squareroundforest.org/arpio/wand/tools.MarkdownOptions.Level", "")
|
||||||
docreflect.Register("code.squareroundforest.org/arpio/wand/tools.commandReader", "\nfunc(in)")
|
docreflect.Register("code.squareroundforest.org/arpio/wand/tools.commandReader", "\nfunc(in)")
|
||||||
docreflect.Register("code.squareroundforest.org/arpio/wand/tools.execCommandDir", "\nfunc(out, commandDir, env)")
|
docreflect.Register("code.squareroundforest.org/arpio/wand/tools.execCommandDir", "\nfunc(out, commandDir, env)")
|
||||||
|
docreflect.Register("code.squareroundforest.org/arpio/wand/tools.execInput", "\nfunc(o, stdin, stdout, stderr, args)")
|
||||||
docreflect.Register("code.squareroundforest.org/arpio/wand/tools.execInternal", "\nfunc(command, args)")
|
docreflect.Register("code.squareroundforest.org/arpio/wand/tools.execInternal", "\nfunc(command, args)")
|
||||||
docreflect.Register("code.squareroundforest.org/arpio/wand/tools.execTransparent", "\nfunc(command, args)")
|
docreflect.Register("code.squareroundforest.org/arpio/wand/tools.execWand", "\nfunc(o, stdin, stdout, stderr, args)")
|
||||||
docreflect.Register("code.squareroundforest.org/arpio/wand/tools.execWand", "\nfunc(o, args)")
|
|
||||||
docreflect.Register("code.squareroundforest.org/arpio/wand/tools.execc", "\nfunc(stdin, stdout, stderr, command, args, env)")
|
docreflect.Register("code.squareroundforest.org/arpio/wand/tools.execc", "\nfunc(stdin, stdout, stderr, command, args, env)")
|
||||||
docreflect.Register("code.squareroundforest.org/arpio/wand/tools.hash", "\nfunc(expression, imports, inlineImports)")
|
docreflect.Register("code.squareroundforest.org/arpio/wand/tools.hash", "\nfunc(expression, imports)")
|
||||||
docreflect.Register("code.squareroundforest.org/arpio/wand/tools.printGoFile", "\nfunc(fn, expression, imports, inlineImports)")
|
docreflect.Register("code.squareroundforest.org/arpio/wand/tools.printGoFile", "\nfunc(fn, expression, imports)")
|
||||||
docreflect.Register("code.squareroundforest.org/arpio/wand/tools.readExec", "\nfunc(o, stdin)")
|
docreflect.Register("code.squareroundforest.org/arpio/wand/tools.readExec", "\nfunc(o, stdin, stdout, stderr)")
|
||||||
|
docreflect.Register("code.squareroundforest.org/arpio/wand/tools.selfPkg", "")
|
||||||
}
|
}
|
||||||
|
|||||||
@ -18,5 +18,6 @@ func init() {
|
|||||||
docreflect.Register("code.squareroundforest.org/arpio/wand/internal/tests/testlib.Options.Bar", "Bars, any number.\n")
|
docreflect.Register("code.squareroundforest.org/arpio/wand/internal/tests/testlib.Options.Bar", "Bars, any number.\n")
|
||||||
docreflect.Register("code.squareroundforest.org/arpio/wand/internal/tests/testlib.Options.Duration", "Duration is another option.\n")
|
docreflect.Register("code.squareroundforest.org/arpio/wand/internal/tests/testlib.Options.Duration", "Duration is another option.\n")
|
||||||
docreflect.Register("code.squareroundforest.org/arpio/wand/internal/tests/testlib.Options.Foo", "Foo is an option.\n")
|
docreflect.Register("code.squareroundforest.org/arpio/wand/internal/tests/testlib.Options.Foo", "Foo is an option.\n")
|
||||||
|
docreflect.Register("code.squareroundforest.org/arpio/wand/internal/tests/testlib.Options.Some", "Some is an option of any type.\n")
|
||||||
docreflect.Register("code.squareroundforest.org/arpio/wand/internal/tests/testlib.Options.Time", "Time is the third option here.\n")
|
docreflect.Register("code.squareroundforest.org/arpio/wand/internal/tests/testlib.Options.Time", "Time is the third option here.\n")
|
||||||
}
|
}
|
||||||
|
|||||||
8
exec.go
8
exec.go
@ -4,13 +4,17 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"path/filepath"
|
"path"
|
||||||
"strconv"
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
func exec(stdin io.Reader, stdout, stderr io.Writer, exit func(int), cmd Cmd, conf Config, env, args []string) {
|
func exec(stdin io.Reader, stdout, stderr io.Writer, exit func(int), cmd Cmd, conf Config, env, args []string) {
|
||||||
_, cmd.name = filepath.Split(args[0])
|
generate := getenv(env, "_wandgenerate")
|
||||||
|
if cmd.name == "" || generate == "" {
|
||||||
|
_, cmd.name = path.Split(args[0])
|
||||||
|
}
|
||||||
|
|
||||||
if err := validateCommand(cmd, conf); err != nil {
|
if err := validateCommand(cmd, conf); err != nil {
|
||||||
fmt.Fprintf(stderr, "program error: %v\n", err)
|
fmt.Fprintf(stderr, "program error: %v\n", err)
|
||||||
exit(1)
|
exit(1)
|
||||||
|
|||||||
2
go.mod
2
go.mod
@ -8,7 +8,7 @@ require (
|
|||||||
code.squareroundforest.org/arpio/notation v0.0.0-20251101123932-5f5c05ee0239
|
code.squareroundforest.org/arpio/notation v0.0.0-20251101123932-5f5c05ee0239
|
||||||
code.squareroundforest.org/arpio/textedit v0.0.0-20251207224821-c75c3965789f
|
code.squareroundforest.org/arpio/textedit v0.0.0-20251207224821-c75c3965789f
|
||||||
code.squareroundforest.org/arpio/textfmt v0.0.0-20251207234108-fed32c8bbe18
|
code.squareroundforest.org/arpio/textfmt v0.0.0-20251207234108-fed32c8bbe18
|
||||||
code.squareroundforest.org/arpio/treerack v0.0.0-20251031193114-4f1c219052ae
|
code.squareroundforest.org/arpio/treerack v0.0.0-20251210201822-5e069c4ca4e7
|
||||||
github.com/iancoleman/strcase v0.3.0
|
github.com/iancoleman/strcase v0.3.0
|
||||||
golang.org/x/term v0.37.0
|
golang.org/x/term v0.37.0
|
||||||
)
|
)
|
||||||
|
|||||||
2
go.sum
2
go.sum
@ -12,6 +12,8 @@ code.squareroundforest.org/arpio/textfmt v0.0.0-20251207234108-fed32c8bbe18 h1:2
|
|||||||
code.squareroundforest.org/arpio/textfmt v0.0.0-20251207234108-fed32c8bbe18/go.mod h1:+0G3gufMAP8SCEIrDT1D/DaVOSfjS8EwPTBs5vfxqQg=
|
code.squareroundforest.org/arpio/textfmt v0.0.0-20251207234108-fed32c8bbe18/go.mod h1:+0G3gufMAP8SCEIrDT1D/DaVOSfjS8EwPTBs5vfxqQg=
|
||||||
code.squareroundforest.org/arpio/treerack v0.0.0-20251031193114-4f1c219052ae h1:D28IunhepRhRSp3U2z84e3WtxbYMRzi/FwEEZg54ULM=
|
code.squareroundforest.org/arpio/treerack v0.0.0-20251031193114-4f1c219052ae h1:D28IunhepRhRSp3U2z84e3WtxbYMRzi/FwEEZg54ULM=
|
||||||
code.squareroundforest.org/arpio/treerack v0.0.0-20251031193114-4f1c219052ae/go.mod h1:9XhPcVt1Y1M609z02lHvEcp00dwPD9NUCoVxS2TpcH8=
|
code.squareroundforest.org/arpio/treerack v0.0.0-20251031193114-4f1c219052ae/go.mod h1:9XhPcVt1Y1M609z02lHvEcp00dwPD9NUCoVxS2TpcH8=
|
||||||
|
code.squareroundforest.org/arpio/treerack v0.0.0-20251210201822-5e069c4ca4e7 h1:5dXQ/w5nvo6k46BUvUNvpA9nnCvIOxPgVBJurIHnIYA=
|
||||||
|
code.squareroundforest.org/arpio/treerack v0.0.0-20251210201822-5e069c4ca4e7/go.mod h1:9XhPcVt1Y1M609z02lHvEcp00dwPD9NUCoVxS2TpcH8=
|
||||||
github.com/iancoleman/strcase v0.3.0 h1:nTXanmYxhfFAMjZL34Ov6gkzEsSJZ5DbhxWjvSASxEI=
|
github.com/iancoleman/strcase v0.3.0 h1:nTXanmYxhfFAMjZL34Ov6gkzEsSJZ5DbhxWjvSASxEI=
|
||||||
github.com/iancoleman/strcase v0.3.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho=
|
github.com/iancoleman/strcase v0.3.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho=
|
||||||
golang.org/x/mod v0.27.0 h1:kb+q2PyFnEADO2IEF935ehFUXlWiNjJWtRNgBLSfbxQ=
|
golang.org/x/mod v0.27.0 h1:kb+q2PyFnEADO2IEF935ehFUXlWiNjJWtRNgBLSfbxQ=
|
||||||
|
|||||||
91
help.go
91
help.go
@ -546,8 +546,8 @@ func docOptions(cmd Cmd, conf Config, titleLevel, wrapWidth, hintStyle int) []En
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func docListSubcommands(cmd Cmd, fullCommand []string, wrapWidth int) []Entry {
|
func docListSubcommands(cmd Cmd, fullCommand []string, level, wrapWidth int) []Entry {
|
||||||
subcommandsTitle := Title(1, "Subcommands:")
|
subcommandsTitle := Title(level+1, "Subcommands:")
|
||||||
|
|
||||||
var (
|
var (
|
||||||
items []DefinitionItem
|
items []DefinitionItem
|
||||||
@ -600,11 +600,11 @@ func docListSubcommands(cmd Cmd, fullCommand []string, wrapWidth int) []Entry {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func docFullSubcommands(cmd Cmd, conf Config) []Entry {
|
func docFullSubcommands(cmd Cmd, conf Config, level int) []Entry {
|
||||||
var e []Entry
|
var e []Entry
|
||||||
e = append(
|
e = append(
|
||||||
e,
|
e,
|
||||||
Title(1, "Subcommands:"),
|
Title(level+1, "Subcommands:"),
|
||||||
Paragraph(Text(docSubcommandHint)),
|
Paragraph(Text(docSubcommandHint)),
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -643,7 +643,7 @@ func docFullSubcommands(cmd Cmd, conf Config) []Entry {
|
|||||||
command = fmt.Sprintf("%s (default)", command)
|
command = fmt.Sprintf("%s (default)", command)
|
||||||
}
|
}
|
||||||
|
|
||||||
e = append(e, Indent(Title(2, command), 2, 0))
|
e = append(e, Indent(Title(level+2, command), 2, 0))
|
||||||
if sc.command.version != "" {
|
if sc.command.version != "" {
|
||||||
e = append(e, Indent(Paragraph(Text("Show version.")), 4, 0))
|
e = append(e, Indent(Paragraph(Text("Show version.")), 4, 0))
|
||||||
continue
|
continue
|
||||||
@ -656,7 +656,7 @@ func docFullSubcommands(cmd Cmd, conf Config) []Entry {
|
|||||||
|
|
||||||
e = append(e, synopsis...)
|
e = append(e, synopsis...)
|
||||||
if docs := docs(sc.command); len(docs) > 0 {
|
if docs := docs(sc.command); len(docs) > 0 {
|
||||||
e = append(e, Indent(Title(3, "Description:"), 4, 0))
|
e = append(e, Indent(Title(level+3, "Description:"), 4, 0))
|
||||||
for i := range docs {
|
for i := range docs {
|
||||||
docs[i] = Indent(docs[i], 4, 0)
|
docs[i] = Indent(docs[i], 4, 0)
|
||||||
}
|
}
|
||||||
@ -675,7 +675,7 @@ func docFullSubcommands(cmd Cmd, conf Config) []Entry {
|
|||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
|
|
||||||
func docEnv(cmd Cmd) []Entry {
|
func docEnv(cmd Cmd, level int) []Entry {
|
||||||
// env will not work if the app has a non-standard name:
|
// env will not work if the app has a non-standard name:
|
||||||
if !commandNameExpression.MatchString(cmd.name) {
|
if !commandNameExpression.MatchString(cmd.name) {
|
||||||
return nil
|
return nil
|
||||||
@ -686,13 +686,13 @@ func docEnv(cmd Cmd) []Entry {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
e := []Entry{Title(1, "Environment variables:")}
|
e := []Entry{Title(level+1, "Environment variables:")}
|
||||||
p := paragraphs(envDocs)
|
p := paragraphs(envDocs)
|
||||||
for _, pi := range p {
|
for _, pi := range p {
|
||||||
e = append(e, Indent(Paragraph(Text(pi)), 4, 0))
|
e = append(e, Indent(Paragraph(Text(pi)), 4, 0))
|
||||||
}
|
}
|
||||||
|
|
||||||
e = append(e, Indent(Title(2, "Example environment variable:"), 4, 0))
|
e = append(e, Indent(Title(level+2, "Example environment variable:"), 4, 0))
|
||||||
option := options[0]
|
option := options[0]
|
||||||
name := strcase.ToScreamingSnake(fmt.Sprintf("%s-%s", cmd.name, option.Name()))
|
name := strcase.ToScreamingSnake(fmt.Sprintf("%s-%s", cmd.name, option.Name()))
|
||||||
value := "42"
|
value := "42"
|
||||||
@ -704,7 +704,7 @@ func docEnv(cmd Cmd) []Entry {
|
|||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
|
|
||||||
func docConfig(cmd Cmd, conf Config) []Entry {
|
func docConfig(cmd Cmd, conf Config, level int) []Entry {
|
||||||
options := allNonHelpOptions(cmd)
|
options := allNonHelpOptions(cmd)
|
||||||
if len(options) == 0 {
|
if len(options) == 0 {
|
||||||
return nil
|
return nil
|
||||||
@ -715,7 +715,7 @@ func docConfig(cmd Cmd, conf Config) []Entry {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
e := []Entry{Title(1, "Configuration:")}
|
e := []Entry{Title(level+1, "Configuration:")}
|
||||||
p := paragraphs(configDocs)
|
p := paragraphs(configDocs)
|
||||||
for _, pi := range p {
|
for _, pi := range p {
|
||||||
e = append(e, Indent(Paragraph(Text(pi)), 4, 0))
|
e = append(e, Indent(Paragraph(Text(pi)), 4, 0))
|
||||||
@ -742,7 +742,7 @@ func docConfig(cmd Cmd, conf Config) []Entry {
|
|||||||
|
|
||||||
e = append(
|
e = append(
|
||||||
e,
|
e,
|
||||||
Indent(Title(2, "Configuration files:"), 4, 0),
|
Indent(Title(level+2, "Configuration files:"), 4, 0),
|
||||||
Indent(List(items...), 8, 0),
|
Indent(List(items...), 8, 0),
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -762,7 +762,7 @@ func docConfig(cmd Cmd, conf Config) []Entry {
|
|||||||
|
|
||||||
e = append(
|
e = append(
|
||||||
e,
|
e,
|
||||||
Indent(Title(2, "Example configuration entry:"), 4, 0),
|
Indent(Title(level+2, "Example configuration entry:"), 4, 0),
|
||||||
Indent(CodeBlock(exampleCode), 4, 0),
|
Indent(CodeBlock(exampleCode), 4, 0),
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -773,7 +773,7 @@ func docConfig(cmd Cmd, conf Config) []Entry {
|
|||||||
|
|
||||||
e = append(
|
e = append(
|
||||||
e,
|
e,
|
||||||
Indent(Title(2, "Example for discarding an inherited entry:"), 4, 0),
|
Indent(Title(level+2, "Example for discarding an inherited entry:"), 4, 0),
|
||||||
Indent(CodeBlock(discardExample), 4, 0),
|
Indent(CodeBlock(discardExample), 4, 0),
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -802,10 +802,19 @@ func helpOptions(cmd Cmd, conf Config, width int) []Entry {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func helpSubcommands(cmd Cmd, fullCommand []string, width int) []Entry {
|
func helpSubcommands(cmd Cmd, fullCommand []string, width int) []Entry {
|
||||||
return docListSubcommands(cmd, fullCommand, width)
|
return docListSubcommands(cmd, fullCommand, 0, width)
|
||||||
}
|
}
|
||||||
|
|
||||||
func manTitle(cmd Cmd, date time.Time, version string) []Entry {
|
func manTitle(cmd Cmd, date time.Time, version string) []Entry {
|
||||||
|
if version == "" {
|
||||||
|
for _, sc := range cmd.subcommands {
|
||||||
|
if sc.version != "" {
|
||||||
|
version = sc.version
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return []Entry{
|
return []Entry{
|
||||||
Title(
|
Title(
|
||||||
0,
|
0,
|
||||||
@ -863,30 +872,30 @@ func manSubcommands(cmd Cmd, conf Config) []Entry {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if hasSubcommands {
|
if hasSubcommands {
|
||||||
return docFullSubcommands(cmd, conf)
|
return docFullSubcommands(cmd, conf, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
return docListSubcommands(cmd, []string{cmd.name}, 0)
|
return docListSubcommands(cmd, []string{cmd.name}, 0, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
func manEnv(cmd Cmd) []Entry {
|
func manEnv(cmd Cmd) []Entry {
|
||||||
return docEnv(cmd)
|
return docEnv(cmd, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
func manConfig(cmd Cmd, conf Config) []Entry {
|
func manConfig(cmd Cmd, conf Config) []Entry {
|
||||||
return docConfig(cmd, conf)
|
return docConfig(cmd, conf, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
func markdownTitle(cmd Cmd) []Entry {
|
func markdownTitle(cmd Cmd, level int) []Entry {
|
||||||
txt := docCommandNameText(cmd, []string{cmd.name})
|
txt := docCommandNameText(cmd, []string{cmd.name})
|
||||||
return []Entry{Title(0, strings.Join(txt, " "))}
|
return []Entry{Title(level, strings.Join(txt, " "))}
|
||||||
}
|
}
|
||||||
|
|
||||||
func markdownSynopsis(cmd Cmd) []Entry {
|
func markdownSynopsis(cmd Cmd, level int) []Entry {
|
||||||
return docSynopsis(cmd, []string{cmd.name}, 1, markdownWrapWidth)
|
return docSynopsis(cmd, []string{cmd.name}, level+1, markdownWrapWidth)
|
||||||
}
|
}
|
||||||
|
|
||||||
func markdownDocs(cmd Cmd) []Entry {
|
func markdownDocs(cmd Cmd, level int) []Entry {
|
||||||
paragraphs := docs(cmd)
|
paragraphs := docs(cmd)
|
||||||
if len(paragraphs) == 0 {
|
if len(paragraphs) == 0 {
|
||||||
return nil
|
return nil
|
||||||
@ -896,11 +905,11 @@ func markdownDocs(cmd Cmd) []Entry {
|
|||||||
paragraphs[i] = Wrap(paragraphs[i], markdownWrapWidth)
|
paragraphs[i] = Wrap(paragraphs[i], markdownWrapWidth)
|
||||||
}
|
}
|
||||||
|
|
||||||
return append([]Entry{Title(1, "Description:")}, paragraphs...)
|
return append([]Entry{Title(level+1, "Description:")}, paragraphs...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func markdownOptions(cmd Cmd, conf Config) []Entry {
|
func markdownOptions(cmd Cmd, conf Config, level int) []Entry {
|
||||||
e := docOptions(cmd, conf, 1, 0, allRelevantHints)
|
e := docOptions(cmd, conf, level+1, 0, allRelevantHints)
|
||||||
for i := 1; i < len(e); i++ {
|
for i := 1; i < len(e); i++ {
|
||||||
e[i] = Wrap(e[i], markdownWrapWidth)
|
e[i] = Wrap(e[i], markdownWrapWidth)
|
||||||
}
|
}
|
||||||
@ -908,7 +917,7 @@ func markdownOptions(cmd Cmd, conf Config) []Entry {
|
|||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
|
|
||||||
func markdownSubcommands(cmd Cmd, conf Config) []Entry {
|
func markdownSubcommands(cmd Cmd, conf Config, level int) []Entry {
|
||||||
var hasSubcommands bool
|
var hasSubcommands bool
|
||||||
for _, sc := range cmd.subcommands {
|
for _, sc := range cmd.subcommands {
|
||||||
if sc.helpFor != nil || sc.version != "" {
|
if sc.helpFor != nil || sc.version != "" {
|
||||||
@ -921,9 +930,9 @@ func markdownSubcommands(cmd Cmd, conf Config) []Entry {
|
|||||||
|
|
||||||
var e []Entry
|
var e []Entry
|
||||||
if hasSubcommands {
|
if hasSubcommands {
|
||||||
e = docFullSubcommands(cmd, conf)
|
e = docFullSubcommands(cmd, conf, level)
|
||||||
} else {
|
} else {
|
||||||
e = docListSubcommands(cmd, []string{cmd.name}, 0)
|
e = docListSubcommands(cmd, []string{cmd.name}, level, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
for i := range e {
|
for i := range e {
|
||||||
@ -933,8 +942,8 @@ func markdownSubcommands(cmd Cmd, conf Config) []Entry {
|
|||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
|
|
||||||
func markdownEnv(cmd Cmd) []Entry {
|
func markdownEnv(cmd Cmd, level int) []Entry {
|
||||||
e := docEnv(cmd)
|
e := docEnv(cmd, level)
|
||||||
for i := range e {
|
for i := range e {
|
||||||
e[i] = Wrap(e[i], markdownWrapWidth)
|
e[i] = Wrap(e[i], markdownWrapWidth)
|
||||||
}
|
}
|
||||||
@ -942,8 +951,8 @@ func markdownEnv(cmd Cmd) []Entry {
|
|||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
|
|
||||||
func markdownConfig(cmd Cmd, conf Config) []Entry {
|
func markdownConfig(cmd Cmd, conf Config, level int) []Entry {
|
||||||
e := docConfig(cmd, conf)
|
e := docConfig(cmd, conf, level)
|
||||||
for i := range e {
|
for i := range e {
|
||||||
e[i] = Wrap(e[i], markdownWrapWidth)
|
e[i] = Wrap(e[i], markdownWrapWidth)
|
||||||
}
|
}
|
||||||
@ -977,13 +986,13 @@ func generateMan(out io.Writer, cmd Cmd, conf Config, date time.Time, version st
|
|||||||
|
|
||||||
func generateMarkdown(out io.Writer, cmd Cmd, conf Config, level int) error {
|
func generateMarkdown(out io.Writer, cmd Cmd, conf Config, level int) error {
|
||||||
var e []Entry
|
var e []Entry
|
||||||
e = append(e, markdownTitle(cmd)...)
|
e = append(e, markdownTitle(cmd, level)...)
|
||||||
e = append(e, markdownSynopsis(cmd)...)
|
e = append(e, markdownSynopsis(cmd, level)...)
|
||||||
e = append(e, markdownDocs(cmd)...)
|
e = append(e, markdownDocs(cmd, level)...)
|
||||||
e = append(e, markdownOptions(cmd, conf)...)
|
e = append(e, markdownOptions(cmd, conf, level)...)
|
||||||
e = append(e, markdownSubcommands(cmd, conf)...)
|
e = append(e, markdownSubcommands(cmd, conf, level)...)
|
||||||
e = append(e, markdownEnv(cmd)...)
|
e = append(e, markdownEnv(cmd, level)...)
|
||||||
e = append(e, markdownConfig(cmd, conf)...)
|
e = append(e, markdownConfig(cmd, conf, level)...)
|
||||||
return Markdown(out, Doc(e...))
|
return Markdown(out, Doc(e...))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
13
help_test.go
13
help_test.go
@ -257,6 +257,7 @@ Options:
|
|||||||
--bar string [*]: Bars, any number.
|
--bar string [*]: Bars, any number.
|
||||||
--duration duration: Duration is another option.
|
--duration duration: Duration is another option.
|
||||||
--foo int: Foo is an option.
|
--foo int: Foo is an option.
|
||||||
|
--some any: Some is an option of any type.
|
||||||
--time time: Time is the third option here.
|
--time time: Time is the third option here.
|
||||||
--help: Show help.
|
--help: Show help.
|
||||||
|
|
||||||
@ -285,6 +286,7 @@ Options:
|
|||||||
--bar string [*]: Bars, any number.
|
--bar string [*]: Bars, any number.
|
||||||
--duration duration: Duration is another option.
|
--duration duration: Duration is another option.
|
||||||
--foo int: Foo is an option.
|
--foo int: Foo is an option.
|
||||||
|
--some any: Some is an option of any type.
|
||||||
--time time: Time is the third option here.
|
--time time: Time is the third option here.
|
||||||
--help: Show help.
|
--help: Show help.
|
||||||
|
|
||||||
@ -381,7 +383,8 @@ Subcommands:
|
|||||||
Command("foo", func(struct {
|
Command("foo", func(struct {
|
||||||
Foo bool
|
Foo bool
|
||||||
Bar string
|
Bar string
|
||||||
}) {}),
|
}) {
|
||||||
|
}),
|
||||||
"f", "foo", "b", "bar",
|
"f", "foo", "b", "bar",
|
||||||
),
|
),
|
||||||
command: "foo help",
|
command: "foo help",
|
||||||
@ -970,6 +973,10 @@ foo
|
|||||||
.br
|
.br
|
||||||
.in 25
|
.in 25
|
||||||
.ti 4
|
.ti 4
|
||||||
|
--some any:\~\~\~\~\~\~\~\~\~\~Some is an option of any type.
|
||||||
|
.br
|
||||||
|
.in 25
|
||||||
|
.ti 4
|
||||||
--time time:\~\~\~\~\~\~\~\~\~Time is the third option here.
|
--time time:\~\~\~\~\~\~\~\~\~Time is the third option here.
|
||||||
.br
|
.br
|
||||||
.in 25
|
.in 25
|
||||||
@ -1234,7 +1241,8 @@ When both the environment variable and the command line option is defined, the c
|
|||||||
impl: ShortForm(Command("foo", func(struct {
|
impl: ShortForm(Command("foo", func(struct {
|
||||||
Foo bool
|
Foo bool
|
||||||
Bar int
|
Bar int
|
||||||
}) {}), "f", "foo", "b", "bar"),
|
}) {
|
||||||
|
}), "f", "foo", "b", "bar"),
|
||||||
command: "foo",
|
command: "foo",
|
||||||
env: "_wandgenerate=man;_wandgeneratedate=2025-12-03;_wandgenerateversion=2025-12-03-abcd123",
|
env: "_wandgenerate=man;_wandgeneratedate=2025-12-03;_wandgenerateversion=2025-12-03-abcd123",
|
||||||
},
|
},
|
||||||
@ -1732,6 +1740,7 @@ foo <subcommand>
|
|||||||
- --bar string \[\*\]: Bars, any number.
|
- --bar string \[\*\]: Bars, any number.
|
||||||
- --duration duration: Duration is another option.
|
- --duration duration: Duration is another option.
|
||||||
- --foo int: Foo is an option.
|
- --foo int: Foo is an option.
|
||||||
|
- --some any: Some is an option of any type.
|
||||||
- --time time: Time is the third option here.
|
- --time time: Time is the third option here.
|
||||||
- --config: Configuration file.
|
- --config: Configuration file.
|
||||||
- --help: Show help.
|
- --help: Show help.
|
||||||
|
|||||||
@ -619,7 +619,7 @@ func (c *context) read() bool {
|
|||||||
}
|
}
|
||||||
token, n, err := c.reader.ReadRune()
|
token, n, err := c.reader.ReadRune()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if err == io.EOF {
|
if errors.Is(err, io.EOF) {
|
||||||
if n == 0 {
|
if n == 0 {
|
||||||
c.eof = true
|
c.eof = true
|
||||||
return false
|
return false
|
||||||
|
|||||||
1
internal/tests/testconfig.ini
Normal file
1
internal/tests/testconfig.ini
Normal file
@ -0,0 +1 @@
|
|||||||
|
one = 42
|
||||||
17
internal/tests/testlib/cmd/main.go
Normal file
17
internal/tests/testlib/cmd/main.go
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
. "code.squareroundforest.org/arpio/wand"
|
||||||
|
"code.squareroundforest.org/arpio/wand/internal/tests/testlib"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
Exec(
|
||||||
|
Group(
|
||||||
|
"test",
|
||||||
|
Default(Command("foo", testlib.Foo)),
|
||||||
|
Command("bar", testlib.Bar),
|
||||||
|
Command("baz", testlib.Baz),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
@ -18,6 +18,9 @@ type Options struct {
|
|||||||
|
|
||||||
// Time is the third option here.
|
// Time is the third option here.
|
||||||
Time time.Time
|
Time time.Time
|
||||||
|
|
||||||
|
// Some is an option of any type.
|
||||||
|
Some any
|
||||||
}
|
}
|
||||||
|
|
||||||
type OptionWithHelp struct {
|
type OptionWithHelp struct {
|
||||||
|
|||||||
@ -0,0 +1,5 @@
|
|||||||
|
package main
|
||||||
|
import "code.squareroundforest.org/arpio/wand"
|
||||||
|
func main() {
|
||||||
|
wand.Exec(func(a string) { println(a) })
|
||||||
|
}
|
||||||
18
internal/tests/tmpdir/7uxW5Ik-qaesYEi3BWbg9Q/go.mod
Normal file
18
internal/tests/tmpdir/7uxW5Ik-qaesYEi3BWbg9Q/go.mod
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
module 7uxW5Ik-qaesYEi3BWbg9Q
|
||||||
|
|
||||||
|
go 1.25.4
|
||||||
|
|
||||||
|
require (
|
||||||
|
code.squareroundforest.org/arpio/bind v0.0.0-20251105181644-3443251be2d5 // indirect
|
||||||
|
code.squareroundforest.org/arpio/docreflect v0.0.0-20251031192707-01c5ff18fab1 // indirect
|
||||||
|
code.squareroundforest.org/arpio/html v0.0.0-20251103020946-e262eca50ac9 // indirect
|
||||||
|
code.squareroundforest.org/arpio/notation v0.0.0-20251101123932-5f5c05ee0239 // indirect
|
||||||
|
code.squareroundforest.org/arpio/textedit v0.0.0-20251207224821-c75c3965789f // indirect
|
||||||
|
code.squareroundforest.org/arpio/textfmt v0.0.0-20251207234108-fed32c8bbe18 // indirect
|
||||||
|
code.squareroundforest.org/arpio/wand v0.0.0-20251210193110-60acf6e82022 // indirect
|
||||||
|
github.com/iancoleman/strcase v0.3.0 // indirect
|
||||||
|
golang.org/x/sys v0.38.0 // indirect
|
||||||
|
golang.org/x/term v0.37.0 // indirect
|
||||||
|
)
|
||||||
|
|
||||||
|
replace code.squareroundforest.org/arpio/wand => /Users/arpio/work/code/wand
|
||||||
20
internal/tests/tmpdir/7uxW5Ik-qaesYEi3BWbg9Q/go.sum
Normal file
20
internal/tests/tmpdir/7uxW5Ik-qaesYEi3BWbg9Q/go.sum
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
code.squareroundforest.org/arpio/bind v0.0.0-20251105181644-3443251be2d5 h1:SIgLIawD6Vv7rAvUobpVshLshdwFEJ0NOUrWpheS088=
|
||||||
|
code.squareroundforest.org/arpio/bind v0.0.0-20251105181644-3443251be2d5/go.mod h1:tTCmCwFABKNm3PO0Dclsp4zWhNQFTfg9+uSrgoarZFI=
|
||||||
|
code.squareroundforest.org/arpio/docreflect v0.0.0-20251031192707-01c5ff18fab1 h1:bJi41U5yGQykg6jVlD2AdWiznvx3Jg7ZpzEU85syOXw=
|
||||||
|
code.squareroundforest.org/arpio/docreflect v0.0.0-20251031192707-01c5ff18fab1/go.mod h1:/3xQI36oJG8qLBxT2fSS61P5/+i1T64fTX9GHRh8XhA=
|
||||||
|
code.squareroundforest.org/arpio/html v0.0.0-20251103020946-e262eca50ac9 h1:b7voJlwe0jKH568X+O7b/JTAUrHLTSKNSSL+hhV2Q/Q=
|
||||||
|
code.squareroundforest.org/arpio/html v0.0.0-20251103020946-e262eca50ac9/go.mod h1:hq+2CENEd4bVSZnOdq38FUFOJJnF3OTQRv78qMGkNlE=
|
||||||
|
code.squareroundforest.org/arpio/notation v0.0.0-20251101123932-5f5c05ee0239 h1:JvLVMuvF2laxXkIZbHC1/0xtKyKndAwIHbIIWkHqTzc=
|
||||||
|
code.squareroundforest.org/arpio/notation v0.0.0-20251101123932-5f5c05ee0239/go.mod h1:ait4Fvg9o0+bq5hlxi9dAcPL5a+/sr33qsZPNpToMLY=
|
||||||
|
code.squareroundforest.org/arpio/textedit v0.0.0-20251207224821-c75c3965789f h1:gomu8xTD953IkL3M528qVEuZ2z93C2I6Hr4vyIwE7kI=
|
||||||
|
code.squareroundforest.org/arpio/textedit v0.0.0-20251207224821-c75c3965789f/go.mod h1:nXdFdxdI69JrkIT97f+AEE4OgplmxbgNFZC5j7gsdqs=
|
||||||
|
code.squareroundforest.org/arpio/textfmt v0.0.0-20251207234108-fed32c8bbe18 h1:2aa62CYm9ld5SNoFxWzE2wUN0xjVWQ+xieoeFantdg4=
|
||||||
|
code.squareroundforest.org/arpio/textfmt v0.0.0-20251207234108-fed32c8bbe18/go.mod h1:+0G3gufMAP8SCEIrDT1D/DaVOSfjS8EwPTBs5vfxqQg=
|
||||||
|
code.squareroundforest.org/arpio/wand v0.0.0-20251210193110-60acf6e82022 h1:9XKwyrmOi2upsYWyjMQOPhO6ebl7AEHSViBVu9U/2jc=
|
||||||
|
code.squareroundforest.org/arpio/wand v0.0.0-20251210193110-60acf6e82022/go.mod h1:dwEF9zEIbOxbLxytOKSuRQPKmvbhPjDCJcoXM3j8cOU=
|
||||||
|
github.com/iancoleman/strcase v0.3.0 h1:nTXanmYxhfFAMjZL34Ov6gkzEsSJZ5DbhxWjvSASxEI=
|
||||||
|
github.com/iancoleman/strcase v0.3.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho=
|
||||||
|
golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc=
|
||||||
|
golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
||||||
|
golang.org/x/term v0.37.0 h1:8EGAD0qCmHYZg6J17DvsMy9/wJ7/D/4pV/wfnld5lTU=
|
||||||
|
golang.org/x/term v0.37.0/go.mod h1:5pB4lxRNYYVZuTLmy8oR2BH8dflOR+IbTYFD8fi3254=
|
||||||
@ -0,0 +1,6 @@
|
|||||||
|
package main
|
||||||
|
import "strings"
|
||||||
|
import "code.squareroundforest.org/arpio/wand"
|
||||||
|
func main() {
|
||||||
|
wand.Exec(strings.Split)
|
||||||
|
}
|
||||||
18
internal/tests/tmpdir/Du66PUa6l2PUdTO2P6Mz8w/go.mod
Normal file
18
internal/tests/tmpdir/Du66PUa6l2PUdTO2P6Mz8w/go.mod
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
module Du66PUa6l2PUdTO2P6Mz8w
|
||||||
|
|
||||||
|
go 1.25.4
|
||||||
|
|
||||||
|
require (
|
||||||
|
code.squareroundforest.org/arpio/bind v0.0.0-20251105181644-3443251be2d5 // indirect
|
||||||
|
code.squareroundforest.org/arpio/docreflect v0.0.0-20251031192707-01c5ff18fab1 // indirect
|
||||||
|
code.squareroundforest.org/arpio/html v0.0.0-20251103020946-e262eca50ac9 // indirect
|
||||||
|
code.squareroundforest.org/arpio/notation v0.0.0-20251101123932-5f5c05ee0239 // indirect
|
||||||
|
code.squareroundforest.org/arpio/textedit v0.0.0-20251207224821-c75c3965789f // indirect
|
||||||
|
code.squareroundforest.org/arpio/textfmt v0.0.0-20251207234108-fed32c8bbe18 // indirect
|
||||||
|
code.squareroundforest.org/arpio/wand v0.0.0-20251210193110-60acf6e82022 // indirect
|
||||||
|
github.com/iancoleman/strcase v0.3.0 // indirect
|
||||||
|
golang.org/x/sys v0.38.0 // indirect
|
||||||
|
golang.org/x/term v0.37.0 // indirect
|
||||||
|
)
|
||||||
|
|
||||||
|
replace code.squareroundforest.org/arpio/wand => /Users/arpio/work/code/wand
|
||||||
20
internal/tests/tmpdir/Du66PUa6l2PUdTO2P6Mz8w/go.sum
Normal file
20
internal/tests/tmpdir/Du66PUa6l2PUdTO2P6Mz8w/go.sum
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
code.squareroundforest.org/arpio/bind v0.0.0-20251105181644-3443251be2d5 h1:SIgLIawD6Vv7rAvUobpVshLshdwFEJ0NOUrWpheS088=
|
||||||
|
code.squareroundforest.org/arpio/bind v0.0.0-20251105181644-3443251be2d5/go.mod h1:tTCmCwFABKNm3PO0Dclsp4zWhNQFTfg9+uSrgoarZFI=
|
||||||
|
code.squareroundforest.org/arpio/docreflect v0.0.0-20251031192707-01c5ff18fab1 h1:bJi41U5yGQykg6jVlD2AdWiznvx3Jg7ZpzEU85syOXw=
|
||||||
|
code.squareroundforest.org/arpio/docreflect v0.0.0-20251031192707-01c5ff18fab1/go.mod h1:/3xQI36oJG8qLBxT2fSS61P5/+i1T64fTX9GHRh8XhA=
|
||||||
|
code.squareroundforest.org/arpio/html v0.0.0-20251103020946-e262eca50ac9 h1:b7voJlwe0jKH568X+O7b/JTAUrHLTSKNSSL+hhV2Q/Q=
|
||||||
|
code.squareroundforest.org/arpio/html v0.0.0-20251103020946-e262eca50ac9/go.mod h1:hq+2CENEd4bVSZnOdq38FUFOJJnF3OTQRv78qMGkNlE=
|
||||||
|
code.squareroundforest.org/arpio/notation v0.0.0-20251101123932-5f5c05ee0239 h1:JvLVMuvF2laxXkIZbHC1/0xtKyKndAwIHbIIWkHqTzc=
|
||||||
|
code.squareroundforest.org/arpio/notation v0.0.0-20251101123932-5f5c05ee0239/go.mod h1:ait4Fvg9o0+bq5hlxi9dAcPL5a+/sr33qsZPNpToMLY=
|
||||||
|
code.squareroundforest.org/arpio/textedit v0.0.0-20251207224821-c75c3965789f h1:gomu8xTD953IkL3M528qVEuZ2z93C2I6Hr4vyIwE7kI=
|
||||||
|
code.squareroundforest.org/arpio/textedit v0.0.0-20251207224821-c75c3965789f/go.mod h1:nXdFdxdI69JrkIT97f+AEE4OgplmxbgNFZC5j7gsdqs=
|
||||||
|
code.squareroundforest.org/arpio/textfmt v0.0.0-20251207234108-fed32c8bbe18 h1:2aa62CYm9ld5SNoFxWzE2wUN0xjVWQ+xieoeFantdg4=
|
||||||
|
code.squareroundforest.org/arpio/textfmt v0.0.0-20251207234108-fed32c8bbe18/go.mod h1:+0G3gufMAP8SCEIrDT1D/DaVOSfjS8EwPTBs5vfxqQg=
|
||||||
|
code.squareroundforest.org/arpio/wand v0.0.0-20251210193110-60acf6e82022 h1:9XKwyrmOi2upsYWyjMQOPhO6ebl7AEHSViBVu9U/2jc=
|
||||||
|
code.squareroundforest.org/arpio/wand v0.0.0-20251210193110-60acf6e82022/go.mod h1:dwEF9zEIbOxbLxytOKSuRQPKmvbhPjDCJcoXM3j8cOU=
|
||||||
|
github.com/iancoleman/strcase v0.3.0 h1:nTXanmYxhfFAMjZL34Ov6gkzEsSJZ5DbhxWjvSASxEI=
|
||||||
|
github.com/iancoleman/strcase v0.3.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho=
|
||||||
|
golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc=
|
||||||
|
golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
||||||
|
golang.org/x/term v0.37.0 h1:8EGAD0qCmHYZg6J17DvsMy9/wJ7/D/4pV/wfnld5lTU=
|
||||||
|
golang.org/x/term v0.37.0/go.mod h1:5pB4lxRNYYVZuTLmy8oR2BH8dflOR+IbTYFD8fi3254=
|
||||||
@ -0,0 +1,22 @@
|
|||||||
|
package main
|
||||||
|
import "io"
|
||||||
|
import "code.squareroundforest.org/arpio/wand"
|
||||||
|
func main() {
|
||||||
|
wand.Exec(func(in io.Reader) (out io.Reader) {
|
||||||
|
out := bytes.NewBuffer(nil)
|
||||||
|
buf := make([]byte, 1)
|
||||||
|
for {
|
||||||
|
n, err := in.Read(buf)
|
||||||
|
if n == 1 {
|
||||||
|
buf[0] = buf[0] * 2
|
||||||
|
out.Write(buf)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return out
|
||||||
|
})
|
||||||
|
}
|
||||||
18
internal/tests/tmpdir/GBAVk0TbT71P1fBFC4wZxQ/go.mod
Normal file
18
internal/tests/tmpdir/GBAVk0TbT71P1fBFC4wZxQ/go.mod
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
module GBAVk0TbT71P1fBFC4wZxQ
|
||||||
|
|
||||||
|
go 1.25.4
|
||||||
|
|
||||||
|
require (
|
||||||
|
code.squareroundforest.org/arpio/bind v0.0.0-20251105181644-3443251be2d5 // indirect
|
||||||
|
code.squareroundforest.org/arpio/docreflect v0.0.0-20251031192707-01c5ff18fab1 // indirect
|
||||||
|
code.squareroundforest.org/arpio/html v0.0.0-20251103020946-e262eca50ac9 // indirect
|
||||||
|
code.squareroundforest.org/arpio/notation v0.0.0-20251101123932-5f5c05ee0239 // indirect
|
||||||
|
code.squareroundforest.org/arpio/textedit v0.0.0-20251207224821-c75c3965789f // indirect
|
||||||
|
code.squareroundforest.org/arpio/textfmt v0.0.0-20251207234108-fed32c8bbe18 // indirect
|
||||||
|
code.squareroundforest.org/arpio/wand v0.0.0-20251210193110-60acf6e82022 // indirect
|
||||||
|
github.com/iancoleman/strcase v0.3.0 // indirect
|
||||||
|
golang.org/x/sys v0.38.0 // indirect
|
||||||
|
golang.org/x/term v0.37.0 // indirect
|
||||||
|
)
|
||||||
|
|
||||||
|
replace code.squareroundforest.org/arpio/wand => /Users/arpio/work/code/wand
|
||||||
20
internal/tests/tmpdir/GBAVk0TbT71P1fBFC4wZxQ/go.sum
Normal file
20
internal/tests/tmpdir/GBAVk0TbT71P1fBFC4wZxQ/go.sum
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
code.squareroundforest.org/arpio/bind v0.0.0-20251105181644-3443251be2d5 h1:SIgLIawD6Vv7rAvUobpVshLshdwFEJ0NOUrWpheS088=
|
||||||
|
code.squareroundforest.org/arpio/bind v0.0.0-20251105181644-3443251be2d5/go.mod h1:tTCmCwFABKNm3PO0Dclsp4zWhNQFTfg9+uSrgoarZFI=
|
||||||
|
code.squareroundforest.org/arpio/docreflect v0.0.0-20251031192707-01c5ff18fab1 h1:bJi41U5yGQykg6jVlD2AdWiznvx3Jg7ZpzEU85syOXw=
|
||||||
|
code.squareroundforest.org/arpio/docreflect v0.0.0-20251031192707-01c5ff18fab1/go.mod h1:/3xQI36oJG8qLBxT2fSS61P5/+i1T64fTX9GHRh8XhA=
|
||||||
|
code.squareroundforest.org/arpio/html v0.0.0-20251103020946-e262eca50ac9 h1:b7voJlwe0jKH568X+O7b/JTAUrHLTSKNSSL+hhV2Q/Q=
|
||||||
|
code.squareroundforest.org/arpio/html v0.0.0-20251103020946-e262eca50ac9/go.mod h1:hq+2CENEd4bVSZnOdq38FUFOJJnF3OTQRv78qMGkNlE=
|
||||||
|
code.squareroundforest.org/arpio/notation v0.0.0-20251101123932-5f5c05ee0239 h1:JvLVMuvF2laxXkIZbHC1/0xtKyKndAwIHbIIWkHqTzc=
|
||||||
|
code.squareroundforest.org/arpio/notation v0.0.0-20251101123932-5f5c05ee0239/go.mod h1:ait4Fvg9o0+bq5hlxi9dAcPL5a+/sr33qsZPNpToMLY=
|
||||||
|
code.squareroundforest.org/arpio/textedit v0.0.0-20251207224821-c75c3965789f h1:gomu8xTD953IkL3M528qVEuZ2z93C2I6Hr4vyIwE7kI=
|
||||||
|
code.squareroundforest.org/arpio/textedit v0.0.0-20251207224821-c75c3965789f/go.mod h1:nXdFdxdI69JrkIT97f+AEE4OgplmxbgNFZC5j7gsdqs=
|
||||||
|
code.squareroundforest.org/arpio/textfmt v0.0.0-20251207234108-fed32c8bbe18 h1:2aa62CYm9ld5SNoFxWzE2wUN0xjVWQ+xieoeFantdg4=
|
||||||
|
code.squareroundforest.org/arpio/textfmt v0.0.0-20251207234108-fed32c8bbe18/go.mod h1:+0G3gufMAP8SCEIrDT1D/DaVOSfjS8EwPTBs5vfxqQg=
|
||||||
|
code.squareroundforest.org/arpio/wand v0.0.0-20251210193110-60acf6e82022 h1:9XKwyrmOi2upsYWyjMQOPhO6ebl7AEHSViBVu9U/2jc=
|
||||||
|
code.squareroundforest.org/arpio/wand v0.0.0-20251210193110-60acf6e82022/go.mod h1:dwEF9zEIbOxbLxytOKSuRQPKmvbhPjDCJcoXM3j8cOU=
|
||||||
|
github.com/iancoleman/strcase v0.3.0 h1:nTXanmYxhfFAMjZL34Ov6gkzEsSJZ5DbhxWjvSASxEI=
|
||||||
|
github.com/iancoleman/strcase v0.3.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho=
|
||||||
|
golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc=
|
||||||
|
golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
||||||
|
golang.org/x/term v0.37.0 h1:8EGAD0qCmHYZg6J17DvsMy9/wJ7/D/4pV/wfnld5lTU=
|
||||||
|
golang.org/x/term v0.37.0/go.mod h1:5pB4lxRNYYVZuTLmy8oR2BH8dflOR+IbTYFD8fi3254=
|
||||||
@ -0,0 +1,5 @@
|
|||||||
|
package main
|
||||||
|
import "code.squareroundforest.org/arpio/wand"
|
||||||
|
func main() {
|
||||||
|
wand.Exec(func(a any) { println(a) })
|
||||||
|
}
|
||||||
18
internal/tests/tmpdir/Vw9o9PuLOlqrxfbxo88FwA/go.mod
Normal file
18
internal/tests/tmpdir/Vw9o9PuLOlqrxfbxo88FwA/go.mod
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
module Vw9o9PuLOlqrxfbxo88FwA
|
||||||
|
|
||||||
|
go 1.25.4
|
||||||
|
|
||||||
|
require (
|
||||||
|
code.squareroundforest.org/arpio/bind v0.0.0-20251105181644-3443251be2d5 // indirect
|
||||||
|
code.squareroundforest.org/arpio/docreflect v0.0.0-20251031192707-01c5ff18fab1 // indirect
|
||||||
|
code.squareroundforest.org/arpio/html v0.0.0-20251103020946-e262eca50ac9 // indirect
|
||||||
|
code.squareroundforest.org/arpio/notation v0.0.0-20251101123932-5f5c05ee0239 // indirect
|
||||||
|
code.squareroundforest.org/arpio/textedit v0.0.0-20251207224821-c75c3965789f // indirect
|
||||||
|
code.squareroundforest.org/arpio/textfmt v0.0.0-20251207234108-fed32c8bbe18 // indirect
|
||||||
|
code.squareroundforest.org/arpio/wand v0.0.0-20251210193110-60acf6e82022 // indirect
|
||||||
|
github.com/iancoleman/strcase v0.3.0 // indirect
|
||||||
|
golang.org/x/sys v0.38.0 // indirect
|
||||||
|
golang.org/x/term v0.37.0 // indirect
|
||||||
|
)
|
||||||
|
|
||||||
|
replace code.squareroundforest.org/arpio/wand => /Users/arpio/work/code/wand
|
||||||
20
internal/tests/tmpdir/Vw9o9PuLOlqrxfbxo88FwA/go.sum
Normal file
20
internal/tests/tmpdir/Vw9o9PuLOlqrxfbxo88FwA/go.sum
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
code.squareroundforest.org/arpio/bind v0.0.0-20251105181644-3443251be2d5 h1:SIgLIawD6Vv7rAvUobpVshLshdwFEJ0NOUrWpheS088=
|
||||||
|
code.squareroundforest.org/arpio/bind v0.0.0-20251105181644-3443251be2d5/go.mod h1:tTCmCwFABKNm3PO0Dclsp4zWhNQFTfg9+uSrgoarZFI=
|
||||||
|
code.squareroundforest.org/arpio/docreflect v0.0.0-20251031192707-01c5ff18fab1 h1:bJi41U5yGQykg6jVlD2AdWiznvx3Jg7ZpzEU85syOXw=
|
||||||
|
code.squareroundforest.org/arpio/docreflect v0.0.0-20251031192707-01c5ff18fab1/go.mod h1:/3xQI36oJG8qLBxT2fSS61P5/+i1T64fTX9GHRh8XhA=
|
||||||
|
code.squareroundforest.org/arpio/html v0.0.0-20251103020946-e262eca50ac9 h1:b7voJlwe0jKH568X+O7b/JTAUrHLTSKNSSL+hhV2Q/Q=
|
||||||
|
code.squareroundforest.org/arpio/html v0.0.0-20251103020946-e262eca50ac9/go.mod h1:hq+2CENEd4bVSZnOdq38FUFOJJnF3OTQRv78qMGkNlE=
|
||||||
|
code.squareroundforest.org/arpio/notation v0.0.0-20251101123932-5f5c05ee0239 h1:JvLVMuvF2laxXkIZbHC1/0xtKyKndAwIHbIIWkHqTzc=
|
||||||
|
code.squareroundforest.org/arpio/notation v0.0.0-20251101123932-5f5c05ee0239/go.mod h1:ait4Fvg9o0+bq5hlxi9dAcPL5a+/sr33qsZPNpToMLY=
|
||||||
|
code.squareroundforest.org/arpio/textedit v0.0.0-20251207224821-c75c3965789f h1:gomu8xTD953IkL3M528qVEuZ2z93C2I6Hr4vyIwE7kI=
|
||||||
|
code.squareroundforest.org/arpio/textedit v0.0.0-20251207224821-c75c3965789f/go.mod h1:nXdFdxdI69JrkIT97f+AEE4OgplmxbgNFZC5j7gsdqs=
|
||||||
|
code.squareroundforest.org/arpio/textfmt v0.0.0-20251207234108-fed32c8bbe18 h1:2aa62CYm9ld5SNoFxWzE2wUN0xjVWQ+xieoeFantdg4=
|
||||||
|
code.squareroundforest.org/arpio/textfmt v0.0.0-20251207234108-fed32c8bbe18/go.mod h1:+0G3gufMAP8SCEIrDT1D/DaVOSfjS8EwPTBs5vfxqQg=
|
||||||
|
code.squareroundforest.org/arpio/wand v0.0.0-20251210193110-60acf6e82022 h1:9XKwyrmOi2upsYWyjMQOPhO6ebl7AEHSViBVu9U/2jc=
|
||||||
|
code.squareroundforest.org/arpio/wand v0.0.0-20251210193110-60acf6e82022/go.mod h1:dwEF9zEIbOxbLxytOKSuRQPKmvbhPjDCJcoXM3j8cOU=
|
||||||
|
github.com/iancoleman/strcase v0.3.0 h1:nTXanmYxhfFAMjZL34Ov6gkzEsSJZ5DbhxWjvSASxEI=
|
||||||
|
github.com/iancoleman/strcase v0.3.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho=
|
||||||
|
golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc=
|
||||||
|
golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
||||||
|
golang.org/x/term v0.37.0 h1:8EGAD0qCmHYZg6J17DvsMy9/wJ7/D/4pV/wfnld5lTU=
|
||||||
|
golang.org/x/term v0.37.0/go.mod h1:5pB4lxRNYYVZuTLmy8oR2BH8dflOR+IbTYFD8fi3254=
|
||||||
@ -0,0 +1,6 @@
|
|||||||
|
package main
|
||||||
|
import "fmt"
|
||||||
|
import "code.squareroundforest.org/arpio/wand"
|
||||||
|
func main() {
|
||||||
|
wand.Exec(func(a any) { println(a) })
|
||||||
|
}
|
||||||
18
internal/tests/tmpdir/W0w-rWwNmthjuerTOFnMIQ/go.mod
Normal file
18
internal/tests/tmpdir/W0w-rWwNmthjuerTOFnMIQ/go.mod
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
module W0w-rWwNmthjuerTOFnMIQ
|
||||||
|
|
||||||
|
go 1.25.4
|
||||||
|
|
||||||
|
require (
|
||||||
|
code.squareroundforest.org/arpio/bind v0.0.0-20251105181644-3443251be2d5 // indirect
|
||||||
|
code.squareroundforest.org/arpio/docreflect v0.0.0-20251031192707-01c5ff18fab1 // indirect
|
||||||
|
code.squareroundforest.org/arpio/html v0.0.0-20251103020946-e262eca50ac9 // indirect
|
||||||
|
code.squareroundforest.org/arpio/notation v0.0.0-20251101123932-5f5c05ee0239 // indirect
|
||||||
|
code.squareroundforest.org/arpio/textedit v0.0.0-20251207224821-c75c3965789f // indirect
|
||||||
|
code.squareroundforest.org/arpio/textfmt v0.0.0-20251207234108-fed32c8bbe18 // indirect
|
||||||
|
code.squareroundforest.org/arpio/wand v0.0.0-20251210193110-60acf6e82022 // indirect
|
||||||
|
github.com/iancoleman/strcase v0.3.0 // indirect
|
||||||
|
golang.org/x/sys v0.38.0 // indirect
|
||||||
|
golang.org/x/term v0.37.0 // indirect
|
||||||
|
)
|
||||||
|
|
||||||
|
replace code.squareroundforest.org/arpio/wand => /Users/arpio/work/code/wand
|
||||||
20
internal/tests/tmpdir/W0w-rWwNmthjuerTOFnMIQ/go.sum
Normal file
20
internal/tests/tmpdir/W0w-rWwNmthjuerTOFnMIQ/go.sum
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
code.squareroundforest.org/arpio/bind v0.0.0-20251105181644-3443251be2d5 h1:SIgLIawD6Vv7rAvUobpVshLshdwFEJ0NOUrWpheS088=
|
||||||
|
code.squareroundforest.org/arpio/bind v0.0.0-20251105181644-3443251be2d5/go.mod h1:tTCmCwFABKNm3PO0Dclsp4zWhNQFTfg9+uSrgoarZFI=
|
||||||
|
code.squareroundforest.org/arpio/docreflect v0.0.0-20251031192707-01c5ff18fab1 h1:bJi41U5yGQykg6jVlD2AdWiznvx3Jg7ZpzEU85syOXw=
|
||||||
|
code.squareroundforest.org/arpio/docreflect v0.0.0-20251031192707-01c5ff18fab1/go.mod h1:/3xQI36oJG8qLBxT2fSS61P5/+i1T64fTX9GHRh8XhA=
|
||||||
|
code.squareroundforest.org/arpio/html v0.0.0-20251103020946-e262eca50ac9 h1:b7voJlwe0jKH568X+O7b/JTAUrHLTSKNSSL+hhV2Q/Q=
|
||||||
|
code.squareroundforest.org/arpio/html v0.0.0-20251103020946-e262eca50ac9/go.mod h1:hq+2CENEd4bVSZnOdq38FUFOJJnF3OTQRv78qMGkNlE=
|
||||||
|
code.squareroundforest.org/arpio/notation v0.0.0-20251101123932-5f5c05ee0239 h1:JvLVMuvF2laxXkIZbHC1/0xtKyKndAwIHbIIWkHqTzc=
|
||||||
|
code.squareroundforest.org/arpio/notation v0.0.0-20251101123932-5f5c05ee0239/go.mod h1:ait4Fvg9o0+bq5hlxi9dAcPL5a+/sr33qsZPNpToMLY=
|
||||||
|
code.squareroundforest.org/arpio/textedit v0.0.0-20251207224821-c75c3965789f h1:gomu8xTD953IkL3M528qVEuZ2z93C2I6Hr4vyIwE7kI=
|
||||||
|
code.squareroundforest.org/arpio/textedit v0.0.0-20251207224821-c75c3965789f/go.mod h1:nXdFdxdI69JrkIT97f+AEE4OgplmxbgNFZC5j7gsdqs=
|
||||||
|
code.squareroundforest.org/arpio/textfmt v0.0.0-20251207234108-fed32c8bbe18 h1:2aa62CYm9ld5SNoFxWzE2wUN0xjVWQ+xieoeFantdg4=
|
||||||
|
code.squareroundforest.org/arpio/textfmt v0.0.0-20251207234108-fed32c8bbe18/go.mod h1:+0G3gufMAP8SCEIrDT1D/DaVOSfjS8EwPTBs5vfxqQg=
|
||||||
|
code.squareroundforest.org/arpio/wand v0.0.0-20251210193110-60acf6e82022 h1:9XKwyrmOi2upsYWyjMQOPhO6ebl7AEHSViBVu9U/2jc=
|
||||||
|
code.squareroundforest.org/arpio/wand v0.0.0-20251210193110-60acf6e82022/go.mod h1:dwEF9zEIbOxbLxytOKSuRQPKmvbhPjDCJcoXM3j8cOU=
|
||||||
|
github.com/iancoleman/strcase v0.3.0 h1:nTXanmYxhfFAMjZL34Ov6gkzEsSJZ5DbhxWjvSASxEI=
|
||||||
|
github.com/iancoleman/strcase v0.3.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho=
|
||||||
|
golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc=
|
||||||
|
golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
||||||
|
golang.org/x/term v0.37.0 h1:8EGAD0qCmHYZg6J17DvsMy9/wJ7/D/4pV/wfnld5lTU=
|
||||||
|
golang.org/x/term v0.37.0/go.mod h1:5pB4lxRNYYVZuTLmy8oR2BH8dflOR+IbTYFD8fi3254=
|
||||||
@ -0,0 +1,6 @@
|
|||||||
|
package main
|
||||||
|
import "fmt"
|
||||||
|
import "code.squareroundforest.org/arpio/wand"
|
||||||
|
func main() {
|
||||||
|
wand.Exec(fmt.Println)
|
||||||
|
}
|
||||||
18
internal/tests/tmpdir/c128RsAggPny5Yt3rXQnjA/go.mod
Normal file
18
internal/tests/tmpdir/c128RsAggPny5Yt3rXQnjA/go.mod
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
module c128RsAggPny5Yt3rXQnjA
|
||||||
|
|
||||||
|
go 1.25.4
|
||||||
|
|
||||||
|
require (
|
||||||
|
code.squareroundforest.org/arpio/bind v0.0.0-20251105181644-3443251be2d5 // indirect
|
||||||
|
code.squareroundforest.org/arpio/docreflect v0.0.0-20251031192707-01c5ff18fab1 // indirect
|
||||||
|
code.squareroundforest.org/arpio/html v0.0.0-20251103020946-e262eca50ac9 // indirect
|
||||||
|
code.squareroundforest.org/arpio/notation v0.0.0-20251101123932-5f5c05ee0239 // indirect
|
||||||
|
code.squareroundforest.org/arpio/textedit v0.0.0-20251207224821-c75c3965789f // indirect
|
||||||
|
code.squareroundforest.org/arpio/textfmt v0.0.0-20251207234108-fed32c8bbe18 // indirect
|
||||||
|
code.squareroundforest.org/arpio/wand v0.0.0-20251210193110-60acf6e82022 // indirect
|
||||||
|
github.com/iancoleman/strcase v0.3.0 // indirect
|
||||||
|
golang.org/x/sys v0.38.0 // indirect
|
||||||
|
golang.org/x/term v0.37.0 // indirect
|
||||||
|
)
|
||||||
|
|
||||||
|
replace code.squareroundforest.org/arpio/wand => /Users/arpio/work/code/wand
|
||||||
20
internal/tests/tmpdir/c128RsAggPny5Yt3rXQnjA/go.sum
Normal file
20
internal/tests/tmpdir/c128RsAggPny5Yt3rXQnjA/go.sum
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
code.squareroundforest.org/arpio/bind v0.0.0-20251105181644-3443251be2d5 h1:SIgLIawD6Vv7rAvUobpVshLshdwFEJ0NOUrWpheS088=
|
||||||
|
code.squareroundforest.org/arpio/bind v0.0.0-20251105181644-3443251be2d5/go.mod h1:tTCmCwFABKNm3PO0Dclsp4zWhNQFTfg9+uSrgoarZFI=
|
||||||
|
code.squareroundforest.org/arpio/docreflect v0.0.0-20251031192707-01c5ff18fab1 h1:bJi41U5yGQykg6jVlD2AdWiznvx3Jg7ZpzEU85syOXw=
|
||||||
|
code.squareroundforest.org/arpio/docreflect v0.0.0-20251031192707-01c5ff18fab1/go.mod h1:/3xQI36oJG8qLBxT2fSS61P5/+i1T64fTX9GHRh8XhA=
|
||||||
|
code.squareroundforest.org/arpio/html v0.0.0-20251103020946-e262eca50ac9 h1:b7voJlwe0jKH568X+O7b/JTAUrHLTSKNSSL+hhV2Q/Q=
|
||||||
|
code.squareroundforest.org/arpio/html v0.0.0-20251103020946-e262eca50ac9/go.mod h1:hq+2CENEd4bVSZnOdq38FUFOJJnF3OTQRv78qMGkNlE=
|
||||||
|
code.squareroundforest.org/arpio/notation v0.0.0-20251101123932-5f5c05ee0239 h1:JvLVMuvF2laxXkIZbHC1/0xtKyKndAwIHbIIWkHqTzc=
|
||||||
|
code.squareroundforest.org/arpio/notation v0.0.0-20251101123932-5f5c05ee0239/go.mod h1:ait4Fvg9o0+bq5hlxi9dAcPL5a+/sr33qsZPNpToMLY=
|
||||||
|
code.squareroundforest.org/arpio/textedit v0.0.0-20251207224821-c75c3965789f h1:gomu8xTD953IkL3M528qVEuZ2z93C2I6Hr4vyIwE7kI=
|
||||||
|
code.squareroundforest.org/arpio/textedit v0.0.0-20251207224821-c75c3965789f/go.mod h1:nXdFdxdI69JrkIT97f+AEE4OgplmxbgNFZC5j7gsdqs=
|
||||||
|
code.squareroundforest.org/arpio/textfmt v0.0.0-20251207234108-fed32c8bbe18 h1:2aa62CYm9ld5SNoFxWzE2wUN0xjVWQ+xieoeFantdg4=
|
||||||
|
code.squareroundforest.org/arpio/textfmt v0.0.0-20251207234108-fed32c8bbe18/go.mod h1:+0G3gufMAP8SCEIrDT1D/DaVOSfjS8EwPTBs5vfxqQg=
|
||||||
|
code.squareroundforest.org/arpio/wand v0.0.0-20251210193110-60acf6e82022 h1:9XKwyrmOi2upsYWyjMQOPhO6ebl7AEHSViBVu9U/2jc=
|
||||||
|
code.squareroundforest.org/arpio/wand v0.0.0-20251210193110-60acf6e82022/go.mod h1:dwEF9zEIbOxbLxytOKSuRQPKmvbhPjDCJcoXM3j8cOU=
|
||||||
|
github.com/iancoleman/strcase v0.3.0 h1:nTXanmYxhfFAMjZL34Ov6gkzEsSJZ5DbhxWjvSASxEI=
|
||||||
|
github.com/iancoleman/strcase v0.3.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho=
|
||||||
|
golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc=
|
||||||
|
golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
||||||
|
golang.org/x/term v0.37.0 h1:8EGAD0qCmHYZg6J17DvsMy9/wJ7/D/4pV/wfnld5lTU=
|
||||||
|
golang.org/x/term v0.37.0/go.mod h1:5pB4lxRNYYVZuTLmy8oR2BH8dflOR+IbTYFD8fi3254=
|
||||||
@ -0,0 +1,6 @@
|
|||||||
|
package main
|
||||||
|
import . "strings"
|
||||||
|
import "code.squareroundforest.org/arpio/wand"
|
||||||
|
func main() {
|
||||||
|
wand.Exec(Split)
|
||||||
|
}
|
||||||
18
internal/tests/tmpdir/djTBWFYLXSZapqVl11Wnpg/go.mod
Normal file
18
internal/tests/tmpdir/djTBWFYLXSZapqVl11Wnpg/go.mod
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
module djTBWFYLXSZapqVl11Wnpg
|
||||||
|
|
||||||
|
go 1.25.4
|
||||||
|
|
||||||
|
require (
|
||||||
|
code.squareroundforest.org/arpio/bind v0.0.0-20251105181644-3443251be2d5 // indirect
|
||||||
|
code.squareroundforest.org/arpio/docreflect v0.0.0-20251031192707-01c5ff18fab1 // indirect
|
||||||
|
code.squareroundforest.org/arpio/html v0.0.0-20251103020946-e262eca50ac9 // indirect
|
||||||
|
code.squareroundforest.org/arpio/notation v0.0.0-20251101123932-5f5c05ee0239 // indirect
|
||||||
|
code.squareroundforest.org/arpio/textedit v0.0.0-20251207224821-c75c3965789f // indirect
|
||||||
|
code.squareroundforest.org/arpio/textfmt v0.0.0-20251207234108-fed32c8bbe18 // indirect
|
||||||
|
code.squareroundforest.org/arpio/wand v0.0.0-20251210193110-60acf6e82022 // indirect
|
||||||
|
github.com/iancoleman/strcase v0.3.0 // indirect
|
||||||
|
golang.org/x/sys v0.38.0 // indirect
|
||||||
|
golang.org/x/term v0.37.0 // indirect
|
||||||
|
)
|
||||||
|
|
||||||
|
replace code.squareroundforest.org/arpio/wand => /Users/arpio/work/code/wand
|
||||||
20
internal/tests/tmpdir/djTBWFYLXSZapqVl11Wnpg/go.sum
Normal file
20
internal/tests/tmpdir/djTBWFYLXSZapqVl11Wnpg/go.sum
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
code.squareroundforest.org/arpio/bind v0.0.0-20251105181644-3443251be2d5 h1:SIgLIawD6Vv7rAvUobpVshLshdwFEJ0NOUrWpheS088=
|
||||||
|
code.squareroundforest.org/arpio/bind v0.0.0-20251105181644-3443251be2d5/go.mod h1:tTCmCwFABKNm3PO0Dclsp4zWhNQFTfg9+uSrgoarZFI=
|
||||||
|
code.squareroundforest.org/arpio/docreflect v0.0.0-20251031192707-01c5ff18fab1 h1:bJi41U5yGQykg6jVlD2AdWiznvx3Jg7ZpzEU85syOXw=
|
||||||
|
code.squareroundforest.org/arpio/docreflect v0.0.0-20251031192707-01c5ff18fab1/go.mod h1:/3xQI36oJG8qLBxT2fSS61P5/+i1T64fTX9GHRh8XhA=
|
||||||
|
code.squareroundforest.org/arpio/html v0.0.0-20251103020946-e262eca50ac9 h1:b7voJlwe0jKH568X+O7b/JTAUrHLTSKNSSL+hhV2Q/Q=
|
||||||
|
code.squareroundforest.org/arpio/html v0.0.0-20251103020946-e262eca50ac9/go.mod h1:hq+2CENEd4bVSZnOdq38FUFOJJnF3OTQRv78qMGkNlE=
|
||||||
|
code.squareroundforest.org/arpio/notation v0.0.0-20251101123932-5f5c05ee0239 h1:JvLVMuvF2laxXkIZbHC1/0xtKyKndAwIHbIIWkHqTzc=
|
||||||
|
code.squareroundforest.org/arpio/notation v0.0.0-20251101123932-5f5c05ee0239/go.mod h1:ait4Fvg9o0+bq5hlxi9dAcPL5a+/sr33qsZPNpToMLY=
|
||||||
|
code.squareroundforest.org/arpio/textedit v0.0.0-20251207224821-c75c3965789f h1:gomu8xTD953IkL3M528qVEuZ2z93C2I6Hr4vyIwE7kI=
|
||||||
|
code.squareroundforest.org/arpio/textedit v0.0.0-20251207224821-c75c3965789f/go.mod h1:nXdFdxdI69JrkIT97f+AEE4OgplmxbgNFZC5j7gsdqs=
|
||||||
|
code.squareroundforest.org/arpio/textfmt v0.0.0-20251207234108-fed32c8bbe18 h1:2aa62CYm9ld5SNoFxWzE2wUN0xjVWQ+xieoeFantdg4=
|
||||||
|
code.squareroundforest.org/arpio/textfmt v0.0.0-20251207234108-fed32c8bbe18/go.mod h1:+0G3gufMAP8SCEIrDT1D/DaVOSfjS8EwPTBs5vfxqQg=
|
||||||
|
code.squareroundforest.org/arpio/wand v0.0.0-20251210193110-60acf6e82022 h1:9XKwyrmOi2upsYWyjMQOPhO6ebl7AEHSViBVu9U/2jc=
|
||||||
|
code.squareroundforest.org/arpio/wand v0.0.0-20251210193110-60acf6e82022/go.mod h1:dwEF9zEIbOxbLxytOKSuRQPKmvbhPjDCJcoXM3j8cOU=
|
||||||
|
github.com/iancoleman/strcase v0.3.0 h1:nTXanmYxhfFAMjZL34Ov6gkzEsSJZ5DbhxWjvSASxEI=
|
||||||
|
github.com/iancoleman/strcase v0.3.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho=
|
||||||
|
golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc=
|
||||||
|
golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
||||||
|
golang.org/x/term v0.37.0 h1:8EGAD0qCmHYZg6J17DvsMy9/wJ7/D/4pV/wfnld5lTU=
|
||||||
|
golang.org/x/term v0.37.0/go.mod h1:5pB4lxRNYYVZuTLmy8oR2BH8dflOR+IbTYFD8fi3254=
|
||||||
@ -0,0 +1,6 @@
|
|||||||
|
package main
|
||||||
|
import str "strings"
|
||||||
|
import "code.squareroundforest.org/arpio/wand"
|
||||||
|
func main() {
|
||||||
|
wand.Exec(str.Split)
|
||||||
|
}
|
||||||
18
internal/tests/tmpdir/fbneVWE281vn9cQJ87O0vA/go.mod
Normal file
18
internal/tests/tmpdir/fbneVWE281vn9cQJ87O0vA/go.mod
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
module fbneVWE281vn9cQJ87O0vA
|
||||||
|
|
||||||
|
go 1.25.4
|
||||||
|
|
||||||
|
require (
|
||||||
|
code.squareroundforest.org/arpio/bind v0.0.0-20251105181644-3443251be2d5 // indirect
|
||||||
|
code.squareroundforest.org/arpio/docreflect v0.0.0-20251031192707-01c5ff18fab1 // indirect
|
||||||
|
code.squareroundforest.org/arpio/html v0.0.0-20251103020946-e262eca50ac9 // indirect
|
||||||
|
code.squareroundforest.org/arpio/notation v0.0.0-20251101123932-5f5c05ee0239 // indirect
|
||||||
|
code.squareroundforest.org/arpio/textedit v0.0.0-20251207224821-c75c3965789f // indirect
|
||||||
|
code.squareroundforest.org/arpio/textfmt v0.0.0-20251207234108-fed32c8bbe18 // indirect
|
||||||
|
code.squareroundforest.org/arpio/wand v0.0.0-20251210193110-60acf6e82022 // indirect
|
||||||
|
github.com/iancoleman/strcase v0.3.0 // indirect
|
||||||
|
golang.org/x/sys v0.38.0 // indirect
|
||||||
|
golang.org/x/term v0.37.0 // indirect
|
||||||
|
)
|
||||||
|
|
||||||
|
replace code.squareroundforest.org/arpio/wand => /Users/arpio/work/code/wand
|
||||||
20
internal/tests/tmpdir/fbneVWE281vn9cQJ87O0vA/go.sum
Normal file
20
internal/tests/tmpdir/fbneVWE281vn9cQJ87O0vA/go.sum
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
code.squareroundforest.org/arpio/bind v0.0.0-20251105181644-3443251be2d5 h1:SIgLIawD6Vv7rAvUobpVshLshdwFEJ0NOUrWpheS088=
|
||||||
|
code.squareroundforest.org/arpio/bind v0.0.0-20251105181644-3443251be2d5/go.mod h1:tTCmCwFABKNm3PO0Dclsp4zWhNQFTfg9+uSrgoarZFI=
|
||||||
|
code.squareroundforest.org/arpio/docreflect v0.0.0-20251031192707-01c5ff18fab1 h1:bJi41U5yGQykg6jVlD2AdWiznvx3Jg7ZpzEU85syOXw=
|
||||||
|
code.squareroundforest.org/arpio/docreflect v0.0.0-20251031192707-01c5ff18fab1/go.mod h1:/3xQI36oJG8qLBxT2fSS61P5/+i1T64fTX9GHRh8XhA=
|
||||||
|
code.squareroundforest.org/arpio/html v0.0.0-20251103020946-e262eca50ac9 h1:b7voJlwe0jKH568X+O7b/JTAUrHLTSKNSSL+hhV2Q/Q=
|
||||||
|
code.squareroundforest.org/arpio/html v0.0.0-20251103020946-e262eca50ac9/go.mod h1:hq+2CENEd4bVSZnOdq38FUFOJJnF3OTQRv78qMGkNlE=
|
||||||
|
code.squareroundforest.org/arpio/notation v0.0.0-20251101123932-5f5c05ee0239 h1:JvLVMuvF2laxXkIZbHC1/0xtKyKndAwIHbIIWkHqTzc=
|
||||||
|
code.squareroundforest.org/arpio/notation v0.0.0-20251101123932-5f5c05ee0239/go.mod h1:ait4Fvg9o0+bq5hlxi9dAcPL5a+/sr33qsZPNpToMLY=
|
||||||
|
code.squareroundforest.org/arpio/textedit v0.0.0-20251207224821-c75c3965789f h1:gomu8xTD953IkL3M528qVEuZ2z93C2I6Hr4vyIwE7kI=
|
||||||
|
code.squareroundforest.org/arpio/textedit v0.0.0-20251207224821-c75c3965789f/go.mod h1:nXdFdxdI69JrkIT97f+AEE4OgplmxbgNFZC5j7gsdqs=
|
||||||
|
code.squareroundforest.org/arpio/textfmt v0.0.0-20251207234108-fed32c8bbe18 h1:2aa62CYm9ld5SNoFxWzE2wUN0xjVWQ+xieoeFantdg4=
|
||||||
|
code.squareroundforest.org/arpio/textfmt v0.0.0-20251207234108-fed32c8bbe18/go.mod h1:+0G3gufMAP8SCEIrDT1D/DaVOSfjS8EwPTBs5vfxqQg=
|
||||||
|
code.squareroundforest.org/arpio/wand v0.0.0-20251210193110-60acf6e82022 h1:9XKwyrmOi2upsYWyjMQOPhO6ebl7AEHSViBVu9U/2jc=
|
||||||
|
code.squareroundforest.org/arpio/wand v0.0.0-20251210193110-60acf6e82022/go.mod h1:dwEF9zEIbOxbLxytOKSuRQPKmvbhPjDCJcoXM3j8cOU=
|
||||||
|
github.com/iancoleman/strcase v0.3.0 h1:nTXanmYxhfFAMjZL34Ov6gkzEsSJZ5DbhxWjvSASxEI=
|
||||||
|
github.com/iancoleman/strcase v0.3.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho=
|
||||||
|
golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc=
|
||||||
|
golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
||||||
|
golang.org/x/term v0.37.0 h1:8EGAD0qCmHYZg6J17DvsMy9/wJ7/D/4pV/wfnld5lTU=
|
||||||
|
golang.org/x/term v0.37.0/go.mod h1:5pB4lxRNYYVZuTLmy8oR2BH8dflOR+IbTYFD8fi3254=
|
||||||
18
internal/tests/tmpdir/k_vqGB1P94wR5O4M7XiD4A/go.mod
Normal file
18
internal/tests/tmpdir/k_vqGB1P94wR5O4M7XiD4A/go.mod
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
module k_vqGB1P94wR5O4M7XiD4A
|
||||||
|
|
||||||
|
go 1.25.4
|
||||||
|
|
||||||
|
require (
|
||||||
|
code.squareroundforest.org/arpio/bind v0.0.0-20251105181644-3443251be2d5 // indirect
|
||||||
|
code.squareroundforest.org/arpio/docreflect v0.0.0-20251031192707-01c5ff18fab1 // indirect
|
||||||
|
code.squareroundforest.org/arpio/html v0.0.0-20251103020946-e262eca50ac9 // indirect
|
||||||
|
code.squareroundforest.org/arpio/notation v0.0.0-20251101123932-5f5c05ee0239 // indirect
|
||||||
|
code.squareroundforest.org/arpio/textedit v0.0.0-20251207224821-c75c3965789f // indirect
|
||||||
|
code.squareroundforest.org/arpio/textfmt v0.0.0-20251207234108-fed32c8bbe18 // indirect
|
||||||
|
code.squareroundforest.org/arpio/wand v0.0.0-20251210193110-60acf6e82022 // indirect
|
||||||
|
github.com/iancoleman/strcase v0.3.0 // indirect
|
||||||
|
golang.org/x/sys v0.38.0 // indirect
|
||||||
|
golang.org/x/term v0.37.0 // indirect
|
||||||
|
)
|
||||||
|
|
||||||
|
replace code.squareroundforest.org/arpio/wand => /Users/arpio/work/code/wand
|
||||||
20
internal/tests/tmpdir/k_vqGB1P94wR5O4M7XiD4A/go.sum
Normal file
20
internal/tests/tmpdir/k_vqGB1P94wR5O4M7XiD4A/go.sum
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
code.squareroundforest.org/arpio/bind v0.0.0-20251105181644-3443251be2d5 h1:SIgLIawD6Vv7rAvUobpVshLshdwFEJ0NOUrWpheS088=
|
||||||
|
code.squareroundforest.org/arpio/bind v0.0.0-20251105181644-3443251be2d5/go.mod h1:tTCmCwFABKNm3PO0Dclsp4zWhNQFTfg9+uSrgoarZFI=
|
||||||
|
code.squareroundforest.org/arpio/docreflect v0.0.0-20251031192707-01c5ff18fab1 h1:bJi41U5yGQykg6jVlD2AdWiznvx3Jg7ZpzEU85syOXw=
|
||||||
|
code.squareroundforest.org/arpio/docreflect v0.0.0-20251031192707-01c5ff18fab1/go.mod h1:/3xQI36oJG8qLBxT2fSS61P5/+i1T64fTX9GHRh8XhA=
|
||||||
|
code.squareroundforest.org/arpio/html v0.0.0-20251103020946-e262eca50ac9 h1:b7voJlwe0jKH568X+O7b/JTAUrHLTSKNSSL+hhV2Q/Q=
|
||||||
|
code.squareroundforest.org/arpio/html v0.0.0-20251103020946-e262eca50ac9/go.mod h1:hq+2CENEd4bVSZnOdq38FUFOJJnF3OTQRv78qMGkNlE=
|
||||||
|
code.squareroundforest.org/arpio/notation v0.0.0-20251101123932-5f5c05ee0239 h1:JvLVMuvF2laxXkIZbHC1/0xtKyKndAwIHbIIWkHqTzc=
|
||||||
|
code.squareroundforest.org/arpio/notation v0.0.0-20251101123932-5f5c05ee0239/go.mod h1:ait4Fvg9o0+bq5hlxi9dAcPL5a+/sr33qsZPNpToMLY=
|
||||||
|
code.squareroundforest.org/arpio/textedit v0.0.0-20251207224821-c75c3965789f h1:gomu8xTD953IkL3M528qVEuZ2z93C2I6Hr4vyIwE7kI=
|
||||||
|
code.squareroundforest.org/arpio/textedit v0.0.0-20251207224821-c75c3965789f/go.mod h1:nXdFdxdI69JrkIT97f+AEE4OgplmxbgNFZC5j7gsdqs=
|
||||||
|
code.squareroundforest.org/arpio/textfmt v0.0.0-20251207234108-fed32c8bbe18 h1:2aa62CYm9ld5SNoFxWzE2wUN0xjVWQ+xieoeFantdg4=
|
||||||
|
code.squareroundforest.org/arpio/textfmt v0.0.0-20251207234108-fed32c8bbe18/go.mod h1:+0G3gufMAP8SCEIrDT1D/DaVOSfjS8EwPTBs5vfxqQg=
|
||||||
|
code.squareroundforest.org/arpio/wand v0.0.0-20251210193110-60acf6e82022 h1:9XKwyrmOi2upsYWyjMQOPhO6ebl7AEHSViBVu9U/2jc=
|
||||||
|
code.squareroundforest.org/arpio/wand v0.0.0-20251210193110-60acf6e82022/go.mod h1:dwEF9zEIbOxbLxytOKSuRQPKmvbhPjDCJcoXM3j8cOU=
|
||||||
|
github.com/iancoleman/strcase v0.3.0 h1:nTXanmYxhfFAMjZL34Ov6gkzEsSJZ5DbhxWjvSASxEI=
|
||||||
|
github.com/iancoleman/strcase v0.3.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho=
|
||||||
|
golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc=
|
||||||
|
golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
||||||
|
golang.org/x/term v0.37.0 h1:8EGAD0qCmHYZg6J17DvsMy9/wJ7/D/4pV/wfnld5lTU=
|
||||||
|
golang.org/x/term v0.37.0/go.mod h1:5pB4lxRNYYVZuTLmy8oR2BH8dflOR+IbTYFD8fi3254=
|
||||||
@ -0,0 +1,5 @@
|
|||||||
|
package main
|
||||||
|
import "code.squareroundforest.org/arpio/wand"
|
||||||
|
func main() {
|
||||||
|
wand.Exec(println)
|
||||||
|
}
|
||||||
18
internal/tests/tmpdir/pPXRXBwDsfnuJDBB1hbG7w/go.mod
Normal file
18
internal/tests/tmpdir/pPXRXBwDsfnuJDBB1hbG7w/go.mod
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
module pPXRXBwDsfnuJDBB1hbG7w
|
||||||
|
|
||||||
|
go 1.25.4
|
||||||
|
|
||||||
|
require (
|
||||||
|
code.squareroundforest.org/arpio/bind v0.0.0-20251105181644-3443251be2d5 // indirect
|
||||||
|
code.squareroundforest.org/arpio/docreflect v0.0.0-20251031192707-01c5ff18fab1 // indirect
|
||||||
|
code.squareroundforest.org/arpio/html v0.0.0-20251103020946-e262eca50ac9 // indirect
|
||||||
|
code.squareroundforest.org/arpio/notation v0.0.0-20251101123932-5f5c05ee0239 // indirect
|
||||||
|
code.squareroundforest.org/arpio/textedit v0.0.0-20251207224821-c75c3965789f // indirect
|
||||||
|
code.squareroundforest.org/arpio/textfmt v0.0.0-20251207234108-fed32c8bbe18 // indirect
|
||||||
|
code.squareroundforest.org/arpio/wand v0.0.0-20251210193110-60acf6e82022 // indirect
|
||||||
|
github.com/iancoleman/strcase v0.3.0 // indirect
|
||||||
|
golang.org/x/sys v0.38.0 // indirect
|
||||||
|
golang.org/x/term v0.37.0 // indirect
|
||||||
|
)
|
||||||
|
|
||||||
|
replace code.squareroundforest.org/arpio/wand => /Users/arpio/work/code/wand
|
||||||
20
internal/tests/tmpdir/pPXRXBwDsfnuJDBB1hbG7w/go.sum
Normal file
20
internal/tests/tmpdir/pPXRXBwDsfnuJDBB1hbG7w/go.sum
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
code.squareroundforest.org/arpio/bind v0.0.0-20251105181644-3443251be2d5 h1:SIgLIawD6Vv7rAvUobpVshLshdwFEJ0NOUrWpheS088=
|
||||||
|
code.squareroundforest.org/arpio/bind v0.0.0-20251105181644-3443251be2d5/go.mod h1:tTCmCwFABKNm3PO0Dclsp4zWhNQFTfg9+uSrgoarZFI=
|
||||||
|
code.squareroundforest.org/arpio/docreflect v0.0.0-20251031192707-01c5ff18fab1 h1:bJi41U5yGQykg6jVlD2AdWiznvx3Jg7ZpzEU85syOXw=
|
||||||
|
code.squareroundforest.org/arpio/docreflect v0.0.0-20251031192707-01c5ff18fab1/go.mod h1:/3xQI36oJG8qLBxT2fSS61P5/+i1T64fTX9GHRh8XhA=
|
||||||
|
code.squareroundforest.org/arpio/html v0.0.0-20251103020946-e262eca50ac9 h1:b7voJlwe0jKH568X+O7b/JTAUrHLTSKNSSL+hhV2Q/Q=
|
||||||
|
code.squareroundforest.org/arpio/html v0.0.0-20251103020946-e262eca50ac9/go.mod h1:hq+2CENEd4bVSZnOdq38FUFOJJnF3OTQRv78qMGkNlE=
|
||||||
|
code.squareroundforest.org/arpio/notation v0.0.0-20251101123932-5f5c05ee0239 h1:JvLVMuvF2laxXkIZbHC1/0xtKyKndAwIHbIIWkHqTzc=
|
||||||
|
code.squareroundforest.org/arpio/notation v0.0.0-20251101123932-5f5c05ee0239/go.mod h1:ait4Fvg9o0+bq5hlxi9dAcPL5a+/sr33qsZPNpToMLY=
|
||||||
|
code.squareroundforest.org/arpio/textedit v0.0.0-20251207224821-c75c3965789f h1:gomu8xTD953IkL3M528qVEuZ2z93C2I6Hr4vyIwE7kI=
|
||||||
|
code.squareroundforest.org/arpio/textedit v0.0.0-20251207224821-c75c3965789f/go.mod h1:nXdFdxdI69JrkIT97f+AEE4OgplmxbgNFZC5j7gsdqs=
|
||||||
|
code.squareroundforest.org/arpio/textfmt v0.0.0-20251207234108-fed32c8bbe18 h1:2aa62CYm9ld5SNoFxWzE2wUN0xjVWQ+xieoeFantdg4=
|
||||||
|
code.squareroundforest.org/arpio/textfmt v0.0.0-20251207234108-fed32c8bbe18/go.mod h1:+0G3gufMAP8SCEIrDT1D/DaVOSfjS8EwPTBs5vfxqQg=
|
||||||
|
code.squareroundforest.org/arpio/wand v0.0.0-20251210193110-60acf6e82022 h1:9XKwyrmOi2upsYWyjMQOPhO6ebl7AEHSViBVu9U/2jc=
|
||||||
|
code.squareroundforest.org/arpio/wand v0.0.0-20251210193110-60acf6e82022/go.mod h1:dwEF9zEIbOxbLxytOKSuRQPKmvbhPjDCJcoXM3j8cOU=
|
||||||
|
github.com/iancoleman/strcase v0.3.0 h1:nTXanmYxhfFAMjZL34Ov6gkzEsSJZ5DbhxWjvSASxEI=
|
||||||
|
github.com/iancoleman/strcase v0.3.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho=
|
||||||
|
golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc=
|
||||||
|
golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
||||||
|
golang.org/x/term v0.37.0 h1:8EGAD0qCmHYZg6J17DvsMy9/wJ7/D/4pV/wfnld5lTU=
|
||||||
|
golang.org/x/term v0.37.0/go.mod h1:5pB4lxRNYYVZuTLmy8oR2BH8dflOR+IbTYFD8fi3254=
|
||||||
@ -0,0 +1,6 @@
|
|||||||
|
package main
|
||||||
|
import "fmt"
|
||||||
|
import "code.squareroundforest.org/arpio/wand"
|
||||||
|
func main() {
|
||||||
|
wand.Exec(func(a)
|
||||||
|
}
|
||||||
18
internal/tests/tmpdir/qo6bOwdhYFcgh80Jx-WTyg/go.mod
Normal file
18
internal/tests/tmpdir/qo6bOwdhYFcgh80Jx-WTyg/go.mod
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
module qo6bOwdhYFcgh80Jx-WTyg
|
||||||
|
|
||||||
|
go 1.25.4
|
||||||
|
|
||||||
|
require (
|
||||||
|
code.squareroundforest.org/arpio/bind v0.0.0-20251105181644-3443251be2d5 // indirect
|
||||||
|
code.squareroundforest.org/arpio/docreflect v0.0.0-20251031192707-01c5ff18fab1 // indirect
|
||||||
|
code.squareroundforest.org/arpio/html v0.0.0-20251103020946-e262eca50ac9 // indirect
|
||||||
|
code.squareroundforest.org/arpio/notation v0.0.0-20251101123932-5f5c05ee0239 // indirect
|
||||||
|
code.squareroundforest.org/arpio/textedit v0.0.0-20251207224821-c75c3965789f // indirect
|
||||||
|
code.squareroundforest.org/arpio/textfmt v0.0.0-20251207234108-fed32c8bbe18 // indirect
|
||||||
|
code.squareroundforest.org/arpio/wand v0.0.0-20251210193110-60acf6e82022 // indirect
|
||||||
|
github.com/iancoleman/strcase v0.3.0 // indirect
|
||||||
|
golang.org/x/sys v0.38.0 // indirect
|
||||||
|
golang.org/x/term v0.37.0 // indirect
|
||||||
|
)
|
||||||
|
|
||||||
|
replace code.squareroundforest.org/arpio/wand => /Users/arpio/work/code/wand
|
||||||
20
internal/tests/tmpdir/qo6bOwdhYFcgh80Jx-WTyg/go.sum
Normal file
20
internal/tests/tmpdir/qo6bOwdhYFcgh80Jx-WTyg/go.sum
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
code.squareroundforest.org/arpio/bind v0.0.0-20251105181644-3443251be2d5 h1:SIgLIawD6Vv7rAvUobpVshLshdwFEJ0NOUrWpheS088=
|
||||||
|
code.squareroundforest.org/arpio/bind v0.0.0-20251105181644-3443251be2d5/go.mod h1:tTCmCwFABKNm3PO0Dclsp4zWhNQFTfg9+uSrgoarZFI=
|
||||||
|
code.squareroundforest.org/arpio/docreflect v0.0.0-20251031192707-01c5ff18fab1 h1:bJi41U5yGQykg6jVlD2AdWiznvx3Jg7ZpzEU85syOXw=
|
||||||
|
code.squareroundforest.org/arpio/docreflect v0.0.0-20251031192707-01c5ff18fab1/go.mod h1:/3xQI36oJG8qLBxT2fSS61P5/+i1T64fTX9GHRh8XhA=
|
||||||
|
code.squareroundforest.org/arpio/html v0.0.0-20251103020946-e262eca50ac9 h1:b7voJlwe0jKH568X+O7b/JTAUrHLTSKNSSL+hhV2Q/Q=
|
||||||
|
code.squareroundforest.org/arpio/html v0.0.0-20251103020946-e262eca50ac9/go.mod h1:hq+2CENEd4bVSZnOdq38FUFOJJnF3OTQRv78qMGkNlE=
|
||||||
|
code.squareroundforest.org/arpio/notation v0.0.0-20251101123932-5f5c05ee0239 h1:JvLVMuvF2laxXkIZbHC1/0xtKyKndAwIHbIIWkHqTzc=
|
||||||
|
code.squareroundforest.org/arpio/notation v0.0.0-20251101123932-5f5c05ee0239/go.mod h1:ait4Fvg9o0+bq5hlxi9dAcPL5a+/sr33qsZPNpToMLY=
|
||||||
|
code.squareroundforest.org/arpio/textedit v0.0.0-20251207224821-c75c3965789f h1:gomu8xTD953IkL3M528qVEuZ2z93C2I6Hr4vyIwE7kI=
|
||||||
|
code.squareroundforest.org/arpio/textedit v0.0.0-20251207224821-c75c3965789f/go.mod h1:nXdFdxdI69JrkIT97f+AEE4OgplmxbgNFZC5j7gsdqs=
|
||||||
|
code.squareroundforest.org/arpio/textfmt v0.0.0-20251207234108-fed32c8bbe18 h1:2aa62CYm9ld5SNoFxWzE2wUN0xjVWQ+xieoeFantdg4=
|
||||||
|
code.squareroundforest.org/arpio/textfmt v0.0.0-20251207234108-fed32c8bbe18/go.mod h1:+0G3gufMAP8SCEIrDT1D/DaVOSfjS8EwPTBs5vfxqQg=
|
||||||
|
code.squareroundforest.org/arpio/wand v0.0.0-20251210193110-60acf6e82022 h1:9XKwyrmOi2upsYWyjMQOPhO6ebl7AEHSViBVu9U/2jc=
|
||||||
|
code.squareroundforest.org/arpio/wand v0.0.0-20251210193110-60acf6e82022/go.mod h1:dwEF9zEIbOxbLxytOKSuRQPKmvbhPjDCJcoXM3j8cOU=
|
||||||
|
github.com/iancoleman/strcase v0.3.0 h1:nTXanmYxhfFAMjZL34Ov6gkzEsSJZ5DbhxWjvSASxEI=
|
||||||
|
github.com/iancoleman/strcase v0.3.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho=
|
||||||
|
golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc=
|
||||||
|
golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
||||||
|
golang.org/x/term v0.37.0 h1:8EGAD0qCmHYZg6J17DvsMy9/wJ7/D/4pV/wfnld5lTU=
|
||||||
|
golang.org/x/term v0.37.0/go.mod h1:5pB4lxRNYYVZuTLmy8oR2BH8dflOR+IbTYFD8fi3254=
|
||||||
@ -0,0 +1,23 @@
|
|||||||
|
package main
|
||||||
|
import "bytes"
|
||||||
|
import "io"
|
||||||
|
import "code.squareroundforest.org/arpio/wand"
|
||||||
|
func main() {
|
||||||
|
wand.Exec(func(in io.Reader) (out io.Reader) {
|
||||||
|
out = bytes.NewBuffer(nil)
|
||||||
|
buf := make([]byte, 1)
|
||||||
|
for {
|
||||||
|
n, err := in.Read(buf)
|
||||||
|
if n == 1 {
|
||||||
|
buf[0] = buf[0] * 2
|
||||||
|
out.(io.Writer).Write(buf)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return out
|
||||||
|
})
|
||||||
|
}
|
||||||
18
internal/tests/tmpdir/wtqcAdcxZGXt7vrbvOkxAw/go.mod
Normal file
18
internal/tests/tmpdir/wtqcAdcxZGXt7vrbvOkxAw/go.mod
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
module wtqcAdcxZGXt7vrbvOkxAw
|
||||||
|
|
||||||
|
go 1.25.4
|
||||||
|
|
||||||
|
require (
|
||||||
|
code.squareroundforest.org/arpio/bind v0.0.0-20251105181644-3443251be2d5 // indirect
|
||||||
|
code.squareroundforest.org/arpio/docreflect v0.0.0-20251031192707-01c5ff18fab1 // indirect
|
||||||
|
code.squareroundforest.org/arpio/html v0.0.0-20251103020946-e262eca50ac9 // indirect
|
||||||
|
code.squareroundforest.org/arpio/notation v0.0.0-20251101123932-5f5c05ee0239 // indirect
|
||||||
|
code.squareroundforest.org/arpio/textedit v0.0.0-20251207224821-c75c3965789f // indirect
|
||||||
|
code.squareroundforest.org/arpio/textfmt v0.0.0-20251207234108-fed32c8bbe18 // indirect
|
||||||
|
code.squareroundforest.org/arpio/wand v0.0.0-20251210193110-60acf6e82022 // indirect
|
||||||
|
github.com/iancoleman/strcase v0.3.0 // indirect
|
||||||
|
golang.org/x/sys v0.38.0 // indirect
|
||||||
|
golang.org/x/term v0.37.0 // indirect
|
||||||
|
)
|
||||||
|
|
||||||
|
replace code.squareroundforest.org/arpio/wand => /Users/arpio/work/code/wand
|
||||||
20
internal/tests/tmpdir/wtqcAdcxZGXt7vrbvOkxAw/go.sum
Normal file
20
internal/tests/tmpdir/wtqcAdcxZGXt7vrbvOkxAw/go.sum
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
code.squareroundforest.org/arpio/bind v0.0.0-20251105181644-3443251be2d5 h1:SIgLIawD6Vv7rAvUobpVshLshdwFEJ0NOUrWpheS088=
|
||||||
|
code.squareroundforest.org/arpio/bind v0.0.0-20251105181644-3443251be2d5/go.mod h1:tTCmCwFABKNm3PO0Dclsp4zWhNQFTfg9+uSrgoarZFI=
|
||||||
|
code.squareroundforest.org/arpio/docreflect v0.0.0-20251031192707-01c5ff18fab1 h1:bJi41U5yGQykg6jVlD2AdWiznvx3Jg7ZpzEU85syOXw=
|
||||||
|
code.squareroundforest.org/arpio/docreflect v0.0.0-20251031192707-01c5ff18fab1/go.mod h1:/3xQI36oJG8qLBxT2fSS61P5/+i1T64fTX9GHRh8XhA=
|
||||||
|
code.squareroundforest.org/arpio/html v0.0.0-20251103020946-e262eca50ac9 h1:b7voJlwe0jKH568X+O7b/JTAUrHLTSKNSSL+hhV2Q/Q=
|
||||||
|
code.squareroundforest.org/arpio/html v0.0.0-20251103020946-e262eca50ac9/go.mod h1:hq+2CENEd4bVSZnOdq38FUFOJJnF3OTQRv78qMGkNlE=
|
||||||
|
code.squareroundforest.org/arpio/notation v0.0.0-20251101123932-5f5c05ee0239 h1:JvLVMuvF2laxXkIZbHC1/0xtKyKndAwIHbIIWkHqTzc=
|
||||||
|
code.squareroundforest.org/arpio/notation v0.0.0-20251101123932-5f5c05ee0239/go.mod h1:ait4Fvg9o0+bq5hlxi9dAcPL5a+/sr33qsZPNpToMLY=
|
||||||
|
code.squareroundforest.org/arpio/textedit v0.0.0-20251207224821-c75c3965789f h1:gomu8xTD953IkL3M528qVEuZ2z93C2I6Hr4vyIwE7kI=
|
||||||
|
code.squareroundforest.org/arpio/textedit v0.0.0-20251207224821-c75c3965789f/go.mod h1:nXdFdxdI69JrkIT97f+AEE4OgplmxbgNFZC5j7gsdqs=
|
||||||
|
code.squareroundforest.org/arpio/textfmt v0.0.0-20251207234108-fed32c8bbe18 h1:2aa62CYm9ld5SNoFxWzE2wUN0xjVWQ+xieoeFantdg4=
|
||||||
|
code.squareroundforest.org/arpio/textfmt v0.0.0-20251207234108-fed32c8bbe18/go.mod h1:+0G3gufMAP8SCEIrDT1D/DaVOSfjS8EwPTBs5vfxqQg=
|
||||||
|
code.squareroundforest.org/arpio/wand v0.0.0-20251210193110-60acf6e82022 h1:9XKwyrmOi2upsYWyjMQOPhO6ebl7AEHSViBVu9U/2jc=
|
||||||
|
code.squareroundforest.org/arpio/wand v0.0.0-20251210193110-60acf6e82022/go.mod h1:dwEF9zEIbOxbLxytOKSuRQPKmvbhPjDCJcoXM3j8cOU=
|
||||||
|
github.com/iancoleman/strcase v0.3.0 h1:nTXanmYxhfFAMjZL34Ov6gkzEsSJZ5DbhxWjvSASxEI=
|
||||||
|
github.com/iancoleman/strcase v0.3.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho=
|
||||||
|
golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc=
|
||||||
|
golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
||||||
|
golang.org/x/term v0.37.0 h1:8EGAD0qCmHYZg6J17DvsMy9/wJ7/D/4pV/wfnld5lTU=
|
||||||
|
golang.org/x/term v0.37.0/go.mod h1:5pB4lxRNYYVZuTLmy8oR2BH8dflOR+IbTYFD8fi3254=
|
||||||
@ -0,0 +1,19 @@
|
|||||||
|
package main
|
||||||
|
import "io"
|
||||||
|
import "code.squareroundforest.org/arpio/wand"
|
||||||
|
func main() {
|
||||||
|
wand.Exec(func(in io.Reader) (out io.Reader) {
|
||||||
|
buf := make([]byte, 1)
|
||||||
|
for {
|
||||||
|
n, err := in.Read(buf)
|
||||||
|
if n == 1 {
|
||||||
|
buf[0] = buf[0] * 2
|
||||||
|
out.Write(buf)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
2
lib.go
2
lib.go
@ -53,7 +53,7 @@ func Args(cmd Cmd, min, max int) Cmd {
|
|||||||
|
|
||||||
func ShortForm(cmd Cmd, f ...string) Cmd {
|
func ShortForm(cmd Cmd, f ...string) Cmd {
|
||||||
if len(f)%2 != 0 {
|
if len(f)%2 != 0 {
|
||||||
f = append(f, "")
|
f = f[:len(f)-1]
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd.shortForms = append(cmd.shortForms, f...)
|
cmd.shortForms = append(cmd.shortForms, f...)
|
||||||
|
|||||||
15
lib_test.go
15
lib_test.go
@ -1 +1,16 @@
|
|||||||
package wand
|
package wand
|
||||||
|
|
||||||
|
import "testing"
|
||||||
|
|
||||||
|
func TestShortForm(t *testing.T) {
|
||||||
|
t.Run(
|
||||||
|
"undefined short form",
|
||||||
|
testExec(
|
||||||
|
testCase{
|
||||||
|
impl: ShortForm(Command("foo", func(struct{ Foo int }) {}), "f", "foo", "b"),
|
||||||
|
command: "foo -b",
|
||||||
|
},
|
||||||
|
"option not supported",
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|||||||
@ -115,15 +115,6 @@ func isTime(t reflect.Type) bool {
|
|||||||
return t.ConvertibleTo(reflect.TypeFor[time.Time]())
|
return t.ConvertibleTo(reflect.TypeFor[time.Time]())
|
||||||
}
|
}
|
||||||
|
|
||||||
func isDuration(t reflect.Type) bool {
|
|
||||||
if t == nil {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
t = unpackType(t)
|
|
||||||
return t == reflect.TypeFor[time.Duration]()
|
|
||||||
}
|
|
||||||
|
|
||||||
func isStruct(t reflect.Type) bool {
|
func isStruct(t reflect.Type) bool {
|
||||||
if t == nil {
|
if t == nil {
|
||||||
return false
|
return false
|
||||||
|
|||||||
@ -44,7 +44,3 @@ func execInternal(command string, args ...string) error {
|
|||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func execTransparent(command string, args ...string) error {
|
|
||||||
return execc(os.Stdin, os.Stdout, os.Stderr, command, args, nil)
|
|
||||||
}
|
|
||||||
|
|||||||
@ -15,12 +15,14 @@ import (
|
|||||||
"unicode"
|
"unicode"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const selfPkg = "code.squareroundforest.org/arpio/wand"
|
||||||
|
|
||||||
type ExecOptions struct {
|
type ExecOptions struct {
|
||||||
NoCache bool
|
NoCache bool
|
||||||
ClearCache bool
|
ClearCache bool
|
||||||
CacheDir string
|
CacheDir string
|
||||||
Import []string
|
Import []string
|
||||||
InlineImport []string
|
ReplaceModule []string
|
||||||
}
|
}
|
||||||
|
|
||||||
func commandReader(in io.Reader) func() ([]string, error) {
|
func commandReader(in io.Reader) func() ([]string, error) {
|
||||||
@ -84,12 +86,6 @@ func commandReader(in io.Reader) func() ([]string, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if escapePartial {
|
if escapePartial {
|
||||||
if escapeOne {
|
|
||||||
escapeOne = false
|
|
||||||
currentArg = append(currentArg, r)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
if r == '\\' {
|
if r == '\\' {
|
||||||
escapeOne = true
|
escapeOne = true
|
||||||
continue
|
continue
|
||||||
@ -140,12 +136,11 @@ func commandReader(in io.Reader) func() ([]string, error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func hash(expression string, imports, inlineImports []string) (string, error) {
|
func hash(expression string, imports []string) (string, error) {
|
||||||
h := fnv.New128()
|
h := fnv.New128()
|
||||||
h.Write([]byte(expression))
|
h.Write([]byte(expression))
|
||||||
allImports := append(imports, inlineImports...)
|
sort.Strings(imports)
|
||||||
sort.Strings(allImports)
|
for _, i := range imports {
|
||||||
for _, i := range allImports {
|
|
||||||
h.Write([]byte(i))
|
h.Write([]byte(i))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -162,7 +157,7 @@ func hash(expression string, imports, inlineImports []string) (string, error) {
|
|||||||
return strings.TrimPrefix(buf.String(), "_"), nil
|
return strings.TrimPrefix(buf.String(), "_"), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func printGoFile(fn string, expression string, imports []string, inlineImports []string) error {
|
func printGoFile(fn string, expression string, imports []string) error {
|
||||||
f, err := os.Create(fn)
|
f, err := os.Create(fn)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -179,23 +174,29 @@ func printGoFile(fn string, expression string, imports []string, inlineImports [
|
|||||||
|
|
||||||
fprintf("package main\n")
|
fprintf("package main\n")
|
||||||
for _, i := range imports {
|
for _, i := range imports {
|
||||||
fprintf("import \"%s\"\n", strings.Split(i, "@")[0])
|
ii := strings.Split(i, "=")
|
||||||
|
p := ii[0]
|
||||||
|
if len(ii) > 1 {
|
||||||
|
p = strings.Join(ii[1:], "=")
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(ii) == 1 {
|
||||||
|
fprintf("import \"%s\"\n", strings.Split(p, "@")[0])
|
||||||
|
} else {
|
||||||
|
fprintf("import %s \"%s\"\n", ii[0], strings.Split(p, "@")[0])
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, i := range inlineImports {
|
fprintf("import \"%s\"\n", selfPkg)
|
||||||
fprintf("import . \"%s\"\n", strings.Split(i, "@")[0])
|
|
||||||
}
|
|
||||||
|
|
||||||
fprintf("import \"code.squareroundforest.org/arpio/wand\"\n")
|
|
||||||
fprintf("func main() {\n")
|
fprintf("func main() {\n")
|
||||||
fprintf("wand.Exec(%s)\n", expression)
|
fprintf("wand.Exec(%s)\n", expression)
|
||||||
fprintf("}")
|
fprintf("}")
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func execWand(o ExecOptions, args []string) error {
|
func execWand(o ExecOptions, stdin io.Reader, stdout, stderr io.Writer, args []string) error {
|
||||||
expression, args := args[0], args[1:]
|
expression, args := args[0], args[1:]
|
||||||
commandHash, err := hash(expression, o.Import, o.InlineImport)
|
commandHash, err := hash(expression, o.Import)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -233,6 +234,14 @@ func execWand(o ExecOptions, args []string) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
goReplace := func(replace string) error {
|
||||||
|
if err := execInternal("go mod edit -replace", replace); err != nil {
|
||||||
|
return fmt.Errorf("failed to get go module: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
if err := os.Chdir(commandDir); err != nil {
|
if err := os.Chdir(commandDir); err != nil {
|
||||||
return fmt.Errorf("failed to switch to temporary directory: %w", err)
|
return fmt.Errorf("failed to switch to temporary directory: %w", err)
|
||||||
}
|
}
|
||||||
@ -244,31 +253,44 @@ func execWand(o ExecOptions, args []string) error {
|
|||||||
return fmt.Errorf("failed to initialize temporary module: %w", err)
|
return fmt.Errorf("failed to initialize temporary module: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var hasSelf bool
|
||||||
for _, pkg := range o.Import {
|
for _, pkg := range o.Import {
|
||||||
if err := goGet(pkg); err != nil {
|
pp := strings.Split(pkg, "=")
|
||||||
|
p := pp[0]
|
||||||
|
if len(pp) > 1 {
|
||||||
|
p = strings.Join(pp[1:], "=")
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := goGet(p); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if p == selfPkg {
|
||||||
|
hasSelf = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !hasSelf {
|
||||||
|
if err := goGet(selfPkg); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, pkg := range o.InlineImport {
|
for _, replace := range o.ReplaceModule {
|
||||||
if err := goGet(pkg); err != nil {
|
if err := goReplace(replace); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := goGet("code.squareroundforest.org/arpio/wand"); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
goFile := path.Join(commandDir, fmt.Sprintf("%s.go", commandHash))
|
goFile := path.Join(commandDir, fmt.Sprintf("%s.go", commandHash))
|
||||||
if _, err := os.Stat(goFile); err != nil {
|
if _, err := os.Stat(goFile); err != nil {
|
||||||
if err := printGoFile(goFile, expression, o.Import, o.InlineImport); err != nil {
|
if err := printGoFile(goFile, expression, o.Import); err != nil {
|
||||||
return fmt.Errorf("failed to create temporary go file: %w", err)
|
return fmt.Errorf("failed to create temporary go file: %w", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := execTransparent("go run", append([]string{commandDir}, args...)...); err != nil {
|
if err := execc(stdin, stdout, stderr, "go run", append([]string{commandDir}, args...), nil); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -281,7 +303,7 @@ func execWand(o ExecOptions, args []string) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func readExec(o ExecOptions, stdin io.Reader) error {
|
func readExec(o ExecOptions, stdin io.Reader, stdout, stderr io.Writer) error {
|
||||||
readCommand := commandReader(stdin)
|
readCommand := commandReader(stdin)
|
||||||
for {
|
for {
|
||||||
args, err := readCommand()
|
args, err := readCommand()
|
||||||
@ -297,16 +319,20 @@ func readExec(o ExecOptions, stdin io.Reader) error {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := execWand(o, args); err != nil {
|
if err := execWand(o, stdin, stdout, stderr, args); err != nil {
|
||||||
fmt.Fprintln(os.Stderr, err)
|
fmt.Fprintln(stderr, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func Exec(o ExecOptions, stdin io.Reader, args ...string) error {
|
func execInput(o ExecOptions, stdin io.Reader, stdout, stderr io.Writer, args ...string) error {
|
||||||
if len(args) == 0 {
|
if len(args) == 0 {
|
||||||
return readExec(o, stdin)
|
return readExec(o, stdin, stdout, stderr)
|
||||||
}
|
}
|
||||||
|
|
||||||
return execWand(o, args)
|
return execWand(o, stdin, stdout, stderr, args)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Exec(o ExecOptions, stdin io.Reader, stdout io.Writer, args ...string) error {
|
||||||
|
return execInput(o, stdin, stdout, os.Stderr, args...)
|
||||||
}
|
}
|
||||||
|
|||||||
202
tools/execwand_test.go
Normal file
202
tools/execwand_test.go
Normal file
@ -0,0 +1,202 @@
|
|||||||
|
package tools
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"code.squareroundforest.org/arpio/notation"
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestExec(t *testing.T) {
|
||||||
|
wd, err := os.Getwd()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
cacheDir := filepath.Join(wd, "../internal/tests/tmpdir")
|
||||||
|
selfReplace := filepath.Join(wd, "..")
|
||||||
|
baseOpt := ExecOptions{
|
||||||
|
ClearCache: true,
|
||||||
|
CacheDir: cacheDir,
|
||||||
|
ReplaceModule: []string{fmt.Sprintf("%s=%s", selfPkg, selfReplace)},
|
||||||
|
}
|
||||||
|
|
||||||
|
t.Run("stdin", func(t *testing.T) {
|
||||||
|
var stdout, stderr bytes.Buffer
|
||||||
|
in := bytes.NewBufferString("strings.Split 1,2,3 ,")
|
||||||
|
o := baseOpt
|
||||||
|
o.Import = []string{"strings"}
|
||||||
|
if err := execInput(o, in, &stdout, &stderr); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if stderr.String() != "" {
|
||||||
|
t.Fatal(stderr.String())
|
||||||
|
}
|
||||||
|
|
||||||
|
if stdout.String() != "1\n2\n3\n" {
|
||||||
|
t.Fatal(stdout.String())
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("stdin multiple lines", func(t *testing.T) {
|
||||||
|
var stdout, stderr bytes.Buffer
|
||||||
|
in := bytes.NewBufferString("strings.Split 1,2,3 ,\nstrings.Split 4,5,6 ,")
|
||||||
|
o := baseOpt
|
||||||
|
o.Import = []string{"strings"}
|
||||||
|
if err := execInput(o, in, &stdout, &stderr); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if stderr.String() != "" {
|
||||||
|
t.Fatal(stderr.String())
|
||||||
|
}
|
||||||
|
|
||||||
|
if stdout.String() != "1\n2\n3\n4\n5\n6\n" {
|
||||||
|
t.Fatal(stdout.String())
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("args", func(t *testing.T) {
|
||||||
|
var stdin, stdout, stderr bytes.Buffer
|
||||||
|
o := baseOpt
|
||||||
|
o.Import = []string{"strings"}
|
||||||
|
if err := execInput(o, &stdin, &stdout, &stderr, "strings.Split", "1,2,3", ","); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if stderr.String() != "" {
|
||||||
|
t.Fatal(stderr.String())
|
||||||
|
}
|
||||||
|
|
||||||
|
if stdout.String() != "1\n2\n3\n" {
|
||||||
|
t.Fatal(stdout.String())
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("inline import", func(t *testing.T) {
|
||||||
|
var stdin, stdout, stderr bytes.Buffer
|
||||||
|
o := baseOpt
|
||||||
|
o.Import = []string{".=strings"}
|
||||||
|
if err := execInput(o, &stdin, &stdout, &stderr, "Split", "1,2,3", ","); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if stderr.String() != "" {
|
||||||
|
t.Fatal(stderr.String())
|
||||||
|
}
|
||||||
|
|
||||||
|
if stdout.String() != "1\n2\n3\n" {
|
||||||
|
t.Fatal(stdout.String())
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("named import", func(t *testing.T) {
|
||||||
|
var stdin, stdout, stderr bytes.Buffer
|
||||||
|
o := baseOpt
|
||||||
|
o.Import = []string{"str=strings"}
|
||||||
|
if err := execInput(o, &stdin, &stdout, &stderr, "str.Split", "1,2,3", ","); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if stderr.String() != "" {
|
||||||
|
t.Fatal(stderr.String())
|
||||||
|
}
|
||||||
|
|
||||||
|
if stdout.String() != "1\n2\n3\n" {
|
||||||
|
t.Fatal(stdout.String())
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("io args", func(t *testing.T) {
|
||||||
|
var stdout, stderr bytes.Buffer
|
||||||
|
in := bytes.NewBuffer([]byte{0, 1, 2})
|
||||||
|
o := baseOpt
|
||||||
|
o.Import = []string{"io", "bytes"}
|
||||||
|
expr := `func(in io.Reader) (out io.Reader) {
|
||||||
|
out = bytes.NewBuffer(nil)
|
||||||
|
buf := make([]byte, 1)
|
||||||
|
for {
|
||||||
|
n, err := in.Read(buf)
|
||||||
|
if n == 1 {
|
||||||
|
buf[0] = buf[0] * 2
|
||||||
|
out.(io.Writer).Write(buf)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return out
|
||||||
|
}`
|
||||||
|
|
||||||
|
if err := execInput(o, in, &stdout, &stderr, expr); err != nil {
|
||||||
|
t.Log(stderr.String())
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if stderr.String() != "" {
|
||||||
|
t.Fatal(stderr.String())
|
||||||
|
}
|
||||||
|
|
||||||
|
if stdout.Len() != 3 || stdout.Bytes()[0] != 0 || stdout.Bytes()[1] != 2 || stdout.Bytes()[2] != 4 {
|
||||||
|
t.Fatal(notation.Sprint(stdout.Bytes()))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("escape", func(t *testing.T) {
|
||||||
|
t.Run("full", func(t *testing.T) {
|
||||||
|
var stdout, stderr bytes.Buffer
|
||||||
|
in := bytes.NewBufferString("'func(a string) { println(a) }' 'foo'")
|
||||||
|
if err := execInput(baseOpt, in, &stdout, &stderr); err != nil {
|
||||||
|
t.Log(stderr.String())
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if stderr.String() != "foo\n" {
|
||||||
|
t.Fatal(stderr.String())
|
||||||
|
}
|
||||||
|
|
||||||
|
if stdout.String() != "" {
|
||||||
|
t.Fatal(stdout.String())
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("one", func(t *testing.T) {
|
||||||
|
var stdout, stderr bytes.Buffer
|
||||||
|
in := bytes.NewBufferString("'func(a string) { println(a) }' foo\\ bar")
|
||||||
|
if err := execInput(baseOpt, in, &stdout, &stderr); err != nil {
|
||||||
|
t.Log(stderr.String())
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if stderr.String() != "foo bar\n" {
|
||||||
|
t.Fatal(stderr.String())
|
||||||
|
}
|
||||||
|
|
||||||
|
if stdout.String() != "" {
|
||||||
|
t.Fatal(stdout.String())
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("one and partial", func(t *testing.T) {
|
||||||
|
var stdout, stderr bytes.Buffer
|
||||||
|
in := bytes.NewBufferString("'func(a string) { println(a) }' \"\\'foo\\'\"")
|
||||||
|
if err := execInput(baseOpt, in, &stdout, &stderr); err != nil {
|
||||||
|
t.Log(stderr.String())
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if stderr.String() != "'foo'\n" {
|
||||||
|
t.Fatal(stderr.String())
|
||||||
|
}
|
||||||
|
|
||||||
|
if stdout.String() != "" {
|
||||||
|
t.Fatal(stdout.String())
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
314
tools/lib_test.go
Normal file
314
tools/lib_test.go
Normal file
@ -0,0 +1,314 @@
|
|||||||
|
package tools_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"code.squareroundforest.org/arpio/wand/tools"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestDocreflect(t *testing.T) {
|
||||||
|
var b bytes.Buffer
|
||||||
|
if err := tools.Docreflect(&b, "testlib", "code.squareroundforest.org/arpio/wand/internal/tests/testlib"); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
const expect = `/*
|
||||||
|
Generated with https://code.squareroundforest.org/arpio/docreflect
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
package testlib
|
||||||
|
import "code.squareroundforest.org/arpio/docreflect"
|
||||||
|
func init() {
|
||||||
|
docreflect.Register("code.squareroundforest.org/arpio/wand/internal/tests/testlib", "")
|
||||||
|
docreflect.Register("code.squareroundforest.org/arpio/wand/internal/tests/testlib.Bar", "\nfunc(out, a, b, c)")
|
||||||
|
docreflect.Register("code.squareroundforest.org/arpio/wand/internal/tests/testlib.Baz", "\nfunc(o)")
|
||||||
|
docreflect.Register("code.squareroundforest.org/arpio/wand/internal/tests/testlib.CustomHelp", "\nfunc(o)")
|
||||||
|
docreflect.Register("code.squareroundforest.org/arpio/wand/internal/tests/testlib.Foo", "Foo sums three numbers.\nIt prints the sum to stdout.\n\nThe input numbers can be any integer.\n\nfunc(a, b, c)")
|
||||||
|
docreflect.Register("code.squareroundforest.org/arpio/wand/internal/tests/testlib.OptionWithHelp", "")
|
||||||
|
docreflect.Register("code.squareroundforest.org/arpio/wand/internal/tests/testlib.OptionWithHelp.Help", "Custom help.\n")
|
||||||
|
docreflect.Register("code.squareroundforest.org/arpio/wand/internal/tests/testlib.Options", "")
|
||||||
|
docreflect.Register("code.squareroundforest.org/arpio/wand/internal/tests/testlib.Options.Bar", "Bars, any number.\n")
|
||||||
|
docreflect.Register("code.squareroundforest.org/arpio/wand/internal/tests/testlib.Options.Duration", "Duration is another option.\n")
|
||||||
|
docreflect.Register("code.squareroundforest.org/arpio/wand/internal/tests/testlib.Options.Foo", "Foo is an option.\n")
|
||||||
|
docreflect.Register("code.squareroundforest.org/arpio/wand/internal/tests/testlib.Options.Some", "Some is an option of any type.\n")
|
||||||
|
docreflect.Register("code.squareroundforest.org/arpio/wand/internal/tests/testlib.Options.Time", "Time is the third option here.\n")
|
||||||
|
}`
|
||||||
|
|
||||||
|
if b.String() != expect {
|
||||||
|
t.Fatal(b.String())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestMan(t *testing.T) {
|
||||||
|
var b bytes.Buffer
|
||||||
|
if err := tools.Man(
|
||||||
|
&b,
|
||||||
|
tools.ManOptions{DateString: "2025-12-09", Version: "v0.9"},
|
||||||
|
"../internal/tests/testlib/cmd",
|
||||||
|
); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
const expect = `.TH "test" 1 "December 2025" "v0.9" "User Commands"
|
||||||
|
.br
|
||||||
|
.sp 1v
|
||||||
|
.in 0
|
||||||
|
.ti 0
|
||||||
|
\fBName:\fR
|
||||||
|
.br
|
||||||
|
.sp 1v
|
||||||
|
.in 4
|
||||||
|
.ti 4
|
||||||
|
test
|
||||||
|
.br
|
||||||
|
.sp 1v
|
||||||
|
.in 0
|
||||||
|
.ti 0
|
||||||
|
\fBSynopsis:\fR
|
||||||
|
.br
|
||||||
|
.sp 1v
|
||||||
|
.nf
|
||||||
|
test [options]... [--] <arg1 int> <arg2 int> <arg3 int>
|
||||||
|
test <subcommand>
|
||||||
|
.fi
|
||||||
|
.br
|
||||||
|
.sp 1v
|
||||||
|
.in 0
|
||||||
|
.ti 0
|
||||||
|
\fBOptions:\fR
|
||||||
|
.br
|
||||||
|
.sp 1v
|
||||||
|
.in 12
|
||||||
|
.ti 4
|
||||||
|
--help:\~Show help.
|
||||||
|
.br
|
||||||
|
.sp 1v
|
||||||
|
.in 0
|
||||||
|
.ti 0
|
||||||
|
\fBSubcommands:\fR
|
||||||
|
.br
|
||||||
|
.sp 1v
|
||||||
|
.in 0
|
||||||
|
.ti 0
|
||||||
|
Show help for each subcommand by calling <command> help or <command> --help.
|
||||||
|
.br
|
||||||
|
.sp 1v
|
||||||
|
.in 2
|
||||||
|
.ti 2
|
||||||
|
\fBtest foo (default)\fR
|
||||||
|
.br
|
||||||
|
.sp 1v
|
||||||
|
.in 4
|
||||||
|
.ti 4
|
||||||
|
\fBSynopsis:\fR
|
||||||
|
.br
|
||||||
|
.sp 1v
|
||||||
|
.nf
|
||||||
|
test foo [options]... [--] <arg1 int> <arg2 int> <arg3 int>
|
||||||
|
test foo <subcommand>
|
||||||
|
.fi
|
||||||
|
.br
|
||||||
|
.sp 1v
|
||||||
|
.in 4
|
||||||
|
.ti 4
|
||||||
|
\fBOptions:\fR
|
||||||
|
.br
|
||||||
|
.sp 1v
|
||||||
|
.in 12
|
||||||
|
.ti 4
|
||||||
|
--help:\~Show help.
|
||||||
|
.br
|
||||||
|
.sp 1v
|
||||||
|
.in 2
|
||||||
|
.ti 2
|
||||||
|
\fBtest bar\fR
|
||||||
|
.br
|
||||||
|
.sp 1v
|
||||||
|
.in 4
|
||||||
|
.ti 4
|
||||||
|
\fBSynopsis:\fR
|
||||||
|
.br
|
||||||
|
.sp 1v
|
||||||
|
.nf
|
||||||
|
test bar [options]... [--] <arg1 int> <arg2 int> <arg3 int>
|
||||||
|
test bar <subcommand>
|
||||||
|
.fi
|
||||||
|
.br
|
||||||
|
.sp 1v
|
||||||
|
.in 4
|
||||||
|
.ti 4
|
||||||
|
\fBOptions:\fR
|
||||||
|
.br
|
||||||
|
.sp 1v
|
||||||
|
.in 12
|
||||||
|
.ti 4
|
||||||
|
--help:\~Show help.
|
||||||
|
.br
|
||||||
|
.sp 1v
|
||||||
|
.in 2
|
||||||
|
.ti 2
|
||||||
|
\fBtest baz\fR
|
||||||
|
.br
|
||||||
|
.sp 1v
|
||||||
|
.in 4
|
||||||
|
.ti 4
|
||||||
|
\fBSynopsis:\fR
|
||||||
|
.br
|
||||||
|
.sp 1v
|
||||||
|
.nf
|
||||||
|
test baz [options]...
|
||||||
|
test baz <subcommand>
|
||||||
|
.fi
|
||||||
|
.br
|
||||||
|
.sp 1v
|
||||||
|
.in 4
|
||||||
|
.ti 4
|
||||||
|
\fBOptions:\fR
|
||||||
|
.br
|
||||||
|
.sp 1v
|
||||||
|
.in 25
|
||||||
|
.ti 4
|
||||||
|
--bar string [*]:\~\~\~\~
|
||||||
|
.br
|
||||||
|
.in 25
|
||||||
|
.ti 4
|
||||||
|
--duration duration:\~
|
||||||
|
.br
|
||||||
|
.in 25
|
||||||
|
.ti 4
|
||||||
|
--foo int:\~\~\~\~\~\~\~\~\~\~\~
|
||||||
|
.br
|
||||||
|
.in 25
|
||||||
|
.ti 4
|
||||||
|
--some any:\~\~\~\~\~\~\~\~\~\~
|
||||||
|
.br
|
||||||
|
.in 25
|
||||||
|
.ti 4
|
||||||
|
--time time:\~\~\~\~\~\~\~\~\~
|
||||||
|
.br
|
||||||
|
.in 25
|
||||||
|
.ti 4
|
||||||
|
--help:\~\~\~\~\~\~\~\~\~\~\~\~\~\~Show help.
|
||||||
|
.br
|
||||||
|
.sp 1v
|
||||||
|
.in 0
|
||||||
|
.ti 0
|
||||||
|
\fBEnvironment variables:\fR
|
||||||
|
.br
|
||||||
|
.sp 1v
|
||||||
|
.in 4
|
||||||
|
.ti 4
|
||||||
|
Every command line option's value can also be provided as an environment variable. Environment variable names need to use snake casing like myapp_foo_bar_baz or MYAPP_FOO_BAR_BAZ, or other casing that doesn't include the '-' dash character, and they need to be prefixed with the name of the application, as in the base name of the command.
|
||||||
|
.br
|
||||||
|
.sp 1v
|
||||||
|
.in 4
|
||||||
|
.ti 4
|
||||||
|
When both the environment variable and the command line option is defined, the command line option overrides the environment variable. Multiple values for the same environment variable can be defined by concatenating the values with the ':' separator character. When overriding multiple values with command line options, all the environment values of the same field are dropped.
|
||||||
|
.br
|
||||||
|
.sp 1v
|
||||||
|
.in 4
|
||||||
|
.ti 4
|
||||||
|
\fBExample environment variable:\fR
|
||||||
|
.br
|
||||||
|
.sp 1v
|
||||||
|
.nf
|
||||||
|
TEST_FOO=42
|
||||||
|
.fi
|
||||||
|
`
|
||||||
|
|
||||||
|
if b.String() != expect {
|
||||||
|
t.Fatal(b.String())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestMarkdown(t *testing.T) {
|
||||||
|
var b bytes.Buffer
|
||||||
|
if err := tools.Markdown(&b, tools.MarkdownOptions{}, "../internal/tests/testlib/cmd"); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
const expect = `# test
|
||||||
|
|
||||||
|
## Synopsis:
|
||||||
|
|
||||||
|
` + "```" + `
|
||||||
|
test [options]... [--] <arg1 int> <arg2 int> <arg3 int>
|
||||||
|
test <subcommand>
|
||||||
|
` + "```" + `
|
||||||
|
|
||||||
|
## Options:
|
||||||
|
|
||||||
|
- --help: Show help.
|
||||||
|
|
||||||
|
## Subcommands:
|
||||||
|
|
||||||
|
Show help for each subcommand by calling \<command\> help or \<command\> --help.
|
||||||
|
|
||||||
|
### test foo (default)
|
||||||
|
|
||||||
|
#### Synopsis:
|
||||||
|
|
||||||
|
` + "```" + `
|
||||||
|
test foo [options]... [--] <arg1 int> <arg2 int> <arg3 int>
|
||||||
|
test foo <subcommand>
|
||||||
|
` + "```" + `
|
||||||
|
|
||||||
|
#### Options:
|
||||||
|
|
||||||
|
- --help: Show help.
|
||||||
|
|
||||||
|
### test bar
|
||||||
|
|
||||||
|
#### Synopsis:
|
||||||
|
|
||||||
|
` + "```" + `
|
||||||
|
test bar [options]... [--] <arg1 int> <arg2 int> <arg3 int>
|
||||||
|
test bar <subcommand>
|
||||||
|
` + "```" + `
|
||||||
|
|
||||||
|
#### Options:
|
||||||
|
|
||||||
|
- --help: Show help.
|
||||||
|
|
||||||
|
### test baz
|
||||||
|
|
||||||
|
#### Synopsis:
|
||||||
|
|
||||||
|
` + "```" + `
|
||||||
|
test baz [options]...
|
||||||
|
test baz <subcommand>
|
||||||
|
` + "```" + `
|
||||||
|
|
||||||
|
#### Options:
|
||||||
|
|
||||||
|
- --bar string \[\*\]:
|
||||||
|
- --duration duration:
|
||||||
|
- --foo int:
|
||||||
|
- --some any:
|
||||||
|
- --time time:
|
||||||
|
- --help: Show help.
|
||||||
|
|
||||||
|
## Environment variables:
|
||||||
|
|
||||||
|
Every command line option's value can also be provided as an environment variable. Environment variable names
|
||||||
|
need to use snake casing like myapp\_foo\_bar\_baz or MYAPP\_FOO\_BAR\_BAZ, or other casing that doesn't include the
|
||||||
|
'-' dash character, and they need to be prefixed with the name of the application, as in the base name of the
|
||||||
|
command.
|
||||||
|
|
||||||
|
When both the environment variable and the command line option is defined, the command line option overrides the
|
||||||
|
environment variable. Multiple values for the same environment variable can be defined by concatenating the
|
||||||
|
values with the ':' separator character. When overriding multiple values with command line options, all the
|
||||||
|
environment values of the same field are dropped.
|
||||||
|
|
||||||
|
### Example environment variable:
|
||||||
|
|
||||||
|
` + "```" + `
|
||||||
|
TEST_FOO=42
|
||||||
|
` + "```" + `
|
||||||
|
`
|
||||||
|
|
||||||
|
if b.String() != expect {
|
||||||
|
t.Fatal(b.String())
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user