support for .binder directory
MODIFY
docs/source/design.md
docs/source/design.md
@@ -7,7 +7,7 @@ The philosophy for the repo2docker buildpacks includes:
- using common configuration files for familiar installation and packaging tools
- allowing configuration files to be combined to compose more complex setups
- specifying default locations for configuration files
-(the repository's root directory or .binder directory)
+(in the repository's root, `binder` or `.binder` directory)
When designing `repo2docker` and adding to it in the future, the

MODIFY
docs/source/usage.rst
docs/source/usage.rst
@@ -75,10 +75,11 @@ Where to put configuration files
``repo2docker`` will look for configuration files in either:
* A folder named ``binder/`` in the root of the repository.
+* A folder named ``.binder/`` in the root of the repository.
* The root directory of the repository.
-If the folder ``binder/`` is located at the top level of the repository,
-only configuration files in the ``binder/`` folder will be considered.
+If either the folder ``binder/`` or ``.binder/`` is located at the top level of
+the repository, only configuration files in that folder will be considered.
Check the complete list of :ref:`configuration files <config-files>` supported
by ``repo2docker`` to see how to configure the build process.

MODIFY
repo2docker/buildpacks/base.py
repo2docker/buildpacks/base.py
@@ -189,6 +189,7 @@ class BuildPack:
self.log = logging.getLogger('repo2docker')
self.appendix = ''
self.labels = {}
+ self._binder_dir = None
if sys.platform.startswith('win'):
self.log.warning("Windows environment detected. Note that Windows "
"support is experimental in repo2docker.")
@@ -414,12 +415,18 @@ class BuildPack:
"""
return None
+ @property
+ def binder_dir(self):
+ if self._binder_dir is None:
+ for dirname in ['binder', '.binder']:
+ if os.path.exists(dirname):
+ self._binder_dir = dirname
+ self._binder_dir = ''
+ return self._binder_dir
+
def binder_path(self, path):
"""Locate a file"""
- if os.path.exists('binder'):
- return os.path.join('binder', path)
- else:
- return path
+ return os.path.join(self.binder_dir, path)
def detect(self):
return True

MODIFY
repo2docker/buildpacks/nix/nix-shell-wrapper
repo2docker/buildpacks/nix/nix-shell-wrapper
@@ -8,12 +8,19 @@ _term() {
trap _term SIGTERM
+# find binder sub-directory (if present)
+for dir in "./binder" "./.binder"; do
+ if [ -e $dir ]; then
+ binder_dir = $dir
+ fi
+done
+
# if there is a binder/ sub-directory it takes precedence
# files outside it are ignored
-if [ -e ./binder ]; then
- nixpath="./binder/default.nix";
- if [ -f ./binder/start ]; then
- chmod u+x ./binder/start
+if [ -z $binder_dir ]; then
+ nixpath="$binder_dir/default.nix";
+ if [ -f $binder_dir/start ]; then
+ chmod u+x $binder_dir/start
# Using `$@`` here which is what the internet recommends leads to
# errors when the command is something like `jupyter --ip=0.0.0.0 ...`
# as nix-shell picks that up as an argument to it instead of the command.
@@ -21,7 +28,7 @@ if [ -e ./binder ]; then
# for -- to indicate "all arguments after this are for the command, not nix-shell"
# but it seems they have stalled/not yet produced an implementation.
# So let's use `$*` for now.
- nix-shell $nixpath --command "./binder/start $*" &
+ nix-shell $nixpath --command "$binder_dir/start $*" &
else
nix-shell $nixpath --command "$*" &
fi

MODIFY
repo2docker/buildpacks/python/__init__.py
repo2docker/buildpacks/python/__init__.py
@@ -67,7 +67,7 @@ class PythonBuildPack(CondaBuildPack):
))
# setup.py exists *and* binder dir is not used
- if not os.path.exists('binder') and os.path.exists(setup_py):
+ if not self.binder_dir and os.path.exists(setup_py):
assemble_scripts.append((
'${NB_USER}',
'{} install --no-cache-dir .'.format(pip)
@@ -88,6 +88,6 @@ class PythonBuildPack(CondaBuildPack):
return True
else:
return False
- if not os.path.exists('binder') and os.path.exists(setup_py):
+ if not self.binder_dir and os.path.exists(setup_py):
return True
return os.path.exists(requirements_txt)

MODIFY
repo2docker/buildpacks/r.py
repo2docker/buildpacks/r.py
@@ -84,7 +84,7 @@ class RBuildPack(PythonBuildPack):
return True
description_R = 'DESCRIPTION'
- if ((not os.path.exists('binder') and os.path.exists(description_R))
+ if (not self.binder_dir and os.path.exists(description_R)
or 'r' in self.stencila_contexts):
if not self.checkpoint_date:
# no R snapshot date set through runtime.txt
@@ -300,7 +300,7 @@ class RBuildPack(PythonBuildPack):
]
description_R = 'DESCRIPTION'
- if not os.path.exists('binder') and os.path.exists(description_R):
+ if not self.binder_dir and os.path.exists(description_R):
assemble_scripts += [
(
"${NB_USER}",

support for .binder directory