d75afaad60c7cd59f337fcfa31fa6bdf6b6f7a70
[vuplus_bitbake] / lib / bb / fetch / __init__.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' implementations
6
7 Classes for obtaining upstream sources for the
8 BitBake build tools.
9
10 Copyright (C) 2003, 2004  Chris Larson
11
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
15 version.
16
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.
20
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. 
24
25 Based on functions from the base bb module, Copyright 2003 Holger Schurig
26 """
27
28 import os, re
29 import bb
30 from   bb import data
31
32 class FetchError(Exception):
33     """Exception raised when a download fails"""
34
35 class NoMethodError(Exception):
36     """Exception raised when there is no method to obtain a supplied url or set of urls"""
37
38 class MissingParameterError(Exception):
39     """Exception raised when a fetch method is missing a critical parameter in the url"""
40
41 class ParameterError(Exception):
42     """Exception raised when a url cannot be proccessed due to invalid parameters."""
43
44 class MD5SumError(Exception):
45     """Exception raised when a MD5SUM of a file does not match the expected one"""
46
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]
58         import types
59         if type(i) == types.StringType:
60             import re
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:
64                     if d:
65                         localfn = bb.fetch.localpath(uri, d)
66                         if localfn:
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]))
69             else:
70 #               bb.msg.note(1, bb.msg.domain.Fetcher, "uri_replace: no match")
71                 return uri
72 #           else:
73 #               for j in i.keys():
74 #                   FIXME: apply replacements against options
75     return bb.encodeurl(result_decoded)
76
77 methods = []
78 urldata = {}
79
80 def init(urls = [], d = None):
81     if d == None:
82         bb.msg.debug(2, bb.msg.domain.Fetcher, "BUG init called with None as data object!!!")
83         return
84
85     for m in methods:
86         m.urls = []
87
88     for u in urls:
89         ud = initdata(u, d)
90         if ud.method:
91             ud.method.urls.append(u)
92
93 def initdata(url, d):
94     if url not in urldata:
95         ud = FetchData()
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)
98         for m in methods:
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"]
104                 ud.method = m
105                 break
106         urldata[url] = ud
107     return urldata[url]
108
109 def go(d):
110     """Fetch all urls"""
111     for m in methods:
112         for u in m.urls:
113             m.go(u, urldata[u], d)
114
115 def localpaths(d):
116     """Return a list of the local filenames, assuming successful fetch"""
117     local = []
118     for m in methods:
119         for u in m.urls:
120             local.append(urldata[u].localpath)
121     return local
122
123 def localpath(url, d):
124     ud = initdata(url, d)
125     if ud.method:
126         return ud.localpath
127     return url
128
129 class FetchData(object):
130     """Class for fetcher variable store"""
131
132 class Fetch(object):
133     """Base class for 'fetch'ing data"""
134
135     def __init__(self, urls = []):
136         self.urls = []
137
138     def supports(self, url, urldata, d):
139         """
140         Check to see if this fetch class supports a given url.
141         """
142         return 0
143
144     def localpath(self, url, urldata, d):
145         """
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)
149         """
150         return url
151
152     def setUrls(self, urls):
153         self.__urls = urls
154
155     def getUrls(self):
156         return self.__urls
157
158     urls = property(getUrls, setUrls, None, "Urls property")
159
160     def go(self, url, urldata, d):
161         """
162         Fetch urls
163         Assumes localpath was called first
164         """
165         raise NoMethodError("Missing implementation for url")
166
167     def getSRCDate(d):
168         """
169         Return the SRC Date for the component
170
171         d the bb.data module
172         """
173         return data.getVar("SRCDATE", d, 1) or data.getVar("CVSDATE", d, 1) or data.getVar("DATE", d, 1 )
174     getSRCDate = staticmethod(getSRCDate)
175
176     def try_mirror(d, tarfn):
177         """
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
181         implementations.
182
183         d Is a bb.data instance
184         tarfn is the name of the tarball
185         """
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)
189             return True
190
191         pn = data.getVar('PN', d, True)
192         src_tarball_stash = None
193         if pn:
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()
195
196         for stash in src_tarball_stash:
197             fetchcmd = data.getVar("FETCHCOMMAND_mirror", d, True) or data.getVar("FETCHCOMMAND_wget", d, True)
198             uri = stash + tarfn
199             bb.msg.note(1, bb.msg.domain.Fetcher, "fetch " + uri)
200             fetchcmd = fetchcmd.replace("${URI}", uri)
201             ret = os.system(fetchcmd)
202             if ret == 0:
203                 bb.msg.note(1, bb.msg.domain.Fetcher, "Fetched %s from tarball stash, skipping checkout" % tarfn)
204                 return True
205         return False
206     try_mirror = staticmethod(try_mirror)
207
208 import cvs
209 import git
210 import local
211 import svn
212 import wget
213 import svk
214 import ssh
215
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())