cl 0.0.4 → 0.1.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
- SHA1:
3
- metadata.gz: 9857c406109f06a92986bef6a3290f5b6647c17f
4
- data.tar.gz: a861829fbef67c227006437d42a3848380c2b084
2
+ SHA256:
3
+ metadata.gz: bb6a93f33e5cae5c1ec0b0bba6b1d3981b853ee6e5a4fde75d3b5c4df7176162
4
+ data.tar.gz: 0a247824d773fd1251b19e353e629780cb36b6b4f1ef3553e8ab2752ffdf9ad4
5
5
  SHA512:
6
- metadata.gz: e5e446a970a5e7f180df5ee0875e25443c17f0a6599c6103440782a02cc0bb8a8380582deb2fbdaed87eee2edbf9a98a339a455f09101f6bd963a7f02a39b78e
7
- data.tar.gz: d98b7935d11f18eefb33ae70c93cb12be5fb7c1a821877460a1b4cd4adaee6531b4c12991834aafe1c745ef0a0b8c4a11fa1be317b35393b5b81dc7b345ad236
6
+ metadata.gz: f69f9e9840312da35a16d7d27a5705e0cf3d4a8364aaff4e7f90757bad2754e8a47ce6a20779e88a16269fb2b6d3ada9215397e84dd9988eba74afc2b44373c7
7
+ data.tar.gz: ea7533eb5588ddedee0343dbef28a7d0bfb9b2a7bab4e9ca2e427e2ce198bc857e3ca5c55526471f657bea485dee454235939b82dd30b7c718c3c2ea0d757210
data/CHANGELOG.md ADDED
@@ -0,0 +1,47 @@
1
+ # Changelog
2
+
3
+ ## 0.1.0 (unreleased)
4
+
5
+ ### Added
6
+
7
+ * Add config, reading from env vars and yml files (inspired by gem-release)
8
+ * Add `abstract` in order to signal a cmd is a base class that is not meant to be executed
9
+ * Add `opt '--path', type: :array` for options that can be given multiple times
10
+ * Add `opt '--one STR', default: 'one'`
11
+ * Add `opt '--one STR', requires :two` or `[:two, :three]` for options that depend on other options
12
+ * Add `opt '--one', alias: :other`
13
+ * Add `opt '--one', deprecated: true`, and `cmd.deprected_opts`, so clients can look up which deprecated options were used
14
+ * Add `opt '--one', alias: :other, deprecated: :other`, so that `cmd.deprecated_opts` returns the alias name if it was used
15
+ * Add `opt '--int', max: 10, type: :integer`
16
+ * Add `opt '--one', format: /.+/`
17
+ * Add `opt '--one', enum: ['one', 'two']`
18
+ * Add `required :one, [:two, :three]` (DNF, i.e: either :one or both :two and :three must be given)
19
+
20
+ ### Changed
21
+
22
+ * Much improved help output, modeled after rubygems' help output
23
+ * Cl is now a class
24
+ * Use the regstry gem, remove the local Registry implementation
25
+ * If a flag (boolean option) has a default `true` automatically add `[no-]` to
26
+ it, allowing to opt out
27
+
28
+ ### Removed
29
+
30
+ * Removed cmd.defaults, options have default: [value] now
31
+
32
+ ## 0.0.4 (2017-08-02)
33
+
34
+ * Ancient history
35
+
36
+ ## 0.0.3 (2017-08-02)
37
+
38
+ * Ancient history
39
+
40
+ ## 0.0.2 (2017-04-09)
41
+
42
+ * Ancient history
43
+
44
+ ## 0.0.1 (2017-04-08)
45
+
46
+ * Ancient history
47
+
data/Gemfile CHANGED
@@ -1,5 +1,8 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
+ gemspec
4
+
3
5
  group :test do
6
+ gem 'memfs'
4
7
  gem 'rspec'
5
8
  end
data/Gemfile.lock CHANGED
@@ -1,26 +1,36 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ cl (0.0.4)
5
+ regstry (~> 1.0.3)
6
+
1
7
  GEM
2
8
  remote: https://rubygems.org/
