samovar 1.5.0 → 1.6.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 245b83811d09cc997ce160fa8c6a5481e3efe0cc
4
- data.tar.gz: b7e021a4cad13a340d6b77dbd2cbe4c066383c5d
3
+ metadata.gz: 06e76d86b275ed684abaabcadd799765248b67d8
4
+ data.tar.gz: 5dbb428a9e5523779b394d3c14cb8661ca14271c
5
5
  SHA512:
6
- metadata.gz: 9a7e9e3e968d94c1d88eb308f1bf1e46c3c29ee2e7c1847d3a42b2b5f55f686e7e45a10ba43b75a98ccff09288a99e733bccd030bf58f05a721e8c43084014f1
7
- data.tar.gz: b8d72d941e4f5f2659c7e4ea9235a66667ed637945d43ee0772eb3774b929afdfff013719ba677a00ff8f4da92cb07d39c822dae2e50e1c1775a2ec1a5a9ec58
6
+ metadata.gz: e412c9871a224a1ad5049fd9d13a94dc1cf6f3f1a6b5c4bb2a92f085ce3a7b629f9a2ab142fe428b1e6a766c2252ef93eaf059b3d92e9bd48582fa9aca6c5abd
7
+ data.tar.gz: ba4f76b3c6b9457647cf8132e02d94df20add0d19e6c7c610ca2277291544db21e767735b4a9850a4756fd765e341c8ecefa3ecc4d0016b063e008a8d1a9f3d9
data/.gitignore CHANGED
@@ -7,3 +7,5 @@
7
7
  /pkg/
8
8
  /spec/reports/
9
9
  /tmp/
10
+ .rspec_status
11
+ .tags
data/.rspec CHANGED
@@ -1,3 +1,4 @@
1
1
  --format documentation
2
- --color
2
+ --backtrace
3
3
  --warnings
4
+ --require spec_helper
data/README.md CHANGED
@@ -116,6 +116,18 @@ Or install it yourself as:
116
116
  application.fruit # 'apple'
117
117
  application.cakes # ['chocolate cake', 'fruit cake']
118
118
 
119
+ ### Explicit Commands
120
+
121
+ Given a custom `Samovar::Command` subclass, you can instantiate it with options:
122
+
123
+ application = Application['--root', path]
124
+
125
+ You can also duplicate an existing command instance with additions/changes:
126
+
127
+ concurrent_application = application['--threads', 12]
128
+
129
+ These forms can be useful when invoking one command from another, or in unit tests.
130
+
119
131
  ## Contributing
120
132
 
121
133
  1. Fork it
data/Rakefile CHANGED
@@ -1,12 +1,9 @@
1
1
  require "bundler/gem_tasks"
2
2
  require "rspec/core/rake_task"
3
3
 
4
- RSpec::Core::RakeTask.new(:spec) do |task|
5
- begin
6
- require('simplecov/version')
7
- task.rspec_opts = %w{--require simplecov} if ENV['COVERAGE']
8
- rescue LoadError
9
- end
10
- end
4
+ # Load all rake tasks:
5
+ import(*Dir.glob('tasks/**/*.rake'))
11
6
 
12
- task :default => :spec
7
+ RSpec::Core::RakeTask.new(:test)
8
+
9
+ task :default => :test
@@ -52,9 +52,7 @@ module Samovar
52
52
  end
53
53
 
54
54
  def parse(input)
55
- self.class.table.parse(input) do |key, value|
56
- self.send("#{key}=", value)
57
- end
55
+ self.class.table.parse(input, self)
58
56
  end
59
57
 
60
58
  def initialize(input = nil)
@@ -36,12 +36,12 @@ module Samovar
36
36
  [to_s, @description]
37
37
  end
38
38
 
39
- def parse(input)
39
+ def parse(input, default)
40
40
  if @stop and stop_index = input.index{|item| @stop === item}
41
41
  input.shift(stop_index)
42
42
  else
43
43
  input.shift(input.size)
44
- end
44
+ end || default
45
45
  end
46
46
  end
47
47
  end
@@ -20,10 +20,13 @@
20
20
 
21
21
  module Samovar
22
22
  class Nested
23
- def initialize(name, commands, key: :command)
23
+ def initialize(name, commands, key: :command, default: nil)
24
24
  @name = name
25
25
  @commands = commands
26
26
  @key = key
27
+
28
+ # This is the default name [of a command], not the default command:
29
+ @default = default
27
30
  end
28
31
 
29
32
  attr :key
@@ -33,15 +36,31 @@ module Samovar
33
36
  end
34
37
 
35
38
  def to_a
