Merge pull request #3275 from minrk/submodule-hooks

improve submodule messages / git hooks
This commit is contained in:
Brian E. Granger 2013-05-09 15:51:43 -07:00
commit fa872236a2
6 changed files with 69 additions and 46 deletions

View File

@ -6,7 +6,7 @@ Authors:
* Brian Granger
"""
#-----------------------------------------------------------------------------
# Copyright (C) 2008-2011 The IPython Development Team
# Copyright (C) 2013 The IPython Development Team
#
# Distributed under the terms of the BSD License. The full license is in
# the file COPYING, distributed as part of this software.
@ -90,6 +90,7 @@ from IPython.kernel.zmq.kernelapp import (
)
from IPython.utils.importstring import import_item
from IPython.utils.localinterfaces import LOCALHOST
from IPython.utils import submodule
from IPython.utils.traitlets import (
Dict, Unicode, Integer, List, Enum, Bool,
DottedObjectName
@ -323,7 +324,7 @@ class NotebookApp(BaseIPythonApplication):
def _log_format_default(self):
"""override default log format to include time"""
return u"%(asctime)s.%(msecs).03d [%(name)s] %(message)s"
return u"%(asctime)s.%(msecs).03d [%(name)s]%(highlevel)s %(message)s"
# create requested profiles by default, if they don't exist:
auto_create = Bool(True)
@ -537,10 +538,6 @@ class NotebookApp(BaseIPythonApplication):
# and all of its ancenstors until propagate is set to False.
self.log.propagate = False
# set the date format
formatter = logging.Formatter(self.log_format, datefmt="%Y-%m-%d %H:%M:%S")
self.log.handlers[0].setFormatter(formatter)
# hook up tornado 3's loggers to our app handlers
for name in ('access', 'application', 'general'):
logging.getLogger('tornado.%s' % name).handlers = self.log.handlers
@ -673,11 +670,23 @@ class NotebookApp(BaseIPythonApplication):
def _signal_info(self, sig, frame):
print self.notebook_info()
def init_components(self):
"""Check the components submodule, and warn if it's unclean"""
status = submodule.check_submodule_status()
if status == 'missing':
self.log.warn("components submodule missing, running `git submodule update`")
submodule.update_submodules(submodule.ipython_parent())
elif status == 'unclean':
self.log.warn("components submodule unclean, you may see 404s on static/components")
self.log.warn("run `setup.py submodule` or `git submodule update` to update")
@catch_config_error
def initialize(self, argv=None):
self.init_logging()
super(NotebookApp, self).initialize(argv)
self.init_configurables()
self.init_components()
self.init_webapp()
self.init_signal()

13
git-hooks/README.md Normal file
View File

@ -0,0 +1,13 @@
git hooks for IPython
add these to your `.git/hooks`
For now, we just have `post-checkout` and `post-merge`,
both of which just update submodules,
so make sure that you have a fully synced repo whenever you checkout or pull.
To use these hooks, you can symlink or copy them to your `.git/hooks` directory.
ln -s ../../git-hooks/post-checkout .git/hooks/post-checkout
ln -s ../../git-hooks/post-merge .git/hooks/post-merge

4
git-hooks/post-checkout Executable file
View File

@ -0,0 +1,4 @@
#!/bin/sh
git submodule init
git submodule update

4
git-hooks/post-merge Executable file
View File

@ -0,0 +1,4 @@
#!/bin/sh
git submodule init
git submodule update

View File

@ -68,7 +68,7 @@ from setupbase import (
find_data_files,
check_for_dependencies,
git_prebuild,
check_for_submodules,
check_submodule_status,
update_submodules,
require_submodules,
UpdateSubmodules,
@ -112,21 +112,37 @@ if os_name == 'windows' and 'sdist' in sys.argv:
#-------------------------------------------------------------------------------
# Make sure we aren't trying to run without submodules
#-------------------------------------------------------------------------------
here = os.path.abspath(os.path.dirname(__file__))
def ensure_submodules_exist():
"""Check out git submodules before distutils can do anything
def require_clean_submodules():
"""Check on git submodules before distutils can do anything
Because distutils cannot be trusted to update the tree
after everything has been set in motion.
Since distutils cannot be trusted to update the tree
after everything has been set in motion,
this is not a distutils command.
"""
# don't do anything if nothing is actually supposed to happen
for do_nothing in ('-h', '--help', '--help-commands', 'clean'):
for do_nothing in ('-h', '--help', '--help-commands', 'clean', 'submodule'):
if do_nothing in sys.argv:
return
if not check_for_submodules():
update_submodules()
ensure_submodules_exist()
status = check_submodule_status(here)
if status == "missing":
print("checking out submodules for the first time")
update_submodules(here)
elif status == "unclean":
print('\n'.join([
"Cannot build / install IPython with unclean submodules",
"Please update submodules with",
" python setup.py submodule",
"or",
" git submodule update",
"or commit any submodule changes you have made."
]))
sys.exit(1)
require_clean_submodules()
#-------------------------------------------------------------------------------
# Things related to the IPython documentation

View File

@ -373,27 +373,10 @@ def check_for_dependencies():
# VCS related
#---------------------------------------------------------------------------
def check_for_submodules():
"""return False if there are any submodules that need to be checked out,
True otherwise.
here = os.path.abspath(os.path.dirname(__file__))
This doesn't check if they are up to date, only existence.
"""
here = os.path.dirname(__file__)
submodules = [
os.path.join(here, 'IPython', 'frontend', 'html', 'notebook', 'static', 'components')
]
for submodule in submodules:
if not os.path.exists(submodule):
return False
return True
def update_submodules():
"""update git submodules"""
import subprocess
print("updating git submodules")
subprocess.check_call('git submodule init'.split())
subprocess.check_call('git submodule update --recursive'.split())
# utils.submodule has checks for submodule status
execfile(pjoin('IPython','utils','submodule.py'), globals())
class UpdateSubmodules(Command):
"""Update git submodules
@ -418,12 +401,10 @@ class UpdateSubmodules(Command):
failure = e
print(e)
if not check_for_submodules():
if not check_submodule_status(here) == 'clean':
print("submodules could not be checked out")
sys.exit(1)
# re-scan package data after update
self.distribution.package_data = find_package_data()
def git_prebuild(pkg_dir, build_cmd=build_py):
"""Return extended build or sdist command class for recording commit
@ -438,10 +419,6 @@ def git_prebuild(pkg_dir, build_cmd=build_py):
class MyBuildPy(build_cmd):
''' Subclass to write commit data into installation tree '''
def run(self):
if not check_for_submodules():
print("submodules missing! Run `setup.py submodule` and try again")
sys.exit(1)
build_cmd.run(self)
# this one will only fire for build commands
if hasattr(self, 'build_lib'):
@ -478,14 +455,14 @@ def git_prebuild(pkg_dir, build_cmd=build_py):
'# GENERATED BY setup.py\n',
'commit = "%s"\n' % repo_commit,
])
return MyBuildPy
return require_submodules(MyBuildPy)
def require_submodules(command):
"""decorator for instructing a command to check for submodules before running"""
class DecoratedCommand(command):
def run(self):
if not check_for_submodules():
if not check_submodule_status(here) == 'clean':
print("submodules missing! Run `setup.py submodule` and try again")
sys.exit(1)
command.run(self)