summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore3
-rw-r--r--Rakefile6
-rw-r--r--lib/bundler.rb3
-rw-r--r--lib/bundler/build_metadata.rb36
-rw-r--r--lib/bundler/cli.rb7
-rw-r--r--lib/bundler/cli/binstubs.rb1
-rw-r--r--lib/bundler/definition.rb13
-rw-r--r--lib/bundler/env.rb1
-rw-r--r--lib/bundler/feature_flag.rb1
-rw-r--r--lib/bundler/installer.rb13
-rw-r--r--lib/bundler/settings.rb1
-rw-r--r--lib/bundler/shared_helpers.rb22
-rw-r--r--lib/bundler/source/path.rb2
-rw-r--r--lib/bundler/source/rubygems.rb1
-rw-r--r--lib/bundler/templates/Gemfile2
-rw-r--r--lib/bundler/templates/gems.rb2
-rw-r--r--lib/bundler/templates/newgem/Gemfile.tt2
-rw-r--r--man/bundle-config.ronn6
-rw-r--r--spec/bundler/definition_spec.rb2
-rw-r--r--spec/commands/binstubs_spec.rb13
-rw-r--r--spec/commands/version_spec.rb26
-rw-r--r--spec/install/gemfile/git_spec.rb4
-rw-r--r--spec/install/gemfile/lockfile_spec.rb48
-rw-r--r--spec/install/gemfile_spec.rb16
-rw-r--r--spec/spec_helper.rb1
-rw-r--r--task/build_metadata.rake33
-rw-r--r--task/git_hooks.rake35
-rw-r--r--task/release.rake7
28 files changed, 278 insertions, 29 deletions
diff --git a/.gitignore b/.gitignore
index 88730f82cd..6230ec1c99 100644
--- a/.gitignore
+++ b/.gitignore
@@ -16,3 +16,6 @@ man/*
# rspec failure tracking
.rspec_status
+
+# files generated during packaging
+/lib/bundler/generated/
diff --git a/Rakefile b/Rakefile
index 00b0649f7d..fcbf7b5866 100644
--- a/Rakefile
+++ b/Rakefile
@@ -366,10 +366,8 @@ task :update_certs => "spec:rubygems:clone_rubygems_master" do
Bundler::SSLCerts::CertificateManager.update_from!(RUBYGEMS_REPO)
end
-require "bundler/gem_tasks"
-task :build => ["man:build"]
-task :release => ["man:require", "man:build"]
-
task :default => :spec
Dir["task/*.{rb,rake}"].each(&method(:load))
+
+task :generate_files => Rake::Task.tasks.select {|t| t.name.start_with?("lib/bundler/generated") }
diff --git a/lib/bundler.rb b/lib/bundler.rb
index 1228785734..c6d68c49de 100644
--- a/lib/bundler.rb
+++ b/lib/bundler.rb
@@ -13,6 +13,7 @@ require "bundler/rubygems_integration"
require "bundler/version"
require "bundler/constants"
require "bundler/current_ruby"
+require "bundler/build_metadata"
module Bundler
environment_preserver = EnvironmentPreserver.new(ENV, EnvironmentPreserver::BUNDLER_KEYS)
@@ -206,7 +207,7 @@ module Bundler
def root
@root ||= begin
- default_gemfile.dirname.expand_path
+ SharedHelpers.root
rescue GemfileNotFound
bundle_dir = default_bundle_dir
raise GemfileNotFound, "Could not locate Gemfile or .bundle/ directory" unless bundle_dir
diff --git a/lib/bundler/build_metadata.rb b/lib/bundler/build_metadata.rb
new file mode 100644
index 0000000000..54436f982d
--- /dev/null
+++ b/lib/bundler/build_metadata.rb
@@ -0,0 +1,36 @@
+# frozen_string_literal: true
+
+module Bundler
+ # Represents metadata from when the Bundler gem was built.
+ module BuildMetadata
+ # begin ivars
+ @release = false
+ # end ivars
+
+ # A hash representation of the build metadata.
+ def self.to_h
+ {
+ "Built At" => built_at,
+ "Git SHA" => git_commit_sha,
+ "Released Version" => release?,
+ }
+ end
+
+ # A string representing the date the bundler gem was built.
+ def self.built_at
+ @built_at ||= Time.now.utc.strftime("%Y-%m-%d").freeze
+ end
+
+ # The SHA for the git commit the bundler gem was built from.
+ def self.git_commit_sha
+ @git_commit_sha ||= Dir.chdir(File.expand_path("..", __FILE__)) do
+ `git rev-parse --short HEAD`.strip.freeze
+ end
+ end
+
+ # Whether this is an official release build of Bundler.
+ def self.release?
+ @release
+ end
+ end
+end
diff --git a/lib/bundler/cli.rb b/lib/bundler/cli.rb
index e93fc9529d..838dcb3e08 100644
--- a/lib/bundler/cli.rb
+++ b/lib/bundler/cli.rb
@@ -262,6 +262,8 @@ module Bundler
"Overwrite existing binstubs if they exist"
method_option "path", :type => :string, :lazy_default => "bin", :banner =>
"Binstub destination directory (default bin)"
+ method_option "shebang", :type => :string, :banner =>
+ "Specify a different shebang executable name than the default (usually 'ruby')"
method_option "standalone", :type => :boolean, :banner =>
"Make binstubs that can work without the Bundler runtime"
def binstubs(*gems)
@@ -395,7 +397,10 @@ module Bundler
desc "version", "Prints the bundler's version information"
def version
- Bundler.ui.info "Bundler version #{Bundler::VERSION}"
+ if ARGV.include?("version")
+ build_info = " (#{BuildMetadata.built_at} commit #{BuildMetadata.git_commit_sha})"
+ end
+ Bundler.ui.info "Bundler version #{Bundler::VERSION}#{build_info}"
end
map %w[-v --version] => :version
diff --git a/lib/bundler/cli/binstubs.rb b/lib/bundler/cli/binstubs.rb
index 82815062d3..f872a2dcc7 100644
--- a/lib/bundler/cli/binstubs.rb
+++ b/lib/bundler/cli/binstubs.rb
@@ -13,6 +13,7 @@ module Bundler
Bundler.definition.validate_runtime!
Bundler.settings[:bin] = options["path"] if options["path"]
Bundler.settings[:bin] = nil if options["path"] && options["path"].empty?
+ Bundler.settings[:shebang] = options["shebang"] if options["shebang"]
installer = Installer.new(Bundler.root, Bundler.definition)
if gems.empty?
diff --git a/lib/bundler/definition.rb b/lib/bundler/definition.rb
index 4b75b39065..d7faff53e7 100644
--- a/lib/bundler/definition.rb
+++ b/lib/bundler/definition.rb
@@ -194,10 +194,19 @@ module Bundler
missing
end
- def missing_dependencies
+ def missing_dependencies?
missing = []
resolve.materialize(current_dependencies, missing)
- missing
+ return false if missing.empty?
+ Bundler.ui.debug "The definition is missing #{missing.map(&:full_name)}"
+ true
+ rescue BundlerError => e
+ Bundler.ui.debug "The definition is missing dependencies, failed to resolve & materialize locally (#{e})"
+ true
+ ensure
+ @index = nil
+ @resolve = nil
+ @specs = nil
end
def requested_specs
diff --git a/lib/bundler/env.rb b/lib/bundler/env.rb
index 325b96fbfa..333173ac27 100644
--- a/lib/bundler/env.rb
+++ b/lib/bundler/env.rb
@@ -14,6 +14,7 @@ module Bundler
out = String.new
append_formatted_table("Environment", environment, out)
+ append_formatted_table("Bundler Build Metadata", BuildMetadata.to_h, out)
unless Bundler.settings.all.empty?
out << "\n## Bundler settings\n\n```\n"
diff --git a/lib/bundler/feature_flag.rb b/lib/bundler/feature_flag.rb
index f472ba2b7b..34fddb1ecc 100644
--- a/lib/bundler/feature_flag.rb
+++ b/lib/bundler/feature_flag.rb
@@ -19,6 +19,7 @@ module Bundler
settings_flag(:init_gems_rb) { bundler_2_mode? }
settings_flag(:only_update_to_newer_versions) { bundler_2_mode? }
settings_flag(:plugins) { @bundler_version >= Gem::Version.new("1.14") }
+ settings_flag(:prefer_gems_rb) { bundler_2_mode? }
settings_flag(:update_requires_all_flag) { bundler_2_mode? }
def initialize(bundler_version)
diff --git a/lib/bundler/installer.rb b/lib/bundler/installer.rb
index ae8055408f..7c13c0c8a9 100644
--- a/lib/bundler/installer.rb
+++ b/lib/bundler/installer.rb
@@ -78,7 +78,7 @@ module Bundler
return
end
- resolve_if_need(options)
+ resolve_if_needed(options)
ensure_specs_are_compatible!
install(options)
@@ -229,18 +229,11 @@ module Bundler
"because a file already exists at that path. Either remove or rename the file so the directory can be created."
end
- def resolve_if_need(options)
+ def resolve_if_needed(options)
if !options["update"] && !options[:inline] && !options["force"] && Bundler.default_lockfile.file?
- local = Bundler.ui.silence do
- begin
- tmpdef = Definition.build(Bundler.default_gemfile, Bundler.default_lockfile, nil)
- true unless tmpdef.new_platform? || tmpdef.missing_dependencies.any?
- rescue BundlerError
- end
- end
+ return if @definition.nothing_changed? && !@definition.missing_dependencies?
end
- return if local
options["local"] ? @definition.resolve_with_cache! : @definition.resolve_remotely!
end
diff --git a/lib/bundler/settings.rb b/lib/bundler/settings.rb
index 34747cbed7..9f4d5b30a0 100644
--- a/lib/bundler/settings.rb
+++ b/lib/bundler/settings.rb
@@ -28,6 +28,7 @@ module Bundler
no_prune
only_update_to_newer_versions
plugins
+ prefer_gems_rb
silence_root_warning
update_requires_all_flag
].freeze
diff --git a/lib/bundler/shared_helpers.rb b/lib/bundler/shared_helpers.rb
index 593d2c1e06..39f0423f7f 100644
--- a/lib/bundler/shared_helpers.rb
+++ b/lib/bundler/shared_helpers.rb
@@ -19,9 +19,15 @@ end
module Bundler
module SharedHelpers
- def default_gemfile
+ def root
gemfile = find_gemfile
raise GemfileNotFound, "Could not locate Gemfile" unless gemfile
+ Pathname.new(gemfile).untaint.expand_path.parent
+ end
+
+ def default_gemfile
+ gemfile = find_gemfile(:order_matters)
+ raise GemfileNotFound, "Could not locate Gemfile" unless gemfile
Pathname.new(gemfile).untaint
end
@@ -137,7 +143,7 @@ module Bundler
end
def print_major_deprecations!
- deprecate_gemfile(find_gemfile) if find_gemfile == find_file("Gemfile")
+ deprecate_gemfile(find_gemfile) if find_gemfile(:order_matters) == find_file("Gemfile")
if RUBY_VERSION < "2"
major_deprecation("Bundler will only support ruby >= 2.0, you are running #{RUBY_VERSION}")
end
@@ -172,10 +178,16 @@ module Bundler
private
- def find_gemfile
+ def find_gemfile(order_matters = false)
given = ENV["BUNDLE_GEMFILE"]
return given if given && !given.empty?
- find_file("Gemfile", "gems.rb")
+ names = gemfile_names
+ names.reverse! if order_matters && Bundler.feature_flag.prefer_gems_rb?
+ find_file(*names)
+ end
+
+ def gemfile_names
+ ["Gemfile", "gems.rb"]
end
def find_file(*names)
@@ -228,7 +240,7 @@ module Bundler
end
# Set BUNDLE_GEMFILE
- Bundler::SharedHelpers.set_env "BUNDLE_GEMFILE", find_gemfile.to_s
+ Bundler::SharedHelpers.set_env "BUNDLE_GEMFILE", find_gemfile(:order_matters).to_s
Bundler::SharedHelpers.set_env "BUNDLER_VERSION", Bundler::VERSION
end
diff --git a/lib/bundler/source/path.rb b/lib/bundler/source/path.rb
index 82f987fdd8..99808d2ef2 100644
--- a/lib/bundler/source/path.rb
+++ b/lib/bundler/source/path.rb
@@ -35,10 +35,12 @@ module Bundler
end
def remote!
+ @local_specs = nil
@allow_remote = true
end
def cached!
+ @local_specs = nil
@allow_cached = true
end
diff --git a/lib/bundler/source/rubygems.rb b/lib/bundler/source/rubygems.rb
index 353194f53f..a1d4266960 100644
--- a/lib/bundler/source/rubygems.rb
+++ b/lib/bundler/source/rubygems.rb
@@ -31,6 +31,7 @@ module Bundler
end
def cached!
+ @specs = nil
@allow_cached = true
end
diff --git a/lib/bundler/templates/Gemfile b/lib/bundler/templates/Gemfile
index 7db8998d32..21c6283123 100644
--- a/lib/bundler/templates/Gemfile
+++ b/lib/bundler/templates/Gemfile
@@ -1,4 +1,6 @@
# frozen_string_literal: true
source "https://rubygems.org"
+git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
+
# gem "rails"
diff --git a/lib/bundler/templates/gems.rb b/lib/bundler/templates/gems.rb
index a6ef23ba3e..9495f50c0e 100644
--- a/lib/bundler/templates/gems.rb
+++ b/lib/bundler/templates/gems.rb
@@ -2,4 +2,6 @@
# A sample gems.rb
source "https://rubygems.org"
+git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
+
# gems "rails"
diff --git a/lib/bundler/templates/newgem/Gemfile.tt b/lib/bundler/templates/newgem/Gemfile.tt
index 4cd2e40f4f..c114bd6665 100644
--- a/lib/bundler/templates/newgem/Gemfile.tt
+++ b/lib/bundler/templates/newgem/Gemfile.tt
@@ -1,4 +1,6 @@
source "https://rubygems.org"
+git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
+
# Specify your gem's dependencies in <%= config[:name] %>.gemspec
gemspec
diff --git a/man/bundle-config.ronn b/man/bundle-config.ronn
index d387350f8b..4fa0025815 100644
--- a/man/bundle-config.ronn
+++ b/man/bundle-config.ronn
@@ -223,9 +223,11 @@ learn more about their operation in [bundle install(1)][bundle-install].
Sets the `--key` parameter for `gem push` when using the `rake release`
command with a private gemstash server.
* `error_on_stderr` (`BUNDLE_ERROR_ON_STDERR`)
- Print Bundler errors to stderr
+ Print Bundler errors to stderr.
* `init_gems_rb` (`BUNDLE_NEW_GEMFILE_NAME`)
- generate a new gems.rb on `bundle init` instead of the `Gemfile`
+ Generate a `gems.rb` instead of a `Gemfile` when running `bundle init`.
+* `prefer_gems_rb` (`BUNDLE_PREFER_GEMS_RB`)
+ Prefer `gems.rb` to `Gemfile` when Bundler is searching for a Gemfile.
* `update_requires_all_flag` (`BUNDLE_UPDATE_REQUIRES_ALL_FLAG`)
Require passing `--all` to `bundle update` when everything should be updated,
and disallow passing no options to `bundle update`.
diff --git a/spec/bundler/definition_spec.rb b/spec/bundler/definition_spec.rb
index 4e93d5e01c..cb642da9f7 100644
--- a/spec/bundler/definition_spec.rb
+++ b/spec/bundler/definition_spec.rb
@@ -5,7 +5,7 @@ RSpec.describe Bundler::Definition do
describe "#lock" do
before do
allow(Bundler).to receive(:settings) { Bundler::Settings.new(".") }
- allow(Bundler).to receive(:default_gemfile) { Pathname.new("Gemfile") }
+ allow(Bundler::SharedHelpers).to receive(:find_gemfile) { Pathname.new("Gemfile") }
allow(Bundler).to receive(:ui) { double("UI", :info => "", :debug => "") }
end
context "when it's not possible to write to the file" do
diff --git a/spec/commands/binstubs_spec.rb b/spec/commands/binstubs_spec.rb
index f3ca2301a7..430dbef314 100644
--- a/spec/commands/binstubs_spec.rb
+++ b/spec/commands/binstubs_spec.rb
@@ -103,6 +103,19 @@ RSpec.describe "bundle binstubs <gem>" do
expect(File.stat(binary).mode.to_s(8)).to eq("100775")
end
end
+
+ context "when using --shebang" do
+ it "sets the specified shebang for the the binstub" do
+ install_gemfile <<-G
+ source "file://#{gem_repo1}"
+ gem "rack"
+ G
+
+ bundle "binstubs rack --shebang jruby"
+
+ expect(File.open("bin/rackup").gets).to eq("#!/usr/bin/env jruby\n")
+ end
+ end
end
context "when the gem doesn't exist" do
diff --git a/spec/commands/version_spec.rb b/spec/commands/version_spec.rb
new file mode 100644
index 0000000000..478edb9e67
--- /dev/null
+++ b/spec/commands/version_spec.rb
@@ -0,0 +1,26 @@
+# frozen_string_literal: true
+
+RSpec.describe "bundle version" do
+ context "with -v" do
+ it "outputs the version" do
+ bundle! "-v"
+ expect(out).to eq("Bundler version #{Bundler::VERSION}")
+ end
+ end
+
+ context "with --version" do
+ it "outputs the version" do
+ bundle! "--version"
+ expect(out).to eq("Bundler version #{Bundler::VERSION}")
+ end
+ end
+
+ context "with version" do
+ it "outputs the version with build metadata" do
+ date = Bundler::BuildMetadata.built_at
+ git_commit_sha = Bundler::BuildMetadata.git_commit_sha
+ bundle! "version"
+ expect(out).to eq("Bundler version #{Bundler::VERSION} (#{date} commit #{git_commit_sha})")
+ end
+ end
+end
diff --git a/spec/install/gemfile/git_spec.rb b/spec/install/gemfile/git_spec.rb
index 31abb4de72..59bbc9c016 100644
--- a/spec/install/gemfile/git_spec.rb
+++ b/spec/install/gemfile/git_spec.rb
@@ -1144,11 +1144,11 @@ RSpec.describe "bundle install with git sources" do
end
`git commit -m 'commit for iteration #{i}' ext/foo.c`
end
- git_sha = git_reader.ref_for("HEAD")
+ git_commit_sha = git_reader.ref_for("HEAD")
install_gemfile <<-G
source "file://#{gem_repo1}"
- gem "foo", :git => "#{lib_path("foo-1.0")}", :ref => "#{git_sha}"
+ gem "foo", :git => "#{lib_path("foo-1.0")}", :ref => "#{git_commit_sha}"
G
run <<-R
diff --git a/spec/install/gemfile/lockfile_spec.rb b/spec/install/gemfile/lockfile_spec.rb
new file mode 100644
index 0000000000..dc1baca6ea
--- /dev/null
+++ b/spec/install/gemfile/lockfile_spec.rb
@@ -0,0 +1,48 @@
+# frozen_string_literal: true
+
+RSpec.describe "bundle install with a lockfile present" do
+ let(:gf) { <<-G }
+ source "file://#{gem_repo1}"
+
+ gem "rack", "1.0.0"
+ G
+
+ subject do
+ install_gemfile(gf)
+ end
+
+ context "gemfile evaluation" do
+ let(:gf) { super() + "\n\n File.open('evals', 'a') {|f| f << %(1\n) } unless ENV['BUNDLER_SPEC_NO_APPEND']" }
+
+ context "with plugins disabled" do
+ before do
+ bundle! "config plugins false"
+ subject
+ end
+
+ it "does not evaluate the gemfile twice" do
+ bundle! :install
+
+ with_env_vars("BUNDLER_SPEC_NO_APPEND" => "1") { expect(the_bundle).to include_gem "rack 1.0.0" }
+
+ # The first eval is from the initial install, we're testing that the
+ # second install doesn't double-eval
+ expect(bundled_app("evals").read.lines.to_a.size).to eq(2)
+ end
+
+ context "when the gem is not installed" do
+ before { FileUtils.rm_rf ".bundle" }
+
+ it "does not evaluate the gemfile twice" do
+ bundle! :install
+
+ with_env_vars("BUNDLER_SPEC_NO_APPEND" => "1") { expect(the_bundle).to include_gem "rack 1.0.0" }
+
+ # The first eval is from the initial install, we're testing that the
+ # second install doesn't double-eval
+ expect(bundled_app("evals").read.lines.to_a.size).to eq(2)
+ end
+ end
+ end
+ end
+end
diff --git a/spec/install/gemfile_spec.rb b/spec/install/gemfile_spec.rb
index 9262dcc92d..d1b1f1e6b8 100644
--- a/spec/install/gemfile_spec.rb
+++ b/spec/install/gemfile_spec.rb
@@ -66,6 +66,22 @@ RSpec.describe "bundle install" do
end
end
+ context "with prefer_gems_rb set" do
+ before { bundle! "config prefer_gems_rb true" }
+
+ it "prefers gems.rb to Gemfile" do
+ create_file("gems.rb", "gem 'bundler'")
+ create_file("Gemfile", "raise 'wrong Gemfile!'")
+
+ bundle! :install
+
+ expect(bundled_app("gems.rb")).to be_file
+ expect(bundled_app("Gemfile.lock")).not_to be_file
+
+ expect(the_bundle).to include_gem "bundler #{Bundler::VERSION}"
+ end
+ end
+
context "with engine specified in symbol" do
it "does not raise any error parsing Gemfile" do
simulate_ruby_version "2.3.0" do
diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb
index f6700ca315..782cffc1d1 100644
--- a/spec/spec_helper.rb
+++ b/spec/spec_helper.rb
@@ -46,7 +46,6 @@ Spec::Rubygems.setup
FileUtils.rm_rf(Spec::Path.gem_repo1)
ENV["RUBYOPT"] = "#{ENV["RUBYOPT"]} -r#{Spec::Path.root}/spec/support/hax.rb"
ENV["BUNDLE_SPEC_RUN"] = "true"
-ENV["BUNDLE_PLUGINS"] = "true"
# Don't wrap output in tests
ENV["THOR_COLUMNS"] = "10000"
diff --git a/task/build_metadata.rake b/task/build_metadata.rake
new file mode 100644
index 0000000000..e06a795259
--- /dev/null
+++ b/task/build_metadata.rake
@@ -0,0 +1,33 @@
+# frozen_string_literal: true
+
+def write_build_metadata(build_metadata)
+ build_metadata_file = "lib/bundler/build_metadata.rb"
+
+ ivars = build_metadata.sort.map do |k, v|
+ " @#{k} = #{BUNDLER_SPEC.send(:ruby_code, v)}"
+ end.join("\n")
+
+ contents = File.read(build_metadata_file)
+ contents.sub!(/^(\s+# begin ivars).+(^\s+# end ivars)/m, "\\1\n#{ivars}\n\\2")
+ File.open(build_metadata_file, "w") {|f| f << contents }
+end
+
+task :build_metadata do
+ build_metadata = {
+ :built_at => BUNDLER_SPEC.date.utc.strftime("%Y-%m-%d"),
+ :git_commit_sha => `git rev-parse --short HEAD`.strip,
+ :release => Rake::Task["release"].instance_variable_get(:@already_invoked),
+ }
+
+ write_build_metadata(build_metadata)
+end
+
+namespace :build_metadata do
+ task :clean do
+ build_metadata = {
+ :release => false,
+ }
+
+ write_build_metadata(build_metadata)
+ end
+end
diff --git a/task/git_hooks.rake b/task/git_hooks.rake
new file mode 100644
index 0000000000..e70d66afaa
--- /dev/null
+++ b/task/git_hooks.rake
@@ -0,0 +1,35 @@
+# frozen_string_literal: true
+directory ".git/hooks"
+
+file ".git/hooks/pre-commit" => [__FILE__] do |t|
+ File.open(t.name, "w") {|f| f << <<-SH }
+#!/bin/sh
+
+set -e
+
+.git/hooks/run-ruby bin/rubocop
+.git/hooks/run-ruby bin/rspec spec/quality_spec.rb
+ SH
+
+ chmod 0o755, t.name, :verbose => false
+end
+
+file ".git/hooks/pre-push" => [__FILE__] do |_t|
+ Dir.chdir(".git/hooks") do
+ safe_ln "pre-commit", "pre-push", :verbose => false
+ end
+end
+
+file ".git/hooks/run-ruby" => [__FILE__] do |t|
+ File.open(t.name, "w") {|f| f << <<-SH }
+#!/bin/bash
+
+ruby="ruby"
+command -v chruby-exec >/dev/null 2>&1 && [[ -f ~/.ruby-version ]] && ruby="chruby-exec $(cat ~/.ruby-version) --"
+ruby $@
+ SH
+
+ chmod 0o755, t.name, :verbose => false
+end
+
+task :git_hooks => Rake::Task.tasks.select {|t| t.name.start_with?(".git/hooks") }
diff --git a/task/release.rake b/task/release.rake
index 104fe1f857..8feaec3ae4 100644
--- a/task/release.rake
+++ b/task/release.rake
@@ -1,4 +1,11 @@
# frozen_string_literal: true
+
+require "bundler/gem_tasks"
+task :build => ["build_metadata", "man:build", "generate_files"] do
+ Rake::Task["build_metadata:clean"].tap(&:reenable).real_invoke
+end
+task :release => ["man:require", "man:build", "build_metadata"]
+
namespace :release do
def confirm(prompt = "")
loop do