├── .github └── workflows │ └── test.yml ├── .gitignore ├── LICENSE ├── README.md ├── api ├── api.go ├── api_test.go ├── credentials.go ├── delete_files.go ├── delete_files_test.go ├── info.go ├── info_test.go ├── key.go ├── list.go ├── response.go ├── upload.go ├── upload_files.go ├── upload_files_test.go └── upload_test.go ├── client ├── args.go ├── args_test.go ├── client.go ├── command.go ├── delete.go ├── delete_test.go ├── exec_error.go ├── help.go ├── help_test.go ├── info.go ├── info_test.go ├── key.go ├── list.go ├── runner.go ├── upload.go ├── upload_test.go ├── version.go └── version_test.go ├── go.mod ├── go.sum ├── main.go ├── main_test.go ├── prepare_neocities_release.sh └── vendor ├── github.com └── ogier │ └── pflag │ ├── .travis.yml │ ├── LICENSE │ ├── README.md │ ├── bool.go │ ├── duration.go │ ├── flag.go │ ├── float32.go │ ├── float64.go │ ├── int.go │ ├── int32.go │ ├── int64.go │ ├── int8.go │ ├── ip.go │ ├── ipmask.go │ ├── string.go │ ├── uint.go │ ├── uint16.go │ ├── uint32.go │ ├── uint64.go │ └── uint8.go └── modules.txt /.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | on: 2 | push: 3 | branches: 4 | - master 5 | pull_request: 6 | branches: 7 | - master 8 | name: test 9 | jobs: 10 | test: 11 | strategy: 12 | matrix: 13 | go-version: [1.23.x, 1.22.x] 14 | os: [ubuntu-latest] 15 | runs-on: ${{ matrix.os }} 16 | steps: 17 | - name: Checkout code 18 | uses: actions/checkout@v4 19 | - name: Install Go 20 | uses: actions/setup-go@v5 21 | with: 22 | go-version: ${{ matrix.go-version }} 23 | - name: test 24 | run: go test -v ./... 25 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled Object files, Static and Dynamic libs (Shared Objects) 2 | *.o 3 | *.a 4 | *.so 5 | 6 | # Folders 7 | _obj 8 | _test 9 | 10 | # Architecture specific extensions/prefixes 11 | *.[568vq] 12 | [568vq].out 13 | 14 | *.cgo1.go 15 | *.cgo2.c 16 | _cgo_defun.c 17 | _cgo_gotypes.go 18 | _cgo_export.* 19 | 20 | _testmain.go 21 | 22 | *.exe 23 | *.test 24 | 25 | # Ignore the neocities binary 26 | neocities 27 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014-2024 Peter Hellberg https://c7.se 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | A Neocities client written in Go 2 | ================================ 3 | 4 | Upload files to you [Neocities](https://neocities.org/) website from the 5 | comfort of your own terminal. 6 | 7 | [![Build Status](https://github.com/peterhellberg/neocities/actions/workflows/test.yml/badge.svg)](https://github.com/peterhellberg/neocities/actions/workflows/test.yml) 8 | [![GoDoc](https://img.shields.io/badge/godoc-reference-blue.svg?style=flat)](https://pkg.go.dev/github.com/peterhellberg/neocities) 9 | [![License MIT](https://img.shields.io/badge/license-MIT-lightgrey.svg?style=flat)](https://github.com/peterhellberg/neocities#license-mit) 10 | 11 | ## Installation 12 | 13 | You can download precompiled binaries for 14 | [OS X](https://github.com/peterhellberg/neocities/releases/download/0.0.4/neocities-0.0.4-darwin-amd64.zip), 15 | [Linux](https://github.com/peterhellberg/neocities/releases/download/0.0.4/neocities-0.0.4-linux-amd64.zip), 16 | [Windows (32 bit)](https://github.com/peterhellberg/neocities/releases/download/0.0.4/neocities-0.0.4-windows-386.zip) and 17 | [Windows (64 bit)](https://github.com/peterhellberg/neocities/releases/download/0.0.4/neocities-0.0.4-windows-amd64.zip) 18 | 19 | Or, if you have [Go](http://golang.org/) installed: 20 | 21 | go install github.com/peterhellberg/neocities@latest 22 | 23 | ## Usage 24 | 25 | [![Cat!](https://neocities.org/img/cat.png)](https://neocities.org/) 26 | 27 | First you need to set two environment variables: 28 | 29 | ```bash 30 | export NEOCITIES_USER= 31 | export NEOCITIES_PASS= 32 | ``` 33 | 34 | Alternatively you can use the `NEOCITIES_KEY` variable. 35 | 36 | Then you should be able to upload files to your website: 37 | 38 | neocities upload foo.html bar.js folder/baz.jpg 39 | 40 | You can also delete files: 41 | 42 | neocities delete foo.html folder/baz.jpg 43 | 44 | You get a list of available commands by default: 45 | 46 | ```bash 47 | $ neocities 48 | usage: neocities [] 49 | 50 | Commands: 51 | upload Upload files to Neocities 52 | delete Delete files from Neocities 53 | info Info about Neocities websites 54 | key Neocities API key 55 | list List files on Neocities 56 | version Show neocities client version 57 | 58 | Help for a specific command: 59 | help [command] 60 | ``` 61 | 62 | ## Donate 63 | 64 | [![Support Neocities](https://neocities.org/img/support-us.png)](https://neocities.org/donate) 65 | 66 | NeoCities is funded by donations. If you’d like to contribute, you can help to pay for server costs using Bitcoin or PayPal. 67 | 68 | ## License (MIT) 69 | 70 | Copyright (c) 2014-2024 [Peter Hellberg](https://c7.se) 71 | 72 | > Permission is hereby granted, free of charge, to any person obtaining 73 | > a copy of this software and associated documentation files (the 74 | > "Software"), to deal in the Software without restriction, including 75 | > without limitation the rights to use, copy, modify, merge, publish, 76 | > distribute, sublicense, and/or sell copies of the Software, and to 77 | > permit persons to whom the Software is furnished to do so, subject to 78 | > the following conditions: 79 | 80 | > The above copyright notice and this permission notice shall be 81 | > included in all copies or substantial portions of the Software. 82 | 83 | > THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 84 | > EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 85 | > MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 86 | > NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 87 | > LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 88 | > OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 89 | > WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 90 | -------------------------------------------------------------------------------- /api/api.go: -------------------------------------------------------------------------------- 1 | package api 2 | 3 | import ( 4 | "errors" 5 | "net/http" 6 | ) 7 | 8 | const ( 9 | apiURL = "https://neocities.org/api/" 10 | userAgent = "neocities (Go package using net/http)" 11 | ) 12 | 13 | var ErrUnexpectedStatusCode = errors.New("unexpected status code") 14 | 15 | func performHTTPRequest(req *http.Request) (Response, error) { 16 | res, err := sendHTTPRequest(req) 17 | if err != nil { 18 | return Response{}, err 19 | } 20 | defer res.Body.Close() 21 | 22 | var r Response 23 | 24 | if err := r.PopulateFromHTTPResponse(res); err != nil { 25 | return r, err 26 | } 27 | 28 | if res.StatusCode != 200 { 29 | return r, ErrUnexpectedStatusCode 30 | } 31 | 32 | return r, nil 33 | } 34 | 35 | // Send HTTP request 36 | func sendHTTPRequest(req *http.Request) (*http.Response, error) { 37 | // Create a HTTP client 38 | client := &http.Client{} 39 | 40 | // Make sure that the correct User-Agent is set 41 | req.Header.Add("User-Agent", userAgent) 42 | 43 | // Send the request and return the response 44 | return client.Do(req) 45 | } 46 | -------------------------------------------------------------------------------- /api/api_test.go: -------------------------------------------------------------------------------- 1 | package api 2 | 3 | import "testing" 4 | 5 | func TestAPI(t *testing.T) { 6 | if got, want := apiURL, "https://neocities.org/api/"; got != want { 7 | t.Fatalf("apiURL = %q, want %q", got, want) 8 | } 9 | 10 | if got, want := userAgent, "neocities (Go package using net/http)"; got != want { 11 | t.Fatalf("userAgent = %q, want %q", got, want) 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /api/credentials.go: -------------------------------------------------------------------------------- 1 | package api 2 | 3 | import "net/http" 4 | 5 | type Authenticator interface { 6 | Authenticate(*http.Request) 7 | } 8 | 9 | // Credentials contains the username and password 10 | type Credentials struct { 11 | User string 12 | Pass string 13 | Key string 14 | } 15 | 16 | func (c Credentials) Authenticate(r *http.Request) { 17 | if r == nil { 18 | return 19 | } 20 | 21 | if c.Key != "" { 22 | r.Header.Set("Authorization", "Bearer "+c.Key) 23 | return 24 | } 25 | 26 | r.SetBasicAuth(c.User, c.Pass) 27 | } 28 | -------------------------------------------------------------------------------- /api/delete_files.go: -------------------------------------------------------------------------------- 1 | package api 2 | 3 | import ( 4 | "net/http" 5 | "net/url" 6 | "strings" 7 | ) 8 | 9 | // DeleteFiles deletes the given filenames 10 | func DeleteFiles(a Authenticator, filenames []string) (Response, error) { 11 | req, err := newDeleteRequest(a, filenames) 12 | if err != nil { 13 | return Response{}, err 14 | } 15 | 16 | return performHTTPRequest(req) 17 | } 18 | 19 | // Create a new delete request 20 | func newDeleteRequest(a Authenticator, filenames []string) (*http.Request, error) { 21 | data := url.Values{} 22 | 23 | for _, file := range filenames { 24 | data.Add("filenames[]", file) 25 | } 26 | 27 | req, err := http.NewRequest("POST", apiURL+"delete", strings.NewReader(data.Encode())) 28 | if err != nil { 29 | return req, err 30 | } 31 | 32 | if a != nil { 33 | a.Authenticate(req) 34 | } 35 | 36 | // Set the content type of the form data 37 | req.Header.Add("Content-Type", "application/x-www-form-urlencoded") 38 | 39 | return req, nil 40 | } 41 | -------------------------------------------------------------------------------- /api/delete_files_test.go: -------------------------------------------------------------------------------- 1 | package api 2 | 3 | import "testing" 4 | 5 | func TestDeleteFiles(t *testing.T) { 6 | cred := Credentials{User: "foo", Pass: "bar", Key: "baz"} 7 | 8 | t.Run("newDeleteRequest", func(t *testing.T) { 9 | req, err := newDeleteRequest(cred, []string{"foo", "bar"}) 10 | if err != nil { 11 | t.Fatalf("unexpected error: %v", err) 12 | } 13 | 14 | if got, want := req.Method, "POST"; got != want { 15 | t.Fatalf("req.Method = %q, want %q", got, want) 16 | } 17 | 18 | if got, want := req.URL.String(), "https://neocities.org/api/delete"; got != want { 19 | t.Fatalf("req.URL.String() = %q, want %q", got, want) 20 | } 21 | }) 22 | } 23 | -------------------------------------------------------------------------------- /api/info.go: -------------------------------------------------------------------------------- 1 | package api 2 | 3 | import "net/http" 4 | 5 | // SiteInfo returns a site info response 6 | func SiteInfo(a Authenticator, site string) (Response, error) { 7 | req, err := newInfoRequest(a, site) 8 | if err != nil { 9 | return Response{}, err 10 | } 11 | 12 | return performHTTPRequest(req) 13 | } 14 | 15 | // Create a new info request 16 | func newInfoRequest(a Authenticator, site string) (*http.Request, error) { 17 | endpoint := "info" 18 | 19 | if site != "" { 20 | endpoint = endpoint + "?sitename=" + site 21 | } 22 | 23 | req, err := http.NewRequest("GET", apiURL+endpoint, nil) 24 | if err != nil { 25 | return req, err 26 | } 27 | 28 | if a != nil { 29 | a.Authenticate(req) 30 | } 31 | 32 | return req, nil 33 | } 34 | -------------------------------------------------------------------------------- /api/info_test.go: -------------------------------------------------------------------------------- 1 | package api 2 | 3 | import "testing" 4 | 5 | func TestInfo(t *testing.T) { 6 | cred := Credentials{User: "foo", Pass: "bar", Key: "baz"} 7 | 8 | t.Run("newInfoRequest", func(t *testing.T) { 9 | req, err := newInfoRequest(cred, "foo") 10 | if err != nil { 11 | t.Fatalf("unexpected error: %v", err) 12 | } 13 | 14 | if got, want := req.Method, "GET"; got != want { 15 | t.Fatalf("req.Method = %q, want %q", got, want) 16 | } 17 | 18 | if got, want := req.URL.String(), "https://neocities.org/api/info?sitename=foo"; got != want { 19 | t.Fatalf("req.URL.String() = %q, want %q", got, want) 20 | } 21 | }) 22 | } 23 | -------------------------------------------------------------------------------- /api/key.go: -------------------------------------------------------------------------------- 1 | package api 2 | 3 | import ( 4 | "encoding/json" 5 | "net/http" 6 | ) 7 | 8 | type KeyResponse struct { 9 | Result string `json:"result"` 10 | ErrorType string `json:"error_type"` 11 | Message string `json:"message"` 12 | APIKey string `json:"api_key"` 13 | } 14 | 15 | func Key(a Authenticator) (*KeyResponse, error) { 16 | req, err := newKeyRequest(a) 17 | if err != nil { 18 | return nil, err 19 | } 20 | 21 | resp, err := sendHTTPRequest(req) 22 | if err != nil { 23 | return nil, err 24 | } 25 | defer resp.Body.Close() 26 | 27 | var kr KeyResponse 28 | 29 | return &kr, json.NewDecoder(resp.Body).Decode(&kr) 30 | } 31 | 32 | func newKeyRequest(a Authenticator) (*http.Request, error) { 33 | endpoint := "key" 34 | 35 | req, err := http.NewRequest("GET", apiURL+endpoint, nil) 36 | if err != nil { 37 | return nil, err 38 | } 39 | 40 | if a != nil { 41 | a.Authenticate(req) 42 | } 43 | 44 | return req, nil 45 | } 46 | -------------------------------------------------------------------------------- /api/list.go: -------------------------------------------------------------------------------- 1 | package api 2 | 3 | import ( 4 | "encoding/json" 5 | "net/http" 6 | ) 7 | 8 | type ListResponse struct { 9 | Result string `json:"result"` 10 | Files []File `json:"files"` 11 | } 12 | 13 | type File struct { 14 | Path string `json:"path"` 15 | IsDirectory bool `json:"is_directory"` 16 | Size int `json:"size,omitempty"` 17 | UpdatedAt string `json:"updated_at"` 18 | Sha1Hash string `json:"sha1_hash,omitempty"` 19 | } 20 | 21 | func List(a Authenticator) (*ListResponse, error) { 22 | req, err := newListRequest(a) 23 | if err != nil { 24 | return nil, err 25 | } 26 | 27 | resp, err := sendHTTPRequest(req) 28 | if err != nil { 29 | return nil, err 30 | } 31 | defer resp.Body.Close() 32 | 33 | var lr ListResponse 34 | 35 | return &lr, json.NewDecoder(resp.Body).Decode(&lr) 36 | } 37 | 38 | func newListRequest(a Authenticator) (*http.Request, error) { 39 | endpoint := "list" 40 | 41 | req, err := http.NewRequest("GET", apiURL+endpoint, nil) 42 | if err != nil { 43 | return nil, err 44 | } 45 | 46 | if a != nil { 47 | a.Authenticate(req) 48 | } 49 | 50 | return req, nil 51 | } 52 | -------------------------------------------------------------------------------- /api/response.go: -------------------------------------------------------------------------------- 1 | package api 2 | 3 | import ( 4 | "encoding/json" 5 | "fmt" 6 | "io" 7 | "net/http" 8 | ) 9 | 10 | // Response from the Neocities API 11 | type Response struct { 12 | Result string `json:"result"` 13 | ErrorType string `json:"error_type"` 14 | Message string `json:"message"` 15 | Info Info 16 | Body []byte 17 | } 18 | 19 | // Info contains the properties for a site 20 | type Info struct { 21 | Sitename string `json:"sitename"` 22 | Hits int32 `json:"hits"` 23 | CreatedAt string `json:"created_at"` 24 | LastUpdated string `json:"last_updated"` 25 | Domain string `json:"domain"` 26 | Tags []string `json:"tags"` 27 | } 28 | 29 | // PopulateFromHTTPResponse use a HTTP response to populate itself 30 | func (r *Response) PopulateFromHTTPResponse(res *http.Response) error { 31 | body, err := io.ReadAll(res.Body) 32 | if err != nil { 33 | return err 34 | } 35 | defer res.Body.Close() 36 | 37 | err = json.Unmarshal(body, &r) 38 | 39 | r.Body = body 40 | 41 | return err 42 | } 43 | 44 | // Print is printing the contents of the response to stdout 45 | func (r *Response) Print() { 46 | fmt.Println("Result: ", r.Result) 47 | 48 | if r.ErrorType != "" { 49 | fmt.Println("ErrorType:", r.ErrorType) 50 | } 51 | 52 | fmt.Println("Message: ", r.Message) 53 | } 54 | -------------------------------------------------------------------------------- /api/upload.go: -------------------------------------------------------------------------------- 1 | package api 2 | 3 | import ( 4 | "bytes" 5 | "mime/multipart" 6 | "net/http" 7 | ) 8 | 9 | // UploadData contains the filename and content 10 | type UploadData struct { 11 | FileName string 12 | Content []byte 13 | } 14 | 15 | func Upload(a Authenticator, data []UploadData) (Response, error) { 16 | req, err := newUploadDataRequest(a, data) 17 | if err != nil { 18 | return Response{}, err 19 | } 20 | 21 | return performHTTPRequest(req) 22 | } 23 | 24 | // Create a new upload data request 25 | func newUploadDataRequest(a Authenticator, data []UploadData) (*http.Request, error) { 26 | body := &bytes.Buffer{} 27 | writer := multipart.NewWriter(body) 28 | 29 | // Add the contents of each file to the multipart body 30 | for _, d := range data { 31 | part, err := writer.CreateFormFile(d.FileName, d.FileName) 32 | if err != nil { 33 | return nil, err 34 | } 35 | 36 | if _, err = part.Write(d.Content); err != nil { 37 | return nil, err 38 | } 39 | } 40 | 41 | if err := writer.Close(); err != nil { 42 | return nil, err 43 | } 44 | 45 | req, err := http.NewRequest("POST", apiURL+"upload", body) 46 | if err != nil { 47 | return req, err 48 | } 49 | 50 | if a != nil { 51 | a.Authenticate(req) 52 | } 53 | 54 | // Set the content type of the form data 55 | req.Header.Add("Content-Type", writer.FormDataContentType()) 56 | 57 | return req, nil 58 | } 59 | -------------------------------------------------------------------------------- /api/upload_files.go: -------------------------------------------------------------------------------- 1 | package api 2 | 3 | import ( 4 | "bytes" 5 | "io" 6 | "mime/multipart" 7 | "net/http" 8 | "os" 9 | "path/filepath" 10 | "strings" 11 | ) 12 | 13 | // UploadFiles takes a set of credentials and 14 | // a list of filename paths to upload to Neocities. 15 | func UploadFiles(a Authenticator, paths []string) (Response, error) { 16 | req, err := newUploadRequest(a, paths) 17 | if err != nil { 18 | return Response{}, err 19 | } 20 | 21 | return performHTTPRequest(req) 22 | } 23 | 24 | // Create a new upload request 25 | func newUploadRequest(a Authenticator, paths []string) (*http.Request, error) { 26 | body := &bytes.Buffer{} 27 | writer := multipart.NewWriter(body) 28 | 29 | // Add the contents of each file to the multipart body 30 | for _, path := range paths { 31 | filepath.Walk(path, func(p string, info os.FileInfo, err error) error { 32 | if info == nil { 33 | return nil 34 | } 35 | 36 | if info.IsDir() { 37 | return nil 38 | } 39 | 40 | file, err := os.Open(p) 41 | if err != nil { 42 | return err 43 | } 44 | defer file.Close() 45 | 46 | part, err := writer.CreateFormFile(strings.Replace(p, "\\", "/", -1), p) 47 | if err != nil { 48 | return err 49 | } 50 | 51 | if _, err := io.Copy(part, file); err != nil { 52 | return err 53 | } 54 | 55 | return nil 56 | }) 57 | } 58 | 59 | if err := writer.Close(); err != nil { 60 | return nil, err 61 | } 62 | 63 | req, err := http.NewRequest("POST", apiURL+"upload", body) 64 | if err != nil { 65 | return nil, err 66 | } 67 | 68 | if a != nil { 69 | a.Authenticate(req) 70 | } 71 | 72 | // Set the content type of the form data 73 | req.Header.Add("Content-Type", writer.FormDataContentType()) 74 | 75 | return req, nil 76 | } 77 | -------------------------------------------------------------------------------- /api/upload_files_test.go: -------------------------------------------------------------------------------- 1 | package api 2 | 3 | import "testing" 4 | 5 | func TestUploadFiles(t *testing.T) { 6 | cred := Credentials{User: "foo", Pass: "bar", Key: "baz"} 7 | 8 | t.Run("newUploadRequest", func(t *testing.T) { 9 | req, err := newUploadRequest(cred, []string{"../LICENSE"}) 10 | if err != nil { 11 | t.Fatalf("unexpected error: %v", err) 12 | } 13 | 14 | if got, want := req.Method, "POST"; got != want { 15 | t.Fatalf("req.Method = %q, want %q", got, want) 16 | } 17 | 18 | if got, want := req.URL.String(), "https://neocities.org/api/upload"; got != want { 19 | t.Fatalf("req.URL.String() = %q, want %q", got, want) 20 | } 21 | }) 22 | } 23 | -------------------------------------------------------------------------------- /api/upload_test.go: -------------------------------------------------------------------------------- 1 | package api 2 | 3 | import ( 4 | "os" 5 | "testing" 6 | ) 7 | 8 | func TestUpload(t *testing.T) { 9 | cred := Credentials{User: "foo", Pass: "bar", Key: "baz"} 10 | 11 | t.Run("newUploadDataRequest", func(t *testing.T) { 12 | testContent, err := os.ReadFile("../LICENSE") 13 | if err != nil { 14 | t.Fatalf("unexpected error: %v", err) 15 | } 16 | 17 | testData := []UploadData{ 18 | { 19 | FileName: "LICENSE_string", 20 | Content: testContent, 21 | }, 22 | } 23 | 24 | req, err := newUploadDataRequest(cred, testData) 25 | if err != nil { 26 | t.Fatalf("unexpected error: %v", err) 27 | } 28 | 29 | if got, want := req.Method, "POST"; got != want { 30 | t.Fatalf("req.Method = %q, want %q", got, want) 31 | } 32 | 33 | if got, want := req.URL.String(), "https://neocities.org/api/upload"; got != want { 34 | t.Fatalf("req.URL.String() = %q, want %q", got, want) 35 | } 36 | }) 37 | } 38 | -------------------------------------------------------------------------------- /client/args.go: -------------------------------------------------------------------------------- 1 | package client 2 | 3 | // Args contains a command and its params 4 | type Args struct { 5 | Command string 6 | Params []string 7 | } 8 | 9 | // newArgs creates a new Args using a list of strings 10 | func newArgs(args []string) *Args { 11 | var ( 12 | command string 13 | params []string 14 | ) 15 | 16 | if len(args) == 0 { 17 | params = []string{} 18 | } else { 19 | command = args[0] 20 | params = args[1:] 21 | } 22 | 23 | return &Args{ 24 | Command: command, 25 | Params: params, 26 | } 27 | } 28 | 29 | // IsParamsEmpty checks if the params size is 0 30 | func (a *Args) IsParamsEmpty() bool { 31 | return a.ParamsSize() == 0 32 | } 33 | 34 | // ParamsSize returns the number of params 35 | func (a *Args) ParamsSize() int { 36 | return len(a.Params) 37 | } 38 | 39 | // FirstParam returns the first param. 40 | // It returns empty string if there are no params. 41 | func (a *Args) FirstParam() string { 42 | if a.ParamsSize() == 0 { 43 | return "" 44 | } 45 | 46 | return a.Params[0] 47 | } 48 | -------------------------------------------------------------------------------- /client/args_test.go: -------------------------------------------------------------------------------- 1 | package client 2 | 3 | import ( 4 | "reflect" 5 | "testing" 6 | ) 7 | 8 | func TestArgs(t *testing.T) { 9 | cmd := "foo" 10 | 11 | t.Run("should contain a Command and Params", func(t *testing.T) { 12 | params := []string{"bar", "baz"} 13 | args := &Args{Command: cmd, Params: params} 14 | 15 | if got, want := args.Command, cmd; got != want { 16 | t.Fatalf("args.Command = %q, want %q", got, want) 17 | } 18 | 19 | if !reflect.DeepEqual(args.Params, params) { 20 | t.Fatalf("args.Params != params") 21 | } 22 | }) 23 | 24 | t.Run("newArgs", func(t *testing.T) { 25 | t.Run("with no arguments", func(t *testing.T) { 26 | args := newArgs([]string{}) 27 | 28 | if got, want := args.Command, ""; got != want { 29 | t.Fatalf("args.Command = %q, want %q", got, want) 30 | } 31 | }) 32 | 33 | t.Run("with command", func(t *testing.T) { 34 | args := newArgs([]string{cmd}) 35 | 36 | if got, want := args.Command, cmd; got != want { 37 | t.Fatalf("args.Command = %q, want %q", got, want) 38 | } 39 | }) 40 | 41 | t.Run("with command and params", func(t *testing.T) { 42 | args := newArgs([]string{cmd, "param1", "param2"}) 43 | 44 | if got, want := args.Command, cmd; got != want { 45 | t.Fatalf("args.Command = %q, want %q", got, want) 46 | } 47 | }) 48 | }) 49 | 50 | t.Run("IsParamsEmpty", func(t *testing.T) { 51 | t.Run("with no params", func(t *testing.T) { 52 | args := newArgs([]string{cmd}) 53 | 54 | if !args.IsParamsEmpty() { 55 | t.Fatalf("args.IsParamsEmpty() is false") 56 | } 57 | }) 58 | 59 | t.Run("with params", func(t *testing.T) { 60 | args := newArgs([]string{cmd, "bar", "baz"}) 61 | 62 | if args.IsParamsEmpty() { 63 | t.Fatalf("args.IsParamsEmpty() is true") 64 | } 65 | }) 66 | }) 67 | } 68 | -------------------------------------------------------------------------------- /client/client.go: -------------------------------------------------------------------------------- 1 | package client 2 | 3 | import ( 4 | "encoding/json" 5 | "io" 6 | "os" 7 | ) 8 | 9 | func dump(v interface{}) { 10 | encodeJSON(os.Stdout, v) 11 | } 12 | 13 | func encodeJSON(w io.Writer, v interface{}) { 14 | enc := json.NewEncoder(w) 15 | 16 | enc.SetIndent("", " ") 17 | 18 | enc.Encode(v) 19 | } 20 | -------------------------------------------------------------------------------- /client/command.go: -------------------------------------------------------------------------------- 1 | package client 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | "strings" 7 | 8 | flag "github.com/ogier/pflag" 9 | 10 | "github.com/peterhellberg/neocities/api" 11 | ) 12 | 13 | // CmdRunner is the default command runner 14 | var CmdRunner = NewRunner() 15 | 16 | // Command contains a function to run, 17 | // a flagset, and usage instructions 18 | type Command struct { 19 | Run func(cmd *Command, args *Args) 20 | Flag flag.FlagSet 21 | 22 | Key string 23 | Usage string 24 | Short string 25 | Long string 26 | } 27 | 28 | // Name returns the name of the command. 29 | // It falls back on the first word in Usage 30 | // if no Name was provided. 31 | func (c *Command) Name() string { 32 | if c.Key != "" { 33 | return c.Key 34 | } 35 | 36 | return strings.Split(c.Usage, " ")[0] 37 | } 38 | 39 | func (c *Command) parseArguments(args *Args) (err error) { 40 | c.Flag.SetInterspersed(true) 41 | c.Flag.Usage = c.PrintUsage 42 | 43 | if err = c.Flag.Parse(args.Params); err == nil { 44 | args.Params = c.Flag.Args() 45 | } 46 | 47 | return 48 | } 49 | 50 | // Call calls the command with provided args 51 | func (c *Command) Call(args *Args) (err error) { 52 | err = c.parseArguments(args) 53 | if err != nil { 54 | return 55 | } 56 | 57 | c.Run(c, args) 58 | 59 | return 60 | } 61 | 62 | // PrintUsage prints usage instructions for the command 63 | func (c *Command) PrintUsage() { 64 | if c.Runnable() { 65 | fmt.Printf("usage: %s\n\n", c.FormattedUsage()) 66 | } 67 | 68 | fmt.Println(strings.Trim(c.Long, "\n")) 69 | } 70 | 71 | // FormattedUsage returns the formatted usage for runnable command 72 | func (c *Command) FormattedUsage() string { 73 | return fmt.Sprintf("neocities %s", c.Usage) 74 | } 75 | 76 | // Runnable checks if the command has a Run function 77 | func (c *Command) Runnable() bool { 78 | return c.Run != nil 79 | } 80 | 81 | func getCredentials() api.Credentials { 82 | if key := os.Getenv("NEOCITIES_KEY"); key != "" { 83 | return api.Credentials{Key: key} 84 | } 85 | 86 | user := os.Getenv("NEOCITIES_USER") 87 | pass := os.Getenv("NEOCITIES_PASS") 88 | 89 | if user == "" { 90 | fmt.Println("Error: Missing environment variable NEOCITIES_USER or NEOCITIES_KEY") 91 | 92 | os.Exit(0) 93 | } 94 | 95 | if pass == "" { 96 | fmt.Println("Error: Missing environment variable NEOCITIES_PASS") 97 | 98 | os.Exit(0) 99 | } 100 | 101 | return api.Credentials{ 102 | User: user, 103 | Pass: pass, 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /client/delete.go: -------------------------------------------------------------------------------- 1 | package client 2 | 3 | import ( 4 | "os" 5 | 6 | "github.com/peterhellberg/neocities/api" 7 | ) 8 | 9 | var cmdDelete = &Command{ 10 | Run: runDelete, 11 | Usage: "delete []", 12 | Short: "Delete files from Neocities", 13 | Long: "Delete files from your Neocities website", 14 | } 15 | 16 | func init() { 17 | CmdRunner.Use(cmdDelete) 18 | } 19 | 20 | func runDelete(cmd *Command, args *Args) { 21 | if args.IsParamsEmpty() { 22 | cmd.PrintUsage() 23 | 24 | os.Exit(0) 25 | } 26 | 27 | cred := getCredentials() 28 | 29 | files := args.Params 30 | 31 | response, err := api.DeleteFiles(cred, files) 32 | if err != nil { 33 | response.Print() 34 | 35 | os.Exit(1) 36 | } 37 | 38 | if os.Getenv("NEOCITIES_VERBOSE") == "true" { 39 | response.Print() 40 | } 41 | 42 | os.Exit(0) 43 | } 44 | -------------------------------------------------------------------------------- /client/delete_test.go: -------------------------------------------------------------------------------- 1 | package client 2 | 3 | import "testing" 4 | 5 | func TestDelete(t *testing.T) { 6 | t.Run("cmdDelete", func(t *testing.T) { 7 | d := cmdDelete 8 | 9 | if got, want := d.Usage, "delete []"; got != want { 10 | t.Fatalf("d.Usage = %q, want %q", got, want) 11 | } 12 | 13 | if got, want := d.Short, "Delete files from Neocities"; got != want { 14 | t.Fatalf("d.Short = %q, want %q", got, want) 15 | } 16 | 17 | if got, want := d.Long, "Delete files from your Neocities website"; got != want { 18 | t.Fatalf("d.Long = %q, want %q", got, want) 19 | } 20 | }) 21 | } 22 | -------------------------------------------------------------------------------- /client/exec_error.go: -------------------------------------------------------------------------------- 1 | package client 2 | 3 | import ( 4 | "os/exec" 5 | "syscall" 6 | ) 7 | 8 | // ExecError contains one error and an exit code. 9 | type ExecError struct { 10 | Err error 11 | ExitCode int 12 | } 13 | 14 | func (execError *ExecError) Error() string { 15 | if execError == nil || execError.Err == nil { 16 | return "" 17 | } 18 | 19 | return execError.Err.Error() 20 | } 21 | 22 | func newExecError(err error) ExecError { 23 | exitCode := 0 24 | 25 | if err != nil { 26 | exitCode = 1 27 | 28 | if exitError, ok := err.(*exec.ExitError); ok { 29 | if status, ok := exitError.Sys().(syscall.WaitStatus); ok { 30 | exitCode = status.ExitStatus() 31 | } 32 | } 33 | } 34 | 35 | return ExecError{ 36 | Err: err, 37 | ExitCode: exitCode, 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /client/help.go: -------------------------------------------------------------------------------- 1 | package client 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | ) 7 | 8 | var cmdHelp = &Command{ 9 | Run: runHelp, 10 | Usage: "help [command]", 11 | Short: "Show help", 12 | Long: "Show usage instructions for a command", 13 | } 14 | 15 | func init() { 16 | CmdRunner.Use(cmdHelp) 17 | } 18 | 19 | func runHelp(cmd *Command, args *Args) { 20 | if args.IsParamsEmpty() { 21 | printUsage() 22 | 23 | os.Exit(0) 24 | } 25 | 26 | for _, cmd := range CmdRunner.All() { 27 | if cmd.Name() == args.FirstParam() { 28 | cmd.PrintUsage() 29 | 30 | os.Exit(0) 31 | } 32 | } 33 | } 34 | 35 | var helpText = `usage: neocities [] 36 | 37 | Commands: 38 | upload Upload files to Neocities 39 | delete Delete files from Neocities 40 | info Info about Neocities websites 41 | key Neocities API key 42 | list List files on Neocities 43 | version Show neocities client version 44 | 45 | Help for a specific command: 46 | help [command] 47 | 48 | Environment setup: 49 | 50 | export NEOCITIES_USER= 51 | export NEOCITIES_PASS= 52 | 53 | (OR) 54 | 55 | export NEOCITIES_KEY= 56 | 57 | ` 58 | 59 | func printUsage() { 60 | fmt.Print(helpText) 61 | } 62 | -------------------------------------------------------------------------------- /client/help_test.go: -------------------------------------------------------------------------------- 1 | package client 2 | 3 | import "testing" 4 | 5 | func TestHelp(t *testing.T) { 6 | t.Run("cmdHelp", func(t *testing.T) { 7 | h := cmdHelp 8 | 9 | if got, want := h.Usage, "help [command]"; got != want { 10 | t.Fatalf("h.Usage = %q, want %q", got, want) 11 | } 12 | 13 | if got, want := h.Short, "Show help"; got != want { 14 | t.Fatalf("h.Short = %q, want %q", got, want) 15 | } 16 | 17 | if got, want := h.Long, "Show usage instructions for a command"; got != want { 18 | t.Fatalf("h.Long = %q, want %q", got, want) 19 | } 20 | }) 21 | } 22 | -------------------------------------------------------------------------------- /client/info.go: -------------------------------------------------------------------------------- 1 | package client 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | 7 | "github.com/peterhellberg/neocities/api" 8 | ) 9 | 10 | var cmdInfo = &Command{ 11 | Run: runInfo, 12 | Usage: "info [sitename]", 13 | Short: "Info about Neocities websites", 14 | Long: "Info about your Neocities website, or somebody elses", 15 | } 16 | 17 | func init() { 18 | CmdRunner.Use(cmdInfo) 19 | } 20 | 21 | func runInfo(cmd *Command, args *Args) { 22 | var ( 23 | site string 24 | cred api.Credentials 25 | ) 26 | 27 | if args.IsParamsEmpty() { 28 | cred = getCredentials() 29 | site = cred.User 30 | } else { 31 | site = args.FirstParam() 32 | } 33 | 34 | response, err := api.SiteInfo(cred, site) 35 | if err != nil { 36 | response.Print() 37 | 38 | os.Exit(1) 39 | } 40 | 41 | if len(response.Body) > 0 { 42 | fmt.Print(string(response.Body)) 43 | } 44 | 45 | os.Exit(0) 46 | } 47 | -------------------------------------------------------------------------------- /client/info_test.go: -------------------------------------------------------------------------------- 1 | package client 2 | 3 | import "testing" 4 | 5 | func TestInfo(t *testing.T) { 6 | t.Run("cmdInfo", func(t *testing.T) { 7 | i := cmdInfo 8 | 9 | if got, want := i.Usage, "info [sitename]"; got != want { 10 | t.Fatalf("i.Usage = %q, want %q", got, want) 11 | } 12 | 13 | if got, want := i.Short, "Info about Neocities websites"; got != want { 14 | t.Fatalf("i.Short = %q, want %q", got, want) 15 | } 16 | 17 | if got, want := i.Long, "Info about your Neocities website, or somebody elses"; got != want { 18 | t.Fatalf("i.Long = %q, want %q", got, want) 19 | } 20 | }) 21 | } 22 | -------------------------------------------------------------------------------- /client/key.go: -------------------------------------------------------------------------------- 1 | package client 2 | 3 | import ( 4 | "fmt" 5 | 6 | "github.com/peterhellberg/neocities/api" 7 | ) 8 | 9 | var cmdKey = &Command{ 10 | Run: runKey, 11 | Usage: "key", 12 | Short: "Neocities API Key", 13 | Long: "Retrieve an API Key for your Neocities user", 14 | } 15 | 16 | func init() { 17 | CmdRunner.Use(cmdKey) 18 | } 19 | 20 | func runKey(cmd *Command, args *Args) { 21 | cred := getCredentials() 22 | 23 | kr, err := api.Key(cred) 24 | if err != nil { 25 | fmt.Println(err) 26 | return 27 | } 28 | 29 | fmt.Println(kr.APIKey) 30 | } 31 | -------------------------------------------------------------------------------- /client/list.go: -------------------------------------------------------------------------------- 1 | package client 2 | 3 | import ( 4 | "fmt" 5 | 6 | "github.com/peterhellberg/neocities/api" 7 | ) 8 | 9 | var cmdList = &Command{ 10 | Run: runList, 11 | Usage: "list", 12 | Short: "List files on Neocities", 13 | Long: "List files in your Neocities website", 14 | } 15 | 16 | func init() { 17 | CmdRunner.Use(cmdList) 18 | } 19 | 20 | func runList(cmd *Command, args *Args) { 21 | cred := getCredentials() 22 | 23 | list, err := api.List(cred) 24 | if err != nil { 25 | fmt.Println(err) 26 | return 27 | } 28 | 29 | dump(list) 30 | } 31 | -------------------------------------------------------------------------------- /client/runner.go: -------------------------------------------------------------------------------- 1 | package client 2 | 3 | import ( 4 | "os" 5 | 6 | flag "github.com/ogier/pflag" 7 | ) 8 | 9 | // Runner contains a map of commands 10 | type Runner struct { 11 | commands map[string]*Command 12 | } 13 | 14 | // NewRunner creates a new Runner 15 | func NewRunner() *Runner { 16 | return &Runner{ 17 | commands: make(map[string]*Command), 18 | } 19 | } 20 | 21 | // All returns all commands 22 | func (r *Runner) All() map[string]*Command { 23 | return r.commands 24 | } 25 | 26 | // Use adds the command to the runner 27 | func (r *Runner) Use(command *Command) { 28 | r.commands[command.Name()] = command 29 | } 30 | 31 | // Lookup looks up a command with the given name 32 | func (r *Runner) Lookup(name string) *Command { 33 | return r.commands[name] 34 | } 35 | 36 | // Execute executes a command 37 | func (r *Runner) Execute() ExecError { 38 | args := newArgs(os.Args[1:]) 39 | 40 | if args.Command == "" { 41 | printUsage() 42 | 43 | return newExecError(nil) 44 | } 45 | 46 | cmd := r.Lookup(args.Command) 47 | 48 | if cmd != nil && cmd.Runnable() { 49 | return r.Call(cmd, args) 50 | } 51 | 52 | return newExecError(nil) 53 | } 54 | 55 | // Call calls a command with the given args 56 | func (r *Runner) Call(cmd *Command, args *Args) ExecError { 57 | err := cmd.Call(args) 58 | if err != nil { 59 | if err == flag.ErrHelp { 60 | err = nil 61 | } 62 | 63 | return newExecError(err) 64 | } 65 | 66 | return newExecError(nil) 67 | } 68 | -------------------------------------------------------------------------------- /client/upload.go: -------------------------------------------------------------------------------- 1 | package client 2 | 3 | import ( 4 | "os" 5 | 6 | "github.com/peterhellberg/neocities/api" 7 | ) 8 | 9 | var cmdUpload = &Command{ 10 | Run: runUpload, 11 | Usage: "upload []", 12 | Short: "Upload files to Neocities", 13 | Long: "Upload files to your Neocities website", 14 | } 15 | 16 | func init() { 17 | CmdRunner.Use(cmdUpload) 18 | } 19 | 20 | func runUpload(cmd *Command, args *Args) { 21 | if args.IsParamsEmpty() { 22 | cmd.PrintUsage() 23 | 24 | os.Exit(0) 25 | } 26 | 27 | cred := getCredentials() 28 | 29 | files := args.Params 30 | 31 | response, err := api.UploadFiles(cred, files) 32 | if err != nil { 33 | response.Print() 34 | 35 | os.Exit(1) 36 | } 37 | 38 | if os.Getenv("NEOCITIES_VERBOSE") == "true" { 39 | response.Print() 40 | } 41 | 42 | os.Exit(0) 43 | } 44 | -------------------------------------------------------------------------------- /client/upload_test.go: -------------------------------------------------------------------------------- 1 | package client 2 | 3 | import "testing" 4 | 5 | func TestUpload(t *testing.T) { 6 | t.Run("cmdUpload", func(t *testing.T) { 7 | u := cmdUpload 8 | 9 | if got, want := u.Usage, "upload []"; got != want { 10 | t.Fatalf("u.Usage = %q, want %q", got, want) 11 | } 12 | 13 | if got, want := u.Short, "Upload files to Neocities"; got != want { 14 | t.Fatalf("u.Short = %q, want %q", got, want) 15 | } 16 | 17 | if got, want := u.Long, "Upload files to your Neocities website"; got != want { 18 | t.Fatalf("u.Long = %q, want %q", got, want) 19 | } 20 | }) 21 | } 22 | -------------------------------------------------------------------------------- /client/version.go: -------------------------------------------------------------------------------- 1 | package client 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | ) 7 | 8 | // Version contains the client version number 9 | const Version = "0.0.4" 10 | 11 | var cmdVersion = &Command{ 12 | Run: runVersion, 13 | Usage: "version", 14 | Short: "Show neocities version", 15 | Long: "Show the version number of the neocities client", 16 | } 17 | 18 | func init() { 19 | CmdRunner.Use(cmdVersion) 20 | } 21 | 22 | func runVersion(cmd *Command, args *Args) { 23 | fmt.Println("neocities version", Version) 24 | 25 | os.Exit(0) 26 | } 27 | -------------------------------------------------------------------------------- /client/version_test.go: -------------------------------------------------------------------------------- 1 | package client 2 | 3 | import "testing" 4 | 5 | func TestVersion(t *testing.T) { 6 | if got, want := Version, "0.0.4"; got != want { 7 | t.Fatalf("Version = %q, want %q", got, want) 8 | } 9 | 10 | t.Run("cmdVersion", func(t *testing.T) { 11 | v := cmdVersion 12 | 13 | if got, want := v.Usage, "version"; got != want { 14 | t.Fatalf("v.Usage = %q, want %q", got, want) 15 | } 16 | 17 | if got, want := v.Short, "Show neocities version"; got != want { 18 | t.Fatalf("v.Short = %q, want %q", got, want) 19 | } 20 | 21 | if got, want := v.Long, "Show the version number of the neocities client"; got != want { 22 | t.Fatalf("v.Long = %q, want %q", got, want) 23 | } 24 | }) 25 | } 26 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/peterhellberg/neocities 2 | 3 | go 1.23.4 4 | 5 | require github.com/ogier/pflag v0.0.1 6 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | github.com/ogier/pflag v0.0.1 h1:RW6JSWSu/RkSatfcLtogGfFgpim5p7ARQ10ECk5O750= 2 | github.com/ogier/pflag v0.0.1/go.mod h1:zkFki7tvTa0tafRvTBIZTvzYyAu6kQhPZFnshFFPE+g= 3 | -------------------------------------------------------------------------------- /main.go: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | A Neocities API client written in Go 4 | 5 | Installation 6 | 7 | Just go get the command: 8 | 9 | go get -u github.com/peterhellberg/neocities 10 | 11 | Usage 12 | 13 | First you need to export some environment variables: 14 | 15 | export NEOCITIES_USER= 16 | export NEOCITIES_PASS= 17 | 18 | Then you can run the command: 19 | 20 | neocities upload [] 21 | 22 | */ 23 | package main 24 | 25 | import ( 26 | "os" 27 | 28 | "github.com/peterhellberg/neocities/client" 29 | ) 30 | 31 | func main() { 32 | err := client.CmdRunner.Execute() 33 | 34 | os.Exit(err.ExitCode) 35 | } 36 | -------------------------------------------------------------------------------- /main_test.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "os" 5 | "os/exec" 6 | "strings" 7 | "testing" 8 | ) 9 | 10 | func TestNeocitiesCommand(t *testing.T) { 11 | t.Run("outputs usage instructions if no args", func(t *testing.T) { 12 | out := execGo("run", "main.go") 13 | expected := "neocities []" 14 | 15 | if !strings.Contains(out, expected) { 16 | t.Fatalf("%q does not contain %q", out, expected) 17 | } 18 | }) 19 | 20 | t.Run("can output help for command", func(t *testing.T) { 21 | out := execGo("run", "main.go", "help", "version") 22 | expected := "Show the version number of the neocities client" 23 | 24 | if !strings.Contains(out, expected) { 25 | t.Fatalf("%q does not contain %q", out, expected) 26 | } 27 | }) 28 | 29 | t.Run("outputs note about missing NEOCITIES_USER variable", func(t *testing.T) { 30 | os.Setenv("NEOCITIES_USER", "") 31 | 32 | out := execGo("run", "main.go", "upload", "LICENSE") 33 | expected := "Error: Missing environment variable NEOCITIES_USER or NEOCITIES_KEY" 34 | 35 | if !strings.Contains(out, expected) { 36 | t.Fatalf("%q does not contain %q", out, expected) 37 | } 38 | }) 39 | 40 | t.Run("outputs note about missing NEOCITIES_PASS variable", func(t *testing.T) { 41 | os.Setenv("NEOCITIES_USER", "foo") 42 | os.Setenv("NEOCITIES_PASS", "") 43 | 44 | out := execGo("run", "main.go", "upload", "LICENSE") 45 | expected := "Error: Missing environment variable NEOCITIES_PASS" 46 | 47 | if !strings.Contains(out, expected) { 48 | t.Fatalf("%q does not contain %q", out, expected) 49 | } 50 | }) 51 | } 52 | 53 | func execGo(args ...string) string { 54 | out, _ := exec.Command("go", args...).CombinedOutput() 55 | 56 | return string(out) 57 | } 58 | -------------------------------------------------------------------------------- /prepare_neocities_release.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | if [ "$#" -ne 1 ] 4 | then 5 | echo "Usage: ./prepare_neocities_release.sh " 6 | exit 1 7 | fi 8 | 9 | function createRelease { 10 | release_name="$RELEASE_BASE-$1-$2" 11 | release_dir="$RELEASES_DIR/$release_name" 12 | 13 | # Create the release dir 14 | mkdir -p $release_dir 15 | 16 | # Cross compile for the given OS/Arch 17 | GOOS=$1 GOARCH=$2 go build -o $release_dir/$3 18 | 19 | # Compress the binary (junk paths, quiet) 20 | zip -j -q -r $release_dir.zip $release_dir 21 | 22 | # Remove the binary 23 | rm $release_dir/$3 24 | 25 | # Remove the release dir 26 | rmdir $release_dir 27 | } 28 | 29 | RELEASES_DIR="/tmp/neocities/releases/$1" 30 | RELEASE_BASE="neocities-$1" 31 | 32 | # Architectures to create releases for 33 | 34 | WINDOWS_386=( 35 | windows 36 | 386 37 | neocities.exe 38 | ) 39 | 40 | WINDOWS_amd64=( 41 | windows 42 | amd64 43 | neocities.exe 44 | ) 45 | 46 | DARWIN_amd64=( 47 | darwin 48 | amd64 49 | neocities 50 | ) 51 | 52 | LINUX_amd64=( 53 | linux 54 | amd64 55 | neocities 56 | ) 57 | 58 | # Create the releases 59 | createRelease ${WINDOWS_386[@]} 60 | createRelease ${WINDOWS_amd64[@]} 61 | createRelease ${DARWIN_amd64[@]} 62 | createRelease ${LINUX_amd64[@]} 63 | 64 | # Open the releases dir 65 | open $RELEASES_DIR 66 | -------------------------------------------------------------------------------- /vendor/github.com/ogier/pflag/.travis.yml: -------------------------------------------------------------------------------- 1 | language: go 2 | -------------------------------------------------------------------------------- /vendor/github.com/ogier/pflag/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2012 Alex Ogier. All rights reserved. 2 | Copyright (c) 2012 The Go Authors. All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are 6 | met: 7 | 8 | * Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | * Redistributions in binary form must reproduce the above 11 | copyright notice, this list of conditions and the following disclaimer 12 | in the documentation and/or other materials provided with the 13 | distribution. 14 | * Neither the name of Google Inc. nor the names of its 15 | contributors may be used to endorse or promote products derived from 16 | this software without specific prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | -------------------------------------------------------------------------------- /vendor/github.com/ogier/pflag/README.md: -------------------------------------------------------------------------------- 1 | ## Description 2 | 3 | pflag is a drop-in replacement for Go's flag package, implementing 4 | POSIX/GNU-style --flags. 5 | 6 | pflag is compatible with the [GNU extensions to the POSIX recommendations 7 | for command-line options][1]. For a more precise description, see the 8 | "Command-line flag syntax" section below. 9 | 10 | [1]: http://www.gnu.org/software/libc/manual/html_node/Argument-Syntax.html 11 | 12 | pflag is available under the same style of BSD license as the Go language, 13 | which can be found in the LICENSE file. 14 | 15 | ## Installation 16 | 17 | pflag is available using the standard `go get` command. 18 | 19 | Install by running: 20 | 21 | go get github.com/ogier/pflag 22 | 23 | Run tests by running: 24 | 25 | go test github.com/ogier/pflag 26 | 27 | ## Usage 28 | 29 | pflag is a drop-in replacement of Go's native flag package. If you import 30 | pflag under the name "flag" then all code should continue to function 31 | with no changes. 32 | 33 | ``` go 34 | import flag "github.com/ogier/pflag" 35 | ``` 36 | 37 | There is one exception to this: if you directly instantiate the Flag struct 38 | there is one more field "Shorthand" that you will need to set. 39 | Most code never instantiates this struct directly, and instead uses 40 | functions such as String(), BoolVar(), and Var(), and is therefore 41 | unaffected. 42 | 43 | Define flags using flag.String(), Bool(), Int(), etc. 44 | 45 | This declares an integer flag, -flagname, stored in the pointer ip, with type *int. 46 | 47 | ``` go 48 | var ip *int = flag.Int("flagname", 1234, "help message for flagname") 49 | ``` 50 | 51 | If you like, you can bind the flag to a variable using the Var() functions. 52 | 53 | ``` go 54 | var flagvar int 55 | func init() { 56 | flag.IntVar(&flagvar, "flagname", 1234, "help message for flagname") 57 | } 58 | ``` 59 | 60 | Or you can create custom flags that satisfy the Value interface (with 61 | pointer receivers) and couple them to flag parsing by 62 | 63 | ``` go 64 | flag.Var(&flagVal, "name", "help message for flagname") 65 | ``` 66 | 67 | For such flags, the default value is just the initial value of the variable. 68 | 69 | After all flags are defined, call 70 | 71 | ``` go 72 | flag.Parse() 73 | ``` 74 | 75 | to parse the command line into the defined flags. 76 | 77 | Flags may then be used directly. If you're using the flags themselves, 78 | they are all pointers; if you bind to variables, they're values. 79 | 80 | ``` go 81 | fmt.Println("ip has value ", *ip) 82 | fmt.Println("flagvar has value ", flagvar) 83 | ``` 84 | 85 | After parsing, the arguments after the flag are available as the 86 | slice flag.Args() or individually as flag.Arg(i). 87 | The arguments are indexed from 0 through flag.NArg()-1. 88 | 89 | The pflag package also defines some new functions that are not in flag, 90 | that give one-letter shorthands for flags. You can use these by appending 91 | 'P' to the name of any function that defines a flag. 92 | 93 | ``` go 94 | var ip = flag.IntP("flagname", "f", 1234, "help message") 95 | var flagvar bool 96 | func init() { 97 | flag.BoolVarP("boolname", "b", true, "help message") 98 | } 99 | flag.VarP(&flagVar, "varname", "v", 1234, "help message") 100 | ``` 101 | 102 | Shorthand letters can be used with single dashes on the command line. 103 | Boolean shorthand flags can be combined with other shorthand flags. 104 | 105 | The default set of command-line flags is controlled by 106 | top-level functions. The FlagSet type allows one to define 107 | independent sets of flags, such as to implement subcommands 108 | in a command-line interface. The methods of FlagSet are 109 | analogous to the top-level functions for the command-line 110 | flag set. 111 | 112 | ## Command line flag syntax 113 | 114 | ``` 115 | --flag // boolean flags only 116 | --flag=x 117 | ``` 118 | 119 | Unlike the flag package, a single dash before an option means something 120 | different than a double dash. Single dashes signify a series of shorthand 121 | letters for flags. All but the last shorthand letter must be boolean flags. 122 | 123 | ``` 124 | // boolean flags 125 | -f 126 | -abc 127 | 128 | // non-boolean flags 129 | -n 1234 130 | -Ifile 131 | 132 | // mixed 133 | -abcs "hello" 134 | -abcn1234 135 | ``` 136 | 137 | Flag parsing stops after the terminator "--". Unlike the flag package, 138 | flags can be interspersed with arguments anywhere on the command line 139 | before this terminator. 140 | 141 | Integer flags accept 1234, 0664, 0x1234 and may be negative. 142 | Boolean flags (in their long form) accept 1, 0, t, f, true, false, 143 | TRUE, FALSE, True, False. 144 | Duration flags accept any input valid for time.ParseDuration. 145 | 146 | ## More info 147 | 148 | You can see the full reference documentation of the pflag package 149 | [at godoc.org][3], or through go's standard documentation system by 150 | running `godoc -http=:6060` and browsing to 151 | [http://localhost:6060/pkg/github.com/ogier/pflag][2] after 152 | installation. 153 | 154 | [2]: http://localhost:6060/pkg/github.com/ogier/pflag 155 | [3]: http://godoc.org/github.com/ogier/pflag 156 | -------------------------------------------------------------------------------- /vendor/github.com/ogier/pflag/bool.go: -------------------------------------------------------------------------------- 1 | package pflag 2 | 3 | import ( 4 | "fmt" 5 | "strconv" 6 | ) 7 | 8 | // optional interface to indicate boolean flags that can be 9 | // supplied without "=value" text 10 | type boolFlag interface { 11 | Value 12 | IsBoolFlag() bool 13 | } 14 | 15 | // -- bool Value 16 | type boolValue bool 17 | 18 | func newBoolValue(val bool, p *bool) *boolValue { 19 | *p = val 20 | return (*boolValue)(p) 21 | } 22 | 23 | func (b *boolValue) Set(s string) error { 24 | v, err := strconv.ParseBool(s) 25 | *b = boolValue(v) 26 | return err 27 | } 28 | 29 | func (b *boolValue) String() string { return fmt.Sprintf("%v", *b) } 30 | 31 | func (b *boolValue) IsBoolFlag() bool { return true } 32 | 33 | // BoolVar defines a bool flag with specified name, default value, and usage string. 34 | // The argument p points to a bool variable in which to store the value of the flag. 35 | func (f *FlagSet) BoolVar(p *bool, name string, value bool, usage string) { 36 | f.VarP(newBoolValue(value, p), name, "", usage) 37 | } 38 | 39 | // Like BoolVar, but accepts a shorthand letter that can be used after a single dash. 40 | func (f *FlagSet) BoolVarP(p *bool, name, shorthand string, value bool, usage string) { 41 | f.VarP(newBoolValue(value, p), name, shorthand, usage) 42 | } 43 | 44 | // BoolVar defines a bool flag with specified name, default value, and usage string. 45 | // The argument p points to a bool variable in which to store the value of the flag. 46 | func BoolVar(p *bool, name string, value bool, usage string) { 47 | CommandLine.VarP(newBoolValue(value, p), name, "", usage) 48 | } 49 | 50 | // Like BoolVar, but accepts a shorthand letter that can be used after a single dash. 51 | func BoolVarP(p *bool, name, shorthand string, value bool, usage string) { 52 | CommandLine.VarP(newBoolValue(value, p), name, shorthand, usage) 53 | } 54 | 55 | // Bool defines a bool flag with specified name, default value, and usage string. 56 | // The return value is the address of a bool variable that stores the value of the flag. 57 | func (f *FlagSet) Bool(name string, value bool, usage string) *bool { 58 | p := new(bool) 59 | f.BoolVarP(p, name, "", value, usage) 60 | return p 61 | } 62 | 63 | // Like Bool, but accepts a shorthand letter that can be used after a single dash. 64 | func (f *FlagSet) BoolP(name, shorthand string, value bool, usage string) *bool { 65 | p := new(bool) 66 | f.BoolVarP(p, name, shorthand, value, usage) 67 | return p 68 | } 69 | 70 | // Bool defines a bool flag with specified name, default value, and usage string. 71 | // The return value is the address of a bool variable that stores the value of the flag. 72 | func Bool(name string, value bool, usage string) *bool { 73 | return CommandLine.BoolP(name, "", value, usage) 74 | } 75 | 76 | // Like Bool, but accepts a shorthand letter that can be used after a single dash. 77 | func BoolP(name, shorthand string, value bool, usage string) *bool { 78 | return CommandLine.BoolP(name, shorthand, value, usage) 79 | } 80 | -------------------------------------------------------------------------------- /vendor/github.com/ogier/pflag/duration.go: -------------------------------------------------------------------------------- 1 | package pflag 2 | 3 | import "time" 4 | 5 | // -- time.Duration Value 6 | type durationValue time.Duration 7 | 8 | func newDurationValue(val time.Duration, p *time.Duration) *durationValue { 9 | *p = val 10 | return (*durationValue)(p) 11 | } 12 | 13 | func (d *durationValue) Set(s string) error { 14 | v, err := time.ParseDuration(s) 15 | *d = durationValue(v) 16 | return err 17 | } 18 | 19 | func (d *durationValue) String() string { return (*time.Duration)(d).String() } 20 | 21 | // Value is the interface to the dynamic value stored in a flag. 22 | // (The default value is represented as a string.) 23 | type Value interface { 24 | String() string 25 | Set(string) error 26 | } 27 | 28 | // DurationVar defines a time.Duration flag with specified name, default value, and usage string. 29 | // The argument p points to a time.Duration variable in which to store the value of the flag. 30 | func (f *FlagSet) DurationVar(p *time.Duration, name string, value time.Duration, usage string) { 31 | f.VarP(newDurationValue(value, p), name, "", usage) 32 | } 33 | 34 | // Like DurationVar, but accepts a shorthand letter that can be used after a single dash. 35 | func (f *FlagSet) DurationVarP(p *time.Duration, name, shorthand string, value time.Duration, usage string) { 36 | f.VarP(newDurationValue(value, p), name, shorthand, usage) 37 | } 38 | 39 | // DurationVar defines a time.Duration flag with specified name, default value, and usage string. 40 | // The argument p points to a time.Duration variable in which to store the value of the flag. 41 | func DurationVar(p *time.Duration, name string, value time.Duration, usage string) { 42 | CommandLine.VarP(newDurationValue(value, p), name, "", usage) 43 | } 44 | 45 | // Like DurationVar, but accepts a shorthand letter that can be used after a single dash. 46 | func DurationVarP(p *time.Duration, name, shorthand string, value time.Duration, usage string) { 47 | CommandLine.VarP(newDurationValue(value, p), name, shorthand, usage) 48 | } 49 | 50 | // Duration defines a time.Duration flag with specified name, default value, and usage string. 51 | // The return value is the address of a time.Duration variable that stores the value of the flag. 52 | func (f *FlagSet) Duration(name string, value time.Duration, usage string) *time.Duration { 53 | p := new(time.Duration) 54 | f.DurationVarP(p, name, "", value, usage) 55 | return p 56 | } 57 | 58 | // Like Duration, but accepts a shorthand letter that can be used after a single dash. 59 | func (f *FlagSet) DurationP(name, shorthand string, value time.Duration, usage string) *time.Duration { 60 | p := new(time.Duration) 61 | f.DurationVarP(p, name, shorthand, value, usage) 62 | return p 63 | } 64 | 65 | // Duration defines a time.Duration flag with specified name, default value, and usage string. 66 | // The return value is the address of a time.Duration variable that stores the value of the flag. 67 | func Duration(name string, value time.Duration, usage string) *time.Duration { 68 | return CommandLine.DurationP(name, "", value, usage) 69 | } 70 | 71 | // Like Duration, but accepts a shorthand letter that can be used after a single dash. 72 | func DurationP(name, shorthand string, value time.Duration, usage string) *time.Duration { 73 | return CommandLine.DurationP(name, shorthand, value, usage) 74 | } 75 | -------------------------------------------------------------------------------- /vendor/github.com/ogier/pflag/flag.go: -------------------------------------------------------------------------------- 1 | // Copyright 2009 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | /* 6 | pflag is a drop-in replacement for Go's flag package, implementing 7 | POSIX/GNU-style --flags. 8 | 9 | pflag is compatible with the GNU extensions to the POSIX recommendations 10 | for command-line options. See 11 | http://www.gnu.org/software/libc/manual/html_node/Argument-Syntax.html 12 | 13 | Usage: 14 | 15 | pflag is a drop-in replacement of Go's native flag package. If you import 16 | pflag under the name "flag" then all code should continue to function 17 | with no changes. 18 | 19 | import flag "github.com/ogier/pflag" 20 | 21 | There is one exception to this: if you directly instantiate the Flag struct 22 | there is one more field "Shorthand" that you will need to set. 23 | Most code never instantiates this struct directly, and instead uses 24 | functions such as String(), BoolVar(), and Var(), and is therefore 25 | unaffected. 26 | 27 | Define flags using flag.String(), Bool(), Int(), etc. 28 | 29 | This declares an integer flag, -flagname, stored in the pointer ip, with type *int. 30 | var ip = flag.Int("flagname", 1234, "help message for flagname") 31 | If you like, you can bind the flag to a variable using the Var() functions. 32 | var flagvar int 33 | func init() { 34 | flag.IntVar(&flagvar, "flagname", 1234, "help message for flagname") 35 | } 36 | Or you can create custom flags that satisfy the Value interface (with 37 | pointer receivers) and couple them to flag parsing by 38 | flag.Var(&flagVal, "name", "help message for flagname") 39 | For such flags, the default value is just the initial value of the variable. 40 | 41 | After all flags are defined, call 42 | flag.Parse() 43 | to parse the command line into the defined flags. 44 | 45 | Flags may then be used directly. If you're using the flags themselves, 46 | they are all pointers; if you bind to variables, they're values. 47 | fmt.Println("ip has value ", *ip) 48 | fmt.Println("flagvar has value ", flagvar) 49 | 50 | After parsing, the arguments after the flag are available as the 51 | slice flag.Args() or individually as flag.Arg(i). 52 | The arguments are indexed from 0 through flag.NArg()-1. 53 | 54 | The pflag package also defines some new functions that are not in flag, 55 | that give one-letter shorthands for flags. You can use these by appending 56 | 'P' to the name of any function that defines a flag. 57 | var ip = flag.IntP("flagname", "f", 1234, "help message") 58 | var flagvar bool 59 | func init() { 60 | flag.BoolVarP("boolname", "b", true, "help message") 61 | } 62 | flag.VarP(&flagVar, "varname", "v", 1234, "help message") 63 | Shorthand letters can be used with single dashes on the command line. 64 | Boolean shorthand flags can be combined with other shorthand flags. 65 | 66 | Command line flag syntax: 67 | --flag // boolean flags only 68 | --flag=x 69 | 70 | Unlike the flag package, a single dash before an option means something 71 | different than a double dash. Single dashes signify a series of shorthand 72 | letters for flags. All but the last shorthand letter must be boolean flags. 73 | // boolean flags 74 | -f 75 | -abc 76 | // non-boolean flags 77 | -n 1234 78 | -Ifile 79 | // mixed 80 | -abcs "hello" 81 | -abcn1234 82 | 83 | Flag parsing stops after the terminator "--". Unlike the flag package, 84 | flags can be interspersed with arguments anywhere on the command line 85 | before this terminator. 86 | 87 | Integer flags accept 1234, 0664, 0x1234 and may be negative. 88 | Boolean flags (in their long form) accept 1, 0, t, f, true, false, 89 | TRUE, FALSE, True, False. 90 | Duration flags accept any input valid for time.ParseDuration. 91 | 92 | The default set of command-line flags is controlled by 93 | top-level functions. The FlagSet type allows one to define 94 | independent sets of flags, such as to implement subcommands 95 | in a command-line interface. The methods of FlagSet are 96 | analogous to the top-level functions for the command-line 97 | flag set. 98 | */ 99 | package pflag 100 | 101 | import ( 102 | "errors" 103 | "fmt" 104 | "io" 105 | "os" 106 | "sort" 107 | "strings" 108 | ) 109 | 110 | // ErrHelp is the error returned if the flag -help is invoked but no such flag is defined. 111 | var ErrHelp = errors.New("pflag: help requested") 112 | 113 | // ErrorHandling defines how to handle flag parsing errors. 114 | type ErrorHandling int 115 | 116 | const ( 117 | ContinueOnError ErrorHandling = iota 118 | ExitOnError 119 | PanicOnError 120 | ) 121 | 122 | // A FlagSet represents a set of defined flags. 123 | type FlagSet struct { 124 | // Usage is the function called when an error occurs while parsing flags. 125 | // The field is a function (not a method) that may be changed to point to 126 | // a custom error handler. 127 | Usage func() 128 | 129 | name string 130 | parsed bool 131 | actual map[string]*Flag 132 | formal map[string]*Flag 133 | shorthands map[byte]*Flag 134 | args []string // arguments after flags 135 | exitOnError bool // does the program exit if there's an error? 136 | errorHandling ErrorHandling 137 | output io.Writer // nil means stderr; use out() accessor 138 | interspersed bool // allow interspersed option/non-option args 139 | } 140 | 141 | // A Flag represents the state of a flag. 142 | type Flag struct { 143 | Name string // name as it appears on command line 144 | Shorthand string // one-letter abbreviated flag 145 | Usage string // help message 146 | Value Value // value as set 147 | DefValue string // default value (as text); for usage message 148 | } 149 | 150 | // sortFlags returns the flags as a slice in lexicographical sorted order. 151 | func sortFlags(flags map[string]*Flag) []*Flag { 152 | list := make(sort.StringSlice, len(flags)) 153 | i := 0 154 | for _, f := range flags { 155 | list[i] = f.Name 156 | i++ 157 | } 158 | list.Sort() 159 | result := make([]*Flag, len(list)) 160 | for i, name := range list { 161 | result[i] = flags[name] 162 | } 163 | return result 164 | } 165 | 166 | func (f *FlagSet) out() io.Writer { 167 | if f.output == nil { 168 | return os.Stderr 169 | } 170 | return f.output 171 | } 172 | 173 | // SetOutput sets the destination for usage and error messages. 174 | // If output is nil, os.Stderr is used. 175 | func (f *FlagSet) SetOutput(output io.Writer) { 176 | f.output = output 177 | } 178 | 179 | // VisitAll visits the flags in lexicographical order, calling fn for each. 180 | // It visits all flags, even those not set. 181 | func (f *FlagSet) VisitAll(fn func(*Flag)) { 182 | for _, flag := range sortFlags(f.formal) { 183 | fn(flag) 184 | } 185 | } 186 | 187 | // VisitAll visits the command-line flags in lexicographical order, calling 188 | // fn for each. It visits all flags, even those not set. 189 | func VisitAll(fn func(*Flag)) { 190 | CommandLine.VisitAll(fn) 191 | } 192 | 193 | // Visit visits the flags in lexicographical order, calling fn for each. 194 | // It visits only those flags that have been set. 195 | func (f *FlagSet) Visit(fn func(*Flag)) { 196 | for _, flag := range sortFlags(f.actual) { 197 | fn(flag) 198 | } 199 | } 200 | 201 | // Visit visits the command-line flags in lexicographical order, calling fn 202 | // for each. It visits only those flags that have been set. 203 | func Visit(fn func(*Flag)) { 204 | CommandLine.Visit(fn) 205 | } 206 | 207 | // Lookup returns the Flag structure of the named flag, returning nil if none exists. 208 | func (f *FlagSet) Lookup(name string) *Flag { 209 | return f.formal[name] 210 | } 211 | 212 | // Lookup returns the Flag structure of the named command-line flag, 213 | // returning nil if none exists. 214 | func Lookup(name string) *Flag { 215 | return CommandLine.formal[name] 216 | } 217 | 218 | // Set sets the value of the named flag. 219 | func (f *FlagSet) Set(name, value string) error { 220 | flag, ok := f.formal[name] 221 | if !ok { 222 | return fmt.Errorf("no such flag -%v", name) 223 | } 224 | err := flag.Value.Set(value) 225 | if err != nil { 226 | return err 227 | } 228 | if f.actual == nil { 229 | f.actual = make(map[string]*Flag) 230 | } 231 | f.actual[name] = flag 232 | return nil 233 | } 234 | 235 | // Set sets the value of the named command-line flag. 236 | func Set(name, value string) error { 237 | return CommandLine.Set(name, value) 238 | } 239 | 240 | // PrintDefaults prints, to standard error unless configured 241 | // otherwise, the default values of all defined flags in the set. 242 | func (f *FlagSet) PrintDefaults() { 243 | f.VisitAll(func(flag *Flag) { 244 | format := "--%s=%s: %s\n" 245 | if _, ok := flag.Value.(*stringValue); ok { 246 | // put quotes on the value 247 | format = "--%s=%q: %s\n" 248 | } 249 | if len(flag.Shorthand) > 0 { 250 | format = " -%s, " + format 251 | } else { 252 | format = " %s " + format 253 | } 254 | fmt.Fprintf(f.out(), format, flag.Shorthand, flag.Name, flag.DefValue, flag.Usage) 255 | }) 256 | } 257 | 258 | // PrintDefaults prints to standard error the default values of all defined command-line flags. 259 | func PrintDefaults() { 260 | CommandLine.PrintDefaults() 261 | } 262 | 263 | // defaultUsage is the default function to print a usage message. 264 | func defaultUsage(f *FlagSet) { 265 | fmt.Fprintf(f.out(), "Usage of %s:\n", f.name) 266 | f.PrintDefaults() 267 | } 268 | 269 | // NOTE: Usage is not just defaultUsage(CommandLine) 270 | // because it serves (via godoc flag Usage) as the example 271 | // for how to write your own usage function. 272 | 273 | // Usage prints to standard error a usage message documenting all defined command-line flags. 274 | // The function is a variable that may be changed to point to a custom function. 275 | var Usage = func() { 276 | fmt.Fprintf(os.Stderr, "Usage of %s:\n", os.Args[0]) 277 | PrintDefaults() 278 | } 279 | 280 | // NFlag returns the number of flags that have been set. 281 | func (f *FlagSet) NFlag() int { return len(f.actual) } 282 | 283 | // NFlag returns the number of command-line flags that have been set. 284 | func NFlag() int { return len(CommandLine.actual) } 285 | 286 | // Arg returns the i'th argument. Arg(0) is the first remaining argument 287 | // after flags have been processed. 288 | func (f *FlagSet) Arg(i int) string { 289 | if i < 0 || i >= len(f.args) { 290 | return "" 291 | } 292 | return f.args[i] 293 | } 294 | 295 | // Arg returns the i'th command-line argument. Arg(0) is the first remaining argument 296 | // after flags have been processed. 297 | func Arg(i int) string { 298 | return CommandLine.Arg(i) 299 | } 300 | 301 | // NArg is the number of arguments remaining after flags have been processed. 302 | func (f *FlagSet) NArg() int { return len(f.args) } 303 | 304 | // NArg is the number of arguments remaining after flags have been processed. 305 | func NArg() int { return len(CommandLine.args) } 306 | 307 | // Args returns the non-flag arguments. 308 | func (f *FlagSet) Args() []string { return f.args } 309 | 310 | // Args returns the non-flag command-line arguments. 311 | func Args() []string { return CommandLine.args } 312 | 313 | // Var defines a flag with the specified name and usage string. The type and 314 | // value of the flag are represented by the first argument, of type Value, which 315 | // typically holds a user-defined implementation of Value. For instance, the 316 | // caller could create a flag that turns a comma-separated string into a slice 317 | // of strings by giving the slice the methods of Value; in particular, Set would 318 | // decompose the comma-separated string into the slice. 319 | func (f *FlagSet) Var(value Value, name string, usage string) { 320 | f.VarP(value, name, "", usage) 321 | } 322 | 323 | // Like Var, but accepts a shorthand letter that can be used after a single dash. 324 | func (f *FlagSet) VarP(value Value, name, shorthand, usage string) { 325 | // Remember the default value as a string; it won't change. 326 | flag := &Flag{name, shorthand, usage, value, value.String()} 327 | _, alreadythere := f.formal[name] 328 | if alreadythere { 329 | msg := fmt.Sprintf("%s flag redefined: %s", f.name, name) 330 | fmt.Fprintln(f.out(), msg) 331 | panic(msg) // Happens only if flags are declared with identical names 332 | } 333 | if f.formal == nil { 334 | f.formal = make(map[string]*Flag) 335 | } 336 | f.formal[name] = flag 337 | 338 | if len(shorthand) == 0 { 339 | return 340 | } 341 | if len(shorthand) > 1 { 342 | fmt.Fprintf(f.out(), "%s shorthand more than ASCII character: %s\n", f.name, shorthand) 343 | panic("shorthand is more than one character") 344 | } 345 | if f.shorthands == nil { 346 | f.shorthands = make(map[byte]*Flag) 347 | } 348 | c := shorthand[0] 349 | old, alreadythere := f.shorthands[c] 350 | if alreadythere { 351 | fmt.Fprintf(f.out(), "%s shorthand reused: %q for %s already used for %s\n", f.name, c, name, old.Name) 352 | panic("shorthand redefinition") 353 | } 354 | f.shorthands[c] = flag 355 | } 356 | 357 | // Var defines a flag with the specified name and usage string. The type and 358 | // value of the flag are represented by the first argument, of type Value, which 359 | // typically holds a user-defined implementation of Value. For instance, the 360 | // caller could create a flag that turns a comma-separated string into a slice 361 | // of strings by giving the slice the methods of Value; in particular, Set would 362 | // decompose the comma-separated string into the slice. 363 | func Var(value Value, name string, usage string) { 364 | CommandLine.VarP(value, name, "", usage) 365 | } 366 | 367 | // Like Var, but accepts a shorthand letter that can be used after a single dash. 368 | func VarP(value Value, name, shorthand, usage string) { 369 | CommandLine.VarP(value, name, shorthand, usage) 370 | } 371 | 372 | // failf prints to standard error a formatted error and usage message and 373 | // returns the error. 374 | func (f *FlagSet) failf(format string, a ...interface{}) error { 375 | err := fmt.Errorf(format, a...) 376 | fmt.Fprintln(f.out(), err) 377 | f.usage() 378 | return err 379 | } 380 | 381 | // usage calls the Usage method for the flag set, or the usage function if 382 | // the flag set is CommandLine. 383 | func (f *FlagSet) usage() { 384 | if f == CommandLine { 385 | Usage() 386 | } else if f.Usage == nil { 387 | defaultUsage(f) 388 | } else { 389 | f.Usage() 390 | } 391 | } 392 | 393 | func (f *FlagSet) setFlag(flag *Flag, value string, origArg string) error { 394 | if err := flag.Value.Set(value); err != nil { 395 | return f.failf("invalid argument %q for %s: %v", value, origArg, err) 396 | } 397 | // mark as visited for Visit() 398 | if f.actual == nil { 399 | f.actual = make(map[string]*Flag) 400 | } 401 | f.actual[flag.Name] = flag 402 | 403 | return nil 404 | } 405 | 406 | func (f *FlagSet) parseArgs(args []string) error { 407 | for len(args) > 0 { 408 | s := args[0] 409 | args = args[1:] 410 | if len(s) == 0 || s[0] != '-' || len(s) == 1 { 411 | if !f.interspersed { 412 | f.args = append(f.args, s) 413 | f.args = append(f.args, args...) 414 | return nil 415 | } 416 | f.args = append(f.args, s) 417 | continue 418 | } 419 | 420 | if s[1] == '-' { 421 | if len(s) == 2 { // "--" terminates the flags 422 | f.args = append(f.args, args...) 423 | return nil 424 | } 425 | name := s[2:] 426 | if len(name) == 0 || name[0] == '-' || name[0] == '=' { 427 | return f.failf("bad flag syntax: %s", s) 428 | } 429 | split := strings.SplitN(name, "=", 2) 430 | name = split[0] 431 | m := f.formal 432 | flag, alreadythere := m[name] // BUG 433 | if !alreadythere { 434 | if name == "help" { // special case for nice help message. 435 | f.usage() 436 | return ErrHelp 437 | } 438 | return f.failf("unknown flag: --%s", name) 439 | } 440 | if len(split) == 1 { 441 | if bv, ok := flag.Value.(boolFlag); !ok || !bv.IsBoolFlag() { 442 | return f.failf("flag needs an argument: %s", s) 443 | } 444 | f.setFlag(flag, "true", s) 445 | } else { 446 | if err := f.setFlag(flag, split[1], s); err != nil { 447 | return err 448 | } 449 | } 450 | } else { 451 | shorthands := s[1:] 452 | for i := 0; i < len(shorthands); i++ { 453 | c := shorthands[i] 454 | flag, alreadythere := f.shorthands[c] 455 | if !alreadythere { 456 | if c == 'h' { // special case for nice help message. 457 | f.usage() 458 | return ErrHelp 459 | } 460 | return f.failf("unknown shorthand flag: %q in -%s", c, shorthands) 461 | } 462 | if bv, ok := flag.Value.(boolFlag); ok && bv.IsBoolFlag() { 463 | f.setFlag(flag, "true", s) 464 | continue 465 | } 466 | if i < len(shorthands)-1 { 467 | if err := f.setFlag(flag, shorthands[i+1:], s); err != nil { 468 | return err 469 | } 470 | break 471 | } 472 | if len(args) == 0 { 473 | return f.failf("flag needs an argument: %q in -%s", c, shorthands) 474 | } 475 | if err := f.setFlag(flag, args[0], s); err != nil { 476 | return err 477 | } 478 | args = args[1:] 479 | break // should be unnecessary 480 | } 481 | } 482 | } 483 | return nil 484 | } 485 | 486 | // Parse parses flag definitions from the argument list, which should not 487 | // include the command name. Must be called after all flags in the FlagSet 488 | // are defined and before flags are accessed by the program. 489 | // The return value will be ErrHelp if -help was set but not defined. 490 | func (f *FlagSet) Parse(arguments []string) error { 491 | f.parsed = true 492 | f.args = make([]string, 0, len(arguments)) 493 | err := f.parseArgs(arguments) 494 | if err != nil { 495 | switch f.errorHandling { 496 | case ContinueOnError: 497 | return err 498 | case ExitOnError: 499 | os.Exit(2) 500 | case PanicOnError: 501 | panic(err) 502 | } 503 | } 504 | return nil 505 | } 506 | 507 | // Parsed reports whether f.Parse has been called. 508 | func (f *FlagSet) Parsed() bool { 509 | return f.parsed 510 | } 511 | 512 | // Parse parses the command-line flags from os.Args[1:]. Must be called 513 | // after all flags are defined and before flags are accessed by the program. 514 | func Parse() { 515 | // Ignore errors; CommandLine is set for ExitOnError. 516 | CommandLine.Parse(os.Args[1:]) 517 | } 518 | 519 | // Whether to support interspersed option/non-option arguments. 520 | func SetInterspersed(interspersed bool) { 521 | CommandLine.SetInterspersed(interspersed) 522 | } 523 | 524 | // Parsed returns true if the command-line flags have been parsed. 525 | func Parsed() bool { 526 | return CommandLine.Parsed() 527 | } 528 | 529 | // The default set of command-line flags, parsed from os.Args. 530 | var CommandLine = NewFlagSet(os.Args[0], ExitOnError) 531 | 532 | // NewFlagSet returns a new, empty flag set with the specified name and 533 | // error handling property. 534 | func NewFlagSet(name string, errorHandling ErrorHandling) *FlagSet { 535 | f := &FlagSet{ 536 | name: name, 537 | errorHandling: errorHandling, 538 | interspersed: true, 539 | } 540 | return f 541 | } 542 | 543 | // Whether to support interspersed option/non-option arguments. 544 | func (f *FlagSet) SetInterspersed(interspersed bool) { 545 | f.interspersed = interspersed 546 | } 547 | 548 | // Init sets the name and error handling property for a flag set. 549 | // By default, the zero FlagSet uses an empty name and the 550 | // ContinueOnError error handling policy. 551 | func (f *FlagSet) Init(name string, errorHandling ErrorHandling) { 552 | f.name = name 553 | f.errorHandling = errorHandling 554 | } 555 | -------------------------------------------------------------------------------- /vendor/github.com/ogier/pflag/float32.go: -------------------------------------------------------------------------------- 1 | package pflag 2 | 3 | import ( 4 | "fmt" 5 | "strconv" 6 | ) 7 | 8 | // -- float32 Value 9 | type float32Value float32 10 | 11 | func newFloat32Value(val float32, p *float32) *float32Value { 12 | *p = val 13 | return (*float32Value)(p) 14 | } 15 | 16 | func (f *float32Value) Set(s string) error { 17 | v, err := strconv.ParseFloat(s, 32) 18 | *f = float32Value(v) 19 | return err 20 | } 21 | 22 | func (f *float32Value) String() string { return fmt.Sprintf("%v", *f) } 23 | 24 | // Float32Var defines a float32 flag with specified name, default value, and usage string. 25 | // The argument p points to a float32 variable in which to store the value of the flag. 26 | func (f *FlagSet) Float32Var(p *float32, name string, value float32, usage string) { 27 | f.VarP(newFloat32Value(value, p), name, "", usage) 28 | } 29 | 30 | // Like Float32Var, but accepts a shorthand letter that can be used after a single dash. 31 | func (f *FlagSet) Float32VarP(p *float32, name, shorthand string, value float32, usage string) { 32 | f.VarP(newFloat32Value(value, p), name, shorthand, usage) 33 | } 34 | 35 | // Float32Var defines a float32 flag with specified name, default value, and usage string. 36 | // The argument p points to a float32 variable in which to store the value of the flag. 37 | func Float32Var(p *float32, name string, value float32, usage string) { 38 | CommandLine.VarP(newFloat32Value(value, p), name, "", usage) 39 | } 40 | 41 | // Like Float32Var, but accepts a shorthand letter that can be used after a single dash. 42 | func Float32VarP(p *float32, name, shorthand string, value float32, usage string) { 43 | CommandLine.VarP(newFloat32Value(value, p), name, shorthand, usage) 44 | } 45 | 46 | // Float32 defines a float32 flag with specified name, default value, and usage string. 47 | // The return value is the address of a float32 variable that stores the value of the flag. 48 | func (f *FlagSet) Float32(name string, value float32, usage string) *float32 { 49 | p := new(float32) 50 | f.Float32VarP(p, name, "", value, usage) 51 | return p 52 | } 53 | 54 | // Like Float32, but accepts a shorthand letter that can be used after a single dash. 55 | func (f *FlagSet) Float32P(name, shorthand string, value float32, usage string) *float32 { 56 | p := new(float32) 57 | f.Float32VarP(p, name, shorthand, value, usage) 58 | return p 59 | } 60 | 61 | // Float32 defines a float32 flag with specified name, default value, and usage string. 62 | // The return value is the address of a float32 variable that stores the value of the flag. 63 | func Float32(name string, value float32, usage string) *float32 { 64 | return CommandLine.Float32P(name, "", value, usage) 65 | } 66 | 67 | // Like Float32, but accepts a shorthand letter that can be used after a single dash. 68 | func Float32P(name, shorthand string, value float32, usage string) *float32 { 69 | return CommandLine.Float32P(name, shorthand, value, usage) 70 | } 71 | -------------------------------------------------------------------------------- /vendor/github.com/ogier/pflag/float64.go: -------------------------------------------------------------------------------- 1 | package pflag 2 | 3 | import ( 4 | "fmt" 5 | "strconv" 6 | ) 7 | 8 | // -- float64 Value 9 | type float64Value float64 10 | 11 | func newFloat64Value(val float64, p *float64) *float64Value { 12 | *p = val 13 | return (*float64Value)(p) 14 | } 15 | 16 | func (f *float64Value) Set(s string) error { 17 | v, err := strconv.ParseFloat(s, 64) 18 | *f = float64Value(v) 19 | return err 20 | } 21 | 22 | func (f *float64Value) String() string { return fmt.Sprintf("%v", *f) } 23 | 24 | // Float64Var defines a float64 flag with specified name, default value, and usage string. 25 | // The argument p points to a float64 variable in which to store the value of the flag. 26 | func (f *FlagSet) Float64Var(p *float64, name string, value float64, usage string) { 27 | f.VarP(newFloat64Value(value, p), name, "", usage) 28 | } 29 | 30 | // Like Float64Var, but accepts a shorthand letter that can be used after a single dash. 31 | func (f *FlagSet) Float64VarP(p *float64, name, shorthand string, value float64, usage string) { 32 | f.VarP(newFloat64Value(value, p), name, shorthand, usage) 33 | } 34 | 35 | // Float64Var defines a float64 flag with specified name, default value, and usage string. 36 | // The argument p points to a float64 variable in which to store the value of the flag. 37 | func Float64Var(p *float64, name string, value float64, usage string) { 38 | CommandLine.VarP(newFloat64Value(value, p), name, "", usage) 39 | } 40 | 41 | // Like Float64Var, but accepts a shorthand letter that can be used after a single dash. 42 | func Float64VarP(p *float64, name, shorthand string, value float64, usage string) { 43 | CommandLine.VarP(newFloat64Value(value, p), name, shorthand, usage) 44 | } 45 | 46 | // Float64 defines a float64 flag with specified name, default value, and usage string. 47 | // The return value is the address of a float64 variable that stores the value of the flag. 48 | func (f *FlagSet) Float64(name string, value float64, usage string) *float64 { 49 | p := new(float64) 50 | f.Float64VarP(p, name, "", value, usage) 51 | return p 52 | } 53 | 54 | // Like Float64, but accepts a shorthand letter that can be used after a single dash. 55 | func (f *FlagSet) Float64P(name, shorthand string, value float64, usage string) *float64 { 56 | p := new(float64) 57 | f.Float64VarP(p, name, shorthand, value, usage) 58 | return p 59 | } 60 | 61 | // Float64 defines a float64 flag with specified name, default value, and usage string. 62 | // The return value is the address of a float64 variable that stores the value of the flag. 63 | func Float64(name string, value float64, usage string) *float64 { 64 | return CommandLine.Float64P(name, "", value, usage) 65 | } 66 | 67 | // Like Float64, but accepts a shorthand letter that can be used after a single dash. 68 | func Float64P(name, shorthand string, value float64, usage string) *float64 { 69 | return CommandLine.Float64P(name, shorthand, value, usage) 70 | } 71 | -------------------------------------------------------------------------------- /vendor/github.com/ogier/pflag/int.go: -------------------------------------------------------------------------------- 1 | package pflag 2 | 3 | import ( 4 | "fmt" 5 | "strconv" 6 | ) 7 | 8 | // -- int Value 9 | type intValue int 10 | 11 | func newIntValue(val int, p *int) *intValue { 12 | *p = val 13 | return (*intValue)(p) 14 | } 15 | 16 | func (i *intValue) Set(s string) error { 17 | v, err := strconv.ParseInt(s, 0, 64) 18 | *i = intValue(v) 19 | return err 20 | } 21 | 22 | func (i *intValue) String() string { return fmt.Sprintf("%v", *i) } 23 | 24 | // IntVar defines an int flag with specified name, default value, and usage string. 25 | // The argument p points to an int variable in which to store the value of the flag. 26 | func (f *FlagSet) IntVar(p *int, name string, value int, usage string) { 27 | f.VarP(newIntValue(value, p), name, "", usage) 28 | } 29 | 30 | // Like IntVar, but accepts a shorthand letter that can be used after a single dash. 31 | func (f *FlagSet) IntVarP(p *int, name, shorthand string, value int, usage string) { 32 | f.VarP(newIntValue(value, p), name, shorthand, usage) 33 | } 34 | 35 | // IntVar defines an int flag with specified name, default value, and usage string. 36 | // The argument p points to an int variable in which to store the value of the flag. 37 | func IntVar(p *int, name string, value int, usage string) { 38 | CommandLine.VarP(newIntValue(value, p), name, "", usage) 39 | } 40 | 41 | // Like IntVar, but accepts a shorthand letter that can be used after a single dash. 42 | func IntVarP(p *int, name, shorthand string, value int, usage string) { 43 | CommandLine.VarP(newIntValue(value, p), name, shorthand, usage) 44 | } 45 | 46 | // Int defines an int flag with specified name, default value, and usage string. 47 | // The return value is the address of an int variable that stores the value of the flag. 48 | func (f *FlagSet) Int(name string, value int, usage string) *int { 49 | p := new(int) 50 | f.IntVarP(p, name, "", value, usage) 51 | return p 52 | } 53 | 54 | // Like Int, but accepts a shorthand letter that can be used after a single dash. 55 | func (f *FlagSet) IntP(name, shorthand string, value int, usage string) *int { 56 | p := new(int) 57 | f.IntVarP(p, name, shorthand, value, usage) 58 | return p 59 | } 60 | 61 | // Int defines an int flag with specified name, default value, and usage string. 62 | // The return value is the address of an int variable that stores the value of the flag. 63 | func Int(name string, value int, usage string) *int { 64 | return CommandLine.IntP(name, "", value, usage) 65 | } 66 | 67 | // Like Int, but accepts a shorthand letter that can be used after a single dash. 68 | func IntP(name, shorthand string, value int, usage string) *int { 69 | return CommandLine.IntP(name, shorthand, value, usage) 70 | } 71 | -------------------------------------------------------------------------------- /vendor/github.com/ogier/pflag/int32.go: -------------------------------------------------------------------------------- 1 | package pflag 2 | 3 | import ( 4 | "fmt" 5 | "strconv" 6 | ) 7 | 8 | // -- int32 Value 9 | type int32Value int32 10 | 11 | func newInt32Value(val int32, p *int32) *int32Value { 12 | *p = val 13 | return (*int32Value)(p) 14 | } 15 | 16 | func (i *int32Value) Set(s string) error { 17 | v, err := strconv.ParseInt(s, 0, 32) 18 | *i = int32Value(v) 19 | return err 20 | } 21 | 22 | func (i *int32Value) String() string { return fmt.Sprintf("%v", *i) } 23 | 24 | // Int32Var defines an int32 flag with specified name, default value, and usage string. 25 | // The argument p points to an int32 variable in which to store the value of the flag. 26 | func (f *FlagSet) Int32Var(p *int32, name string, value int32, usage string) { 27 | f.VarP(newInt32Value(value, p), name, "", usage) 28 | } 29 | 30 | // Like Int32Var, but accepts a shorthand letter that can be used after a single dash. 31 | func (f *FlagSet) Int32VarP(p *int32, name, shorthand string, value int32, usage string) { 32 | f.VarP(newInt32Value(value, p), name, shorthand, usage) 33 | } 34 | 35 | // Int32Var defines an int32 flag with specified name, default value, and usage string. 36 | // The argument p points to an int32 variable in which to store the value of the flag. 37 | func Int32Var(p *int32, name string, value int32, usage string) { 38 | CommandLine.VarP(newInt32Value(value, p), name, "", usage) 39 | } 40 | 41 | // Like Int32Var, but accepts a shorthand letter that can be used after a single dash. 42 | func Int32VarP(p *int32, name, shorthand string, value int32, usage string) { 43 | CommandLine.VarP(newInt32Value(value, p), name, shorthand, usage) 44 | } 45 | 46 | // Int32 defines an int32 flag with specified name, default value, and usage string. 47 | // The return value is the address of an int32 variable that stores the value of the flag. 48 | func (f *FlagSet) Int32(name string, value int32, usage string) *int32 { 49 | p := new(int32) 50 | f.Int32VarP(p, name, "", value, usage) 51 | return p 52 | } 53 | 54 | // Like Int32, but accepts a shorthand letter that can be used after a single dash. 55 | func (f *FlagSet) Int32P(name, shorthand string, value int32, usage string) *int32 { 56 | p := new(int32) 57 | f.Int32VarP(p, name, shorthand, value, usage) 58 | return p 59 | } 60 | 61 | // Int32 defines an int32 flag with specified name, default value, and usage string. 62 | // The return value is the address of an int32 variable that stores the value of the flag. 63 | func Int32(name string, value int32, usage string) *int32 { 64 | return CommandLine.Int32P(name, "", value, usage) 65 | } 66 | 67 | // Like Int32, but accepts a shorthand letter that can be used after a single dash. 68 | func Int32P(name, shorthand string, value int32, usage string) *int32 { 69 | return CommandLine.Int32P(name, shorthand, value, usage) 70 | } 71 | -------------------------------------------------------------------------------- /vendor/github.com/ogier/pflag/int64.go: -------------------------------------------------------------------------------- 1 | package pflag 2 | 3 | import ( 4 | "fmt" 5 | "strconv" 6 | ) 7 | 8 | // -- int64 Value 9 | type int64Value int64 10 | 11 | func newInt64Value(val int64, p *int64) *int64Value { 12 | *p = val 13 | return (*int64Value)(p) 14 | } 15 | 16 | func (i *int64Value) Set(s string) error { 17 | v, err := strconv.ParseInt(s, 0, 64) 18 | *i = int64Value(v) 19 | return err 20 | } 21 | 22 | func (i *int64Value) String() string { return fmt.Sprintf("%v", *i) } 23 | 24 | // Int64Var defines an int64 flag with specified name, default value, and usage string. 25 | // The argument p points to an int64 variable in which to store the value of the flag. 26 | func (f *FlagSet) Int64Var(p *int64, name string, value int64, usage string) { 27 | f.VarP(newInt64Value(value, p), name, "", usage) 28 | } 29 | 30 | // Like Int64Var, but accepts a shorthand letter that can be used after a single dash. 31 | func (f *FlagSet) Int64VarP(p *int64, name, shorthand string, value int64, usage string) { 32 | f.VarP(newInt64Value(value, p), name, shorthand, usage) 33 | } 34 | 35 | // Int64Var defines an int64 flag with specified name, default value, and usage string. 36 | // The argument p points to an int64 variable in which to store the value of the flag. 37 | func Int64Var(p *int64, name string, value int64, usage string) { 38 | CommandLine.VarP(newInt64Value(value, p), name, "", usage) 39 | } 40 | 41 | // Like Int64Var, but accepts a shorthand letter that can be used after a single dash. 42 | func Int64VarP(p *int64, name, shorthand string, value int64, usage string) { 43 | CommandLine.VarP(newInt64Value(value, p), name, shorthand, usage) 44 | } 45 | 46 | // Int64 defines an int64 flag with specified name, default value, and usage string. 47 | // The return value is the address of an int64 variable that stores the value of the flag. 48 | func (f *FlagSet) Int64(name string, value int64, usage string) *int64 { 49 | p := new(int64) 50 | f.Int64VarP(p, name, "", value, usage) 51 | return p 52 | } 53 | 54 | // Like Int64, but accepts a shorthand letter that can be used after a single dash. 55 | func (f *FlagSet) Int64P(name, shorthand string, value int64, usage string) *int64 { 56 | p := new(int64) 57 | f.Int64VarP(p, name, shorthand, value, usage) 58 | return p 59 | } 60 | 61 | // Int64 defines an int64 flag with specified name, default value, and usage string. 62 | // The return value is the address of an int64 variable that stores the value of the flag. 63 | func Int64(name string, value int64, usage string) *int64 { 64 | return CommandLine.Int64P(name, "", value, usage) 65 | } 66 | 67 | // Like Int64, but accepts a shorthand letter that can be used after a single dash. 68 | func Int64P(name, shorthand string, value int64, usage string) *int64 { 69 | return CommandLine.Int64P(name, shorthand, value, usage) 70 | } 71 | -------------------------------------------------------------------------------- /vendor/github.com/ogier/pflag/int8.go: -------------------------------------------------------------------------------- 1 | package pflag 2 | 3 | import ( 4 | "fmt" 5 | "strconv" 6 | ) 7 | 8 | // -- int8 Value 9 | type int8Value int8 10 | 11 | func newInt8Value(val int8, p *int8) *int8Value { 12 | *p = val 13 | return (*int8Value)(p) 14 | } 15 | 16 | func (i *int8Value) Set(s string) error { 17 | v, err := strconv.ParseInt(s, 0, 8) 18 | *i = int8Value(v) 19 | return err 20 | } 21 | 22 | func (i *int8Value) String() string { return fmt.Sprintf("%v", *i) } 23 | 24 | // Int8Var defines an int8 flag with specified name, default value, and usage string. 25 | // The argument p points to an int8 variable in which to store the value of the flag. 26 | func (f *FlagSet) Int8Var(p *int8, name string, value int8, usage string) { 27 | f.VarP(newInt8Value(value, p), name, "", usage) 28 | } 29 | 30 | // Like Int8Var, but accepts a shorthand letter that can be used after a single dash. 31 | func (f *FlagSet) Int8VarP(p *int8, name, shorthand string, value int8, usage string) { 32 | f.VarP(newInt8Value(value, p), name, shorthand, usage) 33 | } 34 | 35 | // Int8Var defines an int8 flag with specified name, default value, and usage string. 36 | // The argument p points to an int8 variable in which to store the value of the flag. 37 | func Int8Var(p *int8, name string, value int8, usage string) { 38 | CommandLine.VarP(newInt8Value(value, p), name, "", usage) 39 | } 40 | 41 | // Like Int8Var, but accepts a shorthand letter that can be used after a single dash. 42 | func Int8VarP(p *int8, name, shorthand string, value int8, usage string) { 43 | CommandLine.VarP(newInt8Value(value, p), name, shorthand, usage) 44 | } 45 | 46 | // Int8 defines an int8 flag with specified name, default value, and usage string. 47 | // The return value is the address of an int8 variable that stores the value of the flag. 48 | func (f *FlagSet) Int8(name string, value int8, usage string) *int8 { 49 | p := new(int8) 50 | f.Int8VarP(p, name, "", value, usage) 51 | return p 52 | } 53 | 54 | // Like Int8, but accepts a shorthand letter that can be used after a single dash. 55 | func (f *FlagSet) Int8P(name, shorthand string, value int8, usage string) *int8 { 56 | p := new(int8) 57 | f.Int8VarP(p, name, shorthand, value, usage) 58 | return p 59 | } 60 | 61 | // Int8 defines an int8 flag with specified name, default value, and usage string. 62 | // The return value is the address of an int8 variable that stores the value of the flag. 63 | func Int8(name string, value int8, usage string) *int8 { 64 | return CommandLine.Int8P(name, "", value, usage) 65 | } 66 | 67 | // Like Int8, but accepts a shorthand letter that can be used after a single dash. 68 | func Int8P(name, shorthand string, value int8, usage string) *int8 { 69 | return CommandLine.Int8P(name, shorthand, value, usage) 70 | } 71 | -------------------------------------------------------------------------------- /vendor/github.com/ogier/pflag/ip.go: -------------------------------------------------------------------------------- 1 | package pflag 2 | 3 | import ( 4 | "fmt" 5 | "net" 6 | ) 7 | 8 | // -- net.IP value 9 | type ipValue net.IP 10 | 11 | func newIPValue(val net.IP, p *net.IP) *ipValue { 12 | *p = val 13 | return (*ipValue)(p) 14 | } 15 | 16 | func (i *ipValue) String() string { return net.IP(*i).String() } 17 | func (i *ipValue) Set(s string) error { 18 | ip := net.ParseIP(s) 19 | if ip == nil { 20 | return fmt.Errorf("failed to parse IP: %q", s) 21 | } 22 | *i = ipValue(ip) 23 | return nil 24 | } 25 | func (i *ipValue) Get() interface{} { 26 | return net.IP(*i) 27 | } 28 | 29 | // IPVar defines an net.IP flag with specified name, default value, and usage string. 30 | // The argument p points to an net.IP variable in which to store the value of the flag. 31 | func (f *FlagSet) IPVar(p *net.IP, name string, value net.IP, usage string) { 32 | f.VarP(newIPValue(value, p), name, "", usage) 33 | } 34 | 35 | // Like IPVar, but accepts a shorthand letter that can be used after a single dash. 36 | func (f *FlagSet) IPVarP(p *net.IP, name, shorthand string, value net.IP, usage string) { 37 | f.VarP(newIPValue(value, p), name, shorthand, usage) 38 | } 39 | 40 | // IPVar defines an net.IP flag with specified name, default value, and usage string. 41 | // The argument p points to an net.IP variable in which to store the value of the flag. 42 | func IPVar(p *net.IP, name string, value net.IP, usage string) { 43 | CommandLine.VarP(newIPValue(value, p), name, "", usage) 44 | } 45 | 46 | // Like IPVar, but accepts a shorthand letter that can be used after a single dash. 47 | func IPVarP(p *net.IP, name, shorthand string, value net.IP, usage string) { 48 | CommandLine.VarP(newIPValue(value, p), name, shorthand, usage) 49 | } 50 | 51 | // IP defines an net.IP flag with specified name, default value, and usage string. 52 | // The return value is the address of an net.IP variable that stores the value of the flag. 53 | func (f *FlagSet) IP(name string, value net.IP, usage string) *net.IP { 54 | p := new(net.IP) 55 | f.IPVarP(p, name, "", value, usage) 56 | return p 57 | } 58 | 59 | // Like IP, but accepts a shorthand letter that can be used after a single dash. 60 | func (f *FlagSet) IPP(name, shorthand string, value net.IP, usage string) *net.IP { 61 | p := new(net.IP) 62 | f.IPVarP(p, name, shorthand, value, usage) 63 | return p 64 | } 65 | 66 | // IP defines an net.IP flag with specified name, default value, and usage string. 67 | // The return value is the address of an net.IP variable that stores the value of the flag. 68 | func IP(name string, value net.IP, usage string) *net.IP { 69 | return CommandLine.IPP(name, "", value, usage) 70 | } 71 | 72 | // Like IP, but accepts a shorthand letter that can be used after a single dash. 73 | func IPP(name, shorthand string, value net.IP, usage string) *net.IP { 74 | return CommandLine.IPP(name, shorthand, value, usage) 75 | } 76 | -------------------------------------------------------------------------------- /vendor/github.com/ogier/pflag/ipmask.go: -------------------------------------------------------------------------------- 1 | package pflag 2 | 3 | import ( 4 | "fmt" 5 | "net" 6 | ) 7 | 8 | // -- net.IPMask value 9 | type ipMaskValue net.IPMask 10 | 11 | func newIPMaskValue(val net.IPMask, p *net.IPMask) *ipMaskValue { 12 | *p = val 13 | return (*ipMaskValue)(p) 14 | } 15 | 16 | func (i *ipMaskValue) String() string { return net.IPMask(*i).String() } 17 | func (i *ipMaskValue) Set(s string) error { 18 | ip := ParseIPv4Mask(s) 19 | if ip == nil { 20 | return fmt.Errorf("failed to parse IP mask: %q", s) 21 | } 22 | *i = ipMaskValue(ip) 23 | return nil 24 | } 25 | func (i *ipMaskValue) Get() interface{} { 26 | return net.IPMask(*i) 27 | } 28 | 29 | // Parse IPv4 netmask written in IP form (e.g. 255.255.255.0). 30 | // This function should really belong to the net package. 31 | func ParseIPv4Mask(s string) net.IPMask { 32 | mask := net.ParseIP(s) 33 | if mask == nil { 34 | return nil 35 | } 36 | return net.IPv4Mask(mask[12], mask[13], mask[14], mask[15]) 37 | } 38 | 39 | // IPMaskVar defines an net.IPMask flag with specified name, default value, and usage string. 40 | // The argument p points to an net.IPMask variable in which to store the value of the flag. 41 | func (f *FlagSet) IPMaskVar(p *net.IPMask, name string, value net.IPMask, usage string) { 42 | f.VarP(newIPMaskValue(value, p), name, "", usage) 43 | } 44 | 45 | // Like IPMaskVar, but accepts a shorthand letter that can be used after a single dash. 46 | func (f *FlagSet) IPMaskVarP(p *net.IPMask, name, shorthand string, value net.IPMask, usage string) { 47 | f.VarP(newIPMaskValue(value, p), name, shorthand, usage) 48 | } 49 | 50 | // IPMaskVar defines an net.IPMask flag with specified name, default value, and usage string. 51 | // The argument p points to an net.IPMask variable in which to store the value of the flag. 52 | func IPMaskVar(p *net.IPMask, name string, value net.IPMask, usage string) { 53 | CommandLine.VarP(newIPMaskValue(value, p), name, "", usage) 54 | } 55 | 56 | // Like IPMaskVar, but accepts a shorthand letter that can be used after a single dash. 57 | func IPMaskVarP(p *net.IPMask, name, shorthand string, value net.IPMask, usage string) { 58 | CommandLine.VarP(newIPMaskValue(value, p), name, shorthand, usage) 59 | } 60 | 61 | // IPMask defines an net.IPMask flag with specified name, default value, and usage string. 62 | // The return value is the address of an net.IPMask variable that stores the value of the flag. 63 | func (f *FlagSet) IPMask(name string, value net.IPMask, usage string) *net.IPMask { 64 | p := new(net.IPMask) 65 | f.IPMaskVarP(p, name, "", value, usage) 66 | return p 67 | } 68 | 69 | // Like IPMask, but accepts a shorthand letter that can be used after a single dash. 70 | func (f *FlagSet) IPMaskP(name, shorthand string, value net.IPMask, usage string) *net.IPMask { 71 | p := new(net.IPMask) 72 | f.IPMaskVarP(p, name, shorthand, value, usage) 73 | return p 74 | } 75 | 76 | // IPMask defines an net.IPMask flag with specified name, default value, and usage string. 77 | // The return value is the address of an net.IPMask variable that stores the value of the flag. 78 | func IPMask(name string, value net.IPMask, usage string) *net.IPMask { 79 | return CommandLine.IPMaskP(name, "", value, usage) 80 | } 81 | 82 | // Like IP, but accepts a shorthand letter that can be used after a single dash. 83 | func IPMaskP(name, shorthand string, value net.IPMask, usage string) *net.IPMask { 84 | return CommandLine.IPMaskP(name, shorthand, value, usage) 85 | } 86 | -------------------------------------------------------------------------------- /vendor/github.com/ogier/pflag/string.go: -------------------------------------------------------------------------------- 1 | package pflag 2 | 3 | import "fmt" 4 | 5 | // -- string Value 6 | type stringValue string 7 | 8 | func newStringValue(val string, p *string) *stringValue { 9 | *p = val 10 | return (*stringValue)(p) 11 | } 12 | 13 | func (s *stringValue) Set(val string) error { 14 | *s = stringValue(val) 15 | return nil 16 | } 17 | 18 | func (s *stringValue) String() string { return fmt.Sprintf("%s", *s) } 19 | 20 | // StringVar defines a string flag with specified name, default value, and usage string. 21 | // The argument p points to a string variable in which to store the value of the flag. 22 | func (f *FlagSet) StringVar(p *string, name string, value string, usage string) { 23 | f.VarP(newStringValue(value, p), name, "", usage) 24 | } 25 | 26 | // Like StringVar, but accepts a shorthand letter that can be used after a single dash. 27 | func (f *FlagSet) StringVarP(p *string, name, shorthand string, value string, usage string) { 28 | f.VarP(newStringValue(value, p), name, shorthand, usage) 29 | } 30 | 31 | // StringVar defines a string flag with specified name, default value, and usage string. 32 | // The argument p points to a string variable in which to store the value of the flag. 33 | func StringVar(p *string, name string, value string, usage string) { 34 | CommandLine.VarP(newStringValue(value, p), name, "", usage) 35 | } 36 | 37 | // Like StringVar, but accepts a shorthand letter that can be used after a single dash. 38 | func StringVarP(p *string, name, shorthand string, value string, usage string) { 39 | CommandLine.VarP(newStringValue(value, p), name, shorthand, usage) 40 | } 41 | 42 | // String defines a string flag with specified name, default value, and usage string. 43 | // The return value is the address of a string variable that stores the value of the flag. 44 | func (f *FlagSet) String(name string, value string, usage string) *string { 45 | p := new(string) 46 | f.StringVarP(p, name, "", value, usage) 47 | return p 48 | } 49 | 50 | // Like String, but accepts a shorthand letter that can be used after a single dash. 51 | func (f *FlagSet) StringP(name, shorthand string, value string, usage string) *string { 52 | p := new(string) 53 | f.StringVarP(p, name, shorthand, value, usage) 54 | return p 55 | } 56 | 57 | // String defines a string flag with specified name, default value, and usage string. 58 | // The return value is the address of a string variable that stores the value of the flag. 59 | func String(name string, value string, usage string) *string { 60 | return CommandLine.StringP(name, "", value, usage) 61 | } 62 | 63 | // Like String, but accepts a shorthand letter that can be used after a single dash. 64 | func StringP(name, shorthand string, value string, usage string) *string { 65 | return CommandLine.StringP(name, shorthand, value, usage) 66 | } 67 | -------------------------------------------------------------------------------- /vendor/github.com/ogier/pflag/uint.go: -------------------------------------------------------------------------------- 1 | package pflag 2 | 3 | import ( 4 | "fmt" 5 | "strconv" 6 | ) 7 | 8 | // -- uint Value 9 | type uintValue uint 10 | 11 | func newUintValue(val uint, p *uint) *uintValue { 12 | *p = val 13 | return (*uintValue)(p) 14 | } 15 | 16 | func (i *uintValue) Set(s string) error { 17 | v, err := strconv.ParseUint(s, 0, 64) 18 | *i = uintValue(v) 19 | return err 20 | } 21 | 22 | func (i *uintValue) String() string { return fmt.Sprintf("%v", *i) } 23 | 24 | // UintVar defines a uint flag with specified name, default value, and usage string. 25 | // The argument p points to a uint variable in which to store the value of the flag. 26 | func (f *FlagSet) UintVar(p *uint, name string, value uint, usage string) { 27 | f.VarP(newUintValue(value, p), name, "", usage) 28 | } 29 | 30 | // Like UintVar, but accepts a shorthand letter that can be used after a single dash. 31 | func (f *FlagSet) UintVarP(p *uint, name, shorthand string, value uint, usage string) { 32 | f.VarP(newUintValue(value, p), name, shorthand, usage) 33 | } 34 | 35 | // UintVar defines a uint flag with specified name, default value, and usage string. 36 | // The argument p points to a uint variable in which to store the value of the flag. 37 | func UintVar(p *uint, name string, value uint, usage string) { 38 | CommandLine.VarP(newUintValue(value, p), name, "", usage) 39 | } 40 | 41 | // Like UintVar, but accepts a shorthand letter that can be used after a single dash. 42 | func UintVarP(p *uint, name, shorthand string, value uint, usage string) { 43 | CommandLine.VarP(newUintValue(value, p), name, shorthand, usage) 44 | } 45 | 46 | // Uint defines a uint flag with specified name, default value, and usage string. 47 | // The return value is the address of a uint variable that stores the value of the flag. 48 | func (f *FlagSet) Uint(name string, value uint, usage string) *uint { 49 | p := new(uint) 50 | f.UintVarP(p, name, "", value, usage) 51 | return p 52 | } 53 | 54 | // Like Uint, but accepts a shorthand letter that can be used after a single dash. 55 | func (f *FlagSet) UintP(name, shorthand string, value uint, usage string) *uint { 56 | p := new(uint) 57 | f.UintVarP(p, name, shorthand, value, usage) 58 | return p 59 | } 60 | 61 | // Uint defines a uint flag with specified name, default value, and usage string. 62 | // The return value is the address of a uint variable that stores the value of the flag. 63 | func Uint(name string, value uint, usage string) *uint { 64 | return CommandLine.UintP(name, "", value, usage) 65 | } 66 | 67 | // Like Uint, but accepts a shorthand letter that can be used after a single dash. 68 | func UintP(name, shorthand string, value uint, usage string) *uint { 69 | return CommandLine.UintP(name, shorthand, value, usage) 70 | } 71 | -------------------------------------------------------------------------------- /vendor/github.com/ogier/pflag/uint16.go: -------------------------------------------------------------------------------- 1 | package pflag 2 | 3 | import ( 4 | "fmt" 5 | "strconv" 6 | ) 7 | 8 | // -- uint16 value 9 | type uint16Value uint16 10 | 11 | func newUint16Value(val uint16, p *uint16) *uint16Value { 12 | *p = val 13 | return (*uint16Value)(p) 14 | } 15 | func (i *uint16Value) String() string { return fmt.Sprintf("%d", *i) } 16 | func (i *uint16Value) Set(s string) error { 17 | v, err := strconv.ParseUint(s, 0, 16) 18 | *i = uint16Value(v) 19 | return err 20 | } 21 | func (i *uint16Value) Get() interface{} { 22 | return uint16(*i) 23 | } 24 | 25 | // Uint16Var defines a uint flag with specified name, default value, and usage string. 26 | // The argument p points to a uint variable in which to store the value of the flag. 27 | func (f *FlagSet) Uint16Var(p *uint16, name string, value uint16, usage string) { 28 | f.VarP(newUint16Value(value, p), name, "", usage) 29 | } 30 | 31 | // Like Uint16Var, but accepts a shorthand letter that can be used after a single dash. 32 | func (f *FlagSet) Uint16VarP(p *uint16, name, shorthand string, value uint16, usage string) { 33 | f.VarP(newUint16Value(value, p), name, shorthand, usage) 34 | } 35 | 36 | // Uint16Var defines a uint flag with specified name, default value, and usage string. 37 | // The argument p points to a uint variable in which to store the value of the flag. 38 | func Uint16Var(p *uint16, name string, value uint16, usage string) { 39 | CommandLine.VarP(newUint16Value(value, p), name, "", usage) 40 | } 41 | 42 | // Like Uint16Var, but accepts a shorthand letter that can be used after a single dash. 43 | func Uint16VarP(p *uint16, name, shorthand string, value uint16, usage string) { 44 | CommandLine.VarP(newUint16Value(value, p), name, shorthand, usage) 45 | } 46 | 47 | // Uint16 defines a uint flag with specified name, default value, and usage string. 48 | // The return value is the address of a uint variable that stores the value of the flag. 49 | func (f *FlagSet) Uint16(name string, value uint16, usage string) *uint16 { 50 | p := new(uint16) 51 | f.Uint16VarP(p, name, "", value, usage) 52 | return p 53 | } 54 | 55 | // Like Uint16, but accepts a shorthand letter that can be used after a single dash. 56 | func (f *FlagSet) Uint16P(name, shorthand string, value uint16, usage string) *uint16 { 57 | p := new(uint16) 58 | f.Uint16VarP(p, name, shorthand, value, usage) 59 | return p 60 | } 61 | 62 | // Uint16 defines a uint flag with specified name, default value, and usage string. 63 | // The return value is the address of a uint variable that stores the value of the flag. 64 | func Uint16(name string, value uint16, usage string) *uint16 { 65 | return CommandLine.Uint16P(name, "", value, usage) 66 | } 67 | 68 | // Like Uint16, but accepts a shorthand letter that can be used after a single dash. 69 | func Uint16P(name, shorthand string, value uint16, usage string) *uint16 { 70 | return CommandLine.Uint16P(name, shorthand, value, usage) 71 | } 72 | -------------------------------------------------------------------------------- /vendor/github.com/ogier/pflag/uint32.go: -------------------------------------------------------------------------------- 1 | package pflag 2 | 3 | import ( 4 | "fmt" 5 | "strconv" 6 | ) 7 | 8 | // -- uint16 value 9 | type uint32Value uint32 10 | 11 | func newUint32Value(val uint32, p *uint32) *uint32Value { 12 | *p = val 13 | return (*uint32Value)(p) 14 | } 15 | func (i *uint32Value) String() string { return fmt.Sprintf("%d", *i) } 16 | func (i *uint32Value) Set(s string) error { 17 | v, err := strconv.ParseUint(s, 0, 32) 18 | *i = uint32Value(v) 19 | return err 20 | } 21 | func (i *uint32Value) Get() interface{} { 22 | return uint32(*i) 23 | } 24 | 25 | // Uint32Var defines a uint32 flag with specified name, default value, and usage string. 26 | // The argument p points to a uint32 variable in which to store the value of the flag. 27 | func (f *FlagSet) Uint32Var(p *uint32, name string, value uint32, usage string) { 28 | f.VarP(newUint32Value(value, p), name, "", usage) 29 | } 30 | 31 | // Like Uint32Var, but accepts a shorthand letter that can be used after a single dash. 32 | func (f *FlagSet) Uint32VarP(p *uint32, name, shorthand string, value uint32, usage string) { 33 | f.VarP(newUint32Value(value, p), name, shorthand, usage) 34 | } 35 | 36 | // Uint32Var defines a uint32 flag with specified name, default value, and usage string. 37 | // The argument p points to a uint32 variable in which to store the value of the flag. 38 | func Uint32Var(p *uint32, name string, value uint32, usage string) { 39 | CommandLine.VarP(newUint32Value(value, p), name, "", usage) 40 | } 41 | 42 | // Like Uint32Var, but accepts a shorthand letter that can be used after a single dash. 43 | func Uint32VarP(p *uint32, name, shorthand string, value uint32, usage string) { 44 | CommandLine.VarP(newUint32Value(value, p), name, shorthand, usage) 45 | } 46 | 47 | // Uint32 defines a uint32 flag with specified name, default value, and usage string. 48 | // The return value is the address of a uint32 variable that stores the value of the flag. 49 | func (f *FlagSet) Uint32(name string, value uint32, usage string) *uint32 { 50 | p := new(uint32) 51 | f.Uint32VarP(p, name, "", value, usage) 52 | return p 53 | } 54 | 55 | // Like Uint32, but accepts a shorthand letter that can be used after a single dash. 56 | func (f *FlagSet) Uint32P(name, shorthand string, value uint32, usage string) *uint32 { 57 | p := new(uint32) 58 | f.Uint32VarP(p, name, shorthand, value, usage) 59 | return p 60 | } 61 | 62 | // Uint32 defines a uint32 flag with specified name, default value, and usage string. 63 | // The return value is the address of a uint32 variable that stores the value of the flag. 64 | func Uint32(name string, value uint32, usage string) *uint32 { 65 | return CommandLine.Uint32P(name, "", value, usage) 66 | } 67 | 68 | // Like Uint32, but accepts a shorthand letter that can be used after a single dash. 69 | func Uint32P(name, shorthand string, value uint32, usage string) *uint32 { 70 | return CommandLine.Uint32P(name, shorthand, value, usage) 71 | } 72 | -------------------------------------------------------------------------------- /vendor/github.com/ogier/pflag/uint64.go: -------------------------------------------------------------------------------- 1 | package pflag 2 | 3 | import ( 4 | "fmt" 5 | "strconv" 6 | ) 7 | 8 | // -- uint64 Value 9 | type uint64Value uint64 10 | 11 | func newUint64Value(val uint64, p *uint64) *uint64Value { 12 | *p = val 13 | return (*uint64Value)(p) 14 | } 15 | 16 | func (i *uint64Value) Set(s string) error { 17 | v, err := strconv.ParseUint(s, 0, 64) 18 | *i = uint64Value(v) 19 | return err 20 | } 21 | 22 | func (i *uint64Value) String() string { return fmt.Sprintf("%v", *i) } 23 | 24 | // Uint64Var defines a uint64 flag with specified name, default value, and usage string. 25 | // The argument p points to a uint64 variable in which to store the value of the flag. 26 | func (f *FlagSet) Uint64Var(p *uint64, name string, value uint64, usage string) { 27 | f.VarP(newUint64Value(value, p), name, "", usage) 28 | } 29 | 30 | // Like Uint64Var, but accepts a shorthand letter that can be used after a single dash. 31 | func (f *FlagSet) Uint64VarP(p *uint64, name, shorthand string, value uint64, usage string) { 32 | f.VarP(newUint64Value(value, p), name, shorthand, usage) 33 | } 34 | 35 | // Uint64Var defines a uint64 flag with specified name, default value, and usage string. 36 | // The argument p points to a uint64 variable in which to store the value of the flag. 37 | func Uint64Var(p *uint64, name string, value uint64, usage string) { 38 | CommandLine.VarP(newUint64Value(value, p), name, "", usage) 39 | } 40 | 41 | // Like Uint64Var, but accepts a shorthand letter that can be used after a single dash. 42 | func Uint64VarP(p *uint64, name, shorthand string, value uint64, usage string) { 43 | CommandLine.VarP(newUint64Value(value, p), name, shorthand, usage) 44 | } 45 | 46 | // Uint64 defines a uint64 flag with specified name, default value, and usage string. 47 | // The return value is the address of a uint64 variable that stores the value of the flag. 48 | func (f *FlagSet) Uint64(name string, value uint64, usage string) *uint64 { 49 | p := new(uint64) 50 | f.Uint64VarP(p, name, "", value, usage) 51 | return p 52 | } 53 | 54 | // Like Uint64, but accepts a shorthand letter that can be used after a single dash. 55 | func (f *FlagSet) Uint64P(name, shorthand string, value uint64, usage string) *uint64 { 56 | p := new(uint64) 57 | f.Uint64VarP(p, name, shorthand, value, usage) 58 | return p 59 | } 60 | 61 | // Uint64 defines a uint64 flag with specified name, default value, and usage string. 62 | // The return value is the address of a uint64 variable that stores the value of the flag. 63 | func Uint64(name string, value uint64, usage string) *uint64 { 64 | return CommandLine.Uint64P(name, "", value, usage) 65 | } 66 | 67 | // Like Uint64, but accepts a shorthand letter that can be used after a single dash. 68 | func Uint64P(name, shorthand string, value uint64, usage string) *uint64 { 69 | return CommandLine.Uint64P(name, shorthand, value, usage) 70 | } 71 | -------------------------------------------------------------------------------- /vendor/github.com/ogier/pflag/uint8.go: -------------------------------------------------------------------------------- 1 | package pflag 2 | 3 | import ( 4 | "fmt" 5 | "strconv" 6 | ) 7 | 8 | // -- uint8 Value 9 | type uint8Value uint8 10 | 11 | func newUint8Value(val uint8, p *uint8) *uint8Value { 12 | *p = val 13 | return (*uint8Value)(p) 14 | } 15 | 16 | func (i *uint8Value) Set(s string) error { 17 | v, err := strconv.ParseUint(s, 0, 8) 18 | *i = uint8Value(v) 19 | return err 20 | } 21 | 22 | func (i *uint8Value) String() string { return fmt.Sprintf("%v", *i) } 23 | 24 | // Uint8Var defines a uint8 flag with specified name, default value, and usage string. 25 | // The argument p points to a uint8 variable in which to store the value of the flag. 26 | func (f *FlagSet) Uint8Var(p *uint8, name string, value uint8, usage string) { 27 | f.VarP(newUint8Value(value, p), name, "", usage) 28 | } 29 | 30 | // Like Uint8Var, but accepts a shorthand letter that can be used after a single dash. 31 | func (f *FlagSet) Uint8VarP(p *uint8, name, shorthand string, value uint8, usage string) { 32 | f.VarP(newUint8Value(value, p), name, shorthand, usage) 33 | } 34 | 35 | // Uint8Var defines a uint8 flag with specified name, default value, and usage string. 36 | // The argument p points to a uint8 variable in which to store the value of the flag. 37 | func Uint8Var(p *uint8, name string, value uint8, usage string) { 38 | CommandLine.VarP(newUint8Value(value, p), name, "", usage) 39 | } 40 | 41 | // Like Uint8Var, but accepts a shorthand letter that can be used after a single dash. 42 | func Uint8VarP(p *uint8, name, shorthand string, value uint8, usage string) { 43 | CommandLine.VarP(newUint8Value(value, p), name, shorthand, usage) 44 | } 45 | 46 | // Uint8 defines a uint8 flag with specified name, default value, and usage string. 47 | // The return value is the address of a uint8 variable that stores the value of the flag. 48 | func (f *FlagSet) Uint8(name string, value uint8, usage string) *uint8 { 49 | p := new(uint8) 50 | f.Uint8VarP(p, name, "", value, usage) 51 | return p 52 | } 53 | 54 | // Like Uint8, but accepts a shorthand letter that can be used after a single dash. 55 | func (f *FlagSet) Uint8P(name, shorthand string, value uint8, usage string) *uint8 { 56 | p := new(uint8) 57 | f.Uint8VarP(p, name, shorthand, value, usage) 58 | return p 59 | } 60 | 61 | // Uint8 defines a uint8 flag with specified name, default value, and usage string. 62 | // The return value is the address of a uint8 variable that stores the value of the flag. 63 | func Uint8(name string, value uint8, usage string) *uint8 { 64 | return CommandLine.Uint8P(name, "", value, usage) 65 | } 66 | 67 | // Like Uint8, but accepts a shorthand letter that can be used after a single dash. 68 | func Uint8P(name, shorthand string, value uint8, usage string) *uint8 { 69 | return CommandLine.Uint8P(name, shorthand, value, usage) 70 | } 71 | -------------------------------------------------------------------------------- /vendor/modules.txt: -------------------------------------------------------------------------------- 1 | # github.com/ogier/pflag v0.0.1 2 | ## explicit 3 | github.com/ogier/pflag 4 | --------------------------------------------------------------------------------