Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 1 | # ex:ts=4:sw=4:sts=4:et |
| 2 | # -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- |
| 3 | """ |
| 4 | BitBake 'Fetch' implementations |
| 5 | |
| 6 | Classes for obtaining upstream sources for the |
| 7 | BitBake build tools. |
| 8 | |
| 9 | """ |
| 10 | |
| 11 | # Copyright (C) 2003, 2004 Chris Larson |
| 12 | # |
| 13 | # This program is free software; you can redistribute it and/or modify |
| 14 | # it under the terms of the GNU General Public License version 2 as |
| 15 | # published by the Free Software Foundation. |
| 16 | # |
| 17 | # This program is distributed in the hope that it will be useful, |
| 18 | # but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 19 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 20 | # GNU General Public License for more details. |
| 21 | # |
| 22 | # You should have received a copy of the GNU General Public License along |
| 23 | # with this program; if not, write to the Free Software Foundation, Inc., |
| 24 | # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
| 25 | # |
| 26 | # Based on functions from the base bb module, Copyright 2003 Holger Schurig |
| 27 | |
| 28 | from future_builtins import zip |
| 29 | import os |
| 30 | import subprocess |
| 31 | import logging |
| 32 | import bb |
| 33 | from bb import data |
| 34 | from bb.fetch2 import FetchMethod |
| 35 | from bb.fetch2 import FetchError |
| 36 | from bb.fetch2 import logger |
| 37 | from bb.fetch2 import runfetchcmd |
| 38 | |
| 39 | class Perforce(FetchMethod): |
| 40 | def supports(self, ud, d): |
| 41 | return ud.type in ['p4'] |
| 42 | |
| 43 | def doparse(url, d): |
| 44 | parm = {} |
| 45 | path = url.split("://")[1] |
| 46 | delim = path.find("@"); |
| 47 | if delim != -1: |
| 48 | (user, pswd, host, port) = path.split('@')[0].split(":") |
| 49 | path = path.split('@')[1] |
| 50 | else: |
| 51 | (host, port) = d.getVar('P4PORT', False).split(':') |
| 52 | user = "" |
| 53 | pswd = "" |
| 54 | |
| 55 | if path.find(";") != -1: |
| 56 | keys=[] |
| 57 | values=[] |
| 58 | plist = path.split(';') |
| 59 | for item in plist: |
| 60 | if item.count('='): |
| 61 | (key, value) = item.split('=') |
| 62 | keys.append(key) |
| 63 | values.append(value) |
| 64 | |
| 65 | parm = dict(zip(keys, values)) |
| 66 | path = "//" + path.split(';')[0] |
| 67 | host += ":%s" % (port) |
| 68 | parm["cset"] = Perforce.getcset(d, path, host, user, pswd, parm) |
| 69 | |
| 70 | return host, path, user, pswd, parm |
| 71 | doparse = staticmethod(doparse) |
| 72 | |
| 73 | def getcset(d, depot, host, user, pswd, parm): |
| 74 | p4opt = "" |
| 75 | if "cset" in parm: |
| 76 | return parm["cset"]; |
| 77 | if user: |
| 78 | p4opt += " -u %s" % (user) |
| 79 | if pswd: |
| 80 | p4opt += " -P %s" % (pswd) |
| 81 | if host: |
| 82 | p4opt += " -p %s" % (host) |
| 83 | |
| 84 | p4date = d.getVar("P4DATE", True) |
| 85 | if "revision" in parm: |
| 86 | depot += "#%s" % (parm["revision"]) |
| 87 | elif "label" in parm: |
| 88 | depot += "@%s" % (parm["label"]) |
| 89 | elif p4date: |
| 90 | depot += "@%s" % (p4date) |
| 91 | |
| 92 | p4cmd = d.getVar('FETCHCMD_p4', True) or "p4" |
| 93 | logger.debug(1, "Running %s%s changes -m 1 %s", p4cmd, p4opt, depot) |
| 94 | p4file, errors = bb.process.run("%s%s changes -m 1 %s" % (p4cmd, p4opt, depot)) |
| 95 | cset = p4file.strip() |
| 96 | logger.debug(1, "READ %s", cset) |
| 97 | if not cset: |
| 98 | return -1 |
| 99 | |
| 100 | return cset.split(' ')[1] |
| 101 | getcset = staticmethod(getcset) |
| 102 | |
| 103 | def urldata_init(self, ud, d): |
| 104 | (host, path, user, pswd, parm) = Perforce.doparse(ud.url, d) |
| 105 | |
| 106 | base_path = path.replace('/...', '') |
| 107 | base_path = self._strip_leading_slashes(base_path) |
| 108 | |
| 109 | if "label" in parm: |
| 110 | version = parm["label"] |
| 111 | else: |
| 112 | version = Perforce.getcset(d, path, host, user, pswd, parm) |
| 113 | |
| 114 | ud.localfile = data.expand('%s+%s+%s.tar.gz' % (host, base_path.replace('/', '.'), version), d) |
| 115 | |
| 116 | def download(self, ud, d): |
| 117 | """ |
| 118 | Fetch urls |
| 119 | """ |
| 120 | |
| 121 | (host, depot, user, pswd, parm) = Perforce.doparse(ud.url, d) |
| 122 | |
| 123 | if depot.find('/...') != -1: |
| 124 | path = depot[:depot.find('/...')] |
| 125 | else: |
| 126 | path = depot[:depot.rfind('/')] |
| 127 | |
| 128 | module = parm.get('module', os.path.basename(path)) |
| 129 | |
| 130 | # Get the p4 command |
| 131 | p4opt = "" |
| 132 | if user: |
| 133 | p4opt += " -u %s" % (user) |
| 134 | |
| 135 | if pswd: |
| 136 | p4opt += " -P %s" % (pswd) |
| 137 | |
| 138 | if host: |
| 139 | p4opt += " -p %s" % (host) |
| 140 | |
| 141 | p4cmd = d.getVar('FETCHCMD_p4', True) or "p4" |
| 142 | |
| 143 | # create temp directory |
| 144 | logger.debug(2, "Fetch: creating temporary directory") |
| 145 | bb.utils.mkdirhier(d.expand('${WORKDIR}')) |
| 146 | mktemp = d.getVar("FETCHCMD_p4mktemp", True) or d.expand("mktemp -d -q '${WORKDIR}/oep4.XXXXXX'") |
| 147 | tmpfile, errors = bb.process.run(mktemp) |
| 148 | tmpfile = tmpfile.strip() |
| 149 | if not tmpfile: |
| 150 | raise FetchError("Fetch: unable to create temporary directory.. make sure 'mktemp' is in the PATH.", ud.url) |
| 151 | |
| 152 | if "label" in parm: |
| 153 | depot = "%s@%s" % (depot, parm["label"]) |
| 154 | else: |
| 155 | cset = Perforce.getcset(d, depot, host, user, pswd, parm) |
| 156 | depot = "%s@%s" % (depot, cset) |
| 157 | |
| 158 | os.chdir(tmpfile) |
| 159 | logger.info("Fetch " + ud.url) |
| 160 | logger.info("%s%s files %s", p4cmd, p4opt, depot) |
| 161 | p4file, errors = bb.process.run("%s%s files %s" % (p4cmd, p4opt, depot)) |
| 162 | p4file = [f.rstrip() for f in p4file.splitlines()] |
| 163 | |
| 164 | if not p4file: |
| 165 | raise FetchError("Fetch: unable to get the P4 files from %s" % depot, ud.url) |
| 166 | |
| 167 | count = 0 |
| 168 | |
| 169 | for file in p4file: |
| 170 | list = file.split() |
| 171 | |
| 172 | if list[2] == "delete": |
| 173 | continue |
| 174 | |
| 175 | dest = list[0][len(path)+1:] |
| 176 | where = dest.find("#") |
| 177 | |
| 178 | subprocess.call("%s%s print -o %s/%s %s" % (p4cmd, p4opt, module, dest[:where], list[0]), shell=True) |
| 179 | count = count + 1 |
| 180 | |
| 181 | if count == 0: |
| 182 | logger.error() |
| 183 | raise FetchError("Fetch: No files gathered from the P4 fetch", ud.url) |
| 184 | |
| 185 | runfetchcmd("tar -czf %s %s" % (ud.localpath, module), d, cleanup = [ud.localpath]) |
| 186 | # cleanup |
| 187 | bb.utils.prunedir(tmpfile) |