Skip to content

Commit f4091e7

Browse files
committed
chore: refactor cli to support resuing the server flags
1 parent 75208fe commit f4091e7

File tree

14 files changed

+166
-126
lines changed

14 files changed

+166
-126
lines changed

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@
22
bin
33
coverage
44
extensions
5-
.idea
5+
.idea

cli/add.go

Lines changed: 4 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ package cli
22

33
import (
44
"context"
5-
"encoding/json"
65
"fmt"
76
"os"
87
"path/filepath"
@@ -11,21 +10,12 @@ import (
1110
"github.com/spf13/cobra"
1211
"golang.org/x/xerrors"
1312

14-
"cdr.dev/slog"
15-
"cdr.dev/slog/sloggers/sloghuman"
16-
"github.com/coder/code-marketplace/internal/extensionsign"
17-
1813
"github.com/coder/code-marketplace/storage"
1914
"github.com/coder/code-marketplace/util"
2015
)
2116

2217
func add() *cobra.Command {
23-
var (
24-
artifactory string
25-
extdir string
26-
repo string
27-
)
28-
18+
addFlags, opts := serverFlags()
2919
cmd := &cobra.Command{
3020
Use: "add <source>",
3121
Short: "Add an extension to the marketplace",
@@ -39,21 +29,7 @@ func add() *cobra.Command {
3929
ctx, cancel := context.WithCancel(cmd.Context())
4030
defer cancel()
4131

42-
verbose, err := cmd.Flags().GetBool("verbose")
43-
if err != nil {
44-
return err
45-
}
46-
logger := slog.Make(sloghuman.Sink(cmd.ErrOrStderr()))
47-
if verbose {
48-
logger = logger.Leveled(slog.LevelDebug)
49-
}
50-
51-
store, err := storage.NewStorage(ctx, &storage.Options{
52-
Artifactory: artifactory,
53-
ExtDir: extdir,
54-
Logger: logger,
55-
Repo: repo,
56-
})
32+
store, err := storage.NewStorage(ctx, opts)
5733
if err != nil {
5834
return err
5935
}
@@ -100,10 +76,7 @@ func add() *cobra.Command {
10076
return nil
10177
},
10278
}
103-
104-
cmd.Flags().StringVar(&extdir, "extensions-dir", "", "The path to extensions.")
105-
cmd.Flags().StringVar(&artifactory, "artifactory", "", "Artifactory server URL.")
106-
cmd.Flags().StringVar(&repo, "repo", "", "Artifactory repository.")
79+
addFlags(cmd)
10780

10881
return cmd
10982
}
@@ -122,28 +95,7 @@ func doAdd(ctx context.Context, source string, store storage.Storage) ([]string,
12295
return nil, err
12396
}
12497

125-
sigManifest, err := extensionsign.GenerateSignatureManifest(vsix)
126-
if err != nil {
127-
return nil, xerrors.Errorf("zip signature manifest: %w", err)
128-
}
129-
130-
data, err := json.Marshal(sigManifest)
131-
if err != nil {
132-
return nil, xerrors.Errorf("encode manifest: %w", err)
133-
}
134-
135-
key, _ := extensionsign.GenerateKey()
136-
sigZip, _ := extensionsign.SignAndZipVSIX(key, vsix)
137-
138-
location, err := store.AddExtension(ctx, manifest, vsix,
139-
storage.File{
140-
RelativePath: "extension.sigzip",
141-
Content: sigZip,
142-
},
143-
storage.File{
144-
RelativePath: ".signature.manifest",
145-
Content: data,
146-
})
98+
location, err := store.AddExtension(ctx, manifest, vsix)
14799
if err != nil {
148100
return nil, err
149101
}

cli/remove.go

Lines changed: 4 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -10,20 +10,15 @@ import (
1010
"github.com/spf13/cobra"
1111
"golang.org/x/xerrors"
1212

13-
"cdr.dev/slog"
14-
"cdr.dev/slog/sloggers/sloghuman"
15-
1613
"github.com/coder/code-marketplace/storage"
1714
"github.com/coder/code-marketplace/util"
1815
)
1916

2017
func remove() *cobra.Command {
2118
var (
22-
all bool
23-
artifactory string
24-
extdir string
25-
repo string
19+
all bool
2620
)
21+
addFlags, opts := serverFlags()
2722

2823
cmd := &cobra.Command{
2924
Use: "remove <id>",
@@ -37,21 +32,7 @@ func remove() *cobra.Command {
3732
ctx, cancel := context.WithCancel(cmd.Context())
3833
defer cancel()
3934

40-
verbose, err := cmd.Flags().GetBool("verbose")
41-
if err != nil {
42-
return err
43-
}
44-
logger := slog.Make(sloghuman.Sink(cmd.ErrOrStderr()))
45-
if verbose {
46-
logger = logger.Leveled(slog.LevelDebug)
47-
}
48-
49-
store, err := storage.NewStorage(ctx, &storage.Options{
50-
Artifactory: artifactory,
51-
ExtDir: extdir,
52-
Logger: logger,
53-
Repo: repo,
54-
})
35+
store, err := storage.NewStorage(ctx, opts)
5536
if err != nil {
5637
return err
5738
}
@@ -120,9 +101,7 @@ func remove() *cobra.Command {
120101
}
121102

122103
cmd.Flags().BoolVar(&all, "all", false, "Whether to delete all versions of the extension.")
123-
cmd.Flags().StringVar(&extdir, "extensions-dir", "", "The path to extensions.")
124-
cmd.Flags().StringVar(&artifactory, "artifactory", "", "Artifactory server URL.")
125-
cmd.Flags().StringVar(&repo, "repo", "", "Artifactory repository.")
104+
addFlags(cmd)
126105

127106
return cmd
128107
}

cli/server.go

Lines changed: 46 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -21,15 +21,52 @@ import (
2121
"github.com/coder/code-marketplace/storage"
2222
)
2323

24+
func serverFlags() (addFlags func(cmd *cobra.Command), opts *storage.Options) {
25+
opts = &storage.Options{}
26+
return func(cmd *cobra.Command) {
27+
cmd.Flags().StringVar(&opts.ExtDir, "extensions-dir", "", "The path to extensions.")
28+
cmd.Flags().StringVar(&opts.Artifactory, "artifactory", "", "Artifactory server URL.")
29+
cmd.Flags().StringVar(&opts.Repo, "repo", "", "Artifactory repository.")
30+
cmd.Flags().DurationVar(&opts.ListCacheDuration, "list-cache-duration", time.Minute, "The duration of the extension cache.")
31+
cmd.Flags().BoolVar(&opts.SignExtensions, "sign", false, "Sign extensions.")
32+
33+
var before func(cmd *cobra.Command, args []string) error
34+
if cmd.PreRunE != nil {
35+
before = cmd.PreRunE
36+
}
37+
if cmd.PreRun != nil {
38+
beforeNoE := cmd.PreRun
39+
before = func(cmd *cobra.Command, args []string) error {
40+
beforeNoE(cmd, args)
41+
return nil
42+
}
43+
}
44+
45+
cmd.PreRunE = func(cmd *cobra.Command, args []string) error {
46+
opts.Logger = cmdLogger(cmd)
47+
if before != nil {
48+
return before(cmd, args)
49+
}
50+
return nil
51+
}
52+
}, opts
53+
}
54+
55+
func cmdLogger(cmd *cobra.Command) slog.Logger {
56+
verbose, _ := cmd.Flags().GetBool("verbose")
57+
logger := slog.Make(sloghuman.Sink(cmd.ErrOrStderr()))
58+
if verbose {
59+
logger = logger.Leveled(slog.LevelDebug)
60+
}
61+
return logger
62+
}
63+
2464
func server() *cobra.Command {
2565
var (
26-
address string
27-
artifactory string
28-
extdir string
29-
repo string
30-
listcacheduration time.Duration
31-
maxpagesize int
66+
address string
67+
maxpagesize int
3268
)
69+
addFlags, opts := serverFlags()
3370

3471
cmd := &cobra.Command{
3572
Use: "server",
@@ -41,26 +78,12 @@ func server() *cobra.Command {
4178
RunE: func(cmd *cobra.Command, args []string) error {
4279
ctx, cancel := context.WithCancel(cmd.Context())
4380
defer cancel()
81+
logger := opts.Logger
4482

4583
notifyCtx, notifyStop := signal.NotifyContext(ctx, interruptSignals...)
4684
defer notifyStop()
4785

48-
verbose, err := cmd.Flags().GetBool("verbose")
49-
if err != nil {
50-
return err
51-
}
52-
logger := slog.Make(sloghuman.Sink(cmd.ErrOrStderr()))
53-
if verbose {
54-
logger = logger.Leveled(slog.LevelDebug)
55-
}
56-
57-
store, err := storage.NewStorage(ctx, &storage.Options{
58-
Artifactory: artifactory,
59-
ExtDir: extdir,
60-
Logger: logger,
61-
Repo: repo,
62-
ListCacheDuration: listcacheduration,
63-
})
86+
store, err := storage.NewStorage(ctx, opts)
6487
if err != nil {
6588
return err
6689
}
@@ -137,12 +160,9 @@ func server() *cobra.Command {
137160
},
138161
}
139162

140-
cmd.Flags().StringVar(&extdir, "extensions-dir", "", "The path to extensions.")
141163
cmd.Flags().IntVar(&maxpagesize, "max-page-size", api.MaxPageSizeDefault, "The maximum number of pages to request")
142-
cmd.Flags().StringVar(&artifactory, "artifactory", "", "Artifactory server URL.")
143-
cmd.Flags().StringVar(&repo, "repo", "", "Artifactory repository.")
144164
cmd.Flags().StringVar(&address, "address", "127.0.0.1:3001", "The address on which to serve the marketplace API.")
145-
cmd.Flags().DurationVar(&listcacheduration, "list-cache-duration", time.Minute, "The duration of the extension cache.")
165+
addFlags(cmd)
146166

147167
return cmd
148168
}

cli/signature.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import (
1313
func signature() *cobra.Command {
1414
cmd := &cobra.Command{
1515
Use: "signature",
16+
Hidden: true, // Debugging tools
1617
Aliases: []string{"sig", "sigs", "signatures"},
1718
}
1819
cmd.AddCommand(compareSignatureSigZips())

internal/extensionsign/sigmanifest.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import (
1010
"github.com/cloudflare/cfssl/scan/crypto/sha256"
1111
"golang.org/x/xerrors"
1212

13-
"github.com/coder/code-marketplace/storage"
13+
"github.com/coder/code-marketplace/storage/easyzip"
1414
)
1515

1616
type SignatureManifest struct {
@@ -94,7 +94,7 @@ func GenerateSignatureManifest(vsixFile []byte) (SignatureManifest, error) {
9494
Entries: make(map[string]File),
9595
}
9696

97-
err = storage.ExtractZip(vsixFile, func(name string, reader io.Reader) error {
97+
err = easyzip.ExtractZip(vsixFile, func(name string, reader io.Reader) error {
9898
fm, err := FileManifest(reader)
9999
if err != nil {
100100
return xerrors.Errorf("file %q: %w", name, err)

internal/extensionsign/sigzip.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,11 @@ import (
88

99
"golang.org/x/xerrors"
1010

11-
"github.com/coder/code-marketplace/storage"
11+
"github.com/coder/code-marketplace/storage/easyzip"
1212
)
1313

1414
func ExtractSignatureManifest(zip []byte) (SignatureManifest, error) {
15-
r, err := storage.GetZipFileReader(zip, ".signature.manifest")
15+
r, err := easyzip.GetZipFileReader(zip, ".signature.manifest")
1616
if err != nil {
1717
return SignatureManifest{}, xerrors.Errorf("get manifest: %w", err)
1818
}

storage/artifactory.go

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import (
1919
"golang.org/x/xerrors"
2020

2121
"cdr.dev/slog"
22+
"github.com/coder/code-marketplace/storage/easyzip"
2223

2324
"github.com/coder/code-marketplace/util"
2425
)
@@ -41,6 +42,8 @@ type ArtifactoryList struct {
4142
Files []ArtifactoryFile `json:"files"`
4243
}
4344

45+
var _ Storage = (*Artifactory)(nil)
46+
4447
// Artifactory implements Storage. It stores extensions remotely through
4548
// Artifactory by both copying the VSIX and extracting said VSIX to a tree
4649
// structure in the form of publisher/extension/version to easily serve
@@ -244,7 +247,7 @@ func (s *Artifactory) AddExtension(ctx context.Context, manifest *VSIXManifest,
244247
}
245248
}
246249

247-
err := ExtractZip(vsix, func(name string, r io.Reader) error {
250+
err := easyzip.ExtractZip(vsix, func(name string, r io.Reader) error {
248251
if util.Contains(assets, name) || (browser != "" && strings.HasPrefix(name, browser)) {
249252
_, err := s.upload(ctx, path.Join(dir, name), r)
250253
return err
@@ -262,6 +265,14 @@ func (s *Artifactory) AddExtension(ctx context.Context, manifest *VSIXManifest,
262265
return "", err
263266
}
264267

268+
for _, file := range extra {
269+
// TODO: I think this is correct?
270+
_, err := s.upload(ctx, path.Join(dir, file.RelativePath), bytes.NewReader(file.Content))
271+
if err != nil {
272+
return "", err
273+
}
274+
}
275+
265276
return s.uri + dir, nil
266277
}
267278

storage/zip.go renamed to storage/easyzip/zip.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package storage
1+
package easyzip
22

33
import (
44
"archive/zip"

storage/zip_test.go renamed to storage/easyzip/zip_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package storage
1+
package easyzip
22

33
import (
44
"archive/zip"

storage/local.go

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,11 @@ import (
1414
"golang.org/x/xerrors"
1515

1616
"cdr.dev/slog"
17+
"github.com/coder/code-marketplace/storage/easyzip"
1718
)
1819

20+
var _ Storage = (*Local)(nil)
21+
1922
// Local implements Storage. It stores extensions locally on disk by both
2023
// copying the VSIX and extracting said VSIX to a tree structure in the form of
2124
// publisher/extension/version to easily serve individual assets via HTTP.
@@ -98,7 +101,7 @@ func (s *Local) AddExtension(ctx context.Context, manifest *VSIXManifest, vsix [
98101
Version: identity.Version,
99102
TargetPlatform: identity.TargetPlatform,
100103
}.String())
101-
err := ExtractZip(vsix, func(name string, r io.Reader) error {
104+
err := easyzip.ExtractZip(vsix, func(name string, r io.Reader) error {
102105
path := filepath.Join(dir, name)
103106
err := os.MkdirAll(filepath.Dir(path), 0o755)
104107
if err != nil {
@@ -164,12 +167,6 @@ func (s *Local) Manifest(ctx context.Context, publisher, name string, version Ve
164167
Addressable: "true",
165168
})
166169

167-
manifest.Assets.Asset = append(manifest.Assets.Asset, VSIXAsset{
168-
Type: VSIXSignatureType,
169-
Path: "extension.sigzip",
170-
Addressable: "true",
171-
})
172-
173170
return manifest, nil
174171
}
175172

0 commit comments

Comments
 (0)