aboutsummaryrefslogtreecommitdiff
path: root/modules/utils.py
blob: dac77c5c1c1292ed3c735d9932a0b13b4f9b1eee (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
from subprocess import CalledProcessError
from subprocess import check_output
from subprocess import STDOUT

import re

from linaropy.git.worktree import Worktree

class CommandPrinter(object):
    """Command consumer that just prints the commands that it receives."""

    def consume(self, command, directory):
        print("{}$ {}".format(directory, ' '.join(command)))


class CommandRunner(object):
    """Command consumer that runs the commands that it receives."""

    def consume(self, command, directory):
        """
        Run the given command in the given directory and print the stdout and
        stderr. If an exception is thrown while running the command, it will be
        rethrown as a RuntimeError.
        """
        # FIXME: This prints the results after the command has finished running.
        # For long-running commands (e.g. an LLVM build) we'll want live
        # output.
        try:
            print(str(check_output(command, stderr=STDOUT, cwd=directory), 'utf-8'))
        except CalledProcessError as exc:
            raise RuntimeError(
                "Error while running command\n{}".format(str(exc.output, 'utf-8'))) from exc


# FIXME: repo.pushToBranch doesn't work, because it doesn't handle remote
# branches properly. Furthermore, there's no support for getting the remote URL,
# so we need to resort to raw git commands. We may also consider moving the
# functionality for parsing info out of the remote URL into the repo object.
from sh import git
from linaropy.cd import cd


def get_user_from_remote(url):
    """Get the username used as part of the remote URL, or None.

    The remote URLs that we expect to see look like $protocol://$user@$location.
    If they look any different, we won't be able to parse them.
    """
    pattern = re.compile("(.*://)?(?P<user>.*)@(.*)\n?")
    match = pattern.match(str(url))
    if match is None:
        return None
    return match.group('user')


def get_remote_branch(repo, local_branch):
    """
    Get the name of the remote branch corresponding to the given local branch.
    """
    with cd(repo.repodir):
        remote = git("remote", "get-url", "--push", "origin").strip()
    user = get_user_from_remote(remote)
    if not user:
        raise EnvironmentError("Couldn't parse user from {}.".format(remote))

    remote_branch = "linaro-local/{}/{}".format(user, local_branch)
    if not repo.is_valid_branch_name(remote_branch):
        raise EnvironmentError(
            "{} is not a valid branch name.".format(remote_branch))

    return remote_branch


def push_branch(proj, local_branch, remote_branch, pathToRepo):
    """Push the given local branch into origin's given remote branch."""
    repo = Worktree(proj, pathToRepo)
    with cd(repo.repodir):
        git("push", "-u", "origin", "+{}:{}".format(local_branch, remote_branch))