rubygems-update 3.3.18 → 3.6.2

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 (832) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +2182 -1067
  3. data/CODE_OF_CONDUCT.md +79 -28
  4. data/Manifest.txt +184 -290
  5. data/README.md +35 -19
  6. data/bundler/CHANGELOG.md +1003 -3
  7. data/bundler/README.md +3 -7
  8. data/bundler/bundler.gemspec +11 -11
  9. data/bundler/exe/bundle +5 -25
  10. data/bundler/lib/bundler/build_metadata.rb +3 -3
  11. data/bundler/lib/bundler/capistrano.rb +1 -1
  12. data/bundler/lib/bundler/checksum.rb +254 -0
  13. data/bundler/lib/bundler/ci_detector.rb +75 -0
  14. data/bundler/lib/bundler/cli/add.rb +7 -5
  15. data/bundler/lib/bundler/cli/binstubs.rb +10 -6
  16. data/bundler/lib/bundler/cli/cache.rb +1 -1
  17. data/bundler/lib/bundler/cli/check.rb +4 -4
  18. data/bundler/lib/bundler/cli/common.rb +11 -1
  19. data/bundler/lib/bundler/cli/config.rb +8 -7
  20. data/bundler/lib/bundler/cli/console.rb +2 -5
  21. data/bundler/lib/bundler/cli/doctor.rb +10 -12
  22. data/bundler/lib/bundler/cli/exec.rb +2 -1
  23. data/bundler/lib/bundler/cli/fund.rb +1 -1
  24. data/bundler/lib/bundler/cli/gem.rb +77 -53
  25. data/bundler/lib/bundler/cli/info.rb +4 -15
  26. data/bundler/lib/bundler/cli/init.rb +6 -2
  27. data/bundler/lib/bundler/cli/inject.rb +1 -1
  28. data/bundler/lib/bundler/cli/install.rb +27 -15
  29. data/bundler/lib/bundler/cli/issue.rb +1 -1
  30. data/bundler/lib/bundler/cli/lock.rb +54 -28
  31. data/bundler/lib/bundler/cli/open.rb +9 -9
  32. data/bundler/lib/bundler/cli/outdated.rb +34 -29
  33. data/bundler/lib/bundler/cli/platform.rb +7 -5
  34. data/bundler/lib/bundler/cli/plugin.rb +9 -15
  35. data/bundler/lib/bundler/cli/pristine.rb +38 -30
  36. data/bundler/lib/bundler/cli/show.rb +4 -4
  37. data/bundler/lib/bundler/cli/update.rb +6 -5
  38. data/bundler/lib/bundler/cli/viz.rb +1 -1
  39. data/bundler/lib/bundler/cli.rb +258 -307
  40. data/bundler/lib/bundler/compact_index_client/cache.rb +55 -60
  41. data/bundler/lib/bundler/compact_index_client/cache_file.rb +148 -0
  42. data/bundler/lib/bundler/compact_index_client/gem_parser.rb +7 -3
  43. data/bundler/lib/bundler/compact_index_client/parser.rb +84 -0
  44. data/bundler/lib/bundler/compact_index_client/updater.rb +71 -83
  45. data/bundler/lib/bundler/compact_index_client.rb +58 -80
  46. data/bundler/lib/bundler/constants.rb +9 -2
  47. data/bundler/lib/bundler/current_ruby.rb +11 -16
  48. data/bundler/lib/bundler/definition.rb +547 -228
  49. data/bundler/lib/bundler/dependency.rb +30 -87
  50. data/bundler/lib/bundler/digest.rb +3 -3
  51. data/bundler/lib/bundler/dsl.rb +115 -65
  52. data/bundler/lib/bundler/endpoint_specification.rb +27 -14
  53. data/bundler/lib/bundler/env.rb +5 -7
  54. data/bundler/lib/bundler/environment_preserver.rb +8 -25
  55. data/bundler/lib/bundler/errors.rb +85 -11
  56. data/bundler/lib/bundler/feature_flag.rb +1 -2
  57. data/bundler/lib/bundler/fetcher/base.rb +5 -3
  58. data/bundler/lib/bundler/fetcher/compact_index.rb +28 -43
  59. data/bundler/lib/bundler/fetcher/dependency.rb +3 -7
  60. data/bundler/lib/bundler/fetcher/downloader.rb +17 -16
  61. data/bundler/lib/bundler/fetcher/gem_remote_fetcher.rb +16 -0
  62. data/bundler/lib/bundler/fetcher/index.rb +2 -3
  63. data/bundler/lib/bundler/fetcher.rb +91 -74
  64. data/bundler/lib/bundler/force_platform.rb +16 -0
  65. data/bundler/lib/bundler/friendly_errors.rb +6 -9
  66. data/bundler/lib/bundler/gem_helper.rb +5 -6
  67. data/bundler/lib/bundler/gem_helpers.rb +45 -7
  68. data/bundler/lib/bundler/gem_version_promoter.rb +68 -109
  69. data/bundler/lib/bundler/graph.rb +9 -9
  70. data/bundler/lib/bundler/index.rb +69 -73
  71. data/bundler/lib/bundler/injector.rb +12 -13
  72. data/bundler/lib/bundler/inline.rb +40 -17
  73. data/bundler/lib/bundler/installer/gem_installer.rb +13 -12
  74. data/bundler/lib/bundler/installer/parallel_installer.rb +19 -66
  75. data/bundler/lib/bundler/installer/standalone.rb +29 -15
  76. data/bundler/lib/bundler/installer.rb +27 -77
  77. data/bundler/lib/bundler/lazy_specification.rb +134 -71
  78. data/bundler/lib/bundler/lockfile_generator.rb +13 -4
  79. data/bundler/lib/bundler/lockfile_parser.rb +134 -61
  80. data/bundler/lib/bundler/man/bundle-add.1 +46 -48
  81. data/bundler/lib/bundler/man/bundle-add.1.ronn +54 -22
  82. data/bundler/lib/bundler/man/bundle-binstubs.1 +10 -19
  83. data/bundler/lib/bundler/man/bundle-binstubs.1.ronn +6 -3
  84. data/bundler/lib/bundler/man/bundle-cache.1 +38 -25
  85. data/bundler/lib/bundler/man/bundle-cache.1.ronn +40 -4
  86. data/bundler/lib/bundler/man/bundle-check.1 +7 -14
  87. data/bundler/lib/bundler/man/bundle-check.1.ronn +7 -2
  88. data/bundler/lib/bundler/man/bundle-clean.1 +4 -11
  89. data/bundler/lib/bundler/man/bundle-clean.1.ronn +1 -1
  90. data/bundler/lib/bundler/man/bundle-config.1 +41 -220
  91. data/bundler/lib/bundler/man/bundle-config.1.ronn +27 -22
  92. data/bundler/lib/bundler/man/bundle-console.1 +33 -0
  93. data/bundler/lib/bundler/man/bundle-console.1.ronn +39 -0
  94. data/bundler/lib/bundler/man/bundle-doctor.1 +5 -19
  95. data/bundler/lib/bundler/man/bundle-doctor.1.ronn +1 -1
  96. data/bundler/lib/bundler/man/bundle-env.1 +9 -0
  97. data/bundler/lib/bundler/man/bundle-env.1.ronn +10 -0
  98. data/bundler/lib/bundler/man/bundle-exec.1 +20 -78
  99. data/bundler/lib/bundler/man/bundle-exec.1.ronn +12 -10
  100. data/bundler/lib/bundler/man/bundle-fund.1 +22 -0
  101. data/bundler/lib/bundler/man/bundle-fund.1.ronn +25 -0
  102. data/bundler/lib/bundler/man/bundle-gem.1 +53 -81
  103. data/bundler/lib/bundler/man/bundle-gem.1.ronn +41 -9
  104. data/bundler/lib/bundler/man/bundle-help.1 +9 -0
  105. data/bundler/lib/bundler/man/bundle-help.1.ronn +12 -0
  106. data/bundler/lib/bundler/man/bundle-info.1 +8 -11
  107. data/bundler/lib/bundler/man/bundle-info.1.ronn +9 -5
  108. data/bundler/lib/bundler/man/bundle-init.1 +7 -12
  109. data/bundler/lib/bundler/man/bundle-init.1.ronn +4 -1
  110. data/bundler/lib/bundler/man/bundle-inject.1 +17 -19
  111. data/bundler/lib/bundler/man/bundle-inject.1.ronn +12 -2
  112. data/bundler/lib/bundler/man/bundle-install.1 +42 -162
  113. data/bundler/lib/bundler/man/bundle-install.1.ronn +31 -49
  114. data/bundler/lib/bundler/man/bundle-issue.1 +45 -0
  115. data/bundler/lib/bundler/man/bundle-issue.1.ronn +37 -0
  116. data/bundler/lib/bundler/man/bundle-licenses.1 +9 -0
  117. data/bundler/lib/bundler/man/bundle-licenses.1.ronn +10 -0
  118. data/bundler/lib/bundler/man/bundle-list.1 +4 -19
  119. data/bundler/lib/bundler/man/bundle-list.1.ronn +4 -1
  120. data/bundler/lib/bundler/man/bundle-lock.1 +25 -34
  121. data/bundler/lib/bundler/man/bundle-lock.1.ronn +25 -4
  122. data/bundler/lib/bundler/man/bundle-open.1 +18 -18
  123. data/bundler/lib/bundler/man/bundle-open.1.ronn +10 -1
  124. data/bundler/lib/bundler/man/bundle-outdated.1 +22 -67
  125. data/bundler/lib/bundler/man/bundle-outdated.1.ronn +20 -12
  126. data/bundler/lib/bundler/man/bundle-platform.1 +16 -28
  127. data/bundler/lib/bundler/man/bundle-platform.1.ronn +14 -7
  128. data/bundler/lib/bundler/man/bundle-plugin.1 +58 -0
  129. data/bundler/lib/bundler/man/bundle-plugin.1.ronn +63 -0
  130. data/bundler/lib/bundler/man/bundle-pristine.1 +5 -16
  131. data/bundler/lib/bundler/man/bundle-pristine.1.ronn +1 -1
  132. data/bundler/lib/bundler/man/bundle-remove.1 +4 -14
  133. data/bundler/lib/bundler/man/bundle-remove.1.ronn +1 -1
  134. data/bundler/lib/bundler/man/bundle-show.1 +7 -11
  135. data/bundler/lib/bundler/man/bundle-show.1.ronn +4 -0
  136. data/bundler/lib/bundler/man/bundle-update.1 +30 -143
  137. data/bundler/lib/bundler/man/bundle-update.1.ronn +14 -6
  138. data/bundler/lib/bundler/man/bundle-version.1 +22 -0
  139. data/bundler/lib/bundler/man/bundle-version.1.ronn +24 -0
  140. data/bundler/lib/bundler/man/bundle-viz.1 +9 -18
  141. data/bundler/lib/bundler/man/bundle-viz.1.ronn +9 -3
  142. data/bundler/lib/bundler/man/bundle.1 +17 -51
  143. data/bundler/lib/bundler/man/bundle.1.ronn +12 -7
  144. data/bundler/lib/bundler/man/gemfile.5 +77 -341
  145. data/bundler/lib/bundler/man/gemfile.5.ronn +73 -54
  146. data/bundler/lib/bundler/man/index.txt +8 -0
  147. data/bundler/lib/bundler/match_metadata.rb +17 -0
  148. data/bundler/lib/bundler/match_platform.rb +1 -1
  149. data/bundler/lib/bundler/match_remote_metadata.rb +29 -0
  150. data/bundler/lib/bundler/materialization.rb +59 -0
  151. data/bundler/lib/bundler/mirror.rb +8 -10
  152. data/bundler/lib/bundler/plugin/api/source.rb +7 -5
  153. data/bundler/lib/bundler/plugin/events.rb +24 -0
  154. data/bundler/lib/bundler/plugin/index.rb +13 -5
  155. data/bundler/lib/bundler/plugin/installer/path.rb +18 -0
  156. data/bundler/lib/bundler/plugin/installer/rubygems.rb +0 -4
  157. data/bundler/lib/bundler/plugin/installer.rb +42 -19
  158. data/bundler/lib/bundler/plugin/source_list.rb +4 -4
  159. data/bundler/lib/bundler/plugin.rb +35 -7
  160. data/bundler/lib/bundler/process_lock.rb +10 -14
  161. data/bundler/lib/bundler/remote_specification.rb +17 -13
  162. data/bundler/lib/bundler/resolver/base.rb +117 -0
  163. data/bundler/lib/bundler/resolver/candidate.rb +82 -0
  164. data/bundler/lib/bundler/resolver/incompatibility.rb +15 -0
  165. data/bundler/lib/bundler/resolver/package.rb +90 -0
  166. data/bundler/lib/bundler/resolver/root.rb +25 -0
  167. data/bundler/lib/bundler/resolver/spec_group.rb +54 -67
  168. data/bundler/lib/bundler/resolver.rb +432 -329
  169. data/bundler/lib/bundler/retry.rb +2 -2
  170. data/bundler/lib/bundler/ruby_dsl.rb +42 -7
  171. data/bundler/lib/bundler/ruby_version.rb +23 -10
  172. data/bundler/lib/bundler/rubygems_ext.rb +286 -81
  173. data/bundler/lib/bundler/rubygems_gem_installer.rb +77 -68
  174. data/bundler/lib/bundler/rubygems_integration.rb +57 -155
  175. data/bundler/lib/bundler/runtime.rb +28 -17
  176. data/bundler/lib/bundler/safe_marshal.rb +31 -0
  177. data/bundler/lib/bundler/self_manager.rb +50 -12
  178. data/bundler/lib/bundler/settings.rb +144 -58
  179. data/bundler/lib/bundler/setup.rb +13 -1
  180. data/bundler/lib/bundler/shared_helpers.rb +87 -36
  181. data/bundler/lib/bundler/source/git/git_proxy.rb +278 -80
  182. data/bundler/lib/bundler/source/git.rb +161 -68
  183. data/bundler/lib/bundler/source/metadata.rb +16 -16
  184. data/bundler/lib/bundler/source/path/installer.rb +1 -22
  185. data/bundler/lib/bundler/source/path.rb +16 -26
  186. data/bundler/lib/bundler/source/rubygems/remote.rb +1 -1
  187. data/bundler/lib/bundler/source/rubygems.rb +94 -154
  188. data/bundler/lib/bundler/source.rb +3 -1
  189. data/bundler/lib/bundler/source_list.rb +34 -4
  190. data/bundler/lib/bundler/spec_set.rb +195 -65
  191. data/bundler/lib/bundler/stub_specification.rb +34 -4
  192. data/bundler/lib/bundler/templates/Executable +1 -1
  193. data/bundler/lib/bundler/templates/Executable.bundler +6 -11
  194. data/bundler/lib/bundler/templates/Executable.standalone +2 -0
  195. data/bundler/lib/bundler/templates/newgem/CODE_OF_CONDUCT.md.tt +77 -29
  196. data/bundler/lib/bundler/templates/newgem/Cargo.toml.tt +7 -0
  197. data/bundler/lib/bundler/templates/newgem/README.md.tt +11 -5
  198. data/bundler/lib/bundler/templates/newgem/Rakefile.tt +19 -8
  199. data/bundler/lib/bundler/templates/newgem/bin/console.tt +0 -4
  200. data/bundler/lib/bundler/templates/newgem/circleci/config.yml.tt +12 -0
  201. data/bundler/lib/bundler/templates/newgem/ext/newgem/Cargo.toml.tt +15 -0
  202. data/bundler/lib/bundler/templates/newgem/ext/newgem/extconf-c.rb.tt +10 -0
  203. data/bundler/lib/bundler/templates/newgem/ext/newgem/extconf-rust.rb.tt +6 -0
  204. data/bundler/lib/bundler/templates/newgem/ext/newgem/newgem.c.tt +1 -1
  205. data/bundler/lib/bundler/templates/newgem/ext/newgem/src/lib.rs.tt +12 -0
  206. data/bundler/lib/bundler/templates/newgem/github/workflows/main.yml.tt +18 -8
  207. data/bundler/lib/bundler/templates/newgem/gitignore.tt +3 -0
  208. data/bundler/lib/bundler/templates/newgem/gitlab-ci.yml.tt +13 -4
  209. data/bundler/lib/bundler/templates/newgem/newgem.gemspec.tt +12 -4
  210. data/bundler/lib/bundler/templates/newgem/rubocop.yml.tt +0 -5
  211. data/bundler/lib/bundler/templates/newgem/standard.yml.tt +1 -1
  212. data/bundler/lib/bundler/ui/rg_proxy.rb +1 -1
  213. data/bundler/lib/bundler/ui/shell.rb +60 -15
  214. data/bundler/lib/bundler/ui/silent.rb +33 -6
  215. data/bundler/lib/bundler/uri_credentials_filter.rb +3 -3
  216. data/bundler/lib/bundler/uri_normalizer.rb +23 -0
  217. data/bundler/lib/bundler/vendor/connection_pool/lib/connection_pool/timed_stack.rb +3 -3
  218. data/bundler/lib/bundler/vendor/connection_pool/lib/connection_pool/version.rb +1 -1
  219. data/bundler/lib/bundler/vendor/connection_pool/lib/connection_pool/wrapper.rb +0 -1
  220. data/bundler/lib/bundler/vendor/connection_pool/lib/connection_pool.rb +56 -7
  221. data/bundler/lib/bundler/vendor/fileutils/lib/fileutils.rb +1350 -418
  222. data/bundler/lib/bundler/vendor/net-http-persistent/.document +1 -0
  223. data/bundler/lib/bundler/vendor/net-http-persistent/README.rdoc +1 -1
  224. data/bundler/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent/connection.rb +4 -3
  225. data/bundler/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent/pool.rb +23 -11
  226. data/bundler/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent/timed_stack_multi.rb +1 -1
  227. data/bundler/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent.rb +102 -64
  228. data/bundler/lib/bundler/vendor/pub_grub/.document +1 -0
  229. data/bundler/lib/bundler/vendor/pub_grub/LICENSE.txt +21 -0
  230. data/bundler/lib/bundler/vendor/pub_grub/lib/pub_grub/assignment.rb +20 -0
  231. data/bundler/lib/bundler/vendor/pub_grub/lib/pub_grub/basic_package_source.rb +189 -0
  232. data/bundler/lib/bundler/vendor/pub_grub/lib/pub_grub/failure_writer.rb +182 -0
  233. data/bundler/lib/bundler/vendor/pub_grub/lib/pub_grub/incompatibility.rb +150 -0
  234. data/bundler/lib/bundler/vendor/pub_grub/lib/pub_grub/package.rb +43 -0
  235. data/bundler/lib/bundler/vendor/pub_grub/lib/pub_grub/partial_solution.rb +121 -0
  236. data/bundler/lib/bundler/vendor/pub_grub/lib/pub_grub/rubygems.rb +45 -0
  237. data/bundler/lib/bundler/vendor/pub_grub/lib/pub_grub/solve_failure.rb +19 -0
  238. data/bundler/lib/bundler/vendor/pub_grub/lib/pub_grub/static_package_source.rb +61 -0
  239. data/bundler/lib/bundler/vendor/pub_grub/lib/pub_grub/term.rb +105 -0
  240. data/bundler/lib/bundler/vendor/pub_grub/lib/pub_grub/version.rb +3 -0
  241. data/bundler/lib/bundler/vendor/pub_grub/lib/pub_grub/version_constraint.rb +129 -0
  242. data/bundler/lib/bundler/vendor/pub_grub/lib/pub_grub/version_range.rb +411 -0
  243. data/bundler/lib/bundler/vendor/pub_grub/lib/pub_grub/version_solver.rb +248 -0
  244. data/bundler/lib/bundler/vendor/pub_grub/lib/pub_grub/version_union.rb +178 -0
  245. data/bundler/lib/bundler/vendor/pub_grub/lib/pub_grub.rb +31 -0
  246. data/bundler/lib/bundler/vendor/securerandom/.document +1 -0
  247. data/bundler/lib/bundler/vendor/securerandom/COPYING +56 -0
  248. data/bundler/lib/bundler/vendor/securerandom/lib/securerandom.rb +102 -0
  249. data/bundler/lib/bundler/vendor/thor/.document +1 -0
  250. data/bundler/lib/bundler/vendor/thor/lib/thor/actions/create_file.rb +3 -2
  251. data/bundler/lib/bundler/vendor/thor/lib/thor/actions/directory.rb +1 -1
  252. data/bundler/lib/bundler/vendor/thor/lib/thor/actions/empty_directory.rb +1 -1
  253. data/bundler/lib/bundler/vendor/thor/lib/thor/actions/file_manipulation.rb +11 -15
  254. data/bundler/lib/bundler/vendor/thor/lib/thor/actions/inject_into_file.rb +15 -4
  255. data/bundler/lib/bundler/vendor/thor/lib/thor/actions.rb +15 -15
  256. data/bundler/lib/bundler/vendor/thor/lib/thor/base.rb +140 -14
  257. data/bundler/lib/bundler/vendor/thor/lib/thor/command.rb +13 -4
  258. data/bundler/lib/bundler/vendor/thor/lib/thor/core_ext/hash_with_indifferent_access.rb +4 -0
  259. data/bundler/lib/bundler/vendor/thor/lib/thor/error.rb +16 -25
  260. data/bundler/lib/bundler/vendor/thor/lib/thor/group.rb +12 -1
  261. data/bundler/lib/bundler/vendor/thor/lib/thor/invocation.rb +1 -1
  262. data/bundler/lib/bundler/vendor/thor/lib/thor/nested_context.rb +2 -2
  263. data/bundler/lib/bundler/vendor/thor/lib/thor/parser/argument.rb +17 -1
  264. data/bundler/lib/bundler/vendor/thor/lib/thor/parser/arguments.rb +33 -17
  265. data/bundler/lib/bundler/vendor/thor/lib/thor/parser/option.rb +28 -9
  266. data/bundler/lib/bundler/vendor/thor/lib/thor/parser/options.rb +46 -7
  267. data/bundler/lib/bundler/vendor/thor/lib/thor/rake_compat.rb +2 -2
  268. data/bundler/lib/bundler/vendor/thor/lib/thor/runner.rb +40 -30
  269. data/bundler/lib/bundler/vendor/thor/lib/thor/shell/basic.rb +35 -159
  270. data/bundler/lib/bundler/vendor/thor/lib/thor/shell/color.rb +1 -46
  271. data/bundler/lib/bundler/vendor/thor/lib/thor/shell/column_printer.rb +29 -0
  272. data/bundler/lib/bundler/vendor/thor/lib/thor/shell/html.rb +1 -46
  273. data/bundler/lib/bundler/vendor/thor/lib/thor/shell/table_printer.rb +118 -0
  274. data/bundler/lib/bundler/vendor/thor/lib/thor/shell/terminal.rb +42 -0
  275. data/bundler/lib/bundler/vendor/thor/lib/thor/shell/wrapped_printer.rb +38 -0
  276. data/bundler/lib/bundler/vendor/thor/lib/thor/shell.rb +1 -1
  277. data/bundler/lib/bundler/vendor/thor/lib/thor/util.rb +8 -7
  278. data/bundler/lib/bundler/vendor/thor/lib/thor/version.rb +1 -1
  279. data/bundler/lib/bundler/vendor/thor/lib/thor.rb +166 -8
  280. data/bundler/lib/bundler/vendor/tsort/.document +1 -0
  281. data/bundler/lib/bundler/vendor/tsort/lib/tsort.rb +3 -0
  282. data/bundler/lib/bundler/vendor/uri/.document +1 -0
  283. data/bundler/lib/bundler/vendor/uri/COPYING +56 -0
  284. data/bundler/lib/bundler/vendor/uri/lib/uri/common.rb +343 -148
  285. data/bundler/lib/bundler/vendor/uri/lib/uri/file.rb +10 -4
  286. data/bundler/lib/bundler/vendor/uri/lib/uri/ftp.rb +3 -2
  287. data/bundler/lib/bundler/vendor/uri/lib/uri/generic.rb +44 -33
  288. data/bundler/lib/bundler/vendor/uri/lib/uri/http.rb +40 -2
  289. data/bundler/lib/bundler/vendor/uri/lib/uri/https.rb +2 -1
  290. data/bundler/lib/bundler/vendor/uri/lib/uri/ldap.rb +1 -1
  291. data/bundler/lib/bundler/vendor/uri/lib/uri/ldaps.rb +2 -1
  292. data/bundler/lib/bundler/vendor/uri/lib/uri/mailto.rb +2 -2
  293. data/bundler/lib/bundler/vendor/uri/lib/uri/rfc2396_parser.rb +25 -12
  294. data/bundler/lib/bundler/vendor/uri/lib/uri/rfc3986_parser.rb +130 -38
  295. data/bundler/lib/bundler/vendor/uri/lib/uri/version.rb +1 -1
  296. data/bundler/lib/bundler/vendor/uri/lib/uri/ws.rb +1 -2
  297. data/bundler/lib/bundler/vendor/uri/lib/uri/wss.rb +2 -1
  298. data/bundler/lib/bundler/vendor/uri/lib/uri.rb +12 -11
  299. data/bundler/lib/bundler/vendored_net_http.rb +23 -0
  300. data/bundler/lib/bundler/vendored_persistent.rb +0 -36
  301. data/bundler/lib/bundler/{vendored_tmpdir.rb → vendored_pub_grub.rb} +1 -1
  302. data/bundler/lib/bundler/vendored_securerandom.rb +12 -0
  303. data/bundler/lib/bundler/vendored_timeout.rb +12 -0
  304. data/bundler/lib/bundler/vendored_uri.rb +18 -1
  305. data/bundler/lib/bundler/version.rb +5 -1
  306. data/bundler/lib/bundler/vlad.rb +1 -1
  307. data/bundler/lib/bundler/worker.rb +5 -7
  308. data/bundler/lib/bundler/yaml_serializer.rb +22 -13
  309. data/bundler/lib/bundler.rb +155 -148
  310. data/{bundler → doc/bundler}/UPGRADING.md +11 -4
  311. data/{CONTRIBUTING.md → doc/rubygems/CONTRIBUTING.md} +40 -17
  312. data/doc/rubygems/POLICIES.md +204 -0
  313. data/{test/rubygems/fake_certlib/openssl.rb → exe/gem} +5 -1
  314. data/{bin → exe}/update_rubygems +12 -10
  315. data/lib/rubygems/available_set.rb +8 -7
  316. data/lib/rubygems/basic_specification.rb +90 -52
  317. data/lib/rubygems/bundler_version_finder.rb +6 -6
  318. data/lib/rubygems/ci_detector.rb +75 -0
  319. data/lib/rubygems/command.rb +68 -64
  320. data/lib/rubygems/command_manager.rb +39 -24
  321. data/lib/rubygems/commands/build_command.rb +14 -19
  322. data/lib/rubygems/commands/cert_command.rb +39 -39
  323. data/lib/rubygems/commands/check_command.rb +30 -25
  324. data/lib/rubygems/commands/cleanup_command.rb +32 -43
  325. data/lib/rubygems/commands/contents_command.rb +33 -25
  326. data/lib/rubygems/commands/dependency_command.rb +22 -23
  327. data/lib/rubygems/commands/environment_command.rb +8 -9
  328. data/lib/rubygems/commands/exec_command.rb +247 -0
  329. data/lib/rubygems/commands/fetch_command.rb +25 -10
  330. data/lib/rubygems/commands/generate_index_command.rb +40 -74
  331. data/lib/rubygems/commands/help_command.rb +15 -14
  332. data/lib/rubygems/commands/info_command.rb +5 -5
  333. data/lib/rubygems/commands/install_command.rb +31 -38
  334. data/lib/rubygems/commands/list_command.rb +6 -5
  335. data/lib/rubygems/commands/lock_command.rb +6 -5
  336. data/lib/rubygems/commands/mirror_command.rb +4 -3
  337. data/lib/rubygems/commands/open_command.rb +11 -12
  338. data/lib/rubygems/commands/outdated_command.rb +6 -5
  339. data/lib/rubygems/commands/owner_command.rb +23 -22
  340. data/lib/rubygems/commands/pristine_command.rb +83 -62
  341. data/lib/rubygems/commands/push_command.rb +38 -13
  342. data/lib/rubygems/commands/query_command.rb +11 -11
  343. data/lib/rubygems/commands/rdoc_command.rb +23 -28
  344. data/lib/rubygems/commands/rebuild_command.rb +262 -0
  345. data/lib/rubygems/commands/search_command.rb +6 -5
  346. data/lib/rubygems/commands/server_command.rb +4 -3
  347. data/lib/rubygems/commands/setup_command.rb +137 -154
  348. data/lib/rubygems/commands/signin_command.rb +10 -9
  349. data/lib/rubygems/commands/signout_command.rb +8 -7
  350. data/lib/rubygems/commands/sources_command.rb +34 -33
  351. data/lib/rubygems/commands/specification_command.rb +25 -20
  352. data/lib/rubygems/commands/stale_command.rb +5 -4
  353. data/lib/rubygems/commands/uninstall_command.rb +66 -59
  354. data/lib/rubygems/commands/unpack_command.rb +23 -30
  355. data/lib/rubygems/commands/update_command.rb +62 -94
  356. data/lib/rubygems/commands/which_command.rb +9 -8
  357. data/lib/rubygems/commands/yank_command.rb +14 -13
  358. data/lib/rubygems/compatibility.rb +5 -6
  359. data/lib/rubygems/config_file.rb +160 -50
  360. data/lib/rubygems/core_ext/kernel_gem.rb +3 -10
  361. data/lib/rubygems/core_ext/kernel_require.rb +88 -114
  362. data/lib/rubygems/core_ext/kernel_warn.rb +30 -39
  363. data/lib/rubygems/core_ext/tcpsocket_init.rb +4 -2
  364. data/lib/rubygems/defaults.rb +53 -22
  365. data/lib/rubygems/dependency.rb +34 -36
  366. data/lib/rubygems/dependency_installer.rb +52 -56
  367. data/lib/rubygems/dependency_list.rb +8 -7
  368. data/lib/rubygems/deprecate.rb +80 -75
  369. data/lib/rubygems/doctor.rb +23 -22
  370. data/lib/rubygems/errors.rb +6 -8
  371. data/lib/rubygems/exceptions.rb +20 -18
  372. data/lib/rubygems/ext/build_error.rb +2 -1
  373. data/lib/rubygems/ext/builder.rb +56 -32
  374. data/lib/rubygems/ext/cargo_builder/link_flag_converter.rb +9 -5
  375. data/lib/rubygems/ext/cargo_builder.rb +158 -131
  376. data/lib/rubygems/ext/cmake_builder.rb +9 -4
  377. data/lib/rubygems/ext/configure_builder.rb +9 -3
  378. data/lib/rubygems/ext/ext_conf_builder.rb +19 -15
  379. data/lib/rubygems/ext/rake_builder.rb +14 -7
  380. data/lib/rubygems/ext.rb +8 -7
  381. data/lib/rubygems/gem_runner.rb +23 -9
  382. data/lib/rubygems/gemcutter_utilities/webauthn_listener/response.rb +163 -0
  383. data/lib/rubygems/gemcutter_utilities/webauthn_listener.rb +105 -0
  384. data/lib/rubygems/gemcutter_utilities/webauthn_poller.rb +80 -0
  385. data/lib/rubygems/gemcutter_utilities.rb +141 -63
  386. data/lib/rubygems/gemspec_helpers.rb +19 -0
  387. data/lib/rubygems/install_default_message.rb +3 -2
  388. data/lib/rubygems/install_message.rb +3 -2
  389. data/lib/rubygems/install_update_options.rb +72 -67
  390. data/lib/rubygems/installer.rb +148 -130
  391. data/lib/rubygems/installer_uninstaller_utils.rb +2 -4
  392. data/lib/rubygems/local_remote_options.rb +24 -28
  393. data/lib/rubygems/name_tuple.rb +10 -11
  394. data/lib/rubygems/package/digest_io.rb +2 -1
  395. data/lib/rubygems/package/file_source.rb +3 -2
  396. data/lib/rubygems/package/io_source.rb +1 -0
  397. data/lib/rubygems/package/old.rb +11 -10
  398. data/lib/rubygems/package/source.rb +1 -0
  399. data/lib/rubygems/package/tar_header.rb +125 -91
  400. data/lib/rubygems/package/tar_reader/entry.rb +106 -29
  401. data/lib/rubygems/package/tar_reader.rb +16 -39
  402. data/lib/rubygems/package/tar_writer.rb +29 -26
  403. data/lib/rubygems/package.rb +122 -84
  404. data/lib/rubygems/package_task.rb +7 -6
  405. data/lib/rubygems/path_support.rb +11 -11
  406. data/lib/rubygems/platform.rb +119 -70
  407. data/lib/rubygems/psych_tree.rb +6 -1
  408. data/lib/rubygems/query_utils.rb +46 -48
  409. data/lib/rubygems/rdoc.rb +13 -3
  410. data/lib/rubygems/remote_fetcher.rb +47 -39
  411. data/lib/rubygems/request/connection_pools.rb +6 -6
  412. data/lib/rubygems/request/http_pool.rb +2 -1
  413. data/lib/rubygems/request/https_pool.rb +1 -0
  414. data/lib/rubygems/request.rb +48 -44
  415. data/lib/rubygems/request_set/gem_dependency_api.rb +141 -144
  416. data/lib/rubygems/request_set/lockfile/parser.rb +31 -30
  417. data/lib/rubygems/request_set/lockfile/tokenizer.rb +24 -14
  418. data/lib/rubygems/request_set/lockfile.rb +11 -15
  419. data/lib/rubygems/request_set.rb +25 -23
  420. data/lib/rubygems/requirement.rb +30 -27
  421. data/lib/rubygems/resolver/activation_request.rb +7 -10
  422. data/lib/rubygems/resolver/api_set/gem_parser.rb +7 -3
  423. data/lib/rubygems/resolver/api_set.rb +20 -13
  424. data/lib/rubygems/resolver/api_specification.rb +8 -7
  425. data/lib/rubygems/resolver/best_set.rb +5 -32
  426. data/lib/rubygems/resolver/composed_set.rb +4 -3
  427. data/lib/rubygems/resolver/conflict.rb +14 -21
  428. data/lib/rubygems/resolver/current_set.rb +1 -0
  429. data/lib/rubygems/resolver/dependency_request.rb +3 -2
  430. data/lib/rubygems/resolver/git_set.rb +2 -2
  431. data/lib/rubygems/resolver/git_specification.rb +7 -6
  432. data/lib/rubygems/resolver/index_set.rb +10 -9
  433. data/lib/rubygems/resolver/index_specification.rb +8 -6
  434. data/lib/rubygems/resolver/installed_specification.rb +6 -5
  435. data/lib/rubygems/resolver/installer_set.rb +19 -22
  436. data/lib/rubygems/resolver/local_specification.rb +4 -3
  437. data/lib/rubygems/resolver/lock_set.rb +6 -5
  438. data/lib/rubygems/resolver/lock_specification.rb +5 -4
  439. data/lib/rubygems/resolver/requirement_list.rb +1 -0
  440. data/lib/rubygems/resolver/set.rb +1 -0
  441. data/lib/rubygems/resolver/source_set.rb +2 -0
  442. data/lib/rubygems/resolver/spec_specification.rb +8 -0
  443. data/lib/rubygems/resolver/specification.rb +2 -1
  444. data/lib/rubygems/resolver/stats.rb +2 -1
  445. data/lib/rubygems/resolver/vendor_set.rb +2 -1
  446. data/lib/rubygems/resolver/vendor_specification.rb +4 -3
  447. data/lib/rubygems/resolver.rb +51 -57
  448. data/lib/rubygems/s3_uri_signer.rb +18 -16
  449. data/lib/rubygems/safe_marshal/elements.rb +146 -0
  450. data/lib/rubygems/safe_marshal/reader.rb +325 -0
  451. data/lib/rubygems/safe_marshal/visitors/stream_printer.rb +31 -0
  452. data/lib/rubygems/safe_marshal/visitors/to_ruby.rb +428 -0
  453. data/lib/rubygems/safe_marshal/visitors/visitor.rb +74 -0
  454. data/lib/rubygems/safe_marshal.rb +74 -0
  455. data/lib/rubygems/safe_yaml.rb +14 -26
  456. data/lib/rubygems/security/policies.rb +48 -49
  457. data/lib/rubygems/security/policy.rb +25 -28
  458. data/lib/rubygems/security/signer.rb +16 -7
  459. data/lib/rubygems/security/trust_dir.rb +12 -13
  460. data/lib/rubygems/security.rb +40 -66
  461. data/lib/rubygems/security_option.rb +7 -6
  462. data/lib/rubygems/shellwords.rb +3 -0
  463. data/lib/rubygems/source/git.rb +34 -31
  464. data/lib/rubygems/source/installed.rb +4 -3
  465. data/lib/rubygems/source/local.rb +49 -49
  466. data/lib/rubygems/source/lock.rb +2 -3
  467. data/lib/rubygems/source/specific_file.rb +6 -4
  468. data/lib/rubygems/source/vendor.rb +1 -2
  469. data/lib/rubygems/source.rb +37 -31
  470. data/lib/rubygems/source_list.rb +8 -8
  471. data/lib/rubygems/spec_fetcher.rb +95 -66
  472. data/lib/rubygems/specification.rb +342 -404
  473. data/lib/rubygems/specification_policy.rb +147 -75
  474. data/lib/rubygems/specification_record.rb +212 -0
  475. data/lib/rubygems/stub_specification.rb +56 -30
  476. data/lib/rubygems/target_rbconfig.rb +50 -0
  477. data/lib/rubygems/text.rb +3 -4
  478. data/lib/rubygems/uninstaller.rb +67 -48
  479. data/lib/rubygems/update_suggestion.rb +56 -0
  480. data/lib/rubygems/uri.rb +10 -10
  481. data/lib/rubygems/uri_formatter.rb +2 -2
  482. data/lib/rubygems/user_interaction.rb +50 -40
  483. data/lib/rubygems/util/licenses.rb +310 -39
  484. data/lib/rubygems/util/list.rb +4 -1
  485. data/lib/rubygems/util.rb +19 -20
  486. data/lib/rubygems/validator.rb +15 -14
  487. data/lib/rubygems/vendor/molinillo/.document +1 -0
  488. data/lib/rubygems/vendor/molinillo/lib/molinillo/delegates/resolution_state.rb +57 -0
  489. data/{bundler/lib/bundler → lib/rubygems}/vendor/molinillo/lib/molinillo/delegates/specification_provider.rb +11 -11
  490. data/{bundler/lib/bundler → lib/rubygems}/vendor/molinillo/lib/molinillo/dependency_graph/action.rb +1 -1
  491. data/{bundler/lib/bundler → lib/rubygems}/vendor/molinillo/lib/molinillo/dependency_graph/add_edge_no_circular.rb +1 -1
  492. data/{bundler/lib/bundler → lib/rubygems}/vendor/molinillo/lib/molinillo/dependency_graph/add_vertex.rb +1 -1
  493. data/{bundler/lib/bundler → lib/rubygems}/vendor/molinillo/lib/molinillo/dependency_graph/delete_edge.rb +1 -1
  494. data/{bundler/lib/bundler → lib/rubygems}/vendor/molinillo/lib/molinillo/dependency_graph/detach_vertex_named.rb +1 -1
  495. data/{bundler/lib/bundler → lib/rubygems}/vendor/molinillo/lib/molinillo/dependency_graph/log.rb +1 -1
  496. data/{bundler/lib/bundler → lib/rubygems}/vendor/molinillo/lib/molinillo/dependency_graph/set_payload.rb +1 -1
  497. data/{bundler/lib/bundler → lib/rubygems}/vendor/molinillo/lib/molinillo/dependency_graph/tag.rb +1 -1
  498. data/{bundler/lib/bundler → lib/rubygems}/vendor/molinillo/lib/molinillo/dependency_graph/vertex.rb +1 -1
  499. data/{bundler/lib/bundler → lib/rubygems}/vendor/molinillo/lib/molinillo/dependency_graph.rb +3 -3
  500. data/{bundler/lib/bundler → lib/rubygems}/vendor/molinillo/lib/molinillo/errors.rb +1 -1
  501. data/lib/rubygems/vendor/molinillo/lib/molinillo/gem_metadata.rb +6 -0
  502. data/{bundler/lib/bundler → lib/rubygems}/vendor/molinillo/lib/molinillo/modules/specification_provider.rb +2 -2
  503. data/{bundler/lib/bundler → lib/rubygems}/vendor/molinillo/lib/molinillo/modules/ui.rb +1 -1
  504. data/{bundler/lib/bundler → lib/rubygems}/vendor/molinillo/lib/molinillo/resolution.rb +4 -4
  505. data/{bundler/lib/bundler → lib/rubygems}/vendor/molinillo/lib/molinillo/resolver.rb +1 -1
  506. data/{bundler/lib/bundler → lib/rubygems}/vendor/molinillo/lib/molinillo/state.rb +1 -1
  507. data/{bundler/lib/bundler → lib/rubygems}/vendor/molinillo/lib/molinillo.rb +2 -2
  508. data/lib/rubygems/vendor/net-http/.document +1 -0
  509. data/lib/rubygems/vendor/net-http/COPYING +56 -0
  510. data/lib/rubygems/vendor/net-http/lib/net/http/exceptions.rb +34 -0
  511. data/lib/rubygems/vendor/net-http/lib/net/http/generic_request.rb +414 -0
  512. data/lib/rubygems/vendor/net-http/lib/net/http/header.rb +981 -0
  513. data/lib/rubygems/vendor/net-http/lib/net/http/proxy_delta.rb +17 -0
  514. data/lib/rubygems/vendor/net-http/lib/net/http/request.rb +88 -0
  515. data/lib/rubygems/vendor/net-http/lib/net/http/requests.rb +430 -0
  516. data/lib/rubygems/vendor/net-http/lib/net/http/response.rb +738 -0
  517. data/lib/rubygems/vendor/net-http/lib/net/http/responses.rb +1174 -0
  518. data/lib/rubygems/vendor/net-http/lib/net/http/status.rb +84 -0
  519. data/lib/rubygems/vendor/net-http/lib/net/http.rb +2580 -0
  520. data/lib/rubygems/vendor/net-http/lib/net/https.rb +23 -0
  521. data/lib/rubygems/vendor/net-protocol/.document +1 -0
  522. data/lib/rubygems/vendor/net-protocol/lib/net/protocol.rb +544 -0
  523. data/lib/rubygems/vendor/optparse/.document +1 -0
  524. data/lib/rubygems/vendor/optparse/COPYING +56 -0
  525. data/lib/rubygems/{optparse → vendor/optparse}/lib/optparse/ac.rb +16 -0
  526. data/lib/rubygems/{optparse → vendor/optparse}/lib/optparse/kwargs.rb +8 -3
  527. data/lib/rubygems/vendor/optparse/lib/optparse/uri.rb +7 -0
  528. data/lib/rubygems/{optparse → vendor/optparse}/lib/optparse/version.rb +9 -0
  529. data/lib/rubygems/{optparse → vendor/optparse}/lib/optparse.rb +206 -83
  530. data/lib/rubygems/vendor/resolv/.document +1 -0
  531. data/lib/rubygems/vendor/resolv/COPYING +56 -0
  532. data/lib/rubygems/vendor/resolv/lib/resolv.rb +3455 -0
  533. data/lib/rubygems/vendor/securerandom/.document +1 -0
  534. data/lib/rubygems/vendor/securerandom/COPYING +56 -0
  535. data/lib/rubygems/vendor/securerandom/lib/securerandom.rb +102 -0
  536. data/lib/rubygems/vendor/timeout/.document +1 -0
  537. data/lib/rubygems/vendor/timeout/COPYING +56 -0
  538. data/lib/rubygems/vendor/timeout/lib/timeout.rb +198 -0
  539. data/lib/rubygems/vendor/tsort/.document +1 -0
  540. data/lib/rubygems/vendor/tsort/lib/tsort.rb +455 -0
  541. data/lib/rubygems/vendor/uri/.document +1 -0
  542. data/lib/rubygems/vendor/uri/COPYING +56 -0
  543. data/lib/rubygems/vendor/uri/lib/uri/common.rb +876 -0
  544. data/lib/rubygems/vendor/uri/lib/uri/file.rb +100 -0
  545. data/lib/rubygems/vendor/uri/lib/uri/ftp.rb +267 -0
  546. data/lib/rubygems/vendor/uri/lib/uri/generic.rb +1578 -0
  547. data/lib/rubygems/vendor/uri/lib/uri/http.rb +125 -0
  548. data/lib/rubygems/vendor/uri/lib/uri/https.rb +23 -0
  549. data/lib/rubygems/vendor/uri/lib/uri/ldap.rb +261 -0
  550. data/lib/rubygems/vendor/uri/lib/uri/ldaps.rb +22 -0
  551. data/lib/rubygems/vendor/uri/lib/uri/mailto.rb +293 -0
  552. data/lib/rubygems/vendor/uri/lib/uri/rfc2396_parser.rb +546 -0
  553. data/lib/rubygems/vendor/uri/lib/uri/rfc3986_parser.rb +206 -0
  554. data/lib/rubygems/vendor/uri/lib/uri/version.rb +6 -0
  555. data/lib/rubygems/vendor/uri/lib/uri/ws.rb +83 -0
  556. data/lib/rubygems/vendor/uri/lib/uri/wss.rb +23 -0
  557. data/lib/rubygems/vendor/uri/lib/uri.rb +104 -0
  558. data/{bundler/lib/bundler → lib/rubygems}/vendored_molinillo.rb +0 -1
  559. data/lib/rubygems/vendored_net_http.rb +5 -0
  560. data/lib/rubygems/vendored_optparse.rb +3 -0
  561. data/lib/rubygems/vendored_securerandom.rb +3 -0
  562. data/lib/rubygems/vendored_timeout.rb +5 -0
  563. data/lib/rubygems/vendored_tsort.rb +3 -0
  564. data/lib/rubygems/version.rb +57 -45
  565. data/lib/rubygems/version_option.rb +6 -8
  566. data/lib/rubygems/yaml_serializer.rb +98 -0
  567. data/lib/rubygems.rb +191 -133
  568. data/rubygems-update.gemspec +16 -9
  569. data/setup.rb +12 -9
  570. metadata +233 -307
  571. data/POLICIES.md +0 -100
  572. data/bin/gem +0 -13
  573. data/bundler/lib/bundler/dep_proxy.rb +0 -55
  574. data/bundler/lib/bundler/templates/gems.rb +0 -5
  575. data/bundler/lib/bundler/templates/newgem/ext/newgem/extconf.rb.tt +0 -5
  576. data/bundler/lib/bundler/templates/newgem/travis.yml.tt +0 -6
  577. data/bundler/lib/bundler/vendor/molinillo/lib/molinillo/delegates/resolution_state.rb +0 -57
  578. data/bundler/lib/bundler/vendor/molinillo/lib/molinillo/gem_metadata.rb +0 -6
  579. data/bundler/lib/bundler/vendor/tmpdir/lib/tmpdir.rb +0 -154
  580. data/bundler/lib/bundler/version_ranges.rb +0 -122
  581. data/lib/rubygems/indexer.rb +0 -427
  582. data/lib/rubygems/mock_gem_ui.rb +0 -85
  583. data/lib/rubygems/optparse/lib/optparse/uri.rb +0 -7
  584. data/lib/rubygems/optparse.rb +0 -3
  585. data/lib/rubygems/resolver/molinillo/LICENSE +0 -9
  586. data/lib/rubygems/resolver/molinillo/lib/molinillo/delegates/resolution_state.rb +0 -57
  587. data/lib/rubygems/resolver/molinillo/lib/molinillo/delegates/specification_provider.rb +0 -88
  588. data/lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph/action.rb +0 -36
  589. data/lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph/add_edge_no_circular.rb +0 -66
  590. data/lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph/add_vertex.rb +0 -62
  591. data/lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph/delete_edge.rb +0 -63
  592. data/lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph/detach_vertex_named.rb +0 -61
  593. data/lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph/log.rb +0 -126
  594. data/lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph/set_payload.rb +0 -46
  595. data/lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph/tag.rb +0 -36
  596. data/lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph/vertex.rb +0 -164
  597. data/lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph.rb +0 -255
  598. data/lib/rubygems/resolver/molinillo/lib/molinillo/errors.rb +0 -143
  599. data/lib/rubygems/resolver/molinillo/lib/molinillo/gem_metadata.rb +0 -6
  600. data/lib/rubygems/resolver/molinillo/lib/molinillo/modules/specification_provider.rb +0 -112
  601. data/lib/rubygems/resolver/molinillo/lib/molinillo/modules/ui.rb +0 -67
  602. data/lib/rubygems/resolver/molinillo/lib/molinillo/resolution.rb +0 -839
  603. data/lib/rubygems/resolver/molinillo/lib/molinillo/resolver.rb +0 -46
  604. data/lib/rubygems/resolver/molinillo/lib/molinillo/state.rb +0 -58
  605. data/lib/rubygems/resolver/molinillo/lib/molinillo.rb +0 -11
  606. data/lib/rubygems/resolver/molinillo.rb +0 -2
  607. data/lib/rubygems/tsort/LICENSE.txt +0 -22
  608. data/lib/rubygems/tsort/lib/tsort.rb +0 -454
  609. data/lib/rubygems/tsort.rb +0 -3
  610. data/test/rubygems/alternate_cert.pem +0 -19
  611. data/test/rubygems/alternate_cert_32.pem +0 -19
  612. data/test/rubygems/alternate_key.pem +0 -27
  613. data/test/rubygems/bad_rake.rb +0 -2
  614. data/test/rubygems/ca_cert.pem +0 -77
  615. data/test/rubygems/child_cert.pem +0 -20
  616. data/test/rubygems/child_cert_32.pem +0 -20
  617. data/test/rubygems/child_key.pem +0 -27
  618. data/test/rubygems/client.pem +0 -107
  619. data/test/rubygems/data/excon-0.7.7.gemspec.rz +0 -0
  620. data/test/rubygems/data/gem-private_key.pem +0 -27
  621. data/test/rubygems/data/gem-public_cert.pem +0 -20
  622. data/test/rubygems/data/null-required-ruby-version.gemspec.rz +0 -0
  623. data/test/rubygems/data/null-required-rubygems-version.gemspec.rz +0 -0
  624. data/test/rubygems/data/pry-0.4.7.gemspec.rz +0 -0
  625. data/test/rubygems/encrypted_private_key.pem +0 -30
  626. data/test/rubygems/expired_cert.pem +0 -19
  627. data/test/rubygems/foo/discover.rb +0 -1
  628. data/test/rubygems/future_cert.pem +0 -19
  629. data/test/rubygems/future_cert_32.pem +0 -19
  630. data/test/rubygems/good_rake.rb +0 -2
  631. data/test/rubygems/grandchild_cert.pem +0 -20
  632. data/test/rubygems/grandchild_cert_32.pem +0 -20
  633. data/test/rubygems/grandchild_key.pem +0 -27
  634. data/test/rubygems/helper.rb +0 -1622
  635. data/test/rubygems/installer_test_case.rb +0 -247
  636. data/test/rubygems/invalid_client.pem +0 -49
  637. data/test/rubygems/invalid_issuer_cert.pem +0 -20
  638. data/test/rubygems/invalid_issuer_cert_32.pem +0 -20
  639. data/test/rubygems/invalid_key.pem +0 -27
  640. data/test/rubygems/invalid_signer_cert.pem +0 -19
  641. data/test/rubygems/invalid_signer_cert_32.pem +0 -19
  642. data/test/rubygems/invalidchild_cert.pem +0 -20
  643. data/test/rubygems/invalidchild_cert_32.pem +0 -20
  644. data/test/rubygems/invalidchild_key.pem +0 -27
  645. data/test/rubygems/package/tar_test_case.rb +0 -139
  646. data/test/rubygems/packages/ascii_binder-0.1.10.1.gem +0 -0
  647. data/test/rubygems/packages/ill-formatted-platform-1.0.0.10.gem +0 -0
  648. data/test/rubygems/plugin/exception/rubygems_plugin.rb +0 -3
  649. data/test/rubygems/plugin/load/rubygems_plugin.rb +0 -4
  650. data/test/rubygems/plugin/standarderror/rubygems_plugin.rb +0 -3
  651. data/test/rubygems/private3072_key.pem +0 -40
  652. data/test/rubygems/private_ec_key.pem +0 -9
  653. data/test/rubygems/private_key.pem +0 -27
  654. data/test/rubygems/public3072_cert.pem +0 -25
  655. data/test/rubygems/public_cert.pem +0 -20
  656. data/test/rubygems/public_cert_32.pem +0 -19
  657. data/test/rubygems/public_key.pem +0 -9
  658. data/test/rubygems/rubygems/commands/crash_command.rb +0 -4
  659. data/test/rubygems/rubygems_plugin.rb +0 -23
  660. data/test/rubygems/sff/discover.rb +0 -1
  661. data/test/rubygems/simple_gem.rb +0 -67
  662. data/test/rubygems/specifications/bar-0.0.2.gemspec +0 -7
  663. data/test/rubygems/specifications/foo-0.0.1-x86-mswin32.gemspec +0 -0
  664. data/test/rubygems/specifications/rubyforge-0.0.1.gemspec +0 -12
  665. data/test/rubygems/ssl_cert.pem +0 -80
  666. data/test/rubygems/ssl_key.pem +0 -27
  667. data/test/rubygems/test_bundled_ca.rb +0 -60
  668. data/test/rubygems/test_config.rb +0 -27
  669. data/test/rubygems/test_deprecate.rb +0 -157
  670. data/test/rubygems/test_exit.rb +0 -11
  671. data/test/rubygems/test_gem.rb +0 -2112
  672. data/test/rubygems/test_gem_available_set.rb +0 -129
  673. data/test/rubygems/test_gem_bundler_version_finder.rb +0 -125
  674. data/test/rubygems/test_gem_command.rb +0 -400
  675. data/test/rubygems/test_gem_command_manager.rb +0 -334
  676. data/test/rubygems/test_gem_commands_build_command.rb +0 -727
  677. data/test/rubygems/test_gem_commands_cert_command.rb +0 -867
  678. data/test/rubygems/test_gem_commands_check_command.rb +0 -67
  679. data/test/rubygems/test_gem_commands_cleanup_command.rb +0 -291
  680. data/test/rubygems/test_gem_commands_contents_command.rb +0 -270
  681. data/test/rubygems/test_gem_commands_dependency_command.rb +0 -227
  682. data/test/rubygems/test_gem_commands_environment_command.rb +0 -167
  683. data/test/rubygems/test_gem_commands_fetch_command.rb +0 -257
  684. data/test/rubygems/test_gem_commands_generate_index_command.rb +0 -80
  685. data/test/rubygems/test_gem_commands_help_command.rb +0 -93
  686. data/test/rubygems/test_gem_commands_info_command.rb +0 -43
  687. data/test/rubygems/test_gem_commands_install_command.rb +0 -1553
  688. data/test/rubygems/test_gem_commands_list_command.rb +0 -32
  689. data/test/rubygems/test_gem_commands_lock_command.rb +0 -66
  690. data/test/rubygems/test_gem_commands_mirror.rb +0 -19
  691. data/test/rubygems/test_gem_commands_open_command.rb +0 -97
  692. data/test/rubygems/test_gem_commands_outdated_command.rb +0 -49
  693. data/test/rubygems/test_gem_commands_owner_command.rb +0 -326
  694. data/test/rubygems/test_gem_commands_pristine_command.rb +0 -659
  695. data/test/rubygems/test_gem_commands_push_command.rb +0 -477
  696. data/test/rubygems/test_gem_commands_query_command.rb +0 -857
  697. data/test/rubygems/test_gem_commands_search_command.rb +0 -15
  698. data/test/rubygems/test_gem_commands_server_command.rb +0 -19
  699. data/test/rubygems/test_gem_commands_setup_command.rb +0 -447
  700. data/test/rubygems/test_gem_commands_signin_command.rb +0 -219
  701. data/test/rubygems/test_gem_commands_signout_command.rb +0 -30
  702. data/test/rubygems/test_gem_commands_sources_command.rb +0 -534
  703. data/test/rubygems/test_gem_commands_specification_command.rb +0 -276
  704. data/test/rubygems/test_gem_commands_stale_command.rb +0 -42
  705. data/test/rubygems/test_gem_commands_uninstall_command.rb +0 -504
  706. data/test/rubygems/test_gem_commands_unpack_command.rb +0 -223
  707. data/test/rubygems/test_gem_commands_update_command.rb +0 -835
  708. data/test/rubygems/test_gem_commands_which_command.rb +0 -84
  709. data/test/rubygems/test_gem_commands_yank_command.rb +0 -180
  710. data/test/rubygems/test_gem_config_file.rb +0 -504
  711. data/test/rubygems/test_gem_dependency.rb +0 -395
  712. data/test/rubygems/test_gem_dependency_installer.rb +0 -1155
  713. data/test/rubygems/test_gem_dependency_list.rb +0 -264
  714. data/test/rubygems/test_gem_dependency_resolution_error.rb +0 -26
  715. data/test/rubygems/test_gem_doctor.rb +0 -194
  716. data/test/rubygems/test_gem_ext_builder.rb +0 -338
  717. data/test/rubygems/test_gem_ext_cargo_builder/custom_name/.gitignore +0 -1
  718. data/test/rubygems/test_gem_ext_cargo_builder/custom_name/Cargo.lock +0 -243
  719. data/test/rubygems/test_gem_ext_cargo_builder/custom_name/Cargo.toml +0 -10
  720. data/test/rubygems/test_gem_ext_cargo_builder/custom_name/build.rb +0 -21
  721. data/test/rubygems/test_gem_ext_cargo_builder/custom_name/custom_name.gemspec +0 -10
  722. data/test/rubygems/test_gem_ext_cargo_builder/custom_name/src/lib.rs +0 -27
  723. data/test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/.gitignore +0 -1
  724. data/test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/Cargo.lock +0 -243
  725. data/test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/Cargo.toml +0 -10
  726. data/test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/build.rb +0 -21
  727. data/test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/rust_ruby_example.gemspec +0 -8
  728. data/test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/src/lib.rs +0 -39
  729. data/test/rubygems/test_gem_ext_cargo_builder.rb +0 -178
  730. data/test/rubygems/test_gem_ext_cargo_builder_link_flag_converter.rb +0 -33
  731. data/test/rubygems/test_gem_ext_cargo_builder_unit.rb +0 -75
  732. data/test/rubygems/test_gem_ext_cmake_builder.rb +0 -83
  733. data/test/rubygems/test_gem_ext_configure_builder.rb +0 -79
  734. data/test/rubygems/test_gem_ext_ext_conf_builder.rb +0 -230
  735. data/test/rubygems/test_gem_ext_rake_builder.rb +0 -112
  736. data/test/rubygems/test_gem_gem_runner.rb +0 -113
  737. data/test/rubygems/test_gem_gemcutter_utilities.rb +0 -272
  738. data/test/rubygems/test_gem_impossible_dependencies_error.rb +0 -59
  739. data/test/rubygems/test_gem_indexer.rb +0 -361
  740. data/test/rubygems/test_gem_install_update_options.rb +0 -207
  741. data/test/rubygems/test_gem_installer.rb +0 -2394
  742. data/test/rubygems/test_gem_local_remote_options.rb +0 -132
  743. data/test/rubygems/test_gem_name_tuple.rb +0 -42
  744. data/test/rubygems/test_gem_package.rb +0 -1178
  745. data/test/rubygems/test_gem_package_old.rb +0 -90
  746. data/test/rubygems/test_gem_package_tar_header.rb +0 -225
  747. data/test/rubygems/test_gem_package_tar_reader.rb +0 -87
  748. data/test/rubygems/test_gem_package_tar_reader_entry.rb +0 -152
  749. data/test/rubygems/test_gem_package_tar_writer.rb +0 -330
  750. data/test/rubygems/test_gem_package_task.rb +0 -117
  751. data/test/rubygems/test_gem_path_support.rb +0 -138
  752. data/test/rubygems/test_gem_platform.rb +0 -391
  753. data/test/rubygems/test_gem_rdoc.rb +0 -136
  754. data/test/rubygems/test_gem_remote_fetcher.rb +0 -1226
  755. data/test/rubygems/test_gem_request.rb +0 -541
  756. data/test/rubygems/test_gem_request_connection_pools.rb +0 -150
  757. data/test/rubygems/test_gem_request_set.rb +0 -671
  758. data/test/rubygems/test_gem_request_set_gem_dependency_api.rb +0 -847
  759. data/test/rubygems/test_gem_request_set_lockfile.rb +0 -468
  760. data/test/rubygems/test_gem_request_set_lockfile_parser.rb +0 -543
  761. data/test/rubygems/test_gem_request_set_lockfile_tokenizer.rb +0 -306
  762. data/test/rubygems/test_gem_requirement.rb +0 -498
  763. data/test/rubygems/test_gem_resolver.rb +0 -791
  764. data/test/rubygems/test_gem_resolver_activation_request.rb +0 -42
  765. data/test/rubygems/test_gem_resolver_api_set.rb +0 -209
  766. data/test/rubygems/test_gem_resolver_api_specification.rb +0 -166
  767. data/test/rubygems/test_gem_resolver_best_set.rb +0 -158
  768. data/test/rubygems/test_gem_resolver_composed_set.rb +0 -43
  769. data/test/rubygems/test_gem_resolver_conflict.rb +0 -81
  770. data/test/rubygems/test_gem_resolver_dependency_request.rb +0 -82
  771. data/test/rubygems/test_gem_resolver_git_set.rb +0 -187
  772. data/test/rubygems/test_gem_resolver_git_specification.rb +0 -113
  773. data/test/rubygems/test_gem_resolver_index_set.rb +0 -87
  774. data/test/rubygems/test_gem_resolver_index_specification.rb +0 -92
  775. data/test/rubygems/test_gem_resolver_installed_specification.rb +0 -46
  776. data/test/rubygems/test_gem_resolver_installer_set.rb +0 -275
  777. data/test/rubygems/test_gem_resolver_local_specification.rb +0 -43
  778. data/test/rubygems/test_gem_resolver_lock_set.rb +0 -61
  779. data/test/rubygems/test_gem_resolver_lock_specification.rb +0 -97
  780. data/test/rubygems/test_gem_resolver_requirement_list.rb +0 -18
  781. data/test/rubygems/test_gem_resolver_specification.rb +0 -62
  782. data/test/rubygems/test_gem_resolver_vendor_set.rb +0 -81
  783. data/test/rubygems/test_gem_resolver_vendor_specification.rb +0 -81
  784. data/test/rubygems/test_gem_security.rb +0 -340
  785. data/test/rubygems/test_gem_security_policy.rb +0 -535
  786. data/test/rubygems/test_gem_security_signer.rb +0 -217
  787. data/test/rubygems/test_gem_security_trust_dir.rb +0 -98
  788. data/test/rubygems/test_gem_silent_ui.rb +0 -116
  789. data/test/rubygems/test_gem_source.rb +0 -253
  790. data/test/rubygems/test_gem_source_fetch_problem.rb +0 -36
  791. data/test/rubygems/test_gem_source_git.rb +0 -303
  792. data/test/rubygems/test_gem_source_installed.rb +0 -34
  793. data/test/rubygems/test_gem_source_list.rb +0 -118
  794. data/test/rubygems/test_gem_source_local.rb +0 -106
  795. data/test/rubygems/test_gem_source_lock.rb +0 -112
  796. data/test/rubygems/test_gem_source_specific_file.rb +0 -75
  797. data/test/rubygems/test_gem_source_subpath_problem.rb +0 -49
  798. data/test/rubygems/test_gem_source_vendor.rb +0 -29
  799. data/test/rubygems/test_gem_spec_fetcher.rb +0 -337
  800. data/test/rubygems/test_gem_specification.rb +0 -3756
  801. data/test/rubygems/test_gem_stream_ui.rb +0 -224
  802. data/test/rubygems/test_gem_stub_specification.rb +0 -277
  803. data/test/rubygems/test_gem_text.rb +0 -102
  804. data/test/rubygems/test_gem_uninstaller.rb +0 -674
  805. data/test/rubygems/test_gem_unsatisfiable_dependency_error.rb +0 -30
  806. data/test/rubygems/test_gem_uri.rb +0 -39
  807. data/test/rubygems/test_gem_uri_formatter.rb +0 -26
  808. data/test/rubygems/test_gem_util.rb +0 -90
  809. data/test/rubygems/test_gem_validator.rb +0 -42
  810. data/test/rubygems/test_gem_version.rb +0 -295
  811. data/test/rubygems/test_gem_version_option.rb +0 -164
  812. data/test/rubygems/test_kernel.rb +0 -129
  813. data/test/rubygems/test_project_sanity.rb +0 -20
  814. data/test/rubygems/test_remote_fetch_error.rb +0 -19
  815. data/test/rubygems/test_require.rb +0 -719
  816. data/test/rubygems/test_rubygems.rb +0 -74
  817. data/test/rubygems/utilities.rb +0 -371
  818. data/test/rubygems/wrong_key_cert.pem +0 -19
  819. data/test/rubygems/wrong_key_cert_32.pem +0 -19
  820. data/test/test_changelog_generator.rb +0 -17
  821. /data/{lib/rubygems/optparse → bundler/lib/bundler/vendor/connection_pool}/.document +0 -0
  822. /data/{lib/rubygems/tsort → bundler/lib/bundler/vendor/fileutils}/.document +0 -0
  823. /data/{lib/rubygems/optparse → bundler/lib/bundler/vendor/fileutils}/COPYING +0 -0
  824. /data/{MAINTAINERS.txt → doc/MAINTAINERS.txt} +0 -0
  825. /data/{UPGRADING.md → doc/rubygems/UPGRADING.md} +0 -0
  826. /data/{bundler/lib/bundler → lib/rubygems}/vendor/molinillo/LICENSE +0 -0
  827. /data/{bundler/lib/bundler/vendor/fileutils → lib/rubygems/vendor/net-protocol}/LICENSE.txt +0 -0
  828. /data/lib/rubygems/{optparse → vendor/optparse}/lib/optionparser.rb +0 -0
  829. /data/lib/rubygems/{optparse → vendor/optparse}/lib/optparse/date.rb +0 -0
  830. /data/lib/rubygems/{optparse → vendor/optparse}/lib/optparse/shellwords.rb +0 -0
  831. /data/lib/rubygems/{optparse → vendor/optparse}/lib/optparse/time.rb +0 -0
  832. /data/{bundler/lib/bundler/vendor/uri → lib/rubygems/vendor/tsort}/LICENSE.txt +0 -0
