Skip to content

Commit 856d2b9

Browse files
authored
Merge pull request #404 from dethancosta/exercism
Add Exercism plugin
2 parents 8f22194 + 716477e commit 856d2b9

5 files changed

Lines changed: 196 additions & 0 deletions

File tree

plugins/exercism/api_key.go

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
package exercism
2+
3+
import (
4+
"context"
5+
"encoding/json"
6+
7+
"github.com/1Password/shell-plugins/sdk"
8+
"github.com/1Password/shell-plugins/sdk/importer"
9+
"github.com/1Password/shell-plugins/sdk/provision"
10+
"github.com/1Password/shell-plugins/sdk/schema"
11+
"github.com/1Password/shell-plugins/sdk/schema/credname"
12+
"github.com/1Password/shell-plugins/sdk/schema/fieldname"
13+
)
14+
15+
func APIKey() schema.CredentialType {
16+
return schema.CredentialType{
17+
Name: credname.APIKey,
18+
DocsURL: sdk.URL("https://exercism.org/docs/using/solving-exercises/working-locally"),
19+
ManagementURL: sdk.URL("https://exercism.org/settings/api_cli"),
20+
Fields: []schema.CredentialField{
21+
{
22+
Name: fieldname.URL,
23+
MarkdownDescription: `The URL of the Exercism API.`,
24+
Secret: false,
25+
},
26+
{
27+
Name: fieldname.APIKey,
28+
MarkdownDescription: "API Key used to authenticate to Exercism.",
29+
Secret: true,
30+
Composition: &schema.ValueComposition{
31+
Length: 36,
32+
Charset: schema.Charset{
33+
Lowercase: true,
34+
Digits: true,
35+
Specific: []rune{'-'},
36+
},
37+
},
38+
},
39+
{
40+
Name: sdk.FieldName("Directory"),
41+
MarkdownDescription: `The path to the workspace directory where the exercises are stored.`,
42+
Secret: false,
43+
},
44+
},
45+
DefaultProvisioner: provision.TempFile(
46+
tempFileConfig,
47+
provision.AtFixedPath("~/.config/exercism/user.json"),
48+
),
49+
Importer: importer.TryAll(
50+
TryExercismConfigFile(),
51+
)}
52+
}
53+
54+
func TryExercismConfigFile() sdk.Importer {
55+
return importer.TryFile("~/.config/exercism/user.json", func(ctx context.Context, contents importer.FileContents, in sdk.ImportInput, out *sdk.ImportAttempt) {
56+
var config Config
57+
if err := contents.ToJSON(&config); err != nil {
58+
out.AddError(err)
59+
return
60+
}
61+
62+
if config.URL == "" || config.APIKey == "" || config.Workspace == "" {
63+
return
64+
}
65+
66+
out.AddCandidate(sdk.ImportCandidate{
67+
Fields: map[sdk.FieldName]string{
68+
fieldname.APIKey: config.APIKey,
69+
fieldname.URL: config.URL,
70+
sdk.FieldName("Directory"): config.Workspace,
71+
},
72+
})
73+
})
74+
}
75+
76+
type Config struct {
77+
URL string `json:"apibaseurl"`
78+
APIKey string `json:"token"`
79+
Workspace string `json:"workspace"`
80+
}
81+
82+
func tempFileConfig(in sdk.ProvisionInput) ([]byte, error) {
83+
config := Config{
84+
URL: in.ItemFields[fieldname.URL],
85+
APIKey: in.ItemFields[fieldname.APIKey],
86+
Workspace: in.ItemFields[sdk.FieldName("Directory")],
87+
}
88+
89+
contents, err := json.Marshal(&config)
90+
if err != nil {
91+
return nil, err
92+
}
93+
94+
return []byte(contents), nil
95+
}