3
9
  specs:
4
10
  diff-lcs (1.3)
5
- rspec (3.5.0)
6
- rspec-core (~> 3.5.0)
7
- rspec-expectations (~> 3.5.0)
8
- rspec-mocks (~> 3.5.0)
9
- rspec-core (3.5.4)
10
- rspec-support (~> 3.5.0)
11
- rspec-expectations (3.5.0)
11
+ memfs (1.0.0)
12
+ regstry (1.0.6)
13
+ rspec (3.8.0)
14
+ rspec-core (~> 3.8.0)
15
+ rspec-expectations (~> 3.8.0)
16
+ rspec-mocks (~> 3.8.0)
17
+ rspec-core (3.8.0)
18
+ rspec-support (~> 3.8.0)
19
+ rspec-expectations (3.8.3)
12
20
  diff-lcs (>= 1.2.0, < 2.0)
13
- rspec-support (~> 3.5.0)
14
- rspec-mocks (3.5.0)
21
+ rspec-support (~> 3.8.0)
22
+ rspec-mocks (3.8.0)
15
23
  diff-lcs (>= 1.2.0, < 2.0)
16
- rspec-support (~> 3.5.0)
17
- rspec-support (3.5.0)
24
+ rspec-support (~> 3.8.0)
25
+ rspec-support (3.8.0)
18
26
 
19
27
  PLATFORMS
20
28
  ruby
21
29
 
22
30
  DEPENDENCIES
31
+ cl!
32
+ memfs
23
33
  rspec
24
34
 
25
35
  BUNDLED WITH
26
- 1.14.6
36
+ 1.17.2
data/NOTES.md CHANGED
@@ -1,25 +1,3 @@
1
- Usage: gem release [gemspec] [options]
1
+ - properly catch errors, see examples/cast etc
2
+ - add conditional required: ->(opts) { opts[:key].nil? }
2
3
 
3
- Options:
4
- -t, --[no-]tag Create a git tag and push it to the destination (defaults to false)
5
- -d, --destination DESTINATION Destination git repository (defaults to origin)
6
- -k, --key KEY Use the given API key from ~/.gem/credentials (not set by default)
7
- --host HOST Push to a gemcutter-compatible host other than rubygems.org (not set by default)
8
-
9
-
10
- Common Options:
11
- -h, --help Get help on this command
12
- -V, --[no-]verbose Set the verbose level of output
13
- -q, --quiet Silence command progress meter
14
- --silent Silence rubygems output
15
- --config-file FILE Use this config file instead of default
16
- --backtrace Show stack backtrace on errors
17
- --debug Turn on Ruby debugging
18
- --norc Avoid loading any .gemrc file
19
-
20
-
21
- Arguments:
22
- gemspec - optional gemspec file name, will use the first *.gemspec if not specified
23
-
24
- Summary:
25
- Build gem from a gemspec and push to rubygems.org
data/README.md CHANGED
@@ -14,7 +14,7 @@ module Owners
14
14
 
15
15
  args :owners
16
16
 
17
- on '-t', '--to TO', 'An owner in an existing group' do |value|
17
+ opt '-t', '--to TO', 'An owner in an existing group' do |value|
18
18
  opts[:to] = value
19
19
  end
20
20
  end