@@ -3,106 +3,185 @@
3
3
  begin
4
4
  require 'rbconfig'
5
5
  rescue LoadError
6
- # for make mjit-headers
6
+ # for make rjit-headers
7
7
  end
8
8
 
9
+ # Namespace for file utility methods for copying, moving, removing, etc.
9
10
  #
10
- # = fileutils.rb
11
+ # == What's Here
11
12
  #
12
- # Copyright (c) 2000-2007 Minero Aoki
13
+ # First, what’s elsewhere. \Module \Bundler::FileUtils:
13
14
  #
14
- # This program is free software.
15
- # You can distribute/modify this program under the same terms of ruby.
15
+ # - Inherits from {class Object}[https://docs.ruby-lang.org/en/master/Object.html].
16
+ # - Supplements {class File}[https://docs.ruby-lang.org/en/master/File.html]
17
+ # (but is not included or extended there).
16
18
  #
17
- # == module Bundler::FileUtils
19
+ # Here, module \Bundler::FileUtils provides methods that are useful for:
18
20
  #
19
- # Namespace for several file utility methods for copying, moving, removing, etc.
21
+ # - {Creating}[rdoc-ref:FileUtils@Creating].
22
+ # - {Deleting}[rdoc-ref:FileUtils@Deleting].
23
+ # - {Querying}[rdoc-ref:FileUtils@Querying].
24
+ # - {Setting}[rdoc-ref:FileUtils@Setting].
25
+ # - {Comparing}[rdoc-ref:FileUtils@Comparing].
26
+ # - {Copying}[rdoc-ref:FileUtils@Copying].
27
+ # - {Moving}[rdoc-ref:FileUtils@Moving].
28
+ # - {Options}[rdoc-ref:FileUtils@Options].
20
29
  #
