mirror of
https://git.yoctoproject.org/poky
synced 2026-02-10 18:53:13 +01:00
This allow to have classic fetch parameters (like destsuffix, sha256, name ...) not being considered by crate fetcher itself (and so mess up its download) Moreover, it allow to overload the name of the downloaded crate (maybe usefull if there is a naming clash between two crates coming from different repositories) (Bitbake rev: 278bd2f1758b8af97552af8d23d16ffb5127a131) Signed-off-by: Frederic Martinsons <frederic.martinsons@gmail.com> Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
140 lines
4.2 KiB
Python
140 lines
4.2 KiB
Python
# ex:ts=4:sw=4:sts=4:et
|
|
# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
|
|
"""
|
|
BitBake 'Fetch' implementation for crates.io
|
|
"""
|
|
|
|
# Copyright (C) 2016 Doug Goldstein
|
|
#
|
|
# SPDX-License-Identifier: GPL-2.0-only
|
|
#
|
|
# Based on functions from the base bb module, Copyright 2003 Holger Schurig
|
|
|
|
import hashlib
|
|
import json
|
|
import os
|
|
import subprocess
|
|
import bb
|
|
from bb.fetch2 import logger, subprocess_setup, UnpackError
|
|
from bb.fetch2.wget import Wget
|
|
|
|
|
|
class Crate(Wget):
|
|
|
|
"""Class to fetch crates via wget"""
|
|
|
|
def _cargo_bitbake_path(self, rootdir):
|
|
return os.path.join(rootdir, "cargo_home", "bitbake")
|
|
|
|
def supports(self, ud, d):
|
|
"""
|
|
Check to see if a given url is for this fetcher
|
|
"""
|
|
return ud.type in ['crate']
|
|
|
|
def recommends_checksum(self, urldata):
|
|
return False
|
|
|
|
def urldata_init(self, ud, d):
|
|
"""
|
|
Sets up to download the respective crate from crates.io
|
|
"""
|
|
|
|
if ud.type == 'crate':
|
|
self._crate_urldata_init(ud, d)
|
|
|
|
super(Crate, self).urldata_init(ud, d)
|
|
|
|
def _crate_urldata_init(self, ud, d):
|
|
"""
|
|
Sets up the download for a crate
|
|
"""
|
|
|
|
# URL syntax is: crate://NAME/VERSION
|
|
# break the URL apart by /
|
|
parts = ud.url.split('/')
|
|
if len(parts) < 5:
|
|
raise bb.fetch2.ParameterError("Invalid URL: Must be crate://HOST/NAME/VERSION", ud.url)
|
|
|
|
# version is expected to be the last token
|
|
# but ignore possible url parameters which will be used
|
|
# by the top fetcher class
|
|
version, _, _ = parts[len(parts) -1].partition(";")
|
|
# second to last field is name
|
|
name = parts[len(parts) - 2]
|
|
# host (this is to allow custom crate registries to be specified
|
|
host = '/'.join(parts[2:len(parts) - 2])
|
|
|
|
# if using upstream just fix it up nicely
|
|
if host == 'crates.io':
|
|
host = 'crates.io/api/v1/crates'
|
|
|
|
ud.url = "https://%s/%s/%s/download" % (host, name, version)
|
|
ud.parm['downloadfilename'] = "%s-%s.crate" % (name, version)
|
|
if 'name' not in ud.parm:
|
|
ud.parm['name'] = name
|
|
|
|
logger.debug2("Fetching %s to %s" % (ud.url, ud.parm['downloadfilename']))
|
|
|
|
def unpack(self, ud, rootdir, d):
|
|
"""
|
|
Uses the crate to build the necessary paths for cargo to utilize it
|
|
"""
|
|
if ud.type == 'crate':
|
|
return self._crate_unpack(ud, rootdir, d)
|
|
else:
|
|
super(Crate, self).unpack(ud, rootdir, d)
|
|
|
|
def _crate_unpack(self, ud, rootdir, d):
|
|
"""
|
|
Unpacks a crate
|
|
"""
|
|
thefile = ud.localpath
|
|
|
|
# possible metadata we need to write out
|
|
metadata = {}
|
|
|
|
# change to the rootdir to unpack but save the old working dir
|
|
save_cwd = os.getcwd()
|
|
os.chdir(rootdir)
|
|
|
|
pn = d.getVar('BPN')
|
|
if pn == ud.parm.get('name'):
|
|
cmd = "tar -xz --no-same-owner -f %s" % thefile
|
|
else:
|
|
cargo_bitbake = self._cargo_bitbake_path(rootdir)
|
|
|
|
cmd = "tar -xz --no-same-owner -f %s -C %s" % (thefile, cargo_bitbake)
|
|
|
|
# ensure we've got these paths made
|
|
bb.utils.mkdirhier(cargo_bitbake)
|
|
|
|
# generate metadata necessary
|
|
with open(thefile, 'rb') as f:
|
|
# get the SHA256 of the original tarball
|
|
tarhash = hashlib.sha256(f.read()).hexdigest()
|
|
|
|
metadata['files'] = {}
|
|
metadata['package'] = tarhash
|
|
|
|
path = d.getVar('PATH')
|
|
if path:
|
|
cmd = "PATH=\"%s\" %s" % (path, cmd)
|
|
bb.note("Unpacking %s to %s/" % (thefile, os.getcwd()))
|
|
|
|
ret = subprocess.call(cmd, preexec_fn=subprocess_setup, shell=True)
|
|
|
|
os.chdir(save_cwd)
|
|
|
|
if ret != 0:
|
|
raise UnpackError("Unpack command %s failed with return value %s" % (cmd, ret), ud.url)
|
|
|
|
# if we have metadata to write out..
|
|
if len(metadata) > 0:
|
|
cratepath = os.path.splitext(os.path.basename(thefile))[0]
|
|
bbpath = self._cargo_bitbake_path(rootdir)
|
|
mdfile = '.cargo-checksum.json'
|
|
mdpath = os.path.join(bbpath, cratepath, mdfile)
|
|
with open(mdpath, "w") as f:
|
|
json.dump(metadata, f)
|