2 # ex:ts=4:sw=4:sts=4:et
3 # -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
5 BitBake 'Fetch' implementations
7 Classes for obtaining upstream sources for the
10 Copyright (C) 2003, 2004 Chris Larson
12 This program is free software; you can redistribute it and/or modify it under
13 the terms of the GNU General Public License as published by the Free Software
14 Foundation; either version 2 of the License, or (at your option) any later
17 This program is distributed in the hope that it will be useful, but WITHOUT
18 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
19 FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
21 You should have received a copy of the GNU General Public License along with
22 this program; if not, write to the Free Software Foundation, Inc., 59 Temple
23 Place, Suite 330, Boston, MA 02111-1307 USA.
25 Based on functions from the base bb module, Copyright 2003 Holger Schurig
32 class FetchError(Exception):
33 """Exception raised when a download fails"""
35 class NoMethodError(Exception):
36 """Exception raised when there is no method to obtain a supplied url or set of urls"""
38 class MissingParameterError(Exception):
39 """Exception raised when a fetch method is missing a critical parameter in the url"""
41 class ParameterError(Exception):
42 """Exception raised when a url cannot be proccessed due to invalid parameters."""
44 class MD5SumError(Exception):
45 """Exception raised when a MD5SUM of a file does not match the expected one"""
47 def uri_replace(uri, uri_find, uri_replace, d):
48 # bb.msg.note(1, bb.msg.domain.Fetcher, "uri_replace: operating on %s" % uri)
49 if not uri or not uri_find or not uri_replace:
50 bb.msg.debug(1, bb.msg.domain.Fetcher, "uri_replace: passed an undefined value, not replacing")
51 uri_decoded = list(bb.decodeurl(uri))
52 uri_find_decoded = list(bb.decodeurl(uri_find))
53 uri_replace_decoded = list(bb.decodeurl(uri_replace))
54 result_decoded = ['','','','','',{}]
55 for i in uri_find_decoded:
56 loc = uri_find_decoded.index(i)
57 result_decoded[loc] = uri_decoded[loc]
59 if type(i) == types.StringType:
61 if (re.match(i, uri_decoded[loc])):
62 result_decoded[loc] = re.sub(i, uri_replace_decoded[loc], uri_decoded[loc])
63 if uri_find_decoded.index(i) == 2:
65 localfn = bb.fetch.localpath(uri, d)
67 result_decoded[loc] = os.path.dirname(result_decoded[loc]) + "/" + os.path.basename(bb.fetch.localpath(uri, d))
68 # bb.msg.note(1, bb.msg.domain.Fetcher, "uri_replace: matching %s against %s and replacing with %s" % (i, uri_decoded[loc], uri_replace_decoded[loc]))
70 # bb.msg.note(1, bb.msg.domain.Fetcher, "uri_replace: no match")
74 # FIXME: apply replacements against options
75 return bb.encodeurl(result_decoded)
80 def init(urls = [], d = None):
82 bb.msg.debug(2, bb.msg.domain.Fetcher, "BUG init called with None as data object!!!")
91 ud.method.urls.append(u)
94 if url not in urldata:
96 (ud.type, ud.host, ud.path, ud.user, ud.pswd, ud.parm) = bb.decodeurl(data.expand(url, d))
97 ud.date = Fetch.getSRCDate(d)
99 if m.supports(url, ud, d):
100 ud.localpath = m.localpath(url, ud, d)
101 ud.md5 = ud.localpath + '.md5'
102 # if user sets localpath for file, use it instead.
103 if "localpath" in ud.parm:
104 ud.localpath = ud.parm["localpath"]
114 # RP - is olddir needed?
115 olddir = os.path.abspath(os.getcwd())
116 m.go(u, urldata[u], d)
120 """Return a list of the local filenames, assuming successful fetch"""
124 local.append(urldata[u].localpath)
127 def localpath(url, d):
128 ud = initdata(url, d)
133 class FetchData(object):
134 """Class for fetcher variable store"""
137 """Base class for 'fetch'ing data"""
139 def __init__(self, urls = []):
142 def supports(self, url, urldata, d):
144 Check to see if this fetch class supports a given url.
148 def localpath(self, url, urldata, d):
150 Return the local filename of a given url assuming a successful fetch.
151 Can also setup variables in urldata for use in go (saving code duplication
152 and duplicate code execution)
156 def setUrls(self, urls):
162 urls = property(getUrls, setUrls, None, "Urls property")
164 def go(self, url, urldata, d):
167 Assumes localpath was called first
169 raise NoMethodError("Missing implementation for url")
173 Return the SRC Date for the component
177 return data.getVar("SRCDATE", d, 1) or data.getVar("CVSDATE", d, 1) or data.getVar("DATE", d, 1 )
178 getSRCDate = staticmethod(getSRCDate)
180 def try_mirror(d, tarfn):
182 Try to use a mirrored version of the sources. We do this
183 to avoid massive loads on foreign cvs and svn servers.
184 This method will be used by the different fetcher
187 d Is a bb.data instance
188 tarfn is the name of the tarball
190 tarpath = os.path.join(data.getVar("DL_DIR", d, 1), tarfn)
191 if os.access(tarpath, os.R_OK):
192 bb.msg.debug(1, bb.msg.domain.Fetcher, "%s already exists, skipping checkout." % tarfn)
195 pn = data.getVar('PN', d, True)
196 src_tarball_stash = None
198 src_tarball_stash = (data.getVar('SRC_TARBALL_STASH_%s' % pn, d, True) or data.getVar('CVS_TARBALL_STASH_%s' % pn, d, True) or data.getVar('SRC_TARBALL_STASH', d, True) or data.getVar('CVS_TARBALL_STASH', d, True) or "").split()
200 for stash in src_tarball_stash:
201 fetchcmd = data.getVar("FETCHCOMMAND_mirror", d, True) or data.getVar("FETCHCOMMAND_wget", d, True)
203 bb.msg.note(1, bb.msg.domain.Fetcher, "fetch " + uri)
204 fetchcmd = fetchcmd.replace("${URI}", uri)
205 ret = os.system(fetchcmd)
207 bb.msg.note(1, bb.msg.domain.Fetcher, "Fetched %s from tarball stash, skipping checkout" % tarfn)
210 try_mirror = staticmethod(try_mirror)
220 methods.append(cvs.Cvs())
221 methods.append(git.Git())
222 methods.append(local.Local())
223 methods.append(svn.Svn())
224 methods.append(wget.Wget())
225 methods.append(svk.Svk())
226 methods.append(ssh.SSH())