21
- # === Module Functions
30
+ # === Creating
22
31
  #
23
- # require 'bundler/vendor/fileutils/lib/fileutils'
32
+ # - ::mkdir: Creates directories.
33
+ # - ::mkdir_p, ::makedirs, ::mkpath: Creates directories,
34
+ # also creating ancestor directories as needed.
35
+ # - ::link_entry: Creates a hard link.
36
+ # - ::ln, ::link: Creates hard links.
37
+ # - ::ln_s, ::symlink: Creates symbolic links.
38
+ # - ::ln_sf: Creates symbolic links, overwriting if necessary.
39
+ # - ::ln_sr: Creates symbolic links relative to targets
24
40
  #
25
- # Bundler::FileUtils.cd(dir, **options)
26
- # Bundler::FileUtils.cd(dir, **options) {|dir| block }
27
- # Bundler::FileUtils.pwd()
28
- # Bundler::FileUtils.mkdir(dir, **options)
29
- # Bundler::FileUtils.mkdir(list, **options)
30
- # Bundler::FileUtils.mkdir_p(dir, **options)
31
- # Bundler::FileUtils.mkdir_p(list, **options)
32
- # Bundler::FileUtils.rmdir(dir, **options)
33
- # Bundler::FileUtils.rmdir(list, **options)
34
- # Bundler::FileUtils.ln(target, link, **options)
35
- # Bundler::FileUtils.ln(targets, dir, **options)
36
- # Bundler::FileUtils.ln_s(target, link, **options)
37
- # Bundler::FileUtils.ln_s(targets, dir, **options)
38
- # Bundler::FileUtils.ln_sf(target, link, **options)
39
- # Bundler::FileUtils.cp(src, dest, **options)
40
- # Bundler::FileUtils.cp(list, dir, **options)
41
- # Bundler::FileUtils.cp_r(src, dest, **options)
42
- # Bundler::FileUtils.cp_r(list, dir, **options)
43
- # Bundler::FileUtils.mv(src, dest, **options)
44
- # Bundler::FileUtils.mv(list, dir, **options)
45
- # Bundler::FileUtils.rm(list, **options)
46
- # Bundler::FileUtils.rm_r(list, **options)
47
- # Bundler::FileUtils.rm_rf(list, **options)
48
- # Bundler::FileUtils.install(src, dest, **options)
49
- # Bundler::FileUtils.chmod(mode, list, **options)
50
- # Bundler::FileUtils.chmod_R(mode, list, **options)
51
- # Bundler::FileUtils.chown(user, group, list, **options)
52
- # Bundler::FileUtils.chown_R(user, group, list, **options)
53
- # Bundler::FileUtils.touch(list, **options)
41
+ # === Deleting
54
42
  #
