github.com/gogf/gf/v2@v2.7.4/internal/command/command.go (about)

     1  // Copyright GoFrame Author(https://goframe.org). All Rights Reserved.
     2  //
     3  // This Source Code Form is subject to the terms of the MIT License.
     4  // If a copy of the MIT was not distributed with this file,
     5  // You can obtain one at https://github.com/gogf/gf.
     6  //
     7  
     8  // Package command provides console operations, like options/arguments reading.
     9  package command
    10  
    11  import (
    12  	"os"
    13  	"regexp"
    14  	"strings"
    15  )
    16  
    17  var (
    18  	defaultParsedArgs    = make([]string, 0)
    19  	defaultParsedOptions = make(map[string]string)
    20  	argumentOptionRegex  = regexp.MustCompile(`^\-{1,2}([\w\?\.\-]+)(=){0,1}(.*)$`)
    21  )
    22  
    23  // Init does custom initialization.
    24  func Init(args ...string) {
    25  	if len(args) == 0 {
    26  		if len(defaultParsedArgs) == 0 && len(defaultParsedOptions) == 0 {
    27  			args = os.Args
    28  		} else {
    29  			return
    30  		}
    31  	} else {
    32  		defaultParsedArgs = make([]string, 0)
    33  		defaultParsedOptions = make(map[string]string)
    34  	}
    35  	// Parsing os.Args with default algorithm.
    36  	defaultParsedArgs, defaultParsedOptions = ParseUsingDefaultAlgorithm(args...)
    37  }
    38  
    39  // ParseUsingDefaultAlgorithm parses arguments using default algorithm.
    40  func ParseUsingDefaultAlgorithm(args ...string) (parsedArgs []string, parsedOptions map[string]string) {
    41  	parsedArgs = make([]string, 0)
    42  	parsedOptions = make(map[string]string)
    43  	for i := 0; i < len(args); {
    44  		array := argumentOptionRegex.FindStringSubmatch(args[i])
    45  		if len(array) > 2 {
    46  			if array[2] == "=" {
    47  				parsedOptions[array[1]] = array[3]
    48  			} else if i < len(args)-1 {
    49  				if len(args[i+1]) > 0 && args[i+1][0] == '-' {
    50  					// Example: gf gen -d -n 1
    51  					parsedOptions[array[1]] = array[3]
    52  				} else {
    53  					// Example: gf gen -n 2
    54  					parsedOptions[array[1]] = args[i+1]
    55  					i += 2
    56  					continue
    57  				}
    58  			} else {
    59  				// Example: gf gen -h
    60  				parsedOptions[array[1]] = array[3]
    61  			}
    62  		} else {
    63  			parsedArgs = append(parsedArgs, args[i])
    64  		}
    65  		i++
    66  	}
    67  	return
    68  }
    69  
    70  // GetOpt returns the option value named `name`.
    71  func GetOpt(name string, def ...string) string {
    72  	Init()
    73  	if v, ok := defaultParsedOptions[name]; ok {
    74  		return v
    75  	}
    76  	if len(def) > 0 {
    77  		return def[0]
    78  	}
    79  	return ""
    80  }
    81  
    82  // GetOptAll returns all parsed options.
    83  func GetOptAll() map[string]string {
    84  	Init()
    85  	return defaultParsedOptions
    86  }
    87  
    88  // ContainsOpt checks whether option named `name` exist in the arguments.
    89  func ContainsOpt(name string) bool {
    90  	Init()
    91  	_, ok := defaultParsedOptions[name]
    92  	return ok
    93  }
    94  
    95  // GetArg returns the argument at `index`.
    96  func GetArg(index int, def ...string) string {
    97  	Init()
    98  	if index < len(defaultParsedArgs) {
    99  		return defaultParsedArgs[index]
   100  	}
   101  	if len(def) > 0 {
   102  		return def[0]
   103  	}
   104  	return ""
   105  }
   106  
   107  // GetArgAll returns all parsed arguments.
   108  func GetArgAll() []string {
   109  	Init()
   110  	return defaultParsedArgs
   111  }
   112  
   113  // GetOptWithEnv returns the command line argument of the specified `key`.
   114  // If the argument does not exist, then it returns the environment variable with specified `key`.
   115  // It returns the default value `def` if none of them exists.
   116  //
   117  // Fetching Rules:
   118  // 1. Command line arguments are in lowercase format, eg: gf.package.variable;
   119  // 2. Environment arguments are in uppercase format, eg: GF_PACKAGE_VARIABLE;
   120  func GetOptWithEnv(key string, def ...string) string {
   121  	cmdKey := strings.ToLower(strings.ReplaceAll(key, "_", "."))
   122  	if ContainsOpt(cmdKey) {
   123  		return GetOpt(cmdKey)
   124  	} else {
   125  		envKey := strings.ToUpper(strings.ReplaceAll(key, ".", "_"))
   126  		if r, ok := os.LookupEnv(envKey); ok {
   127  			return r
   128  		} else {
   129  			if len(def) > 0 {
   130  				return def[0]
   131  			}
   132  		}
   133  	}
   134  	return ""
   135  }