##// END OF EJS Templates
Merge pull request #3770 from damianavila/group_reveal...
Jonathan Frederic -
r11731:66d42bc5 merge
parent child Browse files
Show More
@@ -1,185 +1,185 b''
1 {%- extends 'slides.tpl' -%}
1 {%- extends 'reveal_internals/slides.tpl' -%}
2 2
3 3
4 4 {% block header %}
5 5 <!DOCTYPE html>
6 6 <html>
7 7 <head>
8 8
9 9 <meta charset="utf-8" />
10 10 <meta http-equiv="X-UA-Compatible" content="chrome=1">
11 11
12 12 <meta name="apple-mobile-web-app-capable" content="yes" />
13 13 <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
14 14
15 15 <!-- General and theme style sheets -->
16 16 <link rel="stylesheet" href="{{resources.reveal.url_prefix}}/css/reveal.css">
17 17 <link rel="stylesheet" href="{{resources.reveal.url_prefix}}/css/theme/simple.css" id="theme">
18 18
19 19 <!-- For syntax highlighting -->
20 20 <link rel="stylesheet" href="{{resources.reveal.url_prefix}}/lib/css/zenburn.css">
21 21
22 22 <!-- If the query includes 'print-pdf', use the PDF print sheet -->
23 23 <script>
24 24 document.write( '<link rel="stylesheet" href="{{resources.reveal.url_prefix}}/css/print/' + ( window.location.search.match( /print-pdf/gi ) ? 'pdf' : 'paper' ) + '.css" type="text/css" media="print">' );
25 25 </script>
26 26
27 27 <!--[if lt IE 9]>
28 28 <script src="{{resources.reveal.url_prefix}}/lib/js/html5shiv.js"></script>
29 29 <![endif]-->
30 30
31 31 {% for css in resources.inlining.css -%}
32 32 <style type="text/css">
33 33 {{css}}
34 34 </style>
35 35 {% endfor %}
36 36
37 37 <style type="text/css">
38 38 /* Overrides of notebook CSS for static HTML export */
39 39 .reveal {
40 40 font-size: 20px;
41 41 overflow-y: auto;
42 42 overflow-x: hidden;
43 43 }
44 44 .reveal pre {
45 45 width: 95%;
46 46 padding: 0.4em;
47 47 margin: 0px;
48 48 font-family: monospace, sans-serif;
49 49 font-size: 80%;
50 50 box-shadow: 0px 0px 0px rgba(0, 0, 0, 0);
51 51 }
52 52 .reveal section img {
53 53 border: 0px solid black;
54 54 box-shadow: 0 0 10px rgba(0, 0, 0, 0);
55 55 }
56 56 .reveal .slides {
57 57 text-align: left;
58 58 }
59 59 .reveal.fade {
60 60 opacity: 1;
61 61 }
62 62 div.input_area {
63 63 padding: 0.06em;
64 64 }
65 65 div.code_cell {
66 66 background-color: transparent;
67 67 }
68 68 div.prompt {
69 69 width: 11ex;
70 70 padding: 0.4em;
71 71 margin: 0px;
72 72 font-family: monospace, sans-serif;
73 73 font-size: 80%;
74 74 text-align: right;
75 75 }
76 76 div.output_area pre {
77 77 font-family: monospace, sans-serif;
78 78 font-size: 80%;
79 79 }
80 80 div.output_prompt {
81 81 /* 5px right shift to account for margin in parent container */
82 82 margin: 5px 5px 0 0;
83 83 }
84 84 .rendered_html p {
85 85 text-align: inherit;
86 86 }
87 87 </style>
88 88
89 89 <!-- Custom stylesheet, it must be in the same directory as the html file -->
90 90 <link rel="stylesheet" href="custom.css">
91 91
92 92 </head>
93 93 {% endblock header%}
94 94
95 95
96 96 {% block body %}
97 97 <body>
98 98 <div class="reveal"><div class="slides">
99 99
100 100 {{ super() }}
101 101
102 102 </div></div>
103 103
104 104 <!--
105 105 Uncomment the following block and the addthis_widget.js (see below inside dependencies)
106 106 to get enable social buttons.
107 107 -->
108 108
109 109 <!--
110 110 <div class="addthis_toolbox addthis_floating_style addthis_32x32_style" style="left:20px;top:20px;">
111 111 <a class="addthis_button_twitter"></a>
112 112 <a class="addthis_button_google_plusone_share"></a>
113 113 <a class="addthis_button_linkedin"></a>
114 114 <a class="addthis_button_facebook"></a>
115 115 <a class="addthis_button_more"></a>
116 116 </div>
117 117 -->
118 118
119 119 <script src="{{resources.reveal.url_prefix}}/lib/js/head.min.js"></script>
120 120
121 121 <script src="{{resources.reveal.url_prefix}}/js/reveal.js"></script>
122 122
123 123 <script>
124 124
125 125 // Full list of configuration options available here: https://github.com/hakimel/reveal.js#configuration
126 126 Reveal.initialize({
127 127 controls: true,
128 128 progress: true,
129 129 history: true,
130 130
131 131 theme: Reveal.getQueryHash().theme, // available themes are in /css/theme
132 132 transition: Reveal.getQueryHash().transition || 'linear', // default/cube/page/concave/zoom/linear/none
133 133
134 134 // Optional libraries used to extend on reveal.js
135 135 dependencies: [
136 136 { src: "{{resources.reveal.url_prefix}}/lib/js/classList.js", condition: function() { return !document.body.classList; } },
137 137 { src: "{{resources.reveal.url_prefix}}/plugin/highlight/highlight.js", async: true, callback: function() { hljs.initHighlightingOnLoad(); } },
138 138 { src: "{{resources.reveal.url_prefix}}/plugin/notes/notes.js", async: true, condition: function() { return !!document.body.classList; } }
139 139 // { src: 'http://s7.addthis.com/js/300/addthis_widget.js', async: true},
140 140 ]
141 141 });
142 142 </script>
143 143
144 144 <!-- MathJax configuration -->
145 145 <script type="text/x-mathjax-config">
146 146 MathJax.Hub.Config({
147 147 tex2jax: {
148 148 inlineMath: [ ['$','$'], ["\\(","\\)"] ],
149 149 displayMath: [ ['$$','$$'], ["\\[","\\]"] ]
150 150 },
151 151 displayAlign: 'left', // Change this to 'center' to center equations.
152 152 "HTML-CSS": {
153 153 styles: {'.MathJax_Display': {"margin": 0}}
154 154 }
155 155 });
156 156 </script>
157 157 <!-- End of mathjax configuration -->
158 158
159 159 <script>
160 160 // We wait for the onload function to load MathJax after the page is completely loaded.
161 161 // MathJax is loaded 1 unit of time after the page is ready.
162 162 // This hack prevent problems when you load multiple js files (i.e. social button from addthis).
163 163 //
164 164 window.onload = function () {
165 165 setTimeout(function () {
166 166 var script = document.createElement("script");
167 167 script.type = "text/javascript";
168 168 script.src = "https://c328740.ssl.cf1.rackcdn.com/mathjax/latest/MathJax.js?config=TeX-AMS_HTML";
169 169 document.getElementsByTagName("head")[0].appendChild(script);
170 170 },1)
171 171 }
172 172 </script>
173 173
174 174 <script>
175 175 Reveal.addEventListener( 'slidechanged', function( event ) {
176 176 MathJax.Hub.Rerender(event.currentSlide);
177 177 });
178 178 </script>
179 179
180 180 </body>
181 181 {% endblock body %}
182 182
183 183 {% block footer %}
184 184 </html>
185 185 {% endblock footer %}
@@ -1,17 +1,17 b''
1 {%- extends 'reveal_cells.tpl' -%}
1 {%- extends 'reveal_internals/reveal_cells.tpl' -%}
2 2
3 3
4 4
5 5 {%- block any_cell scoped -%}
6 6 {%- if cell.metadata.align_type in ['Left'] -%}
7 7 {{ super() }}
8 8 {%- elif cell.metadata.align_type in ['center'] -%}
9 9 <div style="text-align:center">
10 10 {{ super() }}
11 11 </div>
12 12 {%- elif cell.metadata.align_type in ['right'] -%}
13 13 <div style="text-align:right">
14 14 {{ super() }}
15 15 </div>
16 16 {%- endif -%}
17 17 {%- endblock any_cell -%}
1 NO CONTENT: file renamed from IPython/nbconvert/templates/reveal_cells.tpl to IPython/nbconvert/templates/reveal_internals/reveal_cells.tpl
@@ -1,17 +1,17 b''
1 {%- extends 'subslides.tpl' -%}
1 {%- extends 'reveal_internals/subslides.tpl' -%}
2 2
3 3
4 4
5 5 {%- block any_cell scoped -%}
6 6 {%- if cell.metadata.slide_type in ['slide'] -%}
7 7 <section>
8 8 <section>
9 9 {%- endif -%}
10 10
11 11 {{ super() }}
12 12
13 13 {%- if cell.metadata.slide_helper in ['slide_end'] -%}
14 14 </section>
15 15 </section>
16 16 {%- endif -%}
17 17 {%- endblock any_cell -%}
@@ -1,15 +1,15 b''
1 {%- extends 'align_reveal_cells.tpl' -%}
1 {%- extends 'reveal_internals/align_reveal_cells.tpl' -%}
2 2
3 3
4 4
5 5 {%- block any_cell scoped -%}
6 6 {%- if cell.metadata.slide_type in ['subslide'] -%}
7 7 <section>
8 8 {%- endif -%}
9 9
10 10 {{ super() }}
11 11
12 12 {%- if cell.metadata.slide_helper in ['subslide_end'] -%}
13 13 </section>
14 14 {%- endif -%}
15 15 {%- endblock any_cell -%}
@@ -1,474 +1,475 b''
1 1 # encoding: utf-8
2 2 """
3 3 This module defines the things that are used in setup.py for building IPython
4 4
5 5 This includes:
6 6
7 7 * The basic arguments to setup
8 8 * Functions for finding things like packages, package data, etc.
9 9 * A function for checking dependencies.
10 10 """
11 11 from __future__ import print_function
12 12
13 13 #-------------------------------------------------------------------------------
14 14 # Copyright (C) 2008 The IPython Development Team
15 15 #
16 16 # Distributed under the terms of the BSD License. The full license is in
17 17 # the file COPYING, distributed as part of this software.
18 18 #-------------------------------------------------------------------------------
19 19
20 20 #-------------------------------------------------------------------------------
21 21 # Imports
22 22 #-------------------------------------------------------------------------------
23 23 import os
24 24 import sys
25 25
26 26 try:
27 27 from configparser import ConfigParser
28 28 except:
29 29 from ConfigParser import ConfigParser
30 30 from distutils.command.build_py import build_py
31 31 from distutils.cmd import Command
32 32 from glob import glob
33 33
34 34 from setupext import install_data_ext
35 35
36 36 #-------------------------------------------------------------------------------
37 37 # Useful globals and utility functions
38 38 #-------------------------------------------------------------------------------
39 39
40 40 # A few handy globals
41 41 isfile = os.path.isfile
42 42 pjoin = os.path.join
43 43 repo_root = os.path.dirname(os.path.abspath(__file__))
44 44
45 45 def oscmd(s):
46 46 print(">", s)
47 47 os.system(s)
48 48
49 49 # Py3 compatibility hacks, without assuming IPython itself is installed with
50 50 # the full py3compat machinery.
51 51
52 52 try:
53 53 execfile
54 54 except NameError:
55 55 def execfile(fname, globs, locs=None):
56 56 locs = locs or globs
57 57 exec(compile(open(fname).read(), fname, "exec"), globs, locs)
58 58
59 59 # A little utility we'll need below, since glob() does NOT allow you to do
60 60 # exclusion on multiple endings!
61 61 def file_doesnt_endwith(test,endings):
62 62 """Return true if test is a file and its name does NOT end with any
63 63 of the strings listed in endings."""
64 64 if not isfile(test):
65 65 return False
66 66 for e in endings:
67 67 if test.endswith(e):
68 68 return False
69 69 return True
70 70
71 71 #---------------------------------------------------------------------------
72 72 # Basic project information
73 73 #---------------------------------------------------------------------------
74 74
75 75 # release.py contains version, authors, license, url, keywords, etc.
76 76 execfile(pjoin(repo_root, 'IPython','core','release.py'), globals())
77 77
78 78 # Create a dict with the basic information
79 79 # This dict is eventually passed to setup after additional keys are added.
80 80 setup_args = dict(
81 81 name = name,
82 82 version = version,
83 83 description = description,
84 84 long_description = long_description,
85 85 author = author,
86 86 author_email = author_email,
87 87 url = url,
88 88 download_url = download_url,
89 89 license = license,
90 90 platforms = platforms,
91 91 keywords = keywords,
92 92 classifiers = classifiers,
93 93 cmdclass = {'install_data': install_data_ext},
94 94 )
95 95
96 96
97 97 #---------------------------------------------------------------------------
98 98 # Find packages
99 99 #---------------------------------------------------------------------------
100 100
101 101 def find_packages():
102 102 """
103 103 Find all of IPython's packages.
104 104 """
105 105 excludes = ['deathrow', 'quarantine']
106 106 packages = []
107 107 for dir,subdirs,files in os.walk('IPython'):
108 108 package = dir.replace(os.path.sep, '.')
109 109 if any(package.startswith('IPython.'+exc) for exc in excludes):
110 110 # package is to be excluded (e.g. deathrow)
111 111 continue
112 112 if '__init__.py' not in files:
113 113 # not a package
114 114 continue
115 115 packages.append(package)
116 116 return packages
117 117
118 118 #---------------------------------------------------------------------------
119 119 # Find package data
120 120 #---------------------------------------------------------------------------
121 121
122 122 def find_package_data():
123 123 """
124 124 Find IPython's package_data.
125 125 """
126 126 # This is not enough for these things to appear in an sdist.
127 127 # We need to muck with the MANIFEST to get this to work
128 128
129 129 # exclude static things that we don't ship (e.g. mathjax)
130 130 excludes = ['mathjax']
131 131
132 132 # add 'static/' prefix to exclusions, and tuplify for use in startswith
133 133 excludes = tuple([os.path.join('static', ex) for ex in excludes])
134 134
135 135 # walk notebook resources:
136 136 cwd = os.getcwd()
137 137 os.chdir(os.path.join('IPython', 'html'))
138 138 static_walk = list(os.walk('static'))
139 139 os.chdir(cwd)
140 140 static_data = []
141 141 for parent, dirs, files in static_walk:
142 142 if parent.startswith(excludes):
143 143 continue
144 144 for f in files:
145 145 static_data.append(os.path.join(parent, f))
146 146
147 147 package_data = {
148 148 'IPython.config.profile' : ['README*', '*/*.py'],
149 149 'IPython.core.tests' : ['*.png', '*.jpg'],
150 150 'IPython.testing' : ['*.txt'],
151 151 'IPython.testing.plugin' : ['*.txt'],
152 152 'IPython.html' : ['templates/*'] + static_data,
153 153 'IPython.qt.console' : ['resources/icon/*.svg'],
154 154 'IPython.nbconvert' : ['templates/*.tpl', 'templates/latex/*.tplx',
155 155 'templates/latex/skeleton/*.tplx', 'templates/skeleton/*',
156 'tests/files/*.*', 'exporters/tests/files/*.*']
156 'templates/reveal_internals/*.tpl', 'tests/files/*.*',
157 'exporters/tests/files/*.*']
157 158 }
158 159 return package_data
159 160
160 161
161 162 #---------------------------------------------------------------------------
162 163 # Find data files
163 164 #---------------------------------------------------------------------------
164 165
165 166 def make_dir_struct(tag,base,out_base):
166 167 """Make the directory structure of all files below a starting dir.
167 168
168 169 This is just a convenience routine to help build a nested directory
169 170 hierarchy because distutils is too stupid to do this by itself.
170 171
171 172 XXX - this needs a proper docstring!
172 173 """
173 174
174 175 # we'll use these a lot below
175 176 lbase = len(base)
176 177 pathsep = os.path.sep
177 178 lpathsep = len(pathsep)
178 179
179 180 out = []
180 181 for (dirpath,dirnames,filenames) in os.walk(base):
181 182 # we need to strip out the dirpath from the base to map it to the
182 183 # output (installation) path. This requires possibly stripping the
183 184 # path separator, because otherwise pjoin will not work correctly
184 185 # (pjoin('foo/','/bar') returns '/bar').
185 186
186 187 dp_eff = dirpath[lbase:]
187 188 if dp_eff.startswith(pathsep):
188 189 dp_eff = dp_eff[lpathsep:]
189 190 # The output path must be anchored at the out_base marker
190 191 out_path = pjoin(out_base,dp_eff)
191 192 # Now we can generate the final filenames. Since os.walk only produces
192 193 # filenames, we must join back with the dirpath to get full valid file
193 194 # paths:
194 195 pfiles = [pjoin(dirpath,f) for f in filenames]
195 196 # Finally, generate the entry we need, which is a pari of (output
196 197 # path, files) for use as a data_files parameter in install_data.
197 198 out.append((out_path, pfiles))
198 199
199 200 return out
200 201
201 202
202 203 def find_data_files():
203 204 """
204 205 Find IPython's data_files.
205 206
206 207 Most of these are docs.
207 208 """
208 209
209 210 docdirbase = pjoin('share', 'doc', 'ipython')
210 211 manpagebase = pjoin('share', 'man', 'man1')
211 212
212 213 # Simple file lists can be made by hand
213 214 manpages = [f for f in glob(pjoin('docs','man','*.1.gz')) if isfile(f)]
214 215 if not manpages:
215 216 # When running from a source tree, the manpages aren't gzipped
216 217 manpages = [f for f in glob(pjoin('docs','man','*.1')) if isfile(f)]
217 218
218 219 igridhelpfiles = [f for f in glob(pjoin('IPython','extensions','igrid_help.*')) if isfile(f)]
219 220
220 221 # For nested structures, use the utility above
221 222 example_files = make_dir_struct(
222 223 'data',
223 224 pjoin('docs','examples'),
224 225 pjoin(docdirbase,'examples')
225 226 )
226 227 manual_files = make_dir_struct(
227 228 'data',
228 229 pjoin('docs','html'),
229 230 pjoin(docdirbase,'manual')
230 231 )
231 232
232 233 # And assemble the entire output list
233 234 data_files = [ (manpagebase, manpages),
234 235 (pjoin(docdirbase, 'extensions'), igridhelpfiles),
235 236 ] + manual_files + example_files
236 237
237 238 return data_files
238 239
239 240
240 241 def make_man_update_target(manpage):
241 242 """Return a target_update-compliant tuple for the given manpage.
242 243
243 244 Parameters
244 245 ----------
245 246 manpage : string
246 247 Name of the manpage, must include the section number (trailing number).
247 248
248 249 Example
249 250 -------
250 251
251 252 >>> make_man_update_target('ipython.1') #doctest: +NORMALIZE_WHITESPACE
252 253 ('docs/man/ipython.1.gz',
253 254 ['docs/man/ipython.1'],
254 255 'cd docs/man && gzip -9c ipython.1 > ipython.1.gz')
255 256 """
256 257 man_dir = pjoin('docs', 'man')
257 258 manpage_gz = manpage + '.gz'
258 259 manpath = pjoin(man_dir, manpage)
259 260 manpath_gz = pjoin(man_dir, manpage_gz)
260 261 gz_cmd = ( "cd %(man_dir)s && gzip -9c %(manpage)s > %(manpage_gz)s" %
261 262 locals() )
262 263 return (manpath_gz, [manpath], gz_cmd)
263 264
264 265 # The two functions below are copied from IPython.utils.path, so we don't need
265 266 # to import IPython during setup, which fails on Python 3.
266 267
267 268 def target_outdated(target,deps):
268 269 """Determine whether a target is out of date.
269 270
270 271 target_outdated(target,deps) -> 1/0
271 272
272 273 deps: list of filenames which MUST exist.
273 274 target: single filename which may or may not exist.
274 275
275 276 If target doesn't exist or is older than any file listed in deps, return
276 277 true, otherwise return false.
277 278 """
278 279 try:
279 280 target_time = os.path.getmtime(target)
280 281 except os.error:
281 282 return 1
282 283 for dep in deps:
283 284 dep_time = os.path.getmtime(dep)
284 285 if dep_time > target_time:
285 286 #print "For target",target,"Dep failed:",dep # dbg
286 287 #print "times (dep,tar):",dep_time,target_time # dbg
287 288 return 1
288 289 return 0
289 290
290 291
291 292 def target_update(target,deps,cmd):
292 293 """Update a target with a given command given a list of dependencies.
293 294
294 295 target_update(target,deps,cmd) -> runs cmd if target is outdated.
295 296
296 297 This is just a wrapper around target_outdated() which calls the given
297 298 command if target is outdated."""
298 299
299 300 if target_outdated(target,deps):
300 301 os.system(cmd)
301 302
302 303 #---------------------------------------------------------------------------
303 304 # Find scripts
304 305 #---------------------------------------------------------------------------
305 306
306 307 def find_scripts(entry_points=False, suffix=''):
307 308 """Find IPython's scripts.
308 309
309 310 if entry_points is True:
310 311 return setuptools entry_point-style definitions
311 312 else:
312 313 return file paths of plain scripts [default]
313 314
314 315 suffix is appended to script names if entry_points is True, so that the
315 316 Python 3 scripts get named "ipython3" etc.
316 317 """
317 318 if entry_points:
318 319 console_scripts = [s % suffix for s in [
319 320 'ipython%s = IPython:start_ipython',
320 321 'pycolor%s = IPython.utils.PyColorize:main',
321 322 'ipcontroller%s = IPython.parallel.apps.ipcontrollerapp:launch_new_instance',
322 323 'ipengine%s = IPython.parallel.apps.ipengineapp:launch_new_instance',
323 324 'iplogger%s = IPython.parallel.apps.iploggerapp:launch_new_instance',
324 325 'ipcluster%s = IPython.parallel.apps.ipclusterapp:launch_new_instance',
325 326 'iptest%s = IPython.testing.iptest:main',
326 327 'irunner%s = IPython.lib.irunner:main',
327 328 ]]
328 329 gui_scripts = []
329 330 scripts = dict(console_scripts=console_scripts, gui_scripts=gui_scripts)
330 331 else:
331 332 parallel_scripts = pjoin('IPython','parallel','scripts')
332 333 main_scripts = pjoin('IPython','scripts')
333 334 scripts = [
334 335 pjoin(parallel_scripts, 'ipengine'),
335 336 pjoin(parallel_scripts, 'ipcontroller'),
336 337 pjoin(parallel_scripts, 'ipcluster'),
337 338 pjoin(parallel_scripts, 'iplogger'),
338 339 pjoin(main_scripts, 'ipython'),
339 340 pjoin(main_scripts, 'pycolor'),
340 341 pjoin(main_scripts, 'irunner'),
341 342 pjoin(main_scripts, 'iptest')
342 343 ]
343 344 return scripts
344 345
345 346 #---------------------------------------------------------------------------
346 347 # Verify all dependencies
347 348 #---------------------------------------------------------------------------
348 349
349 350 def check_for_dependencies():
350 351 """Check for IPython's dependencies.
351 352
352 353 This function should NOT be called if running under setuptools!
353 354 """
354 355 from setupext.setupext import (
355 356 print_line, print_raw, print_status,
356 357 check_for_sphinx, check_for_pygments,
357 358 check_for_nose, check_for_pexpect,
358 359 check_for_pyzmq, check_for_readline,
359 360 check_for_jinja2
360 361 )
361 362 print_line()
362 363 print_raw("BUILDING IPYTHON")
363 364 print_status('python', sys.version)
364 365 print_status('platform', sys.platform)
365 366 if sys.platform == 'win32':
366 367 print_status('Windows version', sys.getwindowsversion())
367 368
368 369 print_raw("")
369 370 print_raw("OPTIONAL DEPENDENCIES")
370 371
371 372 check_for_sphinx()
372 373 check_for_pygments()
373 374 check_for_nose()
374 375 check_for_pexpect()
375 376 check_for_pyzmq()
376 377 check_for_readline()
377 378 check_for_jinja2()
378 379
379 380 #---------------------------------------------------------------------------
380 381 # VCS related
381 382 #---------------------------------------------------------------------------
382 383
383 384 # utils.submodule has checks for submodule status
384 385 execfile(pjoin('IPython','utils','submodule.py'), globals())
385 386
386 387 class UpdateSubmodules(Command):
387 388 """Update git submodules
388 389
389 390 IPython's external javascript dependencies live in a separate repo.
390 391 """
391 392 description = "Update git submodules"
392 393 user_options = []
393 394
394 395 def initialize_options(self):
395 396 pass
396 397
397 398 def finalize_options(self):
398 399 pass
399 400
400 401 def run(self):
401 402 failure = False
402 403 try:
403 404 self.spawn('git submodule init'.split())
404 405 self.spawn('git submodule update --recursive'.split())
405 406 except Exception as e:
406 407 failure = e
407 408 print(e)
408 409
409 410 if not check_submodule_status(repo_root) == 'clean':
410 411 print("submodules could not be checked out")
411 412 sys.exit(1)
412 413
413 414
414 415 def git_prebuild(pkg_dir, build_cmd=build_py):
415 416 """Return extended build or sdist command class for recording commit
416 417
417 418 records git commit in IPython.utils._sysinfo.commit
418 419
419 420 for use in IPython.utils.sysinfo.sys_info() calls after installation.
420 421
421 422 Also ensures that submodules exist prior to running
422 423 """
423 424
424 425 class MyBuildPy(build_cmd):
425 426 ''' Subclass to write commit data into installation tree '''
426 427 def run(self):
427 428 build_cmd.run(self)
428 429 # this one will only fire for build commands
429 430 if hasattr(self, 'build_lib'):
430 431 self._record_commit(self.build_lib)
431 432
432 433 def make_release_tree(self, base_dir, files):
433 434 # this one will fire for sdist
434 435 build_cmd.make_release_tree(self, base_dir, files)
435 436 self._record_commit(base_dir)
436 437
437 438 def _record_commit(self, base_dir):
438 439 import subprocess
439 440 proc = subprocess.Popen('git rev-parse --short HEAD',
440 441 stdout=subprocess.PIPE,
441 442 stderr=subprocess.PIPE,
442 443 shell=True)
443 444 repo_commit, _ = proc.communicate()
444 445 repo_commit = repo_commit.strip().decode("ascii")
445 446
446 447 out_pth = pjoin(base_dir, pkg_dir, 'utils', '_sysinfo.py')
447 448 if os.path.isfile(out_pth) and not repo_commit:
448 449 # nothing to write, don't clobber
449 450 return
450 451
451 452 print("writing git commit '%s' to %s" % (repo_commit, out_pth))
452 453
453 454 # remove to avoid overwriting original via hard link
454 455 try:
455 456 os.remove(out_pth)
456 457 except (IOError, OSError):
457 458 pass
458 459 with open(out_pth, 'w') as out_file:
459 460 out_file.writelines([
460 461 '# GENERATED BY setup.py\n',
461 462 'commit = "%s"\n' % repo_commit,
462 463 ])
463 464 return require_submodules(MyBuildPy)
464 465
465 466
466 467 def require_submodules(command):
467 468 """decorator for instructing a command to check for submodules before running"""
468 469 class DecoratedCommand(command):
469 470 def run(self):
470 471 if not check_submodule_status(repo_root) == 'clean':
471 472 print("submodules missing! Run `setup.py submodule` and try again")
472 473 sys.exit(1)
473 474 command.run(self)
474 475 return DecoratedCommand
General Comments 0
You need to be logged in to leave comments. Login now