1#!/usr/bin/env bash
2#===- llvm/utils/docker/scripts/checkout.sh ---------------------===//
3#
4# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5# See https://llvm.org/LICENSE.txt for license information.
6# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7#
8#===-----------------------------------------------------------------------===//
9
10set -e
11
12function show_usage() {
13  cat << EOF
14Usage: checkout.sh [options]
15
16Checkout svn sources into /tmp/clang-build/src. Used inside a docker container.
17
18Available options:
19  -h|--help           show this help message
20  -b|--branch         svn branch to checkout, i.e. 'trunk',
21                      'branches/release_40'
22                      (default: 'trunk')
23  -r|--revision       svn revision to checkout
24  -c|--cherrypick     revision to cherry-pick. Can be specified multiple times.
25                      Cherry-picks are performed in the sorted order using the
26                      following command:
27                      'svn patch <(svn diff -c \$rev)'.
28  -p|--llvm-project   name of an svn project to checkout.
29                      For clang, please use 'clang', not 'cfe'.
30                      Project 'llvm' is always included and ignored, if
31                      specified.
32                      Can be specified multiple times.
33EOF
34}
35
36LLVM_SVN_REV=""
37CHERRYPICKS=""
38LLVM_BRANCH=""
39# We always checkout llvm
40LLVM_PROJECTS="llvm"
41
42function contains_project() {
43  local TARGET_PROJ="$1"
44  local PROJ
45  for PROJ in $LLVM_PROJECTS; do
46    if [ "$PROJ" == "$TARGET_PROJ" ]; then
47      return 0
48    fi
49  done
50  return 1
51}
52
53while [[ $# -gt 0 ]]; do
54  case "$1" in
55    -r|--revision)
56      shift
57      LLVM_SVN_REV="$1"
58      shift
59      ;;
60    -c|--cherrypick)
61      shift
62      CHERRYPICKS="$CHERRYPICKS $1"
63      shift
64      ;;
65    -b|--branch)
66      shift
67      LLVM_BRANCH="$1"
68      shift
69      ;;
70    -p|--llvm-project)
71      shift
72      PROJ="$1"
73      shift
74
75      if [ "$PROJ" == "cfe" ]; then
76        PROJ="clang"
77      fi
78
79      if ! contains_project "$PROJ" ; then
80        if [ "$PROJ" == "clang-tools-extra" ] && [ ! contains_project "clang" ]; then
81          echo "Project 'clang-tools-extra' specified before 'clang'. Adding 'clang' to a list of projects first."
82          LLVM_PROJECTS="$LLVM_PROJECTS clang"
83        fi
84        LLVM_PROJECTS="$LLVM_PROJECTS $PROJ"
85      else
86        echo "Project '$PROJ' is already enabled, ignoring extra occurrences."
87      fi
88      ;;
89    -h|--help)
90      show_usage
91      exit 0
92      ;;
93    *)
94      echo "Unknown option: $1"
95      exit 1
96  esac
97done
98
99if [ "$LLVM_BRANCH" == "" ]; then
100  LLVM_BRANCH="trunk"
101fi
102
103if [ "$LLVM_SVN_REV" != "" ]; then
104  SVN_REV_ARG="-r$LLVM_SVN_REV"
105  echo "Checking out svn revision r$LLVM_SVN_REV."
106else
107  SVN_REV_ARG=""
108  echo "Checking out latest svn revision."
109fi
110
111# Sort cherrypicks and remove duplicates.
112CHERRYPICKS="$(echo "$CHERRYPICKS" | xargs -n1 | sort | uniq | xargs)"
113
114function apply_cherrypicks() {
115  local CHECKOUT_DIR="$1"
116
117  [ "$CHERRYPICKS" == "" ] || echo "Applying cherrypicks"
118  pushd "$CHECKOUT_DIR"
119
120  # This function is always called on a sorted list of cherrypicks.
121  for CHERRY_REV in $CHERRYPICKS; do
122    echo "Cherry-picking r$CHERRY_REV into $CHECKOUT_DIR"
123
124    local PATCH_FILE="$(mktemp)"
125    svn diff -c $CHERRY_REV > "$PATCH_FILE"
126    svn patch "$PATCH_FILE"
127    rm "$PATCH_FILE"
128  done
129
130  popd
131}
132
133CLANG_BUILD_DIR=/tmp/clang-build
134
135# Get the sources from svn.
136echo "Checking out sources from svn"
137mkdir -p "$CLANG_BUILD_DIR/src"
138for LLVM_PROJECT in $LLVM_PROJECTS; do
139  if [ "$LLVM_PROJECT" == "clang" ]; then
140    SVN_PROJECT="cfe"
141  else
142    SVN_PROJECT="$LLVM_PROJECT"
143  fi
144
145  if [ "$SVN_PROJECT" != "clang-tools-extra" ]; then
146    CHECKOUT_DIR="$CLANG_BUILD_DIR/src/$LLVM_PROJECT"
147  else
148    CHECKOUT_DIR="$CLANG_BUILD_DIR/src/clang/tools/extra"
149  fi
150
151  echo "Checking out https://llvm.org/svn/llvm-project/$SVN_PROJECT to $CHECKOUT_DIR"
152  svn co -q $SVN_REV_ARG \
153    "https://llvm.org/svn/llvm-project/$SVN_PROJECT/$LLVM_BRANCH" \
154    "$CHECKOUT_DIR"
155
156  # We apply cherrypicks to all repositories regardless of whether the revision
157  # changes this repository or not. For repositories not affected by the
158  # cherrypick, applying the cherrypick is a no-op.
159  apply_cherrypicks "$CHECKOUT_DIR"
160done
161
162CHECKSUMS_FILE="/tmp/checksums/checksums.txt"
163
164if [ -f "$CHECKSUMS_FILE" ]; then
165  echo "Validating checksums for LLVM checkout..."
166  python "$(dirname $0)/llvm_checksum/llvm_checksum.py" -c "$CHECKSUMS_FILE" \
167    --partial --multi_dir "$CLANG_BUILD_DIR/src"
168else
169  echo "Skipping checksumming checks..."
170fi
171
172echo "Done"
173