aboutsummaryrefslogtreecommitdiff
path: root/delivery_merge/conda.py
diff options
context:
space:
mode:
authorJoseph Hunkeler <jhunkeler@gmail.com>2019-05-07 12:27:05 -0400
committerJoseph Hunkeler <jhunkeler@gmail.com>2019-05-07 12:27:05 -0400
commit593537b7183adb0b4371ee19d6c6bd583267d305 (patch)
tree262659a479d1c09a9bd0d4c14ebfcdc0c9460544 /delivery_merge/conda.py
parent36740d90353c92e814917a0688764875fda49558 (diff)
downloaddelivery_merge-593537b7183adb0b4371ee19d6c6bd583267d305.tar.gz
Docstrings
Diffstat (limited to 'delivery_merge/conda.py')
-rw-r--r--delivery_merge/conda.py52
1 files changed, 50 insertions, 2 deletions
diff --git a/delivery_merge/conda.py b/delivery_merge/conda.py
index 709dbaf..44e15de 100644
--- a/delivery_merge/conda.py
+++ b/delivery_merge/conda.py
@@ -9,12 +9,25 @@ from subprocess import run
ENV_ORIG = os.environ.copy()
+class BadPlatform(Exception):
+ pass
+
+
def conda_installer(ver, prefix='./miniconda3'):
+ """ Install miniconda into a user-defined prefix and return its path
+
+ :param ver: str: miniconda version (not conda version)
+ :param prefix: str: path to install miniconda into
+ :returns: str: absolute path to installation prefix
+ :raises delivery_merge.conda.BadPlatform: when platform check fails
+ :raises subprocess.CalledProcessError: via check_returncode method
+ """
assert isinstance(ver, str)
assert isinstance(prefix, str)
prefix = os.path.abspath(prefix)
+ # Is miniconda already installed?
if os.path.exists(prefix):
print(f'{prefix}: exists', file=sys.stderr)
return prefix
@@ -23,36 +36,58 @@ def conda_installer(ver, prefix='./miniconda3'):
version = ver
arch = 'x86_64'
platform = sys.platform
+
+ # Emit their installer's concept of "platform"
if sys.platform == 'darwin':
platform = 'MacOSX'
elif sys.platform == 'linux':
platform = 'Linux'
+ else:
+ raise BadPlatform(f'{sys.platform} is not supported.')
url_root = 'https://repo.continuum.io/miniconda'
installer = f'{name}-{version}-{platform}-{arch}.sh'
url = f'{url_root}/{installer}'
install_command = f'./{installer} -b -p {prefix}'.split()
+ # Download installer
if not os.path.exists(installer):
with requests.get(url, stream=True) as data:
with open(installer, 'wb') as fd:
for chunk in data.iter_content(chunk_size=16384):
fd.write(chunk)
os.chmod(installer, 0o755)
- run(install_command)
+
+ # Perform installation
+ run(install_command).check_returncode()
return prefix
def conda_init_path(prefix):
+ """ Redefines $PATH so subsequent shell calls use the just-installed
+ miniconda prefix. This function will not continue prepending to $PATH
+ so it's safe to call more than once.
+
+ :param prefix: str: path to miniconda installation
+ :returns: None
+ """
if os.environ['PATH'] != ENV_ORIG['PATH']:
os.environ['PATH'] = ENV_ORIG['PATH']
os.environ['PATH'] = ':'.join([os.path.join(prefix, 'bin'),
os.environ['PATH']])
- print(f"PATH = {os.environ['PATH']}")
def conda_activate(env_name):
+ """ Activate a conda environment
+
+ Assume: `conda_init_path` as been called beforehand
+ Warning: Arbitrary code execution is possible here due to `shell` usage.
+
+ :param env_name: str: conda environment to activate
+ :returns: dict: new runtime environment
+ :raises subprocess.CalledProcessError: via check_returncode method
+ """
proc = run(f"source activate {env_name} && env",
capture_output=True,
shell=True)
@@ -62,6 +97,15 @@ def conda_activate(env_name):
@contextmanager
def conda_env_load(env_name):
+ """ A simple wrapper for `conda_activate`
+ The current runtime environment is replaced and restored
+
+ >>> with conda_env_load('some_env') as _:
+ >>> # do something
+
+ :param env_name: str: conda environment to activate
+ :returns: None
+ """
last = os.environ.copy()
os.environ = conda_activate(env_name)
try:
@@ -71,4 +115,8 @@ def conda_env_load(env_name):
def conda(*args):
+ """ Execute conda shell commands
+
+ :returns: subprocess.CompletedProcess object
+ """
return sh('conda', *args)