cliqr 0.1.0 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +55 -0
  3. data/README.md +46 -17
  4. data/lib/cliqr/argument_validation/argument_type_validator.rb +31 -0
  5. data/lib/cliqr/argument_validation/option_validator.rb +27 -0
  6. data/lib/cliqr/argument_validation/validator.rb +67 -0
  7. data/lib/cliqr/cli/command_context.rb +21 -12
  8. data/lib/cliqr/cli/config.rb +57 -9
  9. data/lib/cliqr/cli/executor.rb +17 -11
  10. data/lib/cliqr/cli/interface.rb +7 -3
  11. data/lib/cliqr/error.rb +17 -19
  12. data/lib/cliqr/parser/argument_parser.rb +21 -0
  13. data/lib/cliqr/parser/argument_tree_walker.rb +51 -0
  14. data/lib/cliqr/parser/boolean_option_token.rb +26 -0
  15. data/lib/cliqr/parser/parsed_input.rb +53 -0
  16. data/lib/cliqr/parser/parsed_input_builder.rb +61 -0
  17. data/lib/cliqr/parser/single_valued_option_token.rb +53 -0
  18. data/lib/cliqr/parser/token.rb +45 -0
  19. data/lib/cliqr/parser/token_factory.rb +69 -0
  20. data/lib/cliqr/validation/validation_set.rb +48 -0
  21. data/lib/cliqr/validation/validator_factory.rb +265 -0
  22. data/lib/cliqr/validation/verifiable.rb +89 -0
  23. data/lib/cliqr/validation_errors.rb +61 -0
  24. data/lib/cliqr/version.rb +1 -1
  25. data/spec/config/config_validator_spec.rb +51 -30
  26. data/spec/config/option_config_validator_spec.rb +143 -0
  27. data/spec/dsl/interface_spec.rb +48 -114
  28. data/spec/executor/executor_spec.rb +19 -1
  29. data/spec/fixtures/test_option_checker_command.rb +8 -0
  30. data/spec/parser/argument_parser_spec.rb +33 -39
  31. data/spec/validation/argument_validation_spec.rb +141 -0
  32. data/spec/validation/error_spec.rb +22 -0
  33. data/spec/validation/validation_spec.rb +11 -0
  34. metadata +27 -10
  35. data/lib/cliqr/cli/argument_validator.rb +0 -19
  36. data/lib/cliqr/cli/config_validator.rb +0 -104
  37. data/lib/cliqr/cli/parser/argument_parser.rb +0 -23
  38. data/lib/cliqr/cli/parser/argument_tree_walker.rb +0 -56
  39. data/lib/cliqr/cli/parser/option_token.rb +0 -72
  40. data/lib/cliqr/cli/parser/parsed_argument_builder.rb +0 -66
  41. data/lib/cliqr/cli/parser/token.rb +0 -38
  42. data/lib/cliqr/cli/parser/token_factory.rb +0 -58
@@ -8,6 +8,7 @@ require 'fixtures/test_command'
8
8
  require 'fixtures/always_error_command'
9
9
  require 'fixtures/option_reader_command'
10
10
  require 'fixtures/test_option_reader_command'
11
+ require 'fixtures/test_option_checker_command'
11
12
 
12
13
  describe Cliqr::CLI::Executor do
13
14
  it 'returns code 0 for default command runner' do
@@ -79,7 +80,24 @@ some-value
79
80
  cli.execute
80
81
  rescue Cliqr::Error::CliqrError => e
81
82
  expect(e.backtrace[0]).to end_with "cliqr/spec/fixtures/always_error_command.rb:6:in `execute'"
82
- expect(e.message).to eq "command 'my-command' failed\n\nCause: StandardError - I always throw an error"
83
+ expect(e.message).to eq "command 'my-command' failed\n\nCause: StandardError - I always throw an error\n"
83
84
  end
84
85
  end
86
+
87
+ it 'allows command to check if an option exists or not' do
88
+ cli = Cliqr.interface do
89
+ basename 'my-command'
90
+ description 'a command used to test cliqr'
91
+ handler TestOptionCheckerCommand
92
+
93
+ option 'test-option' do
94
+ type :boolean
95
+ end
96
+ end
97
+
98
+ result = cli.execute %w(--test-option), output: :buffer
99
+ expect(result[:stdout]).to eq <<-EOS
100
+ test-option is defined
101
+ EOS
102
+ end
85
103
  end
@@ -0,0 +1,8 @@
1
+ # encoding: utf-8
2
+
3
+ # A command that echoes the value for option named 'test-option'
4
+ class TestOptionCheckerCommand < Cliqr.command
5
+ def execute(context)
6
+ puts 'test-option is defined' if context.option?('test-option')
7
+ end
8
+ end
@@ -2,12 +2,13 @@
2
2
 
