Importante
Este repositorio se ha trasladado a https://github.com/dart-lang/core/tree/main/pkgs/args
Analiza argumentos sin procesar de la línea de comandos en un conjunto de opciones y valores.
Esta biblioteca admite opciones de estilo GNU y POSIX y funciona tanto en aplicaciones del lado del servidor como del lado del cliente.
Primero cree un ArgParser:
var parser = ArgParser();
Luego defina un conjunto de opciones en ese analizador usando addOption() y addFlag(). Esta es la forma mínima de crear una opción llamada "nombre":
parser.addOption('name');
Cuando una opción solo se puede configurar o desarmar (en lugar de tomar un valor de cadena), use una bandera:
parser. addFlag ( 'name' );
Las opciones de marca, de forma predeterminada, aceptan un prefijo 'no-' para negar la opción. Puede desactivar el prefijo 'no-' utilizando el parámetro negatable
:
parser. addFlag ( 'name' , negatable : false );
Nota: De ahora en adelante, "opción" se refiere tanto a las opciones regulares como a las banderas. En los casos en que la distinción sea importante, usaremos la "opción sin marca".
Las opciones pueden tener una abreviatura opcional de un solo carácter, especificada con el parámetro abbr
:
parser. addOption ( 'mode' , abbr : 'm' );
parser. addFlag ( 'verbose' , abbr : 'v' );
Las opciones también pueden tener un valor predeterminado, especificado con el parámetro defaultsTo
. El valor predeterminado se utiliza cuando los argumentos no especifican la opción.
parser. addOption ( 'mode' , defaultsTo : 'debug' );
parser. addFlag ( 'verbose' , defaultsTo : false );
El valor predeterminado para las opciones sin marca puede ser cualquier cadena. Para banderas, debe ser un bool
.
Para validar una opción sin marca, puede utilizar el parámetro allowed
para proporcionar un conjunto de valores permitido. Cuando lo hace, el analizador genera una ArgParserException
si el valor de una opción no está en el conjunto permitido. A continuación se muestra un ejemplo de cómo especificar valores permitidos:
parser. addOption ( 'mode' , allowed : [ 'debug' , 'release' ]);
Puede utilizar el parámetro callback
para asociar una función con una opción. Posteriormente, cuando se produce el análisis, se invoca la función de devolución de llamada con el valor de la opción:
parser. addOption ( 'mode' , callback : (mode) => print ( 'Got mode $ mode ' ));
parser. addFlag ( 'verbose' , callback : (verbose) {
if (verbose) print ( 'Verbose' );
});
Las devoluciones de llamada para todas las opciones se llaman cada vez que se analiza un conjunto de argumentos. Si no se proporciona una opción en los argumentos, su devolución de llamada pasa el valor predeterminado, o null
si no se establece ningún valor predeterminado.
Si una opción es mandatory
pero no se proporciona, el objeto de resultados arroja un [ ArgumentError
][ArgumentError] al recuperarlo.
parser. addOption ( 'mode' , mandatory : true );
Una vez que haya configurado un ArgParser con algunas opciones e indicadores, puede usarlo llamando a ArgParser.parse() con un conjunto de argumentos:
var results = parser. parse ([ 'some' , 'command' , 'line' , 'args' ]);
Estos argumentos generalmente provienen de los argumentos de main()
. Por ejemplo:
main(List<String> args) {
// ...
var results = parser.parse(args);
}
Sin embargo, puede pasar cualquier lista de cadenas. El método parse()
devuelve una instancia de ArgResults, un objeto similar a un mapa que contiene los valores de las opciones analizadas.
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
De forma predeterminada, el método parse()
permite pasar indicadores y opciones adicionales después de los parámetros posicionales, a menos que se use --
para indicar que todos los parámetros adicionales serán posicionales. Los argumentos posicionales van a ArgResults.rest.
print (results.rest); // ['something', 'else']
Para detener el análisis de opciones tan pronto como se encuentre un argumento posicional, allowTrailingOptions: false
al crear ArgParser.
Para pasar opciones y banderas en la línea de comando, use el estilo GNU o POSIX. Considere esta opción:
parser. addOption ( 'name' , abbr : 'n' );
Puede especificar su valor en la línea de comando usando cualquiera de los siguientes:
--name=somevalue
--name somevalue
-nsomevalue
-n somevalue
Considere esta bandera:
parser. addFlag ( 'name' , abbr : 'n' );
Puede configurarlo como verdadero usando uno de los siguientes:
--name
-n
Puedes configurarlo en falso usando lo siguiente:
--no-name
Se pueden combinar varias abreviaturas de indicadores en un solo argumento. Supongamos que define estas banderas:
parser
.. addFlag ( 'verbose' , abbr : 'v' )
.. addFlag ( 'french' , abbr : 'f' )
.. addFlag ( 'iambic-pentameter' , abbr : 'i' );
Puedes configurar las tres banderas a la vez:
-vfi
De forma predeterminada, una opción tiene un solo valor, y los valores de opción posteriores anulan los anteriores; Por ejemplo:
var parser = ArgParser ();
parser. addOption ( 'mode' );
var results = parser. parse ([ '--mode' , 'on' , '--mode' , 'off' ]);
print (results. option ( 'mode' )); // prints 'off'
Se pueden analizar varios valores con addMultiOption()
. Con este método, una opción puede aparecer varias veces y el método parse()
devuelve una lista de valores:
var parser = ArgParser ();
parser. addMultiOption ( 'mode' );
var results = parser. parse ([ '--mode' , 'on' , '--mode' , 'off' ]);
print (results. multiOption ( 'mode' )); // prints '[on, off]'
De forma predeterminada, los valores de una opción de varios valores también pueden estar separados por comas:
var parser = ArgParser ();
parser. addMultiOption ( 'mode' );
var results = parser. parse ([ '--mode' , 'on,off' ]);
print (results. multiOption ( 'mode' )); // prints '[on, off]'
Esto se puede desactivar pasando splitCommas: false
.
Además de las opciones , también puedes definir comandos . Un comando es un argumento con nombre que tiene su propio conjunto de opciones. Por ejemplo, considere este comando de shell:
$ git commit -a
El ejecutable es git
, el comando es commit
y la opción -a
es una opción pasada al comando. Puede agregar un comando usando el método addCommand:
var parser = ArgParser ();
var command = parser. addCommand ( 'commit' );
Devuelve otro ArgParser, que luego puedes usar para definir opciones específicas para ese comando. Si ya tienes un ArgParser para las opciones del comando, puedes pasarlo:
var parser = ArgParser ();
var command = ArgParser ();
parser. addCommand ( 'commit' , command);
El ArgParser de un comando puede definir opciones o indicadores:
command. addFlag ( 'all' , abbr : 'a' );
Puede agregar varios comandos al mismo analizador para que un usuario pueda seleccionar uno entre una variedad de comandos posibles. Al analizar una lista de argumentos, puede determinar qué comando se ingresó y qué opciones se le proporcionaron.
var results = parser. parse ([ 'commit' , '-a' ]);
print (results.command.name); // "commit"
print (results.command[ 'all' ]); // true
Las opciones de un comando deben aparecer después del comando en la lista de argumentos. Por ejemplo, dado el analizador anterior, "git -a commit"
no es válido. El analizador intenta encontrar el comando más a la derecha que acepte una opción. Por ejemplo:
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
Aquí, tanto el analizador de nivel superior como el comando "commit"
pueden aceptar un "-a"
(que probablemente sea una mala interfaz de línea de comando, hay que reconocerlo). En ese caso, cuando aparece "-a"
después de "commit"
, se aplica a ese comando. Si aparece a la izquierda de "commit"
, se entrega al analizador de nivel superior.
Si está escribiendo una aplicación basada en comandos, puede usar las clases CommandRunner y Command para ayudar a estructurarla. CommandRunner tiene soporte integrado para enviar comandos basados en argumentos de línea de comandos, así como para manejar indicadores --help
y argumentos no válidos.
Cuando se utiliza CommandRunner, reemplaza a ArgParser.
En el siguiente ejemplo, creamos una aplicación Dart llamada dgit
que toma los comandos commit
y stash
.
CommandRunner toma un executableName
que se utiliza para generar el mensaje de ayuda.
por dgit commit -a
Archivo dgit.dart
void main ( List < String > args) {
var runner = CommandRunner ( "dgit" , "A dart implementation of distributed version control." )
.. addCommand ( CommitCommand ())
.. addCommand ( StashCommand ())
.. run (args);
}
Cuando se ejecuta la línea run(args)
anterior, analiza los argumentos de la línea de comando buscando uno de los comandos ( commit
o stash
).
Si CommandRunner encuentra un comando coincidente, CommandRunner llama al método run()
anulado en el comando coincidente (por ejemplo, CommitCommand().run).
Los comandos se definen ampliando la clase Command. Por ejemplo:
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' ));
}
}
CommandRunner le permite especificar tanto argumentos globales como argumentos específicos de comandos (e incluso argumentos específicos de subcomandos).
Agregue argumentos directamente al CommandRunner para especificar argumentos globales:
Agregar argumentos globales
var runner = CommandRunner ( 'dgit' , "A dart implementation of distributed version control." );
// add global flag
runner.argParser. addFlag ( 'verbose' , abbr : 'v' , help : 'increase logging' );
Agregue argumentos a cada comando para especificar argumentos específicos del comando.
CommitCommand () {
// we can add command specific arguments here.
// [argParser] is automatically created by the parent class.
argParser. addFlag ( 'all' , abbr : 'a' );
}
Los comandos también pueden tener subcomandos, que se agregan con addSubcommand. Un comando con subcomandos no puede ejecutar su propio código, por lo que no es necesario implementar la ejecución. Por ejemplo:
class StashCommand extends Command {
final String name = "stash" ;
final String description = "Stash changes in the working directory." ;
StashCommand () {
addSubcommand ( StashSaveCommand ());
addSubcommand ( StashListCommand ());
}
}
CommandRunner agrega automáticamente un comando help
que muestra información de uso de los comandos, así como soporte para el indicador --help
para todos los comandos. Si encuentra un error al analizar los argumentos o al procesar un comando, genera una UsageException; su método main()
debería capturarlos e imprimirlos apropiadamente. Por ejemplo:
runner. run (arguments). catchError ((error) {
if (error is ! UsageException ) throw error;
print (error);
exit ( 64 ); // Exit code 64 indicates a usage error.
});
Puede generar automáticamente un texto de ayuda agradable, adecuado para usarlo como salida de --help
. Para mostrar información de buen uso, debe proporcionar algún texto de ayuda cuando cree sus opciones.
Para definir el texto de ayuda para una opción completa, use el parámetro help:
::
parser. addOption ( 'mode' , help : 'The compiler configuration' ,
allowed : [ 'debug' , 'release' ]);
parser. addFlag ( 'verbose' , help : 'Show additional diagnostic info' );
Para opciones sin bandera, también puede proporcionar una cadena de ayuda para el parámetro:
parser. addOption ( 'out' , help : 'The output path' , valueHelp : 'path' ,
allowed : [ 'debug' , 'release' ]);
Para las opciones sin bandera, también puede proporcionar ayuda detallada para cada valor esperado utilizando el parámetro allowedHelp:
::
parser. addOption ( 'arch' , help : 'The architecture to compile for' ,
allowedHelp : {
'ia32' : 'Intel x86' ,
'arm' : 'ARM Holding 32-bit chip'
});
Para mostrar la ayuda, utilice el captador de uso:
print (parser.usage);
La cadena resultante se parece a esta:
--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