|
1 | 1 | from __future__ import print_function
|
2 | 2 | from distutils import log
|
3 |
| -from setuptools import setup, find_packages, Command |
4 |
| -from setuptools.command.sdist import sdist |
5 |
| -from setuptools.command.build_py import build_py |
6 |
| -from setuptools.command.egg_info import egg_info |
7 |
| -from subprocess import check_call |
| 3 | +from setuptools import setup, find_packages |
8 | 4 | import os
|
9 |
| -import json |
10 |
| -import sys |
11 |
| -from os.path import join as pjoin |
| 5 | + |
| 6 | +from jupyter_packaging import ( |
| 7 | + create_cmdclass, |
| 8 | + install_npm, |
| 9 | + ensure_targets, |
| 10 | + combine_commands, |
| 11 | + get_version, |
| 12 | +) |
12 | 13 |
|
13 | 14 | # Name of the project
|
14 | 15 | name = 'ipympl'
|
15 | 16 |
|
16 | 17 | here = os.path.dirname(os.path.abspath(__file__))
|
17 |
| -node_root = pjoin(here, 'js') |
18 |
| -is_repo = os.path.exists(pjoin(here, '.git')) |
19 |
| - |
20 |
| -npm_path = os.pathsep.join([ |
21 |
| - pjoin(node_root, 'node_modules', '.bin'), |
22 |
| - os.environ.get('PATH', os.defpath), |
23 |
| -]) |
| 18 | +long_description = 'Matplotlib Jupyter Extension' |
24 | 19 |
|
25 | 20 | log.info('setup.py entered')
|
26 | 21 | log.info('$PATH=%s' % os.environ['PATH'])
|
27 | 22 |
|
28 |
| -LONG_DESCRIPTION = 'Matplotlib Jupyter Extension' |
29 |
| - |
30 |
| - |
31 |
| -def js_prerelease(command, strict=False): |
32 |
| - """decorator for building minified js/css prior to another command""" |
33 |
| - class DecoratedCommand(command): |
34 |
| - def run(self): |
35 |
| - jsdeps = self.distribution.get_command_obj('jsdeps') |
36 |
| - if not is_repo and all(os.path.exists(t) for t in jsdeps.targets): |
37 |
| - # sdist, nothing to do |
38 |
| - command.run(self) |
39 |
| - return |
40 |
| - |
41 |
| - try: |
42 |
| - self.distribution.run_command('jsdeps') |
43 |
| - except Exception as e: |
44 |
| - missing = [t for t in jsdeps.targets if not os.path.exists(t)] |
45 |
| - if strict or missing: |
46 |
| - log.warn('rebuilding js and css failed') |
47 |
| - if missing: |
48 |
| - log.error('missing files: %s' % missing) |
49 |
| - raise e |
50 |
| - else: |
51 |
| - log.warn('rebuilding js and css failed (not a problem)') |
52 |
| - log.warn(str(e)) |
53 |
| - command.run(self) |
54 |
| - update_package_data(self.distribution) |
55 |
| - return DecoratedCommand |
56 |
| - |
57 |
| - |
58 |
| -def update_package_data(distribution): |
59 |
| - """update package_data to catch changes during setup""" |
60 |
| - build_py = distribution.get_command_obj('build_py') |
61 |
| - distribution.data_files = get_data_files() |
62 |
| - # re-init build_py options which load package_data |
63 |
| - build_py.finalize_options() |
64 |
| - |
65 |
| - |
66 |
| -def get_data_files(): |
67 |
| - """Get the data files for the package. |
68 |
| - """ |
69 |
| - with open(pjoin(node_root, 'package.json')) as f: |
70 |
| - package_json = json.load(f) |
71 |
| - tgz = '%s-%s.tgz' % (package_json['name'], package_json['version']) |
72 |
| - |
73 |
| - return [ |
74 |
| - ('share/jupyter/nbextensions/jupyter-matplotlib', [ |
75 |
| - 'ipympl/static/extension.js', |
76 |
| - 'ipympl/static/index.js', |
77 |
| - 'ipympl/static/index.js.map', |
78 |
| - 'ipympl/static/package.json' |
79 |
| - ]), |
80 |
| - ('etc/jupyter/nbconfig/notebook.d', ['jupyter-matplotlib.json']), |
81 |
| - ('share/jupyter/lab/extensions', ['js/' + tgz]), |
82 |
| - ] |
83 |
| - |
| 23 | +# Get ipympl version |
| 24 | +version = get_version(os.path.join(name, '_version.py')) |
84 | 25 |
|
85 |
| -class NPM(Command): |
86 |
| - description = 'install package.json dependencies using npm' |
| 26 | +js_dir = os.path.join(here, 'js') |
87 | 27 |
|
88 |
| - user_options = [] |
| 28 | +# Representative files that should exist after a successful build |
| 29 | +jstargets = [ |
| 30 | + os.path.join(js_dir, 'dist', 'index.js'), |
| 31 | +] |
89 | 32 |
|
90 |
| - node_modules = pjoin(node_root, 'node_modules') |
| 33 | +data_files_spec = [ |
| 34 | + ('share/jupyter/nbextensions/jupyter-matplotlib', 'ipympl/static', '*.*'), |
| 35 | + ('etc/jupyter/nbconfig/notebook.d', '.', 'jupyter-matplotlib.json'), |
| 36 | +] |
91 | 37 |
|
92 |
| - targets = [ |
93 |
| - pjoin(here, 'ipympl', 'static', 'extension.js'), |
94 |
| - pjoin(here, 'ipympl', 'static', 'index.js'), |
95 |
| - pjoin(here, 'ipympl', 'static', 'package.json') |
96 |
| - ] |
97 |
| - |
98 |
| - def initialize_options(self): |
99 |
| - pass |
100 |
| - |
101 |
| - def finalize_options(self): |
102 |
| - pass |
103 |
| - |
104 |
| - def has_npm(self): |
105 |
| - try: |
106 |
| - check_call(['npm', '--version']) |
107 |
| - return True |
108 |
| - except Exception: |
109 |
| - return False |
110 |
| - |
111 |
| - def run(self): |
112 |
| - has_npm = self.has_npm() |
113 |
| - if not has_npm: |
114 |
| - log.error("`npm` unavailable. If you're running this command " |
115 |
| - "using sudo, make sure `npm` is available to sudo") |
116 |
| - |
117 |
| - env = os.environ.copy() |
118 |
| - env['PATH'] = npm_path |
119 |
| - |
120 |
| - if self.has_npm(): |
121 |
| - log.info("Installing build dependencies with npm. " |
122 |
| - "This may take a while...") |
123 |
| - check_call(['npm', 'install'], cwd=node_root, stdout=sys.stdout, |
124 |
| - stderr=sys.stderr) |
125 |
| - check_call(['npm', 'pack'], cwd=node_root, stdout=sys.stdout, |
126 |
| - stderr=sys.stderr) |
127 |
| - |
128 |
| - for t in self.targets: |
129 |
| - if not os.path.exists(t): |
130 |
| - msg = 'Missing file: %s' % t |
131 |
| - if not has_npm: |
132 |
| - msg += ('\nnpm is required to build a development version ' |
133 |
| - 'of widgetsnbextension') |
134 |
| - raise ValueError(msg) |
135 |
| - |
136 |
| - # update package data in case this created new files |
137 |
| - update_package_data(self.distribution) |
138 |
| - |
139 |
| - |
140 |
| -version_ns = {} |
141 |
| -with open(pjoin(here, 'ipympl', '_version.py')) as f: |
142 |
| - exec(f.read(), {}, version_ns) |
| 38 | +cmdclass = create_cmdclass('jsdeps', data_files_spec=data_files_spec) |
| 39 | +cmdclass['jsdeps'] = combine_commands( |
| 40 | + install_npm(js_dir, build_cmd='build'), ensure_targets(jstargets), |
| 41 | +) |
143 | 42 |
|
144 | 43 | setup_args = dict(
|
145 | 44 | name=name,
|
146 |
| - version=version_ns['__version__'], |
| 45 | + version=version, |
147 | 46 | description='Matplotlib Jupyter Extension',
|
148 |
| - long_description=LONG_DESCRIPTION, |
| 47 | + long_description=long_description, |
149 | 48 | license='BSD License',
|
150 | 49 | include_package_data=True,
|
151 |
| - data_files=get_data_files(), |
152 | 50 | install_requires=[
|
153 | 51 | 'ipykernel>=4.7',
|
154 | 52 | 'ipywidgets>=7.5.0',
|
155 | 53 | 'matplotlib>=2.0.0'
|
156 | 54 | ],
|
157 | 55 | packages=find_packages(),
|
158 | 56 | zip_safe=False,
|
159 |
| - cmdclass={ |
160 |
| - 'build_py': js_prerelease(build_py), |
161 |
| - 'egg_info': js_prerelease(egg_info), |
162 |
| - 'sdist': js_prerelease(sdist, strict=True), |
163 |
| - 'jsdeps': NPM, |
164 |
| - }, |
| 57 | + cmdclass=cmdclass, |
165 | 58 | author='Matplotlib Development Team',
|
166 | 59 |
|
167 | 60 | url='http://matplotlib.org',
|
|
0 commit comments