3
3
  require 'spec_helper'
4
4
 
5
- require 'cliqr/cli/parser/argument_parser'
5
+ require 'cliqr/parser/argument_parser'
6
+ require 'cliqr/parser/parsed_input'
6
7
 
7
8
  require 'fixtures/test_command'
8
9
  require 'fixtures/option_reader_command'
9
10
 
10
- describe Cliqr::CLI::Parser do
11
+ describe Cliqr::Parser do
11
12
  TEST_CLI = Cliqr.interface do
12
13
  basename 'my-command'
13
14
  handler TestCommand
@@ -17,40 +18,35 @@ describe Cliqr::CLI::Parser do
17
18
  end
18
19
  end
19
20
  CONFIG = TEST_CLI.config
20
- PARSER = Cliqr::CLI::Parser
21
+ PARSER = Cliqr::Parser
21
22
 
22
23
  it 'can parse no argument command' do
23
- expect(PARSER.parse(CONFIG, [])).to eq(:command => 'my-command',
24
- :options => [])
24
+ expect(PARSER.parse(CONFIG, [])).to eq(Cliqr::Parser::ParsedInput.new(:command => 'my-command', :options => []))
25
25
  end
26
26
 
27
27
  it 'can parse command with option using long name' do
28
- expected_arguments = {
29
- :command => 'my-command',
30
- :options => [
31
- {
32
- :name => 'test-option',
33
- :value => 'abcd'
34
- }
35
- ]
36
- }
37
- expect(PARSER.parse(CONFIG, %w(--test-option abcd))).to eq(expected_arguments)
28
+ parsed_input = Cliqr::Parser::ParsedInput.new(:command => 'my-command',
29
+ :options => [
30
+ {
31
+ :name => 'test-option',
32
+ :value => 'abcd'
33
+ }
34
+ ])
35
+ expect(PARSER.parse(CONFIG, %w(--test-option abcd))).to eq(parsed_input)
38
36
  end
39
37
 
40
38
  it 'can parse multiple options' do
41
- expected_arguments = {
42
- :command => 'my-command',
43
- :options => [
44
- {
45
- :name => 'test-option-1',
46
- :value => 'abcd'
47
- },
48
- {
49
- :name => 'test-option-2',
50
- :value => 'xyz'
51
- }
52
- ]
53
- }
39
+ parsed_input = Cliqr::Parser::ParsedInput.new(:command => 'my-command',
40
+ :options => [
41
+ {
42
+ :name => 'test-option-1',
43
+ :value => 'abcd'
44
+ },
45
+ {
46
+ :name => 'test-option-2',
47
+ :value => 'xyz'
48
+ }
49
+ ])
54
50
  cli = Cliqr.interface do
55
51
  basename 'my-command'
56
52
  handler TestCommand
@@ -58,20 +54,18 @@ describe Cliqr::CLI::Parser do
58
54
  option 'test-option-1'
59
55
  option 'test-option-2'
60
56
  end
61
- expect(Cliqr::CLI::Parser.parse(cli.config, %w(--test-option-1 abcd --test-option-2 xyz))).to eq(expected_arguments)
57
+ expect(Cliqr::Parser.parse(cli.config, %w(--test-option-1 abcd --test-option-2 xyz))).to eq(parsed_input)
62
58
  end
63
59
 
64
60
  it 'can parse command with option using short name' do
65
- expected_arguments = {
66
- :command => 'my-command',
67
- :options => [
68
- {
69
- :name => 'test-option',
70
- :value => 'abcd'
71
- }
72
- ]
73
- }
74
- expect(PARSER.parse(CONFIG, %w(-t abcd))).to eq(expected_arguments)
61
+ parsed_input = Cliqr::Parser::ParsedInput.new(:command => 'my-command',
62
+ :options => [
63
+ {
64
+ :name => 'test-option',
65
+ :value => 'abcd'
66
+ }
67
+ ])
68
+ expect(PARSER.parse(CONFIG, %w(-t abcd))).to eq(parsed_input)
75
69
  end
76
70
 
77
71
  it 'cannot parse unknown options' do
