Add persitent data store from trunk, sync the fetcher changes to use the persistent...
[bitbake.git] / 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         ud.tag = "master"
54         if 'tag' in ud.parm:
55             ud.tag = ud.parm['tag']
56         # FIXME, set tag to latest revision so local filestash works
57
58         ud.localfile = data.expand('git_%s%s_%s.tar.gz' % (ud.host, ud.path.replace('/', '.'), ud.tag), d)
59
60         return os.path.join(data.getVar("DL_DIR", d, True), ud.localfile)
61
62     def forcefetch(self, url, ud, d):
63         # tag=="master" must always update
64         if (ud.tag == "master"):
65             return True
66         return False
67
68     def go(self, loc, ud, d):
69         """Fetch url"""
70
71         if not self.forcefetch(loc, ud, d) and Fetch.try_mirror(d, ud.localfile):
72             bb.msg.debug(1, bb.msg.domain.Fetcher, "%s already exists (or was stashed). Skipping git checkout." % ud.localpath)
73             return
74
75         gitsrcname = '%s%s' % (ud.host, ud.path.replace('/', '.'))
76
77         repofilename = 'git_%s.tar.gz' % (gitsrcname)
78         repofile = os.path.join(data.getVar("DL_DIR", d, 1), repofilename)
79         repodir = os.path.join(data.expand('${GITDIR}', d), gitsrcname)
80
81         coname = '%s' % (ud.tag)
82         codir = os.path.join(repodir, coname)
83
84         if not os.path.exists(repodir):
85             if Fetch.try_mirror(d, repofilename):    
86                 bb.mkdirhier(repodir)
87                 os.chdir(repodir)
88                 runfetchcmd("tar -xzf %s" % (repofile), d)
89             else:
90                 runfetchcmd("git clone -n %s://%s%s %s" % (ud.proto, ud.host, ud.path, repodir), d)
91
92         os.chdir(repodir)
93         runfetchcmd("git pull %s://%s%s" % (ud.proto, ud.host, ud.path), d)
94         runfetchcmd("git pull --tags %s://%s%s" % (ud.proto, ud.host, ud.path), d)
95         runfetchcmd("git prune-packed", d)
96         runfetchcmd("git pack-redundant --all | xargs -r rm", d)
97         # Remove all but the .git directory
98         runfetchcmd("rm * -Rf", d)
99         # old method of downloading tags
100         #runfetchcmd("rsync -a --verbose --stats --progress rsync://%s%s/ %s" % (ud.host, ud.path, os.path.join(repodir, ".git", "")), d)
101
102         os.chdir(repodir)
103         bb.msg.note(1, bb.msg.domain.Fetcher, "Creating tarball of git repository")
104         runfetchcmd("tar -czf %s %s" % (repofile, os.path.join(".", ".git", "*") ), d)
105
106         if os.path.exists(codir):
107             prunedir(codir)
108
109         bb.mkdirhier(codir)
110         os.chdir(repodir)
111         runfetchcmd("git read-tree %s" % (ud.tag), d)
112         runfetchcmd("git checkout-index -q -f --prefix=%s -a" % (os.path.join(codir, "git", "")), d)
113
114         os.chdir(codir)
115         bb.msg.note(1, bb.msg.domain.Fetcher, "Creating tarball of git checkout")
116         runfetchcmd("tar -czf %s %s" % (ud.localpath, os.path.join(".", "*") ), d)
117
118     def latest_revision(self, url, ud, d):
119
120         output = rungitcmd("git ls-remote %s://%s%s %s" % (ud.proto, ud.host, ud.path, ud.tag), d, True)
121         return output.split()[0]
122