Upstream version 8.36.161.0
[platform/framework/web/crosswalk.git] / src / third_party / chromite / scripts / cros_mirror
1 #!/bin/bash
2 # Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file.
5
6 # Note:
7 # We do *not* source any other files as this is meant to be used as a
8 # standalone helper script with no other dependencies.  So please do
9 # not try to refactor this to rely on anything else.
10
11 ARGV0="cros_mirror"
12
13 MANIFEST_URL_EXT='https://chromium.googlesource.com/chromiumos/manifest.git'
14 MANIFEST_URL_INT='https://chrome-internal.googlesource.com/chromeos/manifest-internal.git'
15 REPO_URL='https://chromium.googlesource.com/external/repo.git'
16 # When we make commits to manifest git repos, we want the owner info to be the
17 # same, and we want it to map to info that end users are unlikely to use.  That
18 # way when the local repo rebase runs, it handles the update gracefully.
19 export GIT_AUTHOR_NAME='Elmur Fudsicle' GIT_AUTHOR_EMAIL='<baba@booya.bizzle>'
20
21 set -e
22
23 #
24 # Helper functions.
25 #
26 info() {
27   if [[ -z ${QUIET} ]]; then
28     echo "info: $*"
29   fi
30 }
31
32 error() {
33   echo "error: $*" >&2
34 }
35
36 die() {
37   error "$*"
38   exit 1
39 }
40
41 _pushd() { pushd "$@" >/dev/null; }
42 _popd()  { popd "$@" >/dev/null; }
43
44 #
45 # Process user flags.
46 #
47 usage() {
48   cat <<EOF
49 Create or maintain a mirror of the ChromiumOS repository.
50
51 Usage: ${ARGV0} [options] --root <dir>
52
53 Options:
54   --external          Pull the external ChromiumOS manifest
55   --internal          Pull the internal ChromeOS manifest (note: Googler-only)
56   -j, --jobs          Number of fetch jobs to run in parallel (default ${JOBS})
57   -q, --quiet         Be quiet!
58   -r, --root          The directory to hold all mirroring information
59   -u, --url           The URL that people will use to pull from this mirror
60   -m, --manifest      The repo manifest to use as a basis (default default.xml)
61   -h, --help          This!
62
63 You must specify the --url option at least once so that all of the paths can
64 be rewritten for external users.  After that, it should be automatically saved
65 and restored at runtime by this script.
66
67 Example:
68 # Create a full mirror in \${PWD} and have users fetch from the local machine.
69 \$ ${ARGV0} -r . -u git://$(hostname -f)
70 # Update the mirror (put this into a cronjob).
71 \$ ${ARGV0} -q -r ${ROOT:-${PWD}}
72
73 See this page for more information:
74 http://dev.chromium.org/chromium-os/how-tos-and-troubleshooting/creating-local-mirrors
75 EOF
76   exit ${1:-0}
77 }
78
79 JOBS=$(getconf _NPROCESSORS_ONLN 2>/dev/null || echo 4)
80 MANIFEST_URL=
81 MANIFEST_NAME=default.xml
82 QUIET=
83 ROOT=
84 URL=
85 while [[ $# -gt 0 ]]; do
86   case $1 in
87   --external)       MANIFEST_URL=${MANIFEST_URL_EXT};;
88   --internal)       MANIFEST_URL=${MANIFEST_URL_INT};;
89   -j|--jobs)        JOBS=$2; shift;;
90   -q|--quiet)       QUIET="-q";;
91   -r|--root)        ROOT=$2; shift;;
92   -u|--url)         URL=$2; shift;;
93   -m|--manifest)    MANIFEST_NAME=$2; shift;;
94   -h|--help)        usage;;
95   -x)               set -x;;
96   *)                usage 1;;
97   esac
98   shift
99 done
100
101 if [[ -z ${ROOT} ]]; then
102   die "need to specify root dir with --root"
103 fi
104 if [[ ! -d ${ROOT} ]]; then
105   die "specified root dir does not exist; please run: mkdir '${ROOT}'"
106 fi
107
108 cd "${ROOT}"
109
110 #
111 # Make sure our tools are up-to-date.
112 #
113 if ! which repo >/dev/null; then
114   die "you must have repo installed and in your \$PATH; please see:" \
115       "http://dev.chromium.org/developers/how-tos/install-depot-tools"
116 fi
117 # This has been tested against 1.7.7.x, so require at least that.
118 if ! gver=$(git --version); then
119   die "you must have git installed!"
120 fi
121 bver="1.7.7"
122 ver_to_int() {
123   local v i=0
124   local ver=( $(echo $(IFS=.; echo $*)) )
125   for v in 0 1 2; do
126     : $(( i = (i << 8) | ${ver[v]} ))
127   done
128   echo ${i}
129 }
130 if [[ $(ver_to_int "${bver}") -gt $(ver_to_int "${gver##* }") ]]; then
131   die "your git version is too old (${gver}); we require at least git ${bver}"
132 fi
133
134
135 #
136 # Initialize the whole tree mirror style.
137 #
138 repo_init() {
139   repo init -u "${MANIFEST_URL}" -m "${MANIFEST_NAME}" \
140     --repo-url="${REPO_URL}" ${QUIET} "$@"
141 }
142 if [[ ! -d .repo ]]; then
143   # Default to external manifest.
144   : ${MANIFEST_URL:=${MANIFEST_URL_EXT}}
145   repo_init --mirror
146 else
147   # Allow people to change manifests on the fly (internal<->external).
148   CURRENT_URL=$(git --git-dir=.repo/manifests.git config remote.origin.url)
149   # Find the previously defined manifest name by following the symbolic link.
150   CURRENT_NAME=$(readlink .repo/manifest.xml)
151   # Strip off the "manifests/" prefix.
152   CURRENT_NAME=${CURRENT_NAME#manifests/}
153   # If no manifest was selected, default to the current one.
154   : ${MANIFEST_URL:=${CURRENT_URL}}
155   if [[ "${CURRENT_URL}" != "${MANIFEST_URL}" || \
156         "${CURRENT_NAME}" != "${MANIFEST_NAME}" ]]; then
157     info "re-initing due to URL or manifest change: \
158       ${CURRENT_URL} -> ${MANIFEST_URL}, ${CURRENT_NAME} -> ${MANIFEST_NAME}"
159     repo_init
160   fi
161 fi
162 if [[ ! -e git ]]; then
163   ln -s . git
164 fi
165
166 #
167 # Pull down any updates.
168 #
169 info "syncing the whole tree"
170 repo sync -j${JOBS} ${QUIET}
171
172 #
173 # Setup our local manifests repo which we'll hack on to point
174 # to our local mirror.  We can't modify the repo in place as
175 # we want to make sure updates are atomic -- don't want other
176 # people to be able to accidentally pull in an unmodified repo.
177 #
178 update_manifests() {
179   local git_repo=$1
180   local checkout=${git_repo##*/}
181   checkout=${checkout%.git}
182
183   if [[ ${MANIFEST_URL} == "${MANIFEST_URL_INT}" ]]; then
184     # Try to head off leakage of Google data.
185     case ${URL} in
186     ssh://* | file://*) ;;
187     *)
188       die "You *must* use a secure channel like ssh:// or file://" \
189           "when mirroring internal Google repositories."
190       ;;
191     esac
192   fi
193
194   if [[ ! -d ${checkout} ]]; then
195     info "cloning ${checkout}"
196     git clone ${QUIET} ./${git_repo} ${checkout}
197     # Make the path relative so the whole tree can be moved w/out breaking.
198     git --git-dir=${checkout}/.git config remote.origin.url ../${git_repo}
199   fi
200
201   info "updating ${checkout}"
202   _pushd ${checkout}
203   git fetch ${QUIET}
204   if [[ -z ${URL} ]]; then
205     # Extract the local URI if they didn't specify one.
206     URL=$(eval $(grep -h fetch= *.xml); echo ${fetch})
207     if [[ ${URL} == "https://chromium.googlesource.com" ]]; then
208       # Guess they want the current system.
209       URL="git://$(hostname -f)"
210     fi
211   fi
212
213   # Setup the fetch= field of the manifest to point to our local mirror.
214   local b branches=(
215     $(git ls-remote | sed 's:.*/::' | egrep -v '\<(HEAD|^master)$')
216     "master"
217   )
218   info "rewriting ${checkout} branches to ${URL}"
219   for b in "${branches[@]}"; do
220     git checkout -q -f -B ${b} origin/${b} >/dev/null
221     find -name '*.xml' -type f \
222       -exec sed -i "s|fetch=\"[^\"]*\"|fetch=\"${URL}\"|" {} +
223     git commit -q -a -m 'set fetch references to local mirror'
224   done
225
226   # Push out our updates.
227   local pub="../${git_repo%.git}-mirror.git"
228   if [[ ! -e ${pub} ]]; then
229     git --git-dir="${pub}" init ${QUIET}
230   fi
231   git push ${QUIET} -f "${pub}" 'refs/heads/*:refs/heads/*'
232   _popd
233 }
234 update_manifests chromiumos/manifest.git
235 if [[ ${MANIFEST_URL} == "${MANIFEST_URL_INT}" ]]; then
236   update_manifests chromeos/manifest-internal.git
237 fi
238
239 #
240 # All done!
241 #
242 if [[ -z ${QUIET} ]]; then
243   if [[ ${MANIFEST_URL} == "${MANIFEST_URL_EXT}" ]]; then
244     cat <<EOF
245
246 You can now serve this tree with:
247 git daemon --base-path=${ROOT} --export-all
248
249 Your users can pull from this mirror with:
250 repo init -u ${URL}/chromiumos/manifest-mirror.git --repo-url=${URL}/external/repo.git
251 EOF
252   else
253     cat <<EOF
254
255 You must only serve these resources over encrypted channels like ssh://.
256
257 Your users can pull from this mirror with:
258 repo init -u ${URL}/chromeos/manifest-internal-mirror.git --repo-url=${URL}/external/repo.git
259 EOF
260   fi
261 fi