@@ -0,0 +1,82 @@
1
+ #!/usr/bin/env ruby
2
+ $: << File.expand_path('lib')
3
+
4
+ require 'cl'
5
+
6
+ class Bool < Cl::Cmd
7
+ arg :bool, type: :bool
8
+
9
+ def run
10
+ [registry_key, bool: bool]
11
+ end
12
+ end
13
+
14
+ class Types < Cl::Cmd
15
+ arg :a, type: :bool
16
+ arg :b, type: :int
17
+ arg :c, type: :float
18
+ arg :d
19
+
20
+ def run
21
+ [registry_key, a: a, b: b, c: c, d: d]
22
+ end
23
+ end
24
+
25
+ def output(cmd, args)
26
+ args = args.map { |key, value| "#{key}=#{value.inspect}" }.join(' ')
27
+ puts "Called #{cmd} with #{args}\n\n"
28
+ end
29
+
30
+ output *Cl.new($0).run(%w(bool on))
31
+
32
+ # Output:
33
+ #
34
+ # Called bool with bool=true
35
+
36
+ output *Cl.new($0).run(%w(bool on))
37
+
38
+ # Output:
39
+ #
40
+ # Called bool with bool=true
41
+
42
+ output *Cl.new($0).run(%w(bool on))
43
+
44
+ # Output:
45
+ #
46
+ # Called bool with bool=true
47
+
48
+ output *Cl.new($0).run(%w(bool on))
49
+
50
+ # Output:
51
+ #
52
+ # Called bool with bool=true
53
+
54
+ output *Cl.new($0).run(%w(types true 1 1.2 foo))
55
+
56
+ # Output:
57
+ #
58
+ # Called types with a=true b=1 c=1.2 d="foo"
59
+
60
+ Cl.new($0).run(%w(types true 1 1.2))
61
+
62
+ # Output:
63
+ #
64
+ # Too many arguments (given: 5, allowed: 4)
65
+ #
66
+ # Usage: cast.rb types [a (bool)] [b (int)] [c (float)] [d]
67
+
68
+ Cl.new($0).run(%w(types true one 1.2))
69
+
70
+ # Output:
71
+ #
72
+ # Wrong argument type (given: "one", expected: int)
73
+ #
74
+ # Usage: cast.rb types [a (bool)] [b (int)] [c (float)] [d]
75
+
76
+ Cl.new($0).run(%w(types true 1 one))
77
+
78
+ # Output:
79
+ #
80
+ # Wrong argument type (given: "one", expected: float)
81
+ #
82
+ # Usage: cast.rb types [a (bool)] [b (int)] [c (float)] [d]
@@ -0,0 +1,36 @@
1
+ #!/usr/bin/env ruby
2
+ $: << File.expand_path('lib')
3
+
4
+ require 'cl'
5
+
6
+ class Opts < Cl::Cmd
7
+ opt '-p', '--path PATH'
8
+ opt '-v', '--verbose'
9
+
10
+ def run
11
+ [registry_key, args, opts]
12
+ end
13
+ end
14
+
15
+ def output(cmd, args, opts)
16
+ puts "Called #{cmd} with args=#{args} opts=#{opts}\n\n"
17
+ end
18
+
19
+ output *Cl.new($0).run(%w(opts -p path -v))
20
+
21
+ # Output:
22
+ #
23
+ # Called cast with args=[] opts={:path=>"path", :verbose=>true}
24
+
25
+ output *Cl.new($0).run(%w(opts --path path --verbose))
26
+
27
+ # Output:
28
+ #
29
+ # Called cast with args=[] opts={:path=>"path", :verbose=>true}
30
+
31
+ output *Cl.new($0).run(%w(opts one -p path two -v three))
32
+
33
+ # Output:
34
+ #
35
+ # Called cast with args=["one", "two", "three"] opts={:path=>"path", :verbose=>true}
36
+
@@ -0,0 +1,46 @@
1
+ #!/usr/bin/env ruby
2
+ $: << File.expand_path('lib')
3
+
4
+ require 'cl'
5
+
6
+ class Required < Cl::Cmd
7
+ arg :one, required: true
8
+ arg :two
9
+
10
+ def run
11
+ [registry_key, one: one, two: two]
12
+ end
13
+ end
14
+
15
+ def output(cmd, args)
16
+ args = args.map { |key, value| "#{key}=#{value.inspect}" }.join(' ')
17
+ puts "Called #{cmd} with #{args}\n\n"
18
+ end
19
+
20
+ output *Cl.new($0).run(%w(required one two))
21
+
22
+ # Output:
23
+ #
24
+ # Called required with one="one" two="two"
25
+
26
+ output *Cl.new($0).run(%w(required one))
27
+
28
+ # Output:
29
+ #
30
+ # Called required with one="one" two=nil
31
+
32
+ output *Cl.new($0).run(%w(required))
33
+
34
+ # Output:
35
+ #
36
+ # Missing arguments (given: 0, required: 1)
37
+ #
38
+ # Usage: args.rb required one [two]
39
+
40
+ output *Cl.new($0).run(%w(required one two three))
41
+
42
+ # Output:
43
+ #
44
+ # Too many arguments (given: 3, allowed: 2)
45
+ #
46
+ # Usage: args.rb required one [two]
@@ -0,0 +1,61 @@
1
+ #!/usr/bin/env ruby
2
+ $: << File.expand_path('lib')
3
+
4
+ require 'cl'
5
+
6
+ class SplatLeft < Cl::Cmd
7
+ register 'splat:left'
8
+
9
+ arg :one, type: :array
10
+ args :two, :three
11
+
12
+ def run
13
+ [registry_key, one: one, two: two, three: three]
14
+ end
15
+ end
16
+
17
+ class SplatMiddle < Cl::Cmd
18
+ register 'splat:middle'
19
+
20
+ arg :one
21
+ arg :two, type: :array
22
+ arg :three
23
+
24
+ def run
25
+ [registry_key, one: one, two: two, three: three]
26
+ end
27
+ end
28
+
29
+ class SplatRight < Cl::Cmd
30
+ register 'splat:right'
31
+
32
+ args :one, :two
33
+ arg :three, type: :array
34
+
35
+ def run
36
+ [registry_key, one: one, two: two, three: three]
37
+ end
38
+ end
39
+
40
+ def output(cmd, args)
41
+ args = args.map { |key, value| "#{key}=#{value.inspect}" }.join(' ')
42
+ puts "Called #{cmd} with #{args}\n\n"
43
+ end
44
+
45
+ output *Cl.new($0).run(%w(splat left foo bar baz buz))
46
+
47
+ # Output:
48
+ #
49
+ # Called splat:left with one=["foo", "bar"] two="baz" three="buz"
50
+
51
+ output *Cl.new($0).run(%w(splat middle foo bar baz buz))
52
+
53
+ # Output:
54
+ #
55
+ # Called splat:middle with one="foo" two=["bar", "baz"] three="buz"
56
+
57
+ output *Cl.new($0).run(%w(splat right foo bar baz buz))
58
+
59
+ # Output:
60
+ #
61
+ # Called splat:middle with one="foo" two="bar" three=["baz", "buz"]
data/examples/gem ADDED
@@ -0,0 +1,104 @@
1
+ #!/usr/bin/env ruby
2
+ $: << File.expand_path('lib')
3
+
4
+ require 'cl'
5
+
6
+ module Gem
7
+ module Release
8
+ module Cmds
9
+ class Release < Cl::Cmd
10
+ arg :gemspec
11
+
12
+ opt '-h', '--host HOST', 'Push to a compatible host other than rubygems.org'
13
+ opt '-k', '--key KEY', 'Rubygems API key to use'
14
+ opt '-q', '--quiet', 'Silence output'
15
+
16
+ def run
17
+ [registry_key, args, opts]
18
+ end
19
+ end
20
+
21
+ class Bump < Cl::Cmd
22
+ defaults commit: true
23
+
24
+ opt '-v', '--version VERSION', 'The version to bump to [1.1.1|major|minor|patch|pre|rc|release]'
25
+ opt '--[no-]commit', 'Bump the version, but do not commit'
26
+
27
+ def run
28
+ [registry_key, args, opts]
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
34
+
35
+ Cl.new($0).run(%w(help))
36
+ puts
37
+
38
+ # Output:
39
+ #
40
+ # Type "gem help COMMAND [SUBCOMMAND]" for more details:
41
+ #
42
+ # gem release [gemspec] [options]
43
+ # gem bump [options]
44
+
45
+ Cl.new($0).run(%w(help release))
46
+ puts
47
+
48
+ # or:
49
+ #
50
+ # Cl.new($0).run(%w(release --help)))
51
+ # Cl.new($0).run(%w(release -h)))
52
+ #
53
+ # Output:
54
+ #
55
+ # Usage: gem release [gemspec] [options]
56
+ #
57
+ # Arguments:
58
+ #
59
+ # gemspec
60
+ #
61
+ # Options:
62
+ #
63
+ # -h --host HOST Push to a compatible host other than rubygems.org
64
+ # -k --key KEY Rubygems API key to use
65
+ # -q --quiet Silence output
66
+ # --help Get help on this command
67
+
68
+ Cl.new($0).run(%w(help release))
69
+ puts
70
+
71
+ # or:
72
+ #
73
+ # Cl.run($0, %w(release --help))
74
+ # Cl.run($0, %w(release -h))
75
+ #
76
+ # Output:
77
+ #
78
+ # Usage: gem bump [options]
79
+ #
80
+ # Options:
81
+ #
82
+ # -v --version VERSION The version to bump to [1.1.1|major|minor|patch|pre|rc|release]
83
+ # --no-commit Bump the version, but do not commit
84
+ # -h --help Get help on this command
85
+
86
+ cmds = [
87
+ Cl.new($0).run(%w(bump -v 1.1.1)),
88
+ Cl.new($0).run(%w(release foo.gemspec -h host -k key -q))
89
+ ]
90
+
91
+ puts "Commands run:\n\n"
92
+ puts cmds.map { |cmd, args, opts| " cmd #{cmd} has run with:\n\n args=#{args}\n opts=#{opts}\n\n" }
93
+
94
+ # Commands run:
95
+ #
96
+ # cmd bump has run with:
97
+ #
98
+ # args=[]
99
+ # opts={:version=>"1.1.1"}
100
+ #
101
+ # cmd release has run with:
102
+ #
103
+ # args=["foo.gemspec"]
104
+ # opts={:host=>"host", :key=>"key", :quiet=>true}
data/examples/heroku ADDED
@@ -0,0 +1,49 @@
1
+ #!/usr/bin/env ruby
2
+ $: << File.expand_path('lib')
3
+
4
+ require 'cl'
5
+
6
+ module Heroku
7
+ module Apps
8
+ class Create < Cl::Cmd
9
+ register 'apps:create'
10
+
11
+ arg :name, required: true
12
+
13
+ opt '-o', '--org ORG'
14
+
15
+ def run; [registry_key, args, opts] end
16
+ end
17
+
18
+ class List < Cl::Cmd
19
+ register 'apps:info'
20
+
21
+ opt '-a', '--app APP'
22
+
23
+ def run; [registry_key, args, opts] end
24
+ end
25
+ end
26
+ end
27
+
28
+ def output(cmd, args, opts)
29
+ puts "Called #{cmd} with args=#{args} opts=#{opts}\n\n"
30
+ end
31
+
32
+ output *Cl.new($0).run(%w(apps:create name -o org))
33
+
34
+ # Output:
35
+ #
36
+ # Called apps:create with args=["name"] opts={:org=>"org"}
37
+
38
+ output *Cl.new($0).run(%w(apps create name -o org))
39
+
40
+ # Output:
41
+ #
42
+ # Called apps:create with args=["name"] opts={:org=>"org"}
43
+
44
+ output *Cl.new($0).run(%w(apps:info -a app))
45
+
46
+ # Output:
47
+ #
48
+ # Called apps:create with args=["app"] opts={}
49
+
@@ -1,3 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+ $: << File.expand_path('lib')
3
+
1
4
  require 'cl'
