Merge pull request #1139 from minrk/run-npm-if-we-should

simplify js build steps
This commit is contained in:
Thomas Kluyver 2016-02-24 16:28:17 +00:00
commit 964c31fbe8
3 changed files with 53 additions and 88 deletions

View File

@ -9,7 +9,7 @@
"url": "https://github.com/jupyter/notebook.git"
},
"scripts": {
"bower": "bower install",
"bower": "bower install --allow-root --config.interactive=false",
"build:watch": "concurrent \"npm run build:css:watch\" \"npm run build:js:watch\"",
"build": "npm run build:css && npm run build:js",
"build:css": "python setup.py css",

View File

@ -55,7 +55,7 @@ from setupbase import (
check_package_data_first,
CompileCSS,
CompileJS,
Bower,
JavascriptDependencies,
JavascriptVersion,
css_js_prerelease,
)
@ -119,7 +119,7 @@ setup_args['cmdclass'] = {
'sdist' : css_js_prerelease(sdist, strict=True),
'css' : CompileCSS,
'js' : CompileJS,
'jsdeps' : Bower,
'jsdeps' : JavascriptDependencies,
'jsversion' : JavascriptVersion,
}

View File

@ -326,61 +326,33 @@ def run(cmd, *args, **kwargs):
return check_call(cmd, *args, **kwargs)
class Bower(Command):
description = "fetch static client-side components with bower"
user_options = [
('force', 'f', "force fetching of bower dependencies"),
]
class JavascriptDependencies(Command):
description = "Fetch Javascript dependencies with npm and bower"
def initialize_options(self):
self.force = False
pass
def finalize_options(self):
self.force = bool(self.force)
pass
bower_dir = pjoin(static, 'components')
node_modules = pjoin(repo_root, 'node_modules')
def should_run(self):
if self.force:
return True
if not os.path.exists(self.bower_dir):
return True
return mtime(self.bower_dir) < mtime(pjoin(repo_root, 'bower.json'))
def should_run_npm(self):
if not which('npm'):
print("npm unavailable", file=sys.stderr)
return False
if not os.path.exists(self.node_modules):
return True
return mtime(self.node_modules) < mtime(pjoin(repo_root, 'package.json'))
def run(self):
if not self.should_run():
print("bower dependencies up to date")
return
if self.should_run_npm():
print("installing build dependencies with npm")
run(['npm', 'install','--progress=false'], cwd=repo_root)
os.utime(self.node_modules, None)
env = os.environ.copy()
env['PATH'] = npm_path
try:
run(['npm', 'install', '--progress=false'], cwd=repo_root)
except OSError as e:
print("Failed to run `npm install`: %s" % e, file=sys.stderr)
print("npm is required to build a development version of the notebook.", file=sys.stderr)
raise
try:
run(
['bower', 'install', '--allow-root', '--config.interactive=false'],
cwd=repo_root,
env=env
)
except OSError as e:
print("Failed to run bower: %s" % e, file=sys.stderr)
run(['npm', 'run', 'bower'], cwd=repo_root)
except Exception as e:
print("Failed to run `npm run bower`: %s" % e, file=sys.stderr)
print("You can install js dependencies with `npm install`", file=sys.stderr)
raise
os.utime(self.bower_dir, None)
# update package data in case this created new files
update_package_data(self.distribution)
@ -444,56 +416,39 @@ class CompileJS(Command):
def finalize_options(self):
self.force = bool(self.force)
apps = ['notebook', 'tree', 'edit', 'terminal', 'auth']
targets = [ pjoin(static, app, 'js', 'built', 'main.min.js') for app in apps ]
target = pjoin(static, 'built', 'index.js')
targets = [target]
def sources(self, name):
def sources(self):
"""Generator yielding .js sources that an application depends on"""
yield pjoin(static, name, 'js', 'built', 'main.min.js')
for sec in [name, 'base', 'auth']:
for f in glob(pjoin(static, sec, 'js', '*.js')):
if not f.endswith('.min.js'):
yield f
yield pjoin(static, 'services', 'built', 'config.js')
yield pjoin(static, 'built', 'index.js')
if name == 'notebook':
for f in glob(pjoin(static, 'services', '*', '*.js')):
yield f
for parent, dirs, files in os.walk(pjoin(static, 'components')):
if os.path.basename(parent) == 'MathJax':
yield pjoin(repo_root, 'package.json')
yield pjoin(repo_root, 'webpack.config.js')
for parent, dirs, files in os.walk(static):
if os.path.basename(parent) in {'MathJax', 'built'}:
# don't look in MathJax, since it takes forever to walk it
# also don't look at build targets as sources
dirs[:] = []
continue
for f in files:
if not f.endswith('.js'):
continue
yield pjoin(parent, f)
def should_run(self, name, target):
if self.force or not os.path.exists(target):
def should_run(self):
if self.force or not os.path.exists(self.target):
print("Missing %s" % self.target)
return True
target_mtime = mtime(target)
for source in self.sources(name):
target_mtime = mtime(self.target)
for source in self.sources():
if mtime(source) > target_mtime:
print(source, target)
print('%s > %s' % (source, self.target))
return True
return False
def build_main(self, name):
"""Build main.min.js"""
target = pjoin(static, name, 'js', 'built', 'main.min.js')
if not self.should_run(name, target):
log.info("%s up to date" % target)
return
log.info("Rebuilding %s" % target)
run(['npm', 'run', 'build'])
def run(self):
self.run_command('jsdeps')
env = os.environ.copy()
env['PATH'] = npm_path
pool = ThreadPool()
pool.map(self.build_main, self.apps)
if self.should_run():
run(['npm', 'run', 'build:js'])
# update package data in case this created new files
update_package_data(self.distribution)
@ -511,17 +466,27 @@ class JavascriptVersion(Command):
def run(self):
nsfile = pjoin(repo_root, "notebook", "static", "base", "js", "namespace.js")
lines = []
found = False
with open(nsfile) as f:
lines = f.readlines()
with open(nsfile, 'w') as f:
found = False
for line in lines:
for line in f.readlines():
if line.strip().startswith("Jupyter.version"):
line = ' Jupyter.version = "{0}";\n'.format(version)
found = True
new_line = ' Jupyter.version = "{0}";\n'.format(version)
if new_line == line:
# no change, don't rewrite file
return
lines.append(new_line)
else:
lines.append(line)
if not found:
raise RuntimeError("Didn't find Jupyter.version line in %s" % nsfile)
print("Writing version=%s to %s" % (version, nsfile))
with open(nsfile, 'w') as f:
for line in lines:
f.write(line)
if not found:
raise RuntimeError("Didn't find Jupyter.version line in %s" % nsfile)
def css_js_prerelease(command, strict=False):
@ -532,7 +497,7 @@ def css_js_prerelease(command, strict=False):
jsdeps = self.distribution.get_command_obj('jsdeps')
js = self.distribution.get_command_obj('js')
css = self.distribution.get_command_obj('css')
jsdeps.force = js.force = strict
js.force = strict
targets = [ jsdeps.bower_dir ]
targets.extend(js.targets)