summaryrefslogtreecommitdiff
path: root/src/edu/stsci/Conda.groovy
diff options
context:
space:
mode:
Diffstat (limited to 'src/edu/stsci/Conda.groovy')
-rw-r--r--src/edu/stsci/Conda.groovy181
1 files changed, 181 insertions, 0 deletions
diff --git a/src/edu/stsci/Conda.groovy b/src/edu/stsci/Conda.groovy
new file mode 100644
index 0000000..dc67052
--- /dev/null
+++ b/src/edu/stsci/Conda.groovy
@@ -0,0 +1,181 @@
+package org.stsci
+
+class Conda implements Serializable {
+ public String prefix
+ public boolean prefix_exists
+ 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.shell_environment = [:]
+ this.environment_name = ""
+ this.channels = []
+ this.override = false
+
+ if (this.prefix_exists) {
+ this.activate("root")
+ }
+ }
+
+ private def runshell(String args, silent=false) {
+ def cmd = new String[3]
+ def proc_env = [:]
+
+ if (this.shell_environment) {
+ proc_env = this.shell_environment
+ }
+
+ cmd[0] = 'bash'
+ cmd[1] = '-c'
+ cmd[2] = args
+
+ def process = new ProcessBuilder(cmd)
+ process.redirectErrorStream(true)
+ Map<String, String> env_tmp = process.environment()
+
+ if (proc_env) {
+ env_tmp <<= proc_env
+ }
+
+ Process p = process.start()
+ if (!silent) {
+ p.inputStream.eachLine { println it}
+ }
+ p.waitFor()
+ return p
+ }
+
+ void activate(String conda_env) {
+ def records = [:]
+ 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 pair = line.split('=', 2).collect { it.trim() }
+ /* Strip out envmodules if they exist, i.e. multiline variables*/
+ if (pair[0].contains("_FUNC_") || !line.contains("=")) {
+ return
+ }
+ records."${pair[0]}" = pair[1]
+ }
+ }
+
+ /* runshell can now natively resolve this conda installation */
+ this.shell_environment = records
+
+ /* record latest conda environment name */
+ this.environment_name = conda_env
+ }
+
+ def version() {
+ return this.runshell("conda --version")
+ }
+
+ def verify() {
+ this.runshell("echo \$PATH")
+ this.runshell("which python")
+ this.runshell("python -c 'from pprint import pprint; import sys; pprint(sys.path)'")
+ }
+
+ 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)
+ }
+
+ 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 remove(String packages, boolean force=false) {
+ String args = ""
+ if (force) {
+ args = "--force"
+ }
+ def proc = this.command("remove", args, packages)
+ return proc.exitcode
+ }
+
+ int destroy(String name) {
+ String args = "-n \"${name}\""
+ def proc = this.command("env remove", args)
+ return proc.exitcode
+ }
+}
+