مهم
تم نقل هذا الريبو إلى https://github.com/dart-lang/core/tree/main/pkgs/args
يوزع وسيطات سطر الأوامر الأولية إلى مجموعة من الخيارات والقيم.
تدعم هذه المكتبة خيارات نمط GNU وPOSIX، وتعمل في كل من التطبيقات من جانب الخادم ومن جانب العميل.
قم أولاً بإنشاء ArgParser:
var parser = ArgParser();
ثم حدد مجموعة من الخيارات على هذا المحلل باستخدام addOption() و addFlag(). إليك الطريقة البسيطة لإنشاء خيار باسم "الاسم":
parser.addOption('name');
عندما يكون من الممكن تعيين خيار ما أو عدم تعيينه فقط (بدلاً من أخذ قيمة سلسلة)، استخدم علامة:
parser. addFlag ( 'name' );
تقبل خيارات العلامة، افتراضيًا، البادئة "لا-" لإلغاء الخيار. يمكنك تعطيل البادئة "no-" باستخدام المعلمة negatable
:
parser. addFlag ( 'name' , negatable : false );
ملاحظة: من الآن فصاعدًا، يشير "الخيار" إلى كل من الخيارات والأعلام العادية. في الحالات التي يكون فيها التمييز مهمًا، سنستخدم "خيار عدم وضع علامة".
يمكن أن تحتوي الخيارات على اختصار اختياري مكون من حرف واحد، يتم تحديده باستخدام المعلمة abbr
:
parser. addOption ( 'mode' , abbr : 'm' );
parser. addFlag ( 'verbose' , abbr : 'v' );
يمكن أن تحتوي الخيارات أيضًا على قيمة افتراضية، يتم تحديدها باستخدام المعلمة defaultsTo
. يتم استخدام القيمة الافتراضية عندما لا تحدد الوسيطات الخيار.
parser. addOption ( 'mode' , defaultsTo : 'debug' );
parser. addFlag ( 'verbose' , defaultsTo : false );
يمكن أن تكون القيمة الافتراضية للخيارات بدون علامة أي سلسلة. بالنسبة للأعلام، يجب أن يكون bool
.
للتحقق من صحة خيار بدون علامة، يمكنك استخدام المعلمة allowed
لتوفير مجموعة من القيم المسموح بها. عند القيام بذلك، يقوم المحلل بطرح ArgParserException
إذا كانت قيمة أحد الخيارات ليست في المجموعة المسموح بها. فيما يلي مثال لتحديد القيم المسموح بها:
parser. addOption ( 'mode' , allowed : [ 'debug' , 'release' ]);
يمكنك استخدام معلمة callback
لربط وظيفة بخيار. لاحقًا، عند حدوث التحليل، يتم استدعاء وظيفة رد الاتصال بقيمة الخيار:
parser. addOption ( 'mode' , callback : (mode) => print ( 'Got mode $ mode ' ));
parser. addFlag ( 'verbose' , callback : (verbose) {
if (verbose) print ( 'Verbose' );
});
يتم استدعاء عمليات الاسترجاعات لجميع الخيارات عندما يتم تحليل مجموعة من الوسائط. إذا لم يتم توفير خيار في الوسيطات، فسيتم تمرير رد الاتصال الخاص به بالقيمة الافتراضية، أو null
إذا لم يتم تعيين قيمة افتراضية.
إذا كان الخيار mandatory
ولكن لم يتم توفيره، فسيقوم كائن النتائج بطرح الخطأ [ ArgumentError
] [ArgumentError] عند استرجاعه.
parser. addOption ( 'mode' , mandatory : true );
بمجرد إعداد ArgParser مع بعض الخيارات والأعلام، يمكنك استخدامه عن طريق استدعاء ArgParser.parse() مع مجموعة من الوسائط:
var results = parser. parse ([ 'some' , 'command' , 'line' , 'args' ]);
تأتي هذه الوسائط عادةً من الوسائط إلى main()
. على سبيل المثال:
main(List<String> args) {
// ...
var results = parser.parse(args);
}
ومع ذلك، يمكنك تمرير أي قائمة من السلاسل. يقوم الأسلوب parse()
بإرجاع مثيل ArgResults، وهو كائن يشبه الخريطة يحتوي على قيم الخيارات التي تم تحليلها.
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
افتراضيًا، يسمح التابع parse()
بتمرير إشارات وخيارات إضافية بعد المعلمات الموضعية ما لم يتم استخدام --
للإشارة إلى أن جميع المعلمات الإضافية ستكون موضعية. تنتقل الوسائط الموضعية إلى ArgResults.rest.
print (results.rest); // ['something', 'else']
لإيقاف تحليل الخيارات بمجرد العثور على وسيطة موضعية، allowTrailingOptions: false
عند إنشاء ArgParser.
لتمرير الخيارات والأعلام فعليًا في سطر الأوامر، استخدم أسلوب GNU أو POSIX. فكر في هذا الخيار:
parser. addOption ( 'name' , abbr : 'n' );
يمكنك تحديد قيمتها في سطر الأوامر باستخدام أي مما يلي:
--name=somevalue
--name somevalue
-nsomevalue
-n somevalue
خذ بعين الاعتبار هذا العلم:
parser. addFlag ( 'name' , abbr : 'n' );
يمكنك ضبطه على "صحيح" باستخدام أحد الإجراءات التالية:
--name
-n
يمكنك ضبطه على خطأ باستخدام ما يلي:
--no-name
يمكن طي اختصارات العلامات المتعددة في وسيطة واحدة. لنفترض أنك حددت هذه العلامات:
parser
.. addFlag ( 'verbose' , abbr : 'v' )
.. addFlag ( 'french' , abbr : 'f' )
.. addFlag ( 'iambic-pentameter' , abbr : 'i' );
يمكنك تعيين جميع الأعلام الثلاثة مرة واحدة:
-vfi
افتراضيًا، يحتوي الخيار على قيمة واحدة فقط، مع تجاوز قيم الخيارات اللاحقة للخيارات السابقة؛ على سبيل المثال:
var parser = ArgParser ();
parser. addOption ( 'mode' );
var results = parser. parse ([ '--mode' , 'on' , '--mode' , 'off' ]);
print (results. option ( 'mode' )); // prints 'off'
يمكن تحليل قيم متعددة باستخدام addMultiOption()
. باستخدام هذه الطريقة، يمكن أن يحدث الخيار عدة مرات، وترجع الطريقة parse()
قائمة من القيم:
var parser = ArgParser ();
parser. addMultiOption ( 'mode' );
var results = parser. parse ([ '--mode' , 'on' , '--mode' , 'off' ]);
print (results. multiOption ( 'mode' )); // prints '[on, off]'
افتراضيًا، يمكن أيضًا فصل قيم الخيار متعدد القيم بفواصل:
var parser = ArgParser ();
parser. addMultiOption ( 'mode' );
var results = parser. parse ([ '--mode' , 'on,off' ]);
print (results. multiOption ( 'mode' )); // prints '[on, off]'
يمكن تعطيل هذا عن طريق تمرير splitCommas: false
.
بالإضافة إلى الخيارات ، يمكنك أيضًا تحديد الأوامر . الأمر عبارة عن وسيطة مسماة تحتوي على مجموعة الخيارات الخاصة بها. على سبيل المثال، خذ بعين الاعتبار أمر الصدفة هذا:
$ git commit -a
الملف القابل للتنفيذ هو git
، والأمر commit
، والخيار -a
هو خيار تم تمريره إلى الأمر. يمكنك إضافة أمر باستخدام طريقة addCommand:
var parser = ArgParser ();
var command = parser. addCommand ( 'commit' );
يقوم بإرجاع ArgParser آخر، والذي يمكنك استخدامه بعد ذلك لتحديد الخيارات الخاصة بهذا الأمر. إذا كان لديك بالفعل ArgParser لخيارات الأمر، فيمكنك تمريره عبر:
var parser = ArgParser ();
var command = ArgParser ();
parser. addCommand ( 'commit' , command);
يمكن لـ ArgParser للأمر بعد ذلك تحديد الخيارات أو العلامات:
command. addFlag ( 'all' , abbr : 'a' );
يمكنك إضافة أوامر متعددة إلى نفس المحلل اللغوي بحيث يمكن للمستخدم تحديد واحد من مجموعة من الأوامر المحتملة. عند تحليل قائمة الوسيطات، يمكنك بعد ذلك تحديد الأمر الذي تم إدخاله والخيارات المتوفرة له.
var results = parser. parse ([ 'commit' , '-a' ]);
print (results.command.name); // "commit"
print (results.command[ 'all' ]); // true
يجب أن تظهر خيارات الأمر بعد الأمر في قائمة الوسائط. على سبيل المثال، في ضوء المحلل اللغوي أعلاه، "git -a commit"
غير صالح. يحاول المحلل اللغوي العثور على الأمر الموجود في أقصى اليمين والذي يقبل أحد الخيارات. على سبيل المثال:
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
هنا، يمكن لكل من المحلل اللغوي عالي المستوى وأمر "commit"
قبول "-a"
(والتي ربما تكون واجهة سطر أوامر سيئة، باعتراف الجميع). في هذه الحالة، عندما يظهر "-a"
بعد "commit"
، يتم تطبيقه على هذا الأمر. إذا ظهر على يسار "commit"
، فسيتم تسليمه إلى المحلل اللغوي ذي المستوى الأعلى.
إذا كنت تكتب تطبيقًا يعتمد على الأوامر، فيمكنك استخدام فئتي CommandRunner وCommand للمساعدة في هيكلته. يحتوي CommandRunner على دعم مدمج للإرسال إلى الأوامر بناءً على وسيطات سطر الأوامر، بالإضافة إلى التعامل مع إشارات --help
والوسائط غير الصالحة.
عند استخدام CommandRunner فإنه يستبدل ArgParser.
في المثال التالي، قمنا ببناء تطبيق دارت يسمى dgit
الذي يأخذ الأوامر commit
stash
.
يأخذ CommandRunner اسمًا executableName
يُستخدم لإنشاء رسالة المساعدة.
على سبيل المثال dgit commit -a
ملف dgit.dart
void main ( List < String > args) {
var runner = CommandRunner ( "dgit" , "A dart implementation of distributed version control." )
.. addCommand ( CommitCommand ())
.. addCommand ( StashCommand ())
.. run (args);
}
عند تنفيذ سطر run(args)
أعلاه، فإنه يقوم بتحليل وسيطات سطر الأوامر بحثًا عن أحد الأوامر ( commit
أو stash
).
إذا عثر CommandRunner على أمر مطابق، فإن CommandRunner يستدعي أسلوب run()
الذي تم تجاوزه في الأمر المطابق (على سبيل المثال، CommitCommand().run).
يتم تعريف الأوامر عن طريق توسيع فئة الأوامر. على سبيل المثال:
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 تحديد كل من الوسيطات العامة بالإضافة إلى وسيطات الأوامر المحددة (وحتى الوسائط المحددة للأوامر الفرعية).
أضف الوسائط مباشرة إلى CommandRunner لتحديد الوسائط العامة:
إضافة الحجج العالمية
var runner = CommandRunner ( 'dgit' , "A dart implementation of distributed version control." );
// add global flag
runner.argParser. addFlag ( 'verbose' , abbr : 'v' , help : 'increase logging' );
أضف وسيطات إلى كل أمر لتحديد وسيطات الأمر المحددة.
CommitCommand () {
// we can add command specific arguments here.
// [argParser] is automatically created by the parent class.
argParser. addFlag ( 'all' , abbr : 'a' );
}
يمكن أن تحتوي الأوامر أيضًا على أوامر فرعية، والتي تتم إضافتها باستخدام addSubcommand. لا يمكن للأمر الذي يحتوي على أوامر فرعية تشغيل التعليمات البرمجية الخاصة به، لذا لا يلزم تنفيذ الأمر run. على سبيل المثال:
class StashCommand extends Command {
final String name = "stash" ;
final String description = "Stash changes in the working directory." ;
StashCommand () {
addSubcommand ( StashSaveCommand ());
addSubcommand ( StashListCommand ());
}
}
يضيف CommandRunner تلقائيًا أمر help
يعرض معلومات الاستخدام للأوامر، بالإضافة إلى دعم علامة --help
لجميع الأوامر. إذا واجه خطأً في تحليل الوسيطات أو معالجة أمر ما، فسيطرح استخدام استثنائي؛ يجب أن تلتقط طريقة main()
هذه العناصر وتطبعها بشكل مناسب. على سبيل المثال:
runner. run (arguments). catchError ((error) {
if (error is ! UsageException ) throw error;
print (error);
exit ( 64 ); // Exit code 64 indicates a usage error.
});
يمكنك تلقائيًا إنشاء نص تعليمات لطيف ومناسب للاستخدام كمخرج --help
. لعرض معلومات الاستخدام الجيدة، يجب عليك تقديم بعض نصوص المساعدة عند إنشاء خياراتك.
لتحديد نص التعليمات لخيار كامل، استخدم المعلمة help:
::
parser. addOption ( 'mode' , help : 'The compiler configuration' ,
allowed : [ 'debug' , 'release' ]);
parser. addFlag ( 'verbose' , help : 'Show additional diagnostic info' );
بالنسبة للخيارات التي لا تحتوي على علامات، يمكنك أيضًا توفير سلسلة تعليمات للمعلمة:
parser. addOption ( 'out' , help : 'The output path' , valueHelp : 'path' ,
allowed : [ 'debug' , 'release' ]);
بالنسبة للخيارات التي لا تتضمن علامة، يمكنك أيضًا تقديم مساعدة تفصيلية لكل قيمة متوقعة باستخدام المعلمة allowedHelp:
::
parser. addOption ( 'arch' , help : 'The architecture to compile for' ,
allowedHelp : {
'ia32' : 'Intel x86' ,
'arm' : 'ARM Holding 32-bit chip'
});
لعرض المساعدة، استخدم مُحضر الاستخدام:
print (parser.usage);
تبدو السلسلة الناتجة كما يلي:
--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