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 # if user sets localpath for file, use it instead.
102 if "localpath" in ud.parm:
103 ud.localpath = ud.parm["localpath"]
113 m.go(u, urldata[u], d)
116 """Return a list of the local filenames, assuming successful fetch"""
120 local.append(urldata[u].localpath)
123 def localpath(url, d):
124 ud = initdata(url, d)
129 class FetchData(object):
130 """Class for fetcher variable store"""
133 """Base class for 'fetch'ing data"""
135 def __init__(self, urls = []):
138 def supports(self, url, urldata, d):
140 Check to see if this fetch class supports a given url.
144 def localpath(self, url, urldata, d):
146 Return the local filename of a given url assuming a successful fetch.
147 Can also setup variables in urldata for use in go (saving code duplication
148 and duplicate code execution)
152 def setUrls(self, urls):
158 urls = property(getUrls, setUrls, None, "Urls property")
160 def go(self, url, urldata, d):
163 Assumes localpath was called first
165 raise NoMethodError("Missing implementation for url")
169 Return the SRC Date for the component
173 return data.getVar("SRCDATE", d, 1) or data.getVar("CVSDATE", d, 1) or data.getVar("DATE", d, 1 )
174 getSRCDate = staticmethod(getSRCDate)
176 def try_mirror(d, tarfn):
178 Try to use a mirrored version of the sources. We do this
179 to avoid massive loads on foreign cvs and svn servers.
180 This method will be used by the different fetcher
183 d Is a bb.data instance
184 tarfn is the name of the tarball
186 tarpath = os.path.join(data.getVar("DL_DIR", d, 1), tarfn)
187 if os.access(tarpath, os.R_OK):
188 bb.msg.debug(1, bb.msg.domain.Fetcher, "%s already exists, skipping checkout." % tarfn)
191 pn = data.getVar('PN', d, True)
192 src_tarball_stash = None
194 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()
196 for stash in src_tarball_stash:
197 fetchcmd = data.getVar("FETCHCOMMAND_mirror", d, True) or data.getVar("FETCHCOMMAND_wget", d, True)
199 bb.msg.note(1, bb.msg.domain.Fetcher, "fetch " + uri)
200 fetchcmd = fetchcmd.replace("${URI}", uri)
201 ret = os.system(fetchcmd)
203 bb.msg.note(1, bb.msg.domain.Fetcher, "Fetched %s from tarball stash, skipping checkout" % tarfn)
206 try_mirror = staticmethod(try_mirror)
216 methods.append(cvs.Cvs())
217 methods.append(git.Git())
218 methods.append(local.Local())
219 methods.append(svn.Svn())
220 methods.append(wget.Wget())
221 methods.append(svk.Svk())
222 methods.append(ssh.SSH())