diff options
author | Richard Purdie <richard.purdie@linuxfoundation.org> | 2022-01-19 14:13:48 +0000 |
---|---|---|
committer | Richard Purdie <richard.purdie@linuxfoundation.org> | 2022-01-19 23:03:43 +0000 |
commit | 12c76723fb65437a3439d2c1f429ae73a00edc4b (patch) | |
tree | 3b9a6bfe4b5a5836f684ac3b55e22389133dd23b | |
parent | e222be06386698e24c664171bd6a1ea07bf28efa (diff) | |
download | poky-12c76723fb65437a3439d2c1f429ae73a00edc4b.tar.gz |
bitbake: fetch2: Add crate fetcher
This imports the crate fetcher from OE-Core to resolve various module issues
and adds some very very basic tests of that new fetcher.
(Bitbake rev: 1f06f326fa8b47e2a4dce756d57a9369a2225201)
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
-rw-r--r-- | bitbake/lib/bb/fetch2/__init__.py | 2 | ||||
-rw-r--r-- | bitbake/lib/bb/fetch2/crate.py | 137 | ||||
-rw-r--r-- | bitbake/lib/bb/tests/fetch.py | 35 |
3 files changed, 174 insertions, 0 deletions
diff --git a/bitbake/lib/bb/fetch2/__init__.py b/bitbake/lib/bb/fetch2/__init__.py index 0b39ea6aaa..d37174185a 100644 --- a/bitbake/lib/bb/fetch2/__init__.py +++ b/bitbake/lib/bb/fetch2/__init__.py | |||
@@ -1942,6 +1942,7 @@ from . import clearcase | |||
1942 | from . import npm | 1942 | from . import npm |
1943 | from . import npmsw | 1943 | from . import npmsw |
1944 | from . import az | 1944 | from . import az |
1945 | from . import crate | ||
1945 | 1946 | ||
1946 | methods.append(local.Local()) | 1947 | methods.append(local.Local()) |
1947 | methods.append(wget.Wget()) | 1948 | methods.append(wget.Wget()) |
@@ -1962,3 +1963,4 @@ methods.append(clearcase.ClearCase()) | |||
1962 | methods.append(npm.Npm()) | 1963 | methods.append(npm.Npm()) |
1963 | methods.append(npmsw.NpmShrinkWrap()) | 1964 | methods.append(npmsw.NpmShrinkWrap()) |
1964 | methods.append(az.Az()) | 1965 | methods.append(az.Az()) |
1966 | methods.append(crate.Crate()) | ||
diff --git a/bitbake/lib/bb/fetch2/crate.py b/bitbake/lib/bb/fetch2/crate.py new file mode 100644 index 0000000000..f7e2354afb --- /dev/null +++ b/bitbake/lib/bb/fetch2/crate.py | |||
@@ -0,0 +1,137 @@ | |||
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' implementation for crates.io | ||
5 | """ | ||
6 | |||
7 | # Copyright (C) 2016 Doug Goldstein | ||
8 | # | ||
9 | # SPDX-License-Identifier: GPL-2.0-only | ||
10 | # | ||
11 | # Based on functions from the base bb module, Copyright 2003 Holger Schurig | ||
12 | |||
13 | import hashlib | ||
14 | import json | ||
15 | import os | ||
16 | import shutil | ||
17 | import subprocess | ||
18 | import bb | ||
19 | from bb.fetch2 import logger, subprocess_setup, UnpackError | ||
20 | from bb.fetch2.wget import Wget | ||
21 | |||
22 | |||
23 | class Crate(Wget): | ||
24 | |||
25 | """Class to fetch crates via wget""" | ||
26 | |||
27 | def _cargo_bitbake_path(self, rootdir): | ||
28 | return os.path.join(rootdir, "cargo_home", "bitbake") | ||
29 | |||
30 | def supports(self, ud, d): | ||
31 | """ | ||
32 | Check to see if a given url is for this fetcher | ||
33 | """ | ||
34 | return ud.type in ['crate'] | ||
35 | |||
36 | def recommends_checksum(self, urldata): | ||
37 | return False | ||
38 | |||
39 | def urldata_init(self, ud, d): | ||
40 | """ | ||
41 | Sets up to download the respective crate from crates.io | ||
42 | """ | ||
43 | |||
44 | if ud.type == 'crate': | ||
45 | self._crate_urldata_init(ud, d) | ||
46 | |||
47 | super(Crate, self).urldata_init(ud, d) | ||
48 | |||
49 | def _crate_urldata_init(self, ud, d): | ||
50 | """ | ||
51 | Sets up the download for a crate | ||
52 | """ | ||
53 | |||
54 | # URL syntax is: crate://NAME/VERSION | ||
55 | # break the URL apart by / | ||
56 | parts = ud.url.split('/') | ||
57 | if len(parts) < 5: | ||
58 | raise bb.fetch2.ParameterError("Invalid URL: Must be crate://HOST/NAME/VERSION", ud.url) | ||
59 | |||
60 | # last field is version | ||
61 | version = parts[len(parts) - 1] | ||
62 | # second to last field is name | ||
63 | name = parts[len(parts) - 2] | ||
64 | # host (this is to allow custom crate registries to be specified | ||
65 | host = '/'.join(parts[2:len(parts) - 2]) | ||
66 | |||
67 | # if using upstream just fix it up nicely | ||
68 | if host == 'crates.io': | ||
69 | host = 'crates.io/api/v1/crates' | ||
70 | |||
71 | ud.url = "https://%s/%s/%s/download" % (host, name, version) | ||
72 | ud.parm['downloadfilename'] = "%s-%s.crate" % (name, version) | ||
73 | ud.parm['name'] = name | ||
74 | |||
75 | logger.debug(2, "Fetching %s to %s" % (ud.url, ud.parm['downloadfilename'])) | ||
76 | |||
77 | def unpack(self, ud, rootdir, d): | ||
78 | """ | ||
79 | Uses the crate to build the necessary paths for cargo to utilize it | ||
80 | """ | ||
81 | if ud.type == 'crate': | ||
82 | return self._crate_unpack(ud, rootdir, d) | ||
83 | else: | ||
84 | super(Crate, self).unpack(ud, rootdir, d) | ||
85 | |||
86 | def _crate_unpack(self, ud, rootdir, d): | ||
87 | """ | ||
88 | Unpacks a crate | ||
89 | """ | ||
90 | thefile = ud.localpath | ||
91 | |||
92 | # possible metadata we need to write out | ||
93 | metadata = {} | ||
94 | |||
95 | # change to the rootdir to unpack but save the old working dir | ||
96 | save_cwd = os.getcwd() | ||
97 | os.chdir(rootdir) | ||
98 | |||
99 | pn = d.getVar('BPN') | ||
100 | if pn == ud.parm.get('name'): | ||
101 | cmd = "tar -xz --no-same-owner -f %s" % thefile | ||
102 | else: | ||
103 | cargo_bitbake = self._cargo_bitbake_path(rootdir) | ||
104 | |||
105 | cmd = "tar -xz --no-same-owner -f %s -C %s" % (thefile, cargo_bitbake) | ||
106 | |||
107 | # ensure we've got these paths made | ||
108 | bb.utils.mkdirhier(cargo_bitbake) | ||
109 | |||
110 | # generate metadata necessary | ||
111 | with open(thefile, 'rb') as f: | ||
112 | # get the SHA256 of the original tarball | ||
113 | tarhash = hashlib.sha256(f.read()).hexdigest() | ||
114 | |||
115 | metadata['files'] = {} | ||
116 | metadata['package'] = tarhash | ||
117 | |||
118 | path = d.getVar('PATH') | ||
119 | if path: | ||
120 | cmd = "PATH=\"%s\" %s" % (path, cmd) | ||
121 | bb.note("Unpacking %s to %s/" % (thefile, os.getcwd())) | ||
122 | |||
123 | ret = subprocess.call(cmd, preexec_fn=subprocess_setup, shell=True) | ||
124 | |||
125 | os.chdir(save_cwd) | ||
126 | |||
127 | if ret != 0: | ||
128 | raise UnpackError("Unpack command %s failed with return value %s" % (cmd, ret), ud.url) | ||
129 | |||
130 | # if we have metadata to write out.. | ||
131 | if len(metadata) > 0: | ||
132 | cratepath = os.path.splitext(os.path.basename(thefile))[0] | ||
133 | bbpath = self._cargo_bitbake_path(rootdir) | ||
134 | mdfile = '.cargo-checksum.json' | ||
135 | mdpath = os.path.join(bbpath, cratepath, mdfile) | ||
136 | with open(mdpath, "w") as f: | ||
137 | json.dump(metadata, f) | ||
diff --git a/bitbake/lib/bb/tests/fetch.py b/bitbake/lib/bb/tests/fetch.py index 2a046d0ded..ec7d83c959 100644 --- a/bitbake/lib/bb/tests/fetch.py +++ b/bitbake/lib/bb/tests/fetch.py | |||
@@ -2260,6 +2260,41 @@ class GitURLWithSpacesTest(FetcherTest): | |||
2260 | self.assertEqual(ud.clonedir, os.path.join(self.dldir, "git2", ref['gitsrcname'])) | 2260 | self.assertEqual(ud.clonedir, os.path.join(self.dldir, "git2", ref['gitsrcname'])) |
2261 | self.assertEqual(ud.fullmirror, os.path.join(self.dldir, "git2_" + ref['gitsrcname'] + '.tar.gz')) | 2261 | self.assertEqual(ud.fullmirror, os.path.join(self.dldir, "git2_" + ref['gitsrcname'] + '.tar.gz')) |
2262 | 2262 | ||
2263 | class CrateTest(FetcherTest): | ||
2264 | def test_crate_url(self): | ||
2265 | |||
2266 | uri = "crate://crates.io/glob/0.2.11" | ||
2267 | self.d.setVar('SRC_URI', uri) | ||
2268 | |||
2269 | uris = self.d.getVar('SRC_URI').split() | ||
2270 | d = self.d | ||
2271 | |||
2272 | fetcher = bb.fetch2.Fetch(uris, self.d) | ||
2273 | fetcher.download() | ||
2274 | fetcher.unpack(self.tempdir) | ||
2275 | self.assertEqual(sorted(os.listdir(self.tempdir)), ['cargo_home', 'download' , 'unpacked']) | ||
2276 | self.assertEqual(sorted(os.listdir(self.tempdir + "/download")), ['glob-0.2.11.crate', 'glob-0.2.11.crate.done']) | ||
2277 | self.assertTrue(os.path.exists(self.tempdir + "/cargo_home/bitbake/glob-0.2.11/.cargo-checksum.json")) | ||
2278 | self.assertTrue(os.path.exists(self.tempdir + "/cargo_home/bitbake/glob-0.2.11/src/lib.rs")) | ||
2279 | |||
2280 | def test_crate_url_multi(self): | ||
2281 | |||
2282 | uri = "crate://crates.io/glob/0.2.11 crate://crates.io/time/0.1.35" | ||
2283 | self.d.setVar('SRC_URI', uri) | ||
2284 | |||
2285 | uris = self.d.getVar('SRC_URI').split() | ||
2286 | d = self.d | ||
2287 | |||
2288 | fetcher = bb.fetch2.Fetch(uris, self.d) | ||
2289 | fetcher.download() | ||
2290 | fetcher.unpack(self.tempdir) | ||
2291 | self.assertEqual(sorted(os.listdir(self.tempdir)), ['cargo_home', 'download' , 'unpacked']) | ||
2292 | self.assertEqual(sorted(os.listdir(self.tempdir + "/download")), ['glob-0.2.11.crate', 'glob-0.2.11.crate.done', 'time-0.1.35.crate', 'time-0.1.35.crate.done']) | ||
2293 | self.assertTrue(os.path.exists(self.tempdir + "/cargo_home/bitbake/glob-0.2.11/.cargo-checksum.json")) | ||
2294 | self.assertTrue(os.path.exists(self.tempdir + "/cargo_home/bitbake/glob-0.2.11/src/lib.rs")) | ||
2295 | self.assertTrue(os.path.exists(self.tempdir + "/cargo_home/bitbake/time-0.1.35/.cargo-checksum.json")) | ||
2296 | self.assertTrue(os.path.exists(self.tempdir + "/cargo_home/bitbake/time-0.1.35/src/lib.rs")) | ||
2297 | |||
2263 | class NPMTest(FetcherTest): | 2298 | class NPMTest(FetcherTest): |
2264 | def skipIfNoNpm(): | 2299 | def skipIfNoNpm(): |
2265 | import shutil | 2300 | import shutil |