plugins/exercism/api_key_test.go

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
package exercism
2+
3+
import (
4+
"strings"
5+
"testing"
6+
7+
"github.com/1Password/shell-plugins/sdk"
8+
"github.com/1Password/shell-plugins/sdk/plugintest"
9+
"github.com/1Password/shell-plugins/sdk/schema/fieldname"
10+
)
11+
12+
func TestAPIKeyProvisioner(t *testing.T) {
13+
plugintest.TestProvisioner(t, APIKey().DefaultProvisioner, map[string]plugintest.ProvisionCase{
14+
"default": {
15+
ItemFields: map[sdk.FieldName]string{
16+
fieldname.URL: "https://api.exercism.org/v1",
17+
fieldname.APIKey: "1ge7a536-9d1c-4a26-9ww3-3d423example",
18+
sdk.FieldName("Directory"): "/Users/username/exercism",
19+
},
20+
ExpectedOutput: sdk.ProvisionOutput{
21+
Files: map[string]sdk.OutputFile{
22+
"~/.config/exercism/user.json": {
23+
Contents: []byte(strings.Join(strings.Fields(plugintest.LoadFixture(t, "user.json")), "")),
24+
},
25+
},
26+
},
27+
},
28+
})
29+
}
30+
31+
func TestAPIKeyImporter(t *testing.T) {
32+
plugintest.TestImporter(t, APIKey().Importer, map[string]plugintest.ImportCase{
33+
"config file": {
34+
Files: map[string]string{
35+
"~/.config/exercism/user.json": plugintest.LoadFixture(t, "user.json"),
36+
},
37+
ExpectedCandidates: []sdk.ImportCandidate{
38+
{
39+
Fields: map[sdk.FieldName]string{
40+
fieldname.URL: "https://api.exercism.org/v1",
41+
fieldname.APIKey: "1ge7a536-9d1c-4a26-9ww3-3d423example",
42+
sdk.FieldName("Directory"): "/Users/username/exercism",
43+
},
44+
},
45+
},
46+
},
47+
})
48+
}

plugins/exercism/exercism.go

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package exercism
2+
3+
import (
4+
"github.com/1Password/shell-plugins/sdk"
5+
"github.com/1Password/shell-plugins/sdk/needsauth"
6+
"github.com/1Password/shell-plugins/sdk/schema"
7+
"github.com/1Password/shell-plugins/sdk/schema/credname"
8+
)
9+
10+
func ExercismCLI() schema.Executable {
11+
return schema.Executable{
12+
Name: "Exercism CLI",
13+
Runs: []string{"exercism"},
14+
DocsURL: sdk.URL("https://exercism.org/docs/using/solving-exercises/working-locally"),
15+
NeedsAuth: needsauth.IfAll(
16+
needsauth.NotForHelpOrVersion(),
17+
needsauth.NotWithoutArgs(),
18+
needsauth.NotForExactArgs("completion", "upgrade", "workspace", "troubleshoot"),
19+
),
20+
Uses: []schema.CredentialUsage{
21+
{
22+
Name: credname.APIKey,
23+
},
24+
},
25+
}
26+
}

plugins/exercism/plugin.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package exercism
2+
3+
import (
4+
"github.com/1Password/shell-plugins/sdk"
5+
"github.com/1Password/shell-plugins/sdk/schema"
6+
)
7+
8+
func New() schema.Plugin {
9+
return schema.Plugin{
10+
Name: "exercism",
11+
Platform: schema.PlatformInfo{
12+
Name: "Exercism",
13+
Homepage: sdk.URL("https://exercism.org"),
14+
},
15+
Credentials: []schema.CredentialType{
16+
APIKey(),
17+
},
18+
Executables: []schema.Executable{
19+
ExercismCLI(),
20+
},
21+
}
22+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"apibaseurl":"https://api.exercism.org/v1",
3+
"token":"1ge7a536-9d1c-4a26-9ww3-3d423example",
4+
"workspace":"/Users/username/exercism"
5+
}

0 commit comments

Comments
 (0)