Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,7 @@ The types you can currently use for positional args are:
- `float32`
- `float64`
- `string`
- `*url.URL`
- `bool`
- `[]byte` (interpreted as a hex string)
- `time.Time`
Expand Down
2 changes: 2 additions & 0 deletions arg/arg.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package arg

import (
"net"
"net/url"
"time"
)

Expand All @@ -24,6 +25,7 @@ type Argable interface {
float32 |
float64 |
string |
*url.URL |
bool |
[]byte |
time.Time |
Expand Down
Binary file modified docs/img/namedargs.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/img/quickstart.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/img/subcommands.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 2 additions & 1 deletion examples/subcommands/cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package main

import (
"fmt"
"net/url"
"strings"
"time"

Expand Down Expand Up @@ -76,7 +77,7 @@ type doOptions struct {
func buildDoCommand() (*cli.Command, error) {
var options doOptions

var thing string
var thing *url.URL

return cli.New(
"do",
Expand Down
16 changes: 16 additions & 0 deletions internal/arg/arg.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"errors"
"fmt"
"net"
"net/url"
"strconv"
"strings"
"time"
Expand Down Expand Up @@ -97,6 +98,8 @@ func (a Arg[T]) Default() string {
return format.Float64(typ)
case string:
return typ
case *url.URL:
return typ.String()
case bool:
return strconv.FormatBool(typ)
case []byte:
Expand Down Expand Up @@ -149,6 +152,8 @@ func (a Arg[T]) String() string {
return format.Float64(typ)
case string:
return typ
case *url.URL:
return typ.String()
case bool:
return strconv.FormatBool(typ)
case []byte:
Expand Down Expand Up @@ -201,6 +206,8 @@ func (a Arg[T]) Type() string {
return format.TypeFloat64
case string:
return format.TypeString
case *url.URL:
return format.TypeURL
case bool:
return format.TypeBool
case []byte:
Expand Down Expand Up @@ -346,6 +353,15 @@ func (a Arg[T]) Set(str string) error {
val := str
*a.value = *parse.Cast[T](&val)

return nil
case *url.URL:
val, err := url.ParseRequestURI(str)
if err != nil {
return parse.Error(parse.KindArgument, a.name, str, typ, err)
}

*a.value = *parse.Cast[T](&val)

return nil
case bool:
val, err := strconv.ParseBool(str)
Expand Down
34 changes: 34 additions & 0 deletions internal/arg/arg_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"bytes"
"errors"
"net"
"net/url"
"testing"
"time"

Expand Down Expand Up @@ -384,6 +385,39 @@ func TestArgableTypes(t *testing.T) {
test.Equal(t, strArg.String(), "newvalue")
})

t.Run("url valid", func(t *testing.T) {
var u *url.URL

urlArg, err := arg.New(&u, "url", "Set a url value", arg.Config[*url.URL]{})
test.Ok(t, err)

rawURL := "https://github.com/FollowTheProcess/cli"

want, err := url.ParseRequestURI(rawURL)
test.Ok(t, err)

err = urlArg.Set(rawURL)
test.Ok(t, err)
test.Equal(t, u.Scheme, want.Scheme)
test.Equal(t, u.Host, want.Host)
test.Equal(t, u.Path, want.Path)

test.Equal(t, urlArg.Type(), format.TypeURL)
test.Equal(t, urlArg.Usage(), "Set a url value")
test.Equal(t, urlArg.String(), rawURL)
})

t.Run("url invalid", func(t *testing.T) {
var u *url.URL

urlArg, err := arg.New(&u, "url", "Set a url value", arg.Config[*url.URL]{})
test.Ok(t, err)

err = urlArg.Set("word")
test.Err(t, err)
test.True(t, errors.Is(err, parse.Err))
})

t.Run("byte slice valid", func(t *testing.T) {
var byt []byte

Expand Down
2 changes: 0 additions & 2 deletions internal/flag/flag.go
Original file line number Diff line number Diff line change
Expand Up @@ -251,8 +251,6 @@ func (f Flag[T]) Type() string { //nolint:cyclop // No other way of doing this r
return format.TypeFloat32Slice
case []float64:
return format.TypeFloat64Slice
case []string:
return format.TypeStringSlice
default:
return fmt.Sprintf("%T", typ)
}
Expand Down
2 changes: 2 additions & 0 deletions internal/format/format.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ const (
TypeFloat32 = "float32"
TypeFloat64 = "float64"
TypeString = "string"
TypeURL = "url"
TypeBool = "bool"
TypeBytesHex = "bytesHex"
TypeTime = "time"
Expand All @@ -58,6 +59,7 @@ const (
TypeFloat32Slice = slice + TypeFloat32
TypeFloat64Slice = slice + TypeFloat64
TypeStringSlice = slice + TypeString
TypeURLSlice = slice + TypeURL
)

// True is the literal boolean true as a string.
Expand Down
Loading