@@ -3,9 +3,12 @@ package cli
33import (
44 "context"
55 "fmt"
6+ "os"
7+ "path/filepath"
68 "strings"
79
810 "github.com/spf13/cobra"
11+ "golang.org/x/xerrors"
912
1013 "cdr.dev/slog"
1114 "cdr.dev/slog/sloggers/sloghuman"
@@ -27,6 +30,7 @@ func add() *cobra.Command {
2730 Example : strings .Join ([]string {
2831 " marketplace add https://domain.tld/extension.vsix --extensions-dir ./extensions" ,
2932 " marketplace add extension.vsix --artifactory http://artifactory.server/artifactory --repo extensions" ,
33+ " marketplace add extension-vsixs/ --extensions-dir ./extensions" ,
3034 }, "\n " ),
3135 Args : cobra .ExactArgs (1 ),
3236 RunE : func (cmd * cobra.Command , args []string ) error {
@@ -52,62 +56,42 @@ func add() *cobra.Command {
5256 return err
5357 }
5458
55- // Read in the extension. In the future we might support stdin as well.
56- vsix , err := storage .ReadVSIX (ctx , args [0 ])
59+ stat , err := os .Stat (args [0 ])
5760 if err != nil {
5861 return err
5962 }
6063
61- // The manifest is required to know where to place the extension since it
62- // is unsafe to rely on the file name or URI.
63- manifest , err := storage .ReadVSIXManifest (vsix )
64- if err != nil {
65- return err
66- }
67-
68- location , err := store .AddExtension (ctx , manifest , vsix )
69- if err != nil {
70- return err
71- }
72-
73- deps := []string {}
74- pack := []string {}
75- for _ , prop := range manifest .Metadata .Properties .Property {
76- if prop .Value == "" {
77- continue
64+ var summary []string
65+ var failed []string
66+ if stat .IsDir () {
67+ files , err := os .ReadDir (args [0 ])
68+ if err != nil {
69+ return err
7870 }
79- switch prop .ID {
80- case storage .DependencyPropertyType :
81- deps = append (deps , strings .Split (prop .Value , "," )... )
82- case storage .PackPropertyType :
83- pack = append (pack , strings .Split (prop .Value , "," )... )
84- }
85- }
86-
87- depCount := len (deps )
88- id := storage .ExtensionIDFromManifest (manifest )
89- summary := []string {
90- fmt .Sprintf ("Unpacked %s to %s" , id , location ),
91- fmt .Sprintf ("%s has %s" , id , util .Plural (depCount , "dependency" , "dependencies" )),
92- }
93-
94- if depCount > 0 {
95- for _ , id := range deps {
96- summary = append (summary , fmt .Sprintf (" - %s" , id ))
97- }
98- }
99-
100- packCount := len (pack )
101- if packCount > 0 {
102- summary = append (summary , fmt .Sprintf ("%s is in a pack with %s" , id , util .Plural (packCount , "other extension" , "" )))
103- for _ , id := range pack {
104- summary = append (summary , fmt .Sprintf (" - %s" , id ))
71+ for _ , file := range files {
72+ s , err := doAdd (ctx , filepath .Join (args [0 ], file .Name ()), store )
73+ if err != nil {
74+ failed = append (failed , file .Name ())
75+ summary = append (summary , fmt .Sprintf ("Failed to unpack %s: %s" , file .Name (), err .Error ()))
76+ } else {
77+ summary = append (summary , s ... )
78+ }
10579 }
10680 } else {
107- summary = append (summary , fmt .Sprintf ("%s is not in a pack" , id ))
81+ summary , err = doAdd (ctx , args [0 ], store )
82+ if err != nil {
83+ return err
84+ }
10885 }
10986
11087 _ , err = fmt .Fprintln (cmd .OutOrStdout (), strings .Join (summary , "\n " ))
88+ failedCount := len (failed )
89+ if failedCount > 0 {
90+ return xerrors .Errorf (
91+ "Failed to add %s: %s" ,
92+ util .Plural (failedCount , "extension" , "" ),
93+ strings .Join (failed , ", " ))
94+ }
11195 return err
11296 },
11397 }
@@ -118,3 +102,62 @@ func add() *cobra.Command {
118102
119103 return cmd
120104}
105+
106+ func doAdd (ctx context.Context , source string , store storage.Storage ) ([]string , error ) {
107+ // Read in the extension. In the future we might support stdin as well.
108+ vsix , err := storage .ReadVSIX (ctx , source )
109+ if err != nil {
110+ return nil , err
111+ }
112+
113+ // The manifest is required to know where to place the extension since it
114+ // is unsafe to rely on the file name or URI.
115+ manifest , err := storage .ReadVSIXManifest (vsix )
116+ if err != nil {
117+ return nil , err
118+ }
119+
120+ location , err := store .AddExtension (ctx , manifest , vsix )
121+ if err != nil {
122+ return nil , err
123+ }
124+
125+ deps := []string {}
126+ pack := []string {}
127+ for _ , prop := range manifest .Metadata .Properties .Property {
128+ if prop .Value == "" {
129+ continue
130+ }
131+ switch prop .ID {
132+ case storage .DependencyPropertyType :
133+ deps = append (deps , strings .Split (prop .Value , "," )... )
134+ case storage .PackPropertyType :
135+ pack = append (pack , strings .Split (prop .Value , "," )... )
136+ }
137+ }
138+
139+ depCount := len (deps )
140+ id := storage .ExtensionIDFromManifest (manifest )
141+ summary := []string {
142+ fmt .Sprintf ("Unpacked %s to %s" , id , location ),
143+ fmt .Sprintf (" - %s has %s" , id , util .Plural (depCount , "dependency" , "dependencies" )),
144+ }
145+
146+ if depCount > 0 {
147+ for _ , id := range deps {
148+ summary = append (summary , fmt .Sprintf (" - %s" , id ))
149+ }
150+ }
151+
152+ packCount := len (pack )
153+ if packCount > 0 {
154+ summary = append (summary , fmt .Sprintf (" - %s is in a pack with %s" , id , util .Plural (packCount , "other extension" , "" )))
155+ for _ , id := range pack {
156+ summary = append (summary , fmt .Sprintf (" - %s" , id ))
157+ }
158+ } else {
159+ summary = append (summary , fmt .Sprintf (" - %s is not in a pack" , id ))
160+ }
161+
162+ return summary , nil
163+ }
0 commit comments