55
- # Possible <tt>options</tt> are:
43
+ # - ::remove_dir: Removes a directory and its descendants.
44
+ # - ::remove_entry: Removes an entry, including its descendants if it is a directory.
45
+ # - ::remove_entry_secure: Like ::remove_entry, but removes securely.
46
+ # - ::remove_file: Removes a file entry.
47
+ # - ::rm, ::remove: Removes entries.
48
+ # - ::rm_f, ::safe_unlink: Like ::rm, but removes forcibly.
49
+ # - ::rm_r: Removes entries and their descendants.
50
+ # - ::rm_rf, ::rmtree: Like ::rm_r, but removes forcibly.
51
+ # - ::rmdir: Removes directories.
56
52
  #
57
- # <tt>:force</tt> :: forced operation (rewrite files if exist, remove
58
- # directories if not empty, etc.);
59
- # <tt>:verbose</tt> :: print command to be run, in bash syntax, before
60
- # performing it;
61
- # <tt>:preserve</tt> :: preserve object's group, user and modification
62
- # time on copying;
63
- # <tt>:noop</tt> :: no changes are made (usable in combination with
64
- # <tt>:verbose</tt> which will print the command to run)
53
+ # === Querying
65
54
  #
66
- # Each method documents the options that it honours. See also ::commands,
67
- # ::options and ::options_of methods to introspect which command have which
68
- # options.
55
+ # - ::pwd, ::getwd: Returns the path to the working directory.
56
+ # - ::uptodate?: Returns whether a given entry is newer than given other entries.
69
57
  #
70
- # All methods that have the concept of a "source" file or directory can take
71
- # either one file or a list of files in that argument. See the method
72
- # documentation for examples.
58
+ # === Setting
73
59
  #
74
- # There are some `low level' methods, which do not accept keyword arguments:
60
+ # - ::cd, ::chdir: Sets the working directory.
61
+ # - ::chmod: Sets permissions for an entry.
62
+ # - ::chmod_R: Sets permissions for an entry and its descendants.
63
+ # - ::chown: Sets the owner and group for entries.
64
+ # - ::chown_R: Sets the owner and group for entries and their descendants.
65
+ # - ::touch: Sets modification and access times for entries,
66
+ # creating if necessary.
75
67
  #
76
- # Bundler::FileUtils.copy_entry(src, dest, preserve = false, dereference_root = false, remove_destination = false)
77
- # Bundler::FileUtils.copy_file(src, dest, preserve = false, dereference = true)
78
- # Bundler::FileUtils.copy_stream(srcstream, deststream)
79
- # Bundler::FileUtils.remove_entry(path, force = false)
80
- # Bundler::FileUtils.remove_entry_secure(path, force = false)
81
- # Bundler::FileUtils.remove_file(path, force = false)
82
- # Bundler::FileUtils.compare_file(path_a, path_b)
83
- # Bundler::FileUtils.compare_stream(stream_a, stream_b)
84
- # Bundler::FileUtils.uptodate?(file, cmp_list)
68
+ # === Comparing
85
69
  #
86
- # == module Bundler::FileUtils::Verbose
70
+ # - ::compare_file, ::cmp, ::identical?: Returns whether two entries are identical.
71
+ # - ::compare_stream: Returns whether two streams are identical.
87
72
  #
88
- # This module has all methods of Bundler::FileUtils module, but it outputs messages
89
- # before acting. This equates to passing the <tt>:verbose</tt> flag to methods
90
- # in Bundler::FileUtils.
73
+ # === Copying
91
74
  #
92
- # == module Bundler::FileUtils::NoWrite
75
+ # - ::copy_entry: Recursively copies an entry.
76
+ # - ::copy_file: Copies an entry.
77
+ # - ::copy_stream: Copies a stream.
78
+ # - ::cp, ::copy: Copies files.
79
+ # - ::cp_lr: Recursively creates hard links.
80
+ # - ::cp_r: Recursively copies files, retaining mode, owner, and group.
81
+ # - ::install: Recursively copies files, optionally setting mode,
82
+ # owner, and group.
93
83
  #
94
- # This module has all methods of Bundler::FileUtils module, but never changes
95
- # files/directories. This equates to passing the <tt>:noop</tt> flag to methods
96
- # in Bundler::FileUtils.
84
+ # === Moving
97
85
  #
98
- # == module Bundler::FileUtils::DryRun
86
+ # - ::mv, ::move: Moves entries.
99
87
  #
100
- # This module has all methods of Bundler::FileUtils module, but never changes
101
- # files/directories. This equates to passing the <tt>:noop</tt> and
102
- # <tt>:verbose</tt> flags to methods in Bundler::FileUtils.
88
+ # === Options
89
+ #
90
+ # - ::collect_method: Returns the names of methods that accept a given option.
91
+ # - ::commands: Returns the names of methods that accept options.
92
+ # - ::have_option?: Returns whether a given method accepts a given option.
93
+ # - ::options: Returns all option names.
94
+ # - ::options_of: Returns the names of the options for a given method.
95
+ #
96
+ # == Path Arguments
97
+ #
98
+ # Some methods in \Bundler::FileUtils accept _path_ arguments,
99
+ # which are interpreted as paths to filesystem entries:
100
+ #
101
+ # - If the argument is a string, that value is the path.
102
+ # - If the argument has method +:to_path+, it is converted via that method.
103
+ # - If the argument has method +:to_str+, it is converted via that method.
104
+ #
105
+ # == About the Examples
106
+ #
107
+ # Some examples here involve trees of file entries.
108
+ # For these, we sometimes display trees using the
109
+ # {tree command-line utility}[https://en.wikipedia.org/wiki/Tree_(command)],
110
+ # which is a recursive directory-listing utility that produces
111
+ # a depth-indented listing of files and directories.
112
+ #
113
+ # We use a helper method to launch the command and control the format:
114
+ #
115
+ # def tree(dirpath = '.')
116
+ # command = "tree --noreport --charset=ascii #{dirpath}"
117
+ # system(command)
118
+ # end
119
+ #
120
+ # To illustrate:
121
+ #
122
+ # tree('src0')
123
+ # # => src0
124
+ # # |-- sub0
125
+ # # | |-- src0.txt
126
+ # # | `-- src1.txt
127
+ # # `-- sub1
128
+ # # |-- src2.txt
129
+ # # `-- src3.txt
130
+ #
131
+ # == Avoiding the TOCTTOU Vulnerability
132
+ #
133
+ # For certain methods that recursively remove entries,
134
+ # there is a potential vulnerability called the
135
+ # {Time-of-check to time-of-use}[https://en.wikipedia.org/wiki/Time-of-check_to_time-of-use],
136
+ # or TOCTTOU, vulnerability that can exist when:
137
+ #
138
+ # - An ancestor directory of the entry at the target path is world writable;
139
+ # such directories include <tt>/tmp</tt>.
140
+ # - The directory tree at the target path includes:
141
+ #
142
+ # - A world-writable descendant directory.
143
+ # - A symbolic link.
144
+ #
145
+ # To avoid that vulnerability, you can use this method to remove entries:
146
+ #
147
+ # - Bundler::FileUtils.remove_entry_secure: removes recursively
148
+ # if the target path points to a directory.
149
+ #
150
+ # Also available are these methods,
151
+ # each of which calls \Bundler::FileUtils.remove_entry_secure:
152
+ #
153
+ # - Bundler::FileUtils.rm_r with keyword argument <tt>secure: true</tt>.
154
+ # - Bundler::FileUtils.rm_rf with keyword argument <tt>secure: true</tt>.
155
+ #
156
+ # Finally, this method for moving entries calls \Bundler::FileUtils.remove_entry_secure
157
+ # if the source and destination are on different file systems
158
+ # (which means that the "move" is really a copy and remove):
159
+ #
160
+ # - Bundler::FileUtils.mv with keyword argument <tt>secure: true</tt>.
161
+ #
162
+ # \Method \Bundler::FileUtils.remove_entry_secure removes securely
163
+ # by applying a special pre-process:
164
+ #
165
+ # - If the target path points to a directory, this method uses methods
166
+ # {File#chown}[https://docs.ruby-lang.org/en/master/File.html#method-i-chown]
167
+ # and {File#chmod}[https://docs.ruby-lang.org/en/master/File.html#method-i-chmod]
168
+ # in removing directories.
169
+ # - The owner of the target directory should be either the current process
170
+ # or the super user (root).
171
+ #
172
+ # WARNING: You must ensure that *ALL* parent directories cannot be
173
+ # moved by other untrusted users. For example, parent directories
174
+ # should not be owned by untrusted users, and should not be world
175
+ # writable except when the sticky bit is set.
176
+ #
177
+ # For details of this security vulnerability, see Perl cases:
178
+ #
179
+ # - {CVE-2005-0448}[https://cve.mitre.org/cgi-bin/cvename.cgi?name=CAN-2005-0448].
180
+ # - {CVE-2004-0452}[https://cve.mitre.org/cgi-bin/cvename.cgi?name=CAN-2004-0452].
103
181
  #
104
182
  module Bundler::FileUtils
105
- VERSION = "1.4.1"
183
+ # The version number.
184
+ VERSION = "1.7.3"
106
185
 
107
186
  def self.private_module_function(name) #:nodoc:
108
187
  module_function name
@@ -110,7 +189,11 @@ module Bundler::FileUtils
110
189
  end
111
190
 
112
191
  #
113
- # Returns the name of the current directory.
192
+ # Returns a string containing the path to the current directory:
193
+ #
194
+ # Bundler::FileUtils.pwd # => "/rdoc/fileutils"
195
+ #
196
+ # Related: Bundler::FileUtils.cd.
114
197
  #
115
198
  def pwd
116
199
  Dir.pwd
@@ -120,19 +203,38 @@ module Bundler::FileUtils
120
203
  alias getwd pwd
121
204
  module_function :getwd
122
205
 
206
+ # Changes the working directory to the given +dir+, which
207
+ # should be {interpretable as a path}[rdoc-ref:FileUtils@Path+Arguments]:
208
+ #
209
+ # With no block given,
210
+ # changes the current directory to the directory at +dir+; returns zero:
211
+ #
212
+ # Bundler::FileUtils.pwd # => "/rdoc/fileutils"
213
+ # Bundler::FileUtils.cd('..')
214
+ # Bundler::FileUtils.pwd # => "/rdoc"
215
+ # Bundler::FileUtils.cd('fileutils')
216
+ #
217
+ # With a block given, changes the current directory to the directory
218
+ # at +dir+, calls the block with argument +dir+,
219
+ # and restores the original current directory; returns the block's value:
123
220
  #
124
- # Changes the current directory to the directory +dir+.
221
+ # Bundler::FileUtils.pwd # => "/rdoc/fileutils"
222
+ # Bundler::FileUtils.cd('..') { |arg| [arg, Bundler::FileUtils.pwd] } # => ["..", "/rdoc"]
223
+ # Bundler::FileUtils.pwd # => "/rdoc/fileutils"
125
224
  #
126
- # If this method is called with block, resumes to the previous
127
- # working directory after the block execution has finished.
225
+ # Keyword arguments:
128
226
  #
129
- # Bundler::FileUtils.cd('/') # change directory
227
+ # - <tt>verbose: true</tt> - prints an equivalent command:
130
228
  #
131
- # Bundler::FileUtils.cd('/', verbose: true) # change directory and report it
229
+ # Bundler::FileUtils.cd('..')
230
+ # Bundler::FileUtils.cd('fileutils')
132
231
  #
133
- # Bundler::FileUtils.cd('/') do # change directory
134
- # # ... # do something
135
- # end # return to original directory
232
+ # Output:
233
+ #
234
+ # cd ..
235
+ # cd fileutils
236
+ #
237
+ # Related: Bundler::FileUtils.pwd.
136
238
  #
137
239
  def cd(dir, verbose: nil, &block) # :yield: dir
138
240
  fu_output_message "cd #{dir}" if verbose
@@ -146,11 +248,19 @@ module Bundler::FileUtils
146
248
  module_function :chdir
147
249
 
148
250
  #
149
- # Returns true if +new+ is newer than all +old_list+.
150
- # Non-existent files are older than any file.
251
+ # Returns +true+ if the file at path +new+
252
+ # is newer than all the files at paths in array +old_list+;
253
+ # +false+ otherwise.
254
+ #
255
+ # Argument +new+ and the elements of +old_list+
256
+ # should be {interpretable as paths}[rdoc-ref:FileUtils@Path+Arguments]:
257
+ #
258
+ # Bundler::FileUtils.uptodate?('Rakefile', ['Gemfile', 'README.md']) # => true
259
+ # Bundler::FileUtils.uptodate?('Gemfile', ['Rakefile', 'README.md']) # => false
151
260
  #
152
- # Bundler::FileUtils.uptodate?('hello.o', %w(hello.c hello.h)) or \
153
- # system 'make hello.o'
261
+ # A non-existent file is considered to be infinitely old.
262
+ #
263
+ # Related: Bundler::FileUtils.touch.
154
264
  #
155
265
  def uptodate?(new, old_list)
156
266
  return false unless File.exist?(new)
@@ -170,12 +280,39 @@ module Bundler::FileUtils
170
280
  private_module_function :remove_trailing_slash
171
281
 
172
282
  #
173
- # Creates one or more directories.
283
+ # Creates directories at the paths in the given +list+
284
+ # (a single path or an array of paths);
285
+ # returns +list+ if it is an array, <tt>[list]</tt> otherwise.
286
+ #
287
+ # Argument +list+ or its elements
288
+ # should be {interpretable as paths}[rdoc-ref:FileUtils@Path+Arguments].
289
+ #
290
+ # With no keyword arguments, creates a directory at each +path+ in +list+
291
+ # by calling: <tt>Dir.mkdir(path, mode)</tt>;
292
+ # see {Dir.mkdir}[https://docs.ruby-lang.org/en/master/Dir.html#method-c-mkdir]:
293
+ #
294
+ # Bundler::FileUtils.mkdir(%w[tmp0 tmp1]) # => ["tmp0", "tmp1"]
295
+ # Bundler::FileUtils.mkdir('tmp4') # => ["tmp4"]
296
+ #
297
+ # Keyword arguments:
298
+ #
299
+ # - <tt>mode: <i>mode</i></tt> - also calls <tt>File.chmod(mode, path)</tt>;
300
+ # see {File.chmod}[https://docs.ruby-lang.org/en/master/File.html#method-c-chmod].
301
+ # - <tt>noop: true</tt> - does not create directories.
302
+ # - <tt>verbose: true</tt> - prints an equivalent command:
303
+ #
304
+ # Bundler::FileUtils.mkdir(%w[tmp0 tmp1], verbose: true)
305
+ # Bundler::FileUtils.mkdir(%w[tmp2 tmp3], mode: 0700, verbose: true)
306
+ #
307
+ # Output:
308
+ #
309
+ # mkdir tmp0 tmp1
310
+ # mkdir -m 700 tmp2 tmp3
174
311
  #
175
- # Bundler::FileUtils.mkdir 'test'
176
- # Bundler::FileUtils.mkdir %w(tmp data)
177
- # Bundler::FileUtils.mkdir 'notexist', noop: true # Does not really create.
178
- # Bundler::FileUtils.mkdir 'tmp', mode: 0700
312
+ # Raises an exception if any path points to an existing
313
+ # file or directory, or if for any reason a directory cannot be created.
314
+ #
315
+ # Related: Bundler::FileUtils.mkdir_p.
179
316
  #
180
317
  def mkdir(list, mode: nil, noop: nil, verbose: nil)
181
318
  list = fu_list(list)
@@ -189,40 +326,56 @@ module Bundler::FileUtils
189
326
  module_function :mkdir
190
327
 
191
328
  #
192
- # Creates a directory and all its parent directories.
193
- # For example,
329
+ # Creates directories at the paths in the given +list+
330
+ # (a single path or an array of paths),
331
+ # also creating ancestor directories as needed;
332
+ # returns +list+ if it is an array, <tt>[list]</tt> otherwise.
333
+ #
334
+ # Argument +list+ or its elements
335
+ # should be {interpretable as paths}[rdoc-ref:FileUtils@Path+Arguments].
336
+ #
337
+ # With no keyword arguments, creates a directory at each +path+ in +list+,
338
+ # along with any needed ancestor directories,
339
+ # by calling: <tt>Dir.mkdir(path, mode)</tt>;
340
+ # see {Dir.mkdir}[https://docs.ruby-lang.org/en/master/Dir.html#method-c-mkdir]:
341
+ #
342
+ # Bundler::FileUtils.mkdir_p(%w[tmp0/tmp1 tmp2/tmp3]) # => ["tmp0/tmp1", "tmp2/tmp3"]
343
+ # Bundler::FileUtils.mkdir_p('tmp4/tmp5') # => ["tmp4/tmp5"]
344
+ #
345
+ # Keyword arguments:
346
+ #
347
+ # - <tt>mode: <i>mode</i></tt> - also calls <tt>File.chmod(mode, path)</tt>;
348
+ # see {File.chmod}[https://docs.ruby-lang.org/en/master/File.html#method-c-chmod].
349
+ # - <tt>noop: true</tt> - does not create directories.
350
+ # - <tt>verbose: true</tt> - prints an equivalent command:
351
+ #
352
+ # Bundler::FileUtils.mkdir_p(%w[tmp0 tmp1], verbose: true)
353
+ # Bundler::FileUtils.mkdir_p(%w[tmp2 tmp3], mode: 0700, verbose: true)
354
+ #
355
+ # Output:
194
356
  #
195
- # Bundler::FileUtils.mkdir_p '/usr/local/lib/ruby'
357
+ # mkdir -p tmp0 tmp1
358
+ # mkdir -p -m 700 tmp2 tmp3
196
359
  #
197
- # causes to make following directories, if they do not exist.
360
+ # Raises an exception if for any reason a directory cannot be created.
198
361
  #
199
- # * /usr
200
- # * /usr/local
201
- # * /usr/local/lib
202
- # * /usr/local/lib/ruby
362
+ # Bundler::FileUtils.mkpath and Bundler::FileUtils.makedirs are aliases for Bundler::FileUtils.mkdir_p.
203
363
  #
204
- # You can pass several directories at a time in a list.
364
+ # Related: Bundler::FileUtils.mkdir.
205
365
  #
206
366
  def mkdir_p(list, mode: nil, noop: nil, verbose: nil)
207
367
  list = fu_list(list)
208
368
  fu_output_message "mkdir -p #{mode ? ('-m %03o ' % mode) : ''}#{list.join ' '}" if verbose
209
369
  return *list if noop
210
370
 
211
- list.map {|path| remove_trailing_slash(path)}.each do |path|
212
- # optimize for the most common case
213
- begin
214
- fu_mkdir path, mode
215
- next
216
- rescue SystemCallError
217
- next if File.directory?(path)
218
- end
371
+ list.each do |item|
372
+ path = remove_trailing_slash(item)
219
373
 
220
374
  stack = []
221
- until path == stack.last # dirname("/")=="/", dirname("C:/")=="C:/"
375
+ until File.directory?(path) || File.dirname(path) == path
222
376
  stack.push path
223
377
  path = File.dirname(path)
224
378
  end
225
- stack.pop # root directory should exist
226
379
  stack.reverse_each do |dir|
227
380
  begin
228
381
  fu_mkdir dir, mode
@@ -253,12 +406,39 @@ module Bundler::FileUtils
253
406
  private_module_function :fu_mkdir
254
407
 
255
408
  #
256
- # Removes one or more directories.
409
+ # Removes directories at the paths in the given +list+
410
+ # (a single path or an array of paths);
411
+ # returns +list+, if it is an array, <tt>[list]</tt> otherwise.
412
+ #
413
+ # Argument +list+ or its elements
414
+ # should be {interpretable as paths}[rdoc-ref:FileUtils@Path+Arguments].
415
+ #
416
+ # With no keyword arguments, removes the directory at each +path+ in +list+,
417
+ # by calling: <tt>Dir.rmdir(path)</tt>;
418
+ # see {Dir.rmdir}[https://docs.ruby-lang.org/en/master/Dir.html#method-c-rmdir]:
419
+ #
420
+ # Bundler::FileUtils.rmdir(%w[tmp0/tmp1 tmp2/tmp3]) # => ["tmp0/tmp1", "tmp2/tmp3"]
421
+ # Bundler::FileUtils.rmdir('tmp4/tmp5') # => ["tmp4/tmp5"]
422
+ #
423
+ # Keyword arguments:
424
+ #
425
+ # - <tt>parents: true</tt> - removes successive ancestor directories
426
+ # if empty.
427
+ # - <tt>noop: true</tt> - does not remove directories.
428
+ # - <tt>verbose: true</tt> - prints an equivalent command:
257
429
  #
258
- # Bundler::FileUtils.rmdir 'somedir'
259
- # Bundler::FileUtils.rmdir %w(somedir anydir otherdir)
260
- # # Does not really remove directory; outputs message.
261
- # Bundler::FileUtils.rmdir 'somedir', verbose: true, noop: true
430
+ # Bundler::FileUtils.rmdir(%w[tmp0/tmp1 tmp2/tmp3], parents: true, verbose: true)
431
+ # Bundler::FileUtils.rmdir('tmp4/tmp5', parents: true, verbose: true)
432
+ #
433
+ # Output:
434
+ #
435
+ # rmdir -p tmp0/tmp1 tmp2/tmp3
436
+ # rmdir -p tmp4/tmp5
437
+ #
438
+ # Raises an exception if a directory does not exist
439
+ # or if for any reason a directory cannot be removed.
440
+ #
441
+ # Related: {methods for deleting}[rdoc-ref:FileUtils@Deleting].
262
442
  #
263
443
  def rmdir(list, parents: nil, noop: nil, verbose: nil)
264
444
  list = fu_list(list)
@@ -279,26 +459,60 @@ module Bundler::FileUtils
279
459
  end
280
460
  module_function :rmdir
281
461
 
462
+ # Creates {hard links}[https://en.wikipedia.org/wiki/Hard_link].
463
+ #
464
+ # Arguments +src+ (a single path or an array of paths)
465
+ # and +dest+ (a single path)
466
+ # should be {interpretable as paths}[rdoc-ref:FileUtils@Path+Arguments].
467
+ #
468
+ # When +src+ is the path to an existing file
469
+ # and +dest+ is the path to a non-existent file,
470
+ # creates a hard link at +dest+ pointing to +src+; returns zero:
471
+ #
472
+ # Dir.children('tmp0/') # => ["t.txt"]
473
+ # Dir.children('tmp1/') # => []
474
+ # Bundler::FileUtils.ln('tmp0/t.txt', 'tmp1/t.lnk') # => 0
475
+ # Dir.children('tmp1/') # => ["t.lnk"]
476
+ #
477
+ # When +src+ is the path to an existing file
478
+ # and +dest+ is the path to an existing directory,
479
+ # creates a hard link at <tt>dest/src</tt> pointing to +src+; returns zero:
282
480
  #
283
- # :call-seq:
284
- # Bundler::FileUtils.ln(target, link, force: nil, noop: nil, verbose: nil)
285
- # Bundler::FileUtils.ln(target, dir, force: nil, noop: nil, verbose: nil)
286
- # Bundler::FileUtils.ln(targets, dir, force: nil, noop: nil, verbose: nil)
481
+ # Dir.children('tmp2') # => ["t.dat"]
482
+ # Dir.children('tmp3') # => []
483
+ # Bundler::FileUtils.ln('tmp2/t.dat', 'tmp3') # => 0
484
+ # Dir.children('tmp3') # => ["t.dat"]
287
485
  #
288
- # In the first form, creates a hard link +link+ which points to +target+.
289
- # If +link+ already exists, raises Errno::EEXIST.
290
- # But if the +force+ option is set, overwrites +link+.
486
+ # When +src+ is an array of paths to existing files
487
+ # and +dest+ is the path to an existing directory,
488
+ # then for each path +target+ in +src+,
489
+ # creates a hard link at <tt>dest/target</tt> pointing to +target+;
490
+ # returns +src+:
291
491
  #
292
- # Bundler::FileUtils.ln 'gcc', 'cc', verbose: true
293
- # Bundler::FileUtils.ln '/usr/bin/emacs21', '/usr/bin/emacs'
492
+ # Dir.children('tmp4/') # => []
493
+ # Bundler::FileUtils.ln(['tmp0/t.txt', 'tmp2/t.dat'], 'tmp4/') # => ["tmp0/t.txt", "tmp2/t.dat"]
494
+ # Dir.children('tmp4/') # => ["t.dat", "t.txt"]
294
495
  #
295
- # In the second form, creates a link +dir/target+ pointing to +target+.
296
- # In the third form, creates several hard links in the directory +dir+,
297
- # pointing to each item in +targets+.
298
- # If +dir+ is not a directory, raises Errno::ENOTDIR.
496
+ # Keyword arguments:
299
497
  #
300
- # Bundler::FileUtils.cd '/sbin'
301
- # Bundler::FileUtils.ln %w(cp mv mkdir), '/bin' # Now /sbin/cp and /bin/cp are linked.
498
+ # - <tt>force: true</tt> - overwrites +dest+ if it exists.
499
+ # - <tt>noop: true</tt> - does not create links.
500
+ # - <tt>verbose: true</tt> - prints an equivalent command:
501
+ #
502
+ # Bundler::FileUtils.ln('tmp0/t.txt', 'tmp1/t.lnk', verbose: true)
503
+ # Bundler::FileUtils.ln('tmp2/t.dat', 'tmp3', verbose: true)
504
+ # Bundler::FileUtils.ln(['tmp0/t.txt', 'tmp2/t.dat'], 'tmp4/', verbose: true)
505
+ #
506
+ # Output:
507
+ #
508
+ # ln tmp0/t.txt tmp1/t.lnk
509
+ # ln tmp2/t.dat tmp3
510
+ # ln tmp0/t.txt tmp2/t.dat tmp4/
511
+ #
512
+ # Raises an exception if +dest+ is the path to an existing file
513
+ # and keyword argument +force+ is not +true+.
514
+ #
515
+ # Related: Bundler::FileUtils.link_entry (has different options).
302
516
  #
303
517
  def ln(src, dest, force: nil, noop: nil, verbose: nil)
304
518
  fu_output_message "ln#{force ? ' -f' : ''} #{[src,dest].flatten.join ' '}" if verbose
@@ -313,28 +527,103 @@ module Bundler::FileUtils
313
527
  alias link ln
314
528
  module_function :link
315
529
 
316
- #
317
- # Hard link +src+ to +dest+. If +src+ is a directory, this method links
318
- # all its contents recursively. If +dest+ is a directory, links
319
- # +src+ to +dest/src+.
320
- #
321
- # +src+ can be a list of files.
322
- #
323
- # If +dereference_root+ is true, this method dereference tree root.
324
- #
325
- # If +remove_destination+ is true, this method removes each destination file before copy.
326
- #
327
- # Bundler::FileUtils.rm_r site_ruby + '/mylib', force: true
328
- # Bundler::FileUtils.cp_lr 'lib/', site_ruby + '/mylib'
329
- #
330
- # # Examples of linking several files to target directory.
331
- # Bundler::FileUtils.cp_lr %w(mail.rb field.rb debug/), site_ruby + '/tmail'
332
- # Bundler::FileUtils.cp_lr Dir.glob('*.rb'), '/home/aamine/lib/ruby', noop: true, verbose: true
333
- #
334
- # # If you want to link all contents of a directory instead of the
335
- # # directory itself, c.f. src/x -> dest/x, src/y -> dest/y,
336
- # # use the following code.
337
- # Bundler::FileUtils.cp_lr 'src/.', 'dest' # cp_lr('src', 'dest') makes dest/src, but this doesn't.
530
+ # Creates {hard links}[https://en.wikipedia.org/wiki/Hard_link].
531
+ #
532
+ # Arguments +src+ (a single path or an array of paths)
533
+ # and +dest+ (a single path)
534
+ # should be {interpretable as paths}[rdoc-ref:FileUtils@Path+Arguments].
535
+ #
536
+ # If +src+ is the path to a directory and +dest+ does not exist,
537
+ # creates links +dest+ and descendents pointing to +src+ and its descendents:
538
+ #
539
+ # tree('src0')
540
+ # # => src0
541
+ # # |-- sub0
542
+ # # | |-- src0.txt
543
+ # # | `-- src1.txt
544
+ # # `-- sub1
545
+ # # |-- src2.txt
546
+ # # `-- src3.txt
547
+ # File.exist?('dest0') # => false
548
+ # Bundler::FileUtils.cp_lr('src0', 'dest0')
549
+ # tree('dest0')
550
+ # # => dest0
551
+ # # |-- sub0
552
+ # # | |-- src0.txt
553
+ # # | `-- src1.txt
554
+ # # `-- sub1
555
+ # # |-- src2.txt
556
+ # # `-- src3.txt
557
+ #
558
+ # If +src+ and +dest+ are both paths to directories,
559
+ # creates links <tt>dest/src</tt> and descendents
560
+ # pointing to +src+ and its descendents:
561
+ #
562
+ # tree('src1')
563
+ # # => src1
564
+ # # |-- sub0
565
+ # # | |-- src0.txt
566
+ # # | `-- src1.txt
567
+ # # `-- sub1
568
+ # # |-- src2.txt
569
+ # # `-- src3.txt
570
+ # Bundler::FileUtils.mkdir('dest1')
571
+ # Bundler::FileUtils.cp_lr('src1', 'dest1')
572
+ # tree('dest1')
573
+ # # => dest1
574
+ # # `-- src1
575
+ # # |-- sub0
576
+ # # | |-- src0.txt
577
+ # # | `-- src1.txt
578
+ # # `-- sub1
579
+ # # |-- src2.txt
580
+ # # `-- src3.txt
581
+ #
582
+ # If +src+ is an array of paths to entries and +dest+ is the path to a directory,
583
+ # for each path +filepath+ in +src+, creates a link at <tt>dest/filepath</tt>
584
+ # pointing to that path:
585
+ #
586
+ # tree('src2')
587
+ # # => src2
588
+ # # |-- sub0
589
+ # # | |-- src0.txt
590
+ # # | `-- src1.txt
591
+ # # `-- sub1
592
+ # # |-- src2.txt
593
+ # # `-- src3.txt
594
+ # Bundler::FileUtils.mkdir('dest2')
595
+ # Bundler::FileUtils.cp_lr(['src2/sub0', 'src2/sub1'], 'dest2')
596
+ # tree('dest2')
597
+ # # => dest2
598
+ # # |-- sub0
599
+ # # | |-- src0.txt
600
+ # # | `-- src1.txt
601
+ # # `-- sub1
602
+ # # |-- src2.txt
603
+ # # `-- src3.txt
604
+ #
605
+ # Keyword arguments:
606
+ #
607
+ # - <tt>dereference_root: false</tt> - if +src+ is a symbolic link,
608
+ # does not dereference it.
609
+ # - <tt>noop: true</tt> - does not create links.
610
+ # - <tt>remove_destination: true</tt> - removes +dest+ before creating links.
611
+ # - <tt>verbose: true</tt> - prints an equivalent command:
612
+ #
613
+ # Bundler::FileUtils.cp_lr('src0', 'dest0', noop: true, verbose: true)
614
+ # Bundler::FileUtils.cp_lr('src1', 'dest1', noop: true, verbose: true)
615
+ # Bundler::FileUtils.cp_lr(['src2/sub0', 'src2/sub1'], 'dest2', noop: true, verbose: true)
616
+ #
617
+ # Output:
618
+ #
619
+ # cp -lr src0 dest0
620
+ # cp -lr src1 dest1
621
+ # cp -lr src2/sub0 src2/sub1 dest2
622
+ #
623
+ # Raises an exception if +dest+ is the path to an existing file or directory
624
+ # and keyword argument <tt>remove_destination: true</tt> is not given.
625
+ #
626
+ # Related: {methods for copying}[rdoc-ref:FileUtils@Copying].
338
627
  #
339
628
  def cp_lr(src, dest, noop: nil, verbose: nil,
340
629
  dereference_root: true, remove_destination: false)
@@ -346,27 +635,79 @@ module Bundler::FileUtils
346
635
  end
347
636
  module_function :cp_lr
348
637
 
638
+ # Creates {symbolic links}[https://en.wikipedia.org/wiki/Symbolic_link].
639
+ #
640
+ # Arguments +src+ (a single path or an array of paths)
641
+ # and +dest+ (a single path)
642
+ # should be {interpretable as paths}[rdoc-ref:FileUtils@Path+Arguments].
643
+ #
644
+ # If +src+ is the path to an existing file:
645
+ #
646
+ # - When +dest+ is the path to a non-existent file,
647
+ # creates a symbolic link at +dest+ pointing to +src+:
648
+ #
649
+ # Bundler::FileUtils.touch('src0.txt')
650
+ # File.exist?('dest0.txt') # => false
651
+ # Bundler::FileUtils.ln_s('src0.txt', 'dest0.txt')
652
+ # File.symlink?('dest0.txt') # => true
653
+ #
654
+ # - When +dest+ is the path to an existing file,
655
+ # creates a symbolic link at +dest+ pointing to +src+
656
+ # if and only if keyword argument <tt>force: true</tt> is given
657
+ # (raises an exception otherwise):
349
658
  #
350
- # :call-seq:
351
- # Bundler::FileUtils.ln_s(target, link, force: nil, noop: nil, verbose: nil)
352
- # Bundler::FileUtils.ln_s(target, dir, force: nil, noop: nil, verbose: nil)
353
- # Bundler::FileUtils.ln_s(targets, dir, force: nil, noop: nil, verbose: nil)
659
+ # Bundler::FileUtils.touch('src1.txt')
660
+ # Bundler::FileUtils.touch('dest1.txt')
661
+ # Bundler::FileUtils.ln_s('src1.txt', 'dest1.txt', force: true)
662
+ # FileTest.symlink?('dest1.txt') # => true
354
663
  #
355
- # In the first form, creates a symbolic link +link+ which points to +target+.
356
- # If +link+ already exists, raises Errno::EEXIST.
357
- # But if the <tt>force</tt> option is set, overwrites +link+.
664
+ # Bundler::FileUtils.ln_s('src1.txt', 'dest1.txt') # Raises Errno::EEXIST.
358
665
  #
359
- # Bundler::FileUtils.ln_s '/usr/bin/ruby', '/usr/local/bin/ruby'
360
- # Bundler::FileUtils.ln_s 'verylongsourcefilename.c', 'c', force: true
666
+ # If +dest+ is the path to a directory,
667
+ # creates a symbolic link at <tt>dest/src</tt> pointing to +src+:
361
668
  #
362
- # In the second form, creates a link +dir/target+ pointing to +target+.
363
- # In the third form, creates several symbolic links in the directory +dir+,
364
- # pointing to each item in +targets+.
365
- # If +dir+ is not a directory, raises Errno::ENOTDIR.
669
+ # Bundler::FileUtils.touch('src2.txt')
670
+ # Bundler::FileUtils.mkdir('destdir2')
671
+ # Bundler::FileUtils.ln_s('src2.txt', 'destdir2')
672
+ # File.symlink?('destdir2/src2.txt') # => true
366
673
  #
367
- # Bundler::FileUtils.ln_s Dir.glob('/bin/*.rb'), '/home/foo/bin'
674
+ # If +src+ is an array of paths to existing files and +dest+ is a directory,
675
+ # for each child +child+ in +src+ creates a symbolic link <tt>dest/child</tt>
676
+ # pointing to +child+:
368
677
  #
369
- def ln_s(src, dest, force: nil, noop: nil, verbose: nil)
678
+ # Bundler::FileUtils.mkdir('srcdir3')
679
+ # Bundler::FileUtils.touch('srcdir3/src0.txt')
680
+ # Bundler::FileUtils.touch('srcdir3/src1.txt')
681
+ # Bundler::FileUtils.mkdir('destdir3')
682
+ # Bundler::FileUtils.ln_s(['srcdir3/src0.txt', 'srcdir3/src1.txt'], 'destdir3')
683
+ # File.symlink?('destdir3/src0.txt') # => true
684
+ # File.symlink?('destdir3/src1.txt') # => true
685
+ #
686
+ # Keyword arguments:
687
+ #
688
+ # - <tt>force: true</tt> - overwrites +dest+ if it exists.
689
+ # - <tt>relative: false</tt> - create links relative to +dest+.
690
+ # - <tt>noop: true</tt> - does not create links.
691
+ # - <tt>verbose: true</tt> - prints an equivalent command:
692
+ #
693
+ # Bundler::FileUtils.ln_s('src0.txt', 'dest0.txt', noop: true, verbose: true)
694
+ # Bundler::FileUtils.ln_s('src1.txt', 'destdir1', noop: true, verbose: true)
695
+ # Bundler::FileUtils.ln_s('src2.txt', 'dest2.txt', force: true, noop: true, verbose: true)
696
+ # Bundler::FileUtils.ln_s(['srcdir3/src0.txt', 'srcdir3/src1.txt'], 'destdir3', noop: true, verbose: true)
697
+ #
698
+ # Output:
699
+ #
700
+ # ln -s src0.txt dest0.txt
701
+ # ln -s src1.txt destdir1
702
+ # ln -sf src2.txt dest2.txt
703
+ # ln -s srcdir3/src0.txt srcdir3/src1.txt destdir3
704
+ #
705
+ # Related: Bundler::FileUtils.ln_sf.
706
+ #
707
+ def ln_s(src, dest, force: nil, relative: false, target_directory: true, noop: nil, verbose: nil)
708
+ if relative
709
+ return ln_sr(src, dest, force: force, noop: noop, verbose: verbose)
710
+ end
370
711
  fu_output_message "ln -s#{force ? 'f' : ''} #{[src,dest].flatten.join ' '}" if verbose
371
712
  return if noop
372
713
  fu_each_src_dest0(src, dest) do |s,d|
@@ -379,29 +720,95 @@ module Bundler::FileUtils
379
720
  alias symlink ln_s
380
721
  module_function :symlink
381
722
 
382
- #
383
- # :call-seq:
384
- # Bundler::FileUtils.ln_sf(*args)
385
- #
386
- # Same as
387
- #
388
- # Bundler::FileUtils.ln_s(*args, force: true)
723
+ # Like Bundler::FileUtils.ln_s, but always with keyword argument <tt>force: true</tt> given.
389
724
  #
390
725
  def ln_sf(src, dest, noop: nil, verbose: nil)
391
726
  ln_s src, dest, force: true, noop: noop, verbose: verbose
392
727
  end
393
728
  module_function :ln_sf
394
729
 
730
+ # Like Bundler::FileUtils.ln_s, but create links relative to +dest+.
395
731
  #
396
- # Hard links a file system entry +src+ to +dest+.
397
- # If +src+ is a directory, this method links its contents recursively.
732
+ def ln_sr(src, dest, target_directory: true, force: nil, noop: nil, verbose: nil)
733
+ options = "#{force ? 'f' : ''}#{target_directory ? '' : 'T'}"
734
+ dest = File.path(dest)
735
+ srcs = Array(src)
736
+ link = proc do |s, target_dir_p = true|
737
+ s = File.path(s)
738
+ if target_dir_p
739
+ d = File.join(destdirs = dest, File.basename(s))
740
+ else
741
+ destdirs = File.dirname(d = dest)
742
+ end
743
+ destdirs = fu_split_path(File.realpath(destdirs))
744
+ if fu_starting_path?(s)
745
+ srcdirs = fu_split_path((File.realdirpath(s) rescue File.expand_path(s)))
746
+ base = fu_relative_components_from(srcdirs, destdirs)
747
+ s = File.join(*base)
748
+ else
749
+ srcdirs = fu_clean_components(*fu_split_path(s))
750
+ base = fu_relative_components_from(fu_split_path(Dir.pwd), destdirs)
751
+ while srcdirs.first&. == ".." and base.last&.!=("..") and !fu_starting_path?(base.last)
752
+ srcdirs.shift
753
+ base.pop
754
+ end
755
+ s = File.join(*base, *srcdirs)
756
+ end
757
+ fu_output_message "ln -s#{options} #{s} #{d}" if verbose
758
+ next if noop
759
+ remove_file d, true if force
760
+ File.symlink s, d
761
+ end
762
+ case srcs.size
763
+ when 0
764
+ when 1
765
+ link[srcs[0], target_directory && File.directory?(dest)]
766
+ else
767
+ srcs.each(&link)
768
+ end
769
+ end
770
+ module_function :ln_sr
771
+
772
+ # Creates {hard links}[https://en.wikipedia.org/wiki/Hard_link]; returns +nil+.
773
+ #
774
+ # Arguments +src+ and +dest+
775
+ # should be {interpretable as paths}[rdoc-ref:FileUtils@Path+Arguments].
776
+ #
777
+ # If +src+ is the path to a file and +dest+ does not exist,
778
+ # creates a hard link at +dest+ pointing to +src+:
779
+ #
780
+ # Bundler::FileUtils.touch('src0.txt')
781
+ # File.exist?('dest0.txt') # => false
782
+ # Bundler::FileUtils.link_entry('src0.txt', 'dest0.txt')
783
+ # File.file?('dest0.txt') # => true
398
784
  #
399
- # Both of +src+ and +dest+ must be a path name.
400
- # +src+ must exist, +dest+ must not exist.
785
+ # If +src+ is the path to a directory and +dest+ does not exist,
786
+ # recursively creates hard links at +dest+ pointing to paths in +src+:
401
787
  #
402
- # If +dereference_root+ is true, this method dereferences the tree root.
788
+ # Bundler::FileUtils.mkdir_p(['src1/dir0', 'src1/dir1'])
789
+ # src_file_paths = [
790
+ # 'src1/dir0/t0.txt',
791
+ # 'src1/dir0/t1.txt',
792
+ # 'src1/dir1/t2.txt',
793
+ # 'src1/dir1/t3.txt',
794
+ # ]
795
+ # Bundler::FileUtils.touch(src_file_paths)
796
+ # File.directory?('dest1') # => true
797
+ # Bundler::FileUtils.link_entry('src1', 'dest1')
798
+ # File.file?('dest1/dir0/t0.txt') # => true
799
+ # File.file?('dest1/dir0/t1.txt') # => true
800
+ # File.file?('dest1/dir1/t2.txt') # => true
801
+ # File.file?('dest1/dir1/t3.txt') # => true
403
802
  #
