diff options
Diffstat (limited to 'bitbake/lib/bb/fetch2/npmsw.py')
-rw-r--r-- | bitbake/lib/bb/fetch2/npmsw.py | 112 |
1 files changed, 74 insertions, 38 deletions
diff --git a/bitbake/lib/bb/fetch2/npmsw.py b/bitbake/lib/bb/fetch2/npmsw.py index 0c3511d8ab..2f9599ee9e 100644 --- a/bitbake/lib/bb/fetch2/npmsw.py +++ b/bitbake/lib/bb/fetch2/npmsw.py | |||
@@ -24,34 +24,39 @@ import bb | |||
24 | from bb.fetch2 import Fetch | 24 | from bb.fetch2 import Fetch |
25 | from bb.fetch2 import FetchMethod | 25 | from bb.fetch2 import FetchMethod |
26 | from bb.fetch2 import ParameterError | 26 | from bb.fetch2 import ParameterError |
27 | from bb.fetch2 import runfetchcmd | ||
27 | from bb.fetch2 import URI | 28 | from bb.fetch2 import URI |
28 | from bb.fetch2.npm import npm_integrity | 29 | from bb.fetch2.npm import npm_integrity |
29 | from bb.fetch2.npm import npm_localfile | 30 | from bb.fetch2.npm import npm_localfile |
30 | from bb.fetch2.npm import npm_unpack | 31 | from bb.fetch2.npm import npm_unpack |
31 | from bb.utils import is_semver | 32 | from bb.utils import is_semver |
33 | from bb.utils import lockfile | ||
34 | from bb.utils import unlockfile | ||
32 | 35 | ||
33 | def foreach_dependencies(shrinkwrap, callback=None, dev=False): | 36 | def foreach_dependencies(shrinkwrap, callback=None, dev=False): |
34 | """ | 37 | """ |
35 | Run a callback for each dependencies of a shrinkwrap file. | 38 | Run a callback for each dependencies of a shrinkwrap file. |
36 | The callback is using the format: | 39 | The callback is using the format: |
37 | callback(name, params, deptree) | 40 | callback(name, data, location) |
38 | with: | 41 | with: |
39 | name = the package name (string) | 42 | name = the package name (string) |
40 | params = the package parameters (dictionary) | 43 | data = the package data (dictionary) |
41 | deptree = the package dependency tree (array of strings) | 44 | location = the location of the package (string) |
42 | """ | 45 | """ |
43 | def _walk_deps(deps, deptree): | 46 | packages = shrinkwrap.get("packages") |
44 | for name in deps: | 47 | if not packages: |
45 | subtree = [*deptree, name] | 48 | raise FetchError("Invalid shrinkwrap file format") |
46 | _walk_deps(deps[name].get("dependencies", {}), subtree) | 49 | |
47 | if callback is not None: | 50 | for location, data in packages.items(): |
48 | if deps[name].get("dev", False) and not dev: | 51 | # Skip empty main and local link target packages |
49 | continue | 52 | if not location.startswith('node_modules/'): |
50 | elif deps[name].get("bundled", False): | 53 | continue |
51 | continue | 54 | elif not dev and data.get("dev", False): |
52 | callback(name, deps[name], subtree) | 55 | continue |
53 | 56 | elif data.get("inBundle", False): | |
54 | _walk_deps(shrinkwrap.get("dependencies", {}), []) | 57 | continue |
58 | name = location.split('node_modules/')[-1] | ||
59 | callback(name, data, location) | ||
55 | 60 | ||
56 | class NpmShrinkWrap(FetchMethod): | 61 | class NpmShrinkWrap(FetchMethod): |
57 | """Class to fetch all package from a shrinkwrap file""" | 62 | """Class to fetch all package from a shrinkwrap file""" |
@@ -72,19 +77,28 @@ class NpmShrinkWrap(FetchMethod): | |||
72 | # Resolve the dependencies | 77 | # Resolve the dependencies |
73 | ud.deps = [] | 78 | ud.deps = [] |
74 | 79 | ||
75 | def _resolve_dependency(name, params, deptree): | 80 | def _resolve_dependency(name, params, destsuffix): |
76 | url = None | 81 | url = None |
77 | localpath = None | 82 | localpath = None |
78 | extrapaths = [] | 83 | extrapaths = [] |
79 | destsubdirs = [os.path.join("node_modules", dep) for dep in deptree] | 84 | unpack = True |
80 | destsuffix = os.path.join(*destsubdirs) | ||
81 | 85 | ||
82 | integrity = params.get("integrity", None) | 86 | integrity = params.get("integrity") |
83 | resolved = params.get("resolved", None) | 87 | resolved = params.get("resolved") |
84 | version = params.get("version", None) | 88 | version = params.get("version") |
89 | link = params.get("link", False) | ||
90 | |||
91 | # Handle link sources | ||
92 | if link: | ||
93 | localpath = resolved | ||
94 | unpack = False | ||
85 | 95 | ||
86 | # Handle registry sources | 96 | # Handle registry sources |
87 | if is_semver(version) and resolved and integrity: | 97 | elif version and is_semver(version) and integrity: |
98 | # Handle duplicate dependencies without url | ||
99 | if not resolved: | ||
100 | return | ||
101 | |||
88 | localfile = npm_localfile(name, version) | 102 | localfile = npm_localfile(name, version) |
89 | 103 | ||
90 | uri = URI(resolved) | 104 | uri = URI(resolved) |
@@ -108,10 +122,10 @@ class NpmShrinkWrap(FetchMethod): | |||
108 | extrapaths.append(resolvefile) | 122 | extrapaths.append(resolvefile) |
109 | 123 | ||
110 | # Handle http tarball sources | 124 | # Handle http tarball sources |
111 | elif version.startswith("http") and integrity: | 125 | elif resolved.startswith("http") and integrity: |
112 | localfile = os.path.join("npm2", os.path.basename(version)) | 126 | localfile = npm_localfile(os.path.basename(resolved)) |
113 | 127 | ||
114 | uri = URI(version) | 128 | uri = URI(resolved) |
115 | uri.params["downloadfilename"] = localfile | 129 | uri.params["downloadfilename"] = localfile |
116 | 130 | ||
117 | checksum_name, checksum_expected = npm_integrity(integrity) | 131 | checksum_name, checksum_expected = npm_integrity(integrity) |
@@ -121,8 +135,12 @@ class NpmShrinkWrap(FetchMethod): | |||
121 | 135 | ||
122 | localpath = os.path.join(d.getVar("DL_DIR"), localfile) | 136 | localpath = os.path.join(d.getVar("DL_DIR"), localfile) |
123 | 137 | ||
138 | # Handle local tarball sources | ||
139 | elif resolved.startswith("file"): | ||
140 | localpath = resolved[5:] | ||
141 | |||
124 | # Handle git sources | 142 | # Handle git sources |
125 | elif version.startswith("git"): | 143 | elif resolved.startswith("git"): |
126 | regex = re.compile(r""" | 144 | regex = re.compile(r""" |
127 | ^ | 145 | ^ |
128 | git\+ | 146 | git\+ |
@@ -134,29 +152,31 @@ class NpmShrinkWrap(FetchMethod): | |||
134 | $ | 152 | $ |
135 | """, re.VERBOSE) | 153 | """, re.VERBOSE) |
136 | 154 | ||
137 | match = regex.match(version) | 155 | match = regex.match(resolved) |
138 | |||
139 | if not match: | 156 | if not match: |
140 | raise ParameterError("Invalid git url: %s" % version, ud.url) | 157 | raise ParameterError("Invalid git url: %s" % resolved, ud.url) |
141 | 158 | ||
142 | groups = match.groupdict() | 159 | groups = match.groupdict() |
143 | 160 | ||
144 | uri = URI("git://" + str(groups["url"])) | 161 | uri = URI("git://" + str(groups["url"])) |
145 | uri.params["protocol"] = str(groups["protocol"]) | 162 | uri.params["protocol"] = str(groups["protocol"]) |
146 | uri.params["rev"] = str(groups["rev"]) | 163 | uri.params["rev"] = str(groups["rev"]) |
164 | uri.params["nobranch"] = "1" | ||
147 | uri.params["destsuffix"] = destsuffix | 165 | uri.params["destsuffix"] = destsuffix |
148 | 166 | ||
149 | url = str(uri) | 167 | url = str(uri) |
150 | 168 | ||
151 | # local tarball sources and local link sources are unsupported | ||
152 | else: | 169 | else: |
153 | raise ParameterError("Unsupported dependency: %s" % name, ud.url) | 170 | raise ParameterError("Unsupported dependency: %s" % name, ud.url) |
154 | 171 | ||
172 | # name is needed by unpack tracer for module mapping | ||
155 | ud.deps.append({ | 173 | ud.deps.append({ |
174 | "name": name, | ||
156 | "url": url, | 175 | "url": url, |
157 | "localpath": localpath, | 176 | "localpath": localpath, |
158 | "extrapaths": extrapaths, | 177 | "extrapaths": extrapaths, |
159 | "destsuffix": destsuffix, | 178 | "destsuffix": destsuffix, |
179 | "unpack": unpack, | ||
160 | }) | 180 | }) |
161 | 181 | ||
162 | try: | 182 | try: |
@@ -177,17 +197,23 @@ class NpmShrinkWrap(FetchMethod): | |||
177 | # This fetcher resolves multiple URIs from a shrinkwrap file and then | 197 | # This fetcher resolves multiple URIs from a shrinkwrap file and then |
178 | # forwards it to a proxy fetcher. The management of the donestamp file, | 198 | # forwards it to a proxy fetcher. The management of the donestamp file, |
179 | # the lockfile and the checksums are forwarded to the proxy fetcher. | 199 | # the lockfile and the checksums are forwarded to the proxy fetcher. |
180 | ud.proxy = Fetch([dep["url"] for dep in ud.deps], data) | 200 | shrinkwrap_urls = [dep["url"] for dep in ud.deps if dep["url"]] |
201 | if shrinkwrap_urls: | ||
202 | ud.proxy = Fetch(shrinkwrap_urls, data) | ||
181 | ud.needdonestamp = False | 203 | ud.needdonestamp = False |
182 | 204 | ||
183 | @staticmethod | 205 | @staticmethod |
184 | def _foreach_proxy_method(ud, handle): | 206 | def _foreach_proxy_method(ud, handle): |
185 | returns = [] | 207 | returns = [] |
186 | for proxy_url in ud.proxy.urls: | 208 | #Check if there are dependencies before try to fetch them |
187 | proxy_ud = ud.proxy.ud[proxy_url] | 209 | if len(ud.deps) > 0: |
188 | proxy_d = ud.proxy.d | 210 | for proxy_url in ud.proxy.urls: |
189 | proxy_ud.setup_localpath(proxy_d) | 211 | proxy_ud = ud.proxy.ud[proxy_url] |
190 | returns.append(handle(proxy_ud.method, proxy_ud, proxy_d)) | 212 | proxy_d = ud.proxy.d |
213 | proxy_ud.setup_localpath(proxy_d) | ||
214 | lf = lockfile(proxy_ud.lockfile) | ||
215 | returns.append(handle(proxy_ud.method, proxy_ud, proxy_d)) | ||
216 | unlockfile(lf) | ||
191 | return returns | 217 | return returns |
192 | 218 | ||
193 | def verify_donestamp(self, ud, d): | 219 | def verify_donestamp(self, ud, d): |
@@ -220,10 +246,11 @@ class NpmShrinkWrap(FetchMethod): | |||
220 | 246 | ||
221 | def unpack(self, ud, rootdir, d): | 247 | def unpack(self, ud, rootdir, d): |
222 | """Unpack the downloaded dependencies""" | 248 | """Unpack the downloaded dependencies""" |
223 | destdir = d.getVar("S") | 249 | destdir = rootdir |
224 | destsuffix = ud.parm.get("destsuffix") | 250 | destsuffix = ud.parm.get("destsuffix") |
225 | if destsuffix: | 251 | if destsuffix: |
226 | destdir = os.path.join(rootdir, destsuffix) | 252 | destdir = os.path.join(rootdir, destsuffix) |
253 | ud.unpack_tracer.unpack("npm-shrinkwrap", destdir) | ||
227 | 254 | ||
228 | bb.utils.mkdirhier(destdir) | 255 | bb.utils.mkdirhier(destdir) |
229 | bb.utils.copyfile(ud.shrinkwrap_file, | 256 | bb.utils.copyfile(ud.shrinkwrap_file, |
@@ -237,7 +264,16 @@ class NpmShrinkWrap(FetchMethod): | |||
237 | 264 | ||
238 | for dep in manual: | 265 | for dep in manual: |
239 | depdestdir = os.path.join(destdir, dep["destsuffix"]) | 266 | depdestdir = os.path.join(destdir, dep["destsuffix"]) |
240 | npm_unpack(dep["localpath"], depdestdir, d) | 267 | if dep["url"]: |
268 | npm_unpack(dep["localpath"], depdestdir, d) | ||
269 | else: | ||
270 | depsrcdir= os.path.join(destdir, dep["localpath"]) | ||
271 | if dep["unpack"]: | ||
272 | npm_unpack(depsrcdir, depdestdir, d) | ||
273 | else: | ||
274 | bb.utils.mkdirhier(depdestdir) | ||
275 | cmd = 'cp -fpPRH "%s/." .' % (depsrcdir) | ||
276 | runfetchcmd(cmd, d, workdir=depdestdir) | ||
241 | 277 | ||
242 | def clean(self, ud, d): | 278 | def clean(self, ud, d): |
243 | """Clean any existing full or partial download""" | 279 | """Clean any existing full or partial download""" |