Skip to content

Commit

Permalink
feat(cmd): Add --url flag to load a pattern URL
Browse files Browse the repository at this point in the history
  • Loading branch information
gabe565 committed Jul 15, 2024
1 parent 9718c91 commit 2be8e5c
Show file tree
Hide file tree
Showing 5 changed files with 54 additions and 4 deletions.
11 changes: 9 additions & 2 deletions cmd/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,16 @@ func run(cmd *cobra.Command, _ []string) error {
pat := pattern.Pattern{
Rule: rule,
}
if conf.File != "" {
format := pattern.Format(conf.FileFormat)
switch {
case conf.File != "":
var err error
if pat, err = pattern.UnmarshalFile(conf.File, pattern.Format(conf.FileFormat)); err != nil {
if pat, err = pattern.UnmarshalFile(conf.File, format); err != nil {
return err
}
case conf.URL != "":
var err error
if pat, err = pattern.UnmarshalURL(context.Background(), conf.URL, format); err != nil {
return err
}
}
Expand Down
3 changes: 2 additions & 1 deletion docs/cli-of-life.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,13 @@ cli-of-life [flags]

```
--completion string Output command-line completion code for the specified shell (one of: bash, zsh, fish, powershell)
-f, --file string Loads a pattern file on startup
-f, --file string Load a pattern file
--file-format string File format (one of: auto, rle, plaintext) (default "auto")
--height uint Board height. Will be ignored if a larger pattern is loaded. (default 600)
-h, --help help for cli-of-life
--play Play on startup
--rule-string string Rule string to use. This will be ignored if a pattern file is loaded. (default "B3/S23")
--url string Load a pattern URL
--width uint Board width. Will be ignored if a larger pattern is loaded. (default 600)
```

1 change: 1 addition & 0 deletions internal/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import "github.com/gabe565/cli-of-life/internal/pattern"

type Config struct {
File string
URL string
FileFormat string
RuleString string
Play bool
Expand Down
4 changes: 3 additions & 1 deletion internal/config/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (

const (
FileFlag = "file"
URLFlag = "url"
FileFormatFlag = "file-format"
RuleStringFlag = "rule-string"
PlayFlag = "play"
Expand All @@ -18,7 +19,8 @@ const (
)

func (c *Config) RegisterFlags(fs *pflag.FlagSet) {
fs.StringVarP(&c.File, FileFlag, "f", c.File, "Loads a pattern file on startup")
fs.StringVarP(&c.File, FileFlag, "f", c.File, "Load a pattern file")
fs.StringVar(&c.URL, URLFlag, c.URL, "Load a pattern URL")
fs.StringVar(&c.FileFormat, FileFormatFlag, c.FileFormat, "File format (one of: "+strings.Join(pattern.FormatStrings(), ", ")+")")
fs.StringVar(&c.RuleString, RuleStringFlag, c.RuleString, "Rule string to use. This will be ignored if a pattern file is loaded.")
fs.BoolVar(&c.Play, PlayFlag, c.Play, "Play on startup")
Expand Down
39 changes: 39 additions & 0 deletions internal/pattern/pattern.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,13 @@ package pattern

import (
"bytes"
"context"
"errors"
"fmt"
"io"
"net/http"
"os"
"path"
"path/filepath"
)

Expand Down Expand Up @@ -67,6 +70,42 @@ func UnmarshalFile(path string, format Format) (Pattern, error) {
}
}

var ErrResponse = errors.New("received an error response")

func UnmarshalURL(ctx context.Context, url string, format Format) (Pattern, error) {
req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil)
if err != nil {
return Pattern{}, err
}

resp, err := http.DefaultClient.Do(req)
if err != nil {
return Pattern{}, err
}
defer func() {
_, _ = io.Copy(io.Discard, resp.Body)
_ = resp.Body.Close()
}()

if resp.StatusCode != http.StatusOK {
return Pattern{}, ErrResponse
}

ext := path.Ext(url)
switch {
case format == FormatRLE, ext == ExtRLE:
return UnmarshalRLE(resp.Body)
case format == FormatPlaintext, ext == ExtPlaintext:
return UnmarshalPlaintext(resp.Body)
default:
pattern, err := Unmarshal(resp.Body)
if err != nil {
err = fmt.Errorf("%w: %s", err, url)
}
return pattern, err
}
}

func Unmarshal(r io.Reader) (Pattern, error) {
buf, err := io.ReadAll(r)
if err != nil {
Expand Down

0 comments on commit 2be8e5c

Please sign in to comment.