2
5
 
3
6
  module Rakeish
@@ -15,9 +18,7 @@ module Rakeish
15
18
 
16
19
  arg :name
17
20
 
18
- opt '-f', '--force' do
19
- opts[:force] = true
20
- end
21
+ opt '-f', '--force'
21
22
 
22
23
  def run; [registry_key, args, opts] end
23
24
  end
@@ -27,9 +28,7 @@ module Rakeish
27
28
 
28
29
  arg :name
29
30
 
30
- opt '-v', '--version VERSION' do |value|
31
- opts[:version] = value
32
- end
31
+ opt '-v', '--version VERSION'
33
32
 
34
33
  def run; [registry_key, args, opts] end
35
34
  end
@@ -40,11 +39,14 @@ def output(result)
40
39
  result.each do |cmd, args, opts|
41
40
  puts "Called #{cmd} with args=#{args} opts=#{opts}"
42
41
  end
42
+ puts
43
43
  end
44
44
 
45
- Cl.runner = :multi
46
- output Cl.run(*%w(db:drop production -f db:create db:migrate production -v 1))
45
+ argv = %w(db:drop production -f db:create db:migrate production -v 1)
46
+ output Cl.new($0, runner: :multi).run(argv)
47
+
47
48
  # Output:
48
- # Called db:drop with args=["production"] opts={:force=>true}
49
- # Called db:create with args=[] opts={}
50
- # Called db:migrate with args=["production"] opts={:version=>"1"}
49
+ #
50
+ # Called db:drop with args=["production"] opts={:force=>true}
51
+ # Called db:create with args=[] opts={}
52
+ # Called db:migrate with args=["production"] opts={:version=>"1"}
data/lib/cl/arg.rb CHANGED
@@ -1,7 +1,8 @@
1
- module Cl
1
+ require 'cl/cast'
2
+
3
+ class Cl
2
4
  class Arg < Struct.new(:name, :opts)
