Skip to content

Commit

Permalink
nu_conda: Another Conda module with Better Performance (#367)
Browse files Browse the repository at this point in the history
* feat(virtual_environments): added nu_conda, another module for (de)activating Conda environments

* chore(nu_conda): added 1 QA to README.md
  • Loading branch information
neur1n authored Jan 30, 2023
1 parent 3334cad commit 01fbd8f
Show file tree
Hide file tree
Showing 2 changed files with 132 additions and 0 deletions.
52 changes: 52 additions & 0 deletions virtual_environments/nu_conda/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# Conda Module for Nushell
A simple module for activating and deactivating Conda environments.


## Prerequisites
- [nushell](https://github.com/nushell/nushell) >= 0.73.0


## Installation
Put `nu_conda.nu` into the module folder of your nushell configuration workspace.


## Usage
```nu
use nu_conda.nu # activate module
nu_conda activate py36 # activate a Conda environment, e.g. py36
nu_conda deactivate # deactivate the activated Conda environment
```

## Philosophy
This module re-implements the activation and deactivation functionalities of
the [conda.nu](https://github.com/Neur1n/nu_scripts/blob/main/virtual_environments/conda.nu)
module while providing a better performance, but not fully replacing it.


## FAQ
**Q**: How better is the performance?\
**A**: Activating a Conda environment costs ~20ms while conda.nu costs ~1500ms on
a PC with Windows 10 Enterprise OS and Intel i7-8700 3.20GHz CPU.

**Q**: How to show the current Conda environment in the prompt?\
**A**: This module does not automatically change the prompt when a Conda
environment is activated, but an environment variable `$env.CONDA_CURR` is set
to the name of the current Conda environment which can be used to customize the
prompt.


**Q**: Does it support Mamba/Micromamba?\
**A**: As [Mamba's documentation](https://mamba.readthedocs.io/en/latest/) said,
`mamba` is drop-in replacement for `conda`, and `micromamba` seems to be
another thing. This module only uses results of `conda/mamba info --envs --json`.
Therefore, I would say Mamba is (partially?) supported but I'm not sure about
Micromamba.


**Q**: How does it choose between Conda and Mamba?\
**A**: This module prefers calling `mamba` than `conda`, but it should be very
easy to change the preference by modifying the source code.


**Q**: Auto-completions?\
**A**: PRs are welcomed.
80 changes: 80 additions & 0 deletions virtual_environments/nu_conda/nu_conda.nu
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
export-env {
let-env CONDA_BASE_PATH = (if ((sys).host.name == "Windows") {$env.Path} else {$env.PATH})

let info = (
if not (which mamba | is-empty) {
(mamba info --envs --json | from json)
} else if not (which conda | is-empty) {
(conda info --envs --json | from json)
} else {
('{"root_prefix": "", "envs": ""}' | from json)
})

let-env CONDA_ROOT = $info.root_prefix

let-env CONDA_ENVS = ($info.envs | reduce -f {} {|it, acc|
if $it == $info.root_prefix {
$acc | upsert "base" $it
} else {
$acc | upsert ($it | path basename) $it
}})

let-env CONDA_CURR = null
}

export def-env activate [name: string] {
if ($env.CONDA_ROOT | is-empty) {
echo "Neither Conda nor Mamba is valid."
return
}

if not $name in $env.CONDA_ENVS {
echo $"Environment ($name) is invalid. Available:"
echo $env.CONDA_ENVS
return
}

let new_path = (
if ((sys).host.name == "Windows") {
update-path-windows ($env.CONDA_ENVS | get $name)
} else {
update-path-linux ($env.CONDA_ENVS | get $name)
})

load-env ({CONDA_CURR: $name} | merge $new_path)
}

export def-env deactivate [] {
if ($env.CONDA_ROOT | is-empty) {
echo "Neither Conda nor Mamba is valid."
return
}

let-env CONDA_CURR = null

load-env {Path: $env.CONDA_BASE_PATH, PATH: $env.CONDA_BASE_PATH}
}

def update-path-linux [env_path: path] {
let env_path = [
$env_path,
([$env_path, "bin"] | path join)
]

return {
Path: ($env.PATH | prepend $env_path),
PATH: ($env.PATH | prepend $env_path)
}
}

def update-path-windows [env_path: path] {
let env_path = [
$env_path,
([$env_path, "Scripts"] | path join),
]

return {
Path: ($env.Path | prepend $env_path),
PATH: ($env.Path | prepend $env_path)
}
}

0 comments on commit 01fbd8f

Please sign in to comment.