summaryrefslogtreecommitdiffstats
path: root/bitbake/lib/bb/fetch2/npmsw.py
diff options
context:
space:
mode:
Diffstat (limited to 'bitbake/lib/bb/fetch2/npmsw.py')
-rw-r--r--bitbake/lib/bb/fetch2/npmsw.py112
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
24from bb.fetch2 import Fetch 24from bb.fetch2 import Fetch
25from bb.fetch2 import FetchMethod 25from bb.fetch2 import FetchMethod
26from bb.fetch2 import ParameterError 26from bb.fetch2 import ParameterError
27from bb.fetch2 import runfetchcmd
27from bb.fetch2 import URI 28from bb.fetch2 import URI
28from bb.fetch2.npm import npm_integrity 29from bb.fetch2.npm import npm_integrity
29from bb.fetch2.npm import npm_localfile 30from bb.fetch2.npm import npm_localfile
30from bb.fetch2.npm import npm_unpack 31from bb.fetch2.npm import npm_unpack
31from bb.utils import is_semver 32from bb.utils import is_semver
33from bb.utils import lockfile
34from bb.utils import unlockfile
32 35
33def foreach_dependencies(shrinkwrap, callback=None, dev=False): 36def 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
56class NpmShrinkWrap(FetchMethod): 61class 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"""