setup.py 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. #!/usr/bin/env python
  2. # coding: utf-8
  3. # Copyright (c) Jupyter Development Team.
  4. # Distributed under the terms of the Modified BSD License.
  5. from os.path import join as pjoin
  6. import json
  7. import os
  8. import sys
  9. # Our own imports
  10. from setupbase import (
  11. create_cmdclass, find_packages, get_version,
  12. command_for_func, combine_commands, install_npm, HERE, run,
  13. skip_npm, which, log
  14. )
  15. from setuptools import setup
  16. from setuptools.command.develop import develop
  17. min_version = (3, 5)
  18. if sys.version_info < min_version:
  19. error = """
  20. Python {0} or above is required, you are using Python {1}.
  21. This may be due to an out of date pip.
  22. Make sure you have pip >= 9.0.1.
  23. """.format('.'.join(str(n) for n in min_version),
  24. '.'.join(str(n) for n in sys.version_info[:3]))
  25. sys.exit(error)
  26. NAME = 'jupyterlab'
  27. DESCRIPTION = 'The JupyterLab server extension.'
  28. with open(pjoin(HERE, 'README.md')) as fid:
  29. LONG_DESCRIPTION = fid.read()
  30. data_files_spec = [
  31. ('share/jupyter/lab/static', '%s/static' % NAME, '**'),
  32. ('share/jupyter/lab/schemas', '%s/schemas' % NAME, '**'),
  33. ('share/jupyter/lab/themes', '%s/themes' % NAME, '**'),
  34. ('etc/jupyter/jupyter_server_config.d',
  35. 'jupyter-config/jupyter_server_config.d', 'jupyterlab.json'),
  36. ]
  37. package_data_spec = dict()
  38. package_data_spec[NAME] = [
  39. 'staging/*', 'staging/templates/*', 'staging/.yarnrc',
  40. 'static/**', 'tests/mock_packages/**', 'themes/**', 'schemas/**', '*.js'
  41. ]
  42. def exclude(filename):
  43. """Exclude JavaScript map files"""
  44. return filename.endswith('.js.map')
  45. staging = pjoin(HERE, NAME, 'staging')
  46. npm = ['node', pjoin(staging, 'yarn.js')]
  47. VERSION = get_version('%s/_version.py' % NAME)
  48. def check_assets():
  49. from distutils.version import LooseVersion
  50. # Representative files that should exist after a successful build
  51. targets = [
  52. 'static/package.json',
  53. 'schemas/@jupyterlab/shortcuts-extension/shortcuts.json',
  54. 'themes/@jupyterlab/theme-light-extension/index.css'
  55. ]
  56. for t in targets:
  57. if not os.path.exists(pjoin(HERE, NAME, t)):
  58. msg = ('Missing file: %s, `build:prod` script did not complete '
  59. 'successfully' % t)
  60. raise ValueError(msg)
  61. if 'sdist' not in sys.argv and 'bdist_wheel' not in sys.argv:
  62. return
  63. target = pjoin(HERE, NAME, 'static', 'package.json')
  64. with open(target) as fid:
  65. version = json.load(fid)['jupyterlab']['version']
  66. if LooseVersion(version) != LooseVersion(VERSION):
  67. raise ValueError('Version mismatch, please run `build:update`')
  68. cmdclass = create_cmdclass('jsdeps', data_files_spec=data_files_spec,
  69. package_data_spec=package_data_spec, exclude=exclude)
  70. # FIXME: part of https://github.com/jupyterlab/jupyterlab/issues/8655
  71. if os.name == 'nt':
  72. build_cmd = 'build'
  73. else:
  74. build_cmd = 'build:prod'
  75. cmdclass['jsdeps'] = combine_commands(
  76. install_npm(build_cmd=build_cmd, path=staging, source_dir=staging,
  77. build_dir=pjoin(HERE, NAME, 'static'), npm=npm),
  78. command_for_func(check_assets)
  79. )
  80. class JupyterlabDevelop(develop):
  81. """A custom develop command that runs yarn"""
  82. def run(self):
  83. if not skip_npm:
  84. if not which('node'):
  85. error_message = """
  86. Please install nodejs and npm before continuing installation.
  87. nodejs may be installed using conda or directly from: https://nodejs.org/
  88. """
  89. log.error(error_message)
  90. return
  91. run(npm, cwd=HERE)
  92. develop.run(self)
  93. # Use default develop - we can ensure core mode later if needed.
  94. cmdclass['develop'] = JupyterlabDevelop
  95. setup_args = dict(
  96. name=NAME,
  97. description=DESCRIPTION,
  98. long_description=LONG_DESCRIPTION,
  99. long_description_content_type='text/markdown',
  100. version=VERSION,
  101. packages=find_packages(),
  102. cmdclass=cmdclass,
  103. author='Jupyter Development Team',
  104. author_email='jupyter@googlegroups.com',
  105. url='http://jupyter.org',
  106. license='BSD',
  107. platforms='Linux, Mac OS X, Windows',
  108. keywords=['ipython', 'jupyter', 'Web'],
  109. classifiers=[
  110. 'Development Status :: 5 - Production/Stable',
  111. 'Intended Audience :: Developers',
  112. 'Intended Audience :: System Administrators',
  113. 'Intended Audience :: Science/Research',
  114. 'License :: OSI Approved :: BSD License',
  115. 'Programming Language :: Python',
  116. 'Programming Language :: Python :: 3',
  117. 'Programming Language :: Python :: 3.5',
  118. 'Programming Language :: Python :: 3.6',
  119. 'Programming Language :: Python :: 3.7',
  120. ],
  121. )
  122. setup_args['install_requires'] = [
  123. 'ipython',
  124. 'tornado!=6.0.0, !=6.0.1, !=6.0.2',
  125. 'jupyterlab_server~=2.0.0b1',
  126. 'nbclassic~=0.2.0rc4',
  127. 'jinja2>=2.10'
  128. ]
  129. setup_args['extras_require'] = {
  130. 'test': [
  131. 'pytest==5.3.2',
  132. 'pytest-cov',
  133. 'pytest-tornasync',
  134. 'pytest-console-scripts',
  135. 'pytest-check-links',
  136. 'requests',
  137. 'wheel',
  138. 'virtualenv'
  139. ],
  140. 'test:sys_platform == "win32"': ['nose-exclude'],
  141. 'docs': [
  142. 'jsx-lexer',
  143. 'recommonmark',
  144. 'sphinx',
  145. 'sphinx_rtd_theme',
  146. 'sphinx-copybutton'
  147. ],
  148. }
  149. setup_args['package_data'] = package_data_spec
  150. setup_args['include_package_data'] = True
  151. setup_args['python_requires'] = '>=3.5'
  152. # Force entrypoints with setuptools (needed for Windows, unconditional
  153. # because of wheels)
  154. setup_args['entry_points'] = {
  155. 'console_scripts': [
  156. 'jupyter-lab = jupyterlab.labapp:main',
  157. 'jupyter-labextension = jupyterlab.labextensions:main',
  158. 'jupyter-labhub = jupyterlab.labhubapp:main',
  159. 'jlpm = jupyterlab.jlpmapp:main',
  160. ],
  161. 'pytest11': [
  162. 'pytest_jupyterlab = jupyterlab.pytest_plugin'
  163. ],
  164. }
  165. if __name__ == '__main__':
  166. setup(**setup_args)