summaryrefslogtreecommitdiff
path: root/deps/npm/scripts/pr
blob: 30a3b05ffe3b18f129a346dc2994402490b26ece (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
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
#!/usr/bin/env bash

# Land a pull request
# Creates a PR-### branch, pulls the commits, opens up an interactive rebase to
# squash, and then annotates the commit with the changelog goobers
#
# Usage:
#   pr <url|number> [<upstream remote>=origin]

main () {
  if [ "$1" = "finish" ]; then
    shift
    finish "$@"
    return $?
  fi

  local url="$(prurl "$@")"
  local num=$(basename $url)
  local prpath="${url#git@github.com:}"
  local repo=${prpath%/pull/$num}
  local prweb="https://github.com/$prpath"
  local root="$(prroot "$url")"
  local api="https://api.github.com/repos/${repo}/pulls/${num}"
  local user=$(curl -s $api | json user.login)
  local ref="$(prref "$url" "$root")"
  local curhead="$(git show --no-patch --pretty=%H HEAD)"
  local curbranch="$(git rev-parse --abbrev-ref HEAD)"
  local cleanlines
  IFS=$'\n' cleanlines=($(git status -s -uno))
  if [ ${#cleanlines[@]} -ne 0 ]; then
    echo "working dir not clean" >&2
    IFS=$'\n' echo "${cleanlines[@]}" >&2
    echo "aborting PR merge" >&2
  fi

  # ok, ready to rock
  branch=PR-$num
  if [ "$curbranch" == "$branch" ]; then
    echo "already on $branch, you're on your own" >&2
    return 1
  fi

  me=$(git config github.user || git config user.name)
  if [ "$me" == "" ]; then
    echo "run 'git config --add github.user <username>'" >&2
    return 1
  fi

  exists=$(git show --no-patch --pretty=%H $branch 2>/dev/null)
  if [ "$exists" == "" ]; then
    git fetch origin pull/$num/head:$branch
    git checkout $branch
  else
    git checkout $branch
    git pull --rebase origin pull/$num/head
  fi

  git rebase -i $curbranch # squash and test

  if [ $? -eq 0 ]; then
    finish "${curbranch}"
  else
    echo "resolve conflicts and run: $0 finish "'"'${curbranch}'"'
  fi
}

# add the PR-URL to the last commit, after squashing
finish () {
  if [ $# -eq 0 ]; then
    echo "Usage: $0 finish <branch> (while on a PR-### branch)" >&2
    return 1
  fi

  local curbranch="$1"
  local ref=$(cat .git/HEAD)
  local prnum
  case $ref in
    "ref: refs/heads/PR-"*)
      prnum=${ref#ref: refs/heads/PR-}
      ;;
    *)
      echo "not on the PR-## branch any more!" >&2
      return 1
      ;;
  esac

  local me=$(git config github.user || git config user.name)
  if [ "$me" == "" ]; then
    echo "run 'git config --add github.user <username>'" >&2
    return 1
  fi

  set -x

  local url="$(prurl "$prnum")"
  local num=$prnum
  local prpath="${url#git@github.com:}"
  local repo=${prpath%/pull/$num}
  local prweb="https://github.com/$prpath"
  local root="$(prroot "$url")"

  local api="https://api.github.com/repos/${repo}/pulls/${num}"
  local user=$(curl -s $api | json user.login)

  local lastmsg="$(git log -1 --pretty=%B)"
  local newmsg="${lastmsg}

PR-URL: ${prweb}
Credit: @${user}
Close: #${num}
Reviewed-by: @${me}
"
  git commit --amend -m "$newmsg"
  git checkout $curbranch
  git merge PR-${prnum} --ff-only
  set +x
}


prurl () {
  local url="$1"
  if [ "$url" == "" ] && type pbpaste &>/dev/null; then
    url="$(pbpaste)"
  fi
  if [[ "$url" =~ ^[0-9]+$ ]]; then
    local us="$2"
    if [ "$us" == "" ]; then
      us="origin"
    fi
    local num="$url"
    local o="$(git config --get remote.${us}.url)"
    url="${o}"
    url="${url#(git:\/\/|https:\/\/)}"
    url="${url#git@}"
    url="${url#github.com[:\/]}"
    url="${url%.git}"
    url="https://github.com/${url}/pull/$num"
  fi
  url=${url%/commits}
  url=${url%/files}
  url="$(echo $url | perl -p -e 's/#issuecomment-[0-9]+$//g')"

  local p='^https:\/\/github.com\/[^\/]+\/[^\/]+\/pull\/[0-9]+$'
  if ! [[ "$url" =~ $p ]]; then
    echo "Usage:"
    echo "  $0 <pull req url>"
    echo "  $0 <pull req number> [<remote name>=origin]"
    type pbpaste &>/dev/null &&
      echo "(will read url/id from clipboard if not specified)"
    exit 1
  fi
  url="${url/https:\/\/github\.com\//git@github.com:}"
  echo "$url"
}

prroot () {
  local url="$1"
  echo "${url/\/pull\/+([0-9])/}"
}

prref () {
  local url="$1"
  local root="$2"
  echo "refs${url:${#root}}/head"
}

main "$@"