File: UpdateThirdPartyFromUpstream.sh

package info (click to toggle)
insighttoolkit4 4.13.3withdata-dfsg1-4
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 489,260 kB
  • sloc: cpp: 557,342; ansic: 146,850; fortran: 34,788; python: 16,572; sh: 2,187; lisp: 2,070; tcl: 993; java: 362; perl: 200; makefile: 129; csh: 81; pascal: 69; xml: 19; ruby: 10
file content (210 lines) | stat: -rw-r--r-- 8,154 bytes parent folder | download | duplicates (3)
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
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
# This file should not have its executable bit set.

# This script should not be run directly. Instead, create an executable file
# "UpdateFromUpstream.sh", which defines the following shell variables:
#
#   - thirdparty_module_name :
#       The name of the ThirdParty module to be updated. This must match the
#       name of the ITK ThirdParty module's base directory (which contains
#       "itk-module.cmake").
#       i.e. "Modules/ThirdParty/<thirdparty_module_name>/itk-module.cmake"
#   - upstream_git_url :
#       The full URL (including the scheme) of the upstream Git repository
#       that the ThirdParty module tracks.
#   - upstream_git_branch :
#      The upstream Git branch name that the ThirdParty module tracks.
#   - snapshot_author_name :
#      The author name to which the upstream files should be attributed,
#      in ITK's Git repository.
#   - snapshot_author_email :
#      The author email to which the upstream files should be attributed.
#      in ITK's Git repository.
#   - snapshot_redact_cmd :
#      A string, containing a command to be eval'd within the CWD of the fresh
#      upstream snapshot, in order to prepare it for being committed to ITK's
#      repository. The string may be empty or contain multiple commands chained
#      with "&&", etc. The command typically removes extraneous files
#      or directories that shouldn't be committed to ITK for size, simplicity,
#      or licensing reasons.
#   - snapshot_relative_path :
#      The path, relative to the ThirdParty module's base directory, that
#      the upstream snapshot's file should be merged into.
#      e.g. "src/mylib/"
#   - snapshot_paths :
#      An optional list of file patterns to be included in the snapshot. E.g.
#        snapshot_paths='
#         dir1
#         dir2/*.c
#         file1.txt
#        '
#
# The script, "UpdateFromUpstream.sh", must be located in the associated
# ThirdParty module's base directory.
#

die()
{
  echo "Error: $@" 1>&2
  exit 1
}

