pflag ist ein direkter Ersatz für das Flag-Paket von Go und implementiert --flags im POSIX/GNU-Stil.
pflag ist mit den GNU-Erweiterungen der POSIX-Empfehlungen für Befehlszeilenoptionen kompatibel. Eine genauere Beschreibung finden Sie im Abschnitt „Syntax der Befehlszeilen-Flags“ weiter unten.
pflag ist unter derselben BSD-Lizenz verfügbar wie die Go-Sprache, die in der LICENSE-Datei zu finden ist.
pflag ist mit dem Standardbefehl go get
verfügbar.
Installieren Sie, indem Sie Folgendes ausführen:
go get github.com/spf13/pflag
Führen Sie Tests durch, indem Sie Folgendes ausführen:
go test github.com/spf13/pflag
pflag ist ein direkter Ersatz für das native Flag-Paket von Go. Wenn Sie pflag unter dem Namen „flag“ importieren, sollte der gesamte Code ohne Änderungen weiterhin funktionieren.
import flag "github.com/spf13/pflag"
Hiervon gibt es eine Ausnahme: Wenn Sie die Flag-Struktur direkt instanziieren, müssen Sie ein weiteres Feld „Kurzschrift“ festlegen. Der meiste Code instanziiert diese Struktur nie direkt und verwendet stattdessen Funktionen wie String(), BoolVar() und Var() und ist daher nicht betroffen.
Definieren Sie Flags mit flag.String(), Bool(), Int() usw.
Dies deklariert ein ganzzahliges Flag, -flagname, das in der Zeiger-IP gespeichert ist, mit dem Typ *int.
var ip * int = flag . Int ( "flagname" , 1234 , "help message for flagname" )
Wenn Sie möchten, können Sie das Flag mithilfe der Var()-Funktionen an eine Variable binden.
var flagvar int
func init () {
flag . IntVar ( & flagvar , "flagname" , 1234 , "help message for flagname" )
}
Oder Sie können benutzerdefinierte Flags erstellen, die die Value-Schnittstelle (mit Zeigerempfängern) erfüllen, und diese mit der Flag-Analyse verknüpfen
flag . Var ( & flagVal , "name" , "help message for flagname" )
Für solche Flags ist der Standardwert nur der Anfangswert der Variablen.
Nachdem alle Flags definiert sind, rufen Sie auf
flag . Parse ()
um die Befehlszeile in die definierten Flags zu analysieren.
Flaggen können dann direkt verwendet werden. Wenn Sie die Flags selbst verwenden, handelt es sich bei allen um Zeiger. Wenn Sie an Variablen binden, handelt es sich um Werte.
fmt . Println ( "ip has value " , * ip )
fmt . Println ( "flagvar has value " , flagvar )
Es stehen Hilfsfunktionen zur Verfügung, um den in einem Flag gespeicherten Wert abzurufen, wenn Sie über ein FlagSet verfügen, aber Schwierigkeiten haben, mit allen Zeigern in Ihrem Code Schritt zu halten. Wenn Sie ein pflag.FlagSet mit einem Flag namens „flagname“ vom Typ int haben, können Sie GetInt() verwenden, um den int-Wert abzurufen. Beachten Sie jedoch, dass „Flagname“ existieren und ein int sein muss. GetString("Flagname") schlägt fehl.
i , err := flagset . GetInt ( "flagname" )
Nach dem Parsen stehen die Argumente nach dem Flag als Slice flag.Args() oder einzeln als flag.Arg(i) zur Verfügung. Die Argumente werden von 0 bis flag.NArg()-1 indiziert.
Das pflag-Paket definiert außerdem einige neue Funktionen, die nicht in flag enthalten sind und Ein-Buchstaben-Abkürzungen für Flags bereitstellen. Sie können diese verwenden, indem Sie „P“ an den Namen einer beliebigen Funktion anhängen, die ein Flag definiert.
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" )
In der Befehlszeile können Kurzbuchstaben mit einzelnen Bindestrichen verwendet werden. Boolesche Kurzschrift-Flags können mit anderen Kurzschrift-Flags kombiniert werden.
Der Standardsatz von Befehlszeilenflags wird durch Funktionen der obersten Ebene gesteuert. Mit dem FlagSet-Typ können Sie unabhängige Flag-Sets definieren, um beispielsweise Unterbefehle in einer Befehlszeilenschnittstelle zu implementieren. Die Methoden von FlagSet sind analog zu den Funktionen der obersten Ebene für den Befehlszeilen-Flagsatz.
Nachdem Sie ein Flag erstellt haben, ist es möglich, pflag.NoOptDefVal für das angegebene Flag festzulegen. Dadurch ändert sich die Bedeutung der Flagge geringfügig. Wenn ein Flag einen NoOptDefVal hat und das Flag in der Befehlszeile ohne Option gesetzt wird, wird das Flag auf NoOptDefVal gesetzt. Zum Beispiel gegeben:
var ip = flag . IntP ( "flagname" , "f" , 1234 , "help message" )
flag . Lookup ( "flagname" ). NoOptDefVal = "4321"
Würde so etwas ergeben
Analysierte Argumente | Resultierender Wert |
---|---|
--flagname=1357 | IP=1357 |
--flagname | IP=4321 |
[Nichts] | IP=1234 |
--flag // boolean flags, or flags with no option default values
--flag x // only on flags without a default value
--flag=x
Im Gegensatz zum Flag-Paket bedeutet ein einzelner Bindestrich vor einer Option etwas anderes als ein doppelter Bindestrich. Einzelne Bindestriche kennzeichnen eine Reihe von Kurzbuchstaben für Flaggen. Alle bis auf den letzten Kurzbuchstaben müssen boolesche Flags oder ein Flag mit einem Standardwert sein
// 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
Das Flag-Parsing stoppt nach dem Abschlusszeichen „--“. Im Gegensatz zum Flag-Paket können Flags vor diesem Abschlusszeichen an einer beliebigen Stelle in der Befehlszeile mit Argumenten durchsetzt werden.
Ganzzahl-Flags akzeptieren 1234, 0664, 0x1234 und können negativ sein. Boolesche Flags (in ihrer Langform) akzeptieren 1, 0, t, f, true, false, TRUE, FALSE, True, False. Dauerflags akzeptieren alle für time.ParseDuration gültigen Eingaben.
Es ist möglich, einen benutzerdefinierten Flagnamen „Normalisierungsfunktion“ festzulegen. Dadurch können Flag-Namen sowohl bei der Erstellung im Code als auch bei der Verwendung in der Befehlszeile in eine „normalisierte“ Form umgewandelt werden. Zum Vergleich wird die „normalisierte“ Form verwendet. Es folgen zwei Beispiele für die Verwendung der benutzerdefinierten Normalisierungsfunktion.
Beispiel Nr. 1 : Sie möchten -, _ und . in Flags, um dasselbe zu vergleichen. auch bekannt als --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 )
Beispiel Nr. 2 : Sie möchten zwei Flags mit einem Alias versehen. auch bekannt als --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 )
Es ist möglich, eine Flagge oder nur deren Abkürzung abzulehnen. Durch das Verwerfen einer Flagge/Kurzschrift wird diese aus dem Hilfetext ausgeblendet und eine Verwendungsmeldung ausgegeben, wenn die veraltete Flagge/Kurzschrift verwendet wird.
Beispiel Nr. 1 : Sie möchten ein Flag mit dem Namen „badflag“ ablehnen und den Benutzern mitteilen, welches Flag sie stattdessen verwenden sollen.
// deprecate a flag by specifying its name and a usage message
flags . MarkDeprecated ( "badflag" , "please use --good-flag instead" )
Dadurch wird „badflag“ aus dem Hilfetext ausgeblendet und Flag --badflag has been deprecated, please use --good-flag instead
wenn „badflag“ verwendet wird.
Beispiel Nr. 2 : Sie möchten den Flag-Namen „noshorthandflag“ beibehalten, aber seinen Kurznamen „n“ ablehnen.
// deprecate a flag shorthand by specifying its flag name and a usage message
flags . MarkShorthandDeprecated ( "noshorthandflag" , "please use --noshorthandflag only" )
Dadurch wird der Kurzname „n“ aus dem Hilfetext ausgeblendet und Flag shorthand -n has been deprecated, please use --noshorthandflag only
wenn die Kurzform „n“ verwendet wird.
Beachten Sie, dass die Nutzungsmeldung hier unbedingt erforderlich ist und nicht leer sein sollte.
Es ist möglich, eine Flagge als ausgeblendet zu markieren, was bedeutet, dass sie weiterhin normal funktioniert, jedoch nicht im Verwendungs-/Hilfetext angezeigt wird.
Beispiel : Sie haben ein Flag mit dem Namen „secretFlag“, das Sie nur für den internen Gebrauch benötigen und möchten nicht, dass es im Hilfetext angezeigt wird oder dass sein Verwendungstext verfügbar ist.
// hide a flag by specifying its name
flags . MarkHidden ( "secretFlag" )
pflag
können Sie die Sortierung von Flags für Hilfe- und Nutzungsmeldungen deaktivieren.
Beispiel :
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 ()
Ausgabe :
-v, --verbose verbose output
--coolflag string it's really cool flag (default "yeaah")
--usefulflag int sometimes it's very useful (default 777)
Um Flags zu unterstützen, die mit flag
Paket von Go definiert wurden, müssen sie dem pflag
Flagset hinzugefügt werden. Dies ist normalerweise erforderlich, um Flags zu unterstützen, die durch Abhängigkeiten von Drittanbietern definiert werden (z. B. golang/glog
).
Beispiel : Sie möchten die Go-Flags zum CommandLine
-Flagset hinzufügen
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 ()
}
Sie können die vollständige Referenzdokumentation des pflag-Pakets auf godoc.org oder über das Standarddokumentationssystem von go einsehen, indem Sie godoc -http=:6060
ausführen und zu http://localhost:6060/pkg/github.com/spf13/pflag navigieren nach der Installation.