Skip to content

Commit c2cb60e

Browse files
committed
Handling errors from commands in a much better way
(And more testable)
1 parent 0861335 commit c2cb60e

17 files changed

+199
-212
lines changed

cmd/add.go

+14-19
Original file line numberDiff line numberDiff line change
@@ -45,29 +45,25 @@ You can add multiple files or folders from the local file system; folders will b
4545
You must specify a destination, which is a folder inside the repository where your files will be added. The value for the --destination flag must begin with a slash.
4646
`,
4747
DisableAutoGenTag: true,
48-
Run: func(cmd *cobra.Command, args []string) {
48+
RunE: func(cmd *cobra.Command, args []string) error {
4949
// Flags
5050
flagStoreConnectionString, err := cmd.Flags().GetString("store")
5151
if err != nil {
52-
ExitWithError(cmd.ErrOrStderr(), ErrorApp, "Cannot get flag 'store'", err)
53-
return
52+
return NewExecError(ErrorApp, "Cannot get flag 'store'", err)
5453
}
5554
flagDestination, err := cmd.Flags().GetString("destination")
5655
if err != nil {
57-
ExitWithError(cmd.ErrOrStderr(), ErrorApp, "Cannot get flag 'destination'", err)
58-
return
56+
return NewExecError(ErrorApp, "Cannot get flag 'destination'", err)
5957
}
6058

6159
// Get the file/folder name from the args
6260
if len(args) < 1 {
63-
ExitWithError(cmd.ErrOrStderr(), ErrorUser, "no file or folder specified", nil)
64-
return
61+
return NewExecError(ErrorUser, "no file or folder specified", nil)
6562
}
6663

6764
// Destination must start with "/"
6865
if !strings.HasPrefix(flagDestination, "/") {
69-
ExitWithError(cmd.ErrOrStderr(), ErrorUser, "destination must start with /", nil)
70-
return
66+
return NewExecError(ErrorUser, "destination must start with /", nil)
7167
}
7268

7369
// Ensure destination ends with a "/"
@@ -78,31 +74,28 @@ You must specify a destination, which is a folder inside the repository where yo
7874
// Create the store object
7975
store, err := fs.GetWithConnectionString(flagStoreConnectionString)
8076
if err != nil || store == nil {
81-
ExitWithError(cmd.ErrOrStderr(), ErrorUser, "Could not initialize store", err)
82-
return
77+
return NewExecError(ErrorUser, "Could not initialize store", err)
8378
}
8479

8580
// Request the info file
8681
info, err := store.GetInfoFile()
8782
if err != nil {
88-
ExitWithError(cmd.ErrOrStderr(), ErrorApp, "Error requesting the info file", err)
89-
return
83+
return NewExecError(ErrorApp, "Error requesting the info file", err)
9084
}
9185
if info == nil {
92-
ExitWithError(cmd.ErrOrStderr(), ErrorUser, "Repository is not initialized", err)
93-
return
86+
return NewExecError(ErrorUser, "Repository is not initialized", err)
9487
}
9588

9689
// Require info files version 3 or higher before any operation that changes the store (which would update the index to the protobuf-based format)
97-
if !requireInfoFileVersion(cmd.ErrOrStderr(), info, 3, flagStoreConnectionString) {
98-
return
90+
err = requireInfoFileVersion(info, 3, flagStoreConnectionString)
91+
if err != nil {
92+
return err
9993
}
10094

10195
// Derive the master key
10296
masterKey, keyId, errMessage, err := GetMasterKey(info)
10397
if err != nil {
104-
ExitWithError(cmd.ErrOrStderr(), ErrorUser, errMessage, err)
105-
return
98+
return NewExecError(ErrorUser, errMessage, err)
10699
}
107100
store.SetMasterKey(keyId, masterKey)
108101

@@ -155,6 +148,8 @@ You must specify a destination, which is a folder inside the repository where yo
155148
fmt.Fprintf(cmd.OutOrStdout(), "Error adding file '%s': %s\n", el.Path, el.Err)
156149
}
157150
}
151+
152+
return nil
158153
},
159154
}
160155

cmd/ls.go

+10-15
Original file line numberDiff line numberDiff line change
@@ -40,42 +40,36 @@ Usage: "prvt ls [<path>] --store <string>"
4040
Shows the list of all files and folders contained in the repository at a given path. If the path is omitted, it's assumed to be "/", which is the root of the repository.
4141
`,
4242
DisableAutoGenTag: true,
43-
Run: func(cmd *cobra.Command, args []string) {
43+
RunE: func(cmd *cobra.Command, args []string) error {
4444
if len(args) > 1 {
45-
ExitWithError(cmd.ErrOrStderr(), ErrorUser, "Can only pass one path", nil)
46-
return
45+
return NewExecError(ErrorUser, "Can only pass one path", nil)
4746
}
4847

4948
// Flags
5049
flagStoreConnectionString, err := cmd.Flags().GetString("store")
5150
if err != nil {
52-
ExitWithError(cmd.ErrOrStderr(), ErrorApp, "Cannot get flag 'store'", err)
53-
return
51+
return NewExecError(ErrorApp, "Cannot get flag 'store'", err)
5452
}
5553

5654
// Create the store object
5755
store, err := fs.GetWithConnectionString(flagStoreConnectionString)
5856
if err != nil || store == nil {
59-
ExitWithError(cmd.ErrOrStderr(), ErrorUser, "Could not initialize store", err)
60-
return
57+
return NewExecError(ErrorUser, "Could not initialize store", err)
6158
}
6259

6360
// Request the info file
6461
info, err := store.GetInfoFile()
6562
if err != nil {
66-
ExitWithError(cmd.ErrOrStderr(), ErrorApp, "Error requesting the info file", err)
67-
return
63+
return NewExecError(ErrorApp, "Error requesting the info file", err)
6864
}
6965
if info == nil {
70-
ExitWithError(cmd.ErrOrStderr(), ErrorUser, "Repository is not initialized", err)
71-
return
66+
return NewExecError(ErrorUser, "Repository is not initialized", err)
7267
}
7368

7469
// Derive the master key
7570
masterKey, keyId, errMessage, err := GetMasterKey(info)
7671
if err != nil {
77-
ExitWithError(cmd.ErrOrStderr(), ErrorUser, errMessage, err)
78-
return
72+
return NewExecError(ErrorUser, errMessage, err)
7973
}
8074
store.SetMasterKey(keyId, masterKey)
8175

@@ -94,8 +88,7 @@ Shows the list of all files and folders contained in the repository at a given p
9488
// Get the list of files in the folder
9589
list, err := index.Instance.ListFolder(path)
9690
if err != nil {
97-
ExitWithError(cmd.ErrOrStderr(), ErrorApp, "Error listing the contents of the folder", err)
98-
return
91+
return NewExecError(ErrorApp, "Error listing the contents of the folder", err)
9992
}
10093

10194
// Sort the result
@@ -115,6 +108,8 @@ Shows the list of all files and folders contained in the repository at a given p
115108
fmt.Fprintln(cmd.OutOrStdout(), el.Path)
116109
}
117110
}
111+
112+
return nil
118113
},
119114
}
120115

