saikouda 0.1.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.
Files changed (228) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +8 -0
  3. data/CODE_OF_CONDUCT.md +74 -0
  4. data/Gemfile +5 -0
  5. data/Gemfile.lock +22 -0
  6. data/LICENSE.txt +21 -0
  7. data/README.md +43 -0
  8. data/Rakefile +2 -0
  9. data/bin/console +14 -0
  10. data/bin/setup +8 -0
  11. data/exe/saikouda +5 -0
  12. data/lib/saikouda/cli.rb +106 -0
  13. data/lib/saikouda/version.rb +3 -0
  14. data/lib/saikouda.rb +7 -0
  15. data/saikouda.gemspec +34 -0
  16. data/vendor/bundle/bin/rake +27 -0
  17. data/vendor/bundle/bin/saikouda +27 -0
  18. data/vendor/bundle/bin/thor +27 -0
  19. data/vendor/bundle/cache/rake-10.5.0.gem +0 -0
  20. data/vendor/bundle/cache/thor-0.20.3.gem +0 -0
  21. data/vendor/bundle/gems/rake-10.5.0/.autotest +7 -0
  22. data/vendor/bundle/gems/rake-10.5.0/.rubocop.yml +27 -0
  23. data/vendor/bundle/gems/rake-10.5.0/.togglerc +7 -0
  24. data/vendor/bundle/gems/rake-10.5.0/CONTRIBUTING.rdoc +38 -0
  25. data/vendor/bundle/gems/rake-10.5.0/History.rdoc +659 -0
  26. data/vendor/bundle/gems/rake-10.5.0/MIT-LICENSE +21 -0
  27. data/vendor/bundle/gems/rake-10.5.0/Manifest.txt +166 -0
  28. data/vendor/bundle/gems/rake-10.5.0/README.rdoc +139 -0
  29. data/vendor/bundle/gems/rake-10.5.0/Rakefile +81 -0
  30. data/vendor/bundle/gems/rake-10.5.0/bin/rake +33 -0
  31. data/vendor/bundle/gems/rake-10.5.0/doc/command_line_usage.rdoc +158 -0
  32. data/vendor/bundle/gems/rake-10.5.0/doc/example/Rakefile1 +38 -0
  33. data/vendor/bundle/gems/rake-10.5.0/doc/example/Rakefile2 +35 -0
  34. data/vendor/bundle/gems/rake-10.5.0/doc/example/a.c +6 -0
  35. data/vendor/bundle/gems/rake-10.5.0/doc/example/b.c +6 -0
  36. data/vendor/bundle/gems/rake-10.5.0/doc/example/main.c +11 -0
  37. data/vendor/bundle/gems/rake-10.5.0/doc/glossary.rdoc +42 -0
  38. data/vendor/bundle/gems/rake-10.5.0/doc/jamis.rb +591 -0
  39. data/vendor/bundle/gems/rake-10.5.0/doc/proto_rake.rdoc +127 -0
  40. data/vendor/bundle/gems/rake-10.5.0/doc/rake.1 +141 -0
  41. data/vendor/bundle/gems/rake-10.5.0/doc/rakefile.rdoc +624 -0
  42. data/vendor/bundle/gems/rake-10.5.0/doc/rational.rdoc +151 -0
  43. data/vendor/bundle/gems/rake-10.5.0/doc/release_notes/rake-0.4.14.rdoc +23 -0
  44. data/vendor/bundle/gems/rake-10.5.0/doc/release_notes/rake-0.4.15.rdoc +35 -0
  45. data/vendor/bundle/gems/rake-10.5.0/doc/release_notes/rake-0.5.0.rdoc +53 -0
  46. data/vendor/bundle/gems/rake-10.5.0/doc/release_notes/rake-0.5.3.rdoc +78 -0
  47. data/vendor/bundle/gems/rake-10.5.0/doc/release_notes/rake-0.5.4.rdoc +46 -0
  48. data/vendor/bundle/gems/rake-10.5.0/doc/release_notes/rake-0.6.0.rdoc +141 -0
  49. data/vendor/bundle/gems/rake-10.5.0/doc/release_notes/rake-0.7.0.rdoc +119 -0
  50. data/vendor/bundle/gems/rake-10.5.0/doc/release_notes/rake-0.7.1.rdoc +59 -0
  51. data/vendor/bundle/gems/rake-10.5.0/doc/release_notes/rake-0.7.2.rdoc +121 -0
  52. data/vendor/bundle/gems/rake-10.5.0/doc/release_notes/rake-0.7.3.rdoc +47 -0
  53. data/vendor/bundle/gems/rake-10.5.0/doc/release_notes/rake-0.8.0.rdoc +114 -0
  54. data/vendor/bundle/gems/rake-10.5.0/doc/release_notes/rake-0.8.2.rdoc +165 -0
  55. data/vendor/bundle/gems/rake-10.5.0/doc/release_notes/rake-0.8.3.rdoc +112 -0
  56. data/vendor/bundle/gems/rake-10.5.0/doc/release_notes/rake-0.8.4.rdoc +147 -0
  57. data/vendor/bundle/gems/rake-10.5.0/doc/release_notes/rake-0.8.5.rdoc +53 -0
  58. data/vendor/bundle/gems/rake-10.5.0/doc/release_notes/rake-0.8.6.rdoc +37 -0
  59. data/vendor/bundle/gems/rake-10.5.0/doc/release_notes/rake-0.8.7.rdoc +55 -0
  60. data/vendor/bundle/gems/rake-10.5.0/doc/release_notes/rake-0.9.0.rdoc +112 -0
  61. data/vendor/bundle/gems/rake-10.5.0/doc/release_notes/rake-0.9.1.rdoc +52 -0
  62. data/vendor/bundle/gems/rake-10.5.0/doc/release_notes/rake-0.9.2.2.rdoc +55 -0
  63. data/vendor/bundle/gems/rake-10.5.0/doc/release_notes/rake-0.9.2.rdoc +49 -0
  64. data/vendor/bundle/gems/rake-10.5.0/doc/release_notes/rake-0.9.3.rdoc +102 -0
  65. data/vendor/bundle/gems/rake-10.5.0/doc/release_notes/rake-0.9.4.rdoc +60 -0
  66. data/vendor/bundle/gems/rake-10.5.0/doc/release_notes/rake-0.9.5.rdoc +55 -0
  67. data/vendor/bundle/gems/rake-10.5.0/doc/release_notes/rake-0.9.6.rdoc +64 -0
  68. data/vendor/bundle/gems/rake-10.5.0/doc/release_notes/rake-10.0.0.rdoc +178 -0
  69. data/vendor/bundle/gems/rake-10.5.0/doc/release_notes/rake-10.0.1.rdoc +58 -0
  70. data/vendor/bundle/gems/rake-10.5.0/doc/release_notes/rake-10.0.2.rdoc +53 -0
  71. data/vendor/bundle/gems/rake-10.5.0/doc/release_notes/rake-10.0.3.rdoc +191 -0
  72. data/vendor/bundle/gems/rake-10.5.0/doc/release_notes/rake-10.1.0.rdoc +61 -0
  73. data/vendor/bundle/gems/rake-10.5.0/lib/rake/alt_system.rb +110 -0
  74. data/vendor/bundle/gems/rake-10.5.0/lib/rake/application.rb +790 -0
  75. data/vendor/bundle/gems/rake-10.5.0/lib/rake/backtrace.rb +23 -0
  76. data/vendor/bundle/gems/rake-10.5.0/lib/rake/clean.rb +76 -0
  77. data/vendor/bundle/gems/rake-10.5.0/lib/rake/cloneable.rb +16 -0
  78. data/vendor/bundle/gems/rake-10.5.0/lib/rake/contrib/.document +1 -0
  79. data/vendor/bundle/gems/rake-10.5.0/lib/rake/contrib/compositepublisher.rb +21 -0
  80. data/vendor/bundle/gems/rake-10.5.0/lib/rake/contrib/ftptools.rb +137 -0
  81. data/vendor/bundle/gems/rake-10.5.0/lib/rake/contrib/publisher.rb +81 -0
  82. data/vendor/bundle/gems/rake-10.5.0/lib/rake/contrib/rubyforgepublisher.rb +18 -0
  83. data/vendor/bundle/gems/rake-10.5.0/lib/rake/contrib/sshpublisher.rb +61 -0
  84. data/vendor/bundle/gems/rake-10.5.0/lib/rake/contrib/sys.rb +4 -0
  85. data/vendor/bundle/gems/rake-10.5.0/lib/rake/cpu_counter.rb +125 -0
  86. data/vendor/bundle/gems/rake-10.5.0/lib/rake/default_loader.rb +14 -0
  87. data/vendor/bundle/gems/rake-10.5.0/lib/rake/dsl_definition.rb +201 -0
  88. data/vendor/bundle/gems/rake-10.5.0/lib/rake/early_time.rb +21 -0
  89. data/vendor/bundle/gems/rake-10.5.0/lib/rake/ext/core.rb +25 -0
  90. data/vendor/bundle/gems/rake-10.5.0/lib/rake/ext/module.rb +2 -0
  91. data/vendor/bundle/gems/rake-10.5.0/lib/rake/ext/pathname.rb +25 -0
  92. data/vendor/bundle/gems/rake-10.5.0/lib/rake/ext/string.rb +175 -0
  93. data/vendor/bundle/gems/rake-10.5.0/lib/rake/ext/time.rb +18 -0
  94. data/vendor/bundle/gems/rake-10.5.0/lib/rake/file_creation_task.rb +24 -0
  95. data/vendor/bundle/gems/rake-10.5.0/lib/rake/file_list.rb +428 -0
  96. data/vendor/bundle/gems/rake-10.5.0/lib/rake/file_task.rb +46 -0
  97. data/vendor/bundle/gems/rake-10.5.0/lib/rake/file_utils.rb +128 -0
  98. data/vendor/bundle/gems/rake-10.5.0/lib/rake/file_utils_ext.rb +144 -0
  99. data/vendor/bundle/gems/rake-10.5.0/lib/rake/gempackagetask.rb +4 -0
  100. data/vendor/bundle/gems/rake-10.5.0/lib/rake/invocation_chain.rb +56 -0
  101. data/vendor/bundle/gems/rake-10.5.0/lib/rake/invocation_exception_mixin.rb +16 -0
  102. data/vendor/bundle/gems/rake-10.5.0/lib/rake/late_time.rb +17 -0
  103. data/vendor/bundle/gems/rake-10.5.0/lib/rake/linked_list.rb +103 -0
  104. data/vendor/bundle/gems/rake-10.5.0/lib/rake/loaders/makefile.rb +53 -0
  105. data/vendor/bundle/gems/rake-10.5.0/lib/rake/multi_task.rb +13 -0
  106. data/vendor/bundle/gems/rake-10.5.0/lib/rake/name_space.rb +38 -0
  107. data/vendor/bundle/gems/rake-10.5.0/lib/rake/packagetask.rb +199 -0
  108. data/vendor/bundle/gems/rake-10.5.0/lib/rake/pathmap.rb +3 -0
  109. data/vendor/bundle/gems/rake-10.5.0/lib/rake/phony.rb +15 -0
  110. data/vendor/bundle/gems/rake-10.5.0/lib/rake/private_reader.rb +20 -0
  111. data/vendor/bundle/gems/rake-10.5.0/lib/rake/promise.rb +99 -0
  112. data/vendor/bundle/gems/rake-10.5.0/lib/rake/pseudo_status.rb +29 -0
  113. data/vendor/bundle/gems/rake-10.5.0/lib/rake/rake_module.rb +38 -0
  114. data/vendor/bundle/gems/rake-10.5.0/lib/rake/rake_test_loader.rb +22 -0
  115. data/vendor/bundle/gems/rake-10.5.0/lib/rake/rdoctask.rb +4 -0
  116. data/vendor/bundle/gems/rake-10.5.0/lib/rake/ruby182_test_unit_fix.rb +29 -0
  117. data/vendor/bundle/gems/rake-10.5.0/lib/rake/rule_recursion_overflow_error.rb +20 -0
  118. data/vendor/bundle/gems/rake-10.5.0/lib/rake/runtest.rb +27 -0
  119. data/vendor/bundle/gems/rake-10.5.0/lib/rake/scope.rb +42 -0
  120. data/vendor/bundle/gems/rake-10.5.0/lib/rake/task.rb +383 -0
  121. data/vendor/bundle/gems/rake-10.5.0/lib/rake/task_argument_error.rb +7 -0
  122. data/vendor/bundle/gems/rake-10.5.0/lib/rake/task_arguments.rb +98 -0
  123. data/vendor/bundle/gems/rake-10.5.0/lib/rake/task_manager.rb +307 -0
  124. data/vendor/bundle/gems/rake-10.5.0/lib/rake/tasklib.rb +24 -0
  125. data/vendor/bundle/gems/rake-10.5.0/lib/rake/testtask.rb +213 -0
  126. data/vendor/bundle/gems/rake-10.5.0/lib/rake/thread_history_display.rb +48 -0
  127. data/vendor/bundle/gems/rake-10.5.0/lib/rake/thread_pool.rb +164 -0
  128. data/vendor/bundle/gems/rake-10.5.0/lib/rake/trace_output.rb +22 -0
  129. data/vendor/bundle/gems/rake-10.5.0/lib/rake/version.rb +7 -0
  130. data/vendor/bundle/gems/rake-10.5.0/lib/rake/win32.rb +56 -0
  131. data/vendor/bundle/gems/rake-10.5.0/lib/rake.rb +79 -0
  132. data/vendor/bundle/gems/rake-10.5.0/rakelib/publish.rake +20 -0
  133. data/vendor/bundle/gems/rake-10.5.0/rakelib/test_times.rake +25 -0
  134. data/vendor/bundle/gems/rake-10.5.0/test/file_creation.rb +34 -0
  135. data/vendor/bundle/gems/rake-10.5.0/test/helper.rb +129 -0
  136. data/vendor/bundle/gems/rake-10.5.0/test/support/rakefile_definitions.rb +478 -0
  137. data/vendor/bundle/gems/rake-10.5.0/test/support/ruby_runner.rb +34 -0
  138. data/vendor/bundle/gems/rake-10.5.0/test/test_private_reader.rb +42 -0
  139. data/vendor/bundle/gems/rake-10.5.0/test/test_rake.rb +40 -0
  140. data/vendor/bundle/gems/rake-10.5.0/test/test_rake_application.rb +643 -0
  141. data/vendor/bundle/gems/rake-10.5.0/test/test_rake_application_options.rb +468 -0
  142. data/vendor/bundle/gems/rake-10.5.0/test/test_rake_backtrace.rb +119 -0
  143. data/vendor/bundle/gems/rake-10.5.0/test/test_rake_clean.rb +61 -0
  144. data/vendor/bundle/gems/rake-10.5.0/test/test_rake_cpu_counter.rb +68 -0
  145. data/vendor/bundle/gems/rake-10.5.0/test/test_rake_definitions.rb +84 -0
  146. data/vendor/bundle/gems/rake-10.5.0/test/test_rake_directory_task.rb +76 -0
  147. data/vendor/bundle/gems/rake-10.5.0/test/test_rake_dsl.rb +40 -0
  148. data/vendor/bundle/gems/rake-10.5.0/test/test_rake_early_time.rb +31 -0
  149. data/vendor/bundle/gems/rake-10.5.0/test/test_rake_extension.rb +59 -0
  150. data/vendor/bundle/gems/rake-10.5.0/test/test_rake_file_creation_task.rb +56 -0
  151. data/vendor/bundle/gems/rake-10.5.0/test/test_rake_file_list.rb +670 -0
  152. data/vendor/bundle/gems/rake-10.5.0/test/test_rake_file_list_path_map.rb +8 -0
  153. data/vendor/bundle/gems/rake-10.5.0/test/test_rake_file_task.rb +197 -0
  154. data/vendor/bundle/gems/rake-10.5.0/test/test_rake_file_utils.rb +314 -0
  155. data/vendor/bundle/gems/rake-10.5.0/test/test_rake_ftp_file.rb +74 -0
  156. data/vendor/bundle/gems/rake-10.5.0/test/test_rake_functional.rb +482 -0
  157. data/vendor/bundle/gems/rake-10.5.0/test/test_rake_invocation_chain.rb +64 -0
  158. data/vendor/bundle/gems/rake-10.5.0/test/test_rake_late_time.rb +18 -0
  159. data/vendor/bundle/gems/rake-10.5.0/test/test_rake_linked_list.rb +84 -0
  160. data/vendor/bundle/gems/rake-10.5.0/test/test_rake_makefile_loader.rb +46 -0
  161. data/vendor/bundle/gems/rake-10.5.0/test/test_rake_multi_task.rb +64 -0
  162. data/vendor/bundle/gems/rake-10.5.0/test/test_rake_name_space.rb +57 -0
  163. data/vendor/bundle/gems/rake-10.5.0/test/test_rake_package_task.rb +79 -0
  164. data/vendor/bundle/gems/rake-10.5.0/test/test_rake_path_map.rb +168 -0
  165. data/vendor/bundle/gems/rake-10.5.0/test/test_rake_path_map_explode.rb +34 -0
  166. data/vendor/bundle/gems/rake-10.5.0/test/test_rake_path_map_partial.rb +18 -0
  167. data/vendor/bundle/gems/rake-10.5.0/test/test_rake_pathname_extensions.rb +15 -0
  168. data/vendor/bundle/gems/rake-10.5.0/test/test_rake_pseudo_status.rb +21 -0
  169. data/vendor/bundle/gems/rake-10.5.0/test/test_rake_rake_test_loader.rb +20 -0
  170. data/vendor/bundle/gems/rake-10.5.0/test/test_rake_reduce_compat.rb +26 -0
  171. data/vendor/bundle/gems/rake-10.5.0/test/test_rake_require.rb +40 -0
  172. data/vendor/bundle/gems/rake-10.5.0/test/test_rake_rules.rb +388 -0
  173. data/vendor/bundle/gems/rake-10.5.0/test/test_rake_scope.rb +44 -0
  174. data/vendor/bundle/gems/rake-10.5.0/test/test_rake_task.rb +393 -0
  175. data/vendor/bundle/gems/rake-10.5.0/test/test_rake_task_argument_parsing.rb +119 -0
  176. data/vendor/bundle/gems/rake-10.5.0/test/test_rake_task_arguments.rb +127 -0
  177. data/vendor/bundle/gems/rake-10.5.0/test/test_rake_task_lib.rb +9 -0
  178. data/vendor/bundle/gems/rake-10.5.0/test/test_rake_task_manager.rb +178 -0
  179. data/vendor/bundle/gems/rake-10.5.0/test/test_rake_task_manager_argument_resolution.rb +19 -0
  180. data/vendor/bundle/gems/rake-10.5.0/test/test_rake_task_with_arguments.rb +172 -0
  181. data/vendor/bundle/gems/rake-10.5.0/test/test_rake_test_task.rb +146 -0
  182. data/vendor/bundle/gems/rake-10.5.0/test/test_rake_thread_pool.rb +145 -0
  183. data/vendor/bundle/gems/rake-10.5.0/test/test_rake_top_level_functions.rb +71 -0
  184. data/vendor/bundle/gems/rake-10.5.0/test/test_rake_win32.rb +72 -0
  185. data/vendor/bundle/gems/rake-10.5.0/test/test_thread_history_display.rb +101 -0
  186. data/vendor/bundle/gems/rake-10.5.0/test/test_trace_output.rb +52 -0
  187. data/vendor/bundle/gems/thor-0.20.3/.document +5 -0
  188. data/vendor/bundle/gems/thor-0.20.3/CHANGELOG.md +204 -0
  189. data/vendor/bundle/gems/thor-0.20.3/CONTRIBUTING.md +15 -0
  190. data/vendor/bundle/gems/thor-0.20.3/LICENSE.md +20 -0
  191. data/vendor/bundle/gems/thor-0.20.3/README.md +51 -0
  192. data/vendor/bundle/gems/thor-0.20.3/bin/thor +6 -0
  193. data/vendor/bundle/gems/thor-0.20.3/lib/thor/actions/create_file.rb +104 -0
  194. data/vendor/bundle/gems/thor-0.20.3/lib/thor/actions/create_link.rb +60 -0
  195. data/vendor/bundle/gems/thor-0.20.3/lib/thor/actions/directory.rb +118 -0
  196. data/vendor/bundle/gems/thor-0.20.3/lib/thor/actions/empty_directory.rb +143 -0
  197. data/vendor/bundle/gems/thor-0.20.3/lib/thor/actions/file_manipulation.rb +373 -0
  198. data/vendor/bundle/gems/thor-0.20.3/lib/thor/actions/inject_into_file.rb +109 -0
  199. data/vendor/bundle/gems/thor-0.20.3/lib/thor/actions.rb +331 -0
  200. data/vendor/bundle/gems/thor-0.20.3/lib/thor/base.rb +678 -0
  201. data/vendor/bundle/gems/thor-0.20.3/lib/thor/command.rb +135 -0
  202. data/vendor/bundle/gems/thor-0.20.3/lib/thor/core_ext/hash_with_indifferent_access.rb +97 -0
  203. data/vendor/bundle/gems/thor-0.20.3/lib/thor/core_ext/io_binary_read.rb +12 -0
  204. data/vendor/bundle/gems/thor-0.20.3/lib/thor/core_ext/ordered_hash.rb +129 -0
  205. data/vendor/bundle/gems/thor-0.20.3/lib/thor/error.rb +114 -0
  206. data/vendor/bundle/gems/thor-0.20.3/lib/thor/group.rb +281 -0
  207. data/vendor/bundle/gems/thor-0.20.3/lib/thor/invocation.rb +177 -0
  208. data/vendor/bundle/gems/thor-0.20.3/lib/thor/line_editor/basic.rb +37 -0
  209. data/vendor/bundle/gems/thor-0.20.3/lib/thor/line_editor/readline.rb +88 -0
  210. data/vendor/bundle/gems/thor-0.20.3/lib/thor/line_editor.rb +17 -0
  211. data/vendor/bundle/gems/thor-0.20.3/lib/thor/parser/argument.rb +70 -0
  212. data/vendor/bundle/gems/thor-0.20.3/lib/thor/parser/arguments.rb +175 -0
  213. data/vendor/bundle/gems/thor-0.20.3/lib/thor/parser/option.rb +146 -0
  214. data/vendor/bundle/gems/thor-0.20.3/lib/thor/parser/options.rb +226 -0
  215. data/vendor/bundle/gems/thor-0.20.3/lib/thor/parser.rb +4 -0
  216. data/vendor/bundle/gems/thor-0.20.3/lib/thor/rake_compat.rb +71 -0
  217. data/vendor/bundle/gems/thor-0.20.3/lib/thor/runner.rb +324 -0
  218. data/vendor/bundle/gems/thor-0.20.3/lib/thor/shell/basic.rb +482 -0
  219. data/vendor/bundle/gems/thor-0.20.3/lib/thor/shell/color.rb +149 -0
  220. data/vendor/bundle/gems/thor-0.20.3/lib/thor/shell/html.rb +126 -0
  221. data/vendor/bundle/gems/thor-0.20.3/lib/thor/shell.rb +81 -0
  222. data/vendor/bundle/gems/thor-0.20.3/lib/thor/util.rb +268 -0
  223. data/vendor/bundle/gems/thor-0.20.3/lib/thor/version.rb +3 -0
  224. data/vendor/bundle/gems/thor-0.20.3/lib/thor.rb +509 -0
  225. data/vendor/bundle/gems/thor-0.20.3/thor.gemspec +21 -0
  226. data/vendor/bundle/specifications/rake-10.5.0.gemspec +43 -0
  227. data/vendor/bundle/specifications/thor-0.20.3.gemspec +35 -0
  228. metadata +314 -0
