#!/usr/bin/env python3
"""
Conda based provider.
https://conda.io/docs/
Conda is an open source package management system and environment management
system that runs on Windows, macOS and Linux. Conda quickly installs, runs and
updates packages and their dependencies. Conda easily creates, saves, loads and
switches between environments on your local computer. It was created for Python
programs, but it can package and distribute software for any language.
"""
import os
import re
import platform
import requests
from collections import namedtuple
from . import Provider
CondaVersionTuple = namedtuple("CondaVersionTuple", ("version", "system", "machine", "file"))
def _parse_version(filename):
"""Parse a Miniconda file name into a CondaVersionTuple object.
>>> _parse_version('Miniconda-1.9.1-Linux-x86_64.sh')
CondaVersionTuple(version=(1, 9, 1), system='Linux', machine='x86_64', file='Miniconda-1.9.1-Linux-x86_64.sh')
>>> _parse_version('Miniconda3-2.2.8-Windows-x86.exe')
CondaVersionTuple(version=(2, 2, 8), system='Windows', machine='x86', file='Miniconda3-2.2.8-Windows-x86.exe')
>>> _parse_version('Miniconda-3.16.0-Linux-armv7l.sh')
CondaVersionTuple(version=(3, 16, 0), system='Linux', machine='armv7l', file='Miniconda-3.16.0-Linux-armv7l.sh')
"""
s = os.path.splitext(filename)[0]
assert '-' in s, s
m, version, system, arch = s.split('-')
if version != 'latest':
assert '.' in version, version
version = tuple(int(v) for v in version.split('.'))
assert m.startswith('Miniconda')
return CondaVersionTuple(version, system, arch, filename)
def _extract_installer_info(filename):
"""
Extract the header information found at the top of the Miniconda install package.
>>> data = '''\
#!/bin/sh
#
# NAME: Miniconda3
# VER: 4.5.4
# PLAT: linux-64
# BYTES: 58468498
# LINES: 502
# MD5: 75a9f0faa822a01dfe0e0e5c43400ed0
'''
"""
pass
def _extract_versions(s):
"""Extract the available Miniconda version tuples from index page.
>>> versions = _extract_versions('''
... <tr>
... <td><a href="Miniconda3-1.9.1-Linux-x86_64.sh">Miniconda-1.9.1-Linux-x86_64.sh</a></td>
... <td class="s">18.9M</td>
... <td>2013-09-06 15:52:09</td>
... <td>7e446886360e48bf937c3b6eca610790</td>
... </tr>
... <tr>
... <td><a href="Miniconda3-1.6.0-Linux-x86_64.sh">Miniconda-1.6.0-Linux-x86_64.sh</a></td>
... <td class="s">18.7M</td>
... <td>2013-06-21 15:30:53</td>
... <td>892d6abdfe274765036ff174f2b360b0</td>
... </tr>
... </table>
... <address>Updated: 2018-06-07 00:11:09 CDT - Files: 376</address>
... <div>
... ''')
>>> for v in versions:
... print(v)
CondaVersionTuple(version=(1, 9, 1), system='Linux', machine='x86_64', file='Miniconda3-1.9.1-Linux-x86_64.sh')
CondaVersionTuple(version=(1, 6, 0), system='Linux', machine='x86_64', file='Miniconda3-1.6.0-Linux-x86_64.sh')
"""
for x in re.findall('a href="([^"]*)"', s):
if not x.startswith('Miniconda3'):
continue
v = _parse_version(x)
if v.version == "latest":
continue
yield v
# FIXME: Cache the live_versions in some way?
[docs]def live_versions():
"""Get the versions currently live on conda website."""
versions = {}
for ver in _extract_versions(requests.get('https://repo.continuum.io/miniconda').text):
if ver.system not in versions:
versions[ver.system] = {}
system_versions = versions[ver.system]
if ver.machine not in system_versions:
system_versions[ver.machine] = []
machine_versions = system_versions[ver.machine]
machine_versions.append(ver)
machine_versions.sort()
return versions
[docs]def installed_version():
"""
~/conda/bin/conda --version
conda 4.5.9
"""
pass
[docs]class Conda(Provider):
"""
The Conda provider can provide;
* Python environment which modules can be installed into.
* Tools (such as gcc / openocd)
"""
def __init__(self, download_dir):
# platform.machine() == 'x86' 32bit x86 computer -- maybe i686 or i386 or i586?
# platform.machine() == 'x86_64' 64bit x86 computer
# platform.machine() == 'armv6l' Older RPi
# platform.machine() == 'armv7l' Newest RPi
self.installer_url = self.INSTALLER_URL[platform.system()][platform.machine()]
pass
[docs] def install_module(self, module):
"""
# lite
for LITE in $LITE_REPOS; do
LITE_DIR=$THIRD_DIR/$LITE
(
echo
cd $LITE_DIR
echo "Installing $LITE from $LITE_DIR (local python module)"
python setup.py develop
)
check_import $LITE
done
"""
pass
[docs] def setup(self):
"""
# Hot patch conda so to not use the systems environments.
function fix_conda {
for py in $(find $CONDA_DIR -name envs_manager.py); do
START_SUM=$(sha256sum $py | sed -e's/ .*//')
sed -i -e"s^expand(join('~', '.conda', 'environments.txt'))^join('$CONDA_DIR', 'environments.txt')^" $py
END_SUM=$(sha256sum $py | sed -e's/ .*//')
if [ $START_SUM != $END_SUM ]; then
sed -i -e"s/$START_SUM/$END_SUM/" $(find $CONDA_DIR -name paths.json)
fi
done
}
if [[ ! -e $CONDA_DIR/bin/conda ]]; then
wget -c https://repo.continuum.io/miniconda/Miniconda3-latest-Linux-x86_64.sh
chmod a+x Miniconda3-latest-Linux-x86_64.sh
# -p to specify the install location
# -b to enable batch mode (no prompts)
# -f to not return an error if the location specified by -p already exists
./Miniconda3-latest-Linux-x86_64.sh -p $CONDA_DIR -b -f
fix_conda
conda config --system --set always_yes yes
conda config --system --set changeps1 no
conda config --system --add envs_dirs $CONDA_DIR/envs
conda config --system --add pkgs_dirs $CONDA_DIR/pkgs
conda update -q conda
fi
fix_conda
conda config --system --add channels timvideos
conda info
"""
pass
if __name__ == "__main__":
import doctest
doctest.testmod()
import pprint
print()
print("Current live conda versions")
print("-"*75)
pprint.pprint(live_versions())