github_cli 0.5.0 → 0.5.1

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 (41) hide show
  1. data/CHANGELOG.md +5 -0
  2. data/Gemfile.lock +1 -1
  3. data/Rakefile +4 -1
  4. data/github_cli.gemspec +3 -1
  5. data/lib/github_cli/dsl.rb +7 -3
  6. data/lib/github_cli/thor_ext.rb +1 -3
  7. data/lib/github_cli/vendor/thor/actions/create_file.rb +105 -0
  8. data/lib/github_cli/vendor/thor/actions/create_link.rb +57 -0
  9. data/lib/github_cli/vendor/thor/actions/directory.rb +98 -0
  10. data/lib/github_cli/vendor/thor/actions/empty_directory.rb +153 -0
  11. data/lib/github_cli/vendor/thor/actions/file_manipulation.rb +308 -0
  12. data/lib/github_cli/vendor/thor/actions/inject_into_file.rb +109 -0
  13. data/lib/github_cli/vendor/thor/actions.rb +318 -0
  14. data/lib/github_cli/vendor/thor/base.rb +641 -0
  15. data/lib/github_cli/vendor/thor/core_ext/dir_escape.rb +0 -0
  16. data/lib/github_cli/vendor/thor/core_ext/file_binary_read.rb +9 -0
  17. data/lib/github_cli/vendor/thor/core_ext/hash_with_indifferent_access.rb +75 -0
  18. data/lib/github_cli/vendor/thor/core_ext/ordered_hash.rb +100 -0
  19. data/lib/github_cli/vendor/thor/empty.txt +0 -0
  20. data/lib/github_cli/vendor/thor/error.rb +35 -0
  21. data/lib/github_cli/vendor/thor/group.rb +285 -0
  22. data/lib/github_cli/vendor/thor/invocation.rb +170 -0
  23. data/lib/github_cli/vendor/thor/parser/argument.rb +74 -0
  24. data/lib/github_cli/vendor/thor/parser/arguments.rb +171 -0
  25. data/lib/github_cli/vendor/thor/parser/option.rb +121 -0
  26. data/lib/github_cli/vendor/thor/parser/options.rb +178 -0
  27. data/lib/github_cli/vendor/thor/parser.rb +4 -0
  28. data/lib/github_cli/vendor/thor/rake_compat.rb +71 -0
  29. data/lib/github_cli/vendor/thor/runner.rb +321 -0
  30. data/lib/github_cli/vendor/thor/shell/basic.rb +389 -0
  31. data/lib/github_cli/vendor/thor/shell/color.rb +144 -0
  32. data/lib/github_cli/vendor/thor/shell/html.rb +123 -0
  33. data/lib/github_cli/vendor/thor/shell.rb +88 -0
  34. data/lib/github_cli/vendor/thor/task.rb +132 -0
  35. data/lib/github_cli/vendor/thor/util.rb +266 -0
  36. data/lib/github_cli/vendor/thor/version.rb +3 -0
  37. data/lib/github_cli/vendor/thor.rb +379 -0
  38. data/lib/github_cli/vendor.rb +7 -5
  39. data/lib/github_cli/version.rb +3 -1
  40. metadata +45 -22
  41. data/bin/ghc +0 -2
