Repository: ipython/ipython

Issue:
python setup.py failed vs git submodule update worked
Hi, 

I am following master and just pulled to get the navigation feature. I'm using IPython from the git repo by issuing

```
python setup.py develop
```

after pulling. This time it told me to update the submodules. Issuing 

```
python setup.py submodule
```

threw an error. While 

```
git submodule update
```

worked. Not sure whether this problem is with my local installation or with some changes in master. I'm not even sure how to debug this. If you want me to test anything please feel free to ask.

Here is the full shell session including the traceback

``` shell
markus@zurich:~/python-dev/ipython$ python setup.py  develop
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.
markus@zurich:~/python-dev/ipython$ python setup.py submodule
Traceback (most recent call last):
  File "setup.py", line 193, in <module>
    package_data = find_package_data()
  File "/home/markus/python-dev/ipython/setupbase.py", line 197, in find_package_data
    assert len(glob(path)) > 0, "No files match pattern %s" % path
AssertionError: No files match pattern IPython/html/static/components/font-awesome/font/*.*
markus@zurich:~/python-dev/ipython$ git submodule update
Submodule path 'IPython/html/static/components': checked out 'bf1ac7f0df7207b26775089c5ac788ce11c23be5'
```



Discussion:
Hm, I need to think about that one. It's a check I just added to verify that pkg_data is valid, but that's computed before calling `setup.py submodule`, which is what makes it valid.  Maybe I can make validate a separate call somewhere else that makes more sense.


Resolving patch:
diff --git a/setup.py b/setup.py
--- a/setup.py
+++ b/setup.py
@@ -58,6 +58,7 @@
     setup_args,
     find_packages,
     find_package_data,
+    check_package_data_first,
     find_entry_points,
     build_scripts_entrypt,
     find_data_files,
@@ -191,6 +192,7 @@ def require_clean_submodules():
 
 packages = find_packages()
 package_data = find_package_data()
+
 data_files = find_data_files()
 
 setup_args['packages'] = packages
@@ -224,7 +226,7 @@ def run(self):
             self.upload_file('bdist_wininst', 'any', dist_file)
 
 setup_args['cmdclass'] = {
-    'build_py': git_prebuild('IPython'),
+    'build_py': check_package_data_first(git_prebuild('IPython')),
     'sdist' : git_prebuild('IPython', sdist),
     'upload_wininst' : UploadWindowsInstallers,
     'submodule' : UpdateSubmodules,
diff --git a/setupbase.py b/setupbase.py
--- a/setupbase.py
+++ b/setupbase.py
@@ -188,7 +188,12 @@ def find_package_data():
         'IPython.nbformat' : ['tests/*.ipynb']
     }
     
-    # verify that package_data makes sense
+    return package_data
+
+
+def check_package_data(package_data):
+    """verify that package_data globs make sense"""
+    print("checking package data")
     for pkg, data in package_data.items():
         pkg_root = pjoin(*pkg.split('.'))
         for d in data:
@@ -198,7 +203,17 @@ def find_package_data():
             else:
                 assert os.path.exists(path), "Missing package data: %s" % path
 
-    return package_data
+
+def check_package_data_first(command):
+    """decorator for checking package_data before running a given command
+    
+    Probably only needs to wrap build_py
+    """
+    class DecoratedCommand(command):
+        def run(self):
+            check_package_data(self.package_data)
+            command.run(self)
+    return DecoratedCommand
 
 
 #---------------------------------------------------------------------------


Test patch: