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