X Tutup
Skip to content

Commit 37164de

Browse files
committed
added git_check_branches_upstream.py
1 parent 1855023 commit 37164de

File tree

1 file changed

+135
-0
lines changed

1 file changed

+135
-0
lines changed

git_check_branches_upstream.py

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
#!/usr/bin/env python
2+
# vim:ts=4:sts=4:sw=4:et
3+
#
4+
# Author: Hari Sekhon
5+
# Date: 2016-07-21 16:19:19 +0100 (Thu, 21 Jul 2016)
6+
#
7+
# https://github.com/harisekhon/pytools
8+
#
9+
# License: see accompanying Hari Sekhon LICENSE file
10+
#
11+
# If you're using my code you're welcome to connect with me on LinkedIn
12+
# and optionally send me feedback to help steer this or other code I publish
13+
#
14+
# https://www.linkedin.com/in/harisekhon
15+
#
16+
17+
"""
18+
19+
Tool to check Git branches have their upstream set consistently
20+
21+
Mainly written for my https://github.com/harisekhon/Dockerfiles repo
22+
which has over 100 branches which get merged, pulled and pushed around
23+
24+
"""
25+
26+
from __future__ import absolute_import
27+
from __future__ import division
28+
from __future__ import print_function
29+
#from __future__ import unicode_literals
30+
31+
import os
32+
import re
33+
import sys
34+
import traceback
35+
import git
36+
srcdir = os.path.abspath(os.path.dirname(__file__))
37+
libdir = os.path.join(srcdir, 'pylib')
38+
sys.path.append(libdir)
39+
try:
40+
# pylint: disable=wrong-import-position
41+
from harisekhon.utils import die, ERRORS, log, log_option, uniq_list_ordered, validate_regex
42+
from harisekhon import CLI
43+
except ImportError as _:
44+
print(traceback.format_exc(), end='')
45+
sys.exit(4)
46+
47+
__author__ = 'Hari Sekhon'
48+
__version__ = '0.1'
49+
50+
51+
class GitCheckBranchesUpstream(CLI):
52+
53+
def __init__(self):
54+
# Python 2.x
55+
super(GitCheckBranchesUpstream, self).__init__()
56+
# Python 3.x
57+
# super().__init__()
58+
self.status = "OK"
59+
self.origin = None
60+
self.branch_prefix = None
61+
self.timeout_default = 86400
62+
self.verbose_default = 2
63+
64+
def add_options(self):
65+
self.add_opt('-b', '--branch-prefix', help='Branch prefix regex to check')
66+
self.add_opt('-o', '--origin', help='Origin repo (default: origin)', default='origin')
67+
68+
def run(self):
69+
if not self.args:
70+
self.usage('no git directory args given')
71+
self.origin = self.get_opt('origin')
72+
args = uniq_list_ordered(self.args)
73+
self.branch_prefix = self.get_opt('branch_prefix')
74+
if self.branch_prefix is not None:
75+
validate_regex(self.branch_prefix, 'branch prefix')
76+
self.branch_prefix = re.compile(self.branch_prefix)
77+
for arg in args:
78+
if not os.path.exists(arg):
79+
print("'%s' not found" % arg)
80+
sys.exit(ERRORS['WARNING'])
81+
if os.path.isfile(arg):
82+
log_option('file', arg)
83+
elif os.path.isdir(arg):
84+
log_option('directory', arg)
85+
else:
86+
die("path '%s' could not be determined as either a file or directory" % arg)
87+
for arg in args:
88+
self.check_git_branches_upstream(arg)
89+
if self.status == "OK":
90+
log.info('SUCCESS - All Git branches are tracking the expected upstream origin branches')
91+
else:
92+
log.critical('FAILED - Found Git branches not tracking the expected upstream origin branches')
93+
sys.exit(ERRORS['CRITICAL'])
94+
95+
def check_git_branches_upstream(self, target):
96+
target = os.path.abspath(target)
97+
gitroot = self.find_git_root(target)
98+
if gitroot is None:
99+
die('Failed to find git root for target {0}'.format(target))
100+
log.debug("finding branches for target '{0}'".format(target))
101+
repo = git.Repo(gitroot)
102+
branches = repo.branches
103+
if self.branch_prefix is not None:
104+
log.debug('restricting to branches matching branch prefix')
105+
branches = [x for x in branches if self.branch_prefix.match(str(x))]
106+
#if log.isEnabledFor(logging.DEBUG):
107+
#log.debug('\n\nbranches for target %s:\n\n%s\n', target, '\n'.join(list(branches)))
108+
for branch in branches:
109+
expected = '{0}/{1}'.format(self.origin, branch)
110+
tracking_branch = str(branch.tracking_branch())
111+
if tracking_branch == expected:
112+
log.info("OK: branch '{0}' is tracking '{1}'".format(branch, tracking_branch))
113+
else:
114+
self.status = "ERROR"
115+
log.error("BAD: branch '{0}' is tracking '{1}' (expected '{2}')"
116+
.format(branch, tracking_branch, expected))
117+
118+
# move to pylib and add unit tests
119+
@staticmethod
120+
def find_git_root(target):
121+
target = os.path.abspath(target)
122+
log.debug("finding git root for target '{0}'".format(target))
123+
gitroot = target
124+
while gitroot and gitroot != '/':
125+
log.debug("trying '{0}'".format(gitroot))
126+
# os.path.isdir doesn't work on git submodule Dockerfiles in PyTools repo :-/
127+
if os.path.exists(os.path.join(gitroot, '.git')):
128+
log.debug("found git root for target '{0}': '{1}'".format(target, gitroot))
129+
return gitroot
130+
gitroot = os.path.dirname(gitroot)
131+
return None
132+
133+
134+
if __name__ == '__main__':
135+
GitCheckBranchesUpstream().main()

0 commit comments

Comments
 (0)
X Tutup