-
Notifications
You must be signed in to change notification settings - Fork 8
/
updateRepos.py
executable file
·261 lines (201 loc) · 8.3 KB
/
updateRepos.py
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
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
#!/usr/bin/env python
# __BEGIN_LICENSE__
# Copyright (c) 2009-2013, United States Government as represented by the
# Administrator of the National Aeronautics and Space Administration. All
# rights reserved.
#
# The NGT platform is 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.
# __END_LICENSE__
import sys
import os, glob, optparse, re, shutil, subprocess, string, time
#import git
def man(option, opt, value, parser):
print >>sys.stderr, parser.usage
print >>sys.stderr, '''Tool for managing lronac pipeline production data'''
sys.exit()
class Usage(Exception):
def __init__(self, msg):
self.msg = msg
#--------------------------------------------------------------------------------
# All status information is saved in this folder
VW_FOLDER = '/home/smcmich1/repo/visionworkbench'
ASP_FOLDER = '/home/smcmich1/repo/StereoPipeline'
TOOLS_FOLDER = '/home/smcmich1/repo/Tools'
TOOLS_B_FOLDER = '/home/smcmich1/repo/ToolsBuild'
LRO_FOLDER = '/home/smcmich1/repo/lronacPipeline'
LRO_B_FOLDER = '/home/smcmich1/repo/lronacPipelineBuild'
#
#def updateRepo(repoFolder, buildFolder):
# """Updates the contents of a repository"""
#
# # Account for in-place builds
# if not buildFolder:
# buildFolder = repoFolder
#
# # Set up repo object
# repoName = os.path.basename(repoFolder)
# repo = git.Repo(repoFolder)
#
# # Up to the user to handle local changes
# if repo.is_dirty():
# raise Exception('Cant operate on dirty repo ' + repoName)
#
#
# # Find the upstream and origin remotes and fetch
# upstreamRemote = None
# originRemote = None
# for r in repo.remotes:
# if r.name == 'upstream':
# upstreamRemote = r
# if r.name == 'origin':
# originRemote = r
#
# if not originRemote: # Upstream remote is optional
# raise Exception('Failed to find origin remote!')
#
# if upstreamRemote:
# upstreamRemote.pull('--rebase')
# #fetchResult = r.fetch()
# #for f in fetchResult:
# # print f
#
#
#
class GitRepo:
"""Class for working with a git repository"""
_gitFolder = ''
_repoFolder = ''
def __init__(self, folder):
"""Constructor"""
self._repoFolder = folder
self._gitFolder = os.path.join(folder, '.git/')
def callGitCommand(self, gitCommandList):
"""Calls a set of git commands on a folder and returns the output text"""
# Get the tag using a subprocess call
cmd = ['git', '--git-dir', self._gitFolder, '--work-tree', self._repoFolder]
cmd = cmd + gitCommandList
#print cmd
p = subprocess.Popen(cmd, stdout=subprocess.PIPE)
textOutput, err = p.communicate()
return textOutput
def getBranch(self):
"""Returns the name of the current branch"""
textOutput = self.callGitCommand(['branch'])
for line in textOutput.split('\n'):
if line.startswith('*'):
return line[2:]
raise Exception('Unable to determine branch!')
def isDirty(self):
"""Returns True if the repo is dirty"""
textOutput = self.callGitCommand(['status'])
return (textOutput.find('Changes not staged for commit') >= 0)
def hasUpstreamRemote(self):
"""Returns True the repo has an upstream source"""
textOutput = self.callGitCommand(['remote'])
return (textOutput.find('upstream') >= 0)
def updateRepo(repoFolder, buildFolder):
"""Updates the contents of a repository"""
print 'Updating repository: ' + repoFolder
# Account for in-place builds
if not buildFolder:
buildFolder = repoFolder
# Set up repo object
repo = GitRepo(repoFolder)
if repo.isDirty():
raise Exception('TODO: Repo dirty! Add stash functionality!')
if repo.getBranch() != 'master':
raise Exception('TODO: Not master branch! Add branch functionality!')
fetchedAnything = False
if repo.hasUpstreamRemote():
print 'Fetching updates from upstream...'
# Fetch from the upstream remote if it exists
upstreamFetchText = repo.callGitCommand(['fetch', 'upstream'])
# If we pulled down anything new, rebase on to it
if len(upstreamFetchText) > 10: # If we fetched anything
fetchedAnything = True
print 'Rebasing on to upstream updates...'
upstreamRebaseText = repo.callGitCommand(['rebase', 'upstream/master'])
if (upstreamRebaseText.find('conflict') >= 0):
print upstreamRebaseText
raise Exception('Found merge conflict in upstream rebase!')
# Fetch from the origin remote
print 'Fetching updates from origin...'
originFetchText = repo.callGitCommand(['fetch', 'origin'])
# If we pulled down anything new, rebase on to it
if len(originFetchText) > 10: # If we fetched anything
fetchedAnything = True
print 'Rebasing on to origin updates...'
originRebaseText = repo.callGitCommand(['rebase', 'origin/master'])
if (originRebaseText.find('conflict') >= 0):
print originRebaseText
raise Exception('Found merge conflict in origin rebase!')
# If we didn't get any new code we are finished!
if not fetchedAnything:
print 'Did not fetch any new updates, finished with ' + repoFolder
return True
# At this point our code should be up to date, try to build
# Move to build folder
cmd = 'cd ' + buildFolder
os.system(cmd)
# Build!
cmd = ['make', '-j', '8']
p = subprocess.Popen(cmd, stdout=subprocess.PIPE)
makeOutput, err = p.communicate()
if (makeOutput.find('make: *** [all] Error') >= 0):
raise Exception('Error building on folder ' + buildFolder)
# TODO: Don't do this if we didn't get new code
if buildFolder == repoFolder: # This is a hack for my repositories!
# Try calling installation
cmd = 'make install '
os.system(cmd)
# TODO: Is there a way to check this?
return True
def main():
#
#try:
# try:
# usage = "usage: archiveManager.py [--help][--manual]\n "
# parser = optparse.OptionParser(usage=usage)
#
# parser.add_option("--find-pbs", dest="pbsName",
# help="Get the full path to the data set for a PBS job.",
# default=None)
#
#
# parser.add_option("--flag-incomplete", action="store_true",
# dest="flagIncomplete", default=False,
# help="Flag incomplete data sets for repeat processing.")
#
# parser.add_option("--clear", action="store_true", dest="clear", default=False,
# help="Clear files after archiving them.")
#
# parser.add_option("--dry-run", action="store_true", dest="dryRun", default=False,
# help="Don't touch any data, just display actions to be taken.")
#
# parser.add_option("--manual", action="callback", callback=man,
# help="Read the manual.")
# (options, args) = parser.parse_args()
#
# except optparse.OptionError, msg:
# raise Usage(msg)
repoList = [(VW_FOLDER, None),
(ASP_FOLDER, None),
(TOOLS_FOLDER, TOOLS_B_FOLDER),
(LRO_FOLDER, LRO_B_FOLDER)]
for r in repoList:
updateRepo(r[0], r[1])
return 0
#except Usage, err:
# print >>sys.stderr, err.msg
# return 2
if __name__ == "__main__":
sys.exit(main())