thor-exclude_pattern 0.18.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.
- checksums.yaml +7 -0
- data/.document +5 -0
- data/CHANGELOG.md +130 -0
- data/LICENSE.md +20 -0
- data/README.md +34 -0
- data/Thorfile +30 -0
- data/bin/rake2thor +86 -0
- data/bin/thor +6 -0
- data/lib/thor.rb +458 -0
- data/lib/thor/actions.rb +318 -0
- data/lib/thor/actions/create_file.rb +105 -0
- data/lib/thor/actions/create_link.rb +60 -0
- data/lib/thor/actions/directory.rb +119 -0
- data/lib/thor/actions/empty_directory.rb +153 -0
- data/lib/thor/actions/file_manipulation.rb +314 -0
- data/lib/thor/actions/inject_into_file.rb +109 -0
- data/lib/thor/base.rb +649 -0
- data/lib/thor/command.rb +136 -0
- data/lib/thor/core_ext/hash_with_indifferent_access.rb +80 -0
- data/lib/thor/core_ext/io_binary_read.rb +12 -0
- data/lib/thor/core_ext/ordered_hash.rb +100 -0
- data/lib/thor/error.rb +32 -0
- data/lib/thor/exclude_pattern/version.rb +5 -0
- data/lib/thor/group.rb +287 -0
- data/lib/thor/invocation.rb +172 -0
- data/lib/thor/parser.rb +4 -0
- data/lib/thor/parser/argument.rb +74 -0
- data/lib/thor/parser/arguments.rb +171 -0
- data/lib/thor/parser/option.rb +121 -0
- data/lib/thor/parser/options.rb +218 -0
- data/lib/thor/rake_compat.rb +72 -0
- data/lib/thor/runner.rb +322 -0
- data/lib/thor/shell.rb +88 -0
- data/lib/thor/shell/basic.rb +393 -0
- data/lib/thor/shell/color.rb +148 -0
- data/lib/thor/shell/html.rb +127 -0
- data/lib/thor/util.rb +270 -0
- data/lib/thor/version.rb +3 -0
- data/spec/actions/create_file_spec.rb +170 -0
- data/spec/actions/create_link_spec.rb +95 -0
- data/spec/actions/directory_spec.rb +169 -0
- data/spec/actions/empty_directory_spec.rb +130 -0
- data/spec/actions/file_manipulation_spec.rb +382 -0
- data/spec/actions/inject_into_file_spec.rb +135 -0
- data/spec/actions_spec.rb +331 -0
- data/spec/base_spec.rb +294 -0
- data/spec/command_spec.rb +80 -0
- data/spec/core_ext/hash_with_indifferent_access_spec.rb +48 -0
- data/spec/core_ext/ordered_hash_spec.rb +115 -0
- data/spec/exit_condition_spec.rb +19 -0
- data/spec/fixtures/application.rb +2 -0
- data/spec/fixtures/app{1}/README +3 -0
- data/spec/fixtures/bundle/execute.rb +6 -0
- data/spec/fixtures/bundle/main.thor +1 -0
- data/spec/fixtures/command.thor +10 -0
- data/spec/fixtures/doc/%file_name%.rb.tt +1 -0
- data/spec/fixtures/doc/COMMENTER +11 -0
- data/spec/fixtures/doc/README +3 -0
- data/spec/fixtures/doc/block_helper.rb +3 -0
- data/spec/fixtures/doc/config.rb +1 -0
- data/spec/fixtures/doc/config.yaml.tt +1 -0
- data/spec/fixtures/doc/excluding/%file_name%.rb.tt +1 -0
- data/spec/fixtures/enum.thor +10 -0
- data/spec/fixtures/group.thor +128 -0
- data/spec/fixtures/invoke.thor +112 -0
- data/spec/fixtures/path with spaces b/data/spec/fixtures/path with → spaces +0 -0
- data/spec/fixtures/preserve/script.sh +3 -0
- data/spec/fixtures/script.thor +199 -0
- data/spec/fixtures/subcommand.thor +17 -0
- data/spec/group_spec.rb +216 -0
- data/spec/helper.rb +67 -0
- data/spec/invocation_spec.rb +100 -0
- data/spec/parser/argument_spec.rb +53 -0
- data/spec/parser/arguments_spec.rb +66 -0
- data/spec/parser/option_spec.rb +202 -0
- data/spec/parser/options_spec.rb +400 -0
- data/spec/rake_compat_spec.rb +72 -0
- data/spec/register_spec.rb +197 -0
- data/spec/runner_spec.rb +241 -0
- data/spec/sandbox/application.rb +2 -0
- data/spec/sandbox/app{1}/README +3 -0
- data/spec/sandbox/bundle/execute.rb +6 -0
- data/spec/sandbox/bundle/main.thor +1 -0
- data/spec/sandbox/command.thor +10 -0
- data/spec/sandbox/doc/%file_name%.rb.tt +1 -0
- data/spec/sandbox/doc/COMMENTER +11 -0
- data/spec/sandbox/doc/README +4 -0
- data/spec/sandbox/doc/block_helper.rb +3 -0
- data/spec/sandbox/doc/config.rb +1 -0
- data/spec/sandbox/doc/config.yaml.tt +1 -0
- data/spec/sandbox/doc/excluding/%file_name%.rb.tt +1 -0
- data/spec/sandbox/enum.thor +10 -0
- data/spec/sandbox/group.thor +128 -0
- data/spec/sandbox/invoke.thor +112 -0
- data/spec/sandbox/path with spaces b/data/spec/sandbox/path with → spaces +0 -0
- data/spec/sandbox/preserve/script.sh +3 -0
- data/spec/sandbox/script.thor +199 -0
- data/spec/sandbox/subcommand.thor +17 -0
- data/spec/shell/basic_spec.rb +311 -0
- data/spec/shell/color_spec.rb +95 -0
- data/spec/shell/html_spec.rb +32 -0
- data/spec/shell_spec.rb +47 -0
- data/spec/subcommand_spec.rb +30 -0
- data/spec/thor_spec.rb +469 -0
- data/spec/util_spec.rb +196 -0
- data/thor.gemspec +24 -0
- metadata +232 -0
@@ -0,0 +1,80 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
describe Thor::Command do
|
4
|
+
def command(options={})
|
5
|
+
options.each do |key, value|
|
6
|
+
options[key] = Thor::Option.parse(key, value)
|
7
|
+
end
|
8
|
+
|
9
|
+
@command ||= Thor::Command.new(:can_has, "I can has cheezburger", "I can has cheezburger\nLots and lots of it", "can_has", options)
|
10
|
+
end
|
11
|
+
|
12
|
+
describe "#formatted_usage" do
|
13
|
+
it "includes namespace within usage" do
|
14
|
+
object = Struct.new(:namespace, :arguments).new("foo", [])
|
15
|
+
expect(command(:bar => :required).formatted_usage(object)).to eq("foo:can_has --bar=BAR")
|
16
|
+
end
|
17
|
+
|
18
|
+
it "includes subcommand name within subcommand usage" do
|
19
|
+
object = Struct.new(:namespace, :arguments).new("main:foo", [])
|
20
|
+
expect(command(:bar => :required).formatted_usage(object, false, true)).to eq("foo can_has --bar=BAR")
|
21
|
+
end
|
22
|
+
|
23
|
+
it "removes default from namespace" do
|
24
|
+
object = Struct.new(:namespace, :arguments).new("default:foo", [])
|
25
|
+
expect(command(:bar => :required).formatted_usage(object)).to eq(":foo:can_has --bar=BAR")
|
26
|
+
end
|
27
|
+
|
28
|
+
it "injects arguments into usage" do
|
29
|
+
options = {:required => true, :type => :string}
|
30
|
+
object = Struct.new(:namespace, :arguments).new("foo", [Thor::Argument.new(:bar, options)])
|
31
|
+
expect(command(:foo => :required).formatted_usage(object)).to eq("foo:can_has BAR --foo=FOO")
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
describe "#dynamic" do
|
36
|
+
it "creates a dynamic command with the given name" do
|
37
|
+
expect(Thor::DynamicCommand.new('command').name).to eq('command')
|
38
|
+
expect(Thor::DynamicCommand.new('command').description).to eq('A dynamically-generated command')
|
39
|
+
expect(Thor::DynamicCommand.new('command').usage).to eq('command')
|
40
|
+
expect(Thor::DynamicCommand.new('command').options).to eq({})
|
41
|
+
end
|
42
|
+
|
43
|
+
it "does not invoke an existing method" do
|
44
|
+
mock = mock()
|
45
|
+
mock.class.should_receive(:handle_no_command_error).with("to_s")
|
46
|
+
Thor::DynamicCommand.new('to_s').run(mock)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
describe "#dup" do
|
51
|
+
it "dup options hash" do
|
52
|
+
command = Thor::Command.new("can_has", nil, nil, nil, :foo => true, :bar => :required)
|
53
|
+
command.dup.options.delete(:foo)
|
54
|
+
expect(command.options[:foo]).to be
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
describe "#run" do
|
59
|
+
it "runs a command by calling a method in the given instance" do
|
60
|
+
mock = mock()
|
61
|
+
mock.should_receive(:can_has).and_return {|*args| args }
|
62
|
+
expect(command.run(mock, [1, 2, 3])).to eq([1, 2, 3])
|
63
|
+
end
|
64
|
+
|
65
|
+
it "raises an error if the method to be invoked is private" do
|
66
|
+
klass = Class.new do
|
67
|
+
def self.handle_no_command_error(name)
|
68
|
+
name
|
69
|
+
end
|
70
|
+
|
71
|
+
private
|
72
|
+
def can_has
|
73
|
+
"fail"
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
expect(command.run(klass.new)).to eq("can_has")
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'helper'
|
2
|
+
require 'thor/core_ext/hash_with_indifferent_access'
|
3
|
+
|
4
|
+
describe Thor::CoreExt::HashWithIndifferentAccess do
|
5
|
+
before do
|
6
|
+
@hash = Thor::CoreExt::HashWithIndifferentAccess.new :foo => 'bar', 'baz' => 'bee', :force => true
|
7
|
+
end
|
8
|
+
|
9
|
+
it "has values accessible by either strings or symbols" do
|
10
|
+
expect(@hash['foo']).to eq('bar')
|
11
|
+
expect(@hash[:foo]).to eq('bar')
|
12
|
+
|
13
|
+
expect(@hash.values_at(:foo, :baz)).to eq(['bar', 'bee'])
|
14
|
+
expect(@hash.delete(:foo)).to eq('bar')
|
15
|
+
end
|
16
|
+
|
17
|
+
it "handles magic boolean predicates" do
|
18
|
+
expect(@hash.force?).to be_true
|
19
|
+
expect(@hash.foo?).to be_true
|
20
|
+
expect(@hash.nothing?).to be_false
|
21
|
+
end
|
22
|
+
|
23
|
+
it "handles magic comparisions" do
|
24
|
+
expect(@hash.foo?('bar')).to be_true
|
25
|
+
expect(@hash.foo?('bee')).to be_false
|
26
|
+
end
|
27
|
+
|
28
|
+
it "maps methods to keys" do
|
29
|
+
expect(@hash.foo).to eq(@hash['foo'])
|
30
|
+
end
|
31
|
+
|
32
|
+
it "merges keys independent if they are symbols or strings" do
|
33
|
+
@hash.merge!('force' => false, :baz => "boom")
|
34
|
+
expect(@hash[:force]).to eq(false)
|
35
|
+
expect(@hash[:baz]).to eq("boom")
|
36
|
+
end
|
37
|
+
|
38
|
+
it "creates a new hash by merging keys independent if they are symbols or strings" do
|
39
|
+
other = @hash.merge('force' => false, :baz => "boom")
|
40
|
+
expect(other[:force]).to eq(false)
|
41
|
+
expect(other[:baz]).to eq("boom")
|
42
|
+
end
|
43
|
+
|
44
|
+
it "converts to a traditional hash" do
|
45
|
+
expect(@hash.to_hash.class).to eq(Hash)
|
46
|
+
expect(@hash).to eq({ 'foo' => 'bar', 'baz' => 'bee', 'force' => true })
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,115 @@
|
|
1
|
+
require 'helper'
|
2
|
+
require 'thor/core_ext/ordered_hash'
|
3
|
+
|
4
|
+
describe Thor::CoreExt::OrderedHash do
|
5
|
+
before do
|
6
|
+
@hash = Thor::CoreExt::OrderedHash.new
|
7
|
+
end
|
8
|
+
|
9
|
+
describe "without any items" do
|
10
|
+
it "returns nil for an undefined key" do
|
11
|
+
expect(@hash["foo"]).to be_nil
|
12
|
+
end
|
13
|
+
|
14
|
+
it "doesn't iterate through any items" do
|
15
|
+
@hash.each { fail }
|
16
|
+
end
|
17
|
+
|
18
|
+
it "has an empty key and values list" do
|
19
|
+
expect(@hash.keys).to be_empty
|
20
|
+
expect(@hash.values).to be_empty
|
21
|
+
end
|
22
|
+
|
23
|
+
it "must be empty" do
|
24
|
+
expect(@hash).to be_empty
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
describe "with several items" do
|
29
|
+
before do
|
30
|
+
@hash[:foo] = "Foo!"
|
31
|
+
@hash[:bar] = "Bar!"
|
32
|
+
@hash[:baz] = "Baz!"
|
33
|
+
@hash[:bop] = "Bop!"
|
34
|
+
@hash[:bat] = "Bat!"
|
35
|
+
end
|
36
|
+
|
37
|
+
it "returns nil for an undefined key" do
|
38
|
+
expect(@hash[:boom]).to be_nil
|
39
|
+
end
|
40
|
+
|
41
|
+
it "returns the value for each key" do
|
42
|
+
expect(@hash[:foo]).to eq("Foo!")
|
43
|
+
expect(@hash[:bar]).to eq("Bar!")
|
44
|
+
expect(@hash[:baz]).to eq("Baz!")
|
45
|
+
expect(@hash[:bop]).to eq("Bop!")
|
46
|
+
expect(@hash[:bat]).to eq("Bat!")
|
47
|
+
end
|
48
|
+
|
49
|
+
it "iterates through the keys and values in order of assignment" do
|
50
|
+
arr = []
|
51
|
+
@hash.each do |key, value|
|
52
|
+
arr << [key, value]
|
53
|
+
end
|
54
|
+
expect(arr).to eq([[:foo, "Foo!"], [:bar, "Bar!"], [:baz, "Baz!"],
|
55
|
+
[:bop, "Bop!"], [:bat, "Bat!"]])
|
56
|
+
end
|
57
|
+
|
58
|
+
it "returns the keys in order of insertion" do
|
59
|
+
expect(@hash.keys).to eq([:foo, :bar, :baz, :bop, :bat])
|
60
|
+
end
|
61
|
+
|
62
|
+
it "returns the values in order of insertion" do
|
63
|
+
expect(@hash.values).to eq(["Foo!", "Bar!", "Baz!", "Bop!", "Bat!"])
|
64
|
+
end
|
65
|
+
|
66
|
+
it "does not move an overwritten node to the end of the ordering" do
|
67
|
+
@hash[:baz] = "Bip!"
|
68
|
+
expect(@hash.values).to eq(["Foo!", "Bar!", "Bip!", "Bop!", "Bat!"])
|
69
|
+
|
70
|
+
@hash[:foo] = "Bip!"
|
71
|
+
expect(@hash.values).to eq(["Bip!", "Bar!", "Bip!", "Bop!", "Bat!"])
|
72
|
+
|
73
|
+
@hash[:bat] = "Bip!"
|
74
|
+
expect(@hash.values).to eq(["Bip!", "Bar!", "Bip!", "Bop!", "Bip!"])
|
75
|
+
end
|
76
|
+
|
77
|
+
it "appends another ordered hash while preserving ordering" do
|
78
|
+
other_hash = Thor::CoreExt::OrderedHash.new
|
79
|
+
other_hash[1] = "one"
|
80
|
+
other_hash[2] = "two"
|
81
|
+
other_hash[3] = "three"
|
82
|
+
expect(@hash.merge(other_hash).values).to eq(["Foo!", "Bar!", "Baz!", "Bop!", "Bat!", "one", "two", "three"])
|
83
|
+
end
|
84
|
+
|
85
|
+
it "overwrites hash keys with matching appended keys" do
|
86
|
+
other_hash = Thor::CoreExt::OrderedHash.new
|
87
|
+
other_hash[:bar] = "bar"
|
88
|
+
expect(@hash.merge(other_hash)[:bar]).to eq("bar")
|
89
|
+
expect(@hash[:bar]).to eq("Bar!")
|
90
|
+
end
|
91
|
+
|
92
|
+
it "converts to an array" do
|
93
|
+
expect(@hash.to_a).to eq([[:foo, "Foo!"], [:bar, "Bar!"], [:baz, "Baz!"], [:bop, "Bop!"], [:bat, "Bat!"]])
|
94
|
+
end
|
95
|
+
|
96
|
+
it "must not be empty" do
|
97
|
+
expect(@hash).not_to be_empty
|
98
|
+
end
|
99
|
+
|
100
|
+
it "deletes values from hash" do
|
101
|
+
expect(@hash.delete(:baz)).to eq("Baz!")
|
102
|
+
expect(@hash.values).to eq(["Foo!", "Bar!", "Bop!", "Bat!"])
|
103
|
+
|
104
|
+
expect(@hash.delete(:foo)).to eq("Foo!")
|
105
|
+
expect(@hash.values).to eq(["Bar!", "Bop!", "Bat!"])
|
106
|
+
|
107
|
+
expect(@hash.delete(:bat)).to eq("Bat!")
|
108
|
+
expect(@hash.values).to eq(["Bar!", "Bop!"])
|
109
|
+
end
|
110
|
+
|
111
|
+
it "returns nil if the value to be deleted can't be found" do
|
112
|
+
expect(@hash.delete(:nothing)).to be_nil
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'helper'
|
2
|
+
require 'thor/base'
|
3
|
+
|
4
|
+
describe "Exit conditions" do
|
5
|
+
it "exits 0, not bubble up EPIPE, if EPIPE is raised" do
|
6
|
+
epiped = false
|
7
|
+
|
8
|
+
command = Class.new(Thor) do
|
9
|
+
desc "my_action", "testing EPIPE"
|
10
|
+
define_method :my_action do
|
11
|
+
epiped = true
|
12
|
+
raise Errno::EPIPE
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
expect{ command.start(["my_action"]) }.to raise_error(SystemExit)
|
17
|
+
expect(epiped).to eq(true)
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'execute')
|
@@ -0,0 +1 @@
|
|
1
|
+
FOO = <%= "FOO" %>
|
@@ -0,0 +1 @@
|
|
1
|
+
class <%= @klass %>; end
|
@@ -0,0 +1 @@
|
|
1
|
+
--- Hi from yaml
|
@@ -0,0 +1 @@
|
|
1
|
+
BAR = <%= "BAR" %>
|
@@ -0,0 +1,128 @@
|
|
1
|
+
class MyCounter < Thor::Group
|
2
|
+
include Thor::Actions
|
3
|
+
add_runtime_options!
|
4
|
+
|
5
|
+
def self.get_from_super
|
6
|
+
from_superclass(:get_from_super, 13)
|
7
|
+
end
|
8
|
+
|
9
|
+
source_root File.expand_path(File.dirname(__FILE__))
|
10
|
+
source_paths << File.expand_path("broken", File.dirname(__FILE__))
|
11
|
+
|
12
|
+
argument :first, :type => :numeric
|
13
|
+
argument :second, :type => :numeric, :default => 2
|
14
|
+
|
15
|
+
class_option :third, :type => :numeric, :desc => "The third argument", :default => 3,
|
16
|
+
:banner => "THREE", :aliases => "-t"
|
17
|
+
class_option :fourth, :type => :numeric, :desc => "The fourth argument"
|
18
|
+
class_option :simple, :type => :numeric, :aliases => 'z'
|
19
|
+
class_option :symbolic, :type => :numeric, :aliases => [:y, :r]
|
20
|
+
|
21
|
+
desc <<-FOO
|
22
|
+
Description:
|
23
|
+
This generator runs three commands: one, two and three.
|
24
|
+
FOO
|
25
|
+
|
26
|
+
def one
|
27
|
+
first
|
28
|
+
end
|
29
|
+
|
30
|
+
def two
|
31
|
+
second
|
32
|
+
end
|
33
|
+
|
34
|
+
def three
|
35
|
+
options[:third]
|
36
|
+
end
|
37
|
+
|
38
|
+
def four
|
39
|
+
options[:fourth]
|
40
|
+
end
|
41
|
+
|
42
|
+
def five
|
43
|
+
options[:simple]
|
44
|
+
end
|
45
|
+
|
46
|
+
def six
|
47
|
+
options[:symbolic]
|
48
|
+
end
|
49
|
+
|
50
|
+
def self.inherited(base)
|
51
|
+
super
|
52
|
+
base.source_paths.unshift(File.expand_path(File.join(File.dirname(__FILE__), "doc")))
|
53
|
+
end
|
54
|
+
|
55
|
+
no_commands do
|
56
|
+
def world(&block)
|
57
|
+
result = capture(&block)
|
58
|
+
concat(result.strip + " world!")
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
class ClearCounter < MyCounter
|
64
|
+
remove_argument :first, :second, :undefine => true
|
65
|
+
remove_class_option :third
|
66
|
+
|
67
|
+
def self.source_root
|
68
|
+
File.expand_path(File.join(File.dirname(__FILE__), "bundle"))
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
class BrokenCounter < MyCounter
|
73
|
+
namespace "app:broken:counter"
|
74
|
+
class_option :fail, :type => :boolean, :default => false
|
75
|
+
|
76
|
+
class << self
|
77
|
+
undef_method :source_root
|
78
|
+
end
|
79
|
+
|
80
|
+
def one
|
81
|
+
options[:first]
|
82
|
+
end
|
83
|
+
|
84
|
+
def four
|
85
|
+
respond_to?(:fail)
|
86
|
+
end
|
87
|
+
|
88
|
+
def five
|
89
|
+
options[:fail] ? this_method_does_not_exist : 5
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
class WhinyGenerator < Thor::Group
|
94
|
+
include Thor::Actions
|
95
|
+
|
96
|
+
def self.source_root
|
97
|
+
File.expand_path(File.dirname(__FILE__))
|
98
|
+
end
|
99
|
+
|
100
|
+
def wrong_arity(required)
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
class CommandConflict < Thor::Group
|
105
|
+
desc "A group with the same name as a default command"
|
106
|
+
def group
|
107
|
+
puts "group"
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
class ParentGroup < Thor::Group
|
112
|
+
private
|
113
|
+
def foo
|
114
|
+
"foo"
|
115
|
+
end
|
116
|
+
|
117
|
+
def baz(name = 'baz')
|
118
|
+
name
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
class ChildGroup < ParentGroup
|
123
|
+
def bar
|
124
|
+
"bar"
|
125
|
+
end
|
126
|
+
|
127
|
+
public_command :foo, :baz
|
128
|
+
end
|