blob: 9b3497c718f192075e7ccc6c054e93c507b84631 (
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
168
169
170
171
172
173
|
#!/bin/bash
# Copyright 2014 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
# The "get_hash_for_release" command can be used in one of two forms:
# - It can be used to return the hash associated with the project in
# the current directory:
#
# ~/chromiumos/chromite$ get_hash_for_release 6822.0.0
# 0b325183cf2eee7f93d7d631a8639c089f4a2d4f
# # This is the hash of the "chromite" package for release 6822.0.0
#
# - It can indicate what is the earliest release where a given hash
# appeared:
#
# ~/chromiumos/chromite$ get_hash_for_release R41 \
# 8eba257003357ca945528fb93dadd2c4d16b7d11
# Oldest release with 8eba257003357ca945528fb93dadd2c4d16b7d11 is 6674.0.0
fetch_manifests() {
temp_dir=/tmp/chrome_manifest_temp
if [[ ! -d "${temp_dir}" ]] ; then
mkdir -p "${temp_dir}"
local git_server="https://chrome-internal.googlesource.com"
git clone -q --depth 1 --single-branch \
"${git_server}/chromeos/manifest-versions" "${temp_dir}"
else
(cd "${temp_dir}" && git pull -q)
fi
}
cleanup_manifests() {
if [[ -d "${temp_dir}" ]] ; then
rm -rf "${temp_dir}"
fi
}
is_child_release() {
# Release numbers are stated in a set of dotted integers.
# 2.0.0.0 is a child of 1.0.0.0 (later release)
# 2.1.0.0 is a child of 2.0.0.0 (new branch)
# 3.0.0.0 is a child of 2.0.0.0 but not 2.1.0.0 since 2.1 branched from 2.0.
# 3.0.1.0 isn't really valid (branches are left aligned) but we ignore this.
local child
local parent
IFS='.' read -a child <<< "$1"
IFS='.' read -a parent <<< "$2"
if [[ ${#child[@]} -ne ${#parent[@]} ]] ; then
return 1
fi
local must_be_root
for idx in $(seq 0 $((${#child[@]} - 1))); do
local parent_num="${parent[idx]}"
[[ -n "${must_be_root}" && "$parent_num" != "0" ]] && return 1
local child_num="${child[idx]}"
[[ "${parent_num}" > "${child_num}" ]] && return 1
[[ "${parent_num}" < "${child_num}" ]] && must_be_root=1
done
return 0
}
get_project_info() {
repo info . 2>/dev/null | egrep '^(Project|Current revision):' | cut -f2 -d:
}
get_revision() {
local release="$1"
local revision="$2"
grep "${project}.*upstream=.*${branch}" \
${temp_dir}/buildspecs/$release/${revision}.xml |
sed -e 's/ *<project.*revision="\([^"]*\)".*/\1/' \
-e 's/^.*\/\([0-9.]*\)\.xml:/\1 : /'
}
get_hash_for_release() {
get_revision '*' "${revision}"
}
get_release_for_hash() {
local release="${revision:1}"
local -a all_revs=($(ls "${temp_dir}/buildspecs/${release}" |
sort -Vr | sed -e 's/\.xml$//'))
latest_rev=$(basename $(cd "${temp_dir}/buildspecs/${release}" &&
git log -n1 --name-only --oneline --grep release . |
grep -v ' ' | sort -V | tail -1 |
sed -e 's/\.xml$//'))
revs=()
for rev in "${all_revs[@]}"; do
is_child_release "${latest_rev}" "${rev}" && revs+=("${rev}")
done
last_released_hash=$(get_revision "${release}" "${latest_rev}" |
awk '{print $1}')
if [[ -z "${last_released_hash}" ]] ; then
echo "Huh? Can't find hash for ${latest_rev}"
return
fi
local -a hashes
found=''
for search_size in 10 100 1000 10000; do
hashes=($(git log --pretty=format:%H -n "${search_size}" \
"${last_released_hash}"))
if echo "${hashes[*]}" | grep -q $hash; then
found=1
break
fi
done
if [[ -z "${found}" ]] ; then
echo "Perhaps ${hash} was never in release ${release}?"
return
fi
# Pop all hashes after the one we care about.
while [[ "${hashes[-1]}" != "${hash}" ]] ; do
unset hashes[${#hashes[@]}-1]
done
oldest_release="${latest_rev}"
idx=1
while [[ $idx -lt ${#revs[@]} ]]; do
rev="${revs[idx]}"
hash_for_rev=$(get_revision "${release}" "${rev}" |
awk '{print $1}')
if ! echo "${hashes[*]}" | grep -q $hash_for_rev; then
break
fi
oldest_release="${rev}"
idx=$(( idx + 1 ))
done
echo "Oldest release with ${hash} is ${oldest_release}"
}
main() {
revision="${1}"
if [[ -z "${revision}" ]] ; then
echo "Usage: $0 <revision> [hash]"
exit 0
fi
if expr "${revision}" : '[MR]' > /dev/null; then
hash="${2}"
shift
fi
project_info=($(get_project_info))
if [[ "${#project_info[@]}" < 2 ]] ; then
echo "Couldn't get project info (are you in a repo directory?)"
exit 0
fi
project="${project_info[0]}"
branch="$(echo ${project_info[1]} | cut -d/ -f3)"
if [[ "${branch}" == "master" ]] ; then
branch=""
elif [[ "${branch}" == "chromeos-3.4" ]] ; then
# Hack for old releases of chromeos-kernel.
branch='\.[4B]"'
fi
fetch_manifests
if [[ -z "${hash}" ]] ; then
get_hash_for_release
else
get_release_for_hash
fi
#cleanup_manifests
}
main "$@"
|