summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoseph Hunkeler <jhunkeler@gmail.com>2017-06-24 23:52:01 -0400
committerJoseph Hunkeler <jhunkeler@gmail.com>2017-06-24 23:52:01 -0400
commit6e0443d1ce9d461593b3480a20c71cf51b349b31 (patch)
tree71947032b2de55e80ebab746c0a9466f2a6b4277
parent46159bf66e2bb45b3bb53db3fd569e1f9c8500dd (diff)
downloadgroovy-sandbox-6e0443d1ce9d461593b3480a20c71cf51b349b31.tar.gz
Was not bored at all.
-rw-r--r--conda.groovy240
1 files changed, 212 insertions, 28 deletions
diff --git a/conda.groovy b/conda.groovy
index bb7d37f..a8e2fb7 100644
--- a/conda.groovy
+++ b/conda.groovy
@@ -1,29 +1,109 @@
-import java.lang.*
+class OSInfo {
+ public String name
+ public String version
+ public String arch
+
+ OSInfo () {
+ name = 'uname -s'.execute().text.trim()
+ if (name == 'Darwin') { name = 'MacOSX' }
+ arch = 'uname -p'.execute().text.trim()
+ if (arch.matches('^i.*86$')) { arch = 'x86' }
+
+ this.name = name
+ this.arch = arch
+ this.version = 'uname -r'.execute().text.trim()
+ }
+
+}
+
+class CondaInstaller {
+ OSInfo os
+ String prefix
+ String dist_version
+ String url
+ def dist = [:]
+
+ CondaInstaller(prefix, dist="miniconda", variant="3", version="latest") {
+ def distributions = [
+ miniconda: [name: 'Miniconda',
+ variant: variant,
+ baseurl: 'https://repo.continuum.io/miniconda'],
+ anaconda: [name: 'Anaconda',
+ variant: variant,
+ baseurl: 'https://repo.continuum.io/archive']
+ ]
+ this.os = new OSInfo()
+ this.dist = distributions."${dist}"
+ this.dist_version = version
+ this.prefix = prefix
+ this.url = "${this.dist.baseurl}/" +
+ "${this.dist.name}${this.dist.variant}-" +
+ "${this.dist_version}-${this.os.name}-${this.os.arch}.sh"
+ }
+
+ void download() {
+
+ println("Downloading $url")
+ File fp = new File('installer.sh')
+ def installer = fp.newOutputStream()
+ installer << new URL(this.url).openStream()
+ installer.close()
+ println("Received ${fp.length()} bytes")
+ }
+
+ int install() {
+ if (new File(this.prefix).exists()) {
+ println("Skipping installation: ${this.prefix} exists.")
+ return 0xFF
+ }
+
+ if (!new File('installer.sh').exists()) {
+ this.download()
+ }
+
+ def cmd = "bash installer.sh -b -p ${this.prefix}"
+ def proc = cmd.execute()
+ def stdout = new StringBuffer()
+
+ proc.inputStream.eachLine { println(it) }
+
+ //proc.waitForProcessOutput(stdout, System.err)
+ //print(stdout.toString())
+
+ return proc.exitValue()
+ }
+
+ private void detect() {
+ }
+}
class Conda {
public String prefix
public boolean prefix_exists
- public Map<String, String> sh_environment
- public String conda_environment
+ public Map<String, String> shell_environment
+ public String environment_name
+ public ArrayList channels
+ public boolean override
Conda (prefix) {
this.prefix = prefix
this.prefix_exists = new File(this.prefix).exists()
- this.sh_environment = [:]
- this.conda_environment = ""
+ this.shell_environment = [:]
+ this.environment_name = ""
+ this.channels = []
+ this.override = false
- /*if (this.prefix_exists) {
- println('Activating root environment')
- this.sh_environment = this.activate("root")
- }*/
+ if (this.prefix_exists) {
+ this.activate("root")
+ }
}
private def runshell(String args, silent=false) {
def cmd = new String[3]
def proc_env = [:]
- if (this.sh_environment) {
- proc_env = this.sh_environment
+ if (this.shell_environment) {
+ proc_env = this.shell_environment
}
cmd[0] = 'bash'
@@ -33,7 +113,10 @@ class Conda {
def process = new ProcessBuilder(cmd)
process.redirectErrorStream(true)
Map<String, String> env_tmp = process.environment()
- env_tmp <<= proc_env
+
+ if (proc_env) {
+ env_tmp <<= proc_env
+ }
Process p = process.start()
if (!silent) {
@@ -45,15 +128,25 @@ class Conda {
void activate(String conda_env) {
def records = [:]
- def bah = this.runshell("source ${prefix}/bin/activate ${conda_env} ; printenv", true)
- bah.inputStream.eachLine { line ->
+ def env_dump = this.runshell("source ${prefix}/bin/activate ${conda_env} ; printenv", true)
+
+ /* Split each environment keypair by first occurance of '=' */
+ env_dump.inputStream.eachLine { line ->
if(line) {
def (k, v) = line.split('=', 2).collect { it.trim() }
+ /* Strip out envmodules if they exist, i.e. multiline variables*/
+ if (k.contains("_FUNC_") || !line.contains("=")) {
+ return
+ }
records."$k" = v
}
}
- this.sh_environment = records
- this.conda_environment = conda_env
+
+ /* runshell can now natively resolve this conda installation */
+ this.shell_environment = records
+
+ /* record latest conda environment name */
+ this.environment_name = conda_env
}
def version() {
@@ -66,25 +159,116 @@ class Conda {
this.runshell("python -c 'from pprint import pprint; import sys; pprint(sys.path)'")
}
- void create(String name, String packages) {
- println("Creating environment: ${name}")
- this.runshell("conda create --yes -n \"${name}\" ${packages}")
+ def command(String task, String... args) {
+ /* Not every Conda task accepts --quiet or --yes
+ so only apply $extra_args when necessary */
+ ArrayList silent_args = ["--quiet", "--yes"]
+ boolean use_channels = false
+ boolean prompt_avoid = false
+ ArrayList channels = this.channels
+
+ switch (task) {
+ case 'install':
+ use_channels = true
+ prompt_avoid = true
+ break
+ case 'create':
+ use_channels = true
+ prompt_avoid = true
+ break
+ case 'search':
+ use_channels = true
+ case 'env remove':
+ prompt_avoid = true
+ break
+ default:
+ break
+ }
+
+ String cmd = "${prefix}/bin/conda ${task}"
+ cmd += ' ' + args.join(' ')
+ if (prompt_avoid) {
+ cmd += ' ' + silent_args.join(' ')
+ }
+
+ if (use_channels) {
+ if (this.override) {
+ cmd += " --override-channels"
+ channels.add("defaults")
+ }
+ for (channel in channels) {
+ cmd += ' -c ' + channel
+ }
+ }
+
+ println("[CONDA] ${cmd}")
+ return this.runshell(cmd)
}
- void install() {
+ boolean provides(String env_name) {
+ def result = ""
+ def output = this.runshell("${this.prefix}/bin/conda env list", true)
+
+ output.inputStream.eachLine { line ->
+ if (line && !line.matches('^#.*$')) {
+ def tmp = line.split(' ')[0].trim()
+ if (tmp == env_name) {
+ result = tmp
+ return
+ }
+ }
+ }
+ if (env_name == result) {
+ return true
+ }
+ return false
+ }
+
+ int create(String name, String packages) {
+ String args = "-n \"${name}\""
+ def proc = this.command("create", args, packages)
+ return proc.exitcode
+ }
+
+ int install(String packages, boolean reinstall=false) {
+ String args = ""
+ if (reinstall) {
+ args = "--force"
+ }
+ def proc = this.command("install", args, packages)
+ return proc.exitcode
}
+ int destroy(String name) {
+ String args = "-n \"${name}\""
+ def proc = this.command("env remove", args)
+ return proc.exitcode
+ }
}
static void main(String[] args) {
- println("OK")
- c = new Conda("/users/jhunk/anaconda3")
- c.activate("root")
- println("Conda exists: ${c.prefix_exists}")
- c.verify()
- c.create("groovy", "python=3.5")
- c.activate("groovy")
- c.verify()
+ final String PREFIX = "/tmp/miniconda3"
+ final String NAME = "astroconda35"
+ final String PKGS = "python=3.5 numpy=1.12 drizzlepac"
+
+ cinst = new CondaInstaller(PREFIX)
+ cinst.install()
+
+ c = new Conda(PREFIX)
+ assert c.prefix_exists == true
+
+ c.override = true
+ c.channels.add("astropy")
+ c.channels.add("http://ssb.stsci.edu/astroconda")
+ c.channels.add("conda-forge")
+
+ if (c.provides(NAME)) {
+ assert c.destroy(NAME) == 0
+ }
+ assert c.create(NAME, PKGS) == 0
+ c.activate(NAME)
+ assert c.environment_name == NAME
+ assert c.provides(NAME) == true
}