1"""
2This module defines the GitKernel class
3
4@author: Ryan Harper (ryanh@us.ibm.com)
5@copyright: IBM 2007
6"""
7
8import os, logging
9import git, source_kernel
10
11
12class GitKernel(git.InstallableGitRepo):
13    """
14    This class represents an installable git kernel repo.
15
16    It is used to pull down a local copy of a git repo, check if the local repo
17    is up-to-date, if not update and then build the kernel from the git repo.
18    """
19    def __init__(self, repodir, giturl, weburl=None):
20        super(GitKernel, self).__init__(repodir, giturl, weburl)
21        self._patches = []
22        self._config = None
23        self._build = None
24        self._branch = None
25        self._revision = None
26
27
28    def configure(self, config):
29        self._config = config
30
31
32    def patch(self, patch):
33        self._patches.append(patch)
34
35
36    def checkout(self, revision, local=None):
37        """
38        Checkout the commit id, branch, or tag.
39
40        @param revision: Name of the git remote branch, revision or tag
41        @param local: Name of the local branch, implies -b
42        """
43        logging.info('Checking out %s', revision)
44        super(GitKernel, self).checkout(revision)
45        self._revision = super(GitKernel, self).get_revision()
46        self._branch = super(GitKernel, self).get_branch()
47        logging.info('Checked out %s on branch %s', self._revision,
48                     self._branch)
49
50
51    def show_branch(self):
52        """
53        Print the current local branch name.
54        """
55        self._branch = super(GitKernel, self).get_branch()
56        logging.info(self._branch)
57
58
59    def show_branches(self, all=True):
60        """
61        Print the local and remote branches.
62
63        @param all: Whether to show all branches (True) or only local branches
64                (False).
65        """
66        self._branch = super(GitKernel, self).get_branch()
67        logging.info(super(GitKernel, self).get_branch(all=all))
68
69
70    def show_revision(self):
71        """
72        Show the current git revision.
73        """
74        self._revision = super(GitKernel, self).get_revision()
75        logging.info(self._revision)
76
77
78    def install(self, host, build=True, builddir=None, revision=None):
79        """
80        Install the git tree in a host.
81
82        @param host: Host object
83        @param build: Whether to build the source tree
84        @param builddir: Specify a build dir. If no build dir is specified,
85                the job temporary directory will be used, so the build won't
86                be persistent.
87        @param revision: Desired commit hash. If ommited, will build from HEAD
88                of the branch.
89        """
90        if revision:
91            self.checkout(revision)
92            self._revision = super(GitKernel, self).get_revision()
93            logging.info('Checked out revision: %s', self._revision)
94
95        if not builddir:
96            self._build = os.path.join(host.get_tmp_dir(), "build")
97            logging.warning('Builddir %s is not persistent (it will be erased '
98                            'in future jobs)', self._build)
99        else:
100            self._build = builddir
101
102        # push source to host for install
103        logging.info('Pushing %s to host', self.source_material)
104        host.send_file(self.source_material, self._build)
105        remote_source_material= os.path.join(self._build,
106                                        os.path.basename(self.source_material))
107
108        # use a source_kernel to configure, patch, build and install.
109        sk = source_kernel.SourceKernel(remote_source_material)
110
111        if build:
112            # apply patches
113            for p in self._patches:
114                sk.patch(p)
115
116            # configure
117            sk.configure(self._config)
118
119            # build
120            sk.build(host)
121
122        # install
123        sk.install(host)
124