From 43459c2621042c99cf6200bf7bde3e7fa41c6417 Mon Sep 17 00:00:00 2001 From: Maniraja Date: Fri, 30 Jun 2023 20:12:54 -0400 Subject: [PATCH 1/3] Add support for Todoist CLI --- plugins/todoist/api_token.go | 76 +++++++++++++++++++++++ plugins/todoist/api_token_test.go | 45 ++++++++++++++ plugins/todoist/plugin.go | 22 +++++++ plugins/todoist/test-fixtures/config.json | 3 + plugins/todoist/todoist.go | 25 ++++++++ 5 files changed, 171 insertions(+) create mode 100644 plugins/todoist/api_token.go create mode 100644 plugins/todoist/api_token_test.go create mode 100644 plugins/todoist/plugin.go create mode 100644 plugins/todoist/test-fixtures/config.json create mode 100644 plugins/todoist/todoist.go diff --git a/plugins/todoist/api_token.go b/plugins/todoist/api_token.go new file mode 100644 index 000000000..718da863a --- /dev/null +++ b/plugins/todoist/api_token.go @@ -0,0 +1,76 @@ +package todoist + +import ( + "context" + "encoding/json" + + "github.com/1Password/shell-plugins/sdk" + "github.com/1Password/shell-plugins/sdk/importer" + "github.com/1Password/shell-plugins/sdk/provision" + "github.com/1Password/shell-plugins/sdk/schema" + "github.com/1Password/shell-plugins/sdk/schema/credname" + "github.com/1Password/shell-plugins/sdk/schema/fieldname" +) + +func APIToken() schema.CredentialType { + return schema.CredentialType{ + Name: credname.APIToken, + DocsURL: sdk.URL("https://todoist.com/help/articles/8048880904476"), + ManagementURL: sdk.URL("https://todoist.com/app/settings/integrations/developer"), + Fields: []schema.CredentialField{ + { + Name: fieldname.Token, + MarkdownDescription: "API Token used to authenticate to Todoist.", + Secret: true, + Composition: &schema.ValueComposition{ + Length: 40, + Charset: schema.Charset{ + Lowercase: true, + Digits: true, + }, + }, + }, + }, + DefaultProvisioner: provision.TempFile( + todoistConfig, + provision.AtFixedPath("~/.config/todoist/config.json"), + ), + Importer: importer.TryAll( + TryTodoistConfigFile(), + )} +} + +func TryTodoistConfigFile() sdk.Importer { + return importer.TryFile("~/.config/todoist/config.json", func(ctx context.Context, contents importer.FileContents, in sdk.ImportInput, out *sdk.ImportAttempt) { + var config Config + if err := contents.ToJSON(&config); err != nil { + out.AddError(err) + return + } + + if config.Token == "" { + return + } + + out.AddCandidate(sdk.ImportCandidate{ + Fields: map[sdk.FieldName]string{ + fieldname.Token: config.Token, + }, + }) + }) +} + +type Config struct { + Token string `json:"token"` +} + +func todoistConfig(in sdk.ProvisionInput) ([]byte, error) { + config := Config{ + Token: in.ItemFields[fieldname.Token], + } + contents, err := json.MarshalIndent(&config, "", " ") + if err != nil { + return nil, err + } + return []byte(contents), nil +} diff --git a/plugins/todoist/api_token_test.go b/plugins/todoist/api_token_test.go new file mode 100644 index 000000000..acffeacff --- /dev/null +++ b/plugins/todoist/api_token_test.go @@ -0,0 +1,45 @@ +package todoist + +import ( + "testing" + + "github.com/1Password/shell-plugins/sdk" + "github.com/1Password/shell-plugins/sdk/plugintest" + "github.com/1Password/shell-plugins/sdk/schema/fieldname" +) + +func TestAPITokenProvisioner(t *testing.T) { + plugintest.TestProvisioner(t, APIToken().DefaultProvisioner, map[string]plugintest.ProvisionCase{ + "config file": { + ItemFields: map[sdk.FieldName]string{ + fieldname.Token: "dbq9y65uguqrk4ognfhdiwcc0zx34z20pexample", + }, + CommandLine: []string{"todoist"}, + ExpectedOutput: sdk.ProvisionOutput{ + CommandLine: []string{"todoist"}, + Files: map[string]sdk.OutputFile{ + "~/.config/todoist/config.json": { + Contents: []byte(plugintest.LoadFixture(t, "config.json")), + }, + }, + }, + }, + }) +} + +func TestAPITokenImporter(t *testing.T) { + plugintest.TestImporter(t, APIToken().Importer, map[string]plugintest.ImportCase{ + "config file": { + Files: map[string]string{ + "~/.config/todoist/config.json": plugintest.LoadFixture(t, "config.json"), + }, + ExpectedCandidates: []sdk.ImportCandidate{ + { + Fields: map[sdk.FieldName]string{ + fieldname.Token: "dbq9y65uguqrk4ognfhdiwcc0zx34z20pexample", + }, + }, + }, + }, + }) +} diff --git a/plugins/todoist/plugin.go b/plugins/todoist/plugin.go new file mode 100644 index 000000000..0981ae67d --- /dev/null +++ b/plugins/todoist/plugin.go @@ -0,0 +1,22 @@ +package todoist + +import ( + "github.com/1Password/shell-plugins/sdk" + "github.com/1Password/shell-plugins/sdk/schema" +) + +func New() schema.Plugin { + return schema.Plugin{ + Name: "todoist", + Platform: schema.PlatformInfo{ + Name: "Todoist", + Homepage: sdk.URL("https://todoist.com"), + }, + Credentials: []schema.CredentialType{ + APIToken(), + }, + Executables: []schema.Executable{ + TodoistCLI(), + }, + } +} diff --git a/plugins/todoist/test-fixtures/config.json b/plugins/todoist/test-fixtures/config.json new file mode 100644 index 000000000..985e5ab9b --- /dev/null +++ b/plugins/todoist/test-fixtures/config.json @@ -0,0 +1,3 @@ +{ + "token": "dbq9y65uguqrk4ognfhdiwcc0zx34z20pexample" +} \ No newline at end of file diff --git a/plugins/todoist/todoist.go b/plugins/todoist/todoist.go new file mode 100644 index 000000000..9ce34559e --- /dev/null +++ b/plugins/todoist/todoist.go @@ -0,0 +1,25 @@ +package todoist + +import ( + "github.com/1Password/shell-plugins/sdk" + "github.com/1Password/shell-plugins/sdk/needsauth" + "github.com/1Password/shell-plugins/sdk/schema" + "github.com/1Password/shell-plugins/sdk/schema/credname" +) + +func TodoistCLI() schema.Executable { + return schema.Executable{ + Name: "Todoist CLI", + Runs: []string{"todoist"}, + DocsURL: sdk.URL("https://github.com/sachaos/todoist"), + NeedsAuth: needsauth.IfAll( + needsauth.NotForHelpOrVersion(), + needsauth.NotWithoutArgs(), + ), + Uses: []schema.CredentialUsage{ + { + Name: credname.APIToken, + }, + }, + } +} From ae0c337b87a91ccfa9ee69eadf7cdf58b25f50c8 Mon Sep 17 00:00:00 2001 From: Maniraja Date: Tue, 25 Jul 2023 20:08:04 -0400 Subject: [PATCH 2/3] Address feedback --- plugins/todoist/todoist.go | 1 - 1 file changed, 1 deletion(-) diff --git a/plugins/todoist/todoist.go b/plugins/todoist/todoist.go index 9ce34559e..6fd5683cc 100644 --- a/plugins/todoist/todoist.go +++ b/plugins/todoist/todoist.go @@ -14,7 +14,6 @@ func TodoistCLI() schema.Executable { DocsURL: sdk.URL("https://github.com/sachaos/todoist"), NeedsAuth: needsauth.IfAll( needsauth.NotForHelpOrVersion(), - needsauth.NotWithoutArgs(), ), Uses: []schema.CredentialUsage{ { From 4131a8662c9cc7e2b114adc8aa7cba81a2987974 Mon Sep 17 00:00:00 2001 From: Arun Date: Mon, 14 Aug 2023 11:36:37 -0400 Subject: [PATCH 3/3] Switch to json.Marshal in the provisioner-generated config file function --- plugins/todoist/api_token.go | 2 +- plugins/todoist/test-fixtures/config.json | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/plugins/todoist/api_token.go b/plugins/todoist/api_token.go index 718da863a..542a98df2 100644 --- a/plugins/todoist/api_token.go +++ b/plugins/todoist/api_token.go @@ -68,7 +68,7 @@ func todoistConfig(in sdk.ProvisionInput) ([]byte, error) { config := Config{ Token: in.ItemFields[fieldname.Token], } - contents, err := json.MarshalIndent(&config, "", " ") + contents, err := json.Marshal(&config) if err != nil { return nil, err } diff --git a/plugins/todoist/test-fixtures/config.json b/plugins/todoist/test-fixtures/config.json index 985e5ab9b..21d1aff4a 100644 --- a/plugins/todoist/test-fixtures/config.json +++ b/plugins/todoist/test-fixtures/config.json @@ -1,3 +1 @@ -{ - "token": "dbq9y65uguqrk4ognfhdiwcc0zx34z20pexample" -} \ No newline at end of file +{"token":"dbq9y65uguqrk4ognfhdiwcc0zx34z20pexample"} \ No newline at end of file