aboutsummaryrefslogtreecommitdiffstats
path: root/Library/Homebrew/dev-cmd/boneyard-formula-pr.rb
blob: b478be6098e5cd8c27f6c8f7291924c2e49bed8c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
# 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.
#   --local:    Perform only local operations (don't push and don't create PR).

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
    local_only = ARGV.include?("--local")
    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 which("hub") || local_only
      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 --no-track -b #{branch} origin/master"
      puts "git commit --no-edit --verbose --message=\"#{formula.name}: migrate to boneyard\" -- #{formula_relpath} #{tap_migrations_path.basename}"

      unless local_only
        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`.'"
      end
    else
      cd formula.tap.path
      safe_system "git", "checkout", "--no-track", "-b", branch, "origin/master"
      safe_system "git", "commit", "--no-edit", "--verbose",
        "--message=#{formula.name}: migrate to boneyard",
        "--", formula_relpath, tap_migrations_path.basename

      unless local_only
        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
    end

    if ARGV.dry_run?
      puts "cd #{boneyard_tap.path}"
      puts "git checkout --no-track -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}"

      unless local_only
        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`.'"
      end
    else
      cd boneyard_tap.formula_dir
      safe_system "git", "checkout", "--no-track", "-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

      unless local_only
        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
end