summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDamien Lespiau <damien.lespiau@intel.com>2012-07-31 00:24:11 +0100
committerDamien Lespiau <damien.lespiau@intel.com>2012-07-31 00:24:11 +0100
commita7cdce28c5c29ec5d6f5f165d3df3fc81289861a (patch)
treed2fc3a72e7f26fea3647efd20d9e14300f228960
Initial commit
-rw-r--r--.gitignore1
-rwxr-xr-xintel-submit-build171
2 files changed, 172 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..45d62d8
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+*.sw?
diff --git a/intel-submit-build b/intel-submit-build
new file mode 100755
index 0000000..afd17ed
--- /dev/null
+++ b/intel-submit-build
@@ -0,0 +1,171 @@
+#!/usr/bin/python -tt
+# vim: ai ts=4 sts=4 et sw=4
+#
+# Copyright (c) 2012 Intel Corporation
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the Free
+# Software Foundation; version 2 of the License
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc., 59
+# Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# Authors:
+# Damien Lespiau <damien.lespiau@intel.com>
+import git, os, re, sys
+
+class ValidationError(Exception):
+ pass
+
+class Logger:
+ DEBUG_COLOR = 37 # white
+ INFO_COLOR = 32 # green
+ WARN_COLOR = 33 # yellow
+ ERR_COLOR = 31 # red
+
+ PREFIX_RE = re.compile('^<(.*?)>\s*(.*)')
+
+ @staticmethod
+ def _color_print(head, color, msg = None, stream = sys.stdout):
+ if os.getenv('ANSI_COLORS_DISABLED') is None:
+ head = '\033[%dm%s:\033[0m' %(color, head)
+ if msg:
+ stream.write('%s %s\n' % (head, msg))
+ else:
+ stream.write('%s ' % head)
+
+ @staticmethod
+ def _color_perror(head, color, msg):
+ Logger._color_print(head, color, msg, sys.stderr)
+
+ @staticmethod
+ def _split_msg(head, msg):
+ m = Logger.PREFIX_RE.match(msg)
+ if m:
+ head += ' <%s>' % m.group(1)
+ msg = m.group(2)
+ return head, msg
+
+ @staticmethod
+ def debug(msg):
+ head, msg = Logger._split_msg('Debug', msg)
+ Logger._color_perror(head, Logger.DEBUG_COLOR, msg)
+
+ @staticmethod
+ def info(msg):
+ head, msg = Logger._split_msg('Info', msg)
+ Logger._color_perror(head, Logger.INFO_COLOR, msg)
+
+ @staticmethod
+ def warning(msg):
+ head, msg = Logger._split_msg('Warning', msg)
+ Logger._color_perror(head, Logger.WARN_COLOR, msg)
+
+ @staticmethod
+ def error(msg):
+ head, msg = Logger._split_msg('Error', msg)
+ Logger._color_perror(head, Logger.ERR_COLOR, msg)
+ sys.exit(1)
+
+class Config:
+ def __init__(self, config_file=None):
+ self.config = {}
+
+ if not config_file:
+ config_file = os.path.join(os.environ['HOME'], '.gfx-repos')
+
+ try:
+ execfile(config_file, self.config)
+ except:
+ print("Could not load %s" % config_file)
+ sys.exit(1)
+
+ self._validate()
+ self._autocomplete()
+
+ def _validate(self):
+ for name in self.get_repositories():
+ desc = self.get_repository(name)
+ if 'path' not in desc:
+ raise ValidationError('Need to specify a \'path\' key in the '
+ 'repository description for %s' % name)
+
+ def _autocomplete(self):
+ for name in self.get_repositories():
+ desc = self.get_repository(name)
+ # expand ~ or ~user in 'path'
+ desc['path'] = os.path.expanduser(desc['path'])
+ # default to the 'origin' remote
+ if 'remote' not in desc:
+ desc['remote'] = 'origin'
+
+ def get_repositories(self):
+ return self.config['repositories']
+
+ def get_repository(self, name):
+ return self.config['repositories'][name]
+
+class GitRepository:
+ def __init__(self, description):
+ self.desc = description
+ # I've seen the GitDB backend choke on packs from the kernel so
+ # let's use GitCmdObjectDB
+ self.repo = git.Repo(self.desc['path'],
+ odbt=git.GitCmdObjectDB)
+
+ def get_remote(self):
+ return self.repo.remote(self.desc['remote'])
+
+ def get_local_branch(self):
+ # TODO: allow overrides the local branch name from config file
+ return self.repo.head.reference.name
+
+ def get_local_commit(self):
+ # TODO: allow overrides the local branch name from config file
+ return self.repo.head.commit.hexsha
+
+ def is_published(self):
+ branch_spec = self.get_remote().name + '/' + self.get_local_branch()
+ sha = self.get_local_commit()
+
+ Logger.debug('Checking if %s is in %s' % (sha, branch_spec))
+ # If we haven't found the commit we are looking for in the first 1000,
+ # it's probably not there. We are trying to check if a local tip of a
+ # branch is in the remote branch, it should usually be the first commit
+ # of the remote branch.
+ for commit in self.repo.iter_commits(branch_spec, max_count=1000):
+ if commit.hexsha == sha:
+ return True
+ return False
+
+config = Config()
+
+entry="""%(name)s:
+ remote: %(remote)s
+ branch: %(remote_branch)s
+ commit: %(commit)s
+"""
+
+for name in config.get_repositories():
+ desc = config.get_repository(name)
+ repo = GitRepository(desc)
+
+ remote = repo.get_remote()
+ Logger.info("Fetching %s for %s" % (remote.url, name))
+ remote.fetch()
+
+ if not repo.is_published():
+ Logger.error("Could not find commit %s in the remote branch" %
+ repo.get_local_commit())
+
+ print entry % { 'name': name,
+ 'remote': remote.url,
+ 'remote_branch': repo.get_local_branch(),
+ 'commit': repo.get_local_commit() }
+