|
1 | 1 | #!/usr/bin/env python
|
2 | 2 |
|
3 |
| -# Copyright (c) IPython Development Team. |
| 3 | +# Copyright (c) Jupyter Development Team. |
4 | 4 | # Distributed under the terms of the Modified BSD License.
|
5 | 5 |
|
6 |
| -# the name of the package |
7 |
| -name = 'widgetsnbextension' |
8 |
| - |
9 |
| -LONG_DESCRIPTION = """ |
10 |
| -.. image:: https://img.shields.io/pypi/v/widgetsnbextension.svg |
11 |
| - :target: https://pypi.python.org/pypi/widgetsnbextension/ |
12 |
| - :alt: Version Number |
13 |
| -
|
14 |
| -.. image:: https://img.shields.io/pypi/dm/widgetsnbextension.svg |
15 |
| - :target: https://pypi.python.org/pypi/widgetsnbextension/ |
16 |
| - :alt: Number of PyPI downloads |
17 |
| -
|
18 |
| -Interactive HTML Widgets |
19 |
| -======================== |
20 |
| -
|
21 |
| -Interactive HTML widgets for Jupyter notebooks. |
22 |
| -
|
23 |
| -Usage |
24 |
| -===== |
25 |
| -
|
26 |
| -Install the corresponding package for your kernel. i.e. Python users would also |
27 |
| -install `ipywidgets`. Refer to that package's documentation for usage |
28 |
| -instructions. |
29 |
| -""" |
30 |
| - |
31 |
| -#----------------------------------------------------------------------------- |
32 |
| -# Minimal Python version sanity check |
33 |
| -#----------------------------------------------------------------------------- |
34 |
| - |
35 |
| -import sys |
36 |
| - |
37 |
| -#----------------------------------------------------------------------------- |
38 |
| -# get on with it |
39 |
| -#----------------------------------------------------------------------------- |
40 |
| - |
| 6 | +from jupyter_packaging import ( |
| 7 | + create_cmdclass, |
| 8 | + install_npm, |
| 9 | + ensure_targets, |
| 10 | + combine_commands, |
| 11 | + get_version, |
| 12 | +) |
41 | 13 | import os
|
42 |
| -import logging as log |
43 |
| -from setuptools import setup, Command |
44 |
| -from setuptools.command.build_py import build_py |
45 |
| -from setuptools.command.sdist import sdist |
46 |
| -from glob import glob |
47 |
| -from os.path import join as pjoin |
48 |
| -from subprocess import check_call |
49 |
| - |
50 |
| -log.basicConfig(level=log.DEBUG) |
51 |
| -log.info('setup.py entered') |
52 |
| -log.info('$PATH=%s' % os.environ['PATH']) |
53 |
| - |
54 |
| -repo_root = os.path.dirname(os.path.abspath(__file__)) |
55 |
| -is_repo = os.path.exists(pjoin(repo_root, '.git')) |
56 |
| - |
57 |
| -npm_path = os.pathsep.join([ |
58 |
| - pjoin(repo_root, 'node_modules', '.bin'), |
59 |
| - os.environ.get("PATH", os.defpath), |
60 |
| -]) |
61 |
| - |
62 |
| -def mtime(path): |
63 |
| - """shorthand for mtime""" |
64 |
| - return os.stat(path).st_mtime |
65 |
| - |
66 |
| -def js_prerelease(command, strict=False): |
67 |
| - """decorator for building minified js/css prior to another command""" |
68 |
| - class DecoratedCommand(command): |
69 |
| - def run(self): |
70 |
| - jsdeps = self.distribution.get_command_obj('jsdeps') |
71 |
| - if not is_repo and all(os.path.exists(t) for t in jsdeps.targets): |
72 |
| - # sdist, nothing to do |
73 |
| - command.run(self) |
74 |
| - return |
75 |
| - |
76 |
| - try: |
77 |
| - self.distribution.run_command('jsdeps') |
78 |
| - except Exception as e: |
79 |
| - missing = [t for t in jsdeps.targets if not os.path.exists(t)] |
80 |
| - if strict or missing: |
81 |
| - log.warn("rebuilding js and css failed") |
82 |
| - if missing: |
83 |
| - log.error("missing files: %s" % missing) |
84 |
| - raise e |
85 |
| - else: |
86 |
| - log.warn("rebuilding js and css failed (not a problem)") |
87 |
| - log.warn(str(e)) |
88 |
| - command.run(self) |
89 |
| - update_package_data(self.distribution) |
90 |
| - return DecoratedCommand |
| 14 | +from setuptools import setup |
91 | 15 |
|
92 |
| - |
93 |
| -def update_package_data(distribution): |
94 |
| - """update package_data to catch changes during setup""" |
95 |
| - build_py = distribution.get_command_obj('build_py') |
96 |
| - # distribution.package_data = find_package_data() |
97 |
| - # re-init build_py options which load package_data |
98 |
| - build_py.finalize_options() |
99 |
| - |
100 |
| - |
101 |
| -class NPM(Command): |
102 |
| - description = "install package,json dependencies using npm" |
103 |
| - |
104 |
| - user_options = [] |
105 |
| - |
106 |
| - node_modules = pjoin(repo_root, 'node_modules') |
107 |
| - |
108 |
| - targets = [ |
109 |
| - pjoin(repo_root, 'widgetsnbextension', 'static', 'extension.js') |
110 |
| - ] |
111 |
| - |
112 |
| - def initialize_options(self): |
113 |
| - pass |
114 |
| - |
115 |
| - def finalize_options(self): |
116 |
| - pass |
117 |
| - |
118 |
| - def has_npm(self): |
119 |
| - try: |
120 |
| - ## shell=True needs to be passed for windows to look at non .exe files. |
121 |
| - shell = (sys.platform == 'win32') |
122 |
| - check_call(['npm', '--version'], shell=shell) |
123 |
| - return True |
124 |
| - except: |
125 |
| - return False |
126 |
| - |
127 |
| - def run(self): |
128 |
| - has_npm = self.has_npm() |
129 |
| - if not has_npm: |
130 |
| - log.error("`npm` unavailable. If you're running this command using sudo, make sure `npm` is available to sudo") |
131 |
| - |
132 |
| - env = os.environ.copy() |
133 |
| - env['PATH'] = npm_path |
134 |
| - |
135 |
| - if self.has_npm(): |
136 |
| - log.info("Installing build dependencies with npm. This may take a while...") |
137 |
| - check_call(['npm', 'install'], cwd=repo_root, stdout=sys.stdout, stderr=sys.stderr, |
138 |
| - shell=(sys.platform == 'win32')) |
139 |
| - os.utime(self.node_modules, None) |
140 |
| - |
141 |
| - for t in self.targets: |
142 |
| - if not os.path.exists(t): |
143 |
| - msg = "Missing file: %s" % t |
144 |
| - if not has_npm: |
145 |
| - msg += '\nnpm is required to build a development version of widgetsnbextension' |
146 |
| - raise ValueError(msg) |
147 |
| - |
148 |
| - |
149 |
| - # update package data in case this created new files |
150 |
| - update_package_data(self.distribution) |
151 |
| - |
152 |
| -pjoin = os.path.join |
153 | 16 | here = os.path.abspath(os.path.dirname(__file__))
|
154 |
| -pkg_root = pjoin(here, name) |
| 17 | +js_dir = os.path.join(here, 'src') |
155 | 18 |
|
156 |
| -version_ns = {} |
157 |
| -with open(pjoin(here, name, '_version.py')) as f: |
158 |
| - exec(f.read(), {}, version_ns) |
| 19 | +# Representative files that should exist after a successful build |
| 20 | +jstargets = [ |
| 21 | + os.path.join(here, 'widgetsnbextension', 'static', 'extension.js') |
| 22 | +] |
159 | 23 |
|
| 24 | +data_files_spec = [( |
| 25 | + 'share/jupyter/nbextensions/jupyter-js-widgets', 'widgetsnbextension/static', 'extension.js*'), |
| 26 | + ('etc/jupyter/nbconfig/notebook.d' , '.', 'widgetsnbextension.json') |
| 27 | +] |
160 | 28 |
|
161 |
| -setup_args = dict( |
162 |
| - name = name, |
163 |
| - version = version_ns['__version__'], |
164 |
| - scripts = [], |
165 |
| - packages = ['widgetsnbextension'], |
166 |
| - package_data = { |
167 |
| - 'widgetsnbextension': ['widgetsnbextension/static/extension.js'], |
168 |
| - }, |
169 |
| - description = "IPython HTML widgets for Jupyter", |
170 |
| - long_description = LONG_DESCRIPTION, |
171 |
| - author = 'IPython Development Team', |
172 |
| - author_email = '[email protected]', |
173 |
| - url = 'http://ipython.org', |
174 |
| - license = 'BSD', |
175 |
| - platforms = "Linux, Mac OS X, Windows", |
176 |
| - keywords = ['Interactive', 'Interpreter', 'Shell', 'Web'], |
177 |
| - classifiers = [ |
178 |
| - 'Intended Audience :: Developers', |
179 |
| - 'Intended Audience :: System Administrators', |
180 |
| - 'Intended Audience :: Science/Research', |
181 |
| - 'License :: OSI Approved :: BSD License', |
182 |
| - 'Programming Language :: Python', |
183 |
| - 'Programming Language :: Python :: 3', |
184 |
| - 'Programming Language :: Python :: 3 :: Only', |
185 |
| - 'Framework :: Jupyter' |
186 |
| - ], |
187 |
| - cmdclass = { |
188 |
| - 'build_py': js_prerelease(build_py), |
189 |
| - 'sdist': js_prerelease(sdist, strict=True), |
190 |
| - 'jsdeps': NPM, |
191 |
| - }, |
192 |
| - data_files = [( |
193 |
| - 'share/jupyter/nbextensions/jupyter-js-widgets', [ |
194 |
| - 'widgetsnbextension/static/extension.js', |
195 |
| - 'widgetsnbextension/static/extension.js.map' |
196 |
| - ]), |
197 |
| - ('etc/jupyter/nbconfig/notebook.d' , ['widgetsnbextension.json']) |
198 |
| - ], |
199 |
| - zip_safe=False, |
200 |
| - include_package_data = True, |
201 |
| - python_requires = '>=3.6' |
| 29 | +cmdclass = create_cmdclass('jsdeps', data_files_spec=data_files_spec) |
| 30 | +cmdclass['jsdeps'] = combine_commands( |
| 31 | + install_npm(js_dir, npm=['yarn'], build_cmd='build'), ensure_targets(jstargets), |
202 | 32 | )
|
203 | 33 |
|
204 |
| -if 'develop' in sys.argv or any(a.startswith('bdist') for a in sys.argv): |
205 |
| - import setuptools |
206 |
| - |
207 |
| -if 'setuptools' in sys.modules: |
208 |
| - # setup.py develop should check for submodules |
209 |
| - from setuptools.command.develop import develop |
210 |
| - setup_args['cmdclass']['develop'] = js_prerelease(develop, strict=True) |
211 | 34 |
|
212 | 35 | if __name__ == '__main__':
|
213 |
| - setup(**setup_args) |
| 36 | + setup(cmdclass=cmdclass) |
0 commit comments