setup.py 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. # -*- coding: utf-8 -*-
  2. # Copyright (c) Jupyter Development Team.
  3. # Distributed under the terms of the Modified BSD License.
  4. from __future__ import print_function
  5. from distutils import log
  6. from setuptools import setup, find_packages, Command
  7. from setuptools.command.sdist import sdist
  8. from setuptools.command.build_py import build_py
  9. from setuptools.command.egg_info import egg_info
  10. from setuptools.command.bdist_egg import bdist_egg
  11. from subprocess import check_call
  12. import json
  13. import os
  14. import sys
  15. here = os.path.dirname(os.path.abspath(__file__))
  16. extension_root = os.path.join(here, 'jupyterlab')
  17. is_repo = os.path.exists(os.path.join(here, '.git'))
  18. def run(cmd, cwd=None):
  19. """Run a command
  20. >>> run('npm install', cwd='./subdir')
  21. """
  22. # On Windows, shell should be True so that the path is searched for the command.
  23. shell = (sys.platform == 'win32')
  24. check_call(cmd.split(), shell=shell, cwd=cwd, stdout=sys.stdout, stderr=sys.stderr)
  25. log.set_verbosity(log.DEBUG)
  26. log.info('setup.py entered')
  27. DESCRIPTION = 'An alpha preview of the JupyterLab notebook server extension.'
  28. LONG_DESCRIPTION = 'This is an alpha preview of JupyterLab. It is not ready for general usage yet. Development happens on https://github.com/jupyter/jupyterlab, with chat on https://gitter.im/jupyter/jupyterlab.'
  29. def js_prerelease(command, strict=False):
  30. """decorator for building minified js/css prior to another command"""
  31. class DecoratedCommand(command):
  32. def run(self):
  33. jsdeps = self.distribution.get_command_obj('jsdeps')
  34. if not is_repo and all(os.path.exists(t) for t in jsdeps.targets):
  35. # sdist, nothing to do
  36. command.run(self)
  37. return
  38. try:
  39. self.distribution.run_command('jsdeps')
  40. except Exception as e:
  41. missing = [t for t in jsdeps.targets if not os.path.exists(t)]
  42. if strict or missing:
  43. log.warn('rebuilding js and css failed')
  44. if missing:
  45. log.error('missing files: %s' % missing)
  46. raise e
  47. else:
  48. log.warn('rebuilding js and css failed (not a problem)')
  49. log.warn(str(e))
  50. command.run(self)
  51. return DecoratedCommand
  52. def update_package_data(distribution):
  53. """update build_py options to get package_data changes"""
  54. build_py = distribution.get_command_obj('build_py')
  55. build_py.finalize_options()
  56. class bdist_egg_disabled(bdist_egg):
  57. """Disabled version of bdist_egg
  58. Prevents setup.py install performing setuptools' default easy_install,
  59. which it should never ever do.
  60. """
  61. def run(self):
  62. sys.exit("Aborting implicit building of eggs. Use `pip install .` to install from source.")
  63. class NPM(Command):
  64. description = 'install package.json dependencies using npm'
  65. user_options = []
  66. # Representative files that should exist after a successful build
  67. targets = [
  68. os.path.join(here, 'jupyterlab', 'build', 'main.css'),
  69. os.path.join(here, 'jupyterlab', 'build', 'main.bundle.js'),
  70. ]
  71. def initialize_options(self):
  72. pass
  73. def finalize_options(self):
  74. pass
  75. def has_npm(self):
  76. try:
  77. run('npm --version')
  78. return True
  79. except:
  80. return False
  81. def run(self):
  82. has_npm = self.has_npm()
  83. if not has_npm:
  84. log.error("`npm` unavailable. If you're running this command using sudo, make sure `npm` is available to sudo")
  85. log.info("Installing build dependencies with npm. This may take a while...")
  86. run('npm install', cwd=here)
  87. run('npm run build:serverextension', cwd=here)
  88. for t in self.targets:
  89. if not os.path.exists(t):
  90. msg = 'Missing file: %s' % t
  91. if not has_npm:
  92. msg += '\nnpm is required to build the development version'
  93. raise ValueError(msg)
  94. # update package data in case this created new files
  95. update_package_data(self.distribution)
  96. with open(os.path.join(here, 'package.json')) as f:
  97. packagejson = json.load(f)
  98. with open(os.path.join(here, 'jupyterlab', '_version.py'), 'w') as f:
  99. f.write('# This file is auto-generated, do not edit!\n')
  100. f.write('__version__ = "%s"\n' % packagejson['version'])
  101. setup_args = {
  102. 'name': 'jupyterlab',
  103. 'version': packagejson['version'],
  104. 'description': DESCRIPTION,
  105. 'long_description': LONG_DESCRIPTION,
  106. 'License': 'BSD',
  107. 'include_package_data': True,
  108. 'install_requires': ['notebook>=4.2.0'],
  109. 'packages': find_packages(),
  110. 'zip_safe': False,
  111. 'package_data': {'jupyterlab': [
  112. 'build/*',
  113. 'lab.html'
  114. ]},
  115. 'cmdclass': {
  116. 'build_py': js_prerelease(build_py),
  117. 'egg_info': js_prerelease(egg_info),
  118. 'sdist': js_prerelease(sdist, strict=True),
  119. 'jsdeps': NPM,
  120. 'bdist_egg': bdist_egg if 'bdist_egg' in sys.argv else bdist_egg_disabled,
  121. },
  122. 'entry_points': {
  123. 'console_scripts': [
  124. 'jupyter-lab = jupyterlab.labapp:main',
  125. 'jupyter-labextension = jupyterlab.labextensions:main',
  126. ]
  127. },
  128. 'author': 'Jupyter Development Team',
  129. 'author_email': 'jupyter@googlegroups.com',
  130. 'url': 'https://github.com/jupyter/jupyterlab',
  131. 'keywords': ['ipython', 'jupyter', 'Web'],
  132. 'classifiers': [
  133. 'Development Status :: 2 - Pre-Alpha',
  134. 'Intended Audience :: Developers',
  135. 'Intended Audience :: Science/Research',
  136. 'License :: OSI Approved :: BSD License',
  137. 'Programming Language :: Python :: 2',
  138. 'Programming Language :: Python :: 2.7',
  139. 'Programming Language :: Python :: 3',
  140. ],
  141. }
  142. setup(**setup_args)