bitbake/lib/bb/fetch:
[bitbake.git] / lib / bb / fetch / svn.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 from   bb.fetch import Fetch
32 from   bb.fetch import FetchError
33 from   bb.fetch import MissingParameterError
34
35 class Svn(Fetch):
36     """Class to fetch a module or modules from svn repositories"""
37     def supports(url, d):
38         """Check to see if a given url can be fetched with svn.
39            Expects supplied url in list form, as outputted by bb.decodeurl().
40         """
41         (type, host, path, user, pswd, parm) = bb.decodeurl(data.expand(url, d))
42         return type in ['svn']
43     supports = staticmethod(supports)
44
45     def localpath(url, d):
46         (type, host, path, user, pswd, parm) = bb.decodeurl(data.expand(url, d))
47         if "localpath" in parm:
48 #           if user overrides local path, use it.
49             return parm["localpath"]
50
51         if not "module" in parm:
52             raise MissingParameterError("svn method needs a 'module' parameter")
53         else:
54             module = parm["module"]
55         if 'rev' in parm:
56             revision = parm['rev']
57         else:
58             revision = ""
59
60         date = Fetch.getSRCDate(d)
61
62         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))
63     localpath = staticmethod(localpath)
64
65     def go(self, d, urls = []):
66         """Fetch urls"""
67         if not urls:
68             urls = self.urls
69
70         localdata = data.createCopy(d)
71         data.setVar('OVERRIDES', "svn:%s" % data.getVar('OVERRIDES', localdata), localdata)
72         data.update_data(localdata)
73
74         for loc in urls:
75             (type, host, path, user, pswd, parm) = bb.decodeurl(data.expand(loc, localdata))
76             if not "module" in parm:
77                 raise MissingParameterError("svn method needs a 'module' parameter")
78             else:
79                 module = parm["module"]
80
81             dlfile = self.localpath(loc, localdata)
82             dldir = data.getVar('DL_DIR', localdata, 1)
83 #           if local path contains the svn
84 #           module, consider the dir above it to be the
85 #           download directory
86 #           pos = dlfile.find(module)
87 #           if pos:
88 #               dldir = dlfile[:pos]
89 #           else:
90 #               dldir = os.path.dirname(dlfile)
91
92 #           setup svn options
93             options = []
94             if 'rev' in parm:
95                 revision = parm['rev']
96             else:
97                 revision = ""
98
99             date = Fetch.getSRCDate(d)
100
101             if "method" in parm:
102                 method = parm["method"]
103             else:
104                 method = "pserver"
105
106             if "proto" in parm:
107                 proto = parm["proto"]
108             else:
109                 proto = "svn"
110
111             svn_rsh = None
112             if method == "ext":
113                 if "rsh" in parm:
114                     svn_rsh = parm["rsh"]
115
116             tarfn = data.expand('%s_%s_%s_%s_%s.tar.gz' % (module.replace('/', '.'), host, path.replace('/', '.'), revision, date), localdata)
117             data.setVar('TARFILES', dlfile, localdata)
118             data.setVar('TARFN', tarfn, localdata)
119
120             dl = os.path.join(dldir, tarfn)
121             if os.access(dl, os.R_OK):
122                 bb.debug(1, "%s already exists, skipping svn checkout." % tarfn)
123                 continue
124
125             svn_tarball_stash = data.getVar('CVS_TARBALL_STASH', d, 1)
126             if svn_tarball_stash:
127                 fetchcmd = data.getVar("FETCHCOMMAND_wget", d, 1)
128                 uri = svn_tarball_stash + tarfn
129                 bb.note("fetch " + uri)
130                 fetchcmd = fetchcmd.replace("${URI}", uri)
131                 ret = os.system(fetchcmd)
132                 if ret == 0:
133                     bb.note("Fetched %s from tarball stash, skipping checkout" % tarfn)
134                     continue
135
136             olddir = os.path.abspath(os.getcwd())
137             os.chdir(data.expand(dldir, localdata))
138
139 #           setup svnroot
140 #            svnroot = ":" + method + ":" + user
141 #            if pswd:
142 #                svnroot += ":" + pswd
143             svnroot = host + path
144
145             data.setVar('SVNROOT', svnroot, localdata)
146             data.setVar('SVNCOOPTS', " ".join(options), localdata)
147             data.setVar('SVNMODULE', module, localdata)
148             svncmd = data.getVar('FETCHCOMMAND', localdata, 1)
149             svncmd = "svn co -r {%s} %s://%s/%s" % (date, proto, svnroot, module)
150
151             if revision:
152                 svncmd = "svn co -r %s %s://%s/%s" % (revision, proto, svnroot, module)
153             if svn_rsh:
154                 svncmd = "svn_RSH=\"%s\" %s" % (svn_rsh, svncmd)
155
156 #           create temp directory
157             bb.debug(2, "Fetch: creating temporary directory")
158             bb.mkdirhier(data.expand('${WORKDIR}', localdata))
159             data.setVar('TMPBASE', data.expand('${WORKDIR}/oesvn.XXXXXX', localdata), localdata)
160             tmppipe = os.popen(data.getVar('MKTEMPDIRCMD', localdata, 1) or "false")
161             tmpfile = tmppipe.readline().strip()
162             if not tmpfile:
163                 bb.error("Fetch: unable to create temporary directory.. make sure 'mktemp' is in the PATH.")
164                 raise FetchError(module)
165
166 #           check out sources there
167             os.chdir(tmpfile)
168             bb.note("Fetch " + loc)
169             bb.debug(1, "Running %s" % svncmd)
170             myret = os.system(svncmd)
171             if myret != 0:
172                 try:
173                     os.rmdir(tmpfile)
174                 except OSError:
175                     pass
176                 raise FetchError(module)
177
178             os.chdir(os.path.join(tmpfile, os.path.dirname(module)))
179 #           tar them up to a defined filename
180             myret = os.system("tar -czf %s %s" % (os.path.join(dldir,tarfn), os.path.basename(module)))
181             if myret != 0:
182                 try:
183                     os.unlink(tarfn)
184                 except OSError:
185                     pass
186 #           cleanup
187             os.system('rm -rf %s' % tmpfile)
188             os.chdir(olddir)
189         del localdata