ing 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (59) hide show
  1. data/.gitignore +5 -0
  2. data/GENERATORS.md +2 -0
  3. data/LICENSE +18 -0
  4. data/OPTIONS.md +2 -0
  5. data/README.md +251 -0
  6. data/TASKS.md +21 -0
  7. data/bin/ing +5 -0
  8. data/examples/rspec_convert.rb +102 -0
  9. data/ing.gemspec +29 -0
  10. data/ing.rb +102 -0
  11. data/lib/ing.rb +78 -0
  12. data/lib/ing/actions/create_file.rb +105 -0
  13. data/lib/ing/actions/create_link.rb +57 -0
  14. data/lib/ing/actions/directory.rb +98 -0
  15. data/lib/ing/actions/empty_directory.rb +155 -0
  16. data/lib/ing/actions/file_manipulation.rb +308 -0
  17. data/lib/ing/actions/inject_into_file.rb +109 -0
  18. data/lib/ing/commands/boot.rb +76 -0
  19. data/lib/ing/commands/generate.rb +64 -0
  20. data/lib/ing/commands/help.rb +87 -0
  21. data/lib/ing/commands/implicit.rb +59 -0
  22. data/lib/ing/commands/list.rb +108 -0
  23. data/lib/ing/dispatcher.rb +132 -0
  24. data/lib/ing/files.rb +190 -0
  25. data/lib/ing/lib_trollop.rb +782 -0
  26. data/lib/ing/shell.rb +390 -0
  27. data/lib/ing/trollop/parser.rb +17 -0
  28. data/lib/ing/util.rb +61 -0
  29. data/lib/ing/version.rb +3 -0
  30. data/lib/thor/actions/file_manipulation.rb +30 -0
  31. data/lib/thor/shell/basic.rb +44 -0
  32. data/test/acceptance/ing_run_tests.rb +164 -0
  33. data/test/actions/create_file_spec.rb +209 -0
  34. data/test/actions/create_link_spec.rb +90 -0
  35. data/test/actions/directory_spec.rb +167 -0
  36. data/test/actions/empty_directory_spec.rb +146 -0
  37. data/test/actions/file_manipulation_spec.rb +433 -0
  38. data/test/actions/inject_into_file_spec.rb +147 -0
  39. data/test/fixtures/application.rb +2 -0
  40. data/test/fixtures/app{1}/README +3 -0
  41. data/test/fixtures/bundle/execute.rb +6 -0
  42. data/test/fixtures/bundle/main.thor +1 -0
  43. data/test/fixtures/doc/%file_name%.rb.tt +1 -0
  44. data/test/fixtures/doc/COMMENTER +10 -0
  45. data/test/fixtures/doc/README +3 -0
  46. data/test/fixtures/doc/block_helper.rb +3 -0
  47. data/test/fixtures/doc/components/.empty_directory +0 -0
  48. data/test/fixtures/doc/config.rb +1 -0
  49. data/test/fixtures/doc/config.yaml.tt +1 -0
  50. data/test/fixtures/group.ing.rb +76 -0
  51. data/test/fixtures/invok.ing.rb +50 -0
  52. data/test/fixtures/namespace.ing.rb +52 -0
  53. data/test/fixtures/require.ing.rb +7 -0
  54. data/test/fixtures/task.ing.rb +36 -0
  55. data/test/fixtures/task.thor +10 -0
  56. data/test/spec_helper.rb +2 -0
  57. data/test/test_helper.rb +41 -0
  58. data/todo.yml +7 -0
  59. metadata +147 -0
