Skip to content
Closed
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
88 changes: 88 additions & 0 deletions url.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
package pflag

import (
"fmt"
"net/url"
)

// -- url.Value
type urlValue struct {
value *url.URL
changed bool
}

func newURLValue(val *url.URL, p *url.URL) *urlValue {
uv := new(urlValue)
uv.value = p
*uv.value = *val
return uv
}

func (u *urlValue) Set(s string) error {
v, err := url.Parse(s)
if err != nil {
return fmt.Errorf("failed to parse URL: %w", err)

Check failure on line 24 in url.go

View workflow job for this annotation

GitHub Actions / Test (1.12)

Errorf format %w has unknown verb w
}
*u.value = *v
u.changed = true
return nil
}

func (u *urlValue) Type() string {
return "url"
}

func (u *urlValue) String() string {
if u.value == nil {
return ""
}
return u.value.String()
}

// URLVar defines a url.URL flag with specified name, default value, and usage string.
func (f *FlagSet) URLVar(p *url.URL, name string, value url.URL, usage string) {
f.VarP(newURLValue(&value, p), name, "", usage)
}

// URLVarP is like URLVar, but accepts a shorthand letter.
func (f *FlagSet) URLVarP(p *url.URL, name, shorthand string, value url.URL, usage string) {
f.VarP(newURLValue(&value, p), name, shorthand, usage)
}

// URL defines a url.URL flag with specified name, default value, and usage string.
func (f *FlagSet) URL(name string, value url.URL, usage string) *url.URL {
p := new(url.URL)
f.URLVarP(p, name, "", value, usage)
return p
}

// URLP is like URL, but accepts a shorthand letter.
func (f *FlagSet) URLP(name, shorthand string, value url.URL, usage string) *url.URL {
p := new(url.URL)
f.URLVarP(p, name, shorthand, value, usage)
return p
}

// URLVar defines a url.URL flag with specified name, default value, and usage string.
func URLVar(p *url.URL, name string, value url.URL, usage string) {
CommandLine.VarP(newURLValue(&value, p), name, "", usage)
}

// URLVarP is like URLVar, but accepts a shorthand letter.
func URLVarP(p *url.URL, name, shorthand string, value url.URL, usage string) {
CommandLine.VarP(newURLValue(&value, p), name, shorthand, usage)
}

// URL defines a url.URL flag with specified name, default value, and usage string.
func URL(name string, value url.URL, usage string) *url.URL {
p := new(url.URL)
CommandLine.URLVarP(p, name, "", value, usage)
return p
}

// URLP is like URL, but accepts a shorthand letter.
func URLP(name, shorthand string, value url.URL, usage string) *url.URL {
p := new(url.URL)
CommandLine.URLVarP(p, name, shorthand, value, usage)
return p
}
62 changes: 62 additions & 0 deletions url_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package pflag

import (
"net/url"
"testing"
)

func TestURL(t *testing.T) {
fs := NewFlagSet("test", ContinueOnError)
u := fs.URL("url", url.URL{Scheme: "https", Host: "example.com"}, "test url flag")
args := []string{"--url", "https://go.dev/pkg/net/url/"}
if err := fs.Parse(args); err != nil {
t.Fatal(err)
}
if u.String() != "https://go.dev/pkg/net/url/" {
t.Errorf("expected https://go.dev/pkg/net/url/, got %s", u.String())
}
}

func TestURLDefault(t *testing.T) {
fs := NewFlagSet("test", ContinueOnError)
u := fs.URL("url", url.URL{Scheme: "https", Host: "example.com"}, "test url flag")
if err := fs.Parse([]string{}); err != nil {
t.Fatal(err)
}
if u.String() != "https://example.com" {
t.Errorf("expected https://example.com, got %s", u.String())
}
}

func TestURLInvalid(t *testing.T) {
fs := NewFlagSet("test", ContinueOnError)
fs.URL("url", url.URL{}, "test url flag")
args := []string{"--url", "://invalid"}
if err := fs.Parse(args); err == nil {
t.Error("expected error for invalid URL, got nil")
}
}

func TestURLP(t *testing.T) {
fs := NewFlagSet("test", ContinueOnError)
u := fs.URLP("url", "u", url.URL{}, "test url flag")
args := []string{"-u", "https://example.com/path"}
if err := fs.Parse(args); err != nil {
t.Fatal(err)
}
if u.String() != "https://example.com/path" {
t.Errorf("expected https://example.com/path, got %s", u.String())
}
}

func TestURLChanged(t *testing.T) {
fs := NewFlagSet("test", ContinueOnError)
fs.URL("url", url.URL{}, "test url flag")
args := []string{"--url", "https://changed.com"}
if err := fs.Parse(args); err != nil {
t.Fatal(err)
}
if !fs.Lookup("url").Changed {
t.Error("expected Changed to be true")
}
}
Loading