github.com/NBISweden/sda-cli@v0.1.2-0.20240506070033-4c8af88918df/main.go (about) 1 package main 2 3 import ( 4 "flag" 5 "fmt" 6 "os" 7 8 createKey "github.com/NBISweden/sda-cli/create_key" 9 "github.com/NBISweden/sda-cli/datasetsize" 10 "github.com/NBISweden/sda-cli/decrypt" 11 "github.com/NBISweden/sda-cli/download" 12 "github.com/NBISweden/sda-cli/encrypt" 13 "github.com/NBISweden/sda-cli/helpers" 14 "github.com/NBISweden/sda-cli/list" 15 "github.com/NBISweden/sda-cli/login" 16 "github.com/NBISweden/sda-cli/upload" 17 "github.com/NBISweden/sda-cli/version" 18 log "github.com/sirupsen/logrus" 19 ) 20 21 var Version = "development" 22 23 var Usage = `USAGE: %s <command> [command-args] 24 25 This is a helper tool that can help with common tasks when interacting 26 with the Sensitive Data Archive (SDA). 27 ` 28 29 // Map of the sub-commands, and their arguments and usage text strings 30 type commandInfo struct { 31 args *flag.FlagSet 32 usage string 33 argHelp string 34 } 35 36 var Commands = map[string]commandInfo{ 37 "encrypt": {encrypt.Args, encrypt.Usage, encrypt.ArgHelp}, 38 "createKey": {createKey.Args, createKey.Usage, createKey.ArgHelp}, 39 "decrypt": {decrypt.Args, decrypt.Usage, decrypt.ArgHelp}, 40 "download": {download.Args, download.Usage, download.ArgHelp}, 41 "upload": {upload.Args, upload.Usage, upload.ArgHelp}, 42 "datasetsize": {datasetsize.Args, datasetsize.Usage, datasetsize.ArgHelp}, 43 "list": {list.Args, list.Usage, list.ArgHelp}, 44 "login": {login.Args, login.Usage, login.ArgHelp}, 45 "version": {version.Args, version.Usage, version.ArgHelp}, 46 } 47 48 // Main does argument parsing, then delegates to one of the sub modules 49 func main() { 50 51 log.SetLevel(log.WarnLevel) 52 command, args := ParseArgs() 53 54 var err error 55 56 switch command { 57 case "encrypt": 58 err = encrypt.Encrypt(args) 59 case "createkey", "createKey", "create-key": 60 err = createKey.CreateKey(args) 61 case "decrypt": 62 err = decrypt.Decrypt(args) 63 case "download": 64 err = download.Download(args) 65 case "upload": 66 err = upload.Upload(args) 67 case "datasetsize": 68 err = datasetsize.DatasetSize(args) 69 case "list": 70 err = list.List(args) 71 case "login": 72 err = login.NewLogin(args) 73 case "version": 74 err = version.Version(Version) 75 default: 76 fmt.Fprintf(os.Stderr, "Unknown command: %s", command) 77 os.Exit(1) 78 } 79 if err != nil { 80 fmt.Fprintf(os.Stderr, "Error: %v\n", err) 81 os.Exit(1) 82 } 83 } 84 85 // Parses the command line arguments into a command, and keep the rest 86 // of the arguments for the subcommand. 87 func ParseArgs() (string, []string) { 88 // Print usage if no arguments are provided. 89 // Terminate with non-zero exit status. 90 if len(os.Args) < 2 { 91 _ = Help("help") 92 os.Exit(1) 93 } 94 95 switch os.Args[1] { 96 case "version", "-v", "-version", "--version": 97 if len(os.Args) != 2 { 98 _ = Help("version") 99 os.Exit(1) 100 } 101 102 return "version", os.Args 103 } 104 105 // Extract the command from the 1st argument, then remove it 106 // from list of arguments. 107 command := os.Args[1] 108 os.Args = append(os.Args[:1], os.Args[2:]...) 109 110 // If the command is "help-like", we print the help text and 111 // exit. Let the Help function whether to exit with status zero 112 // or one depending on whether the subcommand is valid or not. 113 switch command { 114 case "help", "-h", "-help", "--help": 115 var subcommand string 116 117 if len(os.Args) > 1 { 118 subcommand = os.Args[1] 119 } else { 120 subcommand = "help" 121 } 122 123 if Help(subcommand) == nil { 124 os.Exit(0) 125 } 126 os.Exit(1) 127 128 } 129 130 // The "list" command can have no arguments since it can use the 131 // config from login so we immediately return in that case. 132 if command == "list" { 133 return command, os.Args 134 } 135 136 // If no arguments are provided to the subcommand, it's not 137 // going to be valid. Print the subcommand help and exit with a 138 // non-zero exit status. 139 if len(os.Args) == 1 { 140 _ = Help(command) 141 os.Exit(1) 142 } 143 144 return command, os.Args 145 } 146 147 // Prints the main usage string, and the global help or command help 148 // depending on the command argument. Returns an error if the command 149 // is not recognized. 150 func Help(command string) error { 151 info, isLegal := Commands[command] 152 if !isLegal { 153 if command != "help" { 154 fmt.Fprintf(os.Stderr, "Unknown command: %s\n", command) 155 } 156 157 // print main help 158 fmt.Fprintf(os.Stderr, Usage, os.Args[0]) 159 fmt.Fprintln(os.Stderr, "The tool can help with these actions:") 160 for _, info := range Commands { 161 subcommandUsage := helpers.FormatSubcommandUsage(info.usage) 162 fmt.Fprint(os.Stderr, subcommandUsage) 163 } 164 fmt.Fprintf(os.Stderr, 165 "Use '%s help <command>' to get help with subcommand flags.\n", 166 os.Args[0]) 167 168 return fmt.Errorf("Unknown command: %s", command) 169 } 170 171 // print subcommand help 172 fmt.Fprintf(os.Stderr, info.usage+"\n", os.Args[0]) 173 fmt.Fprintln(os.Stderr, "Command line arguments:") 174 info.args.PrintDefaults() 175 fmt.Fprintln(os.Stderr, info.argHelp) 176 177 return nil 178 }