repo2docker/repo2docker/buildpacks/julia/julia_project.py

159 wiersze
5.3 KiB
Python
Czysty Zwykły widok Historia

"""Generates a Dockerfile based on an input matrix for Julia"""
import os
import toml
2019-02-26 16:54:41 +00:00
from ..python import PythonBuildPack
2019-03-07 22:21:57 +00:00
from .semver import find_semver_match
2019-02-26 16:52:44 +00:00
class JuliaProjectTomlBuildPack(PythonBuildPack):
"""
Julia build pack which uses conda.
"""
2019-02-28 06:05:23 +00:00
# ALL EXISTING JULIA VERSIONS
# Note that these must remain ordered, in order for the find_semver_match()
# function to behave correctly.
2019-06-21 19:41:19 +00:00
all_julias = [
"0.7.0",
"1.0.0",
"1.0.1",
"1.0.2",
"1.0.3",
"1.0.4",
2019-12-01 18:36:27 +00:00
"1.0.5",
2019-06-21 19:41:19 +00:00
"1.1.0",
2019-06-21 20:38:25 +00:00
"1.1.1",
2019-08-26 04:46:23 +00:00
"1.2.0",
2019-12-01 18:36:27 +00:00
"1.3.0",
2020-01-01 00:29:54 +00:00
"1.3.1",
2020-04-08 22:19:46 +00:00
"1.4.0",
2019-06-21 19:41:19 +00:00
]
@property
def julia_version(self):
2019-03-06 03:54:24 +00:00
default_julia_version = self.all_julias[-1]
2019-03-05 16:40:34 +00:00
if os.path.exists(self.binder_path("JuliaProject.toml")):
project_toml = toml.load(self.binder_path("JuliaProject.toml"))
2019-03-02 17:56:13 +00:00
else:
project_toml = toml.load(self.binder_path("Project.toml"))
2019-03-05 16:40:34 +00:00
if "compat" in project_toml:
if "julia" in project_toml["compat"]:
julia_version_str = project_toml["compat"]["julia"]
2019-03-02 17:56:13 +00:00
2019-02-28 06:05:23 +00:00
# For Project.toml files, install the latest julia version that
# satisfies the given semver.
2019-03-05 21:54:13 +00:00
_julia_version = find_semver_match(julia_version_str, self.all_julias)
if _julia_version is not None:
return _julia_version
2019-03-05 16:40:34 +00:00
2019-02-28 06:05:23 +00:00
return default_julia_version
def get_build_env(self):
"""Get additional environment settings for Julia and Jupyter
Returns:
an ordered list of environment setting tuples
The tuples contain a string of the environment variable name and
a string of the environment setting:
- `JULIA_PATH`: base path where all Julia Binaries and libraries
will be installed
- `JULIA_DEPOT_PATH`: path where Julia libraries are installed.
- `JULIA_VERSION`: default version of julia to be installed
- `JUPYTER`: environment variable required by IJulia to point to
the `jupyter` executable
For example, a tuple may be `('JULIA_VERSION', '0.6.0')`.
"""
return super().get_build_env() + [
("JULIA_PATH", "${APP_BASE}/julia"),
("JULIA_DEPOT_PATH", "${JULIA_PATH}/pkg"),
("JULIA_VERSION", self.julia_version),
("JUPYTER", "${NB_PYTHON_PREFIX}/bin/jupyter"),
("JUPYTER_DATA_DIR", "${NB_PYTHON_PREFIX}/share/jupyter"),
]
def get_env(self):
return super().get_env() + [("JULIA_PROJECT", "${REPO_DIR}")]
def get_path(self):
"""Adds path to Julia binaries to user's PATH.
Returns:
an ordered list of path strings. The path to the Julia
executable is added to the list.
"""
return super().get_path() + ["${JULIA_PATH}/bin"]
def get_build_scripts(self):
"""
Return series of build-steps common to "ALL" Julia repositories
All scripts found here should be independent of contents of a
particular repository.
This creates a directory with permissions for installing julia packages
(from get_assemble_scripts).
"""
return super().get_build_scripts() + [
(
"root",
r"""
mkdir -p ${JULIA_PATH} && \
curl -sSL "https://julialang-s3.julialang.org/bin/linux/x64/${JULIA_VERSION%[.-]*}/julia-${JULIA_VERSION}-linux-x86_64.tar.gz" | tar -xz -C ${JULIA_PATH} --strip-components 1
""",
),
(
"root",
r"""
mkdir -p ${JULIA_DEPOT_PATH} && \
chown ${NB_USER}:${NB_USER} ${JULIA_DEPOT_PATH}
""",
),
2019-03-02 17:56:13 +00:00
]
def get_assemble_scripts(self):
"""
Return series of build-steps specific to "this" Julia repository
2019-03-21 19:55:34 +00:00
We make sure that the IJulia package gets installed into the default
environment, and not the project specific one, by running the
IJulia install command with JULIA_PROJECT="".
Instantiate and then precompile all packages in the repos julia
environment.
2019-03-02 17:56:13 +00:00
The parent, CondaBuildPack, will add the build steps for
any needed Python packages found in environment.yml.
"""
return super().get_assemble_scripts() + [
(
"${NB_USER}",
r"""
JULIA_PROJECT="" julia -e "using Pkg; Pkg.add(\"IJulia\"); using IJulia; installkernel(\"Julia\", \"--project=${REPO_DIR}\");" && \
julia --project=${REPO_DIR} -e 'using Pkg; Pkg.instantiate(); pkg"precompile"'
""",
)
]
def detect(self):
"""
Check if current repo should be built with the Julia Build pack
super().detect() is not called in this function - it would return
false unless an `environment.yml` is present and we do not want to
require the presence of a `environment.yml` to use Julia.
Instead we just check if the path to `Project.toml` or
`JuliaProject.toml` exists.
"""
return os.path.exists(self.binder_path("Project.toml")) or os.path.exists(
self.binder_path("JuliaProject.toml")
)