Skip to content

Instantly share code, notes, and snippets.

@lukaskj
Created May 20, 2022 02:30
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lukaskj/7eb28068a04d589b31c941c48e1a7fb7 to your computer and use it in GitHub Desktop.
Save lukaskj/7eb28068a04d589b31c941c48e1a7fb7 to your computer and use it in GitHub Desktop.
Haxe argument flags helper
package util;
import haxe.io.Path;
enum OptionType {
String;
Bool;
Int;
}
class Option {
public var name:String;
public var value:Dynamic;
public var type:OptionType;
public var description:String;
public var required:Bool;
public function new(name:String, description:String, ?required:Bool = false, ?type:OptionType = OptionType.String) {
this.name = name;
// this.value = value;
this.type = type;
this.description = description;
this.required = required;
}
}
class Getopt {
private static var instance:Getopt = null;
private static var valid:Bool = true;
private var options:Array<Option>;
private var mappedOptions:Map<String, Option> = [];
private var mappedArguments:Map<String, Dynamic> = [];
private function new() {}
public static function build(options:Array<Option>, ?strict:Bool = false):Getopt {
var instance = getInstance();
instance.options = options;
instance.mapOptions();
valid = instance.mapArgumentsAndValidate();
return instance;
}
public static function getInstance():Getopt {
if (instance == null) {
instance = new Getopt();
}
return instance;
}
private function mapOptions():Void {
this.options.sort((opt1, opt2) -> opt2.required ? 1 : -1);
for (opt in this.options) {
this.mappedOptions.set(opt.name, opt);
}
}
private function mapArgumentsAndValidate():Bool {
var args:Array<String> = Sys.args();
var i:Int = 0;
var regDashes = ~/^\-?\-/;
var regEquals = ~/=?/;
while (i < args.length) {
var arg:String = args[i];
var name:String;
var value:Dynamic = null;
// if (StringTools.startsWith(arg, '--')) {
// arg = regDashes.replace(arg, '');
if (StringTools.contains(arg, '=')) {
var splitArgs = arg.split('=');
name = splitArgs[0];
value = splitArgs[1];
} else {
name = arg;
if (args[i + 1] != null && this.mappedOptions.exists(name)) {
value = args[i + 1];
i++;
}
}
this.mappedArguments.set(name, value);
i++;
}
for (optName => option in this.mappedOptions) {
var value = this.mappedArguments.get(optName);
var existsValue:Bool = this.mappedArguments.exists(optName) && value != null;
switch (option.type) {
// case OptionType.Int:
// option.value = cast(value, Int); // All will be strings
case OptionType.Bool:
option.value = value != null;
default:
option.value = value;
}
if (option.required && !existsValue) {
this.line('');
this.line('Option "${option.description}" (${option.name}) is required.');
return false;
}
}
return true;
}
public function isValid():Bool {
return valid;
}
private function line(str:Dynamic):Void {
return Sys.println(str);
}
public function usage():Void {
var program:String = Path.withoutDirectory(Sys.programPath());
var arguments:Array<String> = [];
var mandatoryArguments:Array<String> = [];
var nonMandatoryArguments:Array<String> = [];
arguments = this.options.map(opt -> '-${opt.name}');
mandatoryArguments = this.options.filter(opt -> opt.required).map(opt -> '${opt.name} ${this.cleanStr(opt.name.toUpperCase())}');
nonMandatoryArguments = this.options.filter(opt -> !opt.required).map(opt -> '[${opt.name} ${this.cleanStr(opt.name.toUpperCase())}]');
this.line('');
this.line('Usage:');
this.line('$program ' + mandatoryArguments.join(' ') + ' ' + nonMandatoryArguments.join(' '));
this.line('');
this.line('Arguments:');
for (opt in this.options) {
this.line('${opt.name}\t\t${opt.description}');
}
}
private function cleanStr(str:String):String {
return ~/[^0-9a-zA-Z]/.replace(str, '');
}
public function get(key:String):Dynamic {
if (!this.mappedOptions.exists(key)) {
return null;
}
return this.mappedOptions.get(key).value;
}
public function exists(key:String):Bool {
return this.mappedOptions.exists(key);
}
public function all():Map<String, Option> {
return this.mappedOptions;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment