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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +2182 -1067
- data/CODE_OF_CONDUCT.md +79 -28
- data/Manifest.txt +184 -290
- data/README.md +35 -19
- data/bundler/CHANGELOG.md +1003 -3
- data/bundler/README.md +3 -7
- data/bundler/bundler.gemspec +11 -11
- data/bundler/exe/bundle +5 -25
- data/bundler/lib/bundler/build_metadata.rb +3 -3
- data/bundler/lib/bundler/capistrano.rb +1 -1
- data/bundler/lib/bundler/checksum.rb +254 -0
- data/bundler/lib/bundler/ci_detector.rb +75 -0
- data/bundler/lib/bundler/cli/add.rb +7 -5
- data/bundler/lib/bundler/cli/binstubs.rb +10 -6
- data/bundler/lib/bundler/cli/cache.rb +1 -1
- data/bundler/lib/bundler/cli/check.rb +4 -4
- data/bundler/lib/bundler/cli/common.rb +11 -1
- data/bundler/lib/bundler/cli/config.rb +8 -7
- data/bundler/lib/bundler/cli/console.rb +2 -5
- data/bundler/lib/bundler/cli/doctor.rb +10 -12
- data/bundler/lib/bundler/cli/exec.rb +2 -1
- data/bundler/lib/bundler/cli/fund.rb +1 -1
- data/bundler/lib/bundler/cli/gem.rb +77 -53
- data/bundler/lib/bundler/cli/info.rb +4 -15
- data/bundler/lib/bundler/cli/init.rb +6 -2
- data/bundler/lib/bundler/cli/inject.rb +1 -1
- data/bundler/lib/bundler/cli/install.rb +27 -15
- data/bundler/lib/bundler/cli/issue.rb +1 -1
- data/bundler/lib/bundler/cli/lock.rb +54 -28
- data/bundler/lib/bundler/cli/open.rb +9 -9
- data/bundler/lib/bundler/cli/outdated.rb +34 -29
- data/bundler/lib/bundler/cli/platform.rb +7 -5
- data/bundler/lib/bundler/cli/plugin.rb +9 -15
- data/bundler/lib/bundler/cli/pristine.rb +38 -30
- data/bundler/lib/bundler/cli/show.rb +4 -4
- data/bundler/lib/bundler/cli/update.rb +6 -5
- data/bundler/lib/bundler/cli/viz.rb +1 -1
- data/bundler/lib/bundler/cli.rb +258 -307
- data/bundler/lib/bundler/compact_index_client/cache.rb +55 -60
- data/bundler/lib/bundler/compact_index_client/cache_file.rb +148 -0
- data/bundler/lib/bundler/compact_index_client/gem_parser.rb +7 -3
- data/bundler/lib/bundler/compact_index_client/parser.rb +84 -0
- data/bundler/lib/bundler/compact_index_client/updater.rb +71 -83
- data/bundler/lib/bundler/compact_index_client.rb +58 -80
- data/bundler/lib/bundler/constants.rb +9 -2
- data/bundler/lib/bundler/current_ruby.rb +11 -16
- data/bundler/lib/bundler/definition.rb +547 -228
- data/bundler/lib/bundler/dependency.rb +30 -87
- data/bundler/lib/bundler/digest.rb +3 -3
- data/bundler/lib/bundler/dsl.rb +115 -65
- data/bundler/lib/bundler/endpoint_specification.rb +27 -14
- data/bundler/lib/bundler/env.rb +5 -7
- data/bundler/lib/bundler/environment_preserver.rb +8 -25
- data/bundler/lib/bundler/errors.rb +85 -11
- data/bundler/lib/bundler/feature_flag.rb +1 -2
- data/bundler/lib/bundler/fetcher/base.rb +5 -3
- data/bundler/lib/bundler/fetcher/compact_index.rb +28 -43
- data/bundler/lib/bundler/fetcher/dependency.rb +3 -7
- data/bundler/lib/bundler/fetcher/downloader.rb +17 -16
- data/bundler/lib/bundler/fetcher/gem_remote_fetcher.rb +16 -0
- data/bundler/lib/bundler/fetcher/index.rb +2 -3
- data/bundler/lib/bundler/fetcher.rb +91 -74
- data/bundler/lib/bundler/force_platform.rb +16 -0
- data/bundler/lib/bundler/friendly_errors.rb +6 -9
- data/bundler/lib/bundler/gem_helper.rb +5 -6
- data/bundler/lib/bundler/gem_helpers.rb +45 -7
- data/bundler/lib/bundler/gem_version_promoter.rb +68 -109
- data/bundler/lib/bundler/graph.rb +9 -9
- data/bundler/lib/bundler/index.rb +69 -73
- data/bundler/lib/bundler/injector.rb +12 -13
- data/bundler/lib/bundler/inline.rb +40 -17
- data/bundler/lib/bundler/installer/gem_installer.rb +13 -12
- data/bundler/lib/bundler/installer/parallel_installer.rb +19 -66
- data/bundler/lib/bundler/installer/standalone.rb +29 -15
- data/bundler/lib/bundler/installer.rb +27 -77
- data/bundler/lib/bundler/lazy_specification.rb +134 -71
- data/bundler/lib/bundler/lockfile_generator.rb +13 -4
- data/bundler/lib/bundler/lockfile_parser.rb +134 -61
- data/bundler/lib/bundler/man/bundle-add.1 +46 -48
- data/bundler/lib/bundler/man/bundle-add.1.ronn +54 -22
- data/bundler/lib/bundler/man/bundle-binstubs.1 +10 -19
- data/bundler/lib/bundler/man/bundle-binstubs.1.ronn +6 -3
- data/bundler/lib/bundler/man/bundle-cache.1 +38 -25
- data/bundler/lib/bundler/man/bundle-cache.1.ronn +40 -4
- data/bundler/lib/bundler/man/bundle-check.1 +7 -14
- data/bundler/lib/bundler/man/bundle-check.1.ronn +7 -2
- data/bundler/lib/bundler/man/bundle-clean.1 +4 -11
- data/bundler/lib/bundler/man/bundle-clean.1.ronn +1 -1
- data/bundler/lib/bundler/man/bundle-config.1 +41 -220
- data/bundler/lib/bundler/man/bundle-config.1.ronn +27 -22
- data/bundler/lib/bundler/man/bundle-console.1 +33 -0
- data/bundler/lib/bundler/man/bundle-console.1.ronn +39 -0
- data/bundler/lib/bundler/man/bundle-doctor.1 +5 -19
- data/bundler/lib/bundler/man/bundle-doctor.1.ronn +1 -1
- data/bundler/lib/bundler/man/bundle-env.1 +9 -0
- data/bundler/lib/bundler/man/bundle-env.1.ronn +10 -0
- data/bundler/lib/bundler/man/bundle-exec.1 +20 -78
- data/bundler/lib/bundler/man/bundle-exec.1.ronn +12 -10
- data/bundler/lib/bundler/man/bundle-fund.1 +22 -0
- data/bundler/lib/bundler/man/bundle-fund.1.ronn +25 -0
- data/bundler/lib/bundler/man/bundle-gem.1 +53 -81
- data/bundler/lib/bundler/man/bundle-gem.1.ronn +41 -9
- data/bundler/lib/bundler/man/bundle-help.1 +9 -0
- data/bundler/lib/bundler/man/bundle-help.1.ronn +12 -0
- data/bundler/lib/bundler/man/bundle-info.1 +8 -11
- data/bundler/lib/bundler/man/bundle-info.1.ronn +9 -5
- data/bundler/lib/bundler/man/bundle-init.1 +7 -12
- data/bundler/lib/bundler/man/bundle-init.1.ronn +4 -1
- data/bundler/lib/bundler/man/bundle-inject.1 +17 -19
- data/bundler/lib/bundler/man/bundle-inject.1.ronn +12 -2
- data/bundler/lib/bundler/man/bundle-install.1 +42 -162
- data/bundler/lib/bundler/man/bundle-install.1.ronn +31 -49
- data/bundler/lib/bundler/man/bundle-issue.1 +45 -0
- data/bundler/lib/bundler/man/bundle-issue.1.ronn +37 -0
- data/bundler/lib/bundler/man/bundle-licenses.1 +9 -0
- data/bundler/lib/bundler/man/bundle-licenses.1.ronn +10 -0
- data/bundler/lib/bundler/man/bundle-list.1 +4 -19
- data/bundler/lib/bundler/man/bundle-list.1.ronn +4 -1
- data/bundler/lib/bundler/man/bundle-lock.1 +25 -34
- data/bundler/lib/bundler/man/bundle-lock.1.ronn +25 -4
- data/bundler/lib/bundler/man/bundle-open.1 +18 -18
- data/bundler/lib/bundler/man/bundle-open.1.ronn +10 -1
- data/bundler/lib/bundler/man/bundle-outdated.1 +22 -67
- data/bundler/lib/bundler/man/bundle-outdated.1.ronn +20 -12
- data/bundler/lib/bundler/man/bundle-platform.1 +16 -28
- data/bundler/lib/bundler/man/bundle-platform.1.ronn +14 -7
- data/bundler/lib/bundler/man/bundle-plugin.1 +58 -0
- data/bundler/lib/bundler/man/bundle-plugin.1.ronn +63 -0
- data/bundler/lib/bundler/man/bundle-pristine.1 +5 -16
- data/bundler/lib/bundler/man/bundle-pristine.1.ronn +1 -1
- data/bundler/lib/bundler/man/bundle-remove.1 +4 -14
- data/bundler/lib/bundler/man/bundle-remove.1.ronn +1 -1
- data/bundler/lib/bundler/man/bundle-show.1 +7 -11
- data/bundler/lib/bundler/man/bundle-show.1.ronn +4 -0
- data/bundler/lib/bundler/man/bundle-update.1 +30 -143
- data/bundler/lib/bundler/man/bundle-update.1.ronn +14 -6
- data/bundler/lib/bundler/man/bundle-version.1 +22 -0
- data/bundler/lib/bundler/man/bundle-version.1.ronn +24 -0
- data/bundler/lib/bundler/man/bundle-viz.1 +9 -18
- data/bundler/lib/bundler/man/bundle-viz.1.ronn +9 -3
- data/bundler/lib/bundler/man/bundle.1 +17 -51
- data/bundler/lib/bundler/man/bundle.1.ronn +12 -7
- data/bundler/lib/bundler/man/gemfile.5 +77 -341
- data/bundler/lib/bundler/man/gemfile.5.ronn +73 -54
- data/bundler/lib/bundler/man/index.txt +8 -0
- data/bundler/lib/bundler/match_metadata.rb +17 -0
- data/bundler/lib/bundler/match_platform.rb +1 -1
- data/bundler/lib/bundler/match_remote_metadata.rb +29 -0
- data/bundler/lib/bundler/materialization.rb +59 -0
- data/bundler/lib/bundler/mirror.rb +8 -10
- data/bundler/lib/bundler/plugin/api/source.rb +7 -5
- data/bundler/lib/bundler/plugin/events.rb +24 -0
- data/bundler/lib/bundler/plugin/index.rb +13 -5
- data/bundler/lib/bundler/plugin/installer/path.rb +18 -0
- data/bundler/lib/bundler/plugin/installer/rubygems.rb +0 -4
- data/bundler/lib/bundler/plugin/installer.rb +42 -19
- data/bundler/lib/bundler/plugin/source_list.rb +4 -4
- data/bundler/lib/bundler/plugin.rb +35 -7
- data/bundler/lib/bundler/process_lock.rb +10 -14
- data/bundler/lib/bundler/remote_specification.rb +17 -13
- data/bundler/lib/bundler/resolver/base.rb +117 -0
- data/bundler/lib/bundler/resolver/candidate.rb +82 -0
- data/bundler/lib/bundler/resolver/incompatibility.rb +15 -0
- data/bundler/lib/bundler/resolver/package.rb +90 -0
- data/bundler/lib/bundler/resolver/root.rb +25 -0
- data/bundler/lib/bundler/resolver/spec_group.rb +54 -67
- data/bundler/lib/bundler/resolver.rb +432 -329
- data/bundler/lib/bundler/retry.rb +2 -2
- data/bundler/lib/bundler/ruby_dsl.rb +42 -7
- data/bundler/lib/bundler/ruby_version.rb +23 -10
- data/bundler/lib/bundler/rubygems_ext.rb +286 -81
- data/bundler/lib/bundler/rubygems_gem_installer.rb +77 -68
- data/bundler/lib/bundler/rubygems_integration.rb +57 -155
- data/bundler/lib/bundler/runtime.rb +28 -17
- data/bundler/lib/bundler/safe_marshal.rb +31 -0
- data/bundler/lib/bundler/self_manager.rb +50 -12
- data/bundler/lib/bundler/settings.rb +144 -58
- data/bundler/lib/bundler/setup.rb +13 -1
- data/bundler/lib/bundler/shared_helpers.rb +87 -36
- data/bundler/lib/bundler/source/git/git_proxy.rb +278 -80
- data/bundler/lib/bundler/source/git.rb +161 -68
- data/bundler/lib/bundler/source/metadata.rb +16 -16
- data/bundler/lib/bundler/source/path/installer.rb +1 -22
- data/bundler/lib/bundler/source/path.rb +16 -26
- data/bundler/lib/bundler/source/rubygems/remote.rb +1 -1
- data/bundler/lib/bundler/source/rubygems.rb +94 -154
- data/bundler/lib/bundler/source.rb +3 -1
- data/bundler/lib/bundler/source_list.rb +34 -4
- data/bundler/lib/bundler/spec_set.rb +195 -65
- data/bundler/lib/bundler/stub_specification.rb +34 -4
- data/bundler/lib/bundler/templates/Executable +1 -1
- data/bundler/lib/bundler/templates/Executable.bundler +6 -11
- data/bundler/lib/bundler/templates/Executable.standalone +2 -0
- data/bundler/lib/bundler/templates/newgem/CODE_OF_CONDUCT.md.tt +77 -29
- data/bundler/lib/bundler/templates/newgem/Cargo.toml.tt +7 -0
- data/bundler/lib/bundler/templates/newgem/README.md.tt +11 -5
- data/bundler/lib/bundler/templates/newgem/Rakefile.tt +19 -8
- data/bundler/lib/bundler/templates/newgem/bin/console.tt +0 -4
- data/bundler/lib/bundler/templates/newgem/circleci/config.yml.tt +12 -0
- data/bundler/lib/bundler/templates/newgem/ext/newgem/Cargo.toml.tt +15 -0
- data/bundler/lib/bundler/templates/newgem/ext/newgem/extconf-c.rb.tt +10 -0
- data/bundler/lib/bundler/templates/newgem/ext/newgem/extconf-rust.rb.tt +6 -0
- data/bundler/lib/bundler/templates/newgem/ext/newgem/newgem.c.tt +1 -1
- data/bundler/lib/bundler/templates/newgem/ext/newgem/src/lib.rs.tt +12 -0
- data/bundler/lib/bundler/templates/newgem/github/workflows/main.yml.tt +18 -8
- data/bundler/lib/bundler/templates/newgem/gitignore.tt +3 -0
- data/bundler/lib/bundler/templates/newgem/gitlab-ci.yml.tt +13 -4
- data/bundler/lib/bundler/templates/newgem/newgem.gemspec.tt +12 -4
- data/bundler/lib/bundler/templates/newgem/rubocop.yml.tt +0 -5
- data/bundler/lib/bundler/templates/newgem/standard.yml.tt +1 -1
- data/bundler/lib/bundler/ui/rg_proxy.rb +1 -1
- data/bundler/lib/bundler/ui/shell.rb +60 -15
- data/bundler/lib/bundler/ui/silent.rb +33 -6
- data/bundler/lib/bundler/uri_credentials_filter.rb +3 -3
- data/bundler/lib/bundler/uri_normalizer.rb +23 -0
- data/bundler/lib/bundler/vendor/connection_pool/lib/connection_pool/timed_stack.rb +3 -3
- data/bundler/lib/bundler/vendor/connection_pool/lib/connection_pool/version.rb +1 -1
- data/bundler/lib/bundler/vendor/connection_pool/lib/connection_pool/wrapper.rb +0 -1
- data/bundler/lib/bundler/vendor/connection_pool/lib/connection_pool.rb +56 -7
- data/bundler/lib/bundler/vendor/fileutils/lib/fileutils.rb +1350 -418
- data/bundler/lib/bundler/vendor/net-http-persistent/.document +1 -0
- data/bundler/lib/bundler/vendor/net-http-persistent/README.rdoc +1 -1
- data/bundler/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent/connection.rb +4 -3
- data/bundler/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent/pool.rb +23 -11
- data/bundler/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent/timed_stack_multi.rb +1 -1
- data/bundler/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent.rb +102 -64
- data/bundler/lib/bundler/vendor/pub_grub/.document +1 -0
- data/bundler/lib/bundler/vendor/pub_grub/LICENSE.txt +21 -0
- data/bundler/lib/bundler/vendor/pub_grub/lib/pub_grub/assignment.rb +20 -0
- data/bundler/lib/bundler/vendor/pub_grub/lib/pub_grub/basic_package_source.rb +189 -0
- data/bundler/lib/bundler/vendor/pub_grub/lib/pub_grub/failure_writer.rb +182 -0
- data/bundler/lib/bundler/vendor/pub_grub/lib/pub_grub/incompatibility.rb +150 -0
- data/bundler/lib/bundler/vendor/pub_grub/lib/pub_grub/package.rb +43 -0
- data/bundler/lib/bundler/vendor/pub_grub/lib/pub_grub/partial_solution.rb +121 -0
- data/bundler/lib/bundler/vendor/pub_grub/lib/pub_grub/rubygems.rb +45 -0
- data/bundler/lib/bundler/vendor/pub_grub/lib/pub_grub/solve_failure.rb +19 -0
- data/bundler/lib/bundler/vendor/pub_grub/lib/pub_grub/static_package_source.rb +61 -0
- data/bundler/lib/bundler/vendor/pub_grub/lib/pub_grub/term.rb +105 -0
- data/bundler/lib/bundler/vendor/pub_grub/lib/pub_grub/version.rb +3 -0
- data/bundler/lib/bundler/vendor/pub_grub/lib/pub_grub/version_constraint.rb +129 -0
- data/bundler/lib/bundler/vendor/pub_grub/lib/pub_grub/version_range.rb +411 -0
- data/bundler/lib/bundler/vendor/pub_grub/lib/pub_grub/version_solver.rb +248 -0
- data/bundler/lib/bundler/vendor/pub_grub/lib/pub_grub/version_union.rb +178 -0
- data/bundler/lib/bundler/vendor/pub_grub/lib/pub_grub.rb +31 -0
- data/bundler/lib/bundler/vendor/securerandom/.document +1 -0
- data/bundler/lib/bundler/vendor/securerandom/COPYING +56 -0
- data/bundler/lib/bundler/vendor/securerandom/lib/securerandom.rb +102 -0
- data/bundler/lib/bundler/vendor/thor/.document +1 -0
- data/bundler/lib/bundler/vendor/thor/lib/thor/actions/create_file.rb +3 -2
- data/bundler/lib/bundler/vendor/thor/lib/thor/actions/directory.rb +1 -1
- data/bundler/lib/bundler/vendor/thor/lib/thor/actions/empty_directory.rb +1 -1
- data/bundler/lib/bundler/vendor/thor/lib/thor/actions/file_manipulation.rb +11 -15
- data/bundler/lib/bundler/vendor/thor/lib/thor/actions/inject_into_file.rb +15 -4
- data/bundler/lib/bundler/vendor/thor/lib/thor/actions.rb +15 -15
- data/bundler/lib/bundler/vendor/thor/lib/thor/base.rb +140 -14
- data/bundler/lib/bundler/vendor/thor/lib/thor/command.rb +13 -4
- data/bundler/lib/bundler/vendor/thor/lib/thor/core_ext/hash_with_indifferent_access.rb +4 -0
- data/bundler/lib/bundler/vendor/thor/lib/thor/error.rb +16 -25
- data/bundler/lib/bundler/vendor/thor/lib/thor/group.rb +12 -1
- data/bundler/lib/bundler/vendor/thor/lib/thor/invocation.rb +1 -1
- data/bundler/lib/bundler/vendor/thor/lib/thor/nested_context.rb +2 -2
- data/bundler/lib/bundler/vendor/thor/lib/thor/parser/argument.rb +17 -1
- data/bundler/lib/bundler/vendor/thor/lib/thor/parser/arguments.rb +33 -17
- data/bundler/lib/bundler/vendor/thor/lib/thor/parser/option.rb +28 -9
- data/bundler/lib/bundler/vendor/thor/lib/thor/parser/options.rb +46 -7
- data/bundler/lib/bundler/vendor/thor/lib/thor/rake_compat.rb +2 -2
- data/bundler/lib/bundler/vendor/thor/lib/thor/runner.rb +40 -30
- data/bundler/lib/bundler/vendor/thor/lib/thor/shell/basic.rb +35 -159
- data/bundler/lib/bundler/vendor/thor/lib/thor/shell/color.rb +1 -46
- data/bundler/lib/bundler/vendor/thor/lib/thor/shell/column_printer.rb +29 -0
- data/bundler/lib/bundler/vendor/thor/lib/thor/shell/html.rb +1 -46
- data/bundler/lib/bundler/vendor/thor/lib/thor/shell/table_printer.rb +118 -0
- data/bundler/lib/bundler/vendor/thor/lib/thor/shell/terminal.rb +42 -0
- data/bundler/lib/bundler/vendor/thor/lib/thor/shell/wrapped_printer.rb +38 -0
- data/bundler/lib/bundler/vendor/thor/lib/thor/shell.rb +1 -1
- data/bundler/lib/bundler/vendor/thor/lib/thor/util.rb +8 -7
- data/bundler/lib/bundler/vendor/thor/lib/thor/version.rb +1 -1
- data/bundler/lib/bundler/vendor/thor/lib/thor.rb +166 -8
- data/bundler/lib/bundler/vendor/tsort/.document +1 -0
- data/bundler/lib/bundler/vendor/tsort/lib/tsort.rb +3 -0
- data/bundler/lib/bundler/vendor/uri/.document +1 -0
- data/bundler/lib/bundler/vendor/uri/COPYING +56 -0
- data/bundler/lib/bundler/vendor/uri/lib/uri/common.rb +343 -148
- data/bundler/lib/bundler/vendor/uri/lib/uri/file.rb +10 -4
- data/bundler/lib/bundler/vendor/uri/lib/uri/ftp.rb +3 -2
- data/bundler/lib/bundler/vendor/uri/lib/uri/generic.rb +44 -33
- data/bundler/lib/bundler/vendor/uri/lib/uri/http.rb +40 -2
- data/bundler/lib/bundler/vendor/uri/lib/uri/https.rb +2 -1
- data/bundler/lib/bundler/vendor/uri/lib/uri/ldap.rb +1 -1
- data/bundler/lib/bundler/vendor/uri/lib/uri/ldaps.rb +2 -1
- data/bundler/lib/bundler/vendor/uri/lib/uri/mailto.rb +2 -2
- data/bundler/lib/bundler/vendor/uri/lib/uri/rfc2396_parser.rb +25 -12
- data/bundler/lib/bundler/vendor/uri/lib/uri/rfc3986_parser.rb +130 -38
- data/bundler/lib/bundler/vendor/uri/lib/uri/version.rb +1 -1
- data/bundler/lib/bundler/vendor/uri/lib/uri/ws.rb +1 -2
- data/bundler/lib/bundler/vendor/uri/lib/uri/wss.rb +2 -1
- data/bundler/lib/bundler/vendor/uri/lib/uri.rb +12 -11
- data/bundler/lib/bundler/vendored_net_http.rb +23 -0
- data/bundler/lib/bundler/vendored_persistent.rb +0 -36
- data/bundler/lib/bundler/{vendored_tmpdir.rb → vendored_pub_grub.rb} +1 -1
- data/bundler/lib/bundler/vendored_securerandom.rb +12 -0
- data/bundler/lib/bundler/vendored_timeout.rb +12 -0
- data/bundler/lib/bundler/vendored_uri.rb +18 -1
- data/bundler/lib/bundler/version.rb +5 -1
- data/bundler/lib/bundler/vlad.rb +1 -1
- data/bundler/lib/bundler/worker.rb +5 -7
- data/bundler/lib/bundler/yaml_serializer.rb +22 -13
- data/bundler/lib/bundler.rb +155 -148
- data/{bundler → doc/bundler}/UPGRADING.md +11 -4
- data/{CONTRIBUTING.md → doc/rubygems/CONTRIBUTING.md} +40 -17
- data/doc/rubygems/POLICIES.md +204 -0
- data/{test/rubygems/fake_certlib/openssl.rb → exe/gem} +5 -1
- data/{bin → exe}/update_rubygems +12 -10
- data/lib/rubygems/available_set.rb +8 -7
- data/lib/rubygems/basic_specification.rb +90 -52
- data/lib/rubygems/bundler_version_finder.rb +6 -6
- data/lib/rubygems/ci_detector.rb +75 -0
- data/lib/rubygems/command.rb +68 -64
- data/lib/rubygems/command_manager.rb +39 -24
- data/lib/rubygems/commands/build_command.rb +14 -19
- data/lib/rubygems/commands/cert_command.rb +39 -39
- data/lib/rubygems/commands/check_command.rb +30 -25
- data/lib/rubygems/commands/cleanup_command.rb +32 -43
- data/lib/rubygems/commands/contents_command.rb +33 -25
- data/lib/rubygems/commands/dependency_command.rb +22 -23
- data/lib/rubygems/commands/environment_command.rb +8 -9
- data/lib/rubygems/commands/exec_command.rb +247 -0
- data/lib/rubygems/commands/fetch_command.rb +25 -10
- data/lib/rubygems/commands/generate_index_command.rb +40 -74
- data/lib/rubygems/commands/help_command.rb +15 -14
- data/lib/rubygems/commands/info_command.rb +5 -5
- data/lib/rubygems/commands/install_command.rb +31 -38
- data/lib/rubygems/commands/list_command.rb +6 -5
- data/lib/rubygems/commands/lock_command.rb +6 -5
- data/lib/rubygems/commands/mirror_command.rb +4 -3
- data/lib/rubygems/commands/open_command.rb +11 -12
- data/lib/rubygems/commands/outdated_command.rb +6 -5
- data/lib/rubygems/commands/owner_command.rb +23 -22
- data/lib/rubygems/commands/pristine_command.rb +83 -62
- data/lib/rubygems/commands/push_command.rb +38 -13
- data/lib/rubygems/commands/query_command.rb +11 -11
- data/lib/rubygems/commands/rdoc_command.rb +23 -28
- data/lib/rubygems/commands/rebuild_command.rb +262 -0
- data/lib/rubygems/commands/search_command.rb +6 -5
- data/lib/rubygems/commands/server_command.rb +4 -3
- data/lib/rubygems/commands/setup_command.rb +137 -154
- data/lib/rubygems/commands/signin_command.rb +10 -9
- data/lib/rubygems/commands/signout_command.rb +8 -7
- data/lib/rubygems/commands/sources_command.rb +34 -33
- data/lib/rubygems/commands/specification_command.rb +25 -20
- data/lib/rubygems/commands/stale_command.rb +5 -4
- data/lib/rubygems/commands/uninstall_command.rb +66 -59
- data/lib/rubygems/commands/unpack_command.rb +23 -30
- data/lib/rubygems/commands/update_command.rb +62 -94
- data/lib/rubygems/commands/which_command.rb +9 -8
- data/lib/rubygems/commands/yank_command.rb +14 -13
- data/lib/rubygems/compatibility.rb +5 -6
- data/lib/rubygems/config_file.rb +160 -50
- data/lib/rubygems/core_ext/kernel_gem.rb +3 -10
- data/lib/rubygems/core_ext/kernel_require.rb +88 -114
- data/lib/rubygems/core_ext/kernel_warn.rb +30 -39
- data/lib/rubygems/core_ext/tcpsocket_init.rb +4 -2
- data/lib/rubygems/defaults.rb +53 -22
- data/lib/rubygems/dependency.rb +34 -36
- data/lib/rubygems/dependency_installer.rb +52 -56
- data/lib/rubygems/dependency_list.rb +8 -7
- data/lib/rubygems/deprecate.rb +80 -75
- data/lib/rubygems/doctor.rb +23 -22
- data/lib/rubygems/errors.rb +6 -8
- data/lib/rubygems/exceptions.rb +20 -18
- data/lib/rubygems/ext/build_error.rb +2 -1
- data/lib/rubygems/ext/builder.rb +56 -32
- data/lib/rubygems/ext/cargo_builder/link_flag_converter.rb +9 -5
- data/lib/rubygems/ext/cargo_builder.rb +158 -131
- data/lib/rubygems/ext/cmake_builder.rb +9 -4
- data/lib/rubygems/ext/configure_builder.rb +9 -3
- data/lib/rubygems/ext/ext_conf_builder.rb +19 -15
- data/lib/rubygems/ext/rake_builder.rb +14 -7
- data/lib/rubygems/ext.rb +8 -7
- data/lib/rubygems/gem_runner.rb +23 -9
- data/lib/rubygems/gemcutter_utilities/webauthn_listener/response.rb +163 -0
- data/lib/rubygems/gemcutter_utilities/webauthn_listener.rb +105 -0
- data/lib/rubygems/gemcutter_utilities/webauthn_poller.rb +80 -0
- data/lib/rubygems/gemcutter_utilities.rb +141 -63
- data/lib/rubygems/gemspec_helpers.rb +19 -0
- data/lib/rubygems/install_default_message.rb +3 -2
- data/lib/rubygems/install_message.rb +3 -2
- data/lib/rubygems/install_update_options.rb +72 -67
- data/lib/rubygems/installer.rb +148 -130
- data/lib/rubygems/installer_uninstaller_utils.rb +2 -4
- data/lib/rubygems/local_remote_options.rb +24 -28
- data/lib/rubygems/name_tuple.rb +10 -11
- data/lib/rubygems/package/digest_io.rb +2 -1
- data/lib/rubygems/package/file_source.rb +3 -2
- data/lib/rubygems/package/io_source.rb +1 -0
- data/lib/rubygems/package/old.rb +11 -10
- data/lib/rubygems/package/source.rb +1 -0
- data/lib/rubygems/package/tar_header.rb +125 -91
- data/lib/rubygems/package/tar_reader/entry.rb +106 -29
- data/lib/rubygems/package/tar_reader.rb +16 -39
- data/lib/rubygems/package/tar_writer.rb +29 -26
- data/lib/rubygems/package.rb +122 -84
- data/lib/rubygems/package_task.rb +7 -6
- data/lib/rubygems/path_support.rb +11 -11
- data/lib/rubygems/platform.rb +119 -70
- data/lib/rubygems/psych_tree.rb +6 -1
- data/lib/rubygems/query_utils.rb +46 -48
- data/lib/rubygems/rdoc.rb +13 -3
- data/lib/rubygems/remote_fetcher.rb +47 -39
- data/lib/rubygems/request/connection_pools.rb +6 -6
- data/lib/rubygems/request/http_pool.rb +2 -1
- data/lib/rubygems/request/https_pool.rb +1 -0
- data/lib/rubygems/request.rb +48 -44
- data/lib/rubygems/request_set/gem_dependency_api.rb +141 -144
- data/lib/rubygems/request_set/lockfile/parser.rb +31 -30
- data/lib/rubygems/request_set/lockfile/tokenizer.rb +24 -14
- data/lib/rubygems/request_set/lockfile.rb +11 -15
- data/lib/rubygems/request_set.rb +25 -23
- data/lib/rubygems/requirement.rb +30 -27
- data/lib/rubygems/resolver/activation_request.rb +7 -10
- data/lib/rubygems/resolver/api_set/gem_parser.rb +7 -3
- data/lib/rubygems/resolver/api_set.rb +20 -13
- data/lib/rubygems/resolver/api_specification.rb +8 -7
- data/lib/rubygems/resolver/best_set.rb +5 -32
- data/lib/rubygems/resolver/composed_set.rb +4 -3
- data/lib/rubygems/resolver/conflict.rb +14 -21
- data/lib/rubygems/resolver/current_set.rb +1 -0
- data/lib/rubygems/resolver/dependency_request.rb +3 -2
- data/lib/rubygems/resolver/git_set.rb +2 -2
- data/lib/rubygems/resolver/git_specification.rb +7 -6
- data/lib/rubygems/resolver/index_set.rb +10 -9
- data/lib/rubygems/resolver/index_specification.rb +8 -6
- data/lib/rubygems/resolver/installed_specification.rb +6 -5
- data/lib/rubygems/resolver/installer_set.rb +19 -22
- data/lib/rubygems/resolver/local_specification.rb +4 -3
- data/lib/rubygems/resolver/lock_set.rb +6 -5
- data/lib/rubygems/resolver/lock_specification.rb +5 -4
- data/lib/rubygems/resolver/requirement_list.rb +1 -0
- data/lib/rubygems/resolver/set.rb +1 -0
- data/lib/rubygems/resolver/source_set.rb +2 -0
- data/lib/rubygems/resolver/spec_specification.rb +8 -0
- data/lib/rubygems/resolver/specification.rb +2 -1
- data/lib/rubygems/resolver/stats.rb +2 -1
- data/lib/rubygems/resolver/vendor_set.rb +2 -1
- data/lib/rubygems/resolver/vendor_specification.rb +4 -3
- data/lib/rubygems/resolver.rb +51 -57
- data/lib/rubygems/s3_uri_signer.rb +18 -16
- data/lib/rubygems/safe_marshal/elements.rb +146 -0
- data/lib/rubygems/safe_marshal/reader.rb +325 -0
- data/lib/rubygems/safe_marshal/visitors/stream_printer.rb +31 -0
- data/lib/rubygems/safe_marshal/visitors/to_ruby.rb +428 -0
- data/lib/rubygems/safe_marshal/visitors/visitor.rb +74 -0
- data/lib/rubygems/safe_marshal.rb +74 -0
- data/lib/rubygems/safe_yaml.rb +14 -26
- data/lib/rubygems/security/policies.rb +48 -49
- data/lib/rubygems/security/policy.rb +25 -28
- data/lib/rubygems/security/signer.rb +16 -7
- data/lib/rubygems/security/trust_dir.rb +12 -13
- data/lib/rubygems/security.rb +40 -66
- data/lib/rubygems/security_option.rb +7 -6
- data/lib/rubygems/shellwords.rb +3 -0
- data/lib/rubygems/source/git.rb +34 -31
- data/lib/rubygems/source/installed.rb +4 -3
- data/lib/rubygems/source/local.rb +49 -49
- data/lib/rubygems/source/lock.rb +2 -3
- data/lib/rubygems/source/specific_file.rb +6 -4
- data/lib/rubygems/source/vendor.rb +1 -2
- data/lib/rubygems/source.rb +37 -31
- data/lib/rubygems/source_list.rb +8 -8
- data/lib/rubygems/spec_fetcher.rb +95 -66
- data/lib/rubygems/specification.rb +342 -404
- data/lib/rubygems/specification_policy.rb +147 -75
- data/lib/rubygems/specification_record.rb +212 -0
- data/lib/rubygems/stub_specification.rb +56 -30
- data/lib/rubygems/target_rbconfig.rb +50 -0
- data/lib/rubygems/text.rb +3 -4
- data/lib/rubygems/uninstaller.rb +67 -48
- data/lib/rubygems/update_suggestion.rb +56 -0
- data/lib/rubygems/uri.rb +10 -10
- data/lib/rubygems/uri_formatter.rb +2 -2
- data/lib/rubygems/user_interaction.rb +50 -40
- data/lib/rubygems/util/licenses.rb +310 -39
- data/lib/rubygems/util/list.rb +4 -1
- data/lib/rubygems/util.rb +19 -20
- data/lib/rubygems/validator.rb +15 -14
- data/lib/rubygems/vendor/molinillo/.document +1 -0
- data/lib/rubygems/vendor/molinillo/lib/molinillo/delegates/resolution_state.rb +57 -0
- data/{bundler/lib/bundler → lib/rubygems}/vendor/molinillo/lib/molinillo/delegates/specification_provider.rb +11 -11
- data/{bundler/lib/bundler → lib/rubygems}/vendor/molinillo/lib/molinillo/dependency_graph/action.rb +1 -1
- data/{bundler/lib/bundler → lib/rubygems}/vendor/molinillo/lib/molinillo/dependency_graph/add_edge_no_circular.rb +1 -1
- data/{bundler/lib/bundler → lib/rubygems}/vendor/molinillo/lib/molinillo/dependency_graph/add_vertex.rb +1 -1
- data/{bundler/lib/bundler → lib/rubygems}/vendor/molinillo/lib/molinillo/dependency_graph/delete_edge.rb +1 -1
- data/{bundler/lib/bundler → lib/rubygems}/vendor/molinillo/lib/molinillo/dependency_graph/detach_vertex_named.rb +1 -1
- data/{bundler/lib/bundler → lib/rubygems}/vendor/molinillo/lib/molinillo/dependency_graph/log.rb +1 -1
- data/{bundler/lib/bundler → lib/rubygems}/vendor/molinillo/lib/molinillo/dependency_graph/set_payload.rb +1 -1
- data/{bundler/lib/bundler → lib/rubygems}/vendor/molinillo/lib/molinillo/dependency_graph/tag.rb +1 -1
- data/{bundler/lib/bundler → lib/rubygems}/vendor/molinillo/lib/molinillo/dependency_graph/vertex.rb +1 -1
- data/{bundler/lib/bundler → lib/rubygems}/vendor/molinillo/lib/molinillo/dependency_graph.rb +3 -3
- data/{bundler/lib/bundler → lib/rubygems}/vendor/molinillo/lib/molinillo/errors.rb +1 -1
- data/lib/rubygems/vendor/molinillo/lib/molinillo/gem_metadata.rb +6 -0
- data/{bundler/lib/bundler → lib/rubygems}/vendor/molinillo/lib/molinillo/modules/specification_provider.rb +2 -2
- data/{bundler/lib/bundler → lib/rubygems}/vendor/molinillo/lib/molinillo/modules/ui.rb +1 -1
- data/{bundler/lib/bundler → lib/rubygems}/vendor/molinillo/lib/molinillo/resolution.rb +4 -4
- data/{bundler/lib/bundler → lib/rubygems}/vendor/molinillo/lib/molinillo/resolver.rb +1 -1
- data/{bundler/lib/bundler → lib/rubygems}/vendor/molinillo/lib/molinillo/state.rb +1 -1
- data/{bundler/lib/bundler → lib/rubygems}/vendor/molinillo/lib/molinillo.rb +2 -2
- data/lib/rubygems/vendor/net-http/.document +1 -0
- data/lib/rubygems/vendor/net-http/COPYING +56 -0
- data/lib/rubygems/vendor/net-http/lib/net/http/exceptions.rb +34 -0
- data/lib/rubygems/vendor/net-http/lib/net/http/generic_request.rb +414 -0
- data/lib/rubygems/vendor/net-http/lib/net/http/header.rb +981 -0
- data/lib/rubygems/vendor/net-http/lib/net/http/proxy_delta.rb +17 -0
- data/lib/rubygems/vendor/net-http/lib/net/http/request.rb +88 -0
- data/lib/rubygems/vendor/net-http/lib/net/http/requests.rb +430 -0
- data/lib/rubygems/vendor/net-http/lib/net/http/response.rb +738 -0
- data/lib/rubygems/vendor/net-http/lib/net/http/responses.rb +1174 -0
- data/lib/rubygems/vendor/net-http/lib/net/http/status.rb +84 -0
- data/lib/rubygems/vendor/net-http/lib/net/http.rb +2580 -0
- data/lib/rubygems/vendor/net-http/lib/net/https.rb +23 -0
- data/lib/rubygems/vendor/net-protocol/.document +1 -0
- data/lib/rubygems/vendor/net-protocol/lib/net/protocol.rb +544 -0
- data/lib/rubygems/vendor/optparse/.document +1 -0
- data/lib/rubygems/vendor/optparse/COPYING +56 -0
- data/lib/rubygems/{optparse → vendor/optparse}/lib/optparse/ac.rb +16 -0
- data/lib/rubygems/{optparse → vendor/optparse}/lib/optparse/kwargs.rb +8 -3
- data/lib/rubygems/vendor/optparse/lib/optparse/uri.rb +7 -0
- data/lib/rubygems/{optparse → vendor/optparse}/lib/optparse/version.rb +9 -0
- data/lib/rubygems/{optparse → vendor/optparse}/lib/optparse.rb +206 -83
- data/lib/rubygems/vendor/resolv/.document +1 -0
- data/lib/rubygems/vendor/resolv/COPYING +56 -0
- data/lib/rubygems/vendor/resolv/lib/resolv.rb +3455 -0
- data/lib/rubygems/vendor/securerandom/.document +1 -0
- data/lib/rubygems/vendor/securerandom/COPYING +56 -0
- data/lib/rubygems/vendor/securerandom/lib/securerandom.rb +102 -0
- data/lib/rubygems/vendor/timeout/.document +1 -0
- data/lib/rubygems/vendor/timeout/COPYING +56 -0
- data/lib/rubygems/vendor/timeout/lib/timeout.rb +198 -0
- data/lib/rubygems/vendor/tsort/.document +1 -0
- data/lib/rubygems/vendor/tsort/lib/tsort.rb +455 -0
- data/lib/rubygems/vendor/uri/.document +1 -0
- data/lib/rubygems/vendor/uri/COPYING +56 -0
- data/lib/rubygems/vendor/uri/lib/uri/common.rb +876 -0
- data/lib/rubygems/vendor/uri/lib/uri/file.rb +100 -0
- data/lib/rubygems/vendor/uri/lib/uri/ftp.rb +267 -0
- data/lib/rubygems/vendor/uri/lib/uri/generic.rb +1578 -0
- data/lib/rubygems/vendor/uri/lib/uri/http.rb +125 -0
- data/lib/rubygems/vendor/uri/lib/uri/https.rb +23 -0
- data/lib/rubygems/vendor/uri/lib/uri/ldap.rb +261 -0
- data/lib/rubygems/vendor/uri/lib/uri/ldaps.rb +22 -0
- data/lib/rubygems/vendor/uri/lib/uri/mailto.rb +293 -0
- data/lib/rubygems/vendor/uri/lib/uri/rfc2396_parser.rb +546 -0
- data/lib/rubygems/vendor/uri/lib/uri/rfc3986_parser.rb +206 -0
- data/lib/rubygems/vendor/uri/lib/uri/version.rb +6 -0
- data/lib/rubygems/vendor/uri/lib/uri/ws.rb +83 -0
- data/lib/rubygems/vendor/uri/lib/uri/wss.rb +23 -0
- data/lib/rubygems/vendor/uri/lib/uri.rb +104 -0
- data/{bundler/lib/bundler → lib/rubygems}/vendored_molinillo.rb +0 -1
- data/lib/rubygems/vendored_net_http.rb +5 -0
- data/lib/rubygems/vendored_optparse.rb +3 -0
- data/lib/rubygems/vendored_securerandom.rb +3 -0
- data/lib/rubygems/vendored_timeout.rb +5 -0
- data/lib/rubygems/vendored_tsort.rb +3 -0
- data/lib/rubygems/version.rb +57 -45
- data/lib/rubygems/version_option.rb +6 -8
- data/lib/rubygems/yaml_serializer.rb +98 -0
- data/lib/rubygems.rb +191 -133
- data/rubygems-update.gemspec +16 -9
- data/setup.rb +12 -9
- metadata +233 -307
- data/POLICIES.md +0 -100
- data/bin/gem +0 -13
- data/bundler/lib/bundler/dep_proxy.rb +0 -55
- data/bundler/lib/bundler/templates/gems.rb +0 -5
- data/bundler/lib/bundler/templates/newgem/ext/newgem/extconf.rb.tt +0 -5
- data/bundler/lib/bundler/templates/newgem/travis.yml.tt +0 -6
- data/bundler/lib/bundler/vendor/molinillo/lib/molinillo/delegates/resolution_state.rb +0 -57
- data/bundler/lib/bundler/vendor/molinillo/lib/molinillo/gem_metadata.rb +0 -6
- data/bundler/lib/bundler/vendor/tmpdir/lib/tmpdir.rb +0 -154
- data/bundler/lib/bundler/version_ranges.rb +0 -122
- data/lib/rubygems/indexer.rb +0 -427
- data/lib/rubygems/mock_gem_ui.rb +0 -85
- data/lib/rubygems/optparse/lib/optparse/uri.rb +0 -7
- data/lib/rubygems/optparse.rb +0 -3
- data/lib/rubygems/resolver/molinillo/LICENSE +0 -9
- data/lib/rubygems/resolver/molinillo/lib/molinillo/delegates/resolution_state.rb +0 -57
- data/lib/rubygems/resolver/molinillo/lib/molinillo/delegates/specification_provider.rb +0 -88
- data/lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph/action.rb +0 -36
- data/lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph/add_edge_no_circular.rb +0 -66
- data/lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph/add_vertex.rb +0 -62
- data/lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph/delete_edge.rb +0 -63
- data/lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph/detach_vertex_named.rb +0 -61
- data/lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph/log.rb +0 -126
- data/lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph/set_payload.rb +0 -46
- data/lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph/tag.rb +0 -36
- data/lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph/vertex.rb +0 -164
- data/lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph.rb +0 -255
- data/lib/rubygems/resolver/molinillo/lib/molinillo/errors.rb +0 -143
- data/lib/rubygems/resolver/molinillo/lib/molinillo/gem_metadata.rb +0 -6
- data/lib/rubygems/resolver/molinillo/lib/molinillo/modules/specification_provider.rb +0 -112
- data/lib/rubygems/resolver/molinillo/lib/molinillo/modules/ui.rb +0 -67
- data/lib/rubygems/resolver/molinillo/lib/molinillo/resolution.rb +0 -839
- data/lib/rubygems/resolver/molinillo/lib/molinillo/resolver.rb +0 -46
- data/lib/rubygems/resolver/molinillo/lib/molinillo/state.rb +0 -58
- data/lib/rubygems/resolver/molinillo/lib/molinillo.rb +0 -11
- data/lib/rubygems/resolver/molinillo.rb +0 -2
- data/lib/rubygems/tsort/LICENSE.txt +0 -22
- data/lib/rubygems/tsort/lib/tsort.rb +0 -454
- data/lib/rubygems/tsort.rb +0 -3
- data/test/rubygems/alternate_cert.pem +0 -19
- data/test/rubygems/alternate_cert_32.pem +0 -19
- data/test/rubygems/alternate_key.pem +0 -27
- data/test/rubygems/bad_rake.rb +0 -2
- data/test/rubygems/ca_cert.pem +0 -77
- data/test/rubygems/child_cert.pem +0 -20
- data/test/rubygems/child_cert_32.pem +0 -20
- data/test/rubygems/child_key.pem +0 -27
- data/test/rubygems/client.pem +0 -107
- data/test/rubygems/data/excon-0.7.7.gemspec.rz +0 -0
- data/test/rubygems/data/gem-private_key.pem +0 -27
- data/test/rubygems/data/gem-public_cert.pem +0 -20
- data/test/rubygems/data/null-required-ruby-version.gemspec.rz +0 -0
- data/test/rubygems/data/null-required-rubygems-version.gemspec.rz +0 -0
- data/test/rubygems/data/pry-0.4.7.gemspec.rz +0 -0
- data/test/rubygems/encrypted_private_key.pem +0 -30
- data/test/rubygems/expired_cert.pem +0 -19
- data/test/rubygems/foo/discover.rb +0 -1
- data/test/rubygems/future_cert.pem +0 -19
- data/test/rubygems/future_cert_32.pem +0 -19
- data/test/rubygems/good_rake.rb +0 -2
- data/test/rubygems/grandchild_cert.pem +0 -20
- data/test/rubygems/grandchild_cert_32.pem +0 -20
- data/test/rubygems/grandchild_key.pem +0 -27
- data/test/rubygems/helper.rb +0 -1622
- data/test/rubygems/installer_test_case.rb +0 -247
- data/test/rubygems/invalid_client.pem +0 -49
- data/test/rubygems/invalid_issuer_cert.pem +0 -20
- data/test/rubygems/invalid_issuer_cert_32.pem +0 -20
- data/test/rubygems/invalid_key.pem +0 -27
- data/test/rubygems/invalid_signer_cert.pem +0 -19
- data/test/rubygems/invalid_signer_cert_32.pem +0 -19
- data/test/rubygems/invalidchild_cert.pem +0 -20
- data/test/rubygems/invalidchild_cert_32.pem +0 -20
- data/test/rubygems/invalidchild_key.pem +0 -27
- data/test/rubygems/package/tar_test_case.rb +0 -139
- data/test/rubygems/packages/ascii_binder-0.1.10.1.gem +0 -0
- data/test/rubygems/packages/ill-formatted-platform-1.0.0.10.gem +0 -0
- data/test/rubygems/plugin/exception/rubygems_plugin.rb +0 -3
- data/test/rubygems/plugin/load/rubygems_plugin.rb +0 -4
- data/test/rubygems/plugin/standarderror/rubygems_plugin.rb +0 -3
- data/test/rubygems/private3072_key.pem +0 -40
- data/test/rubygems/private_ec_key.pem +0 -9
- data/test/rubygems/private_key.pem +0 -27
- data/test/rubygems/public3072_cert.pem +0 -25
- data/test/rubygems/public_cert.pem +0 -20
- data/test/rubygems/public_cert_32.pem +0 -19
- data/test/rubygems/public_key.pem +0 -9
- data/test/rubygems/rubygems/commands/crash_command.rb +0 -4
- data/test/rubygems/rubygems_plugin.rb +0 -23
- data/test/rubygems/sff/discover.rb +0 -1
- data/test/rubygems/simple_gem.rb +0 -67
- data/test/rubygems/specifications/bar-0.0.2.gemspec +0 -7
- data/test/rubygems/specifications/foo-0.0.1-x86-mswin32.gemspec +0 -0
- data/test/rubygems/specifications/rubyforge-0.0.1.gemspec +0 -12
- data/test/rubygems/ssl_cert.pem +0 -80
- data/test/rubygems/ssl_key.pem +0 -27
- data/test/rubygems/test_bundled_ca.rb +0 -60
- data/test/rubygems/test_config.rb +0 -27
- data/test/rubygems/test_deprecate.rb +0 -157
- data/test/rubygems/test_exit.rb +0 -11
- data/test/rubygems/test_gem.rb +0 -2112
- data/test/rubygems/test_gem_available_set.rb +0 -129
- data/test/rubygems/test_gem_bundler_version_finder.rb +0 -125
- data/test/rubygems/test_gem_command.rb +0 -400
- data/test/rubygems/test_gem_command_manager.rb +0 -334
- data/test/rubygems/test_gem_commands_build_command.rb +0 -727
- data/test/rubygems/test_gem_commands_cert_command.rb +0 -867
- data/test/rubygems/test_gem_commands_check_command.rb +0 -67
- data/test/rubygems/test_gem_commands_cleanup_command.rb +0 -291
- data/test/rubygems/test_gem_commands_contents_command.rb +0 -270
- data/test/rubygems/test_gem_commands_dependency_command.rb +0 -227
- data/test/rubygems/test_gem_commands_environment_command.rb +0 -167
- data/test/rubygems/test_gem_commands_fetch_command.rb +0 -257
- data/test/rubygems/test_gem_commands_generate_index_command.rb +0 -80
- data/test/rubygems/test_gem_commands_help_command.rb +0 -93
- data/test/rubygems/test_gem_commands_info_command.rb +0 -43
- data/test/rubygems/test_gem_commands_install_command.rb +0 -1553
- data/test/rubygems/test_gem_commands_list_command.rb +0 -32
- data/test/rubygems/test_gem_commands_lock_command.rb +0 -66
- data/test/rubygems/test_gem_commands_mirror.rb +0 -19
- data/test/rubygems/test_gem_commands_open_command.rb +0 -97
- data/test/rubygems/test_gem_commands_outdated_command.rb +0 -49
- data/test/rubygems/test_gem_commands_owner_command.rb +0 -326
- data/test/rubygems/test_gem_commands_pristine_command.rb +0 -659
- data/test/rubygems/test_gem_commands_push_command.rb +0 -477
- data/test/rubygems/test_gem_commands_query_command.rb +0 -857
- data/test/rubygems/test_gem_commands_search_command.rb +0 -15
- data/test/rubygems/test_gem_commands_server_command.rb +0 -19
- data/test/rubygems/test_gem_commands_setup_command.rb +0 -447
- data/test/rubygems/test_gem_commands_signin_command.rb +0 -219
- data/test/rubygems/test_gem_commands_signout_command.rb +0 -30
- data/test/rubygems/test_gem_commands_sources_command.rb +0 -534
- data/test/rubygems/test_gem_commands_specification_command.rb +0 -276
- data/test/rubygems/test_gem_commands_stale_command.rb +0 -42
- data/test/rubygems/test_gem_commands_uninstall_command.rb +0 -504
- data/test/rubygems/test_gem_commands_unpack_command.rb +0 -223
- data/test/rubygems/test_gem_commands_update_command.rb +0 -835
- data/test/rubygems/test_gem_commands_which_command.rb +0 -84
- data/test/rubygems/test_gem_commands_yank_command.rb +0 -180
- data/test/rubygems/test_gem_config_file.rb +0 -504
- data/test/rubygems/test_gem_dependency.rb +0 -395
- data/test/rubygems/test_gem_dependency_installer.rb +0 -1155
- data/test/rubygems/test_gem_dependency_list.rb +0 -264
- data/test/rubygems/test_gem_dependency_resolution_error.rb +0 -26
- data/test/rubygems/test_gem_doctor.rb +0 -194
- data/test/rubygems/test_gem_ext_builder.rb +0 -338
- data/test/rubygems/test_gem_ext_cargo_builder/custom_name/.gitignore +0 -1
- data/test/rubygems/test_gem_ext_cargo_builder/custom_name/Cargo.lock +0 -243
- data/test/rubygems/test_gem_ext_cargo_builder/custom_name/Cargo.toml +0 -10
- data/test/rubygems/test_gem_ext_cargo_builder/custom_name/build.rb +0 -21
- data/test/rubygems/test_gem_ext_cargo_builder/custom_name/custom_name.gemspec +0 -10
- data/test/rubygems/test_gem_ext_cargo_builder/custom_name/src/lib.rs +0 -27
- data/test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/.gitignore +0 -1
- data/test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/Cargo.lock +0 -243
- data/test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/Cargo.toml +0 -10
- data/test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/build.rb +0 -21
- data/test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/rust_ruby_example.gemspec +0 -8
- data/test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/src/lib.rs +0 -39
- data/test/rubygems/test_gem_ext_cargo_builder.rb +0 -178
- data/test/rubygems/test_gem_ext_cargo_builder_link_flag_converter.rb +0 -33
- data/test/rubygems/test_gem_ext_cargo_builder_unit.rb +0 -75
- data/test/rubygems/test_gem_ext_cmake_builder.rb +0 -83
- data/test/rubygems/test_gem_ext_configure_builder.rb +0 -79
- data/test/rubygems/test_gem_ext_ext_conf_builder.rb +0 -230
- data/test/rubygems/test_gem_ext_rake_builder.rb +0 -112
- data/test/rubygems/test_gem_gem_runner.rb +0 -113
- data/test/rubygems/test_gem_gemcutter_utilities.rb +0 -272
- data/test/rubygems/test_gem_impossible_dependencies_error.rb +0 -59
- data/test/rubygems/test_gem_indexer.rb +0 -361
- data/test/rubygems/test_gem_install_update_options.rb +0 -207
- data/test/rubygems/test_gem_installer.rb +0 -2394
- data/test/rubygems/test_gem_local_remote_options.rb +0 -132
- data/test/rubygems/test_gem_name_tuple.rb +0 -42
- data/test/rubygems/test_gem_package.rb +0 -1178
- data/test/rubygems/test_gem_package_old.rb +0 -90
- data/test/rubygems/test_gem_package_tar_header.rb +0 -225
- data/test/rubygems/test_gem_package_tar_reader.rb +0 -87
- data/test/rubygems/test_gem_package_tar_reader_entry.rb +0 -152
- data/test/rubygems/test_gem_package_tar_writer.rb +0 -330
- data/test/rubygems/test_gem_package_task.rb +0 -117
- data/test/rubygems/test_gem_path_support.rb +0 -138
- data/test/rubygems/test_gem_platform.rb +0 -391
- data/test/rubygems/test_gem_rdoc.rb +0 -136
- data/test/rubygems/test_gem_remote_fetcher.rb +0 -1226
- data/test/rubygems/test_gem_request.rb +0 -541
- data/test/rubygems/test_gem_request_connection_pools.rb +0 -150
- data/test/rubygems/test_gem_request_set.rb +0 -671
- data/test/rubygems/test_gem_request_set_gem_dependency_api.rb +0 -847
- data/test/rubygems/test_gem_request_set_lockfile.rb +0 -468
- data/test/rubygems/test_gem_request_set_lockfile_parser.rb +0 -543
- data/test/rubygems/test_gem_request_set_lockfile_tokenizer.rb +0 -306
- data/test/rubygems/test_gem_requirement.rb +0 -498
- data/test/rubygems/test_gem_resolver.rb +0 -791
- data/test/rubygems/test_gem_resolver_activation_request.rb +0 -42
- data/test/rubygems/test_gem_resolver_api_set.rb +0 -209
- data/test/rubygems/test_gem_resolver_api_specification.rb +0 -166
- data/test/rubygems/test_gem_resolver_best_set.rb +0 -158
- data/test/rubygems/test_gem_resolver_composed_set.rb +0 -43
- data/test/rubygems/test_gem_resolver_conflict.rb +0 -81
- data/test/rubygems/test_gem_resolver_dependency_request.rb +0 -82
- data/test/rubygems/test_gem_resolver_git_set.rb +0 -187
- data/test/rubygems/test_gem_resolver_git_specification.rb +0 -113
- data/test/rubygems/test_gem_resolver_index_set.rb +0 -87
- data/test/rubygems/test_gem_resolver_index_specification.rb +0 -92
- data/test/rubygems/test_gem_resolver_installed_specification.rb +0 -46
- data/test/rubygems/test_gem_resolver_installer_set.rb +0 -275
- data/test/rubygems/test_gem_resolver_local_specification.rb +0 -43
- data/test/rubygems/test_gem_resolver_lock_set.rb +0 -61
- data/test/rubygems/test_gem_resolver_lock_specification.rb +0 -97
- data/test/rubygems/test_gem_resolver_requirement_list.rb +0 -18
- data/test/rubygems/test_gem_resolver_specification.rb +0 -62
- data/test/rubygems/test_gem_resolver_vendor_set.rb +0 -81
- data/test/rubygems/test_gem_resolver_vendor_specification.rb +0 -81
- data/test/rubygems/test_gem_security.rb +0 -340
- data/test/rubygems/test_gem_security_policy.rb +0 -535
- data/test/rubygems/test_gem_security_signer.rb +0 -217
- data/test/rubygems/test_gem_security_trust_dir.rb +0 -98
- data/test/rubygems/test_gem_silent_ui.rb +0 -116
- data/test/rubygems/test_gem_source.rb +0 -253
- data/test/rubygems/test_gem_source_fetch_problem.rb +0 -36
- data/test/rubygems/test_gem_source_git.rb +0 -303
- data/test/rubygems/test_gem_source_installed.rb +0 -34
- data/test/rubygems/test_gem_source_list.rb +0 -118
- data/test/rubygems/test_gem_source_local.rb +0 -106
- data/test/rubygems/test_gem_source_lock.rb +0 -112
- data/test/rubygems/test_gem_source_specific_file.rb +0 -75
- data/test/rubygems/test_gem_source_subpath_problem.rb +0 -49
- data/test/rubygems/test_gem_source_vendor.rb +0 -29
- data/test/rubygems/test_gem_spec_fetcher.rb +0 -337
- data/test/rubygems/test_gem_specification.rb +0 -3756
- data/test/rubygems/test_gem_stream_ui.rb +0 -224
- data/test/rubygems/test_gem_stub_specification.rb +0 -277
- data/test/rubygems/test_gem_text.rb +0 -102
- data/test/rubygems/test_gem_uninstaller.rb +0 -674
- data/test/rubygems/test_gem_unsatisfiable_dependency_error.rb +0 -30
- data/test/rubygems/test_gem_uri.rb +0 -39
- data/test/rubygems/test_gem_uri_formatter.rb +0 -26
- data/test/rubygems/test_gem_util.rb +0 -90
- data/test/rubygems/test_gem_validator.rb +0 -42
- data/test/rubygems/test_gem_version.rb +0 -295
- data/test/rubygems/test_gem_version_option.rb +0 -164
- data/test/rubygems/test_kernel.rb +0 -129
- data/test/rubygems/test_project_sanity.rb +0 -20
- data/test/rubygems/test_remote_fetch_error.rb +0 -19
- data/test/rubygems/test_require.rb +0 -719
- data/test/rubygems/test_rubygems.rb +0 -74
- data/test/rubygems/utilities.rb +0 -371
- data/test/rubygems/wrong_key_cert.pem +0 -19
- data/test/rubygems/wrong_key_cert_32.pem +0 -19
- data/test/test_changelog_generator.rb +0 -17
- /data/{lib/rubygems/optparse → bundler/lib/bundler/vendor/connection_pool}/.document +0 -0
- /data/{lib/rubygems/tsort → bundler/lib/bundler/vendor/fileutils}/.document +0 -0
- /data/{lib/rubygems/optparse → bundler/lib/bundler/vendor/fileutils}/COPYING +0 -0
- /data/{MAINTAINERS.txt → doc/MAINTAINERS.txt} +0 -0
- /data/{UPGRADING.md → doc/rubygems/UPGRADING.md} +0 -0
- /data/{bundler/lib/bundler → lib/rubygems}/vendor/molinillo/LICENSE +0 -0
- /data/{bundler/lib/bundler/vendor/fileutils → lib/rubygems/vendor/net-protocol}/LICENSE.txt +0 -0
- /data/lib/rubygems/{optparse → vendor/optparse}/lib/optionparser.rb +0 -0
- /data/lib/rubygems/{optparse → vendor/optparse}/lib/optparse/date.rb +0 -0
- /data/lib/rubygems/{optparse → vendor/optparse}/lib/optparse/shellwords.rb +0 -0
- /data/lib/rubygems/{optparse → vendor/optparse}/lib/optparse/time.rb +0 -0
- /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
|
6
|
+
# for make rjit-headers
|
7
7
|
end
|
8
8
|
|
9
|
+
# Namespace for file utility methods for copying, moving, removing, etc.
|
9
10
|
#
|
10
|
-
#
|
11
|
+
# == What's Here
|
11
12
|
#
|
12
|
-
#
|
13
|
+
# First, what’s elsewhere. \Module \Bundler::FileUtils:
|
13
14
|
#
|
14
|
-
#
|
15
|
-
#
|
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
|
-
#
|
19
|
+
# Here, module \Bundler::FileUtils provides methods that are useful for:
|
18
20
|
#
|
19
|
-
#
|
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
|
-
# ===
|
30
|
+
# === Creating
|
22
31
|
#
|
23
|
-
#
|
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
|
-
#
|
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
|
-
#
|
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
|
-
#
|
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
|
-
#
|
67
|
-
# ::
|
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
|
-
#
|
71
|
-
# either one file or a list of files in that argument. See the method
|
72
|
-
# documentation for examples.
|
58
|
+
# === Setting
|
73
59
|
#
|
74
|
-
#
|
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
|
-
#
|
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
|
-
#
|
70
|
+
# - ::compare_file, ::cmp, ::identical?: Returns whether two entries are identical.
|
71
|
+
# - ::compare_stream: Returns whether two streams are identical.
|
87
72
|
#
|
88
|
-
#
|
89
|
-
# before acting. This equates to passing the <tt>:verbose</tt> flag to methods
|
90
|
-
# in Bundler::FileUtils.
|
73
|
+
# === Copying
|
91
74
|
#
|
92
|
-
#
|
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
|
-
#
|
95
|
-
# files/directories. This equates to passing the <tt>:noop</tt> flag to methods
|
96
|
-
# in Bundler::FileUtils.
|
84
|
+
# === Moving
|
97
85
|
#
|
98
|
-
#
|
86
|
+
# - ::mv, ::move: Moves entries.
|
99
87
|
#
|
100
|
-
#
|
101
|
-
#
|
102
|
-
#
|
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
|
-
|
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
|
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
|
-
#
|
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
|
-
#
|
127
|
-
# working directory after the block execution has finished.
|
225
|
+
# Keyword arguments:
|
128
226
|
#
|
129
|
-
#
|
227
|
+
# - <tt>verbose: true</tt> - prints an equivalent command:
|
130
228
|
#
|
131
|
-
#
|
229
|
+
# Bundler::FileUtils.cd('..')
|
230
|
+
# Bundler::FileUtils.cd('fileutils')
|
132
231
|
#
|
133
|
-
#
|
134
|
-
#
|
135
|
-
#
|
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
|
150
|
-
#
|
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
|
-
#
|
153
|
-
#
|
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
|
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
|
-
#
|
176
|
-
#
|
177
|
-
#
|
178
|
-
#
|
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
|
193
|
-
#
|
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
|
-
#
|
357
|
+
# mkdir -p tmp0 tmp1
|
358
|
+
# mkdir -p -m 700 tmp2 tmp3
|
196
359
|
#
|
197
|
-
#
|
360
|
+
# Raises an exception if for any reason a directory cannot be created.
|
198
361
|
#
|
199
|
-
#
|
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
|
-
#
|
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.
|
212
|
-
|
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
|
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
|
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
|
-
#
|
259
|
-
#
|
260
|
-
#
|
261
|
-
#
|
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
|
-
#
|
284
|
-
#
|
285
|
-
# Bundler::FileUtils.ln(
|
286
|
-
#
|
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
|
-
#
|
289
|
-
#
|
290
|
-
#
|
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
|
-
#
|
293
|
-
# Bundler::FileUtils.ln '/
|
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
|
-
#
|
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
|
-
#
|
301
|
-
#
|
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
|
-
#
|
318
|
-
#
|
319
|
-
# +
|
320
|
-
#
|
321
|
-
#
|
322
|
-
#
|
323
|
-
#
|
324
|
-
#
|
325
|
-
#
|
326
|
-
#
|
327
|
-
#
|
328
|
-
#
|
329
|
-
#
|
330
|
-
# #
|
331
|
-
#
|
332
|
-
#
|
333
|
-
#
|
334
|
-
#
|
335
|
-
#
|
336
|
-
# #
|
337
|
-
#
|
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
|
-
#
|
351
|
-
#
|
352
|
-
#
|
353
|
-
#
|
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
|
-
#
|
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
|
-
#
|
360
|
-
#
|
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
|
-
#
|
363
|
-
#
|
364
|
-
#
|
365
|
-
#
|
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
|
-
#
|
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
|
-
|
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
|
-
|
397
|
-
|
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
|
-
#
|
400
|
-
#
|
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
|
-
#
|
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
|
-
#
|
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
|
-
#
|
417
|
-
# copies +src+ to +dest
|
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
|
-
#
|
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
|
-
#
|
422
|
-
#
|
423
|
-
#
|
424
|
-
#
|
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
|
-
#
|
440
|
-
#
|
441
|
-
# +
|
442
|
-
#
|
443
|
-
#
|
444
|
-
#
|
445
|
-
#
|
446
|
-
#
|
447
|
-
# If +
|
448
|
-
#
|
449
|
-
#
|
450
|
-
# Bundler::FileUtils.
|
451
|
-
#
|
452
|
-
#
|
453
|
-
# #
|
454
|
-
#
|
455
|
-
#
|
456
|
-
#
|
457
|
-
#
|
458
|
-
#
|
459
|
-
#
|
460
|
-
# Bundler::FileUtils.cp_r
|
461
|
-
#
|
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
|
-
#
|
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
|
-
#
|
480
|
-
#
|
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
|
-
#
|
483
|
-
#
|
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
|
-
#
|
1032
|
+
# Keyword arguments:
|
486
1033
|
#
|
487
|
-
#
|
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
|
-
#
|
507
|
-
#
|
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
|
-
#
|
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
|
-
#
|
528
|
-
#
|
529
|
-
#
|
530
|
-
#
|
531
|
-
#
|
532
|
-
#
|
533
|
-
#
|
534
|
-
#
|
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
|
-
#
|
570
|
-
#
|
1194
|
+
# Argument +list+ or its elements
|
1195
|
+
# should be {interpretable as paths}[rdoc-ref:FileUtils@Path+Arguments].
|
571
1196
|
#
|
572
|
-
#
|
573
|
-
#
|
574
|
-
# Bundler::FileUtils.
|
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
|
-
#
|
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
|
-
#
|
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
|
-
#
|
605
|
-
#
|
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
|
-
#
|
609
|
-
# Bundler::FileUtils.rm_r 'some_dir', force: true
|
1293
|
+
# Output:
|
610
1294
|
#
|
611
|
-
#
|
612
|
-
#
|
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
|
-
#
|
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
|
-
#
|
1316
|
+
# Bundler::FileUtils.rm_r(list, force: true, **kwargs)
|
638
1317
|
#
|
639
|
-
#
|
1318
|
+
# Argument +list+ or its elements
|
1319
|
+
# should be {interpretable as paths}[rdoc-ref:FileUtils@Path+Arguments].
|
640
1320
|
#
|
641
|
-
#
|
642
|
-
#
|
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
|
-
#
|
654
|
-
#
|
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
|
-
#
|
669
|
-
#
|
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
|
-
#
|
674
|
-
#
|
675
|
-
# work.
|
1347
|
+
# Optional argument +force+ specifies whether to ignore
|
1348
|
+
# raised exceptions of StandardError and its descendants.
|
676
1349
|
#
|
677
|
-
#
|
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
|
-
#
|
772
|
-
#
|
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
|
-
#
|
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
|
-
#
|
792
|
-
#
|
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
|
-
#
|
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
|
-
#
|
1501
|
+
# Arguments +a+ and +b+
|
1502
|
+
# should be {interpretable as a path}[rdoc-ref:FileUtils@Path+Arguments].
|
812
1503
|
#
|
813
|
-
#
|
814
|
-
#
|
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
|
-
#
|
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
|
-
|
838
|
-
|
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
|
-
#
|
856
|
-
#
|
857
|
-
#
|
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
|
-
#
|
860
|
-
#
|
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
|
-
|
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
|
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
|
-
|
921
|
-
|
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
|
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
|
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
|
-
#
|
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
|
-
#
|
1055
|
-
#
|
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
|
-
#
|
1132
|
-
#
|
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
|
-
#
|
1135
|
-
#
|
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
|
2164
|
+
opts[:encoding] = fu_windows? ? ::Encoding::UTF_8 : path.encoding
|
1294
2165
|
|
1295
|
-
files =
|
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
|
-
|
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
|
-
|
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 ||= $
|
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
|
-
#
|
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
|
-
#
|
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
|
-
#
|
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
|
-
#
|
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
|
-
#
|
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) }
|