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  }