cmd/repo-init.go

+9-13
Original file line numberDiff line numberDiff line change
@@ -42,31 +42,27 @@ If you want to use a GPG key to protect this repository (including GPG keys stor
4242
In order to use GPG keys, you need to have GPG version 2 installed separately. You also need a GPG keypair (public and private) in your keyring.
4343
`,
4444
DisableAutoGenTag: true,
45-
Run: func(cmd *cobra.Command, args []string) {
45+
RunE: func(cmd *cobra.Command, args []string) error {
4646
// Flags
4747
flagStoreConnectionString, err := cmd.Flags().GetString("store")
4848
if err != nil {
49-
ExitWithError(cmd.ErrOrStderr(), ErrorApp, "Cannot get flag 'store'", err)
50-
return
49+
return NewExecError(ErrorApp, "Cannot get flag 'store'", err)
5150
}
5251
flagGPGKey, err := cmd.Flags().GetString("gpg")
5352
if err != nil {
54-
ExitWithError(cmd.ErrOrStderr(), ErrorApp, "Cannot get flag 'gpg'", err)
55-
return
53+
return NewExecError(ErrorApp, "Cannot get flag 'gpg'", err)
5654
}
5755

5856
// Create the store object
5957
store, err := fs.GetWithConnectionString(flagStoreConnectionString)
6058
if err != nil || store == nil {
61-
ExitWithError(cmd.ErrOrStderr(), ErrorUser, "Could not initialize repository", err)
62-
return
59+
return NewExecError(ErrorUser, "Could not initialize repository", err)
6360
}
6461

6562
// Create the info file after generating a new master key
6663
info, errMessage, err := NewInfoFile(flagGPGKey)
6764
if err != nil {
68-
ExitWithError(cmd.ErrOrStderr(), ErrorUser, errMessage, err)
69-
return
65+
return NewExecError(ErrorUser, errMessage, err)
7066
}
7167

7268
// Set up the index
@@ -76,18 +72,18 @@ In order to use GPG keys, you need to have GPG version 2 installed separately. Y
7672
// We are expecting this to be empty
7773
infoExisting, err := store.GetInfoFile()
7874
if err == nil && infoExisting != nil {
79-
ExitWithError(cmd.ErrOrStderr(), ErrorApp, "Error initializing repository", errors.New("A repository is already initialized in this store"))
80-
return
75+
return NewExecError(ErrorApp, "Error initializing repository", errors.New("A repository is already initialized in this store"))
8176
}
8277

8378
// Store the info file
8479
err = store.SetInfoFile(info)
8580
if err != nil {
86-
ExitWithError(cmd.ErrOrStderr(), ErrorApp, "Cannot store the info file", err)
87-
return
81+
return NewExecError(ErrorApp, "Cannot store the info file", err)
8882
}
8983

9084
fmt.Fprintf(cmd.OutOrStdout(), "Initialized new repository in the store %s\n", flagStoreConnectionString)
85+
86+
return nil
9187
},
9288
}
9389

cmd/repo-key-add.go

+15-21
Original file line numberDiff line numberDiff line change
@@ -38,48 +38,43 @@ If you want to add a GPG key (including GPG keys stored in security tokens or sm
3838
In order to use GPG keys, you need to have GPG version 2 installed separately. You also need a GPG keypair (public and private) in your keyring.`,
3939
DisableAutoGenTag: true,
4040

41-
Run: func(cmd *cobra.Command, args []string) {
41+
RunE: func(cmd *cobra.Command, args []string) error {
4242
// Flags
4343
flagStoreConnectionString, err := cmd.Flags().GetString("store")
4444
if err != nil {
45-
ExitWithError(cmd.ErrOrStderr(), ErrorApp, "Cannot get flag 'store'", err)
46-
return
45+
return NewExecError(ErrorApp, "Cannot get flag 'store'", err)
4746
}
4847
flagGPGKey, err := cmd.Flags().GetString("gpg")
4948
if err != nil {
50-
ExitWithError(cmd.ErrOrStderr(), ErrorApp, "Cannot get flag 'gpg'", err)
51-
return
49+
return NewExecError(ErrorApp, "Cannot get flag 'gpg'", err)
5250
}
5351

5452
// Create the store object
5553
store, err := fs.GetWithConnectionString(flagStoreConnectionString)
5654
if err != nil || store == nil {
57-
ExitWithError(cmd.ErrOrStderr(), ErrorUser, "Could not initialize store", err)
58-
return
55+
return NewExecError(ErrorUser, "Could not initialize store", err)
5956
}
6057

6158
// Request the info file
6259
info, err := store.GetInfoFile()
6360
if err != nil {
64-
ExitWithError(cmd.ErrOrStderr(), ErrorApp, "Error requesting the info file", err)
65-
return
61+
return NewExecError(ErrorApp, "Error requesting the info file", err)
6662
}
6763
if info == nil {
68-
ExitWithError(cmd.ErrOrStderr(), ErrorUser, "Repository is not initialized", err)
69-
return
64+
return NewExecError(ErrorUser, "Repository is not initialized", err)
7065
}
7166

7267
// Require info files version 2 or higher
73-
if !requireInfoFileVersion(cmd.ErrOrStderr(), info, 2, flagStoreConnectionString) {
74-
return
68+
err = requireInfoFileVersion(info, 2, flagStoreConnectionString)
69+
if err != nil {
70+
return err
7571
}
7672

7773
// If we have a GPG key, ensure it's not already added
7874
if flagGPGKey != "" {
7975
for _, k := range info.Keys {
8076
if k.GPGKey == flagGPGKey {
81-
ExitWithError(cmd.ErrOrStderr(), ErrorUser, "A GPG key with the same ID is already authorized to unlock this repository", err)
82-
return
77+
return NewExecError(ErrorUser, "A GPG key with the same ID is already authorized to unlock this repository", err)
8378
}
8479
}
8580
}
@@ -88,8 +83,7 @@ In order to use GPG keys, you need to have GPG version 2 installed separately. Y
8883
fmt.Fprintln(cmd.OutOrStdout(), "Unlocking the repository: if prompted for a passphrase, please type an existing one")
8984
masterKey, _, errMessage, err := GetMasterKey(info)
9085
if err != nil {
91-
ExitWithError(cmd.ErrOrStderr(), ErrorUser, errMessage, err)
92-
return
86+
return NewExecError(ErrorUser, errMessage, err)
9387
}
9488
fmt.Fprintln(cmd.OutOrStdout(), "Repository unlocked")
9589

@@ -99,18 +93,18 @@ In order to use GPG keys, you need to have GPG version 2 installed separately. Y
9993
}
10094
keyId, errMessage, err := AddKey(info, masterKey, flagGPGKey)
10195
if err != nil {
102-
ExitWithError(cmd.ErrOrStderr(), ErrorUser, errMessage, err)
103-
return
96+
return NewExecError(ErrorUser, errMessage, err)
10497
}
10598

10699
// Store the info file
107100
err = store.SetInfoFile(info)
108101
if err != nil {
109-
ExitWithError(cmd.ErrOrStderr(), ErrorApp, "Cannot store the info file", err)
110-
return
102+
return NewExecError(ErrorApp, "Cannot store the info file", err)
111103
}
112104

113105
fmt.Fprintln(cmd.OutOrStdout(), "Key added with id:", keyId)
106+
107+
return nil
114108
},
115109
}
116110

cmd/repo-key-ls.go

+10-11
Original file line numberDiff line numberDiff line change
@@ -37,35 +37,32 @@ Usage: "prvt repo key ls --store <string>"
3737
`,
3838
DisableAutoGenTag: true,
3939

40-
Run: func(cmd *cobra.Command, args []string) {
40+
RunE: func(cmd *cobra.Command, args []string) error {
4141
// Flags
4242
flagStoreConnectionString, err := cmd.Flags().GetString("store")
4343
if err != nil {
44-
ExitWithError(cmd.ErrOrStderr(), ErrorApp, "Cannot get flag 'store'", err)
45-
return
44+
return NewExecError(ErrorApp, "Cannot get flag 'store'", err)
4645
}
4746

4847
// Create the store object
4948
store, err := fs.GetWithConnectionString(flagStoreConnectionString)
5049
if err != nil || store == nil {
51-
ExitWithError(cmd.ErrOrStderr(), ErrorUser, "Could not initialize store", err)
52-
return
50+
return NewExecError(ErrorUser, "Could not initialize store", err)
5351
}
5452

5553
// Request the info file
5654
info, err := store.GetInfoFile()
5755
if err != nil {
58-
ExitWithError(cmd.ErrOrStderr(), ErrorApp, "Error requesting the info file", err)
59-
return
56+
return NewExecError(ErrorApp, "Error requesting the info file", err)
6057
}
6158
if info == nil {
62-
ExitWithError(cmd.ErrOrStderr(), ErrorUser, "Repository is not initialized", err)
63-
return
59+
return NewExecError(ErrorUser, "Repository is not initialized", err)
6460
}
6561

6662
// Require info files version 2 or higher
67-
if !requireInfoFileVersion(cmd.ErrOrStderr(), info, 2, flagStoreConnectionString) {
68-
return
63+
err = requireInfoFileVersion(info, 2, flagStoreConnectionString)
64+
if err != nil {
65+
return err
6966
}
7067

7168
// Table headers
@@ -91,6 +88,8 @@ Usage: "prvt repo key ls --store <string>"
9188
fmt.Fprintln(cmd.OutOrStdout(), "GPG Key | "+k.GPGKey+uid)
9289
}
9390
}
91+
92+
return nil
9493
},
9594
}
9695

0 commit comments

Comments
 (0)