aboutsummaryrefslogtreecommitdiffstats
path: root/Library/Contributions/examples/brew-pull.rb
blob: d96811b6fa9132364db3dbb3aab0751eb5294028 (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
# Gets a patch from a GitHub commit or pull request and applies it to Homebrew.
# Optionally, installs it too.

require 'utils.rb'

if ARGV.include? '--install'
  ARGV.delete '--install'
  install = true
end

if ARGV.empty?
  onoe 'This command requires at least one URL argument'
end

HOMEBREW_REPOSITORY.cd do
  ARGV.each do|arg|
    # This regex should work, if it's too precise, feel free to fix it.
    urlmatch = arg.match 'https:\/\/github.com\/\w+\/homebrew\/(pull\/(\d+)|commit\/\w{4,40})'
    if !urlmatch
      ohai 'Ignoring URL:', "Not a GitHub pull request or commit: #{arg}"
      next
    end

    # GitHub provides commits'/pull-requests' raw patches using this URL.
    url = urlmatch[0] + '.patch'

    # The cache directory seems like a good place to put patches.
    patchpath = (HOMEBREW_CACHE+File.basename(url))
    curl url, '-o', patchpath

    # Store current revision
    revision = `git log -n1 --format=%H`.strip()

    # Makes sense to squash whitespace errors, we don't want them.
    ohai 'Applying patch'
    safe_system 'git', 'am', '--signoff', '--whitespace=fix', patchpath

    issue = urlmatch[2]
    if issue
      ohai "Patch closes issue ##{issue}"
      message = `git log HEAD^.. --format=%B`
      
      # If this is a pull request, append a close message.
      if !message.include? 'Closes #'
        issueline = "Closes ##{issue}."
        signed = 'Signed-off-by:'
        message = message.gsub signed, issueline + "\n\n" + signed
        safe_system 'git', 'commit', '--amend', '-q', '-m', message
      end
    end

    ohai 'Patch changed:'
    safe_system 'git', 'diff', "#{revision}..", '--stat'

    if install
      `git diff #{revision}.. --name-status`.each_line do |line|
        status, filename = line.split()
        # Don't try and do anything to removed files.
        if (status == 'A' or status == 'M') and filename.include? '/Formula/'
          formula = File.basename(filename, '.rb')
          ohai "Installing #{formula}"
          # Not sure if this is the best way to install?
          safe_system 'brew', 'install', '--force', formula
        end
      end
    end
  end
end