diff --git a/jupyter_notebook/static/base/js/namespace.js b/jupyter_notebook/static/base/js/namespace.js index ce6945dda..112719734 100644 --- a/jupyter_notebook/static/base/js/namespace.js +++ b/jupyter_notebook/static/base/js/namespace.js @@ -4,7 +4,7 @@ var IPython = IPython || {}; define([], function(){ "use strict"; - IPython.version = "4.0.0-dev"; + IPython.version = "4.0.0.dev"; IPython._target = '_blank'; return IPython; }); diff --git a/setup.py b/setup.py index 7be7a6927..954ce30a6 100755 --- a/setup.py +++ b/setup.py @@ -1,34 +1,29 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -"""Setup script for IPython. - -Under Posix environments it works like a typical setup.py script. -Under Windows, the command sdist is not supported, since IPython -requires utilities which are not available under Windows.""" +"""Setup script for Jupyter Notebook""" #----------------------------------------------------------------------------- -# Copyright (c) 2008-2011, IPython Development Team. -# Copyright (c) 2001-2007, Fernando Perez -# Copyright (c) 2001, Janko Hauser -# Copyright (c) 2001, Nathaniel Gray +# Copyright (c) 2015-, Jupyter Development Team. +# Copyright (c) 2008-2015, IPython Development Team. # # Distributed under the terms of the Modified BSD License. # -# The full license is in the file COPYING.rst, distributed with this software. +# The full license is in the file COPYING.md, distributed with this software. #----------------------------------------------------------------------------- +from __future__ import print_function + +name = "jupyter_notebook" + #----------------------------------------------------------------------------- # Minimal Python version sanity check #----------------------------------------------------------------------------- -from __future__ import print_function import sys -# This check is also made in IPython/__init__, don't forget to update both when -# changing Python version requirements. v = sys.version_info if v[:2] < (2,7) or (v[0] >= 3 and v[:2] < (3,3)): - error = "ERROR: IPython requires Python version 2.7 or 3.3 or above." + error = "ERROR: %s requires Python version 2.7 or 3.3 or above." % name print(error, file=sys.stderr) sys.exit(1) @@ -36,13 +31,12 @@ PY3 = (sys.version_info[0] >= 3) # At least we're on the python version we need, move on. + #------------------------------------------------------------------------------- # Imports #------------------------------------------------------------------------------- -# Stdlib imports import os -import shutil from glob import glob @@ -53,50 +47,49 @@ if os.path.exists('MANIFEST'): os.remove('MANIFEST') from distutils.core import setup # Our own imports -from setupbase import target_update from setupbase import ( - setup_args, + version, find_packages, find_package_data, check_package_data_first, - find_entry_points, - build_scripts_entrypt, - find_data_files, - check_for_readline, - git_prebuild, check_submodule_status, - update_submodules, require_submodules, + update_submodules, UpdateSubmodules, - get_bdist_wheel, CompileCSS, JavascriptVersion, css_js_prerelease, - install_symlinked, - install_lib_symlink, - install_scripts_for_symlink, - unsymlink, ) isfile = os.path.isfile pjoin = os.path.join -#------------------------------------------------------------------------------- -# Handle OS specific things -#------------------------------------------------------------------------------- - -if os.name in ('nt','dos'): - os_name = 'windows' -else: - os_name = os.name +setup_args = dict( + name = name, + description = "", + version = version, + scripts = glob(pjoin('scripts', '*')), + packages = find_packages(), + package_data = find_package_data(), + author = 'Jupyter Development Team', + author_email = 'jupyter@googlegroups.com', + url = 'http://jupyter.org', + license = 'BSD', + platforms = "Linux, Mac OS X, Windows", + keywords = ['Interactive', 'Interpreter', 'Shell', 'Web'], + classifiers = [ + 'Intended Audience :: Developers', + 'Intended Audience :: System Administrators', + 'Intended Audience :: Science/Research', + 'License :: OSI Approved :: BSD License', + 'Programming Language :: Python', + 'Programming Language :: Python :: 2.7', + 'Programming Language :: Python :: 3', + 'Programming Language :: Python :: 3.3', + ], +) -# Under Windows, 'sdist' has not been supported. Now that the docs build with -# Sphinx it might work, but let's not turn it on until someone confirms that it -# actually works. -if os_name == 'windows' and 'sdist' in sys.argv: - print('The sdist command is not available under Windows. Exiting.') - sys.exit(1) #------------------------------------------------------------------------------- # Make sure we aren't trying to run without submodules @@ -124,7 +117,7 @@ def require_clean_submodules(): update_submodules(here) elif status == "unclean": print('\n'.join([ - "Cannot build / install IPython with unclean submodules", + "Cannot build / install with unclean submodules", "Please update submodules with", " python setup.py submodule", "or", @@ -135,24 +128,6 @@ def require_clean_submodules(): require_clean_submodules() -#------------------------------------------------------------------------------- -# Things related to the IPython documentation -#------------------------------------------------------------------------------- - -# update the manuals when building a source dist -if len(sys.argv) >= 2 and sys.argv[1] in ('sdist','bdist_rpm'): - - # List of things to be updated. Each entry is a triplet of args for - # target_update() - to_update = [ - ('docs/man/ipython.1.gz', - ['docs/man/ipython.1'], - 'cd docs/man && gzip -9c ipython.1 > ipython.1.gz'), - ] - - - [ target_update(*t) for t in to_update ] - #--------------------------------------------------------------------------- # Find all the packages, package data, and data_files #--------------------------------------------------------------------------- @@ -160,68 +135,23 @@ if len(sys.argv) >= 2 and sys.argv[1] in ('sdist','bdist_rpm'): packages = find_packages() package_data = find_package_data() -data_files = find_data_files() - -setup_args['packages'] = packages -setup_args['package_data'] = package_data -setup_args['data_files'] = data_files - #--------------------------------------------------------------------------- # custom distutils commands #--------------------------------------------------------------------------- # imports here, so they are after setuptools import if there was one +from distutils.command.build_py import build_py from distutils.command.sdist import sdist -from distutils.command.upload import upload - -class UploadWindowsInstallers(upload): - - description = "Upload Windows installers to PyPI (only used from tools/release_windows.py)" - user_options = upload.user_options + [ - ('files=', 'f', 'exe file (or glob) to upload') - ] - def initialize_options(self): - upload.initialize_options(self) - meta = self.distribution.metadata - base = '{name}-{version}'.format( - name=meta.get_name(), - version=meta.get_version() - ) - self.files = os.path.join('dist', '%s.*.exe' % base) - - def run(self): - for dist_file in glob(self.files): - self.upload_file('bdist_wininst', 'any', dist_file) + setup_args['cmdclass'] = { 'build_py': css_js_prerelease( - check_package_data_first(git_prebuild('IPython'))), - 'sdist' : css_js_prerelease(git_prebuild('IPython', sdist)), - 'upload_wininst' : UploadWindowsInstallers, + check_package_data_first(build_py)), + 'sdist' : css_js_prerelease(sdist), 'submodule' : UpdateSubmodules, 'css' : CompileCSS, - 'symlink': install_symlinked, - 'install_lib_symlink': install_lib_symlink, - 'install_scripts_sym': install_scripts_for_symlink, - 'unsymlink': unsymlink, 'jsversion' : JavascriptVersion, } -### Temporarily disable install while it's broken during the big split -from textwrap import dedent -from distutils.command.install import install - -class DisabledInstall(install): - def run(self): - msg = dedent(""" - While we are in the midst of The Big Split, - IPython cannot be installed from master. - You can use `pip install -e .` for an editable install, - which still works. - """) - print(msg, file=sys.stderr) - raise SystemExit(1) - -setup_args['cmdclass']['install'] = DisabledInstall #--------------------------------------------------------------------------- @@ -246,91 +176,41 @@ setuptools_extra_args = {} pyzmq = 'pyzmq>=13' -extras_require = dict( - parallel = ['ipython_parallel'], - qtconsole = ['jupyter_qtconsole'], - doc = ['Sphinx>=1.1', 'numpydoc'], - test = ['nose>=0.10.1', 'requests'], - terminal = [], - kernel = ['ipython_kernel'], - nbformat = ['jupyter_nbformat'], - notebook = ['tornado>=4.0', pyzmq, 'jinja2', 'pygments', 'mistune>=0.5'], - nbconvert = ['pygments', 'jinja2', 'mistune>=0.3.1'] -) - -if not sys.platform.startswith('win'): - extras_require['notebook'].append('terminado>=0.3.3') - -if sys.version_info < (3, 3): - extras_require['test'].append('mock') - -extras_require['nbconvert'].extend(extras_require['nbformat']) -extras_require['notebook'].extend(extras_require['kernel']) -extras_require['notebook'].extend(extras_require['nbconvert']) +setup_args['scripts'] = glob(pjoin('scripts', '*')) install_requires = [ - 'decorator', - 'pickleshare', - 'simplegeneric>0.8', + 'jinja2', + 'tornado>=4', + 'ipython_genutils', 'traitlets', + 'jupyter_core', + 'jupyter_client', + 'jupyter_nbformat', + 'jupyter_nbconvert', + 'ipython_kernel', # bless IPython kernel for now ] - -# add platform-specific dependencies -if sys.platform == 'darwin': - install_requires.append('appnope') - if 'bdist_wheel' in sys.argv[1:] or not check_for_readline(): - install_requires.append('gnureadline') - -if sys.platform.startswith('win'): - extras_require['terminal'].append('pyreadline>=2.0') -else: - install_requires.append('pexpect') - -everything = set() -for deps in extras_require.values(): - everything.update(deps) -extras_require['all'] = everything +extras_require = { + ':sys_platform != "win32"': ['terminado>=0.3.3'], + 'test:python_version == "2.7"': ['mock'], + 'test': ['nose', 'requests'], +} if 'setuptools' in sys.modules: # setup.py develop should check for submodules from setuptools.command.develop import develop setup_args['cmdclass']['develop'] = require_submodules(develop) - setup_args['cmdclass']['bdist_wheel'] = css_js_prerelease(get_bdist_wheel()) + + try: + from wheel.bdist_wheel import bdist_wheel + except ImportError: + pass + else: + setup_args['cmdclass']['bdist_wheel'] = css_js_prerelease(bdist_wheel) setuptools_extra_args['zip_safe'] = False - setuptools_extra_args['entry_points'] = { - 'console_scripts': find_entry_points(), - 'pygments.lexers': [ - 'ipythonconsole = IPython.lib.lexers:IPythonConsoleLexer', - 'ipython = IPython.lib.lexers:IPythonLexer', - 'ipython3 = IPython.lib.lexers:IPython3Lexer', - ], - } setup_args['extras_require'] = extras_require requires = setup_args['install_requires'] = install_requires - # Script to be run by the windows binary installer after the default setup - # routine, to add shortcuts and similar windows-only things. Windows - # post-install scripts MUST reside in the scripts/ dir, otherwise distutils - # doesn't find them. - if 'bdist_wininst' in sys.argv: - if len(sys.argv) > 2 and \ - ('sdist' in sys.argv or 'bdist_rpm' in sys.argv): - print("ERROR: bdist_wininst must be run alone. Exiting.", file=sys.stderr) - sys.exit(1) - setup_args['data_files'].append( - ['Scripts', ('scripts/ipython.ico', 'scripts/ipython_nb.ico')]) - setup_args['scripts'] = [pjoin('scripts','ipython_win_post_install.py')] - setup_args['options'] = {"bdist_wininst": - {"install_script": - "ipython_win_post_install.py"}} - -else: - # scripts has to be a non-empty list, or install_scripts isn't called - setup_args['scripts'] = [e.split('=')[0].strip() for e in find_entry_points()] - - setup_args['cmdclass']['build_scripts'] = build_scripts_entrypt - #--------------------------------------------------------------------------- # Do the actual setup now #--------------------------------------------------------------------------- diff --git a/setupbase.py b/setupbase.py index bdfed1fc0..4111bf959 100644 --- a/setupbase.py +++ b/setupbase.py @@ -1,10 +1,9 @@ # encoding: utf-8 """ -This module defines the things that are used in setup.py for building IPython +This module defines the things that are used in setup.py for building the notebook This includes: - * The basic arguments to setup * Functions for finding things like packages, package data, etc. * A function for checking dependencies. """ @@ -14,23 +13,17 @@ This includes: from __future__ import print_function -import errno import os import sys from distutils import log from distutils.command.build_py import build_py -from distutils.command.build_scripts import build_scripts -from distutils.command.install import install -from distutils.command.install_scripts import install_scripts from distutils.cmd import Command from distutils.errors import DistutilsExecError from fnmatch import fnmatch from glob import glob from subprocess import Popen, PIPE -from setupext import install_data_ext - #------------------------------------------------------------------------------- # Useful globals and utility functions #------------------------------------------------------------------------------- @@ -54,42 +47,18 @@ except NameError: locs = locs or globs exec(compile(open(fname).read(), fname, "exec"), globs, locs) -# A little utility we'll need below, since glob() does NOT allow you to do -# exclusion on multiple endings! -def file_doesnt_endwith(test,endings): - """Return true if test is a file and its name does NOT end with any - of the strings listed in endings.""" - if not isfile(test): - return False - for e in endings: - if test.endswith(e): - return False - return True #--------------------------------------------------------------------------- # Basic project information #--------------------------------------------------------------------------- +name = 'jupyter_notebook' + # release.py contains version, authors, license, url, keywords, etc. -execfile(pjoin(repo_root, 'IPython','core','release.py'), globals()) - -# Create a dict with the basic information -# This dict is eventually passed to setup after additional keys are added. -setup_args = dict( - name = name, - version = version, - description = description, - long_description = long_description, - author = author, - author_email = author_email, - url = url, - download_url = download_url, - license = license, - platforms = platforms, - keywords = keywords, - classifiers = classifiers, - cmdclass = {'install_data': install_data_ext}, - ) +version_ns = {} +execfile(pjoin(repo_root, name, '_version.py'), version_ns) + +version = version_ns['__version__'] #--------------------------------------------------------------------------- @@ -98,15 +67,11 @@ setup_args = dict( def find_packages(): """ - Find all of IPython's packages. + Find all of the packages. """ - excludes = ['deathrow', 'quarantine'] packages = [] - for dir,subdirs,files in os.walk('IPython'): + for dir,subdirs,files in os.walk(name): package = dir.replace(os.path.sep, '.') - if any(package.startswith('IPython.'+exc) for exc in excludes): - # package is to be excluded (e.g. deathrow) - continue if '__init__.py' not in files: # not a package continue @@ -119,78 +84,68 @@ def find_packages(): def find_package_data(): """ - Find IPython's package_data. + Find package_data. """ # This is not enough for these things to appear in an sdist. # We need to muck with the MANIFEST to get this to work # exclude components and less from the walk; # we will build the components separately - # excludes = [ - # pjoin('static', 'components'), - # pjoin('static', '*', 'less'), - # ] - # - # # walk notebook resources: - # cwd = os.getcwd() - # os.chdir(os.path.join('IPython', 'html')) - # static_data = [] - # for parent, dirs, files in os.walk('static'): - # if any(fnmatch(parent, pat) for pat in excludes): - # # prevent descending into subdirs - # dirs[:] = [] - # continue - # for f in files: - # static_data.append(pjoin(parent, f)) - # - # components = pjoin("static", "components") - # # select the components we actually need to install - # # (there are lots of resources we bundle for sdist-reasons that we don't actually use) - # static_data.extend([ - # pjoin(components, "backbone", "backbone-min.js"), - # pjoin(components, "bootstrap", "js", "bootstrap.min.js"), - # pjoin(components, "bootstrap-tour", "build", "css", "bootstrap-tour.min.css"), - # pjoin(components, "bootstrap-tour", "build", "js", "bootstrap-tour.min.js"), - # pjoin(components, "es6-promise", "*.js"), - # pjoin(components, "font-awesome", "fonts", "*.*"), - # pjoin(components, "google-caja", "html-css-sanitizer-minified.js"), - # pjoin(components, "jquery", "jquery.min.js"), - # pjoin(components, "jquery-ui", "ui", "minified", "jquery-ui.min.js"), - # pjoin(components, "jquery-ui", "themes", "smoothness", "jquery-ui.min.css"), - # pjoin(components, "jquery-ui", "themes", "smoothness", "images", "*"), - # pjoin(components, "marked", "lib", "marked.js"), - # pjoin(components, "requirejs", "require.js"), - # pjoin(components, "underscore", "underscore-min.js"), - # pjoin(components, "moment", "moment.js"), - # pjoin(components, "moment", "min", "moment.min.js"), - # pjoin(components, "term.js", "src", "term.js"), - # pjoin(components, "text-encoding", "lib", "encoding.js"), - # ]) - # - # # Ship all of Codemirror's CSS and JS - # for parent, dirs, files in os.walk(pjoin(components, 'codemirror')): - # for f in files: - # if f.endswith(('.js', '.css')): - # static_data.append(pjoin(parent, f)) - # - # os.chdir(os.path.join('tests',)) - # js_tests = glob('*.js') + glob('*/*.js') - - # os.chdir(cwd) + excludes = [ + pjoin('static', 'components'), + pjoin('static', '*', 'less'), + ] + + # walk notebook resources: + cwd = os.getcwd() + os.chdir('jupyter_notebook') + static_data = [] + for parent, dirs, files in os.walk('static'): + if any(fnmatch(parent, pat) for pat in excludes): + # prevent descending into subdirs + dirs[:] = [] + continue + for f in files: + static_data.append(pjoin(parent, f)) + + components = pjoin("static", "components") + # select the components we actually need to install + # (there are lots of resources we bundle for sdist-reasons that we don't actually use) + static_data.extend([ + pjoin(components, "backbone", "backbone-min.js"), + pjoin(components, "bootstrap", "js", "bootstrap.min.js"), + pjoin(components, "bootstrap-tour", "build", "css", "bootstrap-tour.min.css"), + pjoin(components, "bootstrap-tour", "build", "js", "bootstrap-tour.min.js"), + pjoin(components, "es6-promise", "*.js"), + pjoin(components, "font-awesome", "fonts", "*.*"), + pjoin(components, "google-caja", "html-css-sanitizer-minified.js"), + pjoin(components, "jquery", "jquery.min.js"), + pjoin(components, "jquery-ui", "ui", "minified", "jquery-ui.min.js"), + pjoin(components, "jquery-ui", "themes", "smoothness", "jquery-ui.min.css"), + pjoin(components, "jquery-ui", "themes", "smoothness", "images", "*"), + pjoin(components, "marked", "lib", "marked.js"), + pjoin(components, "requirejs", "require.js"), + pjoin(components, "underscore", "underscore-min.js"), + pjoin(components, "moment", "moment.js"), + pjoin(components, "moment", "min", "moment.min.js"), + pjoin(components, "term.js", "src", "term.js"), + pjoin(components, "text-encoding", "lib", "encoding.js"), + ]) + + # Ship all of Codemirror's CSS and JS + for parent, dirs, files in os.walk(pjoin(components, 'codemirror')): + for f in files: + if f.endswith(('.js', '.css')): + static_data.append(pjoin(parent, f)) + + os.chdir(os.path.join('tests',)) + js_tests = glob('*.js') + glob('*/*.js') + + os.chdir(cwd) package_data = { - 'IPython.core' : ['profile/README*'], - 'IPython.core.tests' : ['*.png', '*.jpg'], - 'IPython.lib.tests' : ['*.wav'], - 'IPython.testing.plugin' : ['*.txt'], - # 'IPython.html' : ['templates/*'] + static_data, - # 'IPython.html.tests' : js_tests, - # 'IPython.nbformat' : [ - # 'tests/*.ipynb', - # 'v3/nbformat.v3.schema.json', - # 'v4/nbformat.v4.schema.json', - # ], - # 'IPython.kernel': ['resources/*.*'], + 'jupyter_notebook' : ['templates/*'] + static_data, + 'jupyter_notebook.tests' : js_tests, } return package_data @@ -221,289 +176,20 @@ def check_package_data_first(command): return DecoratedCommand -#--------------------------------------------------------------------------- -# Find data files -#--------------------------------------------------------------------------- - -def make_dir_struct(tag,base,out_base): - """Make the directory structure of all files below a starting dir. - - This is just a convenience routine to help build a nested directory - hierarchy because distutils is too stupid to do this by itself. - - XXX - this needs a proper docstring! - """ - - # we'll use these a lot below - lbase = len(base) - pathsep = os.path.sep - lpathsep = len(pathsep) - - out = [] - for (dirpath,dirnames,filenames) in os.walk(base): - # we need to strip out the dirpath from the base to map it to the - # output (installation) path. This requires possibly stripping the - # path separator, because otherwise pjoin will not work correctly - # (pjoin('foo/','/bar') returns '/bar'). - - dp_eff = dirpath[lbase:] - if dp_eff.startswith(pathsep): - dp_eff = dp_eff[lpathsep:] - # The output path must be anchored at the out_base marker - out_path = pjoin(out_base,dp_eff) - # Now we can generate the final filenames. Since os.walk only produces - # filenames, we must join back with the dirpath to get full valid file - # paths: - pfiles = [pjoin(dirpath,f) for f in filenames] - # Finally, generate the entry we need, which is a pari of (output - # path, files) for use as a data_files parameter in install_data. - out.append((out_path, pfiles)) - - return out - - -def find_data_files(): - """ - Find IPython's data_files. - - Just man pages at this point. - """ - - manpagebase = pjoin('share', 'man', 'man1') - - # Simple file lists can be made by hand - manpages = [f for f in glob(pjoin('docs','man','*.1.gz')) if isfile(f)] - if not manpages: - # When running from a source tree, the manpages aren't gzipped - manpages = [f for f in glob(pjoin('docs','man','*.1')) if isfile(f)] - - # And assemble the entire output list - data_files = [ (manpagebase, manpages) ] - - return data_files - - -def make_man_update_target(manpage): - """Return a target_update-compliant tuple for the given manpage. - - Parameters - ---------- - manpage : string - Name of the manpage, must include the section number (trailing number). - - Example - ------- - - >>> make_man_update_target('ipython.1') #doctest: +NORMALIZE_WHITESPACE - ('docs/man/ipython.1.gz', - ['docs/man/ipython.1'], - 'cd docs/man && gzip -9c ipython.1 > ipython.1.gz') - """ - man_dir = pjoin('docs', 'man') - manpage_gz = manpage + '.gz' - manpath = pjoin(man_dir, manpage) - manpath_gz = pjoin(man_dir, manpage_gz) - gz_cmd = ( "cd %(man_dir)s && gzip -9c %(manpage)s > %(manpage_gz)s" % - locals() ) - return (manpath_gz, [manpath], gz_cmd) - -# The two functions below are copied from IPython.utils.path, so we don't need -# to import IPython during setup, which fails on Python 3. - -def target_outdated(target,deps): - """Determine whether a target is out of date. - - target_outdated(target,deps) -> 1/0 - - deps: list of filenames which MUST exist. - target: single filename which may or may not exist. - - If target doesn't exist or is older than any file listed in deps, return - true, otherwise return false. - """ - try: - target_time = os.path.getmtime(target) - except os.error: - return 1 - for dep in deps: - dep_time = os.path.getmtime(dep) - if dep_time > target_time: - #print "For target",target,"Dep failed:",dep # dbg - #print "times (dep,tar):",dep_time,target_time # dbg - return 1 - return 0 - - -def target_update(target,deps,cmd): - """Update a target with a given command given a list of dependencies. - - target_update(target,deps,cmd) -> runs cmd if target is outdated. - - This is just a wrapper around target_outdated() which calls the given - command if target is outdated.""" - - if target_outdated(target,deps): - os.system(cmd) - -#--------------------------------------------------------------------------- -# Find scripts -#--------------------------------------------------------------------------- - -def find_entry_points(): - """Defines the command line entry points for IPython - - This always uses setuptools-style entry points. When setuptools is not in - use, our own build_scripts_entrypt class below parses these and builds - command line scripts. - - Each of our entry points gets both a plain name, e.g. ipython, and one - suffixed with the Python major version number, e.g. ipython3. - """ - ep = [ - 'ipython%s = IPython:start_ipython', - 'iptest%s = IPython.testing.iptestcontroller:main', - ] - suffix = str(sys.version_info[0]) - return [e % '' for e in ep] + [e % suffix for e in ep] - -script_src = """#!{executable} -# This script was automatically generated by setup.py -if __name__ == '__main__': - from {mod} import {func} - {func}() -""" - -class build_scripts_entrypt(build_scripts): - """Build the command line scripts - - Parse setuptools style entry points and write simple scripts to run the - target functions. - - On Windows, this also creates .cmd wrappers for the scripts so that you can - easily launch them from a command line. - """ - def run(self): - self.mkpath(self.build_dir) - outfiles = [] - for script in find_entry_points(): - name, entrypt = script.split('=') - name = name.strip() - entrypt = entrypt.strip() - outfile = os.path.join(self.build_dir, name) - outfiles.append(outfile) - print('Writing script to', outfile) - - mod, func = entrypt.split(':') - with open(outfile, 'w') as f: - f.write(script_src.format(executable=sys.executable, - mod=mod, func=func)) - - if sys.platform == 'win32': - # Write .cmd wrappers for Windows so 'ipython' etc. work at the - # command line - cmd_file = os.path.join(self.build_dir, name + '.cmd') - cmd = '@"{python}" "%~dp0\{script}" %*\r\n'.format( - python=sys.executable, script=name) - log.info("Writing %s wrapper script" % cmd_file) - with open(cmd_file, 'w') as f: - f.write(cmd) - - return outfiles, outfiles - -class install_lib_symlink(Command): - user_options = [ - ('install-dir=', 'd', "directory to install to"), - ] - - def initialize_options(self): - self.install_dir = None - - def finalize_options(self): - self.set_undefined_options('symlink', - ('install_lib', 'install_dir'), - ) - - def run(self): - if sys.platform == 'win32': - raise Exception("This doesn't work on Windows.") - pkg = os.path.join(os.getcwd(), 'IPython') - dest = os.path.join(self.install_dir, 'IPython') - if os.path.islink(dest): - print('removing existing symlink at %s' % dest) - os.unlink(dest) - print('symlinking %s -> %s' % (pkg, dest)) - os.symlink(pkg, dest) - -class unsymlink(install): - def run(self): - dest = os.path.join(self.install_lib, 'IPython') - if os.path.islink(dest): - print('removing symlink at %s' % dest) - os.unlink(dest) - else: - print('No symlink exists at %s' % dest) - -class install_symlinked(install): - def run(self): - if sys.platform == 'win32': - raise Exception("This doesn't work on Windows.") - - # Run all sub-commands (at least those that need to be run) - for cmd_name in self.get_sub_commands(): - self.run_command(cmd_name) - - # 'sub_commands': a list of commands this command might have to run to - # get its work done. See cmd.py for more info. - sub_commands = [('install_lib_symlink', lambda self:True), - ('install_scripts_sym', lambda self:True), - ] - -class install_scripts_for_symlink(install_scripts): - """Redefined to get options from 'symlink' instead of 'install'. - - I love distutils almost as much as I love setuptools. - """ - def finalize_options(self): - self.set_undefined_options('build', ('build_scripts', 'build_dir')) - self.set_undefined_options('symlink', - ('install_scripts', 'install_dir'), - ('force', 'force'), - ('skip_build', 'skip_build'), - ) - -#--------------------------------------------------------------------------- -# Verify all dependencies -#--------------------------------------------------------------------------- - -def check_for_readline(): - """Check for GNU readline""" - try: - import gnureadline as readline - except ImportError: - pass - else: - return True - try: - import readline - except ImportError: - return False - else: - if sys.platform == 'darwin' and 'libedit' in readline.__doc__: - print("Ignoring readline linked to libedit", file=sys.stderr) - return False - return True - #--------------------------------------------------------------------------- # VCS related #--------------------------------------------------------------------------- # utils.submodule has checks for submodule status -execfile(pjoin('IPython','utils','submodule.py'), globals()) +submodule = {} +execfile(pjoin('jupyter_notebook','submodule.py'), submodule) +check_submodule_status = submodule['check_submodule_status'] +update_submodules = submodule['update_submodules'] class UpdateSubmodules(Command): """Update git submodules - IPython's external javascript dependencies live in a separate repo. + The Notebook's external javascript dependencies live in a separate repo. """ description = "Update git submodules" user_options = [] @@ -515,12 +201,10 @@ class UpdateSubmodules(Command): pass def run(self): - failure = False try: self.spawn('git submodule init'.split()) self.spawn('git submodule update --recursive'.split()) except Exception as e: - failure = e print(e) if not check_submodule_status(repo_root) == 'clean': @@ -528,58 +212,6 @@ class UpdateSubmodules(Command): sys.exit(1) -def git_prebuild(pkg_dir, build_cmd=build_py): - """Return extended build or sdist command class for recording commit - - records git commit in IPython.utils._sysinfo.commit - - for use in IPython.utils.sysinfo.sys_info() calls after installation. - - Also ensures that submodules exist prior to running - """ - - class MyBuildPy(build_cmd): - ''' Subclass to write commit data into installation tree ''' - def run(self): - build_cmd.run(self) - # this one will only fire for build commands - if hasattr(self, 'build_lib'): - self._record_commit(self.build_lib) - - def make_release_tree(self, base_dir, files): - # this one will fire for sdist - build_cmd.make_release_tree(self, base_dir, files) - self._record_commit(base_dir) - - def _record_commit(self, base_dir): - import subprocess - proc = subprocess.Popen('git rev-parse --short HEAD', - stdout=subprocess.PIPE, - stderr=subprocess.PIPE, - shell=True) - repo_commit, _ = proc.communicate() - repo_commit = repo_commit.strip().decode("ascii") - - out_pth = pjoin(base_dir, pkg_dir, 'utils', '_sysinfo.py') - if os.path.isfile(out_pth) and not repo_commit: - # nothing to write, don't clobber - return - - print("writing git commit '%s' to %s" % (repo_commit, out_pth)) - - # remove to avoid overwriting original via hard link - try: - os.remove(out_pth) - except (IOError, OSError): - pass - with open(out_pth, 'w') as out_file: - out_file.writelines([ - '# GENERATED BY setup.py\n', - 'commit = u"%s"\n' % repo_commit, - ]) - return require_submodules(MyBuildPy) - - def require_submodules(command): """decorator for instructing a command to check for submodules before running""" class DecoratedCommand(command): @@ -590,73 +222,6 @@ def require_submodules(command): command.run(self) return DecoratedCommand -#--------------------------------------------------------------------------- -# bdist related -#--------------------------------------------------------------------------- - -def get_bdist_wheel(): - """Construct bdist_wheel command for building wheels - - Constructs py2-none-any tag, instead of py2.7-none-any - """ - class RequiresWheel(Command): - description = "Dummy command for missing bdist_wheel" - user_options = [] - - def initialize_options(self): - pass - - def finalize_options(self): - pass - - def run(self): - print("bdist_wheel requires the wheel package") - sys.exit(1) - - if 'setuptools' not in sys.modules: - return RequiresWheel - else: - try: - from wheel.bdist_wheel import bdist_wheel, read_pkg_info, write_pkg_info - except ImportError: - return RequiresWheel - - class bdist_wheel_tag(bdist_wheel): - - def add_requirements(self, metadata_path): - """transform platform-dependent requirements""" - pkg_info = read_pkg_info(metadata_path) - # pkg_info is an email.Message object (?!) - # we have to remove the unconditional 'readline' and/or 'pyreadline' entries - # and transform them to conditionals - requires = pkg_info.get_all('Requires-Dist') - del pkg_info['Requires-Dist'] - def _remove_startswith(lis, prefix): - """like list.remove, but with startswith instead of ==""" - found = False - for idx, item in enumerate(lis): - if item.startswith(prefix): - found = True - break - if found: - lis.pop(idx) - - for pkg in ("gnureadline", "pyreadline", "mock", "terminado", "appnope", "pexpect"): - _remove_startswith(requires, pkg) - requires.append("gnureadline; sys.platform == 'darwin' and platform.python_implementation == 'CPython'") - requires.append("terminado (>=0.3.3); extra == 'notebook' and sys.platform != 'win32'") - requires.append("terminado (>=0.3.3); extra == 'all' and sys.platform != 'win32'") - requires.append("pyreadline (>=2.0); extra == 'terminal' and sys.platform == 'win32' and platform.python_implementation == 'CPython'") - requires.append("pyreadline (>=2.0); extra == 'all' and sys.platform == 'win32' and platform.python_implementation == 'CPython'") - requires.append("mock; extra == 'test' and python_version < '3.3'") - requires.append("appnope; sys.platform == 'darwin'") - requires.append("pexpect; sys.platform != 'win32'") - for r in requires: - pkg_info['Requires-Dist'] = r - write_pkg_info(metadata_path, pkg_info) - - return bdist_wheel_tag - #--------------------------------------------------------------------------- # Notebook related #---------------------------------------------------------------------------