lib/bb/fetch/cvs.py:
[bitbake.git] / lib / bb / fetch / cvs.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 Cvs(Fetch):
36     """Class to fetch a module or modules from cvs repositories"""
37     def supports(url, d):
38         """Check to see if a given url can be fetched with cvs.
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 ['cvs', 'pserver']
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("cvs method needs a 'module' parameter")
53         else:
54             module = parm["module"]
55         if 'tag' in parm:
56             tag = parm['tag']
57         else:
58             tag = ""
59         if 'date' in parm:
60             date = parm['date']
61         else:
62             if not tag:
63                 date = Fetch.getSRCDate(d)
64             else:
65                 date = ""
66
67         return os.path.join(data.getVar("DL_DIR", d, 1),data.expand('%s_%s_%s_%s.tar.gz' % ( module.replace('/', '.'), host, tag, date), d))
68     localpath = staticmethod(localpath)
69
70     def go(self, d, urls = []):
71         """Fetch urls"""
72         if not urls:
73             urls = self.urls
74
75         localdata = data.createCopy(d)
76         data.setVar('OVERRIDES', "cvs:%s" % data.getVar('OVERRIDES', localdata), localdata)
77         data.update_data(localdata)
78
79         for loc in urls:
80             (type, host, path, user, pswd, parm) = bb.decodeurl(data.expand(loc, localdata))
81             if not "module" in parm:
82                 raise MissingParameterError("cvs method needs a 'module' parameter")
83             else:
84                 module = parm["module"]
85
86             dlfile = self.localpath(loc, localdata)
87             dldir = data.getVar('DL_DIR', localdata, 1)
88 #           if local path contains the cvs
89 #           module, consider the dir above it to be the
90 #           download directory
91 #           pos = dlfile.find(module)
92 #           if pos:
93 #               dldir = dlfile[:pos]
94 #           else:
95 #               dldir = os.path.dirname(dlfile)
96
97 #           setup cvs options
98             options = []
99             if 'tag' in parm:
100                 tag = parm['tag']
101             else:
102                 tag = ""
103
104             if 'date' in parm:
105                 date = parm['date']
106             else:
107                 if not tag:
108                     date = Fetch.getSRCDate(d)
109                 else:
110                     date = ""
111
112             if "method" in parm:
113                 method = parm["method"]
114             else:
115                 method = "pserver"
116
117             if "localdir" in parm:
118                 localdir = parm["localdir"]
119             else:
120                 localdir = module
121
122             cvs_rsh = None
123             if method == "ext":
124                 if "rsh" in parm:
125                     cvs_rsh = parm["rsh"]
126
127             tarfn = data.expand('%s_%s_%s_%s.tar.gz' % (module.replace('/', '.'), host, tag, date), localdata)
128             data.setVar('TARFILES', dlfile, localdata)
129             data.setVar('TARFN', tarfn, localdata)
130
131             # try to use the tarball stash
132             if Fetch.try_mirror(d, tarfn):
133                 bb.debug(1, "%s already exists or was mirrored, skipping cvs checkout." % tarfn)
134                 continue
135
136             if date:
137                 options.append("-D %s" % date)
138             if tag:
139                 options.append("-r %s" % tag)
140
141             olddir = os.path.abspath(os.getcwd())
142             os.chdir(data.expand(dldir, localdata))
143
144 #           setup cvsroot
145             if method == "dir":
146                 cvsroot = path
147             else:
148                 cvsroot = ":" + method + ":" + user
149                 if pswd:
150                     cvsroot += ":" + pswd
151                 cvsroot += "@" + host + ":" + path
152
153             data.setVar('CVSROOT', cvsroot, localdata)
154             data.setVar('CVSCOOPTS', " ".join(options), localdata)
155             data.setVar('CVSMODULE', module, localdata)
156             cvscmd = data.getVar('FETCHCOMMAND', localdata, 1)
157             cvsupdatecmd = data.getVar('UPDATECOMMAND', localdata, 1)
158
159             if cvs_rsh:
160                 cvscmd = "CVS_RSH=\"%s\" %s" % (cvs_rsh, cvscmd)
161                 cvsupdatecmd = "CVS_RSH=\"%s\" %s" % (cvs_rsh, cvsupdatecmd)
162
163 #           create module directory
164             bb.debug(2, "Fetch: checking for module directory")
165             pkg=data.expand('${PN}', d)
166             pkgdir=os.path.join(data.expand('${CVSDIR}', localdata), pkg)
167             moddir=os.path.join(pkgdir,localdir)
168             if os.access(os.path.join(moddir,'CVS'), os.R_OK):
169                 bb.note("Update " + loc)
170 #               update sources there
171                 os.chdir(moddir)
172                 myret = os.system(cvsupdatecmd)
173             else:
174                 bb.note("Fetch " + loc)
175 #               check out sources there
176                 bb.mkdirhier(pkgdir)
177                 os.chdir(pkgdir)
178                 bb.debug(1, "Running %s" % cvscmd)
179                 myret = os.system(cvscmd)
180
181             if myret != 0 or not os.access(moddir, os.R_OK):
182                 try:
183                     os.rmdir(moddir)
184                 except OSError:
185                     pass
186                 raise FetchError(module)
187
188             os.chdir(moddir)
189             os.chdir('..')
190 #           tar them up to a defined filename
191             myret = os.system("tar -czf %s %s" % (os.path.join(dldir,tarfn), os.path.basename(moddir)))
192             if myret != 0:
193                 try:
194                     os.unlink(tarfn)
195                 except OSError:
196                     pass
197             os.chdir(olddir)
198         del localdata