@@ -0,0 +1,308 @@
1
+ require 'erb'
2
+ require 'open-uri'
3
+
4
+ class Thor
5
+ module Actions
6
+
7
+ # Copies the file from the relative source to the relative destination. If
8
+ # the destination is not given it's assumed to be equal to the source.
9
+ #
10
+ # ==== Parameters
11
+ # source<String>:: the relative path to the source root.
12
+ # destination<String>:: the relative path to the destination root.
13
+ # config<Hash>:: give :verbose => false to not log the status.
14
+ #
15
+ # ==== Examples
16
+ #
17
+ # copy_file "README", "doc/README"
18
+ #
19
+ # copy_file "doc/README"
20
+ #
21
+ def copy_file(source, *args, &block)
22
+ config = args.last.is_a?(Hash) ? args.pop : {}
23
+ destination = args.first || source
24
+ source = File.expand_path(find_in_source_paths(source.to_s))
25
+
26
+ create_file destination, nil, config do
27
+ content = File.binread(source)
28
+ content = block.call(content) if block
29
+ content
30
+ end
31
+ end
32
+
33
+ # Links the file from the relative source to the relative destination. If
34
+ # the destination is not given it's assumed to be equal to the source.
35
+ #
36
+ # ==== Parameters
37
+ # source<String>:: the relative path to the source root.
38
+ # destination<String>:: the relative path to the destination root.
39
+ # config<Hash>:: give :verbose => false to not log the status.
40
+ #
41
+ # ==== Examples
42
+ #
43
+ # link_file "README", "doc/README"
44
+ #
45
+ # link_file "doc/README"
46
+ #
47
+ def link_file(source, *args, &block)
48
+ config = args.last.is_a?(Hash) ? args.pop : {}
49
+ destination = args.first || source
50
+ source = File.expand_path(find_in_source_paths(source.to_s))
51
+
52
+ create_link destination, source, config
53
+ end
54
+
55
+ # Gets the content at the given address and places it at the given relative
56
+ # destination. If a block is given instead of destination, the content of
57
+ # the url is yielded and used as location.
58
+ #
59
+ # ==== Parameters
60
+ # source<String>:: the address of the given content.
61
+ # destination<String>:: the relative path to the destination root.
62
+ # config<Hash>:: give :verbose => false to not log the status.
63
+ #
64
+ # ==== Examples
65
+ #
66
+ # get "http://gist.github.com/103208", "doc/README"
67
+ #
68
+ # get "http://gist.github.com/103208" do |content|
69
+ # content.split("\n").first
70
+ # end
71
+ #
72
+ def get(source, *args, &block)
73
+ config = args.last.is_a?(Hash) ? args.pop : {}
74
+ destination = args.first
75
+
76
+ source = File.expand_path(find_in_source_paths(source.to_s)) unless source =~ /^https?\:\/\//
77
+ render = open(source) {|input| input.binmode.read }
78
+
79
+ destination ||= if block_given?
80
+ block.arity == 1 ? block.call(render) : block.call
81
+ else
82
+ File.basename(source)
83
+ end
84
+
85
+ create_file destination, render, config
86
+ end
87
+
88
+ # Gets an ERB template at the relative source, executes it and makes a copy
89
+ # at the relative destination. If the destination is not given it's assumed
90
+ # to be equal to the source removing .tt from the filename.
91
+ #
92
+ # ==== Parameters
93
+ # source<String>:: the relative path to the source root.
94
+ # destination<String>:: the relative path to the destination root.
95
+ # config<Hash>:: give :verbose => false to not log the status.
96
+ #
97
+ # ==== Examples
98
+ #
99
+ # template "README", "doc/README"
100
+ #
101
+ # template "doc/README"
102
+ #
103
+ def template(source, *args, &block)
104
+ config = args.last.is_a?(Hash) ? args.pop : {}
105
+ destination = args.first || source.sub(/\.tt$/, '')
106
+
107
+ source = File.expand_path(find_in_source_paths(source.to_s))
108
+ context = instance_eval('binding')
109
+
110
+ create_file destination, nil, config do
111
+ content = ERB.new(::File.binread(source), nil, '-', '@output_buffer').result(context)
112
+ content = block.call(content) if block
113
+ content
114
+ end
115
+ end
116
+
117
+ # Changes the mode of the given file or directory.
118
+ #
119
+ # ==== Parameters
120
+ # mode<Integer>:: the file mode
121
+ # path<String>:: the name of the file to change mode
122
+ # config<Hash>:: give :verbose => false to not log the status.
123
+ #
124
+ # ==== Example
125
+ #
126
+ # chmod "script/*", 0755
127
+ #
128
+ def chmod(path, mode, config={})
129
+ return unless behavior == :invoke
130
+ path = File.expand_path(path, destination_root)
131
+ say_status :chmod, relative_to_original_destination_root(path), config.fetch(:verbose, true)
132
+ FileUtils.chmod_R(mode, path) unless options[:pretend]
133
+ end
134
+
135
+ # Prepend text to a file. Since it depends on insert_into_file, it's reversible.
136
+ #
137
+ # ==== Parameters
138
+ # path<String>:: path of the file to be changed
139
+ # data<String>:: the data to prepend to the file, can be also given as a block.
140
+ # config<Hash>:: give :verbose => false to not log the status.
141
+ #
142
+ # ==== Example
143
+ #
144
+ # prepend_to_file 'config/environments/test.rb', 'config.gem "rspec"'
145
+ #
146
+ # prepend_to_file 'config/environments/test.rb' do
147
+ # 'config.gem "rspec"'
148
+ # end
149
+ #
150
+ def prepend_to_file(path, *args, &block)
151
+ config = args.last.is_a?(Hash) ? args.pop : {}
152
+ config.merge!(:after => /\A/)
153
+ insert_into_file(path, *(args << config), &block)
154
+ end
155
+ alias_method :prepend_file, :prepend_to_file
156
+
157
+ # Append text to a file. Since it depends on insert_into_file, it's reversible.
158
+ #
159
+ # ==== Parameters
160
+ # path<String>:: path of the file to be changed
161
+ # data<String>:: the data to append to the file, can be also given as a block.
162
+ # config<Hash>:: give :verbose => false to not log the status.
163
+ #
164
+ # ==== Example
165
+ #
166
+ # append_to_file 'config/environments/test.rb', 'config.gem "rspec"'
167
+ #
168
+ # append_to_file 'config/environments/test.rb' do
169
+ # 'config.gem "rspec"'
170
+ # end
171
+ #
172
+ def append_to_file(path, *args, &block)
173
+ config = args.last.is_a?(Hash) ? args.pop : {}
174
+ config.merge!(:before => /\z/)
175
+ insert_into_file(path, *(args << config), &block)
176
+ end
177
+ alias_method :append_file, :append_to_file
178
+
179
+ # Injects text right after the class definition. Since it depends on
180
+ # insert_into_file, it's reversible.
181
+ #
182
+ # ==== Parameters
183
+ # path<String>:: path of the file to be changed
184
+ # klass<String|Class>:: the class to be manipulated
185
+ # data<String>:: the data to append to the class, can be also given as a block.
186
+ # config<Hash>:: give :verbose => false to not log the status.
187
+ #
188
+ # ==== Examples
189
+ #
190
+ # inject_into_class "app/controllers/application_controller.rb", ApplicationController, " filter_parameter :password\n"
191
+ #
192
+ # inject_into_class "app/controllers/application_controller.rb", ApplicationController do
193
+ # " filter_parameter :password\n"
194
+ # end
195
+ #
196
+ def inject_into_class(path, klass, *args, &block)
197
+ config = args.last.is_a?(Hash) ? args.pop : {}
198
+ config.merge!(:after => /class #{klass}\n|class #{klass} .*\n/)
199
+ insert_into_file(path, *(args << config), &block)
200
+ end
201
+
202
+ # Run a regular expression replacement on a file.
203
+ #
204
+ # ==== Parameters
205
+ # path<String>:: path of the file to be changed
206
+ # flag<Regexp|String>:: the regexp or string to be replaced
207
+ # replacement<String>:: the replacement, can be also given as a block
208
+ # config<Hash>:: give :verbose => false to not log the status.
209
+ #
210
+ # ==== Example
211
+ #
212
+ # gsub_file 'app/controllers/application_controller.rb', /#\s*(filter_parameter_logging :password)/, '\1'
213
+ #
214
+ # gsub_file 'README', /rake/, :green do |match|
215
+ # match << " no more. Use thor!"
216
+ # end
217
+ #
218
+ def gsub_file(path, flag, *args, &block)
219
+ return unless behavior == :invoke
220
+ config = args.last.is_a?(Hash) ? args.pop : {}
221
+
222
+ path = File.expand_path(path, destination_root)
223
+ say_status :gsub, relative_to_original_destination_root(path), config.fetch(:verbose, true)
224
+
225
+ unless options[:pretend]
226
+ content = File.binread(path)
227
+ content.gsub!(flag, *args, &block)
228
+ File.open(path, 'wb') { |file| file.write(content) }
229
+ end
230
+ end
231
+
232
+ # Uncomment all lines matching a given regex. It will leave the space
233
+ # which existed before the comment hash in tact but will remove any spacing
234
+ # between the comment hash and the beginning of the line.
235
+ #
236
+ # ==== Parameters
237
+ # path<String>:: path of the file to be changed
238
+ # flag<Regexp|String>:: the regexp or string used to decide which lines to uncomment
239
+ # config<Hash>:: give :verbose => false to not log the status.
240
+ #
241
+ # ==== Example
242
+ #
243
+ # uncomment_lines 'config/initializers/session_store.rb', /active_record/
244
+ #
245
+ def uncomment_lines(path, flag, *args)
246
+ flag = flag.respond_to?(:source) ? flag.source : flag
247
+
248
+ gsub_file(path, /^(\s*)#\s*(.*#{flag})/, '\1\2', *args)
249
+ end
250
+
251
+ # Comment all lines matching a given regex. It will leave the space
252
+ # which existed before the beginning of the line in tact and will insert
253
+ # a single space after the comment hash.
254
+ #
255
+ # ==== Parameters
256
+ # path<String>:: path of the file to be changed
257
+ # flag<Regexp|String>:: the regexp or string used to decide which lines to comment
258
+ # config<Hash>:: give :verbose => false to not log the status.
259
+ #
260
+ # ==== Example
261
+ #
262
+ # comment_lines 'config/initializers/session_store.rb', /cookie_store/
263
+ #
264
+ def comment_lines(path, flag, *args)
265
+ flag = flag.respond_to?(:source) ? flag.source : flag
266
+
267
+ gsub_file(path, /^(\s*)([^#|\n]*#{flag})/, '\1# \2', *args)
268
+ end
269
+
270
+ # Removes a file at the given location.
271
+ #
272
+ # ==== Parameters
273
+ # path<String>:: path of the file to be changed
274
+ # config<Hash>:: give :verbose => false to not log the status.
275
+ #
276
+ # ==== Example
277
+ #
278
+ # remove_file 'README'
279
+ # remove_file 'app/controllers/application_controller.rb'
280
+ #
281
+ def remove_file(path, config={})
282
+ return unless behavior == :invoke
283
+ path = File.expand_path(path, destination_root)
284
+
285
+ say_status :remove, relative_to_original_destination_root(path), config.fetch(:verbose, true)
286
+ ::FileUtils.rm_rf(path) if !options[:pretend] && File.exists?(path)
287
+ end
288
+ alias :remove_dir :remove_file
289
+
290
+ private
291
+ attr_accessor :output_buffer
292
+ def concat(string)
293
+ @output_buffer.concat(string)
294
+ end
295
+
296
+ def capture(*args, &block)
297
+ with_output_buffer { block.call(*args) }
298
+ end
299
+
300
+ def with_output_buffer(buf = '') #:nodoc:
301
+ self.output_buffer, old_buffer = buf, output_buffer
302
+ yield
303
+ output_buffer
304
+ ensure
305
+ self.output_buffer = old_buffer
306
+ end
307
+ end
308
+ end
@@ -0,0 +1,109 @@
1
+ require 'thor/actions/empty_directory'
2
+
3
+ class Thor
4
+ module Actions
5
+
6
+ # Injects the given content into a file. Different from gsub_file, this
7
+ # method is reversible.
8
+ #
9
+ # ==== Parameters
10
+ # destination<String>:: Relative path to the destination root
11
+ # data<String>:: Data to add to the file. Can be given as a block.
12
+ # config<Hash>:: give :verbose => false to not log the status and the flag
13
+ # for injection (:after or :before) or :force => true for
14
+ # insert two or more times the same content.
15
+ #
16
+ # ==== Examples
17
+ #
18
+ # insert_into_file "config/environment.rb", "config.gem :thor", :after => "Rails::Initializer.run do |config|\n"
19
+ #
20
+ # insert_into_file "config/environment.rb", :after => "Rails::Initializer.run do |config|\n" do
21
+ # gems = ask "Which gems would you like to add?"
22
+ # gems.split(" ").map{ |gem| " config.gem :#{gem}" }.join("\n")
23
+ # end
24
+ #
25
+ def insert_into_file(destination, *args, &block)
26
+ if block_given?
27
+ data, config = block, args.shift
28
+ else
29
+ data, config = args.shift, args.shift
30
+ end
31
+ action InjectIntoFile.new(self, destination, data, config)
32
+ end
33
+ alias_method :inject_into_file, :insert_into_file
34
+
35
+ class InjectIntoFile < EmptyDirectory #:nodoc:
36
+ attr_reader :replacement, :flag, :behavior
37
+
38
+ def initialize(base, destination, data, config)
39
+ super(base, destination, { :verbose => true }.merge(config))
40
+
41
+ @behavior, @flag = if @config.key?(:after)
42
+ [:after, @config.delete(:after)]
43
+ else
44
+ [:before, @config.delete(:before)]
45
+ end
46
+
47
+ @replacement = data.is_a?(Proc) ? data.call : data
48
+ @flag = Regexp.escape(@flag) unless @flag.is_a?(Regexp)
49
+ end
50
+
51
+ def invoke!
52
+ say_status :invoke
53
+
54
+ content = if @behavior == :after
55
+ '\0' + replacement
56
+ else
57
+ replacement + '\0'
58
+ end
59
+
60
+ replace!(/#{flag}/, content, config[:force])
61
+ end
62
+
63
+ def revoke!
64
+ say_status :revoke
65
+
66
+ regexp = if @behavior == :after
67
+ content = '\1\2'
68
+ /(#{flag})(.*)(#{Regexp.escape(replacement)})/m
69
+ else
70
+ content = '\2\3'
71
+ /(#{Regexp.escape(replacement)})(.*)(#{flag})/m
72
+ end
73
+
74
+ replace!(regexp, content, true)
75
+ end
76
+
77
+ protected
78
+
79
+ def say_status(behavior)
80
+ status = if behavior == :invoke
81
+ if flag == /\A/
82
+ :prepend
83
+ elsif flag == /\z/
84
+ :append
85
+ else
86
+ :insert
87
+ end
88
+ else
89
+ :subtract
90
+ end
91
+
92
+ super(status, config[:verbose])
93
+ end
94
+
95
+ # Adds the content to the file.
96
+ #
97
+ def replace!(regexp, string, force)
98
+ unless base.options[:pretend]
99
+ content = File.binread(destination)
100
+ if force || !content.include?(replacement)
101
+ content.gsub!(regexp, string)
102
+ File.open(destination, 'wb') { |file| file.write(content) }
103
+ end
104
+ end
105
+ end
106
+
107
+ end
108
+ end
109
+ end