diff options
author | Martin Polden <mpolden@mpolden.no> | 2018-08-11 13:53:05 +0200 |
---|---|---|
committer | Martin Polden <mpolden@mpolden.no> | 2018-08-11 13:53:05 +0200 |
commit | 9d753132b9e04d6c2f25f1ae1408f3f22f414338 (patch) | |
tree | da9f1db374aa08782000ad2559b1ee92473d27fb | |
parent | 073754374f4a802585c249db92dcbbde41e6a488 (diff) |
Make LocalDir configuration reusable
-rw-r--r-- | cmd/lftpq/main.go | 6 | ||||
-rw-r--r-- | cmd/lftpq/main_test.go | 83 | ||||
-rw-r--r-- | queue/config.go | 101 | ||||
-rw-r--r-- | queue/config_test.go | 95 |
4 files changed, 221 insertions, 64 deletions
diff --git a/cmd/lftpq/main.go b/cmd/lftpq/main.go index 3d97191..a6d1cad 100644 --- a/cmd/lftpq/main.go +++ b/cmd/lftpq/main.go @@ -22,6 +22,7 @@ type CLI struct { Test bool `short:"t" long:"test" description:"Test and print config"` Quiet bool `short:"q" long:"quiet" description:"Do not print output from lftp"` Import bool `short:"i" long:"import" description:"Build queues from stdin"` + LocalDir string `short:"l" long:"local-dir" description:"Override local dir for this run" value-name:"NAME"` LftpPath string `short:"p" long:"lftp" description:"Path to lftp program" value-name:"NAME" default:"lftp"` consumer queue.Consumer lister lister @@ -35,6 +36,11 @@ func (c *CLI) Run() error { if err != nil { return err } + if c.LocalDir != "" { + if err := cfg.SetLocalDir(c.LocalDir); err != nil { + return err + } + } if c.Test { json, err := cfg.JSON() if err != nil { diff --git a/cmd/lftpq/main_test.go b/cmd/lftpq/main_test.go index 7eea98b..ab4e2c3 100644 --- a/cmd/lftpq/main_test.go +++ b/cmd/lftpq/main_test.go @@ -82,7 +82,18 @@ func TestInvalidConfig(t *testing.T) { } func TestConfigTest(t *testing.T) { - cli, buf := newTestCLI(`{"Default": {"Parser": "show"}, "Sites": []}`) + cli, buf := newTestCLI(` +{ + "LocalDirs": [ + { + "Name": "d1", + "Parser": "movie", + "Template": "/tmp/" + } + ], + "Sites": [] +} +`) defer os.Remove(cli.Config) cli.Test = true if err := cli.Run(); err != nil { @@ -99,14 +110,20 @@ func TestConfigTest(t *testing.T) { "SkipSymlinks": false, "SkipExisting": false, "SkipFiles": false, - "Parser": "show", "LocalDir": "", "Priorities": null, "PostCommand": "", - "Replacements": null, "Merge": false, "Skip": false }, + "LocalDirs": [ + { + "Name": "d1", + "Parser": "movie", + "Template": "/tmp/", + "Replacements": null + } + ], "Sites": [] } ` @@ -118,23 +135,29 @@ func TestConfigTest(t *testing.T) { func TestRunImport(t *testing.T) { cli, buf := newTestCLI(` { + "LocalDirs": [ + { + "Name": "d1", + "Parser": "movie", + "Template": "/tmp/" + } + ], "Default": { - "Parser": "movie", + "LocalDir": "d1", "GetCmd": "mirror" - }, - "Sites": [ + }, + "Sites": [ { "MaxAge": "0", - "Name": "t1", - "LocalDir": "/tmp/" + "Name": "t1" }, { "MaxAge": "0", - "Name": "t2", - "LocalDir": "/tmp/" + "Name": "t2" } - ] -}`) + ] +} +`) defer os.Remove(cli.Config) toImport := ` t1 /foo/bar.2017 @@ -224,19 +247,25 @@ wait func TestRun(t *testing.T) { cli, buf := newTestCLI(` { + "LocalDirs": [ + { + "Name": "d1", + "Parser": "movie", + "Template": "/tmp/" + } + ], "Default": { - "Parser": "movie", + "LocalDir": "d1", "GetCmd": "mirror", "Patterns": [".*"] }, - "Sites": [ + "Sites": [ { "MaxAge": "0", "Name": "t1", "Dirs": [ "/baz" - ], - "LocalDir": "/tmp/" + ] } ] }`) @@ -308,10 +337,18 @@ wait func TestRunSkipSite(t *testing.T) { cli, buf := newTestCLI(` { - "Sites": [ + "LocalDirs": [ + { + "Name": "d1", + "Parser": "movie", + "Template": "/tmp/" + } + ], + "Sites": [ { "MaxAge": "0", "Name": "t1", + "LocalDir": "d1", "Skip": true } ] @@ -329,13 +366,21 @@ func TestRunSkipSite(t *testing.T) { func TestRunListError(t *testing.T) { cli, buf := newTestCLI(` { - "Sites": [ + "LocalDirs": [ + { + "Name": "d1", + "Parser": "movie", + "Template": "/tmp/" + } + ], + "Sites": [ { "MaxAge": "0", "Name": "t1", "Dirs": [ "/foo" - ] + ], + "LocalDir": "d1" } ] }`) diff --git a/queue/config.go b/queue/config.go index 0d30ecd..b1f8b1b 100644 --- a/queue/config.go +++ b/queue/config.go @@ -18,8 +18,9 @@ import ( ) type Config struct { - Default Site - Sites []Site + Default Site + LocalDirs []LocalDir + Sites []Site } type Replacement struct { @@ -28,6 +29,13 @@ type Replacement struct { Replacement string } +type LocalDir struct { + Name string + Parser string + Template string + Replacements []Replacement +} + type Site struct { GetCmd string Name string @@ -41,13 +49,11 @@ type Site struct { SkipSymlinks bool SkipExisting bool SkipFiles bool - Parser string LocalDir string Priorities []string priorities []*regexp.Regexp PostCommand string postCommand *exec.Cmd - Replacements []Replacement Merge bool Skip bool itemParser @@ -104,7 +110,49 @@ func command(cmd string) (*exec.Cmd, error) { return exec.Command(argv[0], argv[1:]...), nil } +func (c *Config) itemParsers() (map[string]itemParser, error) { + itemParsers := make(map[string]itemParser) + for _, d := range c.LocalDirs { + if d.Name == "" { + return nil, fmt.Errorf("invalid local dir name: %q", d.Name) + } + if d.Template == "" { + return nil, fmt.Errorf("invalid local dir template: %q", d.Template) + } + var parserFunc parser.Parser + switch d.Parser { + case "show": + parserFunc = parser.Show + case "movie": + parserFunc = parser.Movie + case "": + parserFunc = parser.Default + default: + return nil, fmt.Errorf("invalid local dir %q: invalid parser: %q (must be %q, %q or %q)", + d.Name, d.Parser, "show", "movie", "") + } + tmpl, err := parseTemplate(d.Template) + if err != nil { + return nil, err + } + replacements, err := compileReplacements(d.Replacements) + if err != nil { + return nil, err + } + itemParsers[d.Name] = itemParser{ + parser: parserFunc, + replacements: replacements, + template: tmpl, + } + } + return itemParsers, nil +} + func (c *Config) load() error { + itemParsers, err := c.itemParsers() + if err != nil { + return err + } for i := range c.Sites { site := &c.Sites[i] maxAge, err := time.ParseDuration(site.MaxAge) @@ -127,16 +175,6 @@ func (c *Config) load() error { return err } site.priorities = priorities - replacements, err := compileReplacements(site.Replacements) - if err != nil { - return err - } - site.Replacements = replacements - - tmpl, err := parseTemplate(site.LocalDir) - if err != nil { - return err - } cmd, err := command(site.PostCommand) if err != nil { @@ -144,27 +182,30 @@ func (c *Config) load() error { } site.postCommand = cmd - var parserFunc parser.Parser - switch site.Parser { - case "show": - parserFunc = parser.Show - case "movie": - parserFunc = parser.Movie - case "": - parserFunc = parser.Default - default: - return fmt.Errorf("invalid parser: %q (must be %q, %q or %q)", - site.Parser, "show", "movie", "") - } - site.itemParser = itemParser{ - parser: parserFunc, - replacements: site.Replacements, - template: tmpl, + itemParser, ok := itemParsers[site.LocalDir] + if !ok { + return fmt.Errorf("site: %q: invalid local dir: %q", site.Name, site.LocalDir) } + site.itemParser = itemParser } return nil } +func (c *Config) SetLocalDir(name string) error { + itemParsers, err := c.itemParsers() + if err != nil { + return err + } + _, ok := itemParsers[name] + if !ok { + return fmt.Errorf("invalid local dir: %q", name) + } + for i := range c.Sites { + c.Sites[i].LocalDir = name + } + return c.load() +} + func (c *Config) JSON() ([]byte, error) { return json.MarshalIndent(c, "", " ") } diff --git a/queue/config_test.go b/queue/config_test.go index af4b4d5..e1b899c 100644 --- a/queue/config_test.go +++ b/queue/config_test.go @@ -9,21 +9,28 @@ import ( func TestLoad(t *testing.T) { cfg := Config{ - Sites: []Site{Site{ + LocalDirs: []LocalDir{ + { + Name: "d1", + Parser: "show", + Template: "/tmp/{{ .Name }}", + Replacements: []Replacement{ + { + Pattern: "\\.the\\.", + Replacement: ".The.", + }}, + }, + }, + Sites: []Site{{ Name: "foo", Dirs: []string{"/site"}, MaxAge: "24h", Patterns: []string{"^match"}, Filters: []string{"^skip"}, SkipSymlinks: true, - Parser: "show", - LocalDir: "/tmp/{{ .Name }}", + LocalDir: "d1", Priorities: []string{"important"}, - Replacements: []Replacement{ - Replacement{ - Pattern: "\\.the\\.", - Replacement: ".The.", - }}, + PostCommand: "xargs echo", }}, } @@ -61,8 +68,20 @@ func TestLoad(t *testing.T) { func TestReadConfig(t *testing.T) { jsonConfig := ` { + "LocalDirs": [ + { + "Name": "d1", + "Parser": "show", + "Template": "/tmp/d1/" + }, + { + "Name": "d2", + "Parser": "movie", + "Template": "/tmp/d2/" + } + ], "Default": { - "Parser": "show" + "LocalDir": "d1" }, "Sites": [ { @@ -70,11 +89,11 @@ func TestReadConfig(t *testing.T) { }, { "Name": "bar", - "Parser": "movie" + "LocalDir": "d2" }, { "Name": "baz", - "Parser": "" + "LocalDir": "" } ] } @@ -88,14 +107,60 @@ func TestReadConfig(t *testing.T) { i int out string }{ - {0, "show"}, - {1, "movie"}, + {0, "d1"}, + {1, "d2"}, {2, ""}, } for _, tt := range tests { site := cfg.Sites[tt.i] - if got := site.Parser; got != tt.out { - t.Errorf("Expected Parser=%q, got Parser=%q for Name=%q", tt.out, got, site.Name) + if got := site.LocalDir; got != tt.out { + t.Errorf("got LocalDir=%q, want %q for Name=%q", got, tt.out, site.Name) + } + } +} + +func TestOverrideLocalDir(t *testing.T) { + jsonConfig := ` +{ + "LocalDirs": [ + { + "Name": "d1", + "Parser": "show", + "Template": "/tmp/d1/" + }, + { + "Name": "d2", + "Parser": "movie", + "Template": "/tmp/d2/" + } + ], + "Default": { + "LocalDir": "d1", + "MaxAge": "24h" + }, + "Sites": [ + { + "Name": "foo" + }, + { + "Name": "bar" + } + ] +} +` + cfg, err := readConfig(strings.NewReader(jsonConfig)) + if err != nil { + t.Fatal(err) + } + if err := cfg.load(); err != nil { + t.Fatal(err) + } + if err := cfg.SetLocalDir("d2"); err != nil { + t.Fatal(err) + } + for _, s := range cfg.Sites { + if s.LocalDir != "d2" { + t.Errorf("got %q, want %q for Name=%q", s.LocalDir, "d2", s.Name) } } } |