unify mirror support and make it independant of the fetcher
[bitbake.git] / lib / bb / fetch / bzr.py
1 """
2 BitBake 'Fetch' implementation for bzr.
3
4 """
5
6 # Copyright (C) 2007 Ross Burton
7 # Copyright (C) 2007 Richard Purdie
8 #
9 #   Classes for obtaining upstream sources for the
10 #   BitBake build tools.
11 #   Copyright (C) 2003, 2004  Chris Larson
12 #
13 # This program is free software; you can redistribute it and/or modify
14 # it under the terms of the GNU General Public License version 2 as
15 # published by the Free Software Foundation.
16 #
17 # This program is distributed in the hope that it will be useful,
18 # but WITHOUT ANY WARRANTY; without even the implied warranty of
19 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20 # GNU General Public License for more details.
21 #
22 # You should have received a copy of the GNU General Public License along
23 # with this program; if not, write to the Free Software Foundation, Inc.,
24 # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
25
26 import os
27 import sys
28 import bb
29 from bb import data
30 from bb.fetch import Fetch
31 from bb.fetch import FetchError
32 from bb.fetch import runfetchcmd
33
34 class Bzr(Fetch):
35     def supports(self, url, ud, d):
36         return ud.type in ['bzr']
37
38     def localpath (self, url, ud, d):
39
40         # Create paths to bzr checkouts
41         relpath = ud.path
42         if relpath.startswith('/'):
43             # Remove leading slash as os.path.join can't cope
44             relpath = relpath[1:]
45         ud.pkgdir = os.path.join(data.expand('${BZRDIR}', d), ud.host, relpath)
46
47         revision = Fetch.srcrev_internal_helper(ud, d)
48         if revision is True:
49             ud.revision = self.latest_revision(url, ud, d)      
50         elif revision:
51             ud.revision = revision
52
53         if not ud.revision:
54             ud.revision = self.latest_revision(url, ud, d)      
55
56         ud.localfile = data.expand('bzr_%s_%s_%s.tar.gz' % (ud.host, ud.path.replace('/', '.'), ud.revision), d)
57         
58         return os.path.join(data.getVar("DL_DIR", d, True), ud.localfile)
59
60     def _buildbzrcommand(self, ud, d, command):
61         """
62         Build up an bzr commandline based on ud
63         command is "fetch", "update", "revno"
64         """
65
66         basecmd = data.expand('${FETCHCMD_bzr}', d)
67
68         proto = "http"
69         if "proto" in ud.parm:
70             proto = ud.parm["proto"]
71
72         bzrroot = ud.host + ud.path
73
74         options = []
75
76         if command is "revno":
77             bzrcmd = "%s revno %s %s://%s" % (basecmd, " ".join(options), proto, bzrroot)
78         else:
79             if ud.revision:
80                 options.append("-r %s" % ud.revision)
81
82             if command is "fetch":
83                 bzrcmd = "%s co %s %s://%s" % (basecmd, " ".join(options), proto, bzrroot)
84             elif command is "update":
85                 bzrcmd = "%s pull %s --overwrite" % (basecmd, " ".join(options))
86             else:
87                 raise FetchError("Invalid bzr command %s" % command)
88
89         return bzrcmd
90
91     def go(self, loc, ud, d):
92         """Fetch url"""
93
94         if os.access(os.path.join(ud.pkgdir, os.path.basename(ud.pkgdir), '.bzr'), os.R_OK):
95             bzrcmd = self._buildbzrcommand(ud, d, "update")
96             bb.msg.debug(1, bb.msg.domain.Fetcher, "BZR Update %s" % loc)
97             os.chdir(os.path.join (ud.pkgdir, os.path.basename(ud.path)))
98             runfetchcmd(bzrcmd, d)
99         else:
100             os.system("rm -rf %s" % os.path.join(ud.pkgdir, os.path.basename(ud.pkgdir)))
101             bzrcmd = self._buildbzrcommand(ud, d, "fetch")
102             bb.msg.debug(1, bb.msg.domain.Fetcher, "BZR Checkout %s" % loc)
103             bb.mkdirhier(ud.pkgdir)
104             os.chdir(ud.pkgdir)
105             bb.msg.debug(1, bb.msg.domain.Fetcher, "Running %s" % bzrcmd)
106             runfetchcmd(bzrcmd, d)
107
108         os.chdir(ud.pkgdir)
109         # tar them up to a defined filename
110         try:
111             runfetchcmd("tar -czf %s %s" % (ud.localpath, os.path.basename(ud.pkgdir)), d)
112         except:
113             t, v, tb = sys.exc_info()
114             try:
115                 os.unlink(ud.localpath)
116             except OSError:
117                 pass
118             raise t, v, tb
119
120     def suppports_srcrev(self):
121         return True
122
123     def _revision_key(self, url, ud, d):
124         """
125         Return a unique key for the url
126         """
127         return "bzr:" + ud.pkgdir
128
129     def _latest_revision(self, url, ud, d):
130         """
131         Return the latest upstream revision number
132         """
133         bb.msg.debug(2, bb.msg.domain.Fetcher, "BZR fetcher hitting network for %s" % url)
134
135         output = runfetchcmd(self._buildbzrcommand(ud, d, "revno"), d, True)
136
137         return output.strip()
138
139     def _sortable_revision(self, url, ud, d):
140         """
141         Return a sortable revision number which in our case is the revision number
142         """
143
144         return self._build_revision(url, ud, d)
145
146     def _build_revision(self, url, ud, d):
147         return ud.revision
148