summaryrefslogtreecommitdiff
path: root/tools/clone_openstack.sh
blob: c59e66c8c7a5d941561d8bdf7b6ab09ca6577472 (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
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
#!/bin/bash
#
#    Licensed under the Apache License, Version 2.0 (the "License"); you may
#    not use this file except in compliance with the License. You may obtain
#    a copy of the License at
#
#         http://www.apache.org/licenses/LICENSE-2.0
#
#    Unless required by applicable law or agreed to in writing, software
#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
#    License for the specific language governing permissions and limitations
#    under the License.
#
# Check out every active repository from git.openstack.org. For new
# copies, set up git-review. For any existing copies, update their
# remotes and pull changes up to the local master.
#
# This script is based on prior art from mordred on the openstack-dev
# mailing list.
# http://lists.openstack.org/pipermail/openstack-dev/2013-October/017532.html
#
# Usage:
#
#  Check out everything under the current directory:
#    $ clone_openstack.sh
#
#  Check out a specific project (you can list multiple names):
#    $ clone_openstack.sh openstack/oslo-incubator
#

trouble_with=""
branched=""

# Figure out if git-hooks is installed and should be used.
# https://github.com/icefox/git-hooks
which git-hooks 2>&1 > /dev/null
USE_GIT_HOOKS=$?

# Users can set INCLUDE_STACKFORGE=1 if they want to always check out
# new copies of stackforge projects.
INCLUDE_STACKFORGE=${INCLUDE_STACKFORGE:-0}

# If we have any trouble at all working with a repository, report that
# and then record the name for the summary at the end.
function track_trouble {
    if [ $1 -ne 0 ]
    then
        echo "Remembering trouble with $2"
        trouble_with="$trouble_with $2"
    fi
}

# Determine the current branch of a local repository.
function current_branch {
    (cd $1 && git rev-parse --abbrev-ref HEAD)
}

# Print a summary report for any repositories that had trouble
# updating.
function report_trouble {
    if [ ! -z "$trouble_with" ]
    then
        echo
        echo "Had trouble updating:"
        for r in $trouble_with
        do
            echo "  $r - $(current_branch $r)"
        done
    fi
}

# Print a summary report for any repositories that were not on the
# master branch when we updated them.
function report_branched {
    if [ ! -z "$branched" ]
    then
        echo
        echo "Branched repos:"
        for r in $branched
        do
            echo "  $r - $(current_branch $r)"
        done
    fi
}

# Check out a new copy of a repository and set it up to be a useful
# local copy.
function clone_new {
    typeset repo="$1"
    typeset url="$2"
    # Ignore stackforge projects unless told otherwise.
    if [[ $repo =~ ^stackforge/.* ]]
    then
        if [ $INCLUDE_STACKFORGE -ne 1 ]
        then
            return 0
        fi
    fi
    echo
    echo "Cloning $repo"
    git clone $url $repo
    (cd $repo && git review -s)
    if [ $USE_GIT_HOOKS -eq 0 ]
    then
        echo "Configuring git hooks"
        (cd $repo && git hooks --install)
    fi
    return 0
}

# Update an existing copy of a repository, including all remotes and
# pulling into the local master branch if we're on that branch
# already.
function update_existing {
    typeset repo="$1"
    echo
    echo "Updating $repo"
    (cd $repo && git remote update)
    RC=$?
    if [ $RC -ne 0 ]
    then
        return $RC
    fi
    # Only run git pull for repos where I'm not working in a branch.
    typeset b=$(current_branch $repo)
    if [ $b == "master" ]
    then
        if (cd $repo && git diff --exit-code >/dev/null)
        then
            (cd $repo && git pull)
        else
            echo "Skipping pull for master branch with local changes"
            (cd $repo && git status)
        fi
    else
        echo "Skipping pull for branch $b"
        branched="$branched $repo"
    fi
}

# Process a single repository found in gerrit, determining whether it
# exists locally already or not.
function get_one_repo {
    typeset repo="$1"
    typeset url="$2"
    typeset pardir=$(dirname $repo)
    if [ ! -z "$pardir" ]
    then
        mkdir -p $pardir
    fi
    if [ ! -d $repo ] ; then
        clone_new $repo $url
    else
        update_existing $repo
    fi
    RC=$?
    return $RC
}

# If we are given a list of projects on the command line, we will only
# work on those. Otherwise, ask gerrit for the full list of openstack
# projects, ignoring the ones in the attic. Stackforge projects are
# ignored if they do not exist locally, so we include them in the
# output list and check for them when we decide what to do with each
# repository.
projects="$*"
if [ -z "$projects" ]
then
    projects=$(ssh review.openstack.org -p 29418 gerrit ls-projects | grep -v 'attic')
    RC=$?
    if [ $RC -ne 0 ]
    then
        echo "Unable to obtain a list of projects from gerrit. Check your ssh credientials for review.openstack.org"
        userid=`id -un`
        gerrit_userid=`git config --get gitreview.username`
        if [ $userid != $gerrit_userid ]
        then
            echo "Identified a possible userid difference between $userid and $gerrit_userid"
        fi
        exit $RC
    fi
else
    # Go ahead and set things up so we will work with stackforge
    # repositories, in case the caller has specified one on the
    # command line.
    INCLUDE_STACKFORGE=1
fi

for repo in $projects; do
    get_one_repo $repo git://git.openstack.org/$repo
    track_trouble $? $repo
done

report_branched
report_trouble