3
- TRUE = /^(true|yes|on)$/
4
- FALSE = /^(false|no|off)$/
5
+ include Cast
5
6
 
6
7
  def define(const)
7
8
  const.send(:attr_accessor, name)
@@ -12,7 +13,11 @@ module Cl
12
13
  end
13
14
 
14
15
  def type
15
- opts[:type] || :str
16
+ opts[:type] || :string
17
+ end
18
+
19
+ def description
20
+ opts[:description]
16
21
  end
17
22
 
18
23
  def splat?
@@ -23,36 +28,13 @@ module Cl
23
28
  !!opts[:required]
24
29
  end
25
30
 
26
- def cast(value)
27
- case type
28
- when nil
29
- value
30
- when :array
31
- Array(value).flatten.map { |value| value.split(',') }.flatten
32
- when :string, :str
33
- value.to_s
34
- when :boolean, :bool
35
- return true if value.to_s =~ TRUE
36
- return false if value.to_s =~ FALSE
37
- !!value
38
- when :integer, :int
39
- Integer(value)
40
- when :float
41
- Float(value)
42
- else
43
- raise ArgumentError, "Unknown type: #{type}" if value
44
- end
45
- rescue ::ArgumentError => e
46
- raise ArgumentError.new(:wrong_type, value.inspect, type)
47
- end
48
-
49
31
  def to_s