@@ -0,0 +1,373 @@
1
+ require "erb"
2
+
3
+ class Thor
4
+ module Actions
5
+ # Copies the file from the relative source to the relative destination. If
6
+ # the destination is not given it's assumed to be equal to the source.
7
+ #
8
+ # ==== Parameters
9
+ # source<String>:: the relative path to the source root.
10
+ # destination<String>:: the relative path to the destination root.
11
+ # config<Hash>:: give :verbose => false to not log the status, and
12
+ # :mode => :preserve, to preserve the file mode from the source.
13
+
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 = yield(content) if block
29
+ content
30
+ end
31
+ if config[:mode] == :preserve
32
+ mode = File.stat(source).mode
33
+ chmod(destination, mode, config)
34
+ end
35
+ end
36
+
37
+ # Links the file from the relative source to the relative destination. If
38
+ # the destination is not given it's assumed to be equal to the source.
39
+ #
40
+ # ==== Parameters
41
+ # source<String>:: the relative path to the source root.
42
+ # destination<String>:: the relative path to the destination root.
43
+ # config<Hash>:: give :verbose => false to not log the status.
44
+ #
45
+ # ==== Examples
46
+ #
47
+ # link_file "README", "doc/README"
48
+ #
49
+ # link_file "doc/README"
50
+ #
51
+ def link_file(source, *args)
52
+ config = args.last.is_a?(Hash) ? args.pop : {}
53
+ destination = args.first || source
54
+ source = File.expand_path(find_in_source_paths(source.to_s))
55
+
56
+ create_link destination, source, config
57
+ end
58
+
59
+ # Gets the content at the given address and places it at the given relative
60
+ # destination. If a block is given instead of destination, the content of
61
+ # the url is yielded and used as location.
62
+ #
63
+ # +get+ relies on open-uri, so passing application user input would provide
64
+ # a command injection attack vector.
65
+ #
66
+ # ==== Parameters
67
+ # source<String>:: the address of the given content.
68
+ # destination<String>:: the relative path to the destination root.
69
+ # config<Hash>:: give :verbose => false to not log the status.
70
+ #
71
+ # ==== Examples
72
+ #
73
+ # get "http://gist.github.com/103208", "doc/README"
74
+ #
75
+ # get "http://gist.github.com/103208" do |content|
76
+ # content.split("\n").first
77
+ # end
78
+ #
79
+ def get(source, *args, &block)
80
+ config = args.last.is_a?(Hash) ? args.pop : {}
81
+ destination = args.first
82
+
83
+ if source =~ %r{^https?\://}
84
+ require "open-uri"
85
+ else
86
+ source = File.expand_path(find_in_source_paths(source.to_s))
87
+ end
88
+
89
+ render = open(source) { |input| input.binmode.read }
90
+
91
+ destination ||= if block_given?
92
+ block.arity == 1 ? yield(render) : yield
93
+ else
94
+ File.basename(source)
95
+ end
96
+
97
+ create_file destination, render, config
98
+ end
99
+
100
+ # Gets an ERB template at the relative source, executes it and makes a copy
101
+ # at the relative destination. If the destination is not given it's assumed
102
+ # to be equal to the source removing .tt from the filename.
103
+ #
104
+ # ==== Parameters
105
+ # source<String>:: the relative path to the source root.
106
+ # destination<String>:: the relative path to the destination root.
107
+ # config<Hash>:: give :verbose => false to not log the status.
108
+ #
109
+ # ==== Examples
110
+ #
111
+ # template "README", "doc/README"
112
+ #
113
+ # template "doc/README"
114
+ #
115
+ def template(source, *args, &block)
116
+ config = args.last.is_a?(Hash) ? args.pop : {}
117
+ destination = args.first || source.sub(/#{TEMPLATE_EXTNAME}$/, "")
118
+
119
+ source = File.expand_path(find_in_source_paths(source.to_s))
120
+ context = config.delete(:context) || instance_eval("binding")
121
+
122
+ create_file destination, nil, config do
123
+ match = ERB.version.match(/(\d+\.\d+\.\d+)/)
124
+ capturable_erb = if match && match[1] >= "2.2.0" # Ruby 2.6+
125
+ CapturableERB.new(::File.binread(source), :trim_mode => "-", :eoutvar => "@output_buffer")
126
+ else
127
+ CapturableERB.new(::File.binread(source), nil, "-", "@output_buffer")
128
+ end
129
+ content = capturable_erb.tap do |erb|
130
+ erb.filename = source
131
+ end.result(context)
132
+ content = yield(content) if block
133
+ content
134
+ end
135
+ end
136
+
137
+ # Changes the mode of the given file or directory.
138
+ #
139
+ # ==== Parameters
140
+ # mode<Integer>:: the file mode
141
+ # path<String>:: the name of the file to change mode
142
+ # config<Hash>:: give :verbose => false to not log the status.
143
+ #
144
+ # ==== Example
145
+ #
146
+ # chmod "script/server", 0755
147
+ #
148
+ def chmod(path, mode, config = {})
149
+ return unless behavior == :invoke
150
+ path = File.expand_path(path, destination_root)
151
+ say_status :chmod, relative_to_original_destination_root(path), config.fetch(:verbose, true)
152
+ unless options[:pretend]
153
+ require "fileutils"
154
+ FileUtils.chmod_R(mode, path)
155
+ end
156
+ end
157
+
158
+ # Prepend text to a file. Since it depends on insert_into_file, it's reversible.
159
+ #
160
+ # ==== Parameters
161
+ # path<String>:: path of the file to be changed
162
+ # data<String>:: the data to prepend to the file, can be also given as a block.
163
+ # config<Hash>:: give :verbose => false to not log the status.
164
+ #
165
+ # ==== Example
166
+ #
167
+ # prepend_to_file 'config/environments/test.rb', 'config.gem "rspec"'
168
+ #
169
+ # prepend_to_file 'config/environments/test.rb' do
170
+ # 'config.gem "rspec"'
171
+ # end
172
+ #
173
+ def prepend_to_file(path, *args, &block)
174
+ config = args.last.is_a?(Hash) ? args.pop : {}
175
+ config[:after] = /\A/
176
+ insert_into_file(path, *(args << config), &block)
177
+ end
178
+ alias_method :prepend_file, :prepend_to_file
179
+
180
+ # Append text to a file. Since it depends on insert_into_file, it's reversible.
181
+ #
182
+ # ==== Parameters
183
+ # path<String>:: path of the file to be changed
184
+ # data<String>:: the data to append to the file, can be also given as a block.
185
+ # config<Hash>:: give :verbose => false to not log the status.
186
+ #
187
+ # ==== Example
188
+ #
189
+ # append_to_file 'config/environments/test.rb', 'config.gem "rspec"'
190
+ #
191
+ # append_to_file 'config/environments/test.rb' do
192
+ # 'config.gem "rspec"'
193
+ # end
194
+ #
195
+ def append_to_file(path, *args, &block)
196
+ config = args.last.is_a?(Hash) ? args.pop : {}
197
+ config[:before] = /\z/
198
+ insert_into_file(path, *(args << config), &block)
199
+ end
200
+ alias_method :append_file, :append_to_file
201
+
202
+ # Injects text right after the class definition. Since it depends on
203
+ # insert_into_file, it's reversible.
204
+ #
205
+ # ==== Parameters
206
+ # path<String>:: path of the file to be changed
207
+ # klass<String|Class>:: the class to be manipulated
208
+ # data<String>:: the data to append to the class, can be also given as a block.
209
+ # config<Hash>:: give :verbose => false to not log the status.
210
+ #
211
+ # ==== Examples
212
+ #
213
+ # inject_into_class "app/controllers/application_controller.rb", ApplicationController, " filter_parameter :password\n"
214
+ #
215
+ # inject_into_class "app/controllers/application_controller.rb", ApplicationController do
216
+ # " filter_parameter :password\n"
217
+ # end
218
+ #
219
+ def inject_into_class(path, klass, *args, &block)
220
+ config = args.last.is_a?(Hash) ? args.pop : {}
221
+ config[:after] = /class #{klass}\n|class #{klass} .*\n/
222
+ insert_into_file(path, *(args << config), &block)
223
+ end
224
+
225
+ # Injects text right after the module definition. Since it depends on
226
+ # insert_into_file, it's reversible.
227
+ #
228
+ # ==== Parameters
229
+ # path<String>:: path of the file to be changed
230
+ # module_name<String|Class>:: the module to be manipulated
231
+ # data<String>:: the data to append to the class, can be also given as a block.
232
+ # config<Hash>:: give :verbose => false to not log the status.
233
+ #
234
+ # ==== Examples
235
+ #
236
+ # inject_into_module "app/helpers/application_helper.rb", ApplicationHelper, " def help; 'help'; end\n"
237
+ #
238
+ # inject_into_module "app/helpers/application_helper.rb", ApplicationHelper do
239
+ # " def help; 'help'; end\n"
240
+ # end
241
+ #
242
+ def inject_into_module(path, module_name, *args, &block)
243
+ config = args.last.is_a?(Hash) ? args.pop : {}
244
+ config[:after] = /module #{module_name}\n|module #{module_name} .*\n/
245
+ insert_into_file(path, *(args << config), &block)
246
+ end
247
+
248
+ # Run a regular expression replacement on a file.
249
+ #
250
+ # ==== Parameters
251
+ # path<String>:: path of the file to be changed
252
+ # flag<Regexp|String>:: the regexp or string to be replaced
253
+ # replacement<String>:: the replacement, can be also given as a block
254
+ # config<Hash>:: give :verbose => false to not log the status.
255
+ #
256
+ # ==== Example
257
+ #
258
+ # gsub_file 'app/controllers/application_controller.rb', /#\s*(filter_parameter_logging :password)/, '\1'
259
+ #
260
+ # gsub_file 'README', /rake/, :green do |match|
261
+ # match << " no more. Use thor!"
262
+ # end
263
+ #
264
+ def gsub_file(path, flag, *args, &block)
265
+ return unless behavior == :invoke
266
+ config = args.last.is_a?(Hash) ? args.pop : {}
267
+
268
+ path = File.expand_path(path, destination_root)
269
+ say_status :gsub, relative_to_original_destination_root(path), config.fetch(:verbose, true)
270
+
271
+ unless options[:pretend]
272
+ content = File.binread(path)
273
+ content.gsub!(flag, *args, &block)
274
+ File.open(path, "wb") { |file| file.write(content) }
275
+ end
276
+ end
277
+
278
+ # Uncomment all lines matching a given regex. It will leave the space
279
+ # which existed before the comment hash in tact but will remove any spacing
280
+ # between the comment hash and the beginning of the line.
281
+ #
282
+ # ==== Parameters
283
+ # path<String>:: path of the file to be changed
284
+ # flag<Regexp|String>:: the regexp or string used to decide which lines to uncomment
285
+ # config<Hash>:: give :verbose => false to not log the status.
286
+ #
287
+ # ==== Example
288
+ #
289
+ # uncomment_lines 'config/initializers/session_store.rb', /active_record/
290
+ #
291
+ def uncomment_lines(path, flag, *args)
292
+ flag = flag.respond_to?(:source) ? flag.source : flag
293
+
294
+ gsub_file(path, /^(\s*)#[[:blank:]]*(.*#{flag})/, '\1\2', *args)
295
+ end
296
+
297
+ # Comment all lines matching a given regex. It will leave the space
298
+ # which existed before the beginning of the line in tact and will insert
299
+ # a single space after the comment hash.
300
+ #
301
+ # ==== Parameters
302
+ # path<String>:: path of the file to be changed
303
+ # flag<Regexp|String>:: the regexp or string used to decide which lines to comment
304
+ # config<Hash>:: give :verbose => false to not log the status.
305
+ #
306
+ # ==== Example
307
+ #
308
+ # comment_lines 'config/initializers/session_store.rb', /cookie_store/
309
+ #
310
+ def comment_lines(path, flag, *args)
311
+ flag = flag.respond_to?(:source) ? flag.source : flag
312
+
313
+ gsub_file(path, /^(\s*)([^#\n]*#{flag})/, '\1# \2', *args)
314
+ end
315
+
316
+ # Removes a file at the given location.
317
+ #
318
+ # ==== Parameters
319
+ # path<String>:: path of the file to be changed
320
+ # config<Hash>:: give :verbose => false to not log the status.
321
+ #
322
+ # ==== Example
323
+ #
324
+ # remove_file 'README'
325
+ # remove_file 'app/controllers/application_controller.rb'
326
+ #
327
+ def remove_file(path, config = {})
328
+ return unless behavior == :invoke
329
+ path = File.expand_path(path, destination_root)
330
+
331
+ say_status :remove, relative_to_original_destination_root(path), config.fetch(:verbose, true)
332
+ if !options[:pretend] && File.exist?(path)
333
+ require "fileutils"
334
+ ::FileUtils.rm_rf(path)
335
+ end
336
+ end
337
+ alias_method :remove_dir, :remove_file
338
+
339
+ attr_accessor :output_buffer
340
+ private :output_buffer, :output_buffer=
341
+
342
+ private
343
+
344
+ def concat(string)
345
+ @output_buffer.concat(string)
346
+ end
347
+
348
+ def capture(*args)
349
+ with_output_buffer { yield(*args) }
350
+ end
351
+
352
+ def with_output_buffer(buf = "".dup) #:nodoc:
353
+ raise ArgumentError, "Buffer can not be a frozen object" if buf.frozen?
354
+ old_buffer = output_buffer
355
+ self.output_buffer = buf
356
+ yield
357
+ output_buffer
358
+ ensure
359
+ self.output_buffer = old_buffer
360
+ end
361
+
362
+ # Thor::Actions#capture depends on what kind of buffer is used in ERB.
363
+ # Thus CapturableERB fixes ERB to use String buffer.
364
+ class CapturableERB < ERB
365
+ def set_eoutvar(compiler, eoutvar = "_erbout")
366
+ compiler.put_cmd = "#{eoutvar}.concat"
367
+ compiler.insert_cmd = "#{eoutvar}.concat"
368
+ compiler.pre_cmd = ["#{eoutvar} = ''.dup"]
369
+ compiler.post_cmd = [eoutvar]
370
+ end
371
+ end
372
+ end
373
+ end
@@ -0,0 +1,109 @@
1
+ require "thor/actions/empty_directory"
2
+
3
+ class Thor
4
+ module Actions
5
+ # Injects the given content into a file. Different from gsub_file, this
6
+ # method is reversible.
7
+ #
8
+ # ==== Parameters
9
+ # destination<String>:: Relative path to the destination root
10
+ # data<String>:: Data to add to the file. Can be given as a block.
11
+ # config<Hash>:: give :verbose => false to not log the status and the flag
12
+ # for injection (:after or :before) or :force => true for
13
+ # insert two or more times the same content.
14
+ #
15
+ # ==== Examples
16
+ #
17
+ # insert_into_file "config/environment.rb", "config.gem :thor", :after => "Rails::Initializer.run do |config|\n"
18
+ #
19
+ # insert_into_file "config/environment.rb", :after => "Rails::Initializer.run do |config|\n" do
20
+ # gems = ask "Which gems would you like to add?"
21
+ # gems.split(" ").map{ |gem| " config.gem :#{gem}" }.join("\n")
22
+ # end
23
+ #
24
+ def insert_into_file(destination, *args, &block)
25
+ data = block_given? ? block : args.shift
26
+ config = args.shift
27
+ action InjectIntoFile.new(self, destination, data, config)
28
+ end
29
+ alias_method :inject_into_file, :insert_into_file
30
+
31
+ class InjectIntoFile < EmptyDirectory #:nodoc:
32
+ attr_reader :replacement, :flag, :behavior
33
+
34
+ def initialize(base, destination, data, config)
35
+ super(base, destination, {:verbose => true}.merge(config))
36
+
37
+ @behavior, @flag = if @config.key?(:after)
38
+ [:after, @config.delete(:after)]
39
+ else
40
+ [:before, @config.delete(:before)]
41
+ end
42
+
43
+ @replacement = data.is_a?(Proc) ? data.call : data
44
+ @flag = Regexp.escape(@flag) unless @flag.is_a?(Regexp)
45
+ end
46
+
47
+ def invoke!
48
+ say_status :invoke
49
+
50
+ content = if @behavior == :after
51
+ '\0' + replacement
52
+ else
53
+ replacement + '\0'
54
+ end
55
+
56
+ if exists?
57
+ replace!(/#{flag}/, content, config[:force])
58
+ else
59
+ unless pretend?
60
+ raise Thor::Error, "The file #{ destination } does not appear to exist"
61
+ end
62
+ end
63
+ end
64
+
65
+ def revoke!
66
+ say_status :revoke
67
+
68
+ regexp = if @behavior == :after
69
+ content = '\1\2'
70
+ /(#{flag})(.*)(#{Regexp.escape(replacement)})/m
71
+ else
72
+ content = '\2\3'
73
+ /(#{Regexp.escape(replacement)})(.*)(#{flag})/m
74
+ end
75
+
76
+ replace!(regexp, content, true)
77
+ end
78
+
79
+ protected
80
+
81
+ def say_status(behavior)
82
+ status = if behavior == :invoke
83
+ if flag == /\A/
84
+ :prepend
85
+ elsif flag == /\z/
86
+ :append
87
+ else
88
+ :insert
89
+ end
90
+ else
91
+ :subtract
92
+ end
93
+
94
+ super(status, config[:verbose])
95
+ end
96
+
97
+ # Adds the content to the file.
98
+ #
99
+ def replace!(regexp, string, force)
100
+ return if pretend?
101
+ content = File.read(destination)
102
+ if force || !content.include?(replacement)
103
+ content.gsub!(regexp, string)
104
+ File.open(destination, "wb") { |file| file.write(content) }
105
+ end
106
+ end
107
+ end
108
+ end
109
+ end