21259a23b0a2803bbbf6c105783a1a06537c9d1e
[vuplus_bitbake] / lib / bb / fetch / git.py
1 # ex:ts=4:sw=4:sts=4:et
2 # -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
3 """
4 BitBake 'Fetch' git implementation
5
6 """
7
8 #Copyright (C) 2005 Richard Purdie
9 #
10 # This program is free software; you can redistribute it and/or modify
11 # it under the terms of the GNU General Public License version 2 as
12 # published by the Free Software Foundation.
13 #
14 # This program is distributed in the hope that it will be useful,
15 # but WITHOUT ANY WARRANTY; without even the implied warranty of
16 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 # GNU General Public License for more details.
18 #
19 # You should have received a copy of the GNU General Public License along
20 # with this program; if not, write to the Free Software Foundation, Inc.,
21 # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22
23 import os, re
24 import bb
25 from   bb    import data
26 from   bb.fetch import Fetch
27 from   bb.fetch import FetchError
28 from   bb.fetch import runfetchcmd
29
30 def prunedir(topdir):
31     # Delete everything reachable from the directory named in 'topdir'.
32     # CAUTION:  This is dangerous!
33     for root, dirs, files in os.walk(topdir, topdown=False):
34         for name in files:
35             os.remove(os.path.join(root, name))
36         for name in dirs:
37             os.rmdir(os.path.join(root, name))
38
39 class Git(Fetch):
40     """Class to fetch a module or modules from git repositories"""
41     def supports(self, url, ud, d):
42         """
43         Check to see if a given url can be fetched with git.
44         """
45         return ud.type in ['git']
46
47     def localpath(self, url, ud, d):
48
49         ud.proto = "rsync"
50         if 'protocol' in ud.parm:
51             ud.proto = ud.parm['protocol']
52
53         tag = Fetch.srcrev_internal_helper(ud, d)
54         if tag is True:
55             ud.tag = self.latest_revision(url, ud, d)   
56         elif tag:
57             ud.tag = tag
58
59         if not ud.tag:
60             ud.tag = self.latest_revision(url, ud, d)   
61
62         if ud.tag == "master":
63             ud.tag = self.latest_revision(url, ud, d)
64
65         ud.localfile = data.expand('git_%s%s_%s.tar.gz' % (ud.host, ud.path.replace('/', '.'), ud.tag), d)
66
67         return os.path.join(data.getVar("DL_DIR", d, True), ud.localfile)
68
69     def go(self, loc, ud, d):
70         """Fetch url"""
71
72         if Fetch.try_mirror(d, ud.localfile):
73             bb.msg.debug(1, bb.msg.domain.Fetcher, "%s already exists (or was stashed). Skipping git checkout." % ud.localpath)
74             return
75
76         gitsrcname = '%s%s' % (ud.host, ud.path.replace('/', '.'))
77
78         repofilename = 'git_%s.tar.gz' % (gitsrcname)
79         repofile = os.path.join(data.getVar("DL_DIR", d, 1), repofilename)
80         repodir = os.path.join(data.expand('${GITDIR}', d), gitsrcname)
81
82         coname = '%s' % (ud.tag)
83         codir = os.path.join(repodir, coname)
84
85         if not os.path.exists(repodir):
86             if Fetch.try_mirror(d, repofilename):    
87                 bb.mkdirhier(repodir)
88                 os.chdir(repodir)
89                 runfetchcmd("tar -xzf %s" % (repofile), d)
90             else:
91                 runfetchcmd("git clone -n %s://%s%s %s" % (ud.proto, ud.host, ud.path, repodir), d)
92
93         os.chdir(repodir)
94         # Remove all but the .git directory
95         runfetchcmd("rm * -Rf", d)
96         runfetchcmd("git fetch %s://%s%s" % (ud.proto, ud.host, ud.path), d)
97         runfetchcmd("git pull --tags %s://%s%s" % (ud.proto, ud.host, ud.path), d)
98         runfetchcmd("git prune-packed", d)
99         runfetchcmd("git pack-redundant --all | xargs -r rm", d)
100
101         os.chdir(repodir)
102         mirror_tarballs = data.getVar("BB_GENERATE_MIRROR_TARBALLS", d, True)
103         if mirror_tarballs != "0": 
104             bb.msg.note(1, bb.msg.domain.Fetcher, "Creating tarball of git repository")
105             runfetchcmd("tar -czf %s %s" % (repofile, os.path.join(".", ".git", "*") ), d)
106
107         if os.path.exists(codir):
108             prunedir(codir)
109
110         bb.mkdirhier(codir)
111         os.chdir(repodir)
112         runfetchcmd("git read-tree %s" % (ud.tag), d)
113         runfetchcmd("git checkout-index -q -f --prefix=%s -a" % (os.path.join(codir, "git", "")), d)
114
115         os.chdir(codir)
116         bb.msg.note(1, bb.msg.domain.Fetcher, "Creating tarball of git checkout")
117         runfetchcmd("tar -czf %s %s" % (ud.localpath, os.path.join(".", "*") ), d)
118
119         os.chdir(repodir)
120         prunedir(codir)
121
122     def suppports_srcrev(self):
123         return True
124
125     def _revision_key(self, url, ud, d):
126         """
127         Return a unique key for the url
128         """
129         return "git:" + ud.host + ud.path.replace('/', '.')
130
131     def _latest_revision(self, url, ud, d):
132
133         output = runfetchcmd("git ls-remote %s://%s%s" % (ud.proto, ud.host, ud.path), d, True)
134         return output.split()[0]
135
136     def _build_revision(self, url, ud, d):
137         return ud.tag
138