update_from_upstream()
{
## Set up paths ##
local module_path=$( cd "$( dirname "$0" )" && pwd )
local toplevel_path=$(cd "$module_path" && git rev-parse --show-toplevel)
if [[ $? -ne 0 ]]; then
  die "Could not find the top-level of a Git repository in \"$module_path\""
fi
cd "$toplevel_path"


## Validate ##
local required_commands=( git grep sed egrep tar dirname basename tr )
for required_command in ${required_commands[@]}; do
  type -p $required_command >/dev/null 2>&1
  if [[ $? -ne 0 ]]; then
    die "Command \"$required_command\" not found"
  fi
done

local input_variables=( thirdparty_module_name snapshot_relative_path \
                        upstream_git_url upstream_git_branch \
                        snapshot_author_name snapshot_author_email \
                        snapshot_relative_path )
for input_variable in ${input_variables[@]}; do
  if [[ -z $(eval echo "\$$input_variable") ]]; then
    die "\$$input_variable must be set"
  fi
done

local module_path_basename=$(basename "$module_path")
if [[ "$thirdparty_module_name" != "$module_path_basename" ]]; then
  die "The script \"$0\" must be in the base directory for the \"$thirdparty_module_name\" module"
fi


## Old snapshot commit ##
local regex_date='20[0-9][0-9]-[0-9][0-9]-[0-9][0-9]'
local snapshot_old_regex="$thirdparty_module_name $regex_date ([0-9a-f]*)"
local snapshot_old_sha=$(git rev-list --author="$snapshot_author_email" --grep="$snapshot_old_regex" -n 1 HEAD)
if [[ -z "$snapshot_old_sha" ]]; then
  read -ep "Create a new snapshot branch? [N/y]: " create_new
  if [[ "$create_new" != "y" && "$create_new" != "Y" ]]; then
    die "Could not find previous snapshot."
  fi
fi

## New upstream commit ##
git fetch --quiet "$upstream_git_url" "$upstream_git_branch" 2> >(sed '/warning: no common commits/d' >&2)
if [[ $? -ne 0 ]]; then
  die "Could not \"git fetch\" from $upstream_git_url:$upstream_git_branch"
fi
local upstream_new_sha=$(git rev-parse FETCH_HEAD)
local upstream_new_sha_short=$(git rev-parse --short=8 $upstream_new_sha)
local upstream_new_datetime=$(git rev-list $upstream_new_sha --format='%ci' -n 1 | grep "^$regex_date")
local upstream_new_date=$(echo "$upstream_new_datetime" | grep -o "$regex_date")


## Old upstream commit ##
if [[ -n "$snapshot_old_sha" ]]; then
  local upstream_old_sha_short=$(
    git cat-file commit $snapshot_old_sha |
    sed -n '/'"$snapshot_old_regex"'/ {s/.*(//;s/)//;p;}' |
    egrep '^[0-9a-f]+$'
  )
  local upstream_old_sha=$(git rev-parse --verify -q "$upstream_old_sha_short")
fi
if [[ "$upstream_old_sha" == "$upstream_new_sha" ]]; then
  echo 'Upstream has no updates'
  exit 0
fi


## New shapshot tree ##
local snapshot_branch_name=`echo "upstream-${thirdparty_module_name}" | tr '[:upper:]' '[:lower:]'` # make string lowercase
local snapshot_temp_dir="$snapshot_branch_name"
local snapshot_temp_path="$toplevel_path/$snapshot_temp_dir/"
local snapshot_temp_index="$toplevel_path/$snapshot_branch_name.index"
rm -rf "$snapshot_temp_path" "$snapshot_temp_index"
cd "$toplevel_path" && git archive --prefix="$snapshot_temp_dir/" $upstream_new_sha -- $snapshot_paths | tar x
( cd "$snapshot_temp_path" && eval "$snapshot_redact_cmd" )
if [[ $? -ne 0 ]]; then
  rm -rf "$snapshot_temp_path" "$snapshot_temp_index"
  die 'Could not eval $snapshot_redact_cmd in upstream snapshot'
fi
local snapshot_new_tree=$(
  GIT_WORK_TREE="$snapshot_temp_path" &&
  GIT_INDEX_FILE="$snapshot_temp_index" &&
  export GIT_WORK_TREE GIT_INDEX_FILE &&
  git add --all &&
  git write-tree
)
rm -rf "$snapshot_temp_path" "$snapshot_temp_index"


## New shapshot commit ##
if [[ -z "$snapshot_old_sha" ]]; then
  local snapshot_new_shortlog="Initial import of $upstream_new_sha"
  local snapshot_new_change_id=$(git commit-tree $snapshot_new_tree </dev/null)
  local snapshot_log_command=""
else
  local snapshot_new_change_id=$(git commit-tree $snapshot_new_tree -p $snapshot_old_sha </dev/null)
  if [[ $github_compare == true ]]; then
    local snapshot_log_command=""
    local snapshot_new_shortlog="${upstream_git_url%.*}/compare/$(git rev-list $upstream_old_sha -n 1)...$upstream_new_sha"
  else
    local snapshot_new_shortlog=$(git shortlog --perl-regexp --author='^((?!Kitware Robot).*)$' --no-merges --abbrev=8 --format='%h %s' $upstream_old_sha..$upstream_new_sha)
    local snapshot_log_command="\$ git shortlog --perl-regexp --author='^((?!Kitware Robot).*)$' --no-merges --abbrev=8 --format='%h %s' $upstream_old_sha_short..$upstream_new_sha_short"
  fi
fi

local snapshot_new_commit_msg="$thirdparty_module_name $upstream_new_date ($upstream_new_sha_short)

Run the UpdateFromUpstream.sh script to extract upstream $thirdparty_module_name
using the following shell commands.

\$ git archive --prefix=$snapshot_branch_name/ $upstream_new_sha_short -- $snapshot_paths | tar x
$snapshot_log_command

$snapshot_new_shortlog

Change-Id: I$snapshot_new_change_id"
if [[ -z "$snapshot_old_sha" ]]; then
  local snapshot_new_sha=$(
    echo "$snapshot_new_commit_msg" |
    GIT_AUTHOR_NAME="$snapshot_author_name" \
    GIT_AUTHOR_EMAIL="$snapshot_author_email" \
    GIT_AUTHOR_DATE="$upstream_new_datetime" \
    git commit-tree $snapshot_new_tree
  )
else
  local snapshot_new_sha=$(
    echo "$snapshot_new_commit_msg" |
    GIT_AUTHOR_NAME="$snapshot_author_name" \
    GIT_AUTHOR_EMAIL="$snapshot_author_email" \
    GIT_AUTHOR_DATE="$upstream_new_datetime" \
    git commit-tree $snapshot_new_tree -p $snapshot_old_sha
  )
fi


## New shapshot branch ##
git update-ref refs/heads/$snapshot_branch_name $snapshot_new_sha
local module_relative_path=${module_path#"$toplevel_path/"}
echo "Created upstream snapshot branch '$snapshot_branch_name'."
if [[ -z "$snapshot_old_sha" ]]; then
    echo "Perform initial merge with commands:

    cd \"$toplevel_path\" &&
    git merge -s ours --no-commit $snapshot_branch_name &&
    git read-tree -u --prefix=$module_relative_path/$snapshot_relative_path/ $snapshot_branch_name &&
    git commit
"
else
    cd "$toplevel_path" &&
    git merge -X subtree=$module_relative_path/$snapshot_relative_path $snapshot_branch_name
    git branch -d "$snapshot_branch_name"
fi

}