@@ -0,0 +1,3 @@
1
+ module Ing
2
+ VERSION = '0.1.1'
3
+ end
@@ -0,0 +1,30 @@
1
+ # patch to access captures in gsub_file
2
+ # https://github.com/kentaroi/thor/commit/46b6d0b18a58eb8f7586e57eb633e96664fb1722
3
+ #
4
+ class Thor
5
+ module Actions
6
+
7
+ def gsub_file(path, flag, *args, &block)
8
+ return unless behavior == :invoke
9
+ config = args.last.is_a?(Hash) ? args.pop : {}
10
+
11
+ path = File.expand_path(path, destination_root)
12
+ say_status :gsub, relative_to_original_destination_root(path), config.fetch(:verbose, true)
13
+
14
+ unless options[:pretend]
15
+ content = File.binread(path)
16
+ if block
17
+ if block.arity == 1
18
+ content.gsub!(flag, *args) { block.call($&) }
19
+ else
20
+ content.gsub!(flag, *args) { block.call(*$~) }
21
+ end
22
+ else
23
+ content.gsub!(flag, *args)
24
+ end
25
+ File.open(path, 'wb') { |file| file.write(content) }
26
+ end
27
+ end
28
+
29
+ end
30
+ end
@@ -0,0 +1,44 @@
1
+ # monkey patch for better ask behavior
2
+
3
+ class Thor
4
+ module Shell
5
+ class Basic
6
+
7
+ def ask(statement, *args)
8
+ options = args.last.is_a?(Hash) ? args.pop : {}
9
+ color = args.pop
10
+ default = options[:default]
11
+ if options[:limited_to]
12
+ ask_filtered(statement, options[:limited_to], color, default)
13
+ else
14
+ ask_simply(statement, color, default)
15
+ end
16
+ end
17
+
18
+ def yes?(statement, *args)
19
+ !!(ask(statement, *args) =~ is?(:yes))
20
+ end
21
+
22
+ protected
23
+
24
+
25
+ def ask_simply(statement, color=nil, default=nil)
26
+ say("#{statement} #{default ? '(default ' + default + ')' : nil} ", color)
27
+ input = stdin.gets.strip
28
+ input.empty? ? default : input
29
+ end
30
+
31
+ def ask_filtered(statement, answer_set, color=nil, default=nil)
32
+ correct_answer = nil
33
+ until correct_answer
34
+ answer = ask_simply("#{statement} #{answer_set.inspect}", color, default)
35
+ correct_answer = answer_set.include?(answer) ? answer : nil
36
+ answers = answer_set.map(&:inspect).join(", ")
37
+ say("Your response must be one of: [#{answers}]. Please try again.") unless correct_answer
38
+ end
39
+ correct_answer
40
+ end
41
+
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,164 @@
1
+ require File.expand_path('../test_helper', File.dirname(__FILE__))
2
+
3
+ describe Ing do
4
+ include TestHelpers
5
+
6
+ def capture_run(args)
7
+ capture(:stdout) { Ing.run args }
8
+ end
9
+
10
+ def reset
11
+ Ing::Dispatcher.dispatched.clear
12
+ end
13
+
14
+ describe "#run" do
15
+
16
+ describe "no method or args given" do
17
+ before { reset }
18
+ subject { ["count_args"] }
19
+
20
+ it 'should run with expected output' do
21
+ assert_equal "CountArgs called with 0 args",
22
+ capture_run(subject).chomp
23
+ end
24
+
25
+ end
26
+
27
+ describe "method given with args" do
28
+ before { reset }
29
+ subject { ["amazing", "describe", "Malcolm"] }
30
+
31
+ it 'should run with expected output' do
32
+ assert_equal "Malcolm is amazing", capture_run(subject).chomp
33
+ end
34
+
35
+ end
36
+
37
+ describe "option args given" do
38
+ before { reset }
39
+ subject { ["amazing", "describe", "--forcefully", "Malcolm"] }
40
+
41
+ it 'should run with expected output' do
42
+ assert_equal "MALCOLM IS AMAZING", capture_run(subject).chomp
43
+ end
44
+
45
+ describe "and option args given at end" do
46
+ before { reset }
47
+ subject { ["amazing", "describe", "Malcolm", "--forcefully"] }
48
+
49
+ it 'should run with expected output' do
50
+ assert_equal "MALCOLM IS AMAZING", capture_run(subject).chomp
51
+ end
52
+ end
53
+
54
+ end
55
+
56
+ describe "unknown method given" do
57
+ before { reset }
58
+ subject { ["amazing", "write", "Malcolm"] }
59
+
60
+ it 'should raise error' do
61
+ assert_raises(::NoMethodError) { capture_run subject }
62
+ end
63
+
64
+ end
65
+
66
+ describe "undefined option given" do
67
+ before { reset }
68
+ subject { ["amazing", "describe", "Malcolm", "--times=3"] }
69
+
70
+ it 'should exit' do
71
+ assert_raises(::SystemExit) { capture_run(subject) }
72
+ end
73
+ end
74
+
75
+ describe "wrong number of args given" do
76
+ before { reset }
77
+ subject { ["amazing", "describe"] }
78
+
79
+ it 'should raise error' do
80
+ assert_raises(::ArgumentError) { capture_run subject }
81
+ end
82
+ end
83
+
84
+ describe "require boot option given" do
85
+ before { reset }
86
+ subject { ["-r", "./test/fixtures/require.ing",
87
+ "--require", "cgi",
88
+ "dynamic_require"
89
+ ]
90
+ }
91
+
92
+ it 'should load specified files and libraries' do
93
+ capture_run subject
94
+ DynamicRequire; CGI
95
+ assert true
96
+ end
97
+
98
+ end
99
+
100
+ describe "namespace boot option given" do
101
+ before { reset }
102
+ subject { ["--require=./test/fixtures/namespace.ing",
103
+ "-n", "some_base_namespace",
104
+ "one:two:three:echo", "call", "hello world"
105
+ ]
106
+ }
107
+
108
+ it 'should run with expected output' do
109
+ assert_equal "hello world", capture_run(subject).chomp
110
+ end
111
+
112
+ describe "and class not within namespace" do
113
+ before { reset }
114
+ subject { ["--require=./test/fixtures/namespace.ing",
115
+ "-n", "some_base_namespace",
116
+ "echo", "call", "hello world"
117
+ ]
118
+ }
119
+
120
+ it 'should raise error' do
121
+ assert_raises(::NameError) { capture_run(subject).chomp }
122
+ end
123
+
124
+ end
125
+
126
+ end
127
+
128
+ describe "dispatch to proc" do
129
+ before { reset }
130
+ subject { %w[p 1 2 3] }
131
+
132
+ P = lambda {|*args|
133
+ opts = (Hash === args.last ? args.pop : {})
134
+ args.reverse.each_with_index {|a,i| puts "#{i}:#{a}"}
135
+ }
136
+
137
+ it 'should run with expected output' do
138
+ log = capture_run(subject).chomp
139
+ assert_equal "0:3\n1:2\n2:1", log
140
+ end
141
+
142
+ end
143
+
144
+ end
145
+
146
+ describe "invoking within tasks" do
147
+ before { reset }
148
+ subject { ["invoking:counter", "one"] }
149
+
150
+ it 'should run with expected output' do
151
+ assert_equal "1\n2\n3\n", capture_run(subject)
152
+ end
153
+ end
154
+
155
+ describe "executing within tasks" do
156
+ before { reset }
157
+ subject { ["executing:counter", "one"] }
158
+
159
+ it 'should run with expected output' do
160
+ assert_equal "1\n2\n3\n3\n", capture_run(subject)
161
+ end
162
+ end
163
+
164
+ end
@@ -0,0 +1,209 @@
1
+ require File.expand_path('../spec_helper', File.dirname(__FILE__))
2
+ require File.expand_path("../../lib/ing/files", File.dirname(__FILE__))
3
+
4
+ describe Ing::Files::CreateFile do
5
+ include SpecHelpers
6
+
7
+ def reset
8
+ ARGV.replace []
9
+ ::FileUtils.rm_rf(destination_root)
10
+ end
11
+
12
+ def create_file(destination=nil, config={}, options={})
13
+ @base = MyCounter.new(options)
14
+ @base.destination_root = destination_root
15
+ @base.call 1,2
16
+ MyCounter.send(:define_method, :file_name, Proc.new {'rdoc'} )
17
+
18
+ @action = Ing::Files::CreateFile.new(@base, destination, "CONFIGURATION",
19
+ { :verbose => !@silence }.merge(config))
20
+ end
21
+
22
+ def invoke!
23
+ capture(:stdout){ @action.invoke! }
24
+ end
25
+
26
+ def revoke!
27
+ capture(:stdout){ @action.revoke! }
28
+ end
29
+
30
+ def silence!
31
+ @silence = true
32
+ end
33
+
34
+ # stubs multiple input responses from $stdin.gets
35
+ # not currently used
36
+ class StubInput
37
+
38
+ def initialize(expected)
39
+ @s = Array(expected)
40
+ end
41
+
42
+ def gets
43
+ @s.shift
44
+ end
45
+
46
+ def reply_for(stream=$stdin, &b)
47
+ stream.stub(:gets, self.method(:gets), &b)
48
+ end
49
+
50
+ end
51
+
52
+ describe "#invoke!" do
53
+ before { reset }
54
+
55
+ it "creates a file" do
56
+ create_file("doc/config.rb")
57
+ invoke!
58
+ assert File.exists?(File.join(destination_root, "doc/config.rb"))
59
+ end
60
+
61
+ it "does not create a file if pretending" do
62
+ create_file("doc/config.rb", {}, :pretend => true)
63
+ invoke!
64
+ refute File.exists?(File.join(destination_root, "doc/config.rb"))
65
+ end
66
+
67
+ it "shows created status to the user" do
68
+ create_file("doc/config.rb")
69
+ assert_equal " create doc/config.rb\n", invoke!
70
+ end
71
+
72
+ it "does not show any information if log status is false" do
73
+ silence!
74
+ create_file("doc/config.rb")
75
+ assert_empty invoke!
76
+ end
77
+
78
+ it "returns the given destination" do
79
+ capture(:stdout) do
80
+ assert_equal "doc/config.rb", create_file("doc/config.rb").invoke!
81
+ end
82
+ end
83
+
84
+ it "converts encoded instructions" do
85
+ create_file("doc/%file_name%.rb.tt")
86
+ invoke!
87
+ assert File.exists?(File.join(destination_root, "doc/rdoc.rb.tt"))
88
+ end
89
+
90
+ describe "when file exists" do
91
+
92
+ describe "and is identical" do
93
+ before do
94
+ reset
95
+ create_file("doc/config.rb")
96
+ invoke!
97
+ end
98
+
99
+ it "shows identical status" do
100
+ create_file("doc/config.rb")
101
+ invoke!
102
+ assert_equal " identical doc/config.rb\n", invoke!
103
+ end
104
+ end
105
+
106
+ describe "and is not identical" do
107
+ before do
108
+ reset
109
+ create_file("doc/config.rb")
110
+ invoke!
111
+ File.open(File.join(destination_root, 'doc/config.rb'), 'w'){ |f| f.write("FOO = 3") }
112
+ end
113
+
114
+ it "shows forced status to the user if force is given" do
115
+ refute create_file("doc/config.rb", {}, :force => true).identical?
116
+ assert_equal " force doc/config.rb\n", invoke!
117
+ end
118
+
119
+ it "shows skipped status to the user if skip is given" do
120
+ refute create_file("doc/config.rb", {}, :skip => true).identical?
121
+ assert_equal " skip doc/config.rb\n", invoke!
122
+ end
123
+
124
+ it "shows forced status to the user if force is configured" do
125
+ refute create_file("doc/config.rb", :force => true).identical?
126
+ assert_equal " force doc/config.rb\n", invoke!
127
+ end
128
+
129
+ it "shows skipped status to the user if skip is configured" do
130
+ refute create_file("doc/config.rb", :skip => true).identical?
131
+ assert_equal " skip doc/config.rb\n", invoke!
132
+ end
133
+
134
+ it "shows conflict status to ther user" do
135
+ refute create_file("doc/config.rb").identical?
136
+ file = File.join(destination_root, 'doc/config.rb')
137
+ content = nil
138
+ $stdin.stub(:gets,'s') do
139
+ content = invoke!
140
+ end
141
+ assert_match(/conflict doc\/config\.rb/, content)
142
+ assert_match(/Overwrite #{file}\? \(enter "h" for help\) \[Ynaqdh\]/, content)
143
+ assert_match(/skip doc\/config\.rb/, content)
144
+ end
145
+
146
+ it "creates the file if the file collision menu returns true" do
147
+ create_file("doc/config.rb")
148
+ $stdin.stub(:gets,'y') do
149
+ assert_match(/force doc\/config\.rb/, invoke!)
150
+ end
151
+ end
152
+
153
+ it "skips the file if the file collision menu returns false" do
154
+ create_file("doc/config.rb")
155
+ $stdin.stub(:gets,'n') do
156
+ assert_match(/skip doc\/config\.rb/, invoke!)
157
+ end
158
+ end
159
+
160
+ # Not sure how to do the mock method here without more flexible mocks....
161
+ # it "executes the block given to show file content" do
162
+ # create_file("doc/config.rb")
163
+ # $stdin.should_receive(:gets).and_return('d')
164
+ # $stdin.should_receive(:gets).and_return('n')
165
+ # @base.shell.should_receive(:system).with(/diff -u/)
166
+ # invoke!
167
+ # end
168
+
169
+ end
170
+ end
171
+ end
172
+
173
+ describe "#revoke!" do
174
+ before { reset }
175
+
176
+ it "removes the destination file" do
177
+ create_file("doc/config.rb")
178
+ invoke!
179
+ revoke!
180
+ refute File.exists?(@action.destination)
181
+ end
182
+
183
+ it "does not raise an error if the file does not exist" do
184
+ create_file("doc/config.rb")
185
+ revoke!
186
+ refute File.exists?(@action.destination)
187
+ end
188
+ end
189
+
190
+ describe "#exists?" do
191
+ before { reset }
192
+ it "returns true if the destination file exists" do
193
+ create_file("doc/config.rb")
194
+ refute @action.exists?
195
+ invoke!
196
+ assert @action.exists?
197
+ end
198
+ end
199
+
200
+ describe "#identical?" do
201
+ before { reset }
202
+ it "returns true if the destination file and is identical" do
203
+ create_file("doc/config.rb")
204
+ refute @action.identical?
205
+ invoke!
206
+ assert @action.identical?
207
+ end
208
+ end
209
+ end