##// END OF EJS Templates
friendlier error messages when invoke/lessc are missing...
Min RK -
Show More
@@ -1,10 +1,16 b''
1 """invoke task file to build CSS"""
1 """invoke task file to build CSS"""
2
2
3 from invoke import task, run
3 from __future__ import print_function
4
4 import os
5 import os
6 import sys
5 from distutils.version import LooseVersion as V
7 from distutils.version import LooseVersion as V
6 from subprocess import check_output
8 from subprocess import check_output
7
9
10 from invoke import task, run
11 from invoke.runner import Result
12 from invoke.exceptions import Failure
13
8 pjoin = os.path.join
14 pjoin = os.path.join
9 static_dir = 'static'
15 static_dir = 'static'
10 components_dir = pjoin(static_dir, 'components')
16 components_dir = pjoin(static_dir, 'components')
@@ -13,6 +19,18 b' here = os.path.dirname(__file__)'
13 min_less_version = '2.0'
19 min_less_version = '2.0'
14 max_less_version = '3.0' # exclusive if string
20 max_less_version = '3.0' # exclusive if string
15
21
22
23 def _fail(msg=''):
24 """Fail a task, logging a message to stderr
25
26 raises a special Failure Exception from invoke.
27 """
28 if msg:
29 print(msg, file=sys.stderr)
30 # raising a Failure allows us to avoid a traceback
31 # we only care about exited, but stdout, stderr, pty are required args
32 raise Failure(Result(stdout='', stderr='', pty=False, exited=1))
33
16 def _need_css_update():
34 def _need_css_update():
17 """Does less need to run?"""
35 """Does less need to run?"""
18
36
@@ -53,23 +71,30 b' def css(minify=False, verbose=False, force=False):'
53 sourcemap = pjoin('style', "%s.min.css.map" % name)
71 sourcemap = pjoin('style', "%s.min.css.map" % name)
54 _compile_less(source, target, sourcemap, minify, verbose)
72 _compile_less(source, target, sourcemap, minify, verbose)
55
73
74
56 def _compile_less(source, target, sourcemap, minify=True, verbose=False):
75 def _compile_less(source, target, sourcemap, minify=True, verbose=False):
57 """Compile a less file by source and target relative to static_dir"""
76 """Compile a less file by source and target relative to static_dir"""
58 min_flag = '-x' if minify else ''
77 min_flag = '-x' if minify else ''
59 ver_flag = '--verbose' if verbose else ''
78 ver_flag = '--verbose' if verbose else ''
60
79
80 install = "(npm install -g 'less@<{}')".format(max_less_version)
61 # pin less to version number from above
81 # pin less to version number from above
62 try:
82 try:
63 out = check_output(['lessc', '--version'])
83 out = check_output(['lessc', '--version'])
64 except OSError as err:
84 except OSError as err:
65 raise ValueError("Unable to find lessc. Please install lessc >= %s and < %s " \
85 _fail("Unable to find lessc. Rebuilding css requires less >= {0} and < {1} {2}".format(
66 % (min_less_version, max_less_version))
86 min_less_version, max_less_version, install
87 ))
67 out = out.decode('utf8', 'replace')
88 out = out.decode('utf8', 'replace')
68 less_version = out.split()[1]
89 less_version = out.split()[1]
69 if min_less_version and V(less_version) < V(min_less_version):
90 if min_less_version and V(less_version) < V(min_less_version):
70 raise ValueError("lessc too old: %s < %s. Use `$ npm install less@X.Y.Z` to install a specific version of less" % (less_version, min_less_version))
91 _fail("lessc too old: {} < {} {}".format(
92 less_version, min_less_version, install,
93 ))
71 if max_less_version and V(less_version) >= V(max_less_version):
94 if max_less_version and V(less_version) >= V(max_less_version):
72 raise ValueError("lessc too new: %s >= %s. Use `$ npm install less@X.Y.Z` to install a specific version of less" % (less_version, max_less_version))
95 _fail("lessc too new: {} >= {} {}".format(
96 less_version, max_less_version, install,
97 ))
73
98
74 static_path = pjoin(here, static_dir)
99 static_path = pjoin(here, static_dir)
75 cwd = os.getcwd()
100 cwd = os.getcwd()
@@ -24,9 +24,10 b' from distutils.command.build_scripts import build_scripts'
24 from distutils.command.install import install
24 from distutils.command.install import install
25 from distutils.command.install_scripts import install_scripts
25 from distutils.command.install_scripts import install_scripts
26 from distutils.cmd import Command
26 from distutils.cmd import Command
27 from distutils.errors import DistutilsExecError
27 from fnmatch import fnmatch
28 from fnmatch import fnmatch
28 from glob import glob
29 from glob import glob
29 from subprocess import check_call
30 from subprocess import Popen, PIPE
30
31
31 from setupext import install_data_ext
32 from setupext import install_data_ext
32
33
@@ -712,7 +713,15 b' class CompileCSS(Command):'
712 cmd.append('--minify')
713 cmd.append('--minify')
713 if self.force:
714 if self.force:
714 cmd.append('--force')
715 cmd.append('--force')
715 check_call(cmd, cwd=pjoin(repo_root, "IPython", "html"))
716 try:
717 p = Popen(cmd, cwd=pjoin(repo_root, "IPython", "html"), stderr=PIPE)
718 except OSError:
719 raise DistutilsExecError("invoke is required to rebuild css (pip install invoke)")
720 out, err = p.communicate()
721 if p.returncode:
722 if sys.version_info[0] >= 3:
723 err = err.decode('utf8', 'replace')
724 raise DistutilsExecError(err.strip())
716
725
717
726
718 class JavascriptVersion(Command):
727 class JavascriptVersion(Command):
@@ -750,6 +759,7 b' def css_js_prerelease(command, strict=True):'
750 if strict:
759 if strict:
751 raise
760 raise
752 else:
761 else:
753 log.warn("Failed to build css sourcemaps: %s" % e)
762 log.warn("rebuilding css and sourcemaps failed (not a problem)")
763 log.warn(str(e))
754 command.run(self)
764 command.run(self)
755 return DecoratedCommand
765 return DecoratedCommand
General Comments 0
You need to be logged in to leave comments. Login now