36
- [@name, "One of #{@commands.keys.join(', ')}."]
39
+ usage = [@name]
40
+
41
+ if @commands.size == 0
42
+ usage << "No commands available."
43
+ elsif @commands.size == 1
44
+ usage << "Only #{@commands.first}."
45
+ else
46
+ usage << "One of: #{@commands.keys.join(', ')}."
47
+ end
48
+
49
+ if @default
50
+ usage << "Default: #{@default}"
51
+ end
52
+
53
+ return usage
37
54
  end
38
55
 
39
- def parse(input)
56
+ def parse(input, default)
40
57
  if command = @commands[input.first]
41
58
  input.shift
42
59
 
43
60
  # puts "Instantiating #{command} with #{input}"
44
61
  command.new(input)
62
+ elsif @default
63
+ default || @commands[@default].new(input)
45
64
  end
46
65
  end
47
66
 
@@ -36,10 +36,10 @@ module Samovar
36
36
  [to_s, @description]
37
37
  end
38
38
 
39
- def parse(input)
39
+ def parse(input, default)
40
40
  if input.first =~ @pattern
41
41
  input.shift
42
- end
42
+ end || default
43
43
  end
44
44
  end
45
45
  end
@@ -74,12 +74,10 @@ module Samovar
74
74
  return result
75
75
  end
76
76
 
77
- def parse(input)
77
+ def parse(input, default = @default)
78
78
  if result = @flags.parse(input)
79
79
  @value.nil? ? coerce(result) : @value
80
- else
81
- @default
82
- end
80
+ end || default
83
81
  end
84
82
 
85
83
  def to_s
@@ -138,8 +136,8 @@ module Samovar
138
136
  end
139
137
  end
140
138
 
141
- def parse(input)
142
- values = @defaults.dup
139
+ def parse(input, default)
140
+ values = (default || @defaults).dup
143
141
 
144
142
  while option = @keyed[input.first]
145
143
  if result = option.parse(input)
@@ -36,10 +36,10 @@ module Samovar
36
36
  [to_s, @description]
37
37
  end
38
38
 
39
- def parse(input)
39
+ def parse(input, default = nil)
40
40
  if offset = input.index(@marker)
41
41
  input.pop(input.size - offset).tap(&:shift)
42
- end
42
+ end || default
43
43
  end
44
44
  end
45
45
  end
@@ -36,19 +36,15 @@ module Samovar
36
36
  end
37
37
 
38
38
  def usage
39
- items = Array.new
40
-
41
- @rows.each do |row|
42
- items << row.to_s
43
- end
44
-
45
- items.join(' ')
39
+ @rows.collect(&:to_s).join(' ')
46
40
  end
47
41
 
48
- def parse(input)
42
+ def parse(input, command)
49
43
  @parser.each do |row|
50
- if result = row.parse(input)
51
- yield row.key, result, row
44
+ current = command.send(row.key)
45
+
46
+ if result = row.parse(input, current)
47
+ command.send("#{row.key}=", result)
52
48
  end
53
49
  end
54
50
  end
@@ -19,5 +19,5 @@
19
19
  # THE SOFTWARE.
20
20
 
21
21
  module Samovar
22
- VERSION = "1.5.0"
22
+ VERSION = "1.6.0"
23
23
  end
@@ -23,5 +23,5 @@ Gem::Specification.new do |spec|
23
23
 
24
24
  spec.add_development_dependency "bundler", "~> 1.11"
25
25
  spec.add_development_dependency "rake", "~> 10.0"
26
- spec.add_development_dependency "rspec", "~> 3.0"
26
+ spec.add_development_dependency "rspec", "~> 3.6"
27
27
  end
@@ -0,0 +1,27 @@
1
+
2
+ require 'samovar'
3
+ require 'stringio'
4
+
5
+ module Samovar::CoerceSpec
6
+ class Coerce < Samovar::Command
7
+ options do
8
+ option '--things <array>', "A list of things" do |input|
9
+ input.split(/\s*,\s*/)
10
+ end
11
+
12
+ option '--count <integer>', "A number to count", type: Integer
13
+ end
14
+ end
15
+
16
+ RSpec.describe Samovar::Command do
17
+ it "should coerce to array" do
18
+ top = Coerce['--things', 'a,b,c']
19
+ expect(top.options[:things]).to be == ['a', 'b', 'c']
20
+ end
21
+
22
+ it "should coerce to integer" do
23
+ top = Coerce['--count', '10']
24
+ expect(top.options[:count]).to be == 10
25
+ end
26
+ end
27
+ end
@@ -2,7 +2,7 @@
2
2
  require 'samovar'
