aos/tools/harness/checkout.py
Daniel Schwyn 6d444bf552 Main handout
Signed-off-by: Daniel Schwyn <daniel.schwyn@inf.ethz.ch>
2022-03-03 14:57:51 +01:00

123 lines
3.5 KiB
Python

##########################################################################
# Copyright (c) 2009, ETH Zurich.
# All rights reserved.
#
# This file is distributed under the terms in the attached LICENSE file.
# If you do not find this file, copies can be found by writing to:
# ETH Zurich D-INFK, Universitaetstrasse 6, CH-8092 Zurich. Attn: Systems Group.
##########################################################################
try:
from mercurial import hg, ui, node, error, commands
mercurial_module = True
except ImportError:
mercurial_module = False
try:
import git
git_module = True
except ImportError:
git_module = False
class Checkout(object):
'''Checkout Base class:
Maintain information about revision number, and directory locations
'''
def __init__(self, base_dir):
# Set parameters
self.base_dir = base_dir
def get_base_dir(self):
return self.base_dir
''' Returns a unique commit identifier as string '''
def get_revision(self):
return '(repository information/git/hg module not available)'
''' Return a string (or None) containing a patch file representing local changes'''
def get_diff(self):
return None
''' Return a dict of additional info '''
def get_meta(self):
return {}
class CheckoutHg(Checkout):
def __init__(self, base_dir, repo):
super(CheckoutHg, self).__init__(base_dir)
self.repo = repo
def get_revision(self):
# identify the parents of the working revision
context = self.repo[None]
parents = context.parents()
s = ', '.join(map(lambda p: node.short(p.node()), parents))
if context.files() or context.deleted():
s += ' with local changes'
else:
s += ' unmodified'
return s
def get_diff(self):
context = self.repo[None]
if not context.files() and not context.deleted():
return None
diffui = ui.ui()
diffui.pushbuffer()
commands.diff(diffui, self.repo, git=True)
return diffui.popbuffer()
class CheckoutGit(Checkout):
def __init__(self, base_dir, repo):
super(CheckoutGit, self).__init__(base_dir)
self.repo = repo
def get_diff(self):
gitc = self.repo.git
return gitc.diff() + "\n\n" + gitc.diff(cached=True)
def get_revision(self):
return self.repo.head.commit.hexsha
def get_meta(self):
repo = self.repo
headc = repo.head.commit
ret = {}
shortsha = self.repo.git.rev_parse(headc.hexsha, short=7)
try:
ret["branch"] = repo.active_branch.name
except TypeError, e:
ret["branch"] = "(HEAD detached at %s)" % shortsha
ret["shortrev"] = shortsha
ret["commitmsg"] = headc.message.split("\n")[0]
ret["commitmsg-tail"] = "".join(headc.message.split("\n")[1:])
ret["dirty"] = str(self.repo.is_dirty())
ret["untracked-files"] = ",".join(self.repo.untracked_files)
return ret
''' Factory method that checks a directory and instantiates
the correct Checkout class '''
def create_for_dir(base_dir):
if git_module:
try:
return CheckoutGit(base_dir, git.Repo(base_dir))
except git.InvalidGitRepositoryError:
pass
if mercurial_module:
try:
return CheckoutHg(base_dir, hg.repository(ui.ui(), base_dir))
except error.RepoError:
pass
return Checkout(base_dir)