@@ -0,0 +1,141 @@
1
+ # encoding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ require 'cliqr/argument_validation/validator'
6
+
7
+ require 'fixtures/test_command'
8
+ require 'fixtures/test_option_reader_command'
9
+
10
+ describe Cliqr::ArgumentValidation::Validator do
11
+ it 'can validate numerical arguments' do
12
+ cli = Cliqr.interface do
13
+ basename 'my-command'
14
+ handler TestOptionReaderCommand
15
+
16
+ option 'test-option' do
17
+ type :numeric
18
+ end
19
+ end
20
+
21
+ result = cli.execute %w(--test-option 123), output: :buffer
22
+ expect(result[:stdout]).to eq <<-EOS
23
+ 123
24
+ EOS
25
+ end
26
+
27
+ it 'does not allow string for numeric option types' do
28
+ cli = Cliqr.interface do
29
+ basename 'my-command'
30
+ handler TestCommand
31
+
32
+ option 'age' do
33
+ type :numeric
34
+ end
35
+ end
36
+
37
+ expect do
38
+ cli.execute %w(--age abcd)
39
+ end.to raise_error(Cliqr::Error::IllegalArgumentError,
40
+ "illegal argument error - only values of type 'numeric' allowed for option 'age'")
41
+ end
42
+
43
+ it 'can validate boolean option arguments' do
44
+ cli = Cliqr.interface do
45
+ basename 'my-command'
46
+ handler TestOptionReaderCommand
47
+
48
+ option 'test-option' do
49
+ type :boolean
50
+ end
51
+ end
52
+
53
+ result = cli.execute %w(--test-option), output: :buffer
54
+ expect(result[:stdout]).to eq <<-EOS
55
+ true
56
+ EOS
57
+ end
58
+
59
+ it 'can validate boolean option argumentswith short name' do
60
+ cli = Cliqr.interface do
61
+ basename 'my-command'
62
+ handler TestOptionReaderCommand
63
+
64
+ option 'test-option' do
65
+ short 't'
66
+ type :boolean
67
+ end
68
+ end
69
+
70
+ result = cli.execute %w(-t), output: :buffer
71
+ expect(result[:stdout]).to eq <<-EOS
72
+ true
73
+ EOS
74
+ end
75
+
76
+ it 'can validate boolean option arguments for false' do
77
+ cli = Cliqr.interface do
78
+ basename 'my-command'
79
+ handler TestOptionReaderCommand
80
+
81
+ option 'test-option' do
82
+ type :boolean
83
+ end
84
+ end
85
+
86
+ result = cli.execute %w(--no-test-option), output: :buffer
87
+ expect(result[:stdout]).to eq <<-EOS
88
+ false
89
+ EOS
90
+ end
91
+
92
+ it 'does not allow string for boolean option types' do
93
+ cli = Cliqr.interface do
94
+ basename 'my-command'
95
+ handler TestCommand
96
+
97
+ option 'opt' do
98
+ type :boolean
99
+ end
100
+ end
101
+
102
+ expect do
103
+ cli.execute %w(--opt qwe)
104
+ end.to raise_error(Cliqr::Error::InvalidArgumentError,
105
+ "invalid command argument \"qwe\"")
106
+ end
107
+
108
+ it 'allows numeric options to be optional' do
109
+ cli = Cliqr.interface do
110
+ basename 'my-command'
111
+ description 'this is an awesome command...try it out'
112
+ handler TestCommand
113
+
114
+ option 'count' do
115
+ type :numeric
116
+ end
117
+ end
118
+
119
+ result = cli.execute [], output: :buffer
120
+ expect(result[:stdout]).to eq <<-EOS
121
+ test command executed
122
+ EOS
123
+ end
124
+
125
+ it 'allows boolean options to be optional' do
126
+ cli = Cliqr.interface do
127
+ basename 'my-command'
128
+ description 'this is an awesome command...try it out'
129
+ handler TestCommand
130
+
131
+ option 'single' do
132
+ type :boolean
133
+ end
134
+ end
135
+
136
+ result = cli.execute [], output: :buffer
137
+ expect(result[:stdout]).to eq <<-EOS
138
+ test command executed
139
+ EOS
140
+ end
141
+ end
@@ -0,0 +1,22 @@
1
+ # encoding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Cliqr::Error do
6
+ it 'makes use of to_s to print the error message' do
7
+ expected_error_message = <<-EOS
8
+ something went wrong
9
+
10
+ Cause: NoMethodError - undefined method `non_existent' for {}:Hash
11
+ EOS
12
+ begin
13
+ begin
14
+ {}.non_existent
15
+ rescue StandardError => e
16
+ raise Cliqr::Error::CommandRuntimeException.new('something went wrong', e)
17
+ end
18
+ rescue Cliqr::Error::CliqrError => e
19
+ expect(e.to_s).to eq(expected_error_message)
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,11 @@
1
+ # encoding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Cliqr::Validation do
6
+ it 'does not know how to validate unknown types' do
7
+ expect do
8
+ Cliqr::Validation::ValidatorFactory.get(:bla, {}).validate(nil, nil, nil)
9
+ end.to raise_error(Cliqr::Error::UnknownValidatorType, "unknown validation type: 'bla'")
10
+ end
11
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cliqr
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Anshul Verma
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-05-29 00:00:00.000000000 Z
11
+ date: 2015-06-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: log4r
@@ -55,35 +55,47 @@ files:
55
55
  - README.md
56
56
  - Rakefile
57
57
  - lib/cliqr.rb
58
- - lib/cliqr/cli/argument_validator.rb
58
+ - lib/cliqr/argument_validation/argument_type_validator.rb
59
+ - lib/cliqr/argument_validation/option_validator.rb
60
+ - lib/cliqr/argument_validation/validator.rb
59
61
  - lib/cliqr/cli/command.rb
60
62
  - lib/cliqr/cli/command_context.rb
61
63
  - lib/cliqr/cli/command_runner_factory.rb
62
64
  - lib/cliqr/cli/config.rb
63
- - lib/cliqr/cli/config_validator.rb
64
65
  - lib/cliqr/cli/executor.rb
65
66
  - lib/cliqr/cli/interface.rb
66
- - lib/cliqr/cli/parser/argument_parser.rb
67
- - lib/cliqr/cli/parser/argument_tree_walker.rb
68
- - lib/cliqr/cli/parser/option_token.rb
69
- - lib/cliqr/cli/parser/parsed_argument_builder.rb
70
- - lib/cliqr/cli/parser/token.rb
71
- - lib/cliqr/cli/parser/token_factory.rb
72
67
  - lib/cliqr/cli/router.rb
73
68
  - lib/cliqr/dsl.rb
74
69
  - lib/cliqr/error.rb
70
+ - lib/cliqr/parser/argument_parser.rb
71
+ - lib/cliqr/parser/argument_tree_walker.rb
72
+ - lib/cliqr/parser/boolean_option_token.rb
73
+ - lib/cliqr/parser/parsed_input.rb
74
+ - lib/cliqr/parser/parsed_input_builder.rb
75
+ - lib/cliqr/parser/single_valued_option_token.rb
76
+ - lib/cliqr/parser/token.rb
77
+ - lib/cliqr/parser/token_factory.rb
78
+ - lib/cliqr/validation/validation_set.rb
79
+ - lib/cliqr/validation/validator_factory.rb
80
+ - lib/cliqr/validation/verifiable.rb
81
+ - lib/cliqr/validation_errors.rb
75
82
  - lib/cliqr/version.rb
76
83
  - spec/config/config_finalize_spec.rb
77
84
  - spec/config/config_validator_spec.rb
85
+ - spec/config/option_config_validator_spec.rb
78
86
  - spec/dsl/interface_spec.rb
79
87
  - spec/executor/command_runner_spec.rb
80
88
  - spec/executor/executor_spec.rb
81
89
  - spec/fixtures/always_error_command.rb
82
90
  - spec/fixtures/option_reader_command.rb
83
91
  - spec/fixtures/test_command.rb
92
+ - spec/fixtures/test_option_checker_command.rb
84
93
  - spec/fixtures/test_option_reader_command.rb
85
94
  - spec/parser/argument_parser_spec.rb
86
95
  - spec/spec_helper.rb
96
+ - spec/validation/argument_validation_spec.rb
97
+ - spec/validation/error_spec.rb
98
+ - spec/validation/validation_spec.rb
87
99
  homepage: https://github.com/anshulverma/cliqr
88
100
  licenses:
89
101
  - MIT
@@ -111,13 +123,18 @@ summary: A framework and DSL for defining CLI interface
111
123
  test_files:
112
124
  - spec/config/config_finalize_spec.rb
113
125
  - spec/config/config_validator_spec.rb
126
+ - spec/config/option_config_validator_spec.rb
114
127
  - spec/dsl/interface_spec.rb
115
128
  - spec/executor/command_runner_spec.rb
116
129
  - spec/executor/executor_spec.rb
117
130
  - spec/fixtures/always_error_command.rb
118
131
  - spec/fixtures/option_reader_command.rb
119
132
  - spec/fixtures/test_command.rb
133
+ - spec/fixtures/test_option_checker_command.rb
120
134
  - spec/fixtures/test_option_reader_command.rb
121
135
  - spec/parser/argument_parser_spec.rb
122
136
  - spec/spec_helper.rb
137
+ - spec/validation/argument_validation_spec.rb
138
+ - spec/validation/error_spec.rb
139
+ - spec/validation/validation_spec.rb
123
140
  has_rdoc:
@@ -1,19 +0,0 @@
1
- # encoding: utf-8
2
-
3
- module Cliqr
4
- module CLI
5
- # Utiity class to validate input to a command
6
- #
7
- # @api private
8
- class ArgumentValidator
9
- # Validate parsed command line arguments
10
- #
11
- # @param [Hash] args Parsed argument hash
12
- #
13
- # @return [Hash] Validated argument hash
14
- def validate(args)
15
- args
16
- end
17
- end
18
- end
19
- end
@@ -1,104 +0,0 @@
1
- # encoding: utf-8
2
-
3
- require 'cliqr/error'
4
-
5
- module Cliqr
6
- module CLI
7
- # Validator for the command line interface configuration
8
- #
9
- # @api private
10
- class ConfigValidator
11
- # Validates the config to make sure all the options are correctly set
12
- #
13
- # @param [Cliqr::CLI::Config] config Settings for building command line interface
14
- #
15
- # @return [Cliqr::CLI::Config] Validated config object
16
- def self.validate(config)
17
- fail Cliqr::Error::ConfigNotFound, 'a valid config should be defined' if config.nil?
18
- fail Cliqr::Error::BasenameNotDefined, 'basename not defined' if config.basename.empty?
19
-
20
- fail Cliqr::Error::HandlerNotDefined,
21
- "handler not defined for command \"#{config.basename}\"" if config.handler.nil?
22
-
23
- fail Cliqr::Error::InvalidCommandHandler,
24
- "handler for command \"#{config.basename}\" should extend from [Cliqr::CLI::Command]" \
25
- unless config.handler < Command
26
-
27
- check_options(config)
28
-
29
- config
30
- end
31
-
32
- # Check if config's options list is not nil
33
- #
34
- # @param [Cliqr::CLI::Config] config Configuration settings for the command line interface
35
- #
36
- # @return [Cliqr::CLI::Config] Validated config
37
- def self.check_options(config)
38
- fail Cliqr::Error::OptionsNotDefinedException,
39
- "option array is nil for command \"#{config.basename}\"" if config.options.nil?
40
-
41
- config
42
- end
43
- end
44
-
45
- # Validator for validating option configuration in a CLI interface config
46
- #
47
- # @api private
48
- class OptionConfigValidator
49
- # Validate a command line interface's config for an option
50
- #
51
- # @param [Cliqr::CLI::OptionConfig] config Config for this particular option
52
- # @param [Cliqr::CLI::Config] parent_config Config of the parent config instance
53
- #
54
- # @return [Cliqr::CLI::OptionConfig] Validated OptionConfig instance
55
- def self.validate(config, parent_config)
56
- validate_option_name(config, parent_config)
57
-
58
- fail Cliqr::Error::InvalidOptionDefinition,
59
- "option \"#{config.name}\" has empty short name" \
60
- if !config.short.nil? && config.short.empty?
61
-
62
- validate_short_option(config, parent_config) if config.short?
63
-
64
- config
65
- end
66
-
67
- # Validates name for an option
68
- #
69
- # @param [Cliqr::CLI::OptionConfig] config Config for this particular option
70
- # @param [Cliqr::CLI::Config] parent_config Config of the parent config instance
71
- #
72
- # @return [Cliqr::CLI::OptionConfig] Validated OptionConfig instance
73
- def self.validate_option_name(config, parent_config)
74
- fail Cliqr::Error::DuplicateOptions,
75
- "multiple options with long name \"#{config.name}\"" \
76
- if parent_config.option?(config.name)
77
-
78
- fail Cliqr::Error::InvalidOptionDefinition,
79
- "option number #{parent_config.options.length + 1} does not have a name field" \
80
- unless config.name?
81
-
82
- config
83
- end
84
-
85
- # Validates short name for an option
86
- #
87
- # @param [Cliqr::CLI::OptionConfig] config Config for this particular option
88
- # @param [Cliqr::CLI::Config] parent_config Config of the parent config instance
89
- #
90
- # @return [Cliqr::CLI::OptionConfig] Validated OptionConfig instance
91
- def self.validate_short_option(config, parent_config)
92
- fail Cliqr::Error::DuplicateOptions,
93
- "multiple options with short name \"#{config.short}\"" \
94
- if parent_config.option?(config.short)
95
-
96
- fail Cliqr::Error::InvalidOptionDefinition,
97
- "short option name can not have more than one characters in \"#{config.name}\"" \
98
- if /^[a-z0-9A-Z]$/.match(config.short).nil?
99
-
100
- config
101
- end
102
- end
103
- end
104
- end