404
- # If +remove_destination+ is true, this method removes each destination file before copy.
803
+ # Keyword arguments:
804
+ #
805
+ # - <tt>dereference_root: true</tt> - dereferences +src+ if it is a symbolic link.
806
+ # - <tt>remove_destination: true</tt> - removes +dest+ before creating links.
807
+ #
808
+ # Raises an exception if +dest+ is the path to an existing file or directory
809
+ # and keyword argument <tt>remove_destination: true</tt> is not given.
810
+ #
811
+ # Related: Bundler::FileUtils.ln (has different options).
405
812
  #
406
813
  def link_entry(src, dest, dereference_root = false, remove_destination = false)
407
814
  Entry_.new(src, nil, dereference_root).traverse do |ent|
@@ -412,16 +819,57 @@ module Bundler::FileUtils
412
819
  end
413
820
  module_function :link_entry
414
821
 
822
+ # Copies files.
823
+ #
824
+ # Arguments +src+ (a single path or an array of paths)
825
+ # and +dest+ (a single path)
826
+ # should be {interpretable as paths}[rdoc-ref:FileUtils@Path+Arguments].
827
+ #
828
+ # If +src+ is the path to a file and +dest+ is not the path to a directory,
829
+ # copies +src+ to +dest+:
830
+ #
831
+ # Bundler::FileUtils.touch('src0.txt')
832
+ # File.exist?('dest0.txt') # => false
833
+ # Bundler::FileUtils.cp('src0.txt', 'dest0.txt')
834
+ # File.file?('dest0.txt') # => true
835
+ #
836
+ # If +src+ is the path to a file and +dest+ is the path to a directory,
837
+ # copies +src+ to <tt>dest/src</tt>:
838
+ #
839
+ # Bundler::FileUtils.touch('src1.txt')
840
+ # Bundler::FileUtils.mkdir('dest1')
841
+ # Bundler::FileUtils.cp('src1.txt', 'dest1')
842
+ # File.file?('dest1/src1.txt') # => true
415
843
  #
416
- # Copies a file content +src+ to +dest+. If +dest+ is a directory,
417
- # copies +src+ to +dest/src+.
844
+ # If +src+ is an array of paths to files and +dest+ is the path to a directory,
845
+ # copies from each +src+ to +dest+:
418
846
  #
419
- # If +src+ is a list of files, then +dest+ must be a directory.
847
+ # src_file_paths = ['src2.txt', 'src2.dat']
848
+ # Bundler::FileUtils.touch(src_file_paths)
849
+ # Bundler::FileUtils.mkdir('dest2')
850
+ # Bundler::FileUtils.cp(src_file_paths, 'dest2')
851
+ # File.file?('dest2/src2.txt') # => true
852
+ # File.file?('dest2/src2.dat') # => true
420
853
  #
421
- # Bundler::FileUtils.cp 'eval.c', 'eval.c.org'
422
- # Bundler::FileUtils.cp %w(cgi.rb complex.rb date.rb), '/usr/lib/ruby/1.6'
423
- # Bundler::FileUtils.cp %w(cgi.rb complex.rb date.rb), '/usr/lib/ruby/1.6', verbose: true
424
- # Bundler::FileUtils.cp 'symlink', 'dest' # copy content, "dest" is not a symlink
854
+ # Keyword arguments:
855
+ #
856
+ # - <tt>preserve: true</tt> - preserves file times.
857
+ # - <tt>noop: true</tt> - does not copy files.
858
+ # - <tt>verbose: true</tt> - prints an equivalent command:
859
+ #
860
+ # Bundler::FileUtils.cp('src0.txt', 'dest0.txt', noop: true, verbose: true)
861
+ # Bundler::FileUtils.cp('src1.txt', 'dest1', noop: true, verbose: true)
862
+ # Bundler::FileUtils.cp(src_file_paths, 'dest2', noop: true, verbose: true)
863
+ #
864
+ # Output:
865
+ #
866
+ # cp src0.txt dest0.txt
867
+ # cp src1.txt dest1
868
+ # cp src2.txt src2.dat dest2
869
+ #
870
+ # Raises an exception if +src+ is a directory.
871
+ #
872
+ # Related: {methods for copying}[rdoc-ref:FileUtils@Copying].
425
873
  #
426
874
  def cp(src, dest, preserve: nil, noop: nil, verbose: nil)
427
875
  fu_output_message "cp#{preserve ? ' -p' : ''} #{[src,dest].flatten.join ' '}" if verbose
@@ -435,30 +883,105 @@ module Bundler::FileUtils
435
883
  alias copy cp
436
884
  module_function :copy
437
885
 
438
- #
439
- # Copies +src+ to +dest+. If +src+ is a directory, this method copies
440
- # all its contents recursively. If +dest+ is a directory, copies
441
- # +src+ to +dest/src+.
442
- #
443
- # +src+ can be a list of files.
444
- #
445
- # If +dereference_root+ is true, this method dereference tree root.
446
- #
447
- # If +remove_destination+ is true, this method removes each destination file before copy.
448
- #
449
- # # Installing Ruby library "mylib" under the site_ruby
450
- # Bundler::FileUtils.rm_r site_ruby + '/mylib', force: true
451
- # Bundler::FileUtils.cp_r 'lib/', site_ruby + '/mylib'
452
- #
453
- # # Examples of copying several files to target directory.
454
- # Bundler::FileUtils.cp_r %w(mail.rb field.rb debug/), site_ruby + '/tmail'
455
- # Bundler::FileUtils.cp_r Dir.glob('*.rb'), '/home/foo/lib/ruby', noop: true, verbose: true
456
- #
457
- # # If you want to copy all contents of a directory instead of the
458
- # # directory itself, c.f. src/x -> dest/x, src/y -> dest/y,
459
- # # use following code.
460
- # Bundler::FileUtils.cp_r 'src/.', 'dest' # cp_r('src', 'dest') makes dest/src,
461
- # # but this doesn't.
886
+ # Recursively copies files.
887
+ #
888
+ # Arguments +src+ (a single path or an array of paths)
889
+ # and +dest+ (a single path)
890
+ # should be {interpretable as paths}[rdoc-ref:FileUtils@Path+Arguments].
891
+ #
892
+ # The mode, owner, and group are retained in the copy;
893
+ # to change those, use Bundler::FileUtils.install instead.
894
+ #
895
+ # If +src+ is the path to a file and +dest+ is not the path to a directory,
896
+ # copies +src+ to +dest+:
897
+ #
898
+ # Bundler::FileUtils.touch('src0.txt')
899
+ # File.exist?('dest0.txt') # => false
900
+ # Bundler::FileUtils.cp_r('src0.txt', 'dest0.txt')
901
+ # File.file?('dest0.txt') # => true
902
+ #
903
+ # If +src+ is the path to a file and +dest+ is the path to a directory,
904
+ # copies +src+ to <tt>dest/src</tt>:
905
+ #
906
+ # Bundler::FileUtils.touch('src1.txt')
907
+ # Bundler::FileUtils.mkdir('dest1')
908
+ # Bundler::FileUtils.cp_r('src1.txt', 'dest1')
909
+ # File.file?('dest1/src1.txt') # => true
910
+ #
911
+ # If +src+ is the path to a directory and +dest+ does not exist,
912
+ # recursively copies +src+ to +dest+:
913
+ #
914
+ # tree('src2')
915
+ # # => src2
916
+ # # |-- dir0
917
+ # # | |-- src0.txt
918
+ # # | `-- src1.txt
919
+ # # `-- dir1
920
+ # # |-- src2.txt
921
+ # # `-- src3.txt
922
+ # Bundler::FileUtils.exist?('dest2') # => false
923
+ # Bundler::FileUtils.cp_r('src2', 'dest2')
924
+ # tree('dest2')
925
+ # # => dest2
926
+ # # |-- dir0
927
+ # # | |-- src0.txt
928
+ # # | `-- src1.txt
929
+ # # `-- dir1
930
+ # # |-- src2.txt
931
+ # # `-- src3.txt
932
+ #
933
+ # If +src+ and +dest+ are paths to directories,
934
+ # recursively copies +src+ to <tt>dest/src</tt>:
935
+ #
936
+ # tree('src3')
937
+ # # => src3
938
+ # # |-- dir0
939
+ # # | |-- src0.txt
940
+ # # | `-- src1.txt
941
+ # # `-- dir1
942
+ # # |-- src2.txt
943
+ # # `-- src3.txt
944
+ # Bundler::FileUtils.mkdir('dest3')
945
+ # Bundler::FileUtils.cp_r('src3', 'dest3')
946
+ # tree('dest3')
947
+ # # => dest3
948
+ # # `-- src3
949
+ # # |-- dir0
950
+ # # | |-- src0.txt
951
+ # # | `-- src1.txt
952
+ # # `-- dir1
953
+ # # |-- src2.txt
954
+ # # `-- src3.txt
955
+ #
956
+ # If +src+ is an array of paths and +dest+ is a directory,
957
+ # recursively copies from each path in +src+ to +dest+;
958
+ # the paths in +src+ may point to files and/or directories.
959
+ #
960
+ # Keyword arguments:
961
+ #
962
+ # - <tt>dereference_root: false</tt> - if +src+ is a symbolic link,
963
+ # does not dereference it.
964
+ # - <tt>noop: true</tt> - does not copy files.
965
+ # - <tt>preserve: true</tt> - preserves file times.
966
+ # - <tt>remove_destination: true</tt> - removes +dest+ before copying files.
967
+ # - <tt>verbose: true</tt> - prints an equivalent command:
968
+ #
969
+ # Bundler::FileUtils.cp_r('src0.txt', 'dest0.txt', noop: true, verbose: true)
970
+ # Bundler::FileUtils.cp_r('src1.txt', 'dest1', noop: true, verbose: true)
971
+ # Bundler::FileUtils.cp_r('src2', 'dest2', noop: true, verbose: true)
972
+ # Bundler::FileUtils.cp_r('src3', 'dest3', noop: true, verbose: true)
973
+ #
974
+ # Output:
975
+ #
976
+ # cp -r src0.txt dest0.txt
977
+ # cp -r src1.txt dest1
978
+ # cp -r src2 dest2
979
+ # cp -r src3 dest3
980
+ #
981
+ # Raises an exception of +src+ is the path to a directory
982
+ # and +dest+ is the path to a file.
983
+ #
984
+ # Related: {methods for copying}[rdoc-ref:FileUtils@Copying].
462
985
  #
463
986
  def cp_r(src, dest, preserve: nil, noop: nil, verbose: nil,
464
987
  dereference_root: true, remove_destination: nil)
@@ -470,21 +993,50 @@ module Bundler::FileUtils
470
993
  end
471
994
  module_function :cp_r
472
995
 
996
+ # Recursively copies files from +src+ to +dest+.
997
+ #
998
+ # Arguments +src+ and +dest+
999
+ # should be {interpretable as paths}[rdoc-ref:FileUtils@Path+Arguments].
1000
+ #
1001
+ # If +src+ is the path to a file, copies +src+ to +dest+:
1002
+ #
1003
+ # Bundler::FileUtils.touch('src0.txt')
1004
+ # File.exist?('dest0.txt') # => false
1005
+ # Bundler::FileUtils.copy_entry('src0.txt', 'dest0.txt')
1006
+ # File.file?('dest0.txt') # => true
473
1007
  #
474
- # Copies a file system entry +src+ to +dest+.
475
- # If +src+ is a directory, this method copies its contents recursively.
476
- # This method preserves file types, c.f. symlink, directory...
477
- # (FIFO, device files and etc. are not supported yet)
1008
+ # If +src+ is a directory, recursively copies +src+ to +dest+:
478
1009
  #
479
- # Both of +src+ and +dest+ must be a path name.
480
- # +src+ must exist, +dest+ must not exist.
1010
+ # tree('src1')
1011
+ # # => src1
1012
+ # # |-- dir0
1013
+ # # | |-- src0.txt
1014
+ # # | `-- src1.txt
1015
+ # # `-- dir1
1016
+ # # |-- src2.txt
1017
+ # # `-- src3.txt
1018
+ # Bundler::FileUtils.copy_entry('src1', 'dest1')
1019
+ # tree('dest1')
1020
+ # # => dest1
1021
+ # # |-- dir0
1022
+ # # | |-- src0.txt
1023
+ # # | `-- src1.txt
1024
+ # # `-- dir1
1025
+ # # |-- src2.txt
1026
+ # # `-- src3.txt
481
1027
  #
482
- # If +preserve+ is true, this method preserves owner, group, and
483
- # modified time. Permissions are copied regardless +preserve+.
1028
+ # The recursive copying preserves file types for regular files,
1029
+ # directories, and symbolic links;
1030
+ # other file types (FIFO streams, device files, etc.) are not supported.
484
1031
  #
485
- # If +dereference_root+ is true, this method dereference tree root.
1032
+ # Keyword arguments:
486
1033
  #
487
- # If +remove_destination+ is true, this method removes each destination file before copy.
1034
+ # - <tt>dereference_root: true</tt> - if +src+ is a symbolic link,
1035
+ # follows the link.
1036
+ # - <tt>preserve: true</tt> - preserves file times.
1037
+ # - <tt>remove_destination: true</tt> - removes +dest+ before copying files.
1038
+ #
1039
+ # Related: {methods for copying}[rdoc-ref:FileUtils@Copying].
488
1040
  #
489
1041
  def copy_entry(src, dest, preserve = false, dereference_root = false, remove_destination = false)
490
1042
  if dereference_root
@@ -502,9 +1054,25 @@ module Bundler::FileUtils
502
1054
  end
503
1055
  module_function :copy_entry
504
1056
 
1057
+ # Copies file from +src+ to +dest+, which should not be directories.
1058
+ #
1059
+ # Arguments +src+ and +dest+
1060
+ # should be {interpretable as paths}[rdoc-ref:FileUtils@Path+Arguments].
1061
+ #
1062
+ # Examples:
1063
+ #
1064
+ # Bundler::FileUtils.touch('src0.txt')
1065
+ # Bundler::FileUtils.copy_file('src0.txt', 'dest0.txt')
1066
+ # File.file?('dest0.txt') # => true
1067
+ #
1068
+ # Keyword arguments:
505
1069
  #
506
- # Copies file contents of +src+ to +dest+.
507
- # Both of +src+ and +dest+ must be a path name.
1070
+ # - <tt>dereference: false</tt> - if +src+ is a symbolic link,
1071
+ # does not follow the link.
1072
+ # - <tt>preserve: true</tt> - preserves file times.
1073
+ # - <tt>remove_destination: true</tt> - removes +dest+ before copying files.
1074
+ #
1075
+ # Related: {methods for copying}[rdoc-ref:FileUtils@Copying].
508
1076
  #
509
1077
  def copy_file(src, dest, preserve = false, dereference = true)
510
1078
  ent = Entry_.new(src, nil, dereference)
@@ -513,25 +1081,79 @@ module Bundler::FileUtils
513
1081
  end
514
1082
  module_function :copy_file
515
1083
 
1084
+ # Copies \IO stream +src+ to \IO stream +dest+ via
1085
+ # {IO.copy_stream}[https://docs.ruby-lang.org/en/master/IO.html#method-c-copy_stream].
516
1086
  #
517
- # Copies stream +src+ to +dest+.
518
- # +src+ must respond to #read(n) and
519
- # +dest+ must respond to #write(str).
1087
+ # Related: {methods for copying}[rdoc-ref:FileUtils@Copying].
520
1088
  #
521
1089
  def copy_stream(src, dest)
522
1090
  IO.copy_stream(src, dest)
523
1091
  end
524
1092
  module_function :copy_stream
525
1093
 
526
- #
527
- # Moves file(s) +src+ to +dest+. If +file+ and +dest+ exist on the different
528
- # disk partition, the file is copied then the original file is removed.
529
- #
530
- # Bundler::FileUtils.mv 'badname.rb', 'goodname.rb'
531
- # Bundler::FileUtils.mv 'stuff.rb', '/notexist/lib/ruby', force: true # no error
532
- #
533
- # Bundler::FileUtils.mv %w(junk.txt dust.txt), '/home/foo/.trash/'
534
- # Bundler::FileUtils.mv Dir.glob('test*.rb'), 'test', noop: true, verbose: true
1094
+ # Moves entries.
1095
+ #
1096
+ # Arguments +src+ (a single path or an array of paths)
1097
+ # and +dest+ (a single path)
1098
+ # should be {interpretable as paths}[rdoc-ref:FileUtils@Path+Arguments].
1099
+ #
1100
+ # If +src+ and +dest+ are on different file systems,
1101
+ # first copies, then removes +src+.
1102
+ #
1103
+ # May cause a local vulnerability if not called with keyword argument
1104
+ # <tt>secure: true</tt>;
1105
+ # see {Avoiding the TOCTTOU Vulnerability}[rdoc-ref:FileUtils@Avoiding+the+TOCTTOU+Vulnerability].
1106
+ #
1107
+ # If +src+ is the path to a single file or directory and +dest+ does not exist,
1108
+ # moves +src+ to +dest+:
1109
+ #
1110
+ # tree('src0')
1111
+ # # => src0
1112
+ # # |-- src0.txt
1113
+ # # `-- src1.txt
1114
+ # File.exist?('dest0') # => false
1115
+ # Bundler::FileUtils.mv('src0', 'dest0')
1116
+ # File.exist?('src0') # => false
1117
+ # tree('dest0')
1118
+ # # => dest0
1119
+ # # |-- src0.txt
1120
+ # # `-- src1.txt
1121
+ #
1122
+ # If +src+ is an array of paths to files and directories
1123
+ # and +dest+ is the path to a directory,
1124
+ # copies from each path in the array to +dest+:
1125
+ #
1126
+ # File.file?('src1.txt') # => true
1127
+ # tree('src1')
1128
+ # # => src1
1129
+ # # |-- src.dat
1130
+ # # `-- src.txt
1131
+ # Dir.empty?('dest1') # => true
1132
+ # Bundler::FileUtils.mv(['src1.txt', 'src1'], 'dest1')
1133
+ # tree('dest1')
1134
+ # # => dest1
1135
+ # # |-- src1
1136
+ # # | |-- src.dat
1137
+ # # | `-- src.txt
1138
+ # # `-- src1.txt
1139
+ #
1140
+ # Keyword arguments:
1141
+ #
1142
+ # - <tt>force: true</tt> - if the move includes removing +src+
1143
+ # (that is, if +src+ and +dest+ are on different file systems),
1144
+ # ignores raised exceptions of StandardError and its descendants.
1145
+ # - <tt>noop: true</tt> - does not move files.
1146
+ # - <tt>secure: true</tt> - removes +src+ securely;
1147
+ # see details at Bundler::FileUtils.remove_entry_secure.
1148
+ # - <tt>verbose: true</tt> - prints an equivalent command:
1149
+ #
1150
+ # Bundler::FileUtils.mv('src0', 'dest0', noop: true, verbose: true)
1151
+ # Bundler::FileUtils.mv(['src1.txt', 'src1'], 'dest1', noop: true, verbose: true)
1152
+ #
1153
+ # Output:
1154
+ #
1155
+ # mv src0 dest0
1156
+ # mv src1.txt src1 dest1
535
1157
  #
536
1158
  def mv(src, dest, force: nil, noop: nil, verbose: nil, secure: nil)
537
1159
  fu_output_message "mv#{force ? ' -f' : ''} #{[src,dest].flatten.join ' '}" if verbose
@@ -565,13 +1187,32 @@ module Bundler::FileUtils
565
1187
  alias move mv
566
1188
  module_function :move
567
1189
 
1190
+ # Removes entries at the paths in the given +list+
1191
+ # (a single path or an array of paths)
1192
+ # returns +list+, if it is an array, <tt>[list]</tt> otherwise.
568
1193
  #
569
- # Remove file(s) specified in +list+. This method cannot remove directories.
570
- # All StandardErrors are ignored when the :force option is set.
1194
+ # Argument +list+ or its elements
1195
+ # should be {interpretable as paths}[rdoc-ref:FileUtils@Path+Arguments].
571
1196
  #
572
- # Bundler::FileUtils.rm %w( junk.txt dust.txt )
573
- # Bundler::FileUtils.rm Dir.glob('*.so')
574
- # Bundler::FileUtils.rm 'NotExistFile', force: true # never raises exception
1197
+ # With no keyword arguments, removes files at the paths given in +list+:
1198
+ #
1199
+ # Bundler::FileUtils.touch(['src0.txt', 'src0.dat'])
1200
+ # Bundler::FileUtils.rm(['src0.dat', 'src0.txt']) # => ["src0.dat", "src0.txt"]
1201
+ #
1202
+ # Keyword arguments:
1203
+ #
1204
+ # - <tt>force: true</tt> - ignores raised exceptions of StandardError
1205
+ # and its descendants.
1206
+ # - <tt>noop: true</tt> - does not remove files; returns +nil+.
1207
+ # - <tt>verbose: true</tt> - prints an equivalent command:
1208
+ #
1209
+ # Bundler::FileUtils.rm(['src0.dat', 'src0.txt'], noop: true, verbose: true)
1210
+ #
1211
+ # Output:
1212
+ #
1213
+ # rm src0.dat src0.txt
1214
+ #
1215
+ # Related: {methods for deleting}[rdoc-ref:FileUtils@Deleting].
575
1216
  #
576
1217
  def rm(list, force: nil, noop: nil, verbose: nil)
577
1218
  list = fu_list(list)
@@ -587,10 +1228,16 @@ module Bundler::FileUtils
587
1228
  alias remove rm
588
1229
  module_function :remove
589
1230
 
1231
+ # Equivalent to:
1232
+ #
1233
+ # Bundler::FileUtils.rm(list, force: true, **kwargs)
590
1234
  #
591
- # Equivalent to
1235
+ # Argument +list+ (a single path or an array of paths)
1236
+ # should be {interpretable as paths}[rdoc-ref:FileUtils@Path+Arguments].
592
1237
  #
593
- # Bundler::FileUtils.rm(list, force: true)
1238
+ # See Bundler::FileUtils.rm for keyword arguments.
1239
+ #
1240
+ # Related: {methods for deleting}[rdoc-ref:FileUtils@Deleting].
594
1241
  #
595
1242
  def rm_f(list, noop: nil, verbose: nil)
596
1243
  rm list, force: true, noop: noop, verbose: verbose
@@ -600,24 +1247,55 @@ module Bundler::FileUtils
600
1247
  alias safe_unlink rm_f
601
1248
  module_function :safe_unlink
602
1249
 
