diff --git a/Library/Homebrew/dev-cmd/boneyard-formula-pr.rb b/Library/Homebrew/dev-cmd/boneyard-formula-pr.rb new file mode 100644 index 0000000000000000000000000000000000000000..34156eca3a8563ff2b913a475f6c6ccf83a6efc9 --- /dev/null +++ b/Library/Homebrew/dev-cmd/boneyard-formula-pr.rb @@ -0,0 +1,136 @@ +# Creates a pull request to boneyard a formula. +# +# Usage: brew boneyard-formula-pr [options...] <formula-name> +# +# Options: +# --dry-run: Print what would be done rather than doing it. + +require "formula" +require "utils/json" +require "fileutils" + +begin + require "json" +rescue LoadError + puts "Homebrew does not provide Ruby dependencies; install with:" + puts " gem install json" + odie "Dependency json is not installed." +end + +module Homebrew + def boneyard_formula_pr + formula = ARGV.formulae.first + odie "No formula found!" unless formula + + formula_relpath = formula.path.relative_path_from(formula.tap.path) + formula_file = "#{formula.name}.rb" + bottle_block = File.read(formula.path).include? " bottle do" + boneyard_tap = Tap.fetch("homebrew", "boneyard") + tap_migrations_path = formula.tap.path/"tap_migrations.json" + if ARGV.dry_run? + puts "brew update" + puts "brew tap #{boneyard_tap.name}" + puts "cd #{formula.tap.path}" + cd formula.tap.path + puts "cp #{formula_relpath} #{boneyard_tap.path}" + puts "git rm #{formula_relpath}" + unless File.exist? tap_migrations_path + puts "Creating tap_migrations.json for #{formula.tap.name}" + puts "git add #{tap_migrations_path}" + end + puts "Loading tap_migrations.json" + puts "Adding #{formula.name} to tap_migrations.json" + else + safe_system HOMEBREW_BREW_FILE, "update" + safe_system HOMEBREW_BREW_FILE, "tap", boneyard_tap.name + cd formula.tap.path + cp formula_relpath, boneyard_tap.formula_dir + safe_system "git", "rm", formula_relpath + unless File.exist? tap_migrations_path + tap_migrations_path.write <<-EOS.undent + { + } + EOS + safe_system "git", "add", tap_migrations_path + end + tap_migrations = Utils::JSON.load(File.read(tap_migrations_path)) + tap_migrations[formula.name] = boneyard_tap.name + tap_migrations = tap_migrations.sort.inject({}) { |a, e| a.merge!(e[0] => e[1]) } + tap_migrations_path.atomic_write(JSON.pretty_generate(tap_migrations) + "\n") + end + unless Formula["hub"].any_version_installed? + if ARGV.dry_run? + puts "brew install hub" + else + safe_system HOMEBREW_BREW_FILE, "install", "hub" + end + end + branch = "#{formula.name}-boneyard" + if ARGV.dry_run? + puts "cd #{formula.tap.path}" + puts "git checkout -b #{branch} origin/master" + puts "git commit --no-edit --verbose --message=\"#{formula.name}: migrate to boneyard\" -- #{formula_relpath} #{tap_migrations_path.basename}" + puts "hub fork --no-remote" + puts "hub fork" + puts "hub fork (to read $HUB_REMOTE)" + puts "git push $HUB_REMOTE #{branch}:#{branch}" + puts "hub pull-request -m $'#{formula.name}: migrate to boneyard\\n\\nCreated with `brew boneyard-formula-pr`.'" + else + cd formula.tap.path + safe_system "git", "checkout", "-b", branch, "origin/master" + safe_system "git", "commit", "--no-edit", "--verbose", + "--message=#{formula.name}: migrate to boneyard", + "--", formula_relpath, tap_migrations_path.basename + safe_system "hub", "fork", "--no-remote" + quiet_system "hub", "fork" + remote = Utils.popen_read("hub fork 2>&1")[/fatal: remote (.+) already exists./, 1] + odie "cannot get remote from 'hub'!" unless remote + safe_system "git", "push", remote, "#{branch}:#{branch}" + pr_message = <<-EOS.undent + #{formula.name}: migrate to boneyard + + Created with `brew boneyard-formula-pr`. + EOS + pr_url = Utils.popen_read("hub", "pull-request", "-m", pr_message).chomp + end + + if ARGV.dry_run? + puts "cd #{boneyard_tap.path}" + puts "git checkout -b #{branch} origin/master" + if bottle_block + puts "Removing bottle block" + else + puts "No bottle block to remove" + end + puts "git add #{formula_file}" + puts "git commit --no-edit --verbose --message=\"#{formula.name}: migrate from #{formula.tap.repo}\" -- #{formula_file}" + puts "hub fork --no-remote" + puts "hub fork" + puts "hub fork (to read $HUB_REMOTE)" + puts "git push $HUB_REMOTE #{branch}:#{branch}" + puts "hub pull-request --browse -m $'#{formula.name}: migrate from #{formula.tap.repo}\\n\\nGoes together with $PR_URL\\n\\nCreated with `brew boneyard-formula-pr`.'" + else + cd boneyard_tap.formula_dir + safe_system "git", "checkout", "-b", branch, "origin/master" + if bottle_block + Utils::Inreplace.inreplace formula_file, / bottle do.+?end\n\n/m, "" + end + safe_system "git", "add", formula_file + safe_system "git", "commit", "--no-edit", "--verbose", + "--message=#{formula.name}: migrate from #{formula.tap.repo}", + "--", formula_file + safe_system "hub", "fork", "--no-remote" + quiet_system "hub", "fork" + remote = Utils.popen_read("hub fork 2>&1")[/fatal: remote (.+) already exists./, 1] + odie "cannot get remote from 'hub'!" unless remote + safe_system "git", "push", remote, "#{branch}:#{branch}" + safe_system "hub", "pull-request", "--browse", "-m", <<-EOS.undent + #{formula.name}: migrate from #{formula.tap.repo} + + Goes together with #{pr_url}. + + Created with `brew boneyard-formula-pr`. + EOS + end + end +end