pflag é um substituto imediato para o pacote flag do Go, implementando --flags no estilo POSIX/GNU.
pflag é compatível com as extensões GNU para as recomendações POSIX para opções de linha de comando. Para obter uma descrição mais precisa, consulte a seção "Sintaxe do sinalizador de linha de comando" abaixo.
pflag está disponível sob o mesmo estilo de licença BSD da linguagem Go, que pode ser encontrada no arquivo LICENSE.
pflag está disponível usando o comando go get
padrão.
Instale executando:
go get github.com/spf13/pflag
Execute testes executando:
go test github.com/spf13/pflag
pflag é um substituto imediato do pacote de flag nativo do Go. Se você importar pflag com o nome "flag", todo o código deverá continuar funcionando sem alterações.
import flag "github.com/spf13/pflag"
Há uma exceção a isso: se você instanciar diretamente a estrutura Flag, haverá mais um campo "Abreviação" que você precisará definir. A maior parte do código nunca instancia essa estrutura diretamente e, em vez disso, usa funções como String(), BoolVar() e Var() e, portanto, não é afetado.
Defina sinalizadores usando flag.String(), Bool(), Int(), etc.
Isso declara um sinalizador inteiro, -flagname, armazenado no ponteiro ip, com tipo *int.
var ip * int = flag . Int ( "flagname" , 1234 , "help message for flagname" )
Se desejar, você pode vincular o sinalizador a uma variável usando as funções Var().
var flagvar int
func init () {
flag . IntVar ( & flagvar , "flagname" , 1234 , "help message for flagname" )
}
Ou você pode criar sinalizadores personalizados que satisfaçam a interface Value (com receptores de ponteiro) e associá-los à análise de sinalizadores por
flag . Var ( & flagVal , "name" , "help message for flagname" )
Para tais sinalizadores, o valor padrão é apenas o valor inicial da variável.
Depois que todos os sinalizadores forem definidos, chame
flag . Parse ()
para analisar a linha de comando nos sinalizadores definidos.
Os sinalizadores podem então ser usados diretamente. Se você estiver usando os próprios sinalizadores, todos eles são ponteiros; se você vincular a variáveis, elas serão valores.
fmt . Println ( "ip has value " , * ip )
fmt . Println ( "flagvar has value " , flagvar )
Existem funções auxiliares disponíveis para obter o valor armazenado em um Flag se você tiver um FlagSet, mas achar difícil acompanhar todos os ponteiros em seu código. Se você tiver um pflag.FlagSet com um sinalizador chamado 'flagname' do tipo int você pode usar GetInt() para obter o valor int. Mas observe que 'flagname' deve existir e deve ser um int. GetString("flagname") falhará.
i , err := flagset . GetInt ( "flagname" )
Após a análise, os argumentos após o sinalizador estão disponíveis como a fatia flag.Args() ou individualmente como flag.Arg(i). Os argumentos são indexados de 0 a flag.NArg()-1.
O pacote pflag também define algumas novas funções que não estão em flag, que fornecem abreviações de uma letra para flags. Você pode usá-los anexando 'P' ao nome de qualquer função que defina um sinalizador.
var ip = flag . IntP ( "flagname" , "f" , 1234 , "help message" )
var flagvar bool
func init () {
flag . BoolVarP ( & flagvar , "boolname" , "b" , true , "help message" )
}
flag . VarP ( & flagVal , "varname" , "v" , "help message" )
Letras abreviadas podem ser usadas com traços simples na linha de comando. Sinalizadores abreviados booleanos podem ser combinados com outros sinalizadores abreviados.
O conjunto padrão de sinalizadores de linha de comando é controlado por funções de nível superior. O tipo FlagSet permite definir conjuntos independentes de sinalizadores, como para implementar subcomandos em uma interface de linha de comando. Os métodos de FlagSet são análogos às funções de nível superior para o conjunto de sinalizadores de linha de comando.
Depois de criar um sinalizador, é possível definir pflag.NoOptDefVal para o sinalizador fornecido. Fazer isso altera ligeiramente o significado da bandeira. Se um sinalizador tiver um NoOptDefVal e o sinalizador for definido na linha de comando sem uma opção, o sinalizador será definido como NoOptDefVal. Por exemplo dado:
var ip = flag . IntP ( "flagname" , "f" , 1234 , "help message" )
flag . Lookup ( "flagname" ). NoOptDefVal = "4321"
Resultaria em algo como
Argumentos analisados | Valor resultante |
---|---|
--flagname=1357 | IP=1357 |
--flagname | ip=4321 |
[nada] | ip=1234 |
--flag // boolean flags, or flags with no option default values
--flag x // only on flags without a default value
--flag=x
Ao contrário do pacote flag, um único traço antes de uma opção significa algo diferente de um traço duplo. Traços únicos significam uma série de letras abreviadas para bandeiras. Todas, exceto a última letra abreviada, devem ser sinalizadores booleanos ou um sinalizador com um valor padrão
// boolean or flags where the 'no option default value' is set
-f
-f=true
-abc
but
-b true is INVALID
// non-boolean and flags without a 'no option default value'
-n 1234
-n=1234
-n1234
// mixed
-abcs "hello"
-absd="hello"
-abcs1234
A análise do sinalizador para após o terminador "--". Ao contrário do pacote flag, os flags podem ser intercalados com argumentos em qualquer lugar da linha de comando antes deste terminador.
Sinalizadores inteiros aceitam 1234, 0664, 0x1234 e podem ser negativos. Sinalizadores booleanos (em sua forma longa) aceitam 1, 0, t, f, verdadeiro, falso, VERDADEIRO, FALSO, Verdadeiro, Falso. Os sinalizadores de duração aceitam qualquer entrada válida para time.ParseDuration.
É possível definir um nome de sinalizador personalizado 'função de normalização'. Ele permite que os nomes dos sinalizadores sejam alterados quando criados no código e quando usados na linha de comando para alguma forma 'normalizada'. A forma 'normalizada' é usada para comparação. Seguem dois exemplos de uso da função de normalização personalizada.
Exemplo # 1 : você deseja -, _ e . em sinalizadores para comparar o mesmo. também conhecido como --my-flag == --my_flag == --my.flag
func wordSepNormalizeFunc ( f * pflag. FlagSet , name string ) pflag. NormalizedName {
from := [] string { "-" , "_" }
to := "."
for _ , sep := range from {
name = strings . Replace ( name , sep , to , - 1 )
}
return pflag . NormalizedName ( name )
}
myFlagSet . SetNormalizeFunc ( wordSepNormalizeFunc )
Exemplo # 2 : você deseja criar um alias para dois sinalizadores. também conhecido como --old-flag-name == --new-flag-name
func aliasNormalizeFunc ( f * pflag. FlagSet , name string ) pflag. NormalizedName {
switch name {
case "old-flag-name" :
name = "new-flag-name"
break
}
return pflag . NormalizedName ( name )
}
myFlagSet . SetNormalizeFunc ( aliasNormalizeFunc )
É possível descontinuar um sinalizador ou apenas sua abreviação. A descontinuação de um sinalizador/abreviação oculta-o do texto de ajuda e imprime uma mensagem de uso quando a sinalização/abreviação obsoleta é usada.
Exemplo # 1 : você deseja descontinuar um sinalizador chamado "badflag" e também informar aos usuários qual sinalizador eles devem usar.
// deprecate a flag by specifying its name and a usage message
flags . MarkDeprecated ( "badflag" , "please use --good-flag instead" )
Isso oculta "badflag" do texto de ajuda e imprime Flag --badflag has been deprecated, please use --good-flag instead
quando "badflag" for usado.
Exemplo # 2 : Você deseja manter o nome de sinalizador "noshorthandflag", mas descontinuar seu nome abreviado "n".
// deprecate a flag shorthand by specifying its flag name and a usage message
flags . MarkShorthandDeprecated ( "noshorthandflag" , "please use --noshorthandflag only" )
Isso oculta o nome abreviado "n" do texto de ajuda e imprime Flag shorthand -n has been deprecated, please use --noshorthandflag only
quando o abreviado "n" for usado.
Observe que a mensagem de uso é essencial aqui e não deve estar vazia.
É possível marcar um sinalizador como oculto, o que significa que ele ainda funcionará normalmente, porém não aparecerá no texto de uso/ajuda.
Exemplo : você tem um sinalizador chamado "secretFlag" que precisa apenas para uso interno e não deseja que ele apareça no texto de ajuda ou que seu texto de uso esteja disponível.
// hide a flag by specifying its name
flags . MarkHidden ( "secretFlag" )
pflag
permite que você desabilite a classificação de sinalizadores para mensagens de ajuda e uso.
Exemplo :
flags . BoolP ( "verbose" , "v" , false , "verbose output" )
flags . String ( "coolflag" , "yeaah" , "it's really cool flag" )
flags . Int ( "usefulflag" , 777 , "sometimes it's very useful" )
flags . SortFlags = false
flags . PrintDefaults ()
Saída :
-v, --verbose verbose output
--coolflag string it's really cool flag (default "yeaah")
--usefulflag int sometimes it's very useful (default 777)
Para suportar sinalizadores definidos usando o pacote flag
do Go, eles devem ser adicionados ao conjunto de sinalizadores pflag
. Isso geralmente é necessário para suportar sinalizadores definidos por dependências de terceiros (por exemplo, golang/glog
).
Exemplo : você deseja adicionar os sinalizadores Go ao conjunto de sinalizadores CommandLine
import (
goflag "flag"
flag "github.com/spf13/pflag"
)
var ip * int = flag . Int ( "flagname" , 1234 , "help message for flagname" )
func main () {
flag . CommandLine . AddGoFlagSet ( goflag . CommandLine )
flag . Parse ()
}
Você pode ver a documentação de referência completa do pacote pflag em godoc.org ou através do sistema de documentação padrão do go executando godoc -http=:6060
e navegando até http://localhost:6060/pkg/github.com/spf13/pflag após a instalação.