1250
+ # Removes entries at the paths in the given +list+
1251
+ # (a single path or an array of paths);
1252
+ # returns +list+, if it is an array, <tt>[list]</tt> otherwise.
1253
+ #
1254
+ # Argument +list+ or its elements
1255
+ # should be {interpretable as paths}[rdoc-ref:FileUtils@Path+Arguments].
1256
+ #
1257
+ # May cause a local vulnerability if not called with keyword argument
1258
+ # <tt>secure: true</tt>;
1259
+ # see {Avoiding the TOCTTOU Vulnerability}[rdoc-ref:FileUtils@Avoiding+the+TOCTTOU+Vulnerability].
1260
+ #
1261
+ # For each file path, removes the file at that path:
1262
+ #
1263
+ # Bundler::FileUtils.touch(['src0.txt', 'src0.dat'])
1264
+ # Bundler::FileUtils.rm_r(['src0.dat', 'src0.txt'])
1265
+ # File.exist?('src0.txt') # => false
1266
+ # File.exist?('src0.dat') # => false
1267
+ #
1268
+ # For each directory path, recursively removes files and directories:
1269
+ #
1270
+ # tree('src1')
1271
+ # # => src1
1272
+ # # |-- dir0
1273
+ # # | |-- src0.txt
1274
+ # # | `-- src1.txt
1275
+ # # `-- dir1
1276
+ # # |-- src2.txt
1277
+ # # `-- src3.txt
1278
+ # Bundler::FileUtils.rm_r('src1')
1279
+ # File.exist?('src1') # => false
1280
+ #
1281
+ # Keyword arguments:
1282
+ #
1283
+ # - <tt>force: true</tt> - ignores raised exceptions of StandardError
1284
+ # and its descendants.
1285
+ # - <tt>noop: true</tt> - does not remove entries; returns +nil+.
1286
+ # - <tt>secure: true</tt> - removes +src+ securely;
1287
+ # see details at Bundler::FileUtils.remove_entry_secure.
1288
+ # - <tt>verbose: true</tt> - prints an equivalent command:
603
1289
  #
604
- # remove files +list+[0] +list+[1]... If +list+[n] is a directory,
605
- # removes its all contents recursively. This method ignores
606
- # StandardError when :force option is set.
1290
+ # Bundler::FileUtils.rm_r(['src0.dat', 'src0.txt'], noop: true, verbose: true)
1291
+ # Bundler::FileUtils.rm_r('src1', noop: true, verbose: true)
607
1292
  #
608
- # Bundler::FileUtils.rm_r Dir.glob('/tmp/*')
609
- # Bundler::FileUtils.rm_r 'some_dir', force: true
1293
+ # Output:
610
1294
  #
611
- # WARNING: This method causes local vulnerability
612
- # if one of parent directories or removing directory tree are world
613
- # writable (including /tmp, whose permission is 1777), and the current
614
- # process has strong privilege such as Unix super user (root), and the
615
- # system has symbolic link. For secure removing, read the documentation
616
- # of remove_entry_secure carefully, and set :secure option to true.
617
- # Default is <tt>secure: false</tt>.
1295
+ # rm -r src0.dat src0.txt
1296
+ # rm -r src1
618
1297
  #
619
- # NOTE: This method calls remove_entry_secure if :secure option is set.
620
- # See also remove_entry_secure.
1298
+ # Related: {methods for deleting}[rdoc-ref:FileUtils@Deleting].
621
1299
  #
622
1300
  def rm_r(list, force: nil, noop: nil, verbose: nil, secure: nil)
623
1301
  list = fu_list(list)
@@ -633,13 +1311,20 @@ module Bundler::FileUtils
633
1311
  end
634
1312
  module_function :rm_r
635
1313
 
1314
+ # Equivalent to:
636
1315
  #
637
- # Equivalent to
1316
+ # Bundler::FileUtils.rm_r(list, force: true, **kwargs)
638
1317
  #
639
- # Bundler::FileUtils.rm_r(list, force: true)
1318
+ # Argument +list+ or its elements
1319
+ # should be {interpretable as paths}[rdoc-ref:FileUtils@Path+Arguments].
640
1320
  #
641
- # WARNING: This method causes local vulnerability.
642
- # Read the documentation of rm_r first.
1321
+ # May cause a local vulnerability if not called with keyword argument
1322
+ # <tt>secure: true</tt>;
1323
+ # see {Avoiding the TOCTTOU Vulnerability}[rdoc-ref:FileUtils@Avoiding+the+TOCTTOU+Vulnerability].
1324
+ #
1325
+ # See Bundler::FileUtils.rm_r for keyword arguments.
1326
+ #
1327
+ # Related: {methods for deleting}[rdoc-ref:FileUtils@Deleting].
643
1328
  #
644
1329
  def rm_rf(list, noop: nil, verbose: nil, secure: nil)
645
1330
  rm_r list, force: true, noop: noop, verbose: verbose, secure: secure
@@ -649,37 +1334,20 @@ module Bundler::FileUtils
649
1334
  alias rmtree rm_rf
650
1335
  module_function :rmtree
651
1336
 
1337
+ # Securely removes the entry given by +path+,
1338
+ # which should be the entry for a regular file, a symbolic link,
1339
+ # or a directory.
652
1340
  #
653
- # This method removes a file system entry +path+. +path+ shall be a
654
- # regular file, a directory, or something. If +path+ is a directory,
655
- # remove it recursively. This method is required to avoid TOCTTOU
656
- # (time-of-check-to-time-of-use) local security vulnerability of rm_r.
657
- # #rm_r causes security hole when:
658
- #
659
- # * Parent directory is world writable (including /tmp).
660
- # * Removing directory tree includes world writable directory.
661
- # * The system has symbolic link.
662
- #
663
- # To avoid this security hole, this method applies special preprocess.
664
- # If +path+ is a directory, this method chown(2) and chmod(2) all
665
- # removing directories. This requires the current process is the
666
- # owner of the removing whole directory tree, or is the super user (root).
1341
+ # Argument +path+
1342
+ # should be {interpretable as a path}[rdoc-ref:FileUtils@Path+Arguments].
667
1343
  #
668
- # WARNING: You must ensure that *ALL* parent directories cannot be
669
- # moved by other untrusted users. For example, parent directories
670
- # should not be owned by untrusted users, and should not be world
671
- # writable except when the sticky bit set.
1344
+ # Avoids a local vulnerability that can exist in certain circumstances;
1345
+ # see {Avoiding the TOCTTOU Vulnerability}[rdoc-ref:FileUtils@Avoiding+the+TOCTTOU+Vulnerability].
672
1346
  #
673
- # WARNING: Only the owner of the removing directory tree, or Unix super
674
- # user (root) should invoke this method. Otherwise this method does not
675
- # work.
1347
+ # Optional argument +force+ specifies whether to ignore
1348
+ # raised exceptions of StandardError and its descendants.
676
1349
  #
677
- # For details of this security vulnerability, see Perl's case:
678
- #
679
- # * https://cve.mitre.org/cgi-bin/cvename.cgi?name=CAN-2005-0448
680
- # * https://cve.mitre.org/cgi-bin/cvename.cgi?name=CAN-2004-0452
681
- #
682
- # For fileutils.rb, this vulnerability is reported in [ruby-dev:26100].
1350
+ # Related: {methods for deleting}[rdoc-ref:FileUtils@Deleting].
683
1351
  #
684
1352
  def remove_entry_secure(path, force = false)
685
1353
  unless fu_have_symlink?
@@ -767,12 +1435,17 @@ module Bundler::FileUtils
767
1435
  end
768
1436
  private_module_function :fu_stat_identical_entry?
769
1437
 
1438
+ # Removes the entry given by +path+,
1439
+ # which should be the entry for a regular file, a symbolic link,
1440
+ # or a directory.
770
1441
  #
771
- # This method removes a file system entry +path+.
772
- # +path+ might be a regular file, a directory, or something.
773
- # If +path+ is a directory, remove it recursively.
1442
+ # Argument +path+
1443
+ # should be {interpretable as a path}[rdoc-ref:FileUtils@Path+Arguments].
774
1444
  #
775
- # See also remove_entry_secure.
1445
+ # Optional argument +force+ specifies whether to ignore
1446
+ # raised exceptions of StandardError and its descendants.
1447
+ #
1448
+ # Related: Bundler::FileUtils.remove_entry_secure.
776
1449
  #
777
1450
  def remove_entry(path, force = false)
778
1451
  Entry_.new(path).postorder_traverse do |ent|
@@ -787,9 +1460,16 @@ module Bundler::FileUtils
787
1460
  end
788
1461
  module_function :remove_entry
789
1462
 
1463
+ # Removes the file entry given by +path+,
1464
+ # which should be the entry for a regular file or a symbolic link.
1465
+ #
1466
+ # Argument +path+
1467
+ # should be {interpretable as a path}[rdoc-ref:FileUtils@Path+Arguments].
790
1468
  #
791
- # Removes a file +path+.
792
- # This method ignores StandardError if +force+ is true.
1469
+ # Optional argument +force+ specifies whether to ignore
1470
+ # raised exceptions of StandardError and its descendants.
1471
+ #
1472
+ # Related: {methods for deleting}[rdoc-ref:FileUtils@Deleting].
793
1473
  #
794
1474
  def remove_file(path, force = false)
795
1475
  Entry_.new(path).remove_file
@@ -798,20 +1478,32 @@ module Bundler::FileUtils
798
1478
  end
799
1479
  module_function :remove_file
800
1480
 
1481
+ # Recursively removes the directory entry given by +path+,
1482
+ # which should be the entry for a regular file, a symbolic link,
1483
+ # or a directory.
1484
+ #
1485
+ # Argument +path+
1486
+ # should be {interpretable as a path}[rdoc-ref:FileUtils@Path+Arguments].
1487
+ #
1488
+ # Optional argument +force+ specifies whether to ignore
1489
+ # raised exceptions of StandardError and its descendants.
801
1490
  #
802
- # Removes a directory +dir+ and its contents recursively.
803
- # This method ignores StandardError if +force+ is true.
1491
+ # Related: {methods for deleting}[rdoc-ref:FileUtils@Deleting].
804
1492
  #
805
1493
  def remove_dir(path, force = false)
806
1494
  remove_entry path, force # FIXME?? check if it is a directory
807
1495
  end
808
1496
  module_function :remove_dir
809
1497
 
1498
+ # Returns +true+ if the contents of files +a+ and +b+ are identical,
1499
+ # +false+ otherwise.
810
1500
  #
811
- # Returns true if the contents of a file +a+ and a file +b+ are identical.
1501
+ # Arguments +a+ and +b+
1502
+ # should be {interpretable as a path}[rdoc-ref:FileUtils@Path+Arguments].
812
1503
  #
813
- # Bundler::FileUtils.compare_file('somefile', 'somefile') #=> true
814
- # Bundler::FileUtils.compare_file('/dev/null', '/dev/urandom') #=> false
1504
+ # Bundler::FileUtils.identical? and Bundler::FileUtils.cmp are aliases for Bundler::FileUtils.compare_file.
1505
+ #
1506
+ # Related: Bundler::FileUtils.compare_stream.
815
1507
  #
816
1508
  def compare_file(a, b)
817
1509
  return false unless File.size(a) == File.size(b)
@@ -828,19 +1520,19 @@ module Bundler::FileUtils
828
1520
  module_function :identical?
829
1521
  module_function :cmp
830
1522
 
1523
+ # Returns +true+ if the contents of streams +a+ and +b+ are identical,
1524
+ # +false+ otherwise.
1525
+ #
1526
+ # Arguments +a+ and +b+
1527
+ # should be {interpretable as a path}[rdoc-ref:FileUtils@Path+Arguments].
831
1528
  #
832
- # Returns true if the contents of a stream +a+ and +b+ are identical.
1529
+ # Related: Bundler::FileUtils.compare_file.
833
1530
  #
834
1531
  def compare_stream(a, b)
835
1532
  bsize = fu_stream_blksize(a, b)
836
1533
 
837
- if RUBY_VERSION > "2.4"
838
- sa = String.new(capacity: bsize)
839
- sb = String.new(capacity: bsize)
840
- else
841
- sa = String.new
842
- sb = String.new
843
- end
1534
+ sa = String.new(capacity: bsize)
1535
+ sb = String.new(capacity: bsize)
844
1536
 
845
1537
  begin
846
1538
  a.read(bsize, sa)
@@ -851,13 +1543,69 @@ module Bundler::FileUtils
851
1543
  end
852
1544
  module_function :compare_stream
853
1545
 
1546
+ # Copies a file entry.
1547
+ # See {install(1)}[https://man7.org/linux/man-pages/man1/install.1.html].
1548
+ #
1549
+ # Arguments +src+ (a single path or an array of paths)
1550
+ # and +dest+ (a single path)
1551
+ # should be {interpretable as paths}[rdoc-ref:FileUtils@Path+Arguments];
1552
+ #
1553
+ # If the entry at +dest+ does not exist, copies from +src+ to +dest+:
1554
+ #
1555
+ # File.read('src0.txt') # => "aaa\n"
1556
+ # File.exist?('dest0.txt') # => false
1557
+ # Bundler::FileUtils.install('src0.txt', 'dest0.txt')
1558
+ # File.read('dest0.txt') # => "aaa\n"
1559
+ #
1560
+ # If +dest+ is a file entry, copies from +src+ to +dest+, overwriting:
1561
+ #
1562
+ # File.read('src1.txt') # => "aaa\n"
1563
+ # File.read('dest1.txt') # => "bbb\n"
1564
+ # Bundler::FileUtils.install('src1.txt', 'dest1.txt')
1565
+ # File.read('dest1.txt') # => "aaa\n"
1566
+ #
1567
+ # If +dest+ is a directory entry, copies from +src+ to <tt>dest/src</tt>,
1568
+ # overwriting if necessary:
1569
+ #
1570
+ # File.read('src2.txt') # => "aaa\n"
1571
+ # File.read('dest2/src2.txt') # => "bbb\n"
1572
+ # Bundler::FileUtils.install('src2.txt', 'dest2')
1573
+ # File.read('dest2/src2.txt') # => "aaa\n"
1574
+ #
1575
+ # If +src+ is an array of paths and +dest+ points to a directory,
1576
+ # copies each path +path+ in +src+ to <tt>dest/path</tt>:
1577
+ #
1578
+ # File.file?('src3.txt') # => true
1579
+ # File.file?('src3.dat') # => true
1580
+ # Bundler::FileUtils.mkdir('dest3')
1581
+ # Bundler::FileUtils.install(['src3.txt', 'src3.dat'], 'dest3')
1582
+ # File.file?('dest3/src3.txt') # => true
1583
+ # File.file?('dest3/src3.dat') # => true
1584
+ #
1585
+ # Keyword arguments:
854
1586
  #
855
- # If +src+ is not same as +dest+, copies it and changes the permission
856
- # mode to +mode+. If +dest+ is a directory, destination is +dest+/+src+.
857
- # This method removes destination before copy.
1587
+ # - <tt>group: <i>group</i></tt> - changes the group if not +nil+,
1588
+ # using {File.chown}[https://docs.ruby-lang.org/en/master/File.html#method-c-chown].
1589
+ # - <tt>mode: <i>permissions</i></tt> - changes the permissions.
1590
+ # using {File.chmod}[https://docs.ruby-lang.org/en/master/File.html#method-c-chmod].
1591
+ # - <tt>noop: true</tt> - does not copy entries; returns +nil+.
1592
+ # - <tt>owner: <i>owner</i></tt> - changes the owner if not +nil+,
1593
+ # using {File.chown}[https://docs.ruby-lang.org/en/master/File.html#method-c-chown].
1594
+ # - <tt>preserve: true</tt> - preserve timestamps
1595
+ # using {File.utime}[https://docs.ruby-lang.org/en/master/File.html#method-c-utime].
1596
+ # - <tt>verbose: true</tt> - prints an equivalent command:
858
1597
  #
859
- # Bundler::FileUtils.install 'ruby', '/usr/local/bin/ruby', mode: 0755, verbose: true
860
- # Bundler::FileUtils.install 'lib.rb', '/usr/local/lib/ruby/site_ruby', verbose: true
1598
+ # Bundler::FileUtils.install('src0.txt', 'dest0.txt', noop: true, verbose: true)
1599
+ # Bundler::FileUtils.install('src1.txt', 'dest1.txt', noop: true, verbose: true)
1600
+ # Bundler::FileUtils.install('src2.txt', 'dest2', noop: true, verbose: true)
1601
+ #
1602
+ # Output:
1603
+ #
1604
+ # install -c src0.txt dest0.txt
1605
+ # install -c src1.txt dest1.txt
1606
+ # install -c src2.txt dest2
1607
+ #
1608
+ # Related: {methods for copying}[rdoc-ref:FileUtils@Copying].
861
1609
  #
862
1610
  def install(src, dest, mode: nil, owner: nil, group: nil, preserve: nil,
863
1611
  noop: nil, verbose: nil)
@@ -877,7 +1625,13 @@ module Bundler::FileUtils
877
1625
  st = File.stat(s)
878
1626
  unless File.exist?(d) and compare_file(s, d)
879
1627
  remove_file d, true
880
- copy_file s, d
1628
+ if d.end_with?('/')
1629
+ mkdir_p d
1630
+ copy_file s, d + File.basename(s)
1631
+ else
1632
+ mkdir_p File.expand_path('..', d)
1633
+ copy_file s, d
1634
+ end
881
1635
  File.utime st.atime, st.mtime, d if preserve
882
1636
  File.chmod fu_mode(mode, st), d if mode
883
1637
  File.chown uid, gid, d if uid or gid
@@ -898,7 +1652,7 @@ module Bundler::FileUtils
898
1652
  when "a"
899
1653
  mask | 07777
900
1654
  else
901
- raise ArgumentError, "invalid `who' symbol in file mode: #{chr}"
1655
+ raise ArgumentError, "invalid 'who' symbol in file mode: #{chr}"
902
1656
  end
903
1657
  end
904
1658
  end
@@ -917,11 +1671,8 @@ module Bundler::FileUtils
917
1671
  private_module_function :apply_mask
918
1672
 
919
1673
  def symbolic_modes_to_i(mode_sym, path) #:nodoc:
920
- mode = if File::Stat === path
921
- path.mode
922
- else
923
- File.stat(path).mode
924
- end
1674
+ path = File.stat(path) unless File::Stat === path
1675
+ mode = path.mode
925
1676
  mode_sym.split(/,/).inject(mode & 07777) do |current_mode, clause|
926
1677
  target, *actions = clause.split(/([=+-])/)
927
1678
  raise ArgumentError, "invalid file mode: #{mode_sym}" if actions.empty?
@@ -938,7 +1689,7 @@ module Bundler::FileUtils
938
1689
  when "x"
939
1690
  mask | 0111
940
1691
  when "X"
941
- if FileTest.directory? path
1692
+ if path.directory?
942
1693
  mask | 0111
943
1694
  else
944
1695
  mask
@@ -955,7 +1706,7 @@ module Bundler::FileUtils
955
1706
  copy_mask = user_mask(chr)
956
1707
  (current_mode & copy_mask) / (copy_mask & 0111) * (user_mask & 0111)
957
1708
  else
958
- raise ArgumentError, "invalid `perm' symbol in file mode: #{chr}"
1709
+ raise ArgumentError, "invalid 'perm' symbol in file mode: #{chr}"
959
1710
  end
960
1711
  end
961
1712
 
@@ -978,37 +1729,78 @@ module Bundler::FileUtils
978
1729
  end
979
1730
  private_module_function :mode_to_s
980
1731
 
1732
+ # Changes permissions on the entries at the paths given in +list+
1733
+ # (a single path or an array of paths)
1734
+ # to the permissions given by +mode+;
1735
+ # returns +list+ if it is an array, <tt>[list]</tt> otherwise:
1736
+ #
1737
+ # - Modifies each entry that is a regular file using
1738
+ # {File.chmod}[https://docs.ruby-lang.org/en/master/File.html#method-c-chmod].
1739
+ # - Modifies each entry that is a symbolic link using
1740
+ # {File.lchmod}[https://docs.ruby-lang.org/en/master/File.html#method-c-lchmod].
1741
+ #
1742
+ # Argument +list+ or its elements
1743
+ # should be {interpretable as paths}[rdoc-ref:FileUtils@Path+Arguments].
1744
+ #
1745
+ # Argument +mode+ may be either an integer or a string:
1746
+ #
1747
+ # - \Integer +mode+: represents the permission bits to be set:
1748
+ #
1749
+ # Bundler::FileUtils.chmod(0755, 'src0.txt')
1750
+ # Bundler::FileUtils.chmod(0644, ['src0.txt', 'src0.dat'])
1751
+ #
1752
+ # - \String +mode+: represents the permissions to be set:
1753
+ #
1754
+ # The string is of the form <tt>[targets][[operator][perms[,perms]]</tt>, where:
1755
+ #
1756
+ # - +targets+ may be any combination of these letters:
1757
+ #
1758
+ # - <tt>'u'</tt>: permissions apply to the file's owner.
1759
+ # - <tt>'g'</tt>: permissions apply to users in the file's group.
1760
+ # - <tt>'o'</tt>: permissions apply to other users not in the file's group.
1761
+ # - <tt>'a'</tt> (the default): permissions apply to all users.
1762
+ #
1763
+ # - +operator+ may be one of these letters:
1764
+ #
1765
+ # - <tt>'+'</tt>: adds permissions.
1766
+ # - <tt>'-'</tt>: removes permissions.
1767
+ # - <tt>'='</tt>: sets (replaces) permissions.
1768
+ #
1769
+ # - +perms+ (may be repeated, with separating commas)
1770
+ # may be any combination of these letters:
1771
+ #
1772
+ # - <tt>'r'</tt>: Read.
1773
+ # - <tt>'w'</tt>: Write.
1774
+ # - <tt>'x'</tt>: Execute (search, for a directory).
1775
+ # - <tt>'X'</tt>: Search (for a directories only;
1776
+ # must be used with <tt>'+'</tt>)
1777
+ # - <tt>'s'</tt>: Uid or gid.
1778
+ # - <tt>'t'</tt>: Sticky bit.
1779
+ #
1780
+ # Examples:
1781
+ #
1782
+ # Bundler::FileUtils.chmod('u=wrx,go=rx', 'src1.txt')
1783
+ # Bundler::FileUtils.chmod('u=wrx,go=rx', '/usr/bin/ruby')
1784
+ #
1785
+ # Keyword arguments:
1786
+ #
1787
+ # - <tt>noop: true</tt> - does not change permissions; returns +nil+.
1788
+ # - <tt>verbose: true</tt> - prints an equivalent command:
1789
+ #
1790
+ # Bundler::FileUtils.chmod(0755, 'src0.txt', noop: true, verbose: true)
1791
+ # Bundler::FileUtils.chmod(0644, ['src0.txt', 'src0.dat'], noop: true, verbose: true)
1792
+ # Bundler::FileUtils.chmod('u=wrx,go=rx', 'src1.txt', noop: true, verbose: true)
1793
+ # Bundler::FileUtils.chmod('u=wrx,go=rx', '/usr/bin/ruby', noop: true, verbose: true)
1794
+ #
1795
+ # Output:
1796
+ #
1797
+ # chmod 755 src0.txt
1798
+ # chmod 644 src0.txt src0.dat
1799
+ # chmod u=wrx,go=rx src1.txt
1800
+ # chmod u=wrx,go=rx /usr/bin/ruby
1801
+ #
1802
+ # Related: Bundler::FileUtils.chmod_R.
981
1803
  #
