Wichtig
Dieses Repo wurde nach https://github.com/dart-lang/core/tree/main/pkgs/args verschoben
Analysiert rohe Befehlszeilenargumente in eine Reihe von Optionen und Werten.
Diese Bibliothek unterstützt Optionen im GNU- und POSIX-Stil und funktioniert sowohl in serverseitigen als auch in clientseitigen Apps.
Erstellen Sie zunächst einen ArgParser:
var parser = ArgParser();
Definieren Sie dann mit addOption() und addFlag() eine Reihe von Optionen für diesen Parser. Hier ist die minimale Möglichkeit, eine Option mit dem Namen „name“ zu erstellen:
parser.addOption('name');
Wenn eine Option nur gesetzt oder deaktiviert werden kann (anstatt einen String-Wert anzunehmen), verwenden Sie ein Flag:
parser. addFlag ( 'name' );
Flag-Optionen akzeptieren standardmäßig ein „no-“-Präfix, um die Option zu negieren. Sie können das Präfix „no-“ mithilfe des negatable
Parameters deaktivieren:
parser. addFlag ( 'name' , negatable : false );
Hinweis: Von hier an bezieht sich „Option“ sowohl auf reguläre Optionen als auch auf Flags. In Fällen, in denen die Unterscheidung wichtig ist, verwenden wir die „Nicht-Flag-Option“.
Optionen können eine optionale Abkürzung aus einem Zeichen haben, die mit dem Parameter abbr
angegeben wird:
parser. addOption ( 'mode' , abbr : 'm' );
parser. addFlag ( 'verbose' , abbr : 'v' );
Optionen können auch einen Standardwert haben, der mit dem Parameter defaultsTo
angegeben wird. Der Standardwert wird verwendet, wenn Argumente die Option nicht angeben.
parser. addOption ( 'mode' , defaultsTo : 'debug' );
parser. addFlag ( 'verbose' , defaultsTo : false );
Der Standardwert für Nicht-Flag-Optionen kann eine beliebige Zeichenfolge sein. Für Flags muss es ein bool
sein.
Um eine Nicht-Flag-Option zu validieren, können Sie den Parameter „ allowed
“ verwenden, um einen zulässigen Satz von Werten bereitzustellen. Wenn Sie dies tun, löst der Parser eine ArgParserException
aus, wenn der Wert für eine Option nicht im zulässigen Satz liegt. Hier ist ein Beispiel für die Angabe zulässiger Werte:
parser. addOption ( 'mode' , allowed : [ 'debug' , 'release' ]);
Mit dem callback
Parameter können Sie eine Funktion einer Option zuordnen. Später, wenn die Analyse erfolgt, wird die Rückruffunktion mit dem Wert der Option aufgerufen:
parser. addOption ( 'mode' , callback : (mode) => print ( 'Got mode $ mode ' ));
parser. addFlag ( 'verbose' , callback : (verbose) {
if (verbose) print ( 'Verbose' );
});
Die Rückrufe für alle Optionen werden immer dann aufgerufen, wenn eine Reihe von Argumenten analysiert wird. Wenn in den Argumenten keine Option angegeben ist, wird ihrem Rückruf der Standardwert oder null
übergeben, wenn kein Standardwert festgelegt ist.
Wenn eine Option mandatory
ist, aber nicht bereitgestellt wird, löst das Ergebnisobjekt beim Abrufen einen [ ArgumentError
][ArgumentError] aus.
parser. addOption ( 'mode' , mandatory : true );
Sobald Sie einen ArgParser mit einigen Optionen und Flags eingerichtet haben, verwenden Sie ihn, indem Sie ArgParser.parse() mit einer Reihe von Argumenten aufrufen:
var results = parser. parse ([ 'some' , 'command' , 'line' , 'args' ]);
Diese Argumente stammen normalerweise aus den Argumenten für main()
. Zum Beispiel:
main(List<String> args) {
// ...
var results = parser.parse(args);
}
Sie können jedoch eine beliebige Liste von Zeichenfolgen übergeben. Die parse()
Methode gibt eine Instanz von ArgResults zurück, ein kartenähnliches Objekt, das die Werte der analysierten Optionen enthält.
var parser = ArgParser ();
parser. addOption ( 'mode' );
parser. addFlag ( 'verbose' , defaultsTo : true );
var results = parser. parse ([ '--mode' , 'debug' , 'something' , 'else' ]);
print (results. option ( 'mode' )); // debug
print (results. flag ( 'verbose' )); // true
Standardmäßig ermöglicht die parse()
Methode die Übergabe zusätzlicher Flags und Optionen nach Positionsparametern, es sei denn, --
wird verwendet, um anzugeben, dass alle weiteren Parameter Positionsparameter sein werden. Die Positionsargumente gehen in ArgResults.rest.
print (results.rest); // ['something', 'else']
Um das Parsen von Optionen zu stoppen, sobald ein Positionsargument gefunden wird, erlauben Sie beim Erstellen des ArgParsers allowTrailingOptions: false
.
Um tatsächlich Optionen und Flags in der Befehlszeile zu übergeben, verwenden Sie den GNU- oder POSIX-Stil. Betrachten Sie diese Option:
parser. addOption ( 'name' , abbr : 'n' );
Sie können seinen Wert in der Befehlszeile mit einem der folgenden Befehle angeben:
--name=somevalue
--name somevalue
-nsomevalue
-n somevalue
Betrachten Sie diese Flagge:
parser. addFlag ( 'name' , abbr : 'n' );
Sie können es mit einer der folgenden Methoden auf „true“ setzen:
--name
-n
Sie können es wie folgt auf „false“ setzen:
--no-name
Mehrere Flaggenabkürzungen können zu einem einzigen Argument zusammengefasst werden. Angenommen, Sie definieren diese Flags:
parser
.. addFlag ( 'verbose' , abbr : 'v' )
.. addFlag ( 'french' , abbr : 'f' )
.. addFlag ( 'iambic-pentameter' , abbr : 'i' );
Sie können alle drei Flags gleichzeitig setzen:
-vfi
Standardmäßig hat eine Option nur einen einzigen Wert, wobei spätere Optionswerte frühere überschreiben; Zum Beispiel:
var parser = ArgParser ();
parser. addOption ( 'mode' );
var results = parser. parse ([ '--mode' , 'on' , '--mode' , 'off' ]);
print (results. option ( 'mode' )); // prints 'off'
Mit addMultiOption()
können mehrere Werte geparst werden. Mit dieser Methode kann eine Option mehrmals vorkommen und die Methode parse()
gibt eine Liste von Werten zurück:
var parser = ArgParser ();
parser. addMultiOption ( 'mode' );
var results = parser. parse ([ '--mode' , 'on' , '--mode' , 'off' ]);
print (results. multiOption ( 'mode' )); // prints '[on, off]'
Standardmäßig können Werte für eine mehrwertige Option auch durch Kommas getrennt werden:
var parser = ArgParser ();
parser. addMultiOption ( 'mode' );
var results = parser. parse ([ '--mode' , 'on,off' ]);
print (results. multiOption ( 'mode' )); // prints '[on, off]'
Dies kann durch die Übergabe splitCommas: false
deaktiviert werden.
Neben Optionen können Sie auch Befehle definieren. Ein Befehl ist ein benanntes Argument, das über einen eigenen Satz von Optionen verfügt. Betrachten Sie beispielsweise diesen Shell-Befehl:
$ git commit -a
Die ausführbare Datei ist git
, der Befehl ist commit
und die Option -a
ist eine Option, die an den Befehl übergeben wird. Sie können einen Befehl mit der addCommand-Methode hinzufügen:
var parser = ArgParser ();
var command = parser. addCommand ( 'commit' );
Es gibt einen weiteren ArgParser zurück, den Sie dann verwenden können, um für diesen Befehl spezifische Optionen zu definieren. Wenn Sie bereits über einen ArgParser für die Befehlsoptionen verfügen, können Sie ihn übergeben:
var parser = ArgParser ();
var command = ArgParser ();
parser. addCommand ( 'commit' , command);
Der ArgParser für einen Befehl kann dann Optionen oder Flags definieren:
command. addFlag ( 'all' , abbr : 'a' );
Sie können demselben Parser mehrere Befehle hinzufügen, sodass ein Benutzer einen aus einer Reihe möglicher Befehle auswählen kann. Beim Parsen einer Argumentliste können Sie dann feststellen, welcher Befehl eingegeben wurde und welche Optionen dafür bereitgestellt wurden.
var results = parser. parse ([ 'commit' , '-a' ]);
print (results.command.name); // "commit"
print (results.command[ 'all' ]); // true
Optionen für einen Befehl müssen nach dem Befehl in der Argumentliste erscheinen. Angesichts des obigen Parsers ist beispielsweise "git -a commit"
ungültig . Der Parser versucht, den Befehl ganz rechts zu finden, der eine Option akzeptiert. Zum Beispiel:
var parser = ArgParser ();
parser. addFlag ( 'all' , abbr : 'a' );
var command = parser. addCommand ( 'commit' );
command. addFlag ( 'all' , abbr : 'a' );
var results = parser. parse ([ 'commit' , '-a' ]);
print (results.command[ 'all' ]); // true
Hier können sowohl der Parser der obersten Ebene als auch der Befehl "commit"
ein "-a"
akzeptieren (was zugegebenermaßen wahrscheinlich eine schlechte Befehlszeilenschnittstelle ist). Wenn in diesem Fall "-a"
nach "commit"
erscheint, wird es auf diesen Befehl angewendet. Wenn es links von "commit"
erscheint, wird es an den Parser der obersten Ebene übergeben.
Wenn Sie eine befehlsbasierte Anwendung schreiben, können Sie die Klassen CommandRunner und Command zur Strukturierung verwenden. CommandRunner verfügt über integrierte Unterstützung für das Senden von Befehlen basierend auf Befehlszeilenargumenten sowie für die Behandlung --help
Flags und ungültigen Argumenten.
Bei Verwendung des CommandRunner ersetzt es den ArgParser.
Im folgenden Beispiel erstellen wir eine Dart-Anwendung namens dgit
die die Befehle commit
und stash
akzeptiert.
Der CommandRunner benötigt einen executableName
, der zum Generieren der Hilfemeldung verwendet wird.
zB dgit commit -a
Datei dgit.dart
void main ( List < String > args) {
var runner = CommandRunner ( "dgit" , "A dart implementation of distributed version control." )
.. addCommand ( CommitCommand ())
.. addCommand ( StashCommand ())
.. run (args);
}
Wenn die obige run(args)
-Zeile ausgeführt wird, analysiert sie die Befehlszeilenargumente und sucht nach einem der Befehle ( commit
oder stash
).
Wenn der CommandRunner einen passenden Befehl findet, ruft der CommandRunner die überschriebene run()
Methode für den passenden Befehl auf (z. B. CommitCommand().run).
Befehle werden durch Erweiterung der Command-Klasse definiert. Zum Beispiel:
class CommitCommand extends Command {
// The [name] and [description] properties must be defined by every
// subclass.
final name = "commit" ;
final description = "Record changes to the repository." ;
CommitCommand () {
// we can add command specific arguments here.
// [argParser] is automatically created by the parent class.
argParser. addFlag ( 'all' , abbr : 'a' );
}
// [run] may also return a Future.
void run () {
// [argResults] is set before [run()] is called and contains the flags/options
// passed to this command.
print (argResults. flag ( 'all' ));
}
}
Mit CommandRunner können Sie sowohl globale Argumente als auch befehlsspezifische Argumente (und sogar unterbefehlsspezifische Argumente) angeben.
Fügen Sie Argumente direkt zum CommandRunner hinzu, um globale Argumente anzugeben:
Globale Argumente hinzufügen
var runner = CommandRunner ( 'dgit' , "A dart implementation of distributed version control." );
// add global flag
runner.argParser. addFlag ( 'verbose' , abbr : 'v' , help : 'increase logging' );
Fügen Sie jedem Befehl Argumente hinzu, um befehlsspezifische Argumente anzugeben.
CommitCommand () {
// we can add command specific arguments here.
// [argParser] is automatically created by the parent class.
argParser. addFlag ( 'all' , abbr : 'a' );
}
Befehle können auch Unterbefehle haben, die mit addSubcommand hinzugefügt werden. Ein Befehl mit Unterbefehlen kann keinen eigenen Code ausführen, daher muss run nicht implementiert werden. Zum Beispiel:
class StashCommand extends Command {
final String name = "stash" ;
final String description = "Stash changes in the working directory." ;
StashCommand () {
addSubcommand ( StashSaveCommand ());
addSubcommand ( StashListCommand ());
}
}
CommandRunner fügt automatisch einen help
hinzu, der Nutzungsinformationen für Befehle anzeigt und das Flag --help
für alle Befehle unterstützt. Wenn beim Parsen der Argumente oder beim Verarbeiten eines Befehls ein Fehler auftritt, wird eine UsageException ausgelöst. Ihre main()
Methode sollte diese abfangen und entsprechend ausgeben. Zum Beispiel:
runner. run (arguments). catchError ((error) {
if (error is ! UsageException ) throw error;
print (error);
exit ( 64 ); // Exit code 64 indicates a usage error.
});
Sie können automatisch einen schönen Hilfetext generieren, der sich als Ausgabe von --help
eignet. Um gute Nutzungsinformationen anzuzeigen, sollten Sie beim Erstellen Ihrer Optionen einen Hilfetext bereitstellen.
Um Hilfetext für eine gesamte Option zu definieren, verwenden Sie den Parameter help:
::
parser. addOption ( 'mode' , help : 'The compiler configuration' ,
allowed : [ 'debug' , 'release' ]);
parser. addFlag ( 'verbose' , help : 'Show additional diagnostic info' );
Für Nicht-Flag-Optionen können Sie auch eine Hilfezeichenfolge für den Parameter bereitstellen:
parser. addOption ( 'out' , help : 'The output path' , valueHelp : 'path' ,
allowed : [ 'debug' , 'release' ]);
Für Nicht-Flag-Optionen können Sie auch detaillierte Hilfe für jeden erwarteten Wert bereitstellen, indem Sie den Parameter allowedHelp:
verwenden:
parser. addOption ( 'arch' , help : 'The architecture to compile for' ,
allowedHelp : {
'ia32' : 'Intel x86' ,
'arm' : 'ARM Holding 32-bit chip'
});
Um die Hilfe anzuzeigen, verwenden Sie den Usage-Getter:
print (parser.usage);
Die resultierende Zeichenfolge sieht in etwa so aus:
--mode The compiler configuration
[debug, release]
--out=<path> The output path
--[no-]verbose Show additional diagnostic info
--arch The architecture to compile for
[arm] ARM Holding 32-bit chip
[ia32] Intel x86