50
32
  str = name
51
33
  case type
52
34
  when :array then str = "#{str}.."
53
- when :integer, :int then str = "#{str} (int)"
54
- when :boolean, :bool then str = "#{str} (bool)"
55
- when :float then str = "#{str} (float)"
35
+ when :integer, :int then str = "#{str}:int"
36
+ when :boolean, :bool then str = "#{str}:bool"
37
+ when :float then str = "#{str}:float"
56
38
  end
57
39
  required? ? str : "[#{str}]"
58
40
  end
data/lib/cl/args.rb CHANGED
@@ -1,13 +1,16 @@
1
1
  require 'cl/arg'
2
2
 
3
- module Cl
3
+ class Cl
4
4
  class Args
5
5
  include Enumerable
6
6
 
7
- def define(const, name, opts = {})
7
+ def define(const, name, *args)
8
+ opts = args.last.is_a?(Hash) ? args.pop.dup : {}
9
+ opts[:description] = args.shift if args.any?
10
+
8
11
  arg = Arg.new(name, opts)
9
12
  arg.define(const)
10
- args << arg
13
+ self.args << arg
11
14
  end
12
15
 
13
16
  def apply(cmd, args)
@@ -41,11 +44,11 @@ module Cl
41
44
  end
42
45
 
43
46
  def splat?
44
- args.any?(&:splat?)
47
+ any?(&:splat?)
45
48
  end
46
49
 
47
50
  def required
48
- args.select { |arg| arg.required? }.size
51
+ select(&:required?).size
49
52
  end
50
53
 
51
54
  def grouped(values)