Compare commits
No commits in common. "main" and "v0.1.1" have entirely different histories.
|
@ -21,4 +21,4 @@ jobs:
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: shards install
|
run: shards install
|
||||||
- name: Run tests
|
- name: Run tests
|
||||||
run: crystal spec --error-trace
|
run: crystal spec
|
||||||
|
|
|
@ -67,7 +67,7 @@ which implements `from_arg` as a proxy for that type.
|
||||||
|
|
||||||
## Converters
|
## Converters
|
||||||
|
|
||||||
Converters are simply modules which have a `self.from_arg` method which takes
|
Converers are simply modules which have a `self.from_arg` method which takes
|
||||||
a value string, and returns the converted value. For Example:
|
a value string, and returns the converted value. For Example:
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
|
@ -44,16 +44,3 @@ struct TestConverters
|
||||||
@[ArgParser::Field(converter: ArgParser::EnumValueConverter(Color))]
|
@[ArgParser::Field(converter: ArgParser::EnumValueConverter(Color))]
|
||||||
getter ncolor : Color
|
getter ncolor : Color
|
||||||
end
|
end
|
||||||
|
|
||||||
struct TestValidators
|
|
||||||
include ArgParser
|
|
||||||
|
|
||||||
@[ArgParser::Validate::Format(/^[a-zA-Z]+$/)]
|
|
||||||
getter first_name : String
|
|
||||||
|
|
||||||
@[ArgParser::Validate::Format(/^[a-zA-Z]+$/)]
|
|
||||||
getter last_name : String?
|
|
||||||
|
|
||||||
@[ArgParser::Validate::InRange(1, 100)]
|
|
||||||
getter age : Int32
|
|
||||||
end
|
|
||||||
|
|
|
@ -1,7 +0,0 @@
|
||||||
require "../spec_helper"
|
|
||||||
|
|
||||||
Spectator.describe "ArgParser from_arg" do
|
|
||||||
it "should parse a union" do
|
|
||||||
expect(Union(String, Nil).from_arg("foo")).to eq("foo")
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,28 +0,0 @@
|
||||||
require "../spec_helper"
|
|
||||||
|
|
||||||
Spectator.describe "ArgParser validators" do
|
|
||||||
let(valid_args) { ["positional stuff", "--first_name", "John", "--age", "32"] }
|
|
||||||
let(invalid_args) { ["positional stuff", "--first_name", "John^", "--last_name", "Doe1", "--age", "101"] }
|
|
||||||
|
|
||||||
context "valid arguments" do
|
|
||||||
it "should not raise an error" do
|
|
||||||
expect { TestValidators.new(valid_args) }.not_to raise_error
|
|
||||||
end
|
|
||||||
|
|
||||||
it "should set the name" do
|
|
||||||
opts = TestValidators.new(valid_args)
|
|
||||||
expect(opts.first_name).to eq("John")
|
|
||||||
end
|
|
||||||
|
|
||||||
it "should set the age" do
|
|
||||||
opts = TestValidators.new(valid_args)
|
|
||||||
expect(opts.age).to eq(32)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
context "invalid arguments" do
|
|
||||||
it "should raise an error" do
|
|
||||||
expect { TestValidators.new(invalid_args) }.to raise_error(ArgParser::ValidationError)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -65,34 +65,34 @@ module ArgParser
|
||||||
i = 0
|
i = 0
|
||||||
while !%args.empty?
|
while !%args.empty?
|
||||||
arg = %args.shift
|
arg = %args.shift
|
||||||
next unless key = parse_key(arg)
|
key = parse_key(arg)
|
||||||
|
next unless key
|
||||||
|
|
||||||
# TODO: Find a different way to handle this
|
|
||||||
value = %args.shift rescue "true"
|
value = %args.shift rescue "true"
|
||||||
if value && parse_key(value)
|
if value.starts_with?("-")
|
||||||
%args.unshift(value)
|
%args.unshift(value)
|
||||||
value = "true"
|
value = "true"
|
||||||
end
|
end
|
||||||
|
|
||||||
next unless value
|
|
||||||
|
|
||||||
case key
|
case key
|
||||||
{% for name, value in properties %}
|
{% for name, value in properties %}
|
||||||
when {{ value[:key].id.stringify }}{% if value[:alias] %}, {{ value[:alias].id.stringify }}{% end %}
|
when {{ value[:key].id.stringify }}{% if value[:alias] %}, {{ value[:alias].id.stringify }}{% end %}
|
||||||
%found{name} = true
|
%found{name} = true
|
||||||
begin
|
begin
|
||||||
{% if value[:type] < Array %}
|
{% if value[:type] == String %}
|
||||||
|
%var{name} = value
|
||||||
|
{% elsif value[:type] < Array %}
|
||||||
%var{name} ||= [] of {{value[:type].type_vars[0]}}
|
%var{name} ||= [] of {{value[:type].type_vars[0]}}
|
||||||
{% if value[:converter] %}
|
{% if value[:converter] %}
|
||||||
%var{name}.concat {{ value[:converter] }}.from_arg(value)
|
%var{name}.concat {{ value[:converter] }}.from_arg(value)
|
||||||
{% else %}
|
{% else %}
|
||||||
%var{name} << {{value[:type].type_vars[0]}}.from_arg(value)
|
%var{name} << ::Union({{value[:type].type_vars[0]}}).from_arg(value)
|
||||||
{% end %}
|
{% end %}
|
||||||
{% else %}
|
{% else %}
|
||||||
{% if value[:converter] %}
|
{% if value[:converter] %}
|
||||||
%var{name} = {{ value[:converter] }}.from_arg(value)
|
%var{name} = {{ value[:converter] }}.from_arg(value)
|
||||||
{% else %}
|
{% else %}
|
||||||
%var{name} = {{value[:type]}}.from_arg(value)
|
%var{name} = ::Union({{value[:type]}}).from_arg(value)
|
||||||
{% end %}
|
{% end %}
|
||||||
{% end %}
|
{% end %}
|
||||||
rescue
|
rescue
|
||||||
|
@ -106,7 +106,7 @@ module ArgParser
|
||||||
|
|
||||||
{% for name, value in properties %}
|
{% for name, value in properties %}
|
||||||
{% unless value[:nilable] || value[:has_default] %}
|
{% unless value[:nilable] || value[:has_default] %}
|
||||||
if %var{name}.nil? && !%found{name} && !{{value[:type]}}.nilable?
|
if %var{name}.nil? && !%found{name} && !::Union({{value[:type]}}).nilable?
|
||||||
on_missing_attribute({{value[:key].id.stringify}})
|
on_missing_attribute({{value[:key].id.stringify}})
|
||||||
end
|
end
|
||||||
{% end %}
|
{% end %}
|
||||||
|
@ -145,8 +145,8 @@ module ArgParser
|
||||||
{% end %}
|
{% end %}
|
||||||
|
|
||||||
%validator{name} = {{ validator.name(generic_args: false) }}.new({{ args.join(", ").id }})
|
%validator{name} = {{ validator.name(generic_args: false) }}.new({{ args.join(", ").id }})
|
||||||
if %found{name} && !%var{name}.nil? && !%validator{name}.validate({{name.id.stringify}}, %var{name})
|
if %found{name} && !%validator{name}.validate({{name.id.stringify}}, @{{name}})
|
||||||
on_validation_error({{name.stringify}}, %var{name}, %validator{name}.errors)
|
on_validation_error({{name.stringify}}, @{{name}}, %validator{name}.errors)
|
||||||
end
|
end
|
||||||
{% end %}
|
{% end %}
|
||||||
{% end %}
|
{% end %}
|
||||||
|
@ -154,10 +154,8 @@ module ArgParser
|
||||||
end
|
end
|
||||||
|
|
||||||
# Parse the argument key.
|
# Parse the argument key.
|
||||||
# Standard arg names start with a `--.
|
# Standard arg names start with a `--`
|
||||||
# Aliases start with a single `-`.
|
# Aliases start with a single `-`
|
||||||
#
|
|
||||||
# Arguments without a value become boolean true values.
|
|
||||||
#
|
#
|
||||||
# Note: You can override this method to change the way keys are parsed.
|
# Note: You can override this method to change the way keys are parsed.
|
||||||
def parse_key(arg : String) : String?
|
def parse_key(arg : String) : String?
|
||||||
|
|
|
@ -133,19 +133,14 @@ end
|
||||||
def Union.from_arg(arg : String)
|
def Union.from_arg(arg : String)
|
||||||
{% begin %}
|
{% begin %}
|
||||||
{% for type in T %}
|
{% for type in T %}
|
||||||
{% if type != Nil %}
|
begin
|
||||||
begin
|
%val = {{type}}.from_arg(arg)
|
||||||
%val = {{type}}.from_arg(arg)
|
return %val if %val.is_a?({{type}})
|
||||||
return %val if %val.is_a?({{type}})
|
rescue
|
||||||
rescue
|
end
|
||||||
end
|
|
||||||
{% end %}
|
|
||||||
{% end %}
|
{% end %}
|
||||||
|
|
||||||
{% if T.includes?(Nil) %}
|
raise ArgParser::Error.new("Argument '#{arg}' cannot be converted to any of the union types: {{T}}")
|
||||||
nil
|
|
||||||
{% else %}
|
|
||||||
raise ArgParser::Error.new("Argument '#{arg}' cannot be converted to any of the union types: {{T}}")
|
|
||||||
{% end %}
|
|
||||||
{% end %}
|
{% end %}
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue