bitbake/bb/fetch:
[bitbake.git] / lib / bb / fetch / git.py
1 #!/usr/bin/env python
2 # ex:ts=4:sw=4:sts=4:et
3 # -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
4 """
5 BitBake 'Fetch' git implementation
6
7 Copyright (C) 2005 Richard Purdie
8
9 This program is free software; you can redistribute it and/or modify it under
10 the terms of the GNU General Public License as published by the Free Software
11 Foundation; either version 2 of the License, or (at your option) any later
12 version.
13
14 This program is distributed in the hope that it will be useful, but WITHOUT
15 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
16 FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License along with
19 this program; if not, write to the Free Software Foundation, Inc., 59 Temple
20 Place, Suite 330, Boston, MA 02111-1307 USA. 
21 """
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
29 def prunedir(topdir):
30     # Delete everything reachable from the directory named in 'topdir'.
31     # CAUTION:  This is dangerous!
32     for root, dirs, files in os.walk(topdir, topdown=False):
33         for name in files:
34             os.remove(os.path.join(root, name))
35         for name in dirs:
36             os.rmdir(os.path.join(root, name))
37
38 def rungitcmd(cmd,d):
39
40     bb.debug(1, "Running %s" % cmd)
41
42     # Need to export PATH as git is likely to be in metadata paths 
43     # rather than host provided
44     pathcmd = 'export PATH=%s; %s' % (data.expand('${PATH}', d), cmd)
45
46     myret = os.system(pathcmd)
47
48     if myret != 0:
49         raise FetchError("Git: %s failed" % pathcmd)
50
51 def gettag(parm):
52     if 'tag' in parm:
53         tag = parm['tag']
54     else:
55         tag = ""
56     if not tag:
57         tag = "master"
58
59     return tag
60
61 class Git(Fetch):
62     """Class to fetch a module or modules from git repositories"""
63     def supports(url, d):
64         """Check to see if a given url can be fetched with cvs.
65            Expects supplied url in list form, as outputted by bb.decodeurl().
66         """
67         (type, host, path, user, pswd, parm) = bb.decodeurl(data.expand(url, d))
68         return type in ['git']
69     supports = staticmethod(supports)
70
71     def localpath(url, d):
72         (type, host, path, user, pswd, parm) = bb.decodeurl(data.expand(url, d))
73
74         #if user sets localpath for file, use it instead.
75         if "localpath" in parm:
76             return parm["localpath"]
77
78         tag = gettag(parm)
79
80         localname = data.expand('git_%s%s_%s.tar.gz' % (host, path.replace('/', '.'), tag), d)
81
82         return os.path.join(data.getVar("DL_DIR", d, 1),data.expand('%s' % (localname), d))
83
84     localpath = staticmethod(localpath)
85
86     def go(self, d, urls = []):
87         """Fetch urls"""
88         if not urls:
89             urls = self.urls
90
91         for loc in urls:
92             (type, host, path, user, pswd, parm) = bb.decodeurl(data.expand(loc, d))
93
94             tag = gettag(parm)
95
96             gitsrcname = '%s%s' % (host, path.replace('/', '.'))
97
98             repofile = os.path.join(data.getVar("DL_DIR", d, 1), 'git_%s.tar.gz' % (gitsrcname))
99             repodir = os.path.join(data.expand('${GITDIR}', d), gitsrcname)
100
101             coname = '%s' % (tag)
102             codir = os.path.join(repodir, coname)
103
104             cofile = self.localpath(loc, d)
105
106             # Always update to current if tag=="master"
107             #if os.access(cofile, os.R_OK) and (tag != "master"):
108             if os.access(cofile, os.R_OK):
109                 bb.debug(1, "%s already exists, skipping git checkout." % cofile)
110                 continue
111
112 # Still Need to add GIT_TARBALL_STASH Support...
113 #            pn = data.getVar('PN', d, 1)
114 #            cvs_tarball_stash = None
115 #            if pn:
116 #                cvs_tarball_stash = data.getVar('CVS_TARBALL_STASH_%s' % pn, d, 1)
117 #            if cvs_tarball_stash == None:
118 #                cvs_tarball_stash = data.getVar('CVS_TARBALL_STASH', d, 1)
119 #            if cvs_tarball_stash:
120 #                fetchcmd = data.getVar("FETCHCOMMAND_wget", d, 1)
121 #                uri = cvs_tarball_stash + tarfn
122 #                bb.note("fetch " + uri)
123 #                fetchcmd = fetchcmd.replace("${URI}", uri)
124 #                ret = os.system(fetchcmd)
125 #                if ret == 0:
126 #                    bb.note("Fetched %s from tarball stash, skipping checkout" % tarfn)
127 #                    continue
128          
129             #if os.path.exists(repodir):
130                 #prunedir(repodir)
131
132             bb.mkdirhier(repodir)
133             os.chdir(repodir)
134
135             #print("Changing to %s" % repodir)
136
137             if os.access(repofile, os.R_OK):
138                 rungitcmd("tar -xzf %s" % (repofile),d)
139             else:
140                 rungitcmd("git clone rsync://%s%s %s" % (host, path, repodir),d)
141
142             rungitcmd("rsync -a --verbose --stats --progress rsync://%s%s/ %s" % (host, path, os.path.join(repodir, ".git", "")),d)
143
144             #print("Changing to %s" % repodir)
145             os.chdir(repodir)
146             rungitcmd("git pull rsync://%s%s" % (host, path),d)
147
148             #print("Changing to %s" % repodir)
149             os.chdir(repodir)
150             rungitcmd("tar -czf %s %s" % (repofile, os.path.join(".", ".git", "*") ),d)
151
152             if os.path.exists(codir):
153                 prunedir(codir)
154
155             #print("Changing to %s" % repodir)
156             bb.mkdirhier(codir)
157             os.chdir(repodir)
158             rungitcmd("git read-tree %s" % (tag),d)
159
160             rungitcmd("git checkout-index -q -f --prefix=%s -a" % (os.path.join(codir, "git", "")),d)
161
162             #print("Changing to %s" % codir)
163             os.chdir(codir)
164             rungitcmd("tar -czf %s %s" % (cofile, os.path.join(".", "*") ),d)
165