3
3
  require 'stringio'
4
4
 
5
- module Command
5
+ module Samovar::CommandSpec
6
6
  class Bottom < Samovar::Command
7
7
  self.description = "Create a new teapot package using the specified repository."
8
8
 
@@ -25,37 +25,46 @@ module Command
25
25
  nested '<command>',
26
26
  'bottom' => Bottom
27
27
  end
28
- end
29
28
 
30
- describe Samovar::Command do
31
- it "should use default value" do
32
- top = Command::Top.parse([])
33
- expect(top.options[:configuration]).to be == 'TEAPOT_CONFIGURATION'
34
- end
35
-
36
- it "should parse a simple command" do
37
- top = Command::Top.parse(["-c", "path", "bottom", "foobar", "A", "B", "--", "args", "args"])
29
+ RSpec.describe Samovar::Command do
30
+ it "should use default value" do
31
+ top = Top[]
32
+ expect(top.options[:configuration]).to be == 'TEAPOT_CONFIGURATION'
33
+ end
38
34
 
39
- expect(top.options[:configuration]).to be == 'path'
40
- expect(top.command.class).to be == Command::Bottom
41
- expect(top.command.project_name).to be == 'foobar'
42
- expect(top.command.packages).to be == ['A', 'B']
43
- expect(top.command.argv).to be == ["args", "args"]
44
- end
45
-
46
- it "should generate documentation" do
47
- top = Command::Top.new([])
48
- buffer = StringIO.new
49
- top.print_usage('top', output: buffer)
35
+ it "can update options" do
36
+ top = Top[]
37
+ expect(top.options[:configuration]).to be == 'TEAPOT_CONFIGURATION'
38
+
39
+ top = top['--verbose']
40
+ expect(top.options[:configuration]).to be == 'TEAPOT_CONFIGURATION'
41
+ expect(top.options[:logging]).to be == :verbose
42
+ end
50
43
 
51
- expect(buffer.string).to be_include(Command::Top.description)
52
- end
53
-
54
- it "can run commands" do
55
- expect(subject.system("ls")).to be_truthy
56
- expect(subject.system!("ls")).to be_truthy
44
+ it "should parse a simple command" do
45
+ top = Top["-c", "path", "bottom", "foobar", "A", "B", "--", "args", "args"]
46
+
47
+ expect(top.options[:configuration]).to be == 'path'
48
+ expect(top.command.class).to be == Bottom
49
+ expect(top.command.project_name).to be == 'foobar'
50
+ expect(top.command.packages).to be == ['A', 'B']
51
+ expect(top.command.argv).to be == ["args", "args"]
52
+ end
57
53
 
58
- expect(subject.system("fail")).to be_falsey
59
- expect{subject.system!("fail")}.to raise_error(Samovar::SystemError)
54
+ it "should generate documentation" do
55
+ top = Top[]
56
+ buffer = StringIO.new
57
+ top.print_usage('top', output: buffer)
58
+
59
+ expect(buffer.string).to be_include(Top.description)
60
+ end
61
+
62
+ it "can run commands" do
63
+ expect(subject.system("ls")).to be_truthy
64
+ expect(subject.system!("ls")).to be_truthy
65
+
66
+ expect(subject.system("fail")).to be_falsey
67
+ expect{subject.system!("fail")}.to raise_error(Samovar::SystemError)
68
+ end
60
69
  end
61
70
  end