982
- # Changes permission bits on the named files (in +list+) to the bit pattern
983
- # represented by +mode+.
984
- #
985
- # +mode+ is the symbolic and absolute mode can be used.
986
- #
987
- # Absolute mode is
988
- # Bundler::FileUtils.chmod 0755, 'somecommand'
989
- # Bundler::FileUtils.chmod 0644, %w(my.rb your.rb his.rb her.rb)
990
- # Bundler::FileUtils.chmod 0755, '/usr/bin/ruby', verbose: true
991
- #
992
- # Symbolic mode is
993
- # Bundler::FileUtils.chmod "u=wrx,go=rx", 'somecommand'
994
- # Bundler::FileUtils.chmod "u=wr,go=rr", %w(my.rb your.rb his.rb her.rb)
995
- # Bundler::FileUtils.chmod "u=wrx,go=rx", '/usr/bin/ruby', verbose: true
996
- #
997
- # "a" :: is user, group, other mask.
998
- # "u" :: is user's mask.
999
- # "g" :: is group's mask.
1000
- # "o" :: is other's mask.
1001
- # "w" :: is write permission.
1002
- # "r" :: is read permission.
1003
- # "x" :: is execute permission.
1004
- # "X" ::
1005
- # is execute permission for directories only, must be used in conjunction with "+"
1006
- # "s" :: is uid, gid.
1007
- # "t" :: is sticky bit.
1008
- # "+" :: is added to a class given the specified mode.
1009
- # "-" :: Is removed from a given class given mode.
1010
- # "=" :: Is the exact nature of the class will be given a specified mode.
1011
-
1012
1804
  def chmod(mode, list, noop: nil, verbose: nil)
1013
1805
  list = fu_list(list)
1014
1806
  fu_output_message sprintf('chmod %s %s', mode_to_s(mode), list.join(' ')) if verbose
@@ -1019,12 +1811,7 @@ module Bundler::FileUtils
1019
1811
  end
1020
1812
  module_function :chmod
1021
1813
 
1022
- #
1023
- # Changes permission bits on the named files (in +list+)
1024
- # to the bit pattern represented by +mode+.
1025
- #
1026
- # Bundler::FileUtils.chmod_R 0700, "/tmp/app.#{$$}"
1027
- # Bundler::FileUtils.chmod_R "u=wrx", "/tmp/app.#{$$}"
1814
+ # Like Bundler::FileUtils.chmod, but changes permissions recursively.
1028
1815
  #
1029
1816
  def chmod_R(mode, list, noop: nil, verbose: nil, force: nil)
1030
1817
  list = fu_list(list)
@@ -1044,15 +1831,68 @@ module Bundler::FileUtils
1044
1831
  end
1045
1832
  module_function :chmod_R
1046
1833
 
1834
+ # Changes the owner and group on the entries at the paths given in +list+
1835
+ # (a single path or an array of paths)
1836
+ # to the given +user+ and +group+;
1837
+ # returns +list+ if it is an array, <tt>[list]</tt> otherwise:
1838
+ #
1839
+ # - Modifies each entry that is a regular file using
1840
+ # {File.chown}[https://docs.ruby-lang.org/en/master/File.html#method-c-chown].
1841
+ # - Modifies each entry that is a symbolic link using
1842
+ # {File.lchown}[https://docs.ruby-lang.org/en/master/File.html#method-c-lchown].
1843
+ #
1844
+ # Argument +list+ or its elements
1845
+ # should be {interpretable as paths}[rdoc-ref:FileUtils@Path+Arguments].
1846
+ #
1847
+ # User and group:
1848
+ #
1849
+ # - Argument +user+ may be a user name or a user id;
1850
+ # if +nil+ or +-1+, the user is not changed.
1851
+ # - Argument +group+ may be a group name or a group id;
1852
+ # if +nil+ or +-1+, the group is not changed.
1853
+ # - The user must be a member of the group.
1047
1854
  #
1048
- # Changes owner and group on the named files (in +list+)
1049
- # to the user +user+ and the group +group+. +user+ and +group+
1050
- # may be an ID (Integer/String) or a name (String).
1051
- # If +user+ or +group+ is nil, this method does not change
1052
- # the attribute.
1855
+ # Examples:
1053
1856
  #
1054
- # Bundler::FileUtils.chown 'root', 'staff', '/usr/local/bin/ruby'
1055
- # Bundler::FileUtils.chown nil, 'bin', Dir.glob('/usr/bin/*'), verbose: true
1857
+ # # One path.
1858
+ # # User and group as string names.
1859
+ # File.stat('src0.txt').uid # => 1004
1860
+ # File.stat('src0.txt').gid # => 1004
1861
+ # Bundler::FileUtils.chown('user2', 'group1', 'src0.txt')
1862
+ # File.stat('src0.txt').uid # => 1006
1863
+ # File.stat('src0.txt').gid # => 1005
1864
+ #
1865
+ # # User and group as uid and gid.
1866
+ # Bundler::FileUtils.chown(1004, 1004, 'src0.txt')
1867
+ # File.stat('src0.txt').uid # => 1004
1868
+ # File.stat('src0.txt').gid # => 1004
1869
+ #
1870
+ # # Array of paths.
1871
+ # Bundler::FileUtils.chown(1006, 1005, ['src0.txt', 'src0.dat'])
1872
+ #
1873
+ # # Directory (not recursive).
1874
+ # Bundler::FileUtils.chown('user2', 'group1', '.')
1875
+ #
1876
+ # Keyword arguments:
1877
+ #
1878
+ # - <tt>noop: true</tt> - does not change permissions; returns +nil+.
1879
+ # - <tt>verbose: true</tt> - prints an equivalent command:
1880
+ #
1881
+ # Bundler::FileUtils.chown('user2', 'group1', 'src0.txt', noop: true, verbose: true)
1882
+ # Bundler::FileUtils.chown(1004, 1004, 'src0.txt', noop: true, verbose: true)
1883
+ # Bundler::FileUtils.chown(1006, 1005, ['src0.txt', 'src0.dat'], noop: true, verbose: true)
1884
+ # Bundler::FileUtils.chown('user2', 'group1', path, noop: true, verbose: true)
1885
+ # Bundler::FileUtils.chown('user2', 'group1', '.', noop: true, verbose: true)
1886
+ #
1887
+ # Output:
1888
+ #
1889
+ # chown user2:group1 src0.txt
1890
+ # chown 1004:1004 src0.txt
1891
+ # chown 1006:1005 src0.txt src0.dat
1892
+ # chown user2:group1 src0.txt
1893
+ # chown user2:group1 .
1894
+ #
1895
+ # Related: Bundler::FileUtils.chown_R.
1056
1896
  #
1057
1897
  def chown(user, group, list, noop: nil, verbose: nil)
1058
1898
  list = fu_list(list)
@@ -1068,15 +1908,7 @@ module Bundler::FileUtils
1068
1908
  end
1069
1909
  module_function :chown
1070
1910
 
1071
- #
1072
- # Changes owner and group on the named files (in +list+)
1073
- # to the user +user+ and the group +group+ recursively.
1074
- # +user+ and +group+ may be an ID (Integer/String) or
1075
- # a name (String). If +user+ or +group+ is nil, this
1076
- # method does not change the attribute.
1077
- #
1078
- # Bundler::FileUtils.chown_R 'www', 'www', '/var/www/htdocs'
1079
- # Bundler::FileUtils.chown_R 'cvs', 'cvs', '/var/cvs', verbose: true
1911
+ # Like Bundler::FileUtils.chown, but changes owner and group recursively.
1080
1912
  #
1081
1913
  def chown_R(user, group, list, noop: nil, verbose: nil, force: nil)
1082
1914
  list = fu_list(list)
@@ -1127,12 +1959,50 @@ module Bundler::FileUtils
1127
1959
  end
1128
1960
  private_module_function :fu_get_gid
1129
1961
 
1962
+ # Updates modification times (mtime) and access times (atime)
1963
+ # of the entries given by the paths in +list+
1964
+ # (a single path or an array of paths);
1965
+ # returns +list+ if it is an array, <tt>[list]</tt> otherwise.
1966
+ #
1967
+ # By default, creates an empty file for any path to a non-existent entry;
1968
+ # use keyword argument +nocreate+ to raise an exception instead.
1969
+ #
1970
+ # Argument +list+ or its elements
1971
+ # should be {interpretable as paths}[rdoc-ref:FileUtils@Path+Arguments].
1972
+ #
1973
+ # Examples:
1974
+ #
1975
+ # # Single path.
1976
+ # f = File.new('src0.txt') # Existing file.
1977
+ # f.atime # => 2022-06-10 11:11:21.200277 -0700
1978
+ # f.mtime # => 2022-06-10 11:11:21.200277 -0700
1979
+ # Bundler::FileUtils.touch('src0.txt')
1980
+ # f = File.new('src0.txt')
1981
+ # f.atime # => 2022-06-11 08:28:09.8185343 -0700
1982
+ # f.mtime # => 2022-06-11 08:28:09.8185343 -0700
1983
+ #
1984
+ # # Array of paths.
1985
+ # Bundler::FileUtils.touch(['src0.txt', 'src0.dat'])
1986
+ #
1987
+ # Keyword arguments:
1130
1988
  #
1131
- # Updates modification time (mtime) and access time (atime) of file(s) in
1132
- # +list+. Files are created if they don't exist.
1989
+ # - <tt>mtime: <i>time</i></tt> - sets the entry's mtime to the given time,
1990
+ # instead of the current time.
1991
+ # - <tt>nocreate: true</tt> - raises an exception if the entry does not exist.
1992
+ # - <tt>noop: true</tt> - does not touch entries; returns +nil+.
1993
+ # - <tt>verbose: true</tt> - prints an equivalent command:
1133
1994
  #
1134
- # Bundler::FileUtils.touch 'timestamp'
1135
- # Bundler::FileUtils.touch Dir.glob('*.c'); system 'make'
1995
+ # Bundler::FileUtils.touch('src0.txt', noop: true, verbose: true)
1996
+ # Bundler::FileUtils.touch(['src0.txt', 'src0.dat'], noop: true, verbose: true)
1997
+ # Bundler::FileUtils.touch(path, noop: true, verbose: true)
1998
+ #
1999
+ # Output:
2000
+ #
2001
+ # touch src0.txt
2002
+ # touch src0.txt src0.dat
2003
+ # touch src0.txt
2004
+ #
2005
+ # Related: Bundler::FileUtils.uptodate?.
1136
2006
  #
1137
2007
  def touch(list, noop: nil, verbose: nil, mtime: nil, nocreate: nil)
1138
2008
  list = fu_list(list)
@@ -1159,21 +2029,22 @@ module Bundler::FileUtils
1159
2029
 
1160
2030
  private
1161
2031
 
1162
- module StreamUtils_
2032
+ module StreamUtils_ # :nodoc:
2033
+
1163
2034
  private
1164
2035
 
1165
2036
  case (defined?(::RbConfig) ? ::RbConfig::CONFIG['host_os'] : ::RUBY_PLATFORM)
1166
2037
  when /mswin|mingw/
1167
- def fu_windows?; true end
2038
+ def fu_windows?; true end #:nodoc:
1168
2039
  else
1169
- def fu_windows?; false end
2040
+ def fu_windows?; false end #:nodoc:
1170
2041
  end
1171
2042
 
1172
2043
  def fu_copy_stream0(src, dest, blksize = nil) #:nodoc:
1173
2044
  IO.copy_stream(src, dest)
1174
2045
  end
1175
2046
 
1176
- def fu_stream_blksize(*streams)
2047
+ def fu_stream_blksize(*streams) #:nodoc:
1177
2048
  streams.each do |s|
1178
2049
  next unless s.respond_to?(:stat)
1179
2050
  size = fu_blksize(s.stat)
@@ -1182,14 +2053,14 @@ module Bundler::FileUtils
1182
2053
  fu_default_blksize()
1183
2054
  end
1184
2055
 
1185
- def fu_blksize(st)
2056
+ def fu_blksize(st) #:nodoc:
1186
2057
  s = st.blksize
1187
2058
  return nil unless s
1188
2059
  return nil if s == 0
1189
2060
  s
1190
2061
  end
1191
2062
 
1192
- def fu_default_blksize
2063
+ def fu_default_blksize #:nodoc:
1193
2064
  1024
1194
2065
  end
1195
2066
  end
@@ -1290,14 +2161,9 @@ module Bundler::FileUtils
1290
2161
 
1291
2162
  def entries
1292
2163
  opts = {}
1293
- opts[:encoding] = ::Encoding::UTF_8 if fu_windows?
2164
+ opts[:encoding] = fu_windows? ? ::Encoding::UTF_8 : path.encoding
1294
2165
 
1295
- files = if Dir.respond_to?(:children)
1296
- Dir.children(path, **opts)
1297
- else
1298
- Dir.entries(path(), **opts)
1299
- .reject {|n| n == '.' or n == '..' }
1300
- end
2166
+ files = Dir.children(path, **opts)
1301
2167
 
1302
2168
  untaint = RUBY_VERSION < '2.7'
1303
2169
  files.map {|n| Entry_.new(prefix(), join(rel(), untaint ? n.untaint : n)) }
@@ -1345,6 +2211,7 @@ module Bundler::FileUtils
1345
2211
  else
1346
2212
  File.chmod mode, path()
1347
2213
  end
2214
+ rescue Errno::EOPNOTSUPP
1348
2215
  end
1349
2216
 
1350
2217
  def chown(uid, gid)
@@ -1439,7 +2306,7 @@ module Bundler::FileUtils
1439
2306
  if st.symlink?
1440
2307
  begin
1441
2308
  File.lchmod mode, path
1442
- rescue NotImplementedError
2309
+ rescue NotImplementedError, Errno::EOPNOTSUPP
1443
2310
  end
1444
2311
  else
1445
2312
  File.chmod mode, path
@@ -1498,13 +2365,21 @@ module Bundler::FileUtils
1498
2365
 
1499
2366
  def postorder_traverse
1500
2367
  if directory?
1501
- entries().each do |ent|
2368
+ begin
2369
+ children = entries()
2370
+ rescue Errno::EACCES
2371
+ # Failed to get the list of children.
2372
+ # Assuming there is no children, try to process the parent directory.
2373
+ yield self
2374
+ return
2375
+ end
2376
+
2377
+ children.each do |ent|
1502
2378
  ent.postorder_traverse do |e|
1503
2379
  yield e
1504
2380
  end
1505
2381
  end
1506
2382
  end
1507
- ensure
1508
2383
  yield self
1509
2384
  end
1510
2385
 
@@ -1559,7 +2434,15 @@ module Bundler::FileUtils
1559
2434
  def join(dir, base)
1560
2435
  return File.path(dir) if not base or base == '.'
1561
2436
  return File.path(base) if not dir or dir == '.'
1562
- File.join(dir, base)
2437
+ begin
2438
+ File.join(dir, base)
2439
+ rescue EncodingError
2440
+ if fu_windows?
2441
+ File.join(dir.encode(::Encoding::UTF_8), base.encode(::Encoding::UTF_8))
2442
+ else
2443
+ raise
2444
+ end
2445
+ end
1563
2446
  end
1564
2447
 
1565
2448
  if File::ALT_SEPARATOR
@@ -1590,15 +2473,15 @@ module Bundler::FileUtils
1590
2473
  end
1591
2474
  private_module_function :fu_each_src_dest
1592
2475
 
1593
- def fu_each_src_dest0(src, dest) #:nodoc:
2476
+ def fu_each_src_dest0(src, dest, target_directory = true) #:nodoc:
1594
2477
  if tmp = Array.try_convert(src)
1595
2478
  tmp.each do |s|
1596
2479
  s = File.path(s)
1597
- yield s, File.join(dest, File.basename(s))
2480
+ yield s, (target_directory ? File.join(dest, File.basename(s)) : dest)
1598
2481
  end
1599
2482
  else
1600
2483
  src = File.path(src)
1601
- if File.directory?(dest)
2484
+ if target_directory and File.directory?(dest)
1602
2485
  yield src, File.join(dest, File.basename(src))
1603
2486
  else
1604
2487
  yield src, File.path(dest)
@@ -1614,7 +2497,7 @@ module Bundler::FileUtils
1614
2497
 
1615
2498
  def fu_output_message(msg) #:nodoc:
1616
2499
  output = @fileutils_output if defined?(@fileutils_output)
1617
- output ||= $stderr
2500
+ output ||= $stdout
1618
2501
  if defined?(@fileutils_label)
1619
2502
  msg = @fileutils_label + msg
1620
2503
  end
@@ -1622,6 +2505,56 @@ module Bundler::FileUtils
1622
2505
  end
1623
2506
  private_module_function :fu_output_message
1624
2507
 
2508
+ def fu_split_path(path) #:nodoc:
2509
+ path = File.path(path)
2510
+ list = []
2511
+ until (parent, base = File.split(path); parent == path or parent == ".")
2512
+ list << base
2513
+ path = parent
2514
+ end
2515
+ list << path
2516
+ list.reverse!
2517
+ end
2518
+ private_module_function :fu_split_path
2519
+
2520
+ def fu_relative_components_from(target, base) #:nodoc:
2521
+ i = 0
2522
+ while target[i]&.== base[i]
2523
+ i += 1
2524
+ end
2525
+ Array.new(base.size-i, '..').concat(target[i..-1])
2526
+ end
2527
+ private_module_function :fu_relative_components_from
2528
+
2529
+ def fu_clean_components(*comp) #:nodoc:
2530
+ comp.shift while comp.first == "."
2531
+ return comp if comp.empty?
2532
+ clean = [comp.shift]
2533
+ path = File.join(*clean, "") # ending with File::SEPARATOR
2534
+ while c = comp.shift
2535
+ if c == ".." and clean.last != ".." and !(fu_have_symlink? && File.symlink?(path))
2536
+ clean.pop
2537
+ path.chomp!(%r((?<=\A|/)[^/]+/\z), "")
2538
+ else
2539
+ clean << c
2540
+ path << c << "/"
2541
+ end
2542
+ end
2543
+ clean
2544
+ end
2545
+ private_module_function :fu_clean_components
2546
+
2547
+ if fu_windows?
2548
+ def fu_starting_path?(path) #:nodoc:
2549
+ path&.start_with?(%r(\w:|/))
2550
+ end
2551
+ else
2552
+ def fu_starting_path?(path) #:nodoc:
2553
+ path&.start_with?("/")
2554
+ end
2555
+ end
2556
+ private_module_function :fu_starting_path?
2557
+
1625
2558
  # This hash table holds command options.
1626
2559
  OPT_TABLE = {} #:nodoc: internal use only
1627
2560
  (private_instance_methods & methods(false)).inject(OPT_TABLE) {|tbl, name|
@@ -1631,50 +2564,49 @@ module Bundler::FileUtils
1631
2564
 
1632
2565
  public
1633
2566
 
2567
+ # Returns an array of the string names of \Bundler::FileUtils methods
2568
+ # that accept one or more keyword arguments:
1634
2569
  #
1635
- # Returns an Array of names of high-level methods that accept any keyword
1636
- # arguments.
1637
- #
1638
- # p Bundler::FileUtils.commands #=> ["chmod", "cp", "cp_r", "install", ...]
2570
+ # Bundler::FileUtils.commands.sort.take(3) # => ["cd", "chdir", "chmod"]
1639
2571
  #
1640
2572
  def self.commands
1641
2573
  OPT_TABLE.keys
1642
2574
  end
1643
2575
 
2576
+ # Returns an array of the string keyword names:
1644
2577
  #
1645
- # Returns an Array of option names.
1646
- #
1647
- # p Bundler::FileUtils.options #=> ["noop", "force", "verbose", "preserve", "mode"]
2578
+ # Bundler::FileUtils.options.take(3) # => ["noop", "verbose", "force"]
1648
2579
  #
1649
2580
  def self.options
1650
2581
  OPT_TABLE.values.flatten.uniq.map {|sym| sym.to_s }
1651
2582
  end
1652
2583
 
2584
+ # Returns +true+ if method +mid+ accepts the given option +opt+, +false+ otherwise;
2585
+ # the arguments may be strings or symbols:
1653
2586
  #
1654
- # Returns true if the method +mid+ have an option +opt+.
1655
- #
1656
- # p Bundler::FileUtils.have_option?(:cp, :noop) #=> true
1657
- # p Bundler::FileUtils.have_option?(:rm, :force) #=> true
1658
- # p Bundler::FileUtils.have_option?(:rm, :preserve) #=> false
2587
+ # Bundler::FileUtils.have_option?(:chmod, :noop) # => true
2588
+ # Bundler::FileUtils.have_option?('chmod', 'secure') # => false
1659
2589
  #
1660
2590
  def self.have_option?(mid, opt)
1661
2591
  li = OPT_TABLE[mid.to_s] or raise ArgumentError, "no such method: #{mid}"
1662
2592
  li.include?(opt)
1663
2593
  end
1664
2594
 
2595
+ # Returns an array of the string keyword name for method +mid+;
2596
+ # the argument may be a string or a symbol:
1665
2597
  #
1666
- # Returns an Array of option names of the method +mid+.
1667
- #
1668
- # p Bundler::FileUtils.options_of(:rm) #=> ["noop", "verbose", "force"]
2598
+ # Bundler::FileUtils.options_of(:rm) # => ["force", "noop", "verbose"]
2599
+ # Bundler::FileUtils.options_of('mv') # => ["force", "noop", "verbose", "secure"]
1669
2600
  #
1670
2601
  def self.options_of(mid)
1671
2602
  OPT_TABLE[mid.to_s].map {|sym| sym.to_s }
1672
2603
  end
1673
2604
 
2605
+ # Returns an array of the string method names of the methods
2606
+ # that accept the given keyword option +opt+;
2607
+ # the argument must be a symbol:
1674
2608
  #
1675
- # Returns an Array of methods names which have the option +opt+.
1676
- #
1677
- # p Bundler::FileUtils.collect_method(:preserve) #=> ["cp", "cp_r", "copy", "install"]
2609
+ # Bundler::FileUtils.collect_method(:preserve) # => ["cp", "copy", "cp_r", "install"]
1678
2610
  #
1679
2611
  def self.collect_method(opt)
1680
2612
  OPT_TABLE.keys.select {|m| OPT_TABLE[m].include?(opt) }