blob: 8a291935c1237024763d6aa9f87f41a09074cbe3 [file] [log] [blame]
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001# ex:ts=4:sw=4:sts=4:et
2# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
3"""
4BitBake 'Fetch' implementation for svn.
5
6"""
7
8# Copyright (C) 2003, 2004 Chris Larson
9# Copyright (C) 2004 Marcin Juszkiewicz
10#
11# This program is free software; you can redistribute it and/or modify
12# it under the terms of the GNU General Public License version 2 as
13# published by the Free Software Foundation.
14#
15# This program is distributed in the hope that it will be useful,
16# but WITHOUT ANY WARRANTY; without even the implied warranty of
17# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18# GNU General Public License for more details.
19#
20# You should have received a copy of the GNU General Public License along
21# with this program; if not, write to the Free Software Foundation, Inc.,
22# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
23#
24# Based on functions from the base bb module, Copyright 2003 Holger Schurig
25
26import os
27import sys
28import logging
29import bb
30import re
31from bb import data
32from bb.fetch2 import FetchMethod
33from bb.fetch2 import FetchError
34from bb.fetch2 import MissingParameterError
35from bb.fetch2 import runfetchcmd
36from bb.fetch2 import logger
37
38class Svn(FetchMethod):
39 """Class to fetch a module or modules from svn repositories"""
40 def supports(self, ud, d):
41 """
42 Check to see if a given url can be fetched with svn.
43 """
44 return ud.type in ['svn']
45
46 def urldata_init(self, ud, d):
47 """
48 init svn specific variable within url data
49 """
50 if not "module" in ud.parm:
51 raise MissingParameterError('module', ud.url)
52
53 ud.basecmd = d.getVar('FETCHCMD_svn', True)
54
55 ud.module = ud.parm["module"]
56
Patrick Williamsf1e5d692016-03-30 15:21:19 -050057 if not "path_spec" in ud.parm:
58 ud.path_spec = ud.module
59 else:
60 ud.path_spec = ud.parm["path_spec"]
61
Patrick Williamsc124f4f2015-09-15 14:41:29 -050062 # Create paths to svn checkouts
63 relpath = self._strip_leading_slashes(ud.path)
64 ud.pkgdir = os.path.join(data.expand('${SVNDIR}', d), ud.host, relpath)
65 ud.moddir = os.path.join(ud.pkgdir, ud.module)
66
67 ud.setup_revisons(d)
68
69 if 'rev' in ud.parm:
70 ud.revision = ud.parm['rev']
71
72 ud.localfile = data.expand('%s_%s_%s_%s_.tar.gz' % (ud.module.replace('/', '.'), ud.host, ud.path.replace('/', '.'), ud.revision), d)
73
74 def _buildsvncommand(self, ud, d, command):
75 """
76 Build up an svn commandline based on ud
77 command is "fetch", "update", "info"
78 """
79
80 proto = ud.parm.get('protocol', 'svn')
81
82 svn_rsh = None
83 if proto == "svn+ssh" and "rsh" in ud.parm:
84 svn_rsh = ud.parm["rsh"]
85
86 svnroot = ud.host + ud.path
87
88 options = []
89
90 options.append("--no-auth-cache")
91
92 if ud.user:
93 options.append("--username %s" % ud.user)
94
95 if ud.pswd:
96 options.append("--password %s" % ud.pswd)
97
98 if command == "info":
99 svncmd = "%s info %s %s://%s/%s/" % (ud.basecmd, " ".join(options), proto, svnroot, ud.module)
100 elif command == "log1":
101 svncmd = "%s log --limit 1 %s %s://%s/%s/" % (ud.basecmd, " ".join(options), proto, svnroot, ud.module)
102 else:
103 suffix = ""
104 if ud.revision:
105 options.append("-r %s" % ud.revision)
106 suffix = "@%s" % (ud.revision)
107
108 if command == "fetch":
109 transportuser = ud.parm.get("transportuser", "")
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500110 svncmd = "%s co %s %s://%s%s/%s%s %s" % (ud.basecmd, " ".join(options), proto, transportuser, svnroot, ud.module, suffix, ud.path_spec)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500111 elif command == "update":
112 svncmd = "%s update %s" % (ud.basecmd, " ".join(options))
113 else:
114 raise FetchError("Invalid svn command %s" % command, ud.url)
115
116 if svn_rsh:
117 svncmd = "svn_RSH=\"%s\" %s" % (svn_rsh, svncmd)
118
119 return svncmd
120
121 def download(self, ud, d):
122 """Fetch url"""
123
124 logger.debug(2, "Fetch: checking for module directory '" + ud.moddir + "'")
125
126 if os.access(os.path.join(ud.moddir, '.svn'), os.R_OK):
127 svnupdatecmd = self._buildsvncommand(ud, d, "update")
128 logger.info("Update " + ud.url)
129 # update sources there
130 os.chdir(ud.moddir)
131 # We need to attempt to run svn upgrade first in case its an older working format
132 try:
133 runfetchcmd(ud.basecmd + " upgrade", d)
134 except FetchError:
135 pass
136 logger.debug(1, "Running %s", svnupdatecmd)
137 bb.fetch2.check_network_access(d, svnupdatecmd, ud.url)
138 runfetchcmd(svnupdatecmd, d)
139 else:
140 svnfetchcmd = self._buildsvncommand(ud, d, "fetch")
141 logger.info("Fetch " + ud.url)
142 # check out sources there
143 bb.utils.mkdirhier(ud.pkgdir)
144 os.chdir(ud.pkgdir)
145 logger.debug(1, "Running %s", svnfetchcmd)
146 bb.fetch2.check_network_access(d, svnfetchcmd, ud.url)
147 runfetchcmd(svnfetchcmd, d)
148
149 scmdata = ud.parm.get("scmdata", "")
150 if scmdata == "keep":
151 tar_flags = ""
152 else:
153 tar_flags = "--exclude '.svn'"
154
155 os.chdir(ud.pkgdir)
156 # tar them up to a defined filename
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500157 runfetchcmd("tar %s -czf %s %s" % (tar_flags, ud.localpath, ud.path_spec), d, cleanup = [ud.localpath])
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500158
159 def clean(self, ud, d):
160 """ Clean SVN specific files and dirs """
161
162 bb.utils.remove(ud.localpath)
163 bb.utils.remove(ud.moddir, True)
164
165
166 def supports_srcrev(self):
167 return True
168
169 def _revision_key(self, ud, d, name):
170 """
171 Return a unique key for the url
172 """
173 return "svn:" + ud.moddir
174
175 def _latest_revision(self, ud, d, name):
176 """
177 Return the latest upstream revision number
178 """
179 bb.fetch2.check_network_access(d, self._buildsvncommand(ud, d, "log1"))
180
181 output = runfetchcmd("LANG=C LC_ALL=C " + self._buildsvncommand(ud, d, "log1"), d, True)
182
183 # skip the first line, as per output of svn log
184 # then we expect the revision on the 2nd line
185 revision = re.search('^r([0-9]*)', output.splitlines()[1]).group(1)
186
187 return revision
188
189 def sortable_revision(self, ud, d, name):
190 """
191 Return a sortable revision number which in our case is the revision number
192 """
193
194 return False, self._build_revision(ud, d)
195
196 def _build_revision(self, ud, d):
197 return ud.revision