Mercurial > repos > shellac > sam_consensus_v3
comparison env/lib/python3.9/site-packages/planemo/git.py @ 0:4f3585e2f14b draft default tip
"planemo upload commit 60cee0fc7c0cda8592644e1aad72851dec82c959"
author | shellac |
---|---|
date | Mon, 22 Mar 2021 18:12:50 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:4f3585e2f14b |
---|---|
1 """Utilities for interacting with git using planemo abstractions.""" | |
2 from __future__ import absolute_import | |
3 | |
4 import os | |
5 import subprocess | |
6 | |
7 from galaxy.util import unicodify | |
8 | |
9 from planemo import io | |
10 | |
11 | |
12 def git_env_for(path): | |
13 """Setup env dictionary to target specified git repo with git commands.""" | |
14 env = os.environ.copy() | |
15 env.update({ | |
16 "GIT_WORK_DIR": path, | |
17 "GIT_DIR": os.path.join(path, ".git") | |
18 }) | |
19 return env | |
20 | |
21 | |
22 def ls_remote(ctx, remote_repo): | |
23 """Return a dictionary with refs as key and commits as value.""" | |
24 commits_and_refs = io.communicate( | |
25 ["git", "ls-remote", remote_repo], | |
26 stdout=subprocess.PIPE, | |
27 )[0] | |
28 return dict(line.split()[::-1] for line in commits_and_refs.decode('utf-8').splitlines()) | |
29 | |
30 | |
31 def init(ctx, repo_path): | |
32 env = git_env_for(repo_path) | |
33 io.communicate(["git", "init"], env=env) | |
34 | |
35 | |
36 def add(ctx, repo_path, file_path): | |
37 env = git_env_for(repo_path) | |
38 io.communicate(["git", "add", os.path.relpath(file_path, repo_path)], env=env, cwd=repo_path) | |
39 | |
40 | |
41 def commit(ctx, repo_path, message=""): | |
42 env = git_env_for(repo_path) | |
43 io.communicate(["git", "commit", "-m", message], env=env) | |
44 | |
45 | |
46 def push(ctx, repo_path, to=None, branch=None, force=False): | |
47 env = git_env_for(repo_path) | |
48 cmd = ["git", "push"] | |
49 if force: | |
50 cmd += ["--force"] | |
51 if to and branch: | |
52 cmd += ['-u', to, branch] | |
53 io.communicate(cmd, env=env, cwd=repo_path) | |
54 | |
55 | |
56 def branch(ctx, repo_path, branch, from_branch=None): | |
57 env = git_env_for(repo_path) | |
58 cmd = ["git", "checkout", "-b", branch] | |
59 if from_branch is not None: | |
60 cmd.append(from_branch) | |
61 io.communicate(cmd, env=env) | |
62 | |
63 | |
64 def checkout(ctx, remote_repo, local_path, branch=None, remote="origin", from_branch="master"): | |
65 """Checkout a new branch from a remote repository.""" | |
66 env = git_env_for(local_path) | |
67 if not os.path.exists(local_path): | |
68 io.communicate(command_clone(ctx, remote_repo, local_path)) | |
69 else: | |
70 io.communicate(["git", "fetch", remote], env=env) | |
71 | |
72 if branch: | |
73 io.communicate(["git", "checkout", "%s/%s" % (remote, from_branch), "-b", branch], env=env) | |
74 else: | |
75 io.communicate(["git", "merge", "--ff-only", "%s/%s" % (remote, from_branch)], env=env) | |
76 | |
77 | |
78 def command_clone(ctx, src, dest, mirror=False, branch=None): | |
79 """Produce a command-line string to clone a repository. | |
80 | |
81 Take in ``ctx`` to allow more configurability down the road. | |
82 """ | |
83 cmd = ['git', 'clone'] | |
84 if mirror: | |
85 cmd.append("--mirror") | |
86 if branch is not None: | |
87 cmd.extend(["--branch", branch]) | |
88 cmd.extend([src, dest]) | |
89 return cmd | |
90 | |
91 | |
92 def diff(ctx, directory, range): | |
93 """Produce a list of diff-ed files for commit range.""" | |
94 cmd_template = "cd '%s' && git diff --name-only '%s' --" | |
95 cmd = cmd_template % (directory, range) | |
96 stdout, _ = io.communicate( | |
97 cmd, | |
98 stdout=subprocess.PIPE, stderr=subprocess.PIPE, | |
99 universal_newlines=True | |
100 ) | |
101 return [line.strip() for line in unicodify(stdout).splitlines() if line] | |
102 | |
103 | |
104 def clone(*args, **kwds): | |
105 """Clone a git repository. | |
106 | |
107 See :func:`command_clone` for description of arguments. | |
108 """ | |
109 command = command_clone(*args, **kwds) | |
110 return io.communicate(command) | |
111 | |
112 | |
113 def rev(ctx, directory): | |
114 """Raw revision for git directory specified. | |
115 | |
116 Throws ``RuntimeError`` if not a git directory. | |
117 """ | |
118 cmd_template = "cd '%s' && git rev-parse HEAD" | |
119 cmd = cmd_template % directory | |
120 stdout, _ = io.communicate( | |
121 cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE | |
122 ) | |
123 return unicodify(stdout).strip() | |
124 | |
125 | |
126 def is_rev_dirty(ctx, directory): | |
127 """Check if specified git repository has uncommitted changes.""" | |
128 return io.shell(['git', 'diff', '--quiet'], cwd=directory) != 0 | |
129 | |
130 | |
131 def rev_if_git(ctx, directory): | |
132 """Determine git revision (or ``None``).""" | |
133 try: | |
134 the_rev = rev(ctx, directory) | |
135 is_dirty = is_rev_dirty(ctx, directory) | |
136 if is_dirty: | |
137 the_rev += "-dirty" | |
138 return the_rev | |
139 except RuntimeError: | |
140 return None |