Created
March 18, 2012 18:59
-
-
Save bollwyvl/2079831 to your computer and use it in GitHub Desktop.
Rug stuff
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class RugWorkspaceImplementation(WorkspaceImplementation): | |
def pretty_status(self, project=None): | |
""" | |
returns a nicely-formatted version of the rug status command | |
TODO: refactor when the pretty status comes out for reals | |
""" | |
if project is None: | |
project = self.repo._impl._rug | |
stat = project.status(porcelain=True) | |
if not stat.strip(): | |
return {} | |
result = {} | |
for bits in stat.split("\n"): | |
bits = bits.split("\t") | |
result[bits[1]] = dict( | |
status=bits[0], | |
repo=bits[2], | |
) | |
return result | |
def stage(self, action, paths): | |
""" | |
Modifies files in the current commit. | |
If executed within the WSGI loop, this WILL explode. | |
TODO: this is the kind of thing we'll have to do. | |
""" | |
self.set_repo_status("staging") | |
try: | |
paths = [p | |
for p | |
in paths | |
if self.safe_path(p)] | |
self._stage_project( | |
self.repo._impl._rug, | |
action, | |
paths, | |
self.repo._impl._rug.dir) | |
except: | |
self.set_repo_status() | |
raise | |
self.set_repo_status() | |
def _stage_project(self, project, action, paths, root): | |
""" | |
Recursively stage the repos that are rquired for the given paths | |
""" | |
stat = self.pretty_status(project) | |
if not stat: | |
return | |
DELETED = self.stat_type_reverse[self.DELETED] | |
subproj_paths = {} | |
if action == WS.STAGE_STAGE: | |
for path in paths: | |
# this should give us the project-relative path | |
path = os.path.relpath( | |
os.path.join(root, path), | |
project.dir | |
) | |
if path in stat: | |
r = project.repos[stat[path]["repo"]] | |
if r["vcs"] == "rug": | |
subproj_paths[r["repo"]].setdefault([]).append(path) | |
else: | |
# this should give us the repo-relative path | |
proj_path = os.path.relpath( | |
os.path.join(root, path), | |
os.path.join(project.dir, r["path"]) | |
) | |
log.info([ | |
"ADD/REMOVE?", | |
root, | |
project.dir, | |
r["path"], | |
path, | |
proj_path]) | |
if DELETED in stat[path]["status"]: | |
r['repo'].remove(proj_path) | |
else: | |
r['repo'].add(proj_path) | |
else: | |
raise NotImplementedError( | |
"%s does not belong to any known repo" % path) | |
# RECURSE | |
[self._stage(sp, sp_paths, root) | |
for sp, sp_paths in subproj_paths.items()] | |
def finish_commit(self, summary, message, paths=[]): | |
self.set_repo_status("committing") | |
try: | |
# a dict, passed around in recursion, that contains full fs paths | |
# to the repos that need committing | |
to_commit = {} | |
self._repos_to_commit( | |
self.repo._impl._rug, | |
paths, | |
to_commit, | |
self.repo._impl._rug.dir) | |
message = "\n".join([t or "" for t in [summary, message]]).strip() | |
# walk back through the repos, committing the leaves first | |
# and finally committing the highest project... NEEDS ADD? | |
for repo_path in sorted(to_commit.keys(), reverse=True): | |
to_commit[repo_path].commit(message) | |
except: | |
self.set_repo_status() | |
raise | |
self.set_repo_status() | |
def _repos_to_commit(self, project, paths, to_commit, root): | |
""" | |
Recursively collect the repos that need to be committed | |
given a set of paths | |
""" | |
stat = self.pretty_status(project) | |
if not stat: | |
return | |
pp = project.dir | |
subproj_paths = {} | |
for path in paths: | |
# get the project-relative path | |
path = os.path.relpath( | |
os.path.join(root, path), | |
project.dir | |
) | |
if path in stat: | |
r = project.repos[stat[path]['repo']] | |
if r['vcs'] == "rug": | |
subproj_paths[r['repo']].setdefault([]).append(path) | |
else: | |
# this duplicates stuff... meh | |
to_commit[os.path.join(pp, r['path'])] = r['repo'] | |
# assuming commit is good enough for a project? | |
to_commit[pp] = project | |
else: | |
raise NotImplementedError( | |
"%s does not belong to any known repo" % path) | |
# RECURSE | |
[self._repos_to_commit(sp, sp_paths, to_commit, root) | |
for sp, sp_paths in subproj_paths.items()] |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment