Skip to content

Commit 7552361

Browse files
authored
Merge pull request #309 from minrk/stencila
stencila support
2 parents 784bbff + 4aff6c5 commit 7552361

File tree

15 files changed

+753
-10
lines changed

15 files changed

+753
-10
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ MANIFEST
99

1010
.DS_Store
1111
.cache
12+
.pytest_cache
1213
.coverage
1314
htmlcov
1415

.travis.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ env:
3737
matrix:
3838
- REPO_TYPE=conda
3939
- REPO_TYPE=venv
40+
- REPO_TYPE=stencila
4041
- REPO_TYPE=julia
4142
- REPO_TYPE=r
4243
- REPO_TYPE=dockerfile

repo2docker/buildpacks/base.py

Lines changed: 90 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -65,9 +65,9 @@
6565
6666
EXPOSE 8888
6767
68-
{% if env -%}
69-
# Almost all environment variables
70-
{% for item in env -%}
68+
{% if build_env -%}
69+
# Environment variables required for build
70+
{% for item in build_env -%}
7171
ENV {{item[0]}} {{item[1]}}
7272
{% endfor -%}
7373
{% endif -%}
@@ -94,6 +94,14 @@
9494
COPY src/ ${HOME}
9595
RUN chown -R ${NB_USER}:${NB_USER} ${HOME}
9696
97+
{% if env -%}
98+
# The rest of the environment
99+
{% for item in env -%}
100+
ENV {{item[0]}} {{item[1]}}
101+
{% endfor -%}
102+
{% endif -%}
103+
104+
97105
# Run assemble scripts! These will actually build the specification
98106
# in the repository into the image.
99107
{% for sd in assemble_script_directives -%}
@@ -182,6 +190,21 @@ def get_base_packages(self):
182190
"unzip",
183191
}
184192

193+
def get_build_env(self):
194+
"""
195+
Ordered list of environment variables to be set for this image.
196+
197+
Ordered so that environment variables can use other environment
198+
variables in their values.
199+
200+
Expects tuples, with the first item being the environment variable
201+
name and the second item being the value.
202+
203+
These environment variables will be set prior to build.
204+
Use .get_env() to set environment variables after build.
205+
"""
206+
return []
207+
185208
def get_env(self):
186209
"""
187210
Ordered list of environment variables to be set for this image.
@@ -191,6 +214,8 @@ def get_env(self):
191214
192215
Expects tuples, with the first item being the environment variable
193216
name and the second item being the value.
217+
218+
These variables will not be available to build.
194219
"""
195220
return []
196221

@@ -225,6 +250,30 @@ def get_build_script_files(self):
225250
"""
226251
return {}
227252

253+
254+
@property
255+
def stencila_manifest_dir(self):
256+
"""Find the stencila manifest dir if it exists"""
257+
if hasattr(self, '_stencila_manifest_dir'):
258+
return self._stencila_manifest_dir
259+
260+
# look for a manifest.xml that suggests stencila could be used
261+
# when we find one, stencila should be installed
262+
# and set environment variables such that
263+
# this file is located at:
264+
# ${STENCILA_ARCHIVE_DIR}/${STENCILA_ARCHIVE}/manifest.xml
265+
266+
self._stencila_manifest_dir = None
267+
for root, dirs, files in os.walk("."):
268+
if "manifest.xml" in files:
269+
self._stencila_manifest_dir = root.split(os.path.sep, 1)[1]
270+
self.log.info(
271+
"Found stencila manifest.xml in %s",
272+
self._stencila_manifest_dir,
273+
)
274+
break
275+
return self._stencila_manifest_dir
276+
228277
def get_build_scripts(self):
229278
"""
230279
Ordered list of shell script snippets to build the base image.
@@ -322,6 +371,7 @@ def render(self):
322371
return t.render(
323372
packages=sorted(self.get_packages()),
324373
path=self.get_path(),
374+
build_env=self.get_build_env(),
325375
env=self.get_env(),
326376
labels=self.get_labels(),
327377
build_script_directives=build_script_directives,
@@ -388,11 +438,31 @@ def _filter_tar(tar):
388438

389439

390440
class BaseImage(BuildPack):
391-
def get_env(self):
441+
def get_build_env(self):
442+
"""Return env directives required for build"""
392443
return [
393444
("APP_BASE", "/srv")
394445
]
395446

447+
def get_env(self):
448+
"""Return env directives to be set after build"""
449+
env = []
450+
if self.stencila_manifest_dir:
451+
# manifest_dir is the path containing the manifest.xml
452+
# archive_dir is the directory containing archive directories (one level up)
453+
# default archive is the name of the directory in the archive_dir
454+
# such that
455+
# ${STENCILA_ARCHIVE_DIR}/${STENCILA_ARCHIVE}/manifest.xml
456+
# exists.
457+
458+
archive_dir, archive = os.path.split(self.stencila_manifest_dir)
459+
env.extend([
460+
("STENCILA_ARCHIVE_DIR", "${HOME}/" + archive_dir),
461+
("STENCILA_ARCHIVE", archive),
462+
])
463+
return env
464+
465+
396466
def detect(self):
397467
return True
398468

@@ -425,6 +495,22 @@ def get_assemble_scripts(self):
425495
))
426496
except FileNotFoundError:
427497
pass
498+
if self.stencila_manifest_dir:
499+
assemble_scripts.extend(
500+
[
501+
(
502+
"${NB_USER}",
503+
r"""
504+
${KERNEL_PYTHON_PREFIX}/bin/pip install --no-cache https://github.com/stencila/py/archive/f6a245fd.tar.gz && \
505+
${KERNEL_PYTHON_PREFIX}/bin/python -m stencila register && \
506+
${NB_PYTHON_PREFIX}/bin/pip install --no-cache nbstencilaproxy==0.1.1 && \
507+
jupyter serverextension enable --sys-prefix --py nbstencilaproxy && \
508+
jupyter nbextension install --sys-prefix --py nbstencilaproxy && \
509+
jupyter nbextension enable --sys-prefix --py nbstencilaproxy
510+
""",
511+
)
512+
]
513+
)
428514
return assemble_scripts
429515

430516
def get_post_build_scripts(self):

repo2docker/buildpacks/conda/__init__.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,14 @@ class CondaBuildPack(BaseImage):
1818
Uses miniconda since it is more lightweight than Anaconda.
1919
2020
"""
21-
def get_env(self):
21+
def get_build_env(self):
2222
"""Return environment variables to be set.
2323
2424
We set `CONDA_DIR` to the conda install directory and
2525
the `NB_PYTHON_PREFIX` to the location of the jupyter binary.
2626
2727
"""
28-
env = super().get_env() + [
28+
env = super().get_build_env() + [
2929
('CONDA_DIR', '${APP_BASE}/conda'),
3030
('NB_PYTHON_PREFIX', '${CONDA_DIR}'),
3131
]

repo2docker/buildpacks/julia.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ class JuliaBuildPack(CondaBuildPack):
1212
See https://github.com/JuliaPy/PyCall.jl/issues/410
1313
1414
"""
15-
def get_env(self):
15+
def get_build_env(self):
1616
"""Get additional environment settings for Julia and Jupyter
1717
1818
Returns:
@@ -31,7 +31,7 @@ def get_env(self):
3131
For example, a tuple may be `('JULIA_VERSION', '0.6.0')`.
3232
3333
"""
34-
return super().get_env() + [
34+
return super().get_build_env() + [
3535
('JULIA_PATH', '${APP_BASE}/julia'),
3636
('JULIA_HOME', '${JULIA_PATH}/bin'),
3737
('JULIA_PKGDIR', '${JULIA_PATH}/pkg'),

repo2docker/buildpacks/r.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,15 +82,15 @@ def get_path(self):
8282
'/usr/lib/rstudio-server/bin/'
8383
]
8484

85-
def get_env(self):
85+
def get_build_env(self):
8686
"""
8787
Return environment variables to be set.
8888
8989
We want libraries to be installed in a path that users can write to
9090
without needing root. This is set via the `R_LIBS_USER` environment
9191
variable, so we set that here.
9292
"""
93-
return super().get_env() + [
93+
return super().get_build_env() + [
9494
# This is the path where user libraries are installed
9595
('R_LIBS_USER', '${APP_BASE}/rlibs')
9696
]
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
@article{kluyver2016jupyter,
2+
title={Jupyter Notebooks-a publishing format for reproducible computational workflows.},
3+
author={Kluyver, Thomas and Ragan-Kelley, Benjamin and P{\'e}rez, Fernando and Granger, Brian E and Bussonnier, Matthias and Frederic, Jonathan and Kelley, Kyle and Hamrick, Jessica B and Grout, Jason and Corlay, Sylvain and others},
4+
journal={ELPUB},
5+
pages={87--90},
6+
year={2016}
7+
}
8+
@article{ragan2014jupyter,
9+
title={The Jupyter/IPython architecture: a unified view of computational research, from interactive exploration to communication and publication.},
10+
author={Ragan-Kelley, M and Perez, F and Granger, B and Kluyver, T and Ivanov, P and Frederic, J and Bussonnier, M},
11+
journal={AGU Fall Meeting Abstracts},
12+
year={2014}
13+
}
14+
@article{perez2015project,
15+
title={Project Jupyter: Computational narratives as the engine of collaborative data science},
16+
author={Perez, Fernando and Granger, Brian E},
17+
journal={Retrieved September},
18+
volume={11},
19+
pages={207},
20+
year={2015}
21+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<dar>
2+
<documents>
3+
<document id="py-jupyter.ipynb" name="py-jupyter.ipynb" type="article" path="py-jupyter.ipynb.jats.xml" src="py-jupyter.ipynb" />
4+
</documents>
5+
<assets/>
6+
</dar>

tests/stencila/basic/archive/py-jupyter/py-jupyter.ipynb

Lines changed: 195 additions & 0 deletions
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)