summaryrefslogtreecommitdiffstats
path: root/scripts/lib/recipetool/create_npm.py
diff options
context:
space:
mode:
authorPaul Eggleton <paul.eggleton@linux.intel.com>2016-03-09 17:48:55 +1300
committerRichard Purdie <richard.purdie@linuxfoundation.org>2016-03-09 17:00:29 +0000
commitbc0e99d2b165ff547e02c7169a8b0d210de54a1a (patch)
tree94ca561bf4a2c0e3824bfdc6b2673e760145d61b /scripts/lib/recipetool/create_npm.py
parent309b2e6c571248a3b77c432ed96dfb976cb840bc (diff)
downloadpoky-bc0e99d2b165ff547e02c7169a8b0d210de54a1a.tar.gz
recipetool: create: shrinkwrap and lockdown npm modules
"npm shrinkwrap" creates a file that ensures that the exact same versions get fetched the next time the recipe is built. lockdown is similar but also includes sha1sums of the modules thus validating they haven't changed between builds. These ensure that the build is reproducible. Fixes [YOCTO #9225]. (From OE-Core rev: 277377f13b2b771915eb853e336ca24b84523ed1) Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'scripts/lib/recipetool/create_npm.py')
-rw-r--r--scripts/lib/recipetool/create_npm.py57
1 files changed, 57 insertions, 0 deletions
diff --git a/scripts/lib/recipetool/create_npm.py b/scripts/lib/recipetool/create_npm.py
index 4bf6caed5c..b3ffcdbc5b 100644
--- a/scripts/lib/recipetool/create_npm.py
+++ b/scripts/lib/recipetool/create_npm.py
@@ -15,14 +15,27 @@
15# with this program; if not, write to the Free Software Foundation, Inc., 15# with this program; if not, write to the Free Software Foundation, Inc.,
16# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 16# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17 17
18import os
18import logging 19import logging
20import subprocess
21import tempfile
22import shutil
19import json 23import json
20from recipetool.create import RecipeHandler, split_pkg_licenses 24from recipetool.create import RecipeHandler, split_pkg_licenses
21 25
22logger = logging.getLogger('recipetool') 26logger = logging.getLogger('recipetool')
23 27
24 28
29tinfoil = None
30
31def tinfoil_init(instance):
32 global tinfoil
33 tinfoil = instance
34
35
25class NpmRecipeHandler(RecipeHandler): 36class NpmRecipeHandler(RecipeHandler):
37 lockdownpath = None
38
26 def _handle_license(self, data): 39 def _handle_license(self, data):
27 ''' 40 '''
28 Handle the license value from an npm package.json file 41 Handle the license value from an npm package.json file
@@ -34,7 +47,44 @@ class NpmRecipeHandler(RecipeHandler):
34 license = license.get('type', None) 47 license = license.get('type', None)
35 return None 48 return None
36 49
50 def _shrinkwrap(self, srctree, localfilesdir, extravalues, lines_before):
51 try:
52 runenv = dict(os.environ, PATH=tinfoil.config_data.getVar('PATH', True))
53 bb.process.run('npm shrinkwrap', cwd=srctree, stderr=subprocess.STDOUT, env=runenv, shell=True)
54 except bb.process.ExecutionError as e:
55 logger.warn('npm shrinkwrap failed:\n%s' % e.stdout)
56 return
57
58 tmpfile = os.path.join(localfilesdir, 'npm-shrinkwrap.json')
59 shutil.move(os.path.join(srctree, 'npm-shrinkwrap.json'), tmpfile)
60 extravalues.setdefault('extrafiles', {})
61 extravalues['extrafiles']['npm-shrinkwrap.json'] = tmpfile
62 lines_before.append('NPM_SHRINKWRAP := "${THISDIR}/${PN}/npm-shrinkwrap.json"')
63
64 def _lockdown(self, srctree, localfilesdir, extravalues, lines_before):
65 runenv = dict(os.environ, PATH=tinfoil.config_data.getVar('PATH', True))
66 if not NpmRecipeHandler.lockdownpath:
67 NpmRecipeHandler.lockdownpath = tempfile.mkdtemp('recipetool-npm-lockdown')
68 bb.process.run('npm install lockdown --prefix %s' % NpmRecipeHandler.lockdownpath,
69 cwd=srctree, stderr=subprocess.STDOUT, env=runenv, shell=True)
70 relockbin = os.path.join(NpmRecipeHandler.lockdownpath, 'node_modules', 'lockdown', 'relock.js')
71 if not os.path.exists(relockbin):
72 logger.warn('Could not find relock.js within lockdown directory; skipping lockdown')
73 return
74 try:
75 bb.process.run('node %s' % relockbin, cwd=srctree, stderr=subprocess.STDOUT, env=runenv, shell=True)
76 except bb.process.ExecutionError as e:
77 logger.warn('lockdown-relock failed:\n%s' % e.stdout)
78 return
79
80 tmpfile = os.path.join(localfilesdir, 'lockdown.json')
81 shutil.move(os.path.join(srctree, 'lockdown.json'), tmpfile)
82 extravalues.setdefault('extrafiles', {})
83 extravalues['extrafiles']['lockdown.json'] = tmpfile
84 lines_before.append('NPM_LOCKDOWN := "${THISDIR}/${PN}/lockdown.json"')
85
37 def process(self, srctree, classes, lines_before, lines_after, handled, extravalues): 86 def process(self, srctree, classes, lines_before, lines_after, handled, extravalues):
87 import bb.utils
38 import oe 88 import oe
39 from collections import OrderedDict 89 from collections import OrderedDict
40 90
@@ -58,6 +108,13 @@ class NpmRecipeHandler(RecipeHandler):
58 if 'homepage' in data: 108 if 'homepage' in data:
59 lines_before.append('HOMEPAGE = "%s"' % data['homepage']) 109 lines_before.append('HOMEPAGE = "%s"' % data['homepage'])
60 110
111 # Shrinkwrap
112 localfilesdir = tempfile.mkdtemp(prefix='recipetool-npm')
113 self._shrinkwrap(srctree, localfilesdir, extravalues, lines_before)
114
115 # Lockdown
116 self._lockdown(srctree, localfilesdir, extravalues, lines_before)
117
61 # Split each npm module out to is own package 118 # Split each npm module out to is own package
62 npmpackages = oe.package.npm_split_package_dirs(srctree) 119 npmpackages = oe.package.npm_split_package_dirs(srctree)
63 for item in handled: 120 for item in handled: