From 5641ed9f1ba9e4b416e0f37d212f132ea90be2fe Mon Sep 17 00:00:00 2001 From: Michael Rykov Date: Tue, 25 Jul 2017 14:59:02 +0800 Subject: [PATCH] =?UTF-8?q?Add=20=E2=80=9CpaperboyInfo=E2=80=9D=20method?= =?UTF-8?q?=20to=20API?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cmd/root.go | 5 ++-- cmd/version.go | 15 ++++------ mail/config.go | 25 ++++++++++++++++- main.go | 4 +-- server/resolver.go | 18 ++++++++++++ server/schema.go | 7 +++++ server/schema_test.go | 65 +++++++++++++++++++++++++++++++++++-------- 7 files changed, 113 insertions(+), 26 deletions(-) diff --git a/cmd/root.go b/cmd/root.go index 4ee1403..67388c5 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -25,7 +25,8 @@ to quickly create a Cobra application.`, // Execute adds all child commands to the root command sets flags appropriately. // This is called by main.main(). It only needs to happen once to the rootCmd. -func Execute() { +func Execute(build mail.BuildInfo) { + mail.Config.Build = build RootCmd.AddCommand(newCmd) RootCmd.AddCommand(sendCmd) RootCmd.AddCommand(serverCmd) @@ -90,7 +91,7 @@ func loadConfig() error { if err := viperConfig.ReadInConfig(); err != nil { return err } - return viperConfig.Unmarshal(&mail.Config) + return viperConfig.Unmarshal(&mail.Config.ConfigFile) } // Error helpers diff --git a/cmd/version.go b/cmd/version.go index d1c76bc..83d6bb1 100644 --- a/cmd/version.go +++ b/cmd/version.go @@ -1,20 +1,17 @@ package cmd import ( - "fmt" + "github.com/rykov/paperboy/mail" "github.com/spf13/cobra" - "runtime" + + "fmt" ) var versionCmd = &cobra.Command{ Use: "version", Short: "Print the version number of Paperboy", Long: `A longer description...`, -} - -func SetVersion(ver, date string) { - versionStr := fmt.Sprintf("v%s %s/%s (%s)", ver, runtime.GOOS, runtime.GOARCH, date) - versionCmd.Run = func(cmd *cobra.Command, args []string) { - fmt.Println("Paperboy Email Engine " + versionStr) - } + Run: func(cmd *cobra.Command, args []string) { + fmt.Printf("Paperboy Email Engine %s\n", mail.Config.Build) + }, } diff --git a/mail/config.go b/mail/config.go index 2c899c2..54c796c 100644 --- a/mail/config.go +++ b/mail/config.go @@ -1,10 +1,23 @@ package mail +import ( + "fmt" + "runtime" +) + // Initial blank config var Config = config{} -// See https://www.paperboy.email/docs/configuration/ type config struct { + // Version/build + Build BuildInfo + + // From config.toml + ConfigFile +} + +// See https://www.paperboy.email/docs/configuration/ +type ConfigFile struct { // General Theme string From string @@ -32,3 +45,13 @@ type smtpConfig struct { User string Pass string } + +// Initial blank config +type BuildInfo struct { + Version string + BuildDate string +} + +func (i BuildInfo) String() string { + return fmt.Sprintf("v%s %s/%s (%s)", i.Version, runtime.GOOS, runtime.GOARCH, i.BuildDate) +} diff --git a/main.go b/main.go index dbafd79..572ca5d 100644 --- a/main.go +++ b/main.go @@ -15,6 +15,7 @@ package main import "github.com/rykov/paperboy/cmd" +import "github.com/rykov/paperboy/mail" // Populated by goreleaser var ( @@ -24,6 +25,5 @@ var ( // Commands managed by Cobra func main() { - cmd.SetVersion(version, date) - cmd.Execute() + cmd.Execute(mail.BuildInfo{version, date}) } diff --git a/server/resolver.go b/server/resolver.go index 40791f8..424ff31 100644 --- a/server/resolver.go +++ b/server/resolver.go @@ -78,3 +78,21 @@ func (e *renderedEmail) HTML() *string { out := string(e.msg.HTML) return &out } + +// ===== Build/Version information ===== + +func (r *Resolver) PaperboyInfo(ctx context.Context) *paperboyInfo { + return &paperboyInfo{mail.Config.Build} +} + +type paperboyInfo struct { + b mail.BuildInfo +} + +func (i *paperboyInfo) Version() string { + return i.b.Version +} + +func (i *paperboyInfo) BuildDate() string { + return i.b.BuildDate +} diff --git a/server/schema.go b/server/schema.go index 81fe8b5..e69d4cc 100644 --- a/server/schema.go +++ b/server/schema.go @@ -30,6 +30,7 @@ const schemaText = ` # The Query type, represents all of the entry points type Query { renderOne(content: String!, recipient: String!): RenderedEmail + paperboyInfo: PaperboyInfo! } # A single rendered email information @@ -40,6 +41,12 @@ const schemaText = ` # html: HTML } + # Build/version information + type PaperboyInfo { + version: String! + buildDate: String! + } + # HTML (same as string) scalar HTML ` diff --git a/server/schema_test.go b/server/schema_test.go index 1c8ff28..bb42283 100644 --- a/server/schema_test.go +++ b/server/schema_test.go @@ -12,6 +12,7 @@ import ( "os" "strings" "testing" + "time" ) func TestMain(m *testing.M) { @@ -19,23 +20,14 @@ func TestMain(m *testing.M) { os.Exit(m.Run()) } -func TestSchemaBasicQuery(t *testing.T) { - var fs = mail.AppFs - - afero.WriteFile(fs, "config.toml", []byte(""), 0644) - afero.WriteFile(fs, fs.ContentPath("c1.md"), []byte("# Hello"), 0644) - afero.WriteFile(fs, fs.ListPath("r1.yaml"), []byte(`--- -- email: ex@example.org -`), 0644) - - schema := graphql.MustParseSchema(schemaText, &Resolver{}) - response := schema.Exec(context.TODO(), `{ +func TestRenderOneQuery(t *testing.T) { + response := issueGraphQLQuery(`{ renderOne(content: "c1", recipient: "r1#0") { rawMessage text html } - }`, "", map[string]interface{}{}) + }`) if errs := response.Errors; len(errs) > 0 { t.Fatalf("GraphQL errors %+v", errs) @@ -76,3 +68,52 @@ func TestSchemaBasicQuery(t *testing.T) { t.Errorf("Invalid RawMessage Text: %s", s) } } + +func TestPaperboyInfoQuery(t *testing.T) { + expected := &mail.Config.Build + expected.BuildDate = time.Now().String() + expected.Version = "1.2.3" + + response := issueGraphQLQuery(`{ + paperboyInfo { + version + buildDate + } + }`) + + if errs := response.Errors; len(errs) > 0 { + t.Fatalf("GraphQL errors %+v", errs) + } + + resp := struct { + PaperboyInfo struct { + Version string + BuildDate string + } + }{} + + if err := json.Unmarshal(response.Data, &resp); err != nil { + t.Fatalf("JSON unmarshal error: %s", err) + } + + actual := resp.PaperboyInfo + if actual.Version != expected.Version { + t.Errorf("Invalid version: %s", actual.Version) + } + if actual.BuildDate != expected.BuildDate { + t.Errorf("Invalid buildDate: %s", actual.BuildDate) + } +} + +func issueGraphQLQuery(query string) *graphql.Response { + var fs = mail.AppFs + + afero.WriteFile(fs, "config.toml", []byte(""), 0644) + afero.WriteFile(fs, fs.ContentPath("c1.md"), []byte("# Hello"), 0644) + afero.WriteFile(fs, fs.ListPath("r1.yaml"), []byte(`--- +- email: ex@example.org +`), 0644) + + schema := graphql.MustParseSchema(schemaText, &Resolver{}) + return schema.Exec(context.TODO(), query, "", map[string]interface{}{}) +}