From e068eea7850a859bb0fe00bcb3b029ec63a6ce66 Mon Sep 17 00:00:00 2001 From: Richard Purdie Date: Fri, 10 Feb 2006 10:13:42 +0000 Subject: Update bitbake to latest bitbake svn git-svn-id: https://svn.o-hand.com/repos/poky/trunk@264 311d38ba-8fff-0310-9ca6-ca027cbcb966 --- bitbake/lib/bb/fetch/__init__.py | 175 ++++++++++++++++++++++++++++++++ bitbake/lib/bb/fetch/bk.py | 40 ++++++++ bitbake/lib/bb/fetch/cvs.py | 214 +++++++++++++++++++++++++++++++++++++++ bitbake/lib/bb/fetch/git.py | 165 ++++++++++++++++++++++++++++++ bitbake/lib/bb/fetch/local.py | 61 +++++++++++ bitbake/lib/bb/fetch/svn.py | 189 ++++++++++++++++++++++++++++++++++ bitbake/lib/bb/fetch/wget.py | 167 ++++++++++++++++++++++++++++++ 7 files changed, 1011 insertions(+) create mode 100644 bitbake/lib/bb/fetch/__init__.py create mode 100644 bitbake/lib/bb/fetch/bk.py create mode 100644 bitbake/lib/bb/fetch/cvs.py create mode 100644 bitbake/lib/bb/fetch/git.py create mode 100644 bitbake/lib/bb/fetch/local.py create mode 100644 bitbake/lib/bb/fetch/svn.py create mode 100644 bitbake/lib/bb/fetch/wget.py (limited to 'bitbake/lib/bb') diff --git a/bitbake/lib/bb/fetch/__init__.py b/bitbake/lib/bb/fetch/__init__.py new file mode 100644 index 000000000..da5b10c4b --- /dev/null +++ b/bitbake/lib/bb/fetch/__init__.py @@ -0,0 +1,175 @@ +#!/usr/bin/env python +# ex:ts=4:sw=4:sts=4:et +# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- +""" +BitBake 'Fetch' implementations + +Classes for obtaining upstream sources for the +BitBake build tools. + +Copyright (C) 2003, 2004 Chris Larson + +This program is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free Software +Foundation; either version 2 of the License, or (at your option) any later +version. + +This program is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with +this program; if not, write to the Free Software Foundation, Inc., 59 Temple +Place, Suite 330, Boston, MA 02111-1307 USA. + +Based on functions from the base bb module, Copyright 2003 Holger Schurig +""" + +import os, re +import bb +from bb import data + +class FetchError(Exception): + """Exception raised when a download fails""" + +class NoMethodError(Exception): + """Exception raised when there is no method to obtain a supplied url or set of urls""" + +class MissingParameterError(Exception): + """Exception raised when a fetch method is missing a critical parameter in the url""" + +class MD5SumError(Exception): + """Exception raised when a MD5SUM of a file does not match the expected one""" + +def uri_replace(uri, uri_find, uri_replace, d): +# bb.note("uri_replace: operating on %s" % uri) + if not uri or not uri_find or not uri_replace: + bb.debug(1, "uri_replace: passed an undefined value, not replacing") + uri_decoded = list(bb.decodeurl(uri)) + uri_find_decoded = list(bb.decodeurl(uri_find)) + uri_replace_decoded = list(bb.decodeurl(uri_replace)) + result_decoded = ['','','','','',{}] + for i in uri_find_decoded: + loc = uri_find_decoded.index(i) + result_decoded[loc] = uri_decoded[loc] + import types + if type(i) == types.StringType: + import re + if (re.match(i, uri_decoded[loc])): + result_decoded[loc] = re.sub(i, uri_replace_decoded[loc], uri_decoded[loc]) + if uri_find_decoded.index(i) == 2: + if d: + localfn = bb.fetch.localpath(uri, d) + if localfn: + result_decoded[loc] = os.path.dirname(result_decoded[loc]) + "/" + os.path.basename(bb.fetch.localpath(uri, d)) +# bb.note("uri_replace: matching %s against %s and replacing with %s" % (i, uri_decoded[loc], uri_replace_decoded[loc])) + else: +# bb.note("uri_replace: no match") + return uri +# else: +# for j in i.keys(): +# FIXME: apply replacements against options + return bb.encodeurl(result_decoded) + +methods = [] + +def init(urls = [], d = None): + if d == None: + bb.debug(2,"BUG init called with None as data object!!!") + return + + for m in methods: + m.urls = [] + + for u in urls: + for m in methods: + m.data = d + if m.supports(u, d): + m.urls.append(u) + +def go(d): + """Fetch all urls""" + for m in methods: + if m.urls: + m.go(d) + +def localpaths(d): + """Return a list of the local filenames, assuming successful fetch""" + local = [] + for m in methods: + for u in m.urls: + local.append(m.localpath(u, d)) + return local + +def localpath(url, d): + for m in methods: + if m.supports(url, d): + return m.localpath(url, d) + return url + +class Fetch(object): + """Base class for 'fetch'ing data""" + + def __init__(self, urls = []): + self.urls = [] + for url in urls: + if self.supports(bb.decodeurl(url), d) is 1: + self.urls.append(url) + + def supports(url, d): + """Check to see if this fetch class supports a given url. + Expects supplied url in list form, as outputted by bb.decodeurl(). + """ + return 0 + supports = staticmethod(supports) + + def localpath(url, d): + """Return the local filename of a given url assuming a successful fetch. + """ + return url + localpath = staticmethod(localpath) + + def setUrls(self, urls): + self.__urls = urls + + def getUrls(self): + return self.__urls + + urls = property(getUrls, setUrls, None, "Urls property") + + def setData(self, data): + self.__data = data + + def getData(self): + return self.__data + + data = property(getData, setData, None, "Data property") + + def go(self, urls = []): + """Fetch urls""" + raise NoMethodError("Missing implementation for url") + + def getSRCDate(d): + """ + Return the SRC Date for the component + + d the bb.data module + """ + return data.getVar("SRCDATE", d, 1) or data.getVar("CVSDATE", d, 1) or data.getVar("DATE", d, 1 ) + getSRCDate = staticmethod(getSRCDate) + +#if __name__ == "__main__": + +import bk +import cvs +import git +import local +import svn +import wget + +methods.append(bk.Bk()) +methods.append(cvs.Cvs()) +methods.append(git.Git()) +methods.append(local.Local()) +methods.append(svn.Svn()) +methods.append(wget.Wget()) diff --git a/bitbake/lib/bb/fetch/bk.py b/bitbake/lib/bb/fetch/bk.py new file mode 100644 index 000000000..6bd6c018f --- /dev/null +++ b/bitbake/lib/bb/fetch/bk.py @@ -0,0 +1,40 @@ +#!/usr/bin/env python +# ex:ts=4:sw=4:sts=4:et +# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- +""" +BitBake 'Fetch' implementations + +Classes for obtaining upstream sources for the +BitBake build tools. + +Copyright (C) 2003, 2004 Chris Larson + +This program is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free Software +Foundation; either version 2 of the License, or (at your option) any later +version. + +This program is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with +this program; if not, write to the Free Software Foundation, Inc., 59 Temple +Place, Suite 330, Boston, MA 02111-1307 USA. + +Based on functions from the base bb module, Copyright 2003 Holger Schurig +""" + +import os, re +import bb +from bb import data +from bb.fetch import Fetch + +class Bk(Fetch): + def supports(url, d): + """Check to see if a given url can be fetched via bitkeeper. + Expects supplied url in list form, as outputted by bb.decodeurl(). + """ + (type, host, path, user, pswd, parm) = bb.decodeurl(data.expand(url, d)) + return type in ['bk'] + supports = staticmethod(supports) diff --git a/bitbake/lib/bb/fetch/cvs.py b/bitbake/lib/bb/fetch/cvs.py new file mode 100644 index 000000000..461a2f50f --- /dev/null +++ b/bitbake/lib/bb/fetch/cvs.py @@ -0,0 +1,214 @@ +#!/usr/bin/env python +# ex:ts=4:sw=4:sts=4:et +# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- +""" +BitBake 'Fetch' implementations + +Classes for obtaining upstream sources for the +BitBake build tools. + +Copyright (C) 2003, 2004 Chris Larson + +This program is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free Software +Foundation; either version 2 of the License, or (at your option) any later +version. + +This program is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with +this program; if not, write to the Free Software Foundation, Inc., 59 Temple +Place, Suite 330, Boston, MA 02111-1307 USA. + +Based on functions from the base bb module, Copyright 2003 Holger Schurig +""" + +import os, re +import bb +from bb import data +from bb.fetch import Fetch +from bb.fetch import FetchError +from bb.fetch import MissingParameterError + +class Cvs(Fetch): + """Class to fetch a module or modules from cvs repositories""" + def supports(url, d): + """Check to see if a given url can be fetched with cvs. + Expects supplied url in list form, as outputted by bb.decodeurl(). + """ + (type, host, path, user, pswd, parm) = bb.decodeurl(data.expand(url, d)) + return type in ['cvs', 'pserver'] + supports = staticmethod(supports) + + def localpath(url, d): + (type, host, path, user, pswd, parm) = bb.decodeurl(data.expand(url, d)) + if "localpath" in parm: +# if user overrides local path, use it. + return parm["localpath"] + + if not "module" in parm: + raise MissingParameterError("cvs method needs a 'module' parameter") + else: + module = parm["module"] + if 'tag' in parm: + tag = parm['tag'] + else: + tag = "" + if 'date' in parm: + date = parm['date'] + else: + if not tag: + date = Fetch.getSRCDate(d) + else: + date = "" + + return os.path.join(data.getVar("DL_DIR", d, 1),data.expand('%s_%s_%s_%s.tar.gz' % ( module.replace('/', '.'), host, tag, date), d)) + localpath = staticmethod(localpath) + + def go(self, d, urls = []): + """Fetch urls""" + if not urls: + urls = self.urls + + localdata = data.createCopy(d) + data.setVar('OVERRIDES', "cvs:%s" % data.getVar('OVERRIDES', localdata), localdata) + data.update_data(localdata) + + for loc in urls: + (type, host, path, user, pswd, parm) = bb.decodeurl(data.expand(loc, localdata)) + if not "module" in parm: + raise MissingParameterError("cvs method needs a 'module' parameter") + else: + module = parm["module"] + + dlfile = self.localpath(loc, localdata) + dldir = data.getVar('DL_DIR', localdata, 1) +# if local path contains the cvs +# module, consider the dir above it to be the +# download directory +# pos = dlfile.find(module) +# if pos: +# dldir = dlfile[:pos] +# else: +# dldir = os.path.dirname(dlfile) + +# setup cvs options + options = [] + if 'tag' in parm: + tag = parm['tag'] + else: + tag = "" + + if 'date' in parm: + date = parm['date'] + else: + if not tag: + date = Fetch.getSRCDate(d) + else: + date = "" + + if "method" in parm: + method = parm["method"] + else: + method = "pserver" + + if "localdir" in parm: + localdir = parm["localdir"] + else: + localdir = module + + cvs_rsh = None + if method == "ext": + if "rsh" in parm: + cvs_rsh = parm["rsh"] + + tarfn = data.expand('%s_%s_%s_%s.tar.gz' % (module.replace('/', '.'), host, tag, date), localdata) + data.setVar('TARFILES', dlfile, localdata) + data.setVar('TARFN', tarfn, localdata) + + dl = os.path.join(dldir, tarfn) + if os.access(dl, os.R_OK): + bb.debug(1, "%s already exists, skipping cvs checkout." % tarfn) + continue + + pn = data.getVar('PN', d, 1) + cvs_tarball_stash = None + if pn: + cvs_tarball_stash = data.getVar('CVS_TARBALL_STASH_%s' % pn, d, 1) + if cvs_tarball_stash == None: + cvs_tarball_stash = data.getVar('CVS_TARBALL_STASH', d, 1) + if cvs_tarball_stash: + fetchcmd = data.getVar("FETCHCOMMAND_wget", d, 1) + uri = cvs_tarball_stash + tarfn + bb.note("fetch " + uri) + fetchcmd = fetchcmd.replace("${URI}", uri) + ret = os.system(fetchcmd) + if ret == 0: + bb.note("Fetched %s from tarball stash, skipping checkout" % tarfn) + continue + + if date: + options.append("-D %s" % date) + if tag: + options.append("-r %s" % tag) + + olddir = os.path.abspath(os.getcwd()) + os.chdir(data.expand(dldir, localdata)) + +# setup cvsroot + if method == "dir": + cvsroot = path + else: + cvsroot = ":" + method + ":" + user + if pswd: + cvsroot += ":" + pswd + cvsroot += "@" + host + ":" + path + + data.setVar('CVSROOT', cvsroot, localdata) + data.setVar('CVSCOOPTS', " ".join(options), localdata) + data.setVar('CVSMODULE', module, localdata) + cvscmd = data.getVar('FETCHCOMMAND', localdata, 1) + cvsupdatecmd = data.getVar('UPDATECOMMAND', localdata, 1) + + if cvs_rsh: + cvscmd = "CVS_RSH=\"%s\" %s" % (cvs_rsh, cvscmd) + cvsupdatecmd = "CVS_RSH=\"%s\" %s" % (cvs_rsh, cvsupdatecmd) + +# create module directory + bb.debug(2, "Fetch: checking for module directory") + pkg=data.expand('${PN}', d) + pkgdir=os.path.join(data.expand('${CVSDIR}', localdata), pkg) + moddir=os.path.join(pkgdir,localdir) + if os.access(os.path.join(moddir,'CVS'), os.R_OK): + bb.note("Update " + loc) +# update sources there + os.chdir(moddir) + myret = os.system(cvsupdatecmd) + else: + bb.note("Fetch " + loc) +# check out sources there + bb.mkdirhier(pkgdir) + os.chdir(pkgdir) + bb.debug(1, "Running %s" % cvscmd) + myret = os.system(cvscmd) + + if myret != 0: + try: + os.rmdir(moddir) + except OSError: + pass + raise FetchError(module) + + os.chdir(moddir) + os.chdir('..') +# tar them up to a defined filename + myret = os.system("tar -czf %s %s" % (os.path.join(dldir,tarfn), os.path.basename(moddir))) + if myret != 0: + try: + os.unlink(tarfn) + except OSError: + pass + os.chdir(olddir) + del localdata diff --git a/bitbake/lib/bb/fetch/git.py b/bitbake/lib/bb/fetch/git.py new file mode 100644 index 000000000..296b92639 --- /dev/null +++ b/bitbake/lib/bb/fetch/git.py @@ -0,0 +1,165 @@ +#!/usr/bin/env python +# ex:ts=4:sw=4:sts=4:et +# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- +""" +BitBake 'Fetch' git implementation + +Copyright (C) 2005 Richard Purdie + +This program is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free Software +Foundation; either version 2 of the License, or (at your option) any later +version. + +This program is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with +this program; if not, write to the Free Software Foundation, Inc., 59 Temple +Place, Suite 330, Boston, MA 02111-1307 USA. +""" + +import os, re +import bb +from bb import data +from bb.fetch import Fetch +from bb.fetch import FetchError + +def prunedir(topdir): + # Delete everything reachable from the directory named in 'topdir'. + # CAUTION: This is dangerous! + for root, dirs, files in os.walk(topdir, topdown=False): + for name in files: + os.remove(os.path.join(root, name)) + for name in dirs: + os.rmdir(os.path.join(root, name)) + +def rungitcmd(cmd,d): + + bb.debug(1, "Running %s" % cmd) + + # Need to export PATH as git is likely to be in metadata paths + # rather than host provided + pathcmd = 'export PATH=%s; %s' % (data.expand('${PATH}', d), cmd) + + myret = os.system(pathcmd) + + if myret != 0: + raise FetchError("Git: %s failed" % pathcmd) + +def gettag(parm): + if 'tag' in parm: + tag = parm['tag'] + else: + tag = "" + if not tag: + tag = "master" + + return tag + +class Git(Fetch): + """Class to fetch a module or modules from git repositories""" + def supports(url, d): + """Check to see if a given url can be fetched with cvs. + Expects supplied url in list form, as outputted by bb.decodeurl(). + """ + (type, host, path, user, pswd, parm) = bb.decodeurl(data.expand(url, d)) + return type in ['git'] + supports = staticmethod(supports) + + def localpath(url, d): + (type, host, path, user, pswd, parm) = bb.decodeurl(data.expand(url, d)) + + #if user sets localpath for file, use it instead. + if "localpath" in parm: + return parm["localpath"] + + tag = gettag(parm) + + localname = data.expand('git_%s%s_%s.tar.gz' % (host, path.replace('/', '.'), tag), d) + + return os.path.join(data.getVar("DL_DIR", d, 1),data.expand('%s' % (localname), d)) + + localpath = staticmethod(localpath) + + def go(self, d, urls = []): + """Fetch urls""" + if not urls: + urls = self.urls + + for loc in urls: + (type, host, path, user, pswd, parm) = bb.decodeurl(data.expand(loc, d)) + + tag = gettag(parm) + + gitsrcname = '%s%s' % (host, path.replace('/', '.')) + + repofile = os.path.join(data.getVar("DL_DIR", d, 1), 'git_%s.tar.gz' % (gitsrcname)) + repodir = os.path.join(data.expand('${GITDIR}', d), gitsrcname) + + coname = '%s' % (tag) + codir = os.path.join(repodir, coname) + + cofile = self.localpath(loc, d) + + # Always update to current if tag=="master" + #if os.access(cofile, os.R_OK) and (tag != "master"): + if os.access(cofile, os.R_OK): + bb.debug(1, "%s already exists, skipping git checkout." % cofile) + continue + +# Still Need to add GIT_TARBALL_STASH Support... +# pn = data.getVar('PN', d, 1) +# cvs_tarball_stash = None +# if pn: +# cvs_tarball_stash = data.getVar('CVS_TARBALL_STASH_%s' % pn, d, 1) +# if cvs_tarball_stash == None: +# cvs_tarball_stash = data.getVar('CVS_TARBALL_STASH', d, 1) +# if cvs_tarball_stash: +# fetchcmd = data.getVar("FETCHCOMMAND_wget", d, 1) +# uri = cvs_tarball_stash + tarfn +# bb.note("fetch " + uri) +# fetchcmd = fetchcmd.replace("${URI}", uri) +# ret = os.system(fetchcmd) +# if ret == 0: +# bb.note("Fetched %s from tarball stash, skipping checkout" % tarfn) +# continue + + #if os.path.exists(repodir): + #prunedir(repodir) + + bb.mkdirhier(repodir) + os.chdir(repodir) + + #print("Changing to %s" % repodir) + + if os.access(repofile, os.R_OK): + rungitcmd("tar -xzf %s" % (repofile),d) + else: + rungitcmd("git clone rsync://%s%s %s" % (host, path, repodir),d) + + rungitcmd("rsync -a --verbose --stats --progress rsync://%s%s/ %s" % (host, path, os.path.join(repodir, ".git", "")),d) + + #print("Changing to %s" % repodir) + os.chdir(repodir) + rungitcmd("git pull rsync://%s%s" % (host, path),d) + + #print("Changing to %s" % repodir) + os.chdir(repodir) + rungitcmd("tar -czf %s %s" % (repofile, os.path.join(".", ".git", "*") ),d) + + if os.path.exists(codir): + prunedir(codir) + + #print("Changing to %s" % repodir) + bb.mkdirhier(codir) + os.chdir(repodir) + rungitcmd("git read-tree %s" % (tag),d) + + rungitcmd("git checkout-index -q -f --prefix=%s -a" % (os.path.join(codir, "git", "")),d) + + #print("Changing to %s" % codir) + os.chdir(codir) + rungitcmd("tar -czf %s %s" % (cofile, os.path.join(".", "*") ),d) + diff --git a/bitbake/lib/bb/fetch/local.py b/bitbake/lib/bb/fetch/local.py new file mode 100644 index 000000000..51938f823 --- /dev/null +++ b/bitbake/lib/bb/fetch/local.py @@ -0,0 +1,61 @@ +#!/usr/bin/env python +# ex:ts=4:sw=4:sts=4:et +# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- +""" +BitBake 'Fetch' implementations + +Classes for obtaining upstream sources for the +BitBake build tools. + +Copyright (C) 2003, 2004 Chris Larson + +This program is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free Software +Foundation; either version 2 of the License, or (at your option) any later +version. + +This program is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with +this program; if not, write to the Free Software Foundation, Inc., 59 Temple +Place, Suite 330, Boston, MA 02111-1307 USA. + +Based on functions from the base bb module, Copyright 2003 Holger Schurig +""" + +import os, re +import bb +from bb import data +from bb.fetch import Fetch + +class Local(Fetch): + def supports(url, d): + """Check to see if a given url can be fetched in the local filesystem. + Expects supplied url in list form, as outputted by bb.decodeurl(). + """ + (type, host, path, user, pswd, parm) = bb.decodeurl(data.expand(url, d)) + return type in ['file','patch'] + supports = staticmethod(supports) + + def localpath(url, d): + """Return the local filename of a given url assuming a successful fetch. + """ + path = url.split("://")[1] + newpath = path + if path[0] != "/": + filespath = data.getVar('FILESPATH', d, 1) + if filespath: + newpath = bb.which(filespath, path) + if not newpath: + filesdir = data.getVar('FILESDIR', d, 1) + if filesdir: + newpath = os.path.join(filesdir, path) + return newpath + localpath = staticmethod(localpath) + + def go(self, urls = []): + """Fetch urls (no-op for Local method)""" +# no need to fetch local files, we'll deal with them in place. + return 1 diff --git a/bitbake/lib/bb/fetch/svn.py b/bitbake/lib/bb/fetch/svn.py new file mode 100644 index 000000000..ac5eebf5c --- /dev/null +++ b/bitbake/lib/bb/fetch/svn.py @@ -0,0 +1,189 @@ +#!/usr/bin/env python +# ex:ts=4:sw=4:sts=4:et +# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- +""" +BitBake 'Fetch' implementations + +Classes for obtaining upstream sources for the +BitBake build tools. + +Copyright (C) 2003, 2004 Chris Larson + +This program is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free Software +Foundation; either version 2 of the License, or (at your option) any later +version. + +This program is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with +this program; if not, write to the Free Software Foundation, Inc., 59 Temple +Place, Suite 330, Boston, MA 02111-1307 USA. + +Based on functions from the base bb module, Copyright 2003 Holger Schurig +""" + +import os, re +import bb +from bb import data +from bb.fetch import Fetch +from bb.fetch import FetchError +from bb.fetch import MissingParameterError + +class Svn(Fetch): + """Class to fetch a module or modules from svn repositories""" + def supports(url, d): + """Check to see if a given url can be fetched with svn. + Expects supplied url in list form, as outputted by bb.decodeurl(). + """ + (type, host, path, user, pswd, parm) = bb.decodeurl(data.expand(url, d)) + return type in ['svn'] + supports = staticmethod(supports) + + def localpath(url, d): + (type, host, path, user, pswd, parm) = bb.decodeurl(data.expand(url, d)) + if "localpath" in parm: +# if user overrides local path, use it. + return parm["localpath"] + + if not "module" in parm: + raise MissingParameterError("svn method needs a 'module' parameter") + else: + module = parm["module"] + if 'rev' in parm: + revision = parm['rev'] + else: + revision = "" + + date = Fetch.getSRCDate(d) + + return os.path.join(data.getVar("DL_DIR", d, 1),data.expand('%s_%s_%s_%s_%s.tar.gz' % ( module.replace('/', '.'), host, path.replace('/', '.'), revision, date), d)) + localpath = staticmethod(localpath) + + def go(self, d, urls = []): + """Fetch urls""" + if not urls: + urls = self.urls + + localdata = data.createCopy(d) + data.setVar('OVERRIDES', "svn:%s" % data.getVar('OVERRIDES', localdata), localdata) + data.update_data(localdata) + + for loc in urls: + (type, host, path, user, pswd, parm) = bb.decodeurl(data.expand(loc, localdata)) + if not "module" in parm: + raise MissingParameterError("svn method needs a 'module' parameter") + else: + module = parm["module"] + + dlfile = self.localpath(loc, localdata) + dldir = data.getVar('DL_DIR', localdata, 1) +# if local path contains the svn +# module, consider the dir above it to be the +# download directory +# pos = dlfile.find(module) +# if pos: +# dldir = dlfile[:pos] +# else: +# dldir = os.path.dirname(dlfile) + +# setup svn options + options = [] + if 'rev' in parm: + revision = parm['rev'] + else: + revision = "" + + date = Fetch.getSRCDate(d) + + if "method" in parm: + method = parm["method"] + else: + method = "pserver" + + if "proto" in parm: + proto = parm["proto"] + else: + proto = "svn" + + svn_rsh = None + if method == "ext": + if "rsh" in parm: + svn_rsh = parm["rsh"] + + tarfn = data.expand('%s_%s_%s_%s_%s.tar.gz' % (module.replace('/', '.'), host, path.replace('/', '.'), revision, date), localdata) + data.setVar('TARFILES', dlfile, localdata) + data.setVar('TARFN', tarfn, localdata) + + dl = os.path.join(dldir, tarfn) + if os.access(dl, os.R_OK): + bb.debug(1, "%s already exists, skipping svn checkout." % tarfn) + continue + + svn_tarball_stash = data.getVar('CVS_TARBALL_STASH', d, 1) + if svn_tarball_stash: + fetchcmd = data.getVar("FETCHCOMMAND_wget", d, 1) + uri = svn_tarball_stash + tarfn + bb.note("fetch " + uri) + fetchcmd = fetchcmd.replace("${URI}", uri) + ret = os.system(fetchcmd) + if ret == 0: + bb.note("Fetched %s from tarball stash, skipping checkout" % tarfn) + continue + + olddir = os.path.abspath(os.getcwd()) + os.chdir(data.expand(dldir, localdata)) + +# setup svnroot +# svnroot = ":" + method + ":" + user +# if pswd: +# svnroot += ":" + pswd + svnroot = host + path + + data.setVar('SVNROOT', svnroot, localdata) + data.setVar('SVNCOOPTS', " ".join(options), localdata) + data.setVar('SVNMODULE', module, localdata) + svncmd = data.getVar('FETCHCOMMAND', localdata, 1) + svncmd = "svn co -r {%s} %s://%s/%s" % (date, proto, svnroot, module) + + if revision: + svncmd = "svn co -r %s %s://%s/%s" % (revision, proto, svnroot, module) + if svn_rsh: + svncmd = "svn_RSH=\"%s\" %s" % (svn_rsh, svncmd) + +# create temp directory + bb.debug(2, "Fetch: creating temporary directory") + bb.mkdirhier(data.expand('${WORKDIR}', localdata)) + data.setVar('TMPBASE', data.expand('${WORKDIR}/oesvn.XXXXXX', localdata), localdata) + tmppipe = os.popen(data.getVar('MKTEMPDIRCMD', localdata, 1) or "false") + tmpfile = tmppipe.readline().strip() + if not tmpfile: + bb.error("Fetch: unable to create temporary directory.. make sure 'mktemp' is in the PATH.") + raise FetchError(module) + +# check out sources there + os.chdir(tmpfile) + bb.note("Fetch " + loc) + bb.debug(1, "Running %s" % svncmd) + myret = os.system(svncmd) + if myret != 0: + try: + os.rmdir(tmpfile) + except OSError: + pass + raise FetchError(module) + + os.chdir(os.path.join(tmpfile, os.path.dirname(module))) +# tar them up to a defined filename + myret = os.system("tar -czf %s %s" % (os.path.join(dldir,tarfn), os.path.basename(module))) + if myret != 0: + try: + os.unlink(tarfn) + except OSError: + pass +# cleanup + os.system('rm -rf %s' % tmpfile) + os.chdir(olddir) + del localdata diff --git a/bitbake/lib/bb/fetch/wget.py b/bitbake/lib/bb/fetch/wget.py new file mode 100644 index 000000000..e47a8859b --- /dev/null +++ b/bitbake/lib/bb/fetch/wget.py @@ -0,0 +1,167 @@ +#!/usr/bin/env python +# ex:ts=4:sw=4:sts=4:et +# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- +""" +BitBake 'Fetch' implementations + +Classes for obtaining upstream sources for the +BitBake build tools. + +Copyright (C) 2003, 2004 Chris Larson + +This program is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free Software +Foundation; either version 2 of the License, or (at your option) any later +version. + +This program is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with +this program; if not, write to the Free Software Foundation, Inc., 59 Temple +Place, Suite 330, Boston, MA 02111-1307 USA. + +Based on functions from the base bb module, Copyright 2003 Holger Schurig +""" + +import os, re +import bb +from bb import data +from bb.fetch import Fetch +from bb.fetch import FetchError +from bb.fetch import MD5SumError +from bb.fetch import uri_replace + +class Wget(Fetch): + """Class to fetch urls via 'wget'""" + def supports(url, d): + """Check to see if a given url can be fetched using wget. + Expects supplied url in list form, as outputted by bb.decodeurl(). + """ + (type, host, path, user, pswd, parm) = bb.decodeurl(data.expand(url, d)) + return type in ['http','https','ftp'] + supports = staticmethod(supports) + + def localpath(url, d): +# strip off parameters + (type, host, path, user, pswd, parm) = bb.decodeurl(data.expand(url, d)) + if "localpath" in parm: +# if user overrides local path, use it. + return parm["localpath"] + url = bb.encodeurl([type, host, path, user, pswd, {}]) + + return os.path.join(data.getVar("DL_DIR", d), os.path.basename(url)) + localpath = staticmethod(localpath) + + def go(self, d, urls = []): + """Fetch urls""" + + def md5_sum(parm, d): + """ + Return the MD5SUM associated with the to be downloaded + file. + It can return None if no md5sum is associated + """ + try: + return parm['md5sum'] + except: + return None + + def verify_md5sum(wanted_sum, got_sum): + """ + Verify the md5sum we wanted with the one we got + """ + if not wanted_sum: + return True + + return wanted_sum == got_sum + + def fetch_uri(uri, basename, dl, md5, parm, d): + # the MD5 sum we want to verify + wanted_md5sum = md5_sum(parm, d) + if os.path.exists(dl): +# file exists, but we didnt complete it.. trying again.. + fetchcmd = data.getVar("RESUMECOMMAND", d, 1) + else: + fetchcmd = data.getVar("FETCHCOMMAND", d, 1) + + bb.note("fetch " + uri) + fetchcmd = fetchcmd.replace("${URI}", uri) + fetchcmd = fetchcmd.replace("${FILE}", basename) + bb.debug(2, "executing " + fetchcmd) + ret = os.system(fetchcmd) + if ret != 0: + return False + + # check if sourceforge did send us to the mirror page + dl_dir = data.getVar("DL_DIR", d, True) + if not os.path.exists(dl): + os.system("rm %s*" % dl) # FIXME shell quote it + bb.debug(2,"sourceforge.net send us to the mirror on %s" % basename) + return False + +# supposedly complete.. write out md5sum + if bb.which(data.getVar('PATH', d), 'md5sum'): + try: + md5pipe = os.popen('md5sum ' + dl) + md5data = (md5pipe.readline().split() or [ "" ])[0] + md5pipe.close() + except OSError: + md5data = "" + + # verify the md5sum + if not verify_md5sum(wanted_md5sum, md5data): + raise MD5SumError(uri) + + md5out = file(md5, 'w') + md5out.write(md5data) + md5out.close() + return True + + if not urls: + urls = self.urls + + localdata = data.createCopy(d) + data.setVar('OVERRIDES', "wget:" + data.getVar('OVERRIDES', localdata), localdata) + data.update_data(localdata) + + for uri in urls: + completed = 0 + (type, host, path, user, pswd, parm) = bb.decodeurl(data.expand(uri, localdata)) + basename = os.path.basename(path) + dl = self.localpath(uri, d) + dl = data.expand(dl, localdata) + md5 = dl + '.md5' + + if os.path.exists(md5): +# complete, nothing to see here.. + continue + + premirrors = [ i.split() for i in (data.getVar('PREMIRRORS', localdata, 1) or "").split('\n') if i ] + for (find, replace) in premirrors: + newuri = uri_replace(uri, find, replace, d) + if newuri != uri: + if fetch_uri(newuri, basename, dl, md5, parm, localdata): + completed = 1 + break + + if completed: + continue + + if fetch_uri(uri, basename, dl, md5, parm, localdata): + continue + +# try mirrors + mirrors = [ i.split() for i in (data.getVar('MIRRORS', localdata, 1) or "").split('\n') if i ] + for (find, replace) in mirrors: + newuri = uri_replace(uri, find, replace, d) + if newuri != uri: + if fetch_uri(newuri, basename, dl, md5, parm, localdata): + completed = 1 + break + + if not completed: + raise FetchError(uri) + + del localdata -- cgit v1.2.3