@@ -0,0 +1,30 @@
1
+
2
+ require 'samovar'
3
+ require 'stringio'
4
+
5
+ module Samovar::NestedSpec
6
+ class InnerA < Samovar::Command
7
+ end
8
+
9
+ class InnerB < Samovar::Command
10
+ end
11
+
12
+ class Outer < Samovar::Command
13
+ nested '<command>',
14
+ 'inner-a' => InnerA,
15
+ 'inner-b' => InnerB,
16
+ default: 'inner-b'
17
+ end
18
+
19
+ RSpec.describe Samovar::Nested do
20
+ it "should select default nested command" do
21
+ outer = Outer[]
22
+ expect(outer.command).to be_kind_of(InnerB)
23
+ end
24
+
25
+ it "should select explicitly named nested command" do
26
+ outer = Outer['inner-a']
27
+ expect(outer.command).to be_kind_of(InnerA)
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,24 @@
1
+
2
+ RSpec.describe Samovar::Options do
3
+ subject(:options) do
4
+ described_class.parse do
5
+ option '-x <value>', "The x factor", default: 2
6
+ option '-y <value>', "The y factor"
7
+ end
8
+ end
9
+
10
+ it "should set defaults" do
11
+ values = options.parse([], nil)
12
+ expect(values).to be == {x: 2}
13
+ end
14
+
15
+ it "should preserve current values" do
16
+ values = options.parse([], {x: 1, y: 2, z: 3})
17
+ expect(values).to be == {x: 1, y: 2, z: 3}
18
+ end
19
+
20
+ it "should update specified values" do
21
+ values = options.parse(['-x', 10], {x: 1, y: 2, z: 3})
22
+ expect(values).to be == {x: 10, y: 2, z: 3}
23
+ end
24
+ end
@@ -0,0 +1,29 @@
1
+
2
+ if ENV['COVERAGE'] || ENV['TRAVIS']
3
+ begin
4
+ require 'simplecov'
5
+
6
+ SimpleCov.start do
7
+ add_filter "/spec/"
8
+ end
9
+
10
+ if ENV['TRAVIS']
11
+ require 'coveralls'
12
+ Coveralls.wear!
13
+ end
14
+ rescue LoadError
15
+ warn "Could not load simplecov: #{$!}"
16
+ end
17
+ end
18
+
19
+ require "bundler/setup"
20
+ require "samovar"
21
+
22
+ RSpec.configure do |config|
23
+ # Enable flags like --only-failures and --next-failure
24
+ config.example_status_persistence_file_path = ".rspec_status"
25
+
26
+ config.expect_with :rspec do |c|
27
+ c.syntax = :expect
28
+ end
29
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: samovar
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.5.0
4
+ version: 1.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Samuel Williams
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-07-05 00:00:00.000000000 Z
11
+ date: 2017-07-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: mapping
@@ -72,14 +72,14 @@ dependencies:
72
72
  requirements:
73
73
  - - "~>"
74
74
  - !ruby/object:Gem::Version
75
- version: '3.0'
75
+ version: '3.6'
76
76
  type: :development
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
80
  - - "~>"
81
81
  - !ruby/object:Gem::Version
82
- version: '3.0'
82
+ version: '3.6'
83
83
  description:
84
84
  email:
85
85
  - samuel.williams@oriontransfer.co.nz
@@ -89,7 +89,6 @@ extra_rdoc_files: []
89
89
  files:
90
90
  - ".gitignore"
91
91
  - ".rspec"
92
- - ".simplecov"
93
92
  - ".travis.yml"
94
93
  - Gemfile
95
94
  - README.md
@@ -109,8 +108,11 @@ files:
109
108
  - lib/samovar/table.rb
110
109
  - lib/samovar/version.rb
111
110
  - samovar.gemspec
111
+ - spec/samovar/coerce_spec.rb
112
112
  - spec/samovar/command_spec.rb
113
- - spec/samovar/type_spec.rb
113
+ - spec/samovar/nested_spec.rb
114
+ - spec/samovar/options_spec.rb
115
+ - spec/spec_helper.rb
114
116
  - teapot.png
115
117
  homepage: https://github.com/ioquatix/samovar
116
118
  licenses:
@@ -138,5 +140,8 @@ specification_version: 4
138
140
  summary: Samovar is a flexible option parser excellent support for sub-commands and
139
141
  help documentation.
140
142
  test_files:
143
+ - spec/samovar/coerce_spec.rb
141
144
  - spec/samovar/command_spec.rb
142
- - spec/samovar/type_spec.rb
145
+ - spec/samovar/nested_spec.rb
146
+ - spec/samovar/options_spec.rb
147
+ - spec/spec_helper.rb
data/.simplecov DELETED
@@ -1,9 +0,0 @@
1
-
2
- SimpleCov.start do
3
- add_filter "/spec/"
4
- end
5
-
6
- if ENV['TRAVIS']
7
- require 'coveralls'
8
- Coveralls.wear!
9
- end
@@ -1,27 +0,0 @@
1
-
2
- require 'samovar'
3
- require 'stringio'
4
-
5
- module Command
6
- class Coerce < Samovar::Command
7
- options do
8
- option '--things <array>', "A list of things" do |input|
9
- input.split(/\s*,\s*/)
10
- end
11
-
12
- option '--count <integer>', "A number to count", type: Integer
13
- end
14
- end
15
- end
16
-
17
- describe Samovar::Command do
18
- it "should coerce to array" do
19
- top = Command::Coerce.parse(['--things', 'a,b,c'])
20
- expect(top.options[:things]).to be == ['a', 'b', 'c']
21
- end
22
-
23
- it "should coerce to integer" do
24
- top = Command::Coerce.parse(['--count', '10'])
25
- expect(top.options[:count]).to be == 10
26
- end
27
- end