diff --git a/cmd/slackdump/main.go b/cmd/slackdump/main.go index 5abe2d14..6ef70512 100644 --- a/cmd/slackdump/main.go +++ b/cmd/slackdump/main.go @@ -22,6 +22,8 @@ const ( slackCookieEnv = "COOKIE" ) +const defFilenameTemplate = "{{.ID}}{{ if .ThreadTS}}-{{.ThreadTS}}{{end}}" + var build = "dev" // secrets defines the names of the supported secret files that we load our @@ -136,7 +138,7 @@ func parseCmdLine(args []string) (params, error) { fs.StringVar(&p.appCfg.Output.Filename, "o", "-", "Output `filename` for users and channels. Use '-' for standard\nOutput.") fs.StringVar(&p.appCfg.Output.Format, "r", "", "report `format`. One of 'json' or 'text'") - fs.StringVar(&p.appCfg.FilenameTemplate, "ft", "{{.ID}}{{ if .ThreadTS}}-{{.ThreadTS}}{{end}}", "output file naming template.") + fs.StringVar(&p.appCfg.FilenameTemplate, "ft", defFilenameTemplate, "output file naming template.") // options fs.BoolVar(&p.appCfg.Options.DumpFiles, "f", slackdump.DefOptions.DumpFiles, "same as -download") diff --git a/cmd/slackdump/main_test.go b/cmd/slackdump/main_test.go index a77f6ca6..c0980ffc 100644 --- a/cmd/slackdump/main_test.go +++ b/cmd/slackdump/main_test.go @@ -59,9 +59,10 @@ func Test_checkParameters(t *testing.T) { Token: "x", Cookie: "d", }, - Input: app.Input{List: []string{}}, - Output: app.Output{Filename: "-", Format: "text"}, - Options: slackdump.DefOptions, + FilenameTemplate: defFilenameTemplate, + Input: app.Input{List: []string{}}, + Output: app.Output{Filename: "-", Format: "text"}, + Options: slackdump.DefOptions, }}, false, }, @@ -77,9 +78,10 @@ func Test_checkParameters(t *testing.T) { Token: "x", Cookie: "d", }, - Input: app.Input{List: []string{}}, - Output: app.Output{Filename: "-", Format: "text"}, - Options: slackdump.DefOptions, + FilenameTemplate: defFilenameTemplate, + Input: app.Input{List: []string{}}, + Output: app.Output{Filename: "-", Format: "text"}, + Options: slackdump.DefOptions, }}, false, }, diff --git a/internal/app/app.go b/internal/app/app.go index 529ed846..2c077dc2 100644 --- a/internal/app/app.go +++ b/internal/app/app.go @@ -4,6 +4,7 @@ import ( "context" "encoding/json" "errors" + "html/template" "io" "os" "strings" @@ -19,14 +20,22 @@ const ( ) type App struct { - sd *slackdump.SlackDumper + sd *slackdump.SlackDumper + tmpl *template.Template cfg Config } // New creates a new slackdump app. func New(cfg Config) (*App, error) { - return &App{cfg: cfg}, nil + if err := cfg.Validate(); err != nil { + return nil, err + } + tmpl, err := cfg.compileTemplates() + if err != nil { + return nil, err + } + return &App{cfg: cfg, tmpl: tmpl}, nil } // init initialises the slack dumper app. @@ -107,7 +116,7 @@ func (app *App) newDumpFunc(s string) dumpFunc { func (app *App) renderFilename(c *slackdump.Conversation) string { var buf strings.Builder - if err := app.cfg.tmpl.ExecuteTemplate(&buf, filenameTmplName, c); err != nil { + if err := app.tmpl.ExecuteTemplate(&buf, filenameTmplName, c); err != nil { // this should nevar happen panic(err) } diff --git a/internal/app/config.go b/internal/app/config.go index f45979ea..2271d595 100644 --- a/internal/app/config.go +++ b/internal/app/config.go @@ -25,7 +25,6 @@ type Config struct { Latest TimeValue // latest time to dump conversations to FilenameTemplate string - tmpl *template.Template Options slackdump.Options } @@ -125,13 +124,15 @@ func (p *Config) Validate() error { return nil } -func (p *Config) compileValidateTemplate() error { - var err error - p.tmpl, err = template.New(filenameTmplName).Parse(p.FilenameTemplate) +func (cfg *Config) compileTemplates() (*template.Template, error) { + return template.New(filenameTmplName).Parse(cfg.FilenameTemplate) +} + +func (cfg *Config) compileValidateTemplate() error { + tmpl, err := cfg.compileTemplates() if err != nil { return err } - // are you ready for some filth? Here we go! // let's define some indicators @@ -152,15 +153,15 @@ func (p *Config) compileValidateTemplate() error { // now we render the template and check for OK/NotOK values in the output. var buf strings.Builder - if err := p.tmpl.ExecuteTemplate(&buf, filenameTmplName, tc); err != nil { + if err := tmpl.ExecuteTemplate(&buf, filenameTmplName, tc); err != nil { return err } if strings.Contains(buf.String(), NotOK) || len(buf.String()) == 0 { - return fmt.Errorf("invalid fields in the template: %q", p.FilenameTemplate) + return fmt.Errorf("invalid fields in the template: %q", cfg.FilenameTemplate) } if !strings.Contains(buf.String(), OK) { // must contain at least one OK - return fmt.Errorf("this does not resolve to anything useful: %q", p.FilenameTemplate) + return fmt.Errorf("this does not resolve to anything useful: %q", cfg.FilenameTemplate) } return nil } diff --git a/internal/app/config_test.go b/internal/app/config_test.go index 3644a8c8..796c02d6 100644 --- a/internal/app/config_test.go +++ b/internal/app/config_test.go @@ -1,7 +1,6 @@ package app import ( - "html/template" "testing" "github.com/rusq/slackdump" @@ -16,7 +15,6 @@ func TestConfig_compileValidateTemplate(t *testing.T) { Oldest TimeValue Latest TimeValue FilenameTemplate string - tmpl *template.Template Options slackdump.Options } tests := []struct { @@ -26,42 +24,42 @@ func TestConfig_compileValidateTemplate(t *testing.T) { }{ { "id is ok", - fields{FilenameTemplate: "{{.ID}}", tmpl: template.New("")}, + fields{FilenameTemplate: "{{.ID}}"}, false, }, { "name is ok", - fields{FilenameTemplate: "{{.Name}}", tmpl: template.New("")}, + fields{FilenameTemplate: "{{.Name}}"}, false, }, { "just threadTS is not ok", - fields{FilenameTemplate: "{{.ThreadTS}}", tmpl: template.New("")}, + fields{FilenameTemplate: "{{.ThreadTS}}"}, true, }, { "threadTS and message ID is ok", - fields{FilenameTemplate: "{{.ID}}-{{.ThreadTS}}", tmpl: template.New("")}, + fields{FilenameTemplate: "{{.ID}}-{{.ThreadTS}}"}, false, }, { "threadTS and message ID is ok (conditional)", - fields{FilenameTemplate: "{{.ID}}{{ if .ThreadTS}}-{{.ThreadTS}}{{end}}", tmpl: template.New("")}, + fields{FilenameTemplate: "{{.ID}}{{ if .ThreadTS}}-{{.ThreadTS}}{{end}}"}, false, }, { "message is not ok", - fields{FilenameTemplate: "{{.Message}}", tmpl: template.New("")}, + fields{FilenameTemplate: "{{.Message}}"}, true, }, { "unknown field is not ok", - fields{FilenameTemplate: "{{.Who_dis}}", tmpl: template.New("")}, + fields{FilenameTemplate: "{{.Who_dis}}"}, true, }, { "empty not ok", - fields{FilenameTemplate: "", tmpl: template.New("")}, + fields{FilenameTemplate: ""}, true, }, } @@ -75,7 +73,6 @@ func TestConfig_compileValidateTemplate(t *testing.T) { Oldest: tt.fields.Oldest, Latest: tt.fields.Latest, FilenameTemplate: tt.fields.FilenameTemplate, - tmpl: tt.fields.tmpl, Options: tt.fields.Options, } if err := p.compileValidateTemplate(); (err != nil) != tt.wantErr {