Skip to content

Commit 1a62135

Browse files
committed
Clean setup using jupyter-packaging
Signed-off-by: martinRenou <[email protected]>
1 parent 3372f9b commit 1a62135

File tree

3 files changed

+35
-132
lines changed

3 files changed

+35
-132
lines changed

MANIFEST.in

+4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
recursive-include ipympl/static *.*
2+
23
include js/*.tgz
34
include js/package.json
45
include LICENSE
56
include jupyter-matplotlib.json
7+
8+
include setup.py
9+
include pyproject.toml

pyproject.toml

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
[build-system]
2+
requires = ["jupyter_packaging~=0.7.0", "setuptools>=40.8.0", "wheel"]
3+
build-backend = "setuptools.build_meta"

setup.py

+28-132
Original file line numberDiff line numberDiff line change
@@ -1,167 +1,63 @@
11
from __future__ import print_function
22
from distutils import log
3-
from setuptools import setup, find_packages, Command
3+
from setuptools import setup, find_packages
44
from setuptools.command.sdist import sdist
55
from setuptools.command.build_py import build_py
66
from setuptools.command.egg_info import egg_info
7-
from subprocess import check_call
87
import os
9-
import json
10-
import sys
11-
from os.path import join as pjoin
8+
9+
from jupyter_packaging import (
10+
create_cmdclass,
11+
install_npm,
12+
ensure_targets,
13+
combine_commands,
14+
get_version,
15+
)
1216

1317
# Name of the project
1418
name = 'ipympl'
1519

1620
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-
])
21+
long_description = 'Matplotlib Jupyter Extension'
2422

2523
log.info('setup.py entered')
2624
log.info('$PATH=%s' % os.environ['PATH'])
2725

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-
26+
# Get ipympl version
27+
version = get_version(os.path.join(name, '_version.py'))
8428

85-
class NPM(Command):
86-
description = 'install package.json dependencies using npm'
29+
js_dir = os.path.join(here, 'js')
8730

88-
user_options = []
31+
# Representative files that should exist after a successful build
32+
jstargets = [
33+
os.path.join(js_dir, 'dist', 'index.js'),
34+
]
8935

90-
node_modules = pjoin(node_root, 'node_modules')
36+
data_files_spec = [
37+
('share/jupyter/nbextensions/jupyter-matplotlib', 'ipympl/static', '*.*'),
38+
('etc/jupyter/nbconfig/notebook.d', '.', 'jupyter-matplotlib.json'),
39+
]
9140

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)
41+
cmdclass = create_cmdclass('jsdeps', data_files_spec=data_files_spec)
42+
cmdclass['jsdeps'] = combine_commands(
43+
install_npm(js_dir, build_cmd='build'), ensure_targets(jstargets),
44+
)
14345

14446
setup_args = dict(
14547
name=name,
146-
version=version_ns['__version__'],
48+
version=version,
14749
description='Matplotlib Jupyter Extension',
148-
long_description=LONG_DESCRIPTION,
50+
long_description=long_description,
14951
license='BSD License',
15052
include_package_data=True,
151-
data_files=get_data_files(),
15253
install_requires=[
15354
'ipykernel>=4.7',
15455
'ipywidgets>=7.5.0',
15556
'matplotlib>=2.0.0'
15657
],
15758
packages=find_packages(),
15859
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-
},
60+
cmdclass=cmdclass,
16561
author='Matplotlib Development Team',
16662
author_email='[email protected]',
16763
url='http://matplotlib.org',

0 commit comments

Comments
 (0)