1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
|
# sh-ves: Bourne Shell Virtual Environment System
sh-ves is a collection of simple scripts for managing the values
of environment variables. It can be used to create independent
collections of variables, with their values, which are called
environments, and swap between them.
sh-ves is not a package manager, and does not directly interface
with a package manager. It simple allows swapping between environments,
so it is on the user to install the different versions of various packages
on their own, if they would like to use sh-ves for this.
## Installation
To install, run
```bash
$ make install
```
which will copy the scripts into `~/.local/bin/ves_scripts`, create the
sh-ves data directories, and install the `ves(1)` man page to
`~/.local/share/man/man1`. Then add the following line to your shell's rc or
profile file,
```bash
. ~/.local/bin/ves_scripts/ves-init.sh
```
sh-ves operates by defining shell functions, so this file must be sourced
into each shell session that wants to use it. `make uninstall` removes the
scripts; `make purge` additionally removes all data, including your saved
environments.
### fish
sh-ves also works in fish via a shim. If fish is detected, `make install`
copies `ves.fish` to `~/.config/fish/functions/` (which autoloads a `ves`
function — no rc file changes needed) and tab completions to
`~/.config/fish/completions/`. The shim runs each command through
the real POSIX implementation in an `sh` subshell, then replays any
environment changes into the fish session, so all commands behave
identically. Activation state is carried in exported `SHVES_SAVED_*`
variables, so activate/deactivate work across invocations.
## Commands
sh-ves consists of a series of related scripts, which can be called
from a global wrapper function for convenience. All of these examples use
the global wrapper.
### Create a new environment
A new environment can be created by using the command,
```bash
$ ves create
```
The default environment will not override any environment variables
from the parent process. If you would like to override the PATH and LDPATH
variables, use the following,
```bash
$ ves create --override
```
Be aware that this will truncate PATH and LDPATH to empty strings initially,
and so you will need to set these up yourself within the environment.
### Activate an environment
To activate a created environment, use the command,
```bash
$ ves activate
```
An environment of the specified name must exist, and no other ves environment
can be active already. ves environments do not support composition, and the
system will not allow a second environment to be activated on top of an
existing one.
Activating a ves environment will apply all of the stored environment
variables over top of the parent environment.
### Deactivate an environment
To deactivate a ves environment, use the command,
```bash
$ ves deactivate
```
when within an active environment. This will restore the environment variables
to the state they were prior to activating the environment.
### Switch between environments
As a convenience, the command,
```bash
$ ves switch
```
will deactivate the current environment (if any) and activate the named
one in a single step.
### Run a command inside an environment
To run a one-off command inside an environment without activating it,
```bash
$ ves run
```
The environment is applied in a subshell, so the current shell is left
untouched and no deactivation is necessary.
### Add a variable to the environment
To add a new environment variable to the environment, use the command
```bash
$ ves export [--env=]
```
If called from within an activate ves environment, the `--env` flag can
be omitted, which will result in the export applying to the active
environment.
To remove a variable from an environment entirely,
```bash
$ ves unset [--env=]
```
If the target environment is active, the live variable is restored to its
pre-activation value.
To see all variables stored in an environment,
```bash
$ ves show []
```
which defaults to the active environment when no name is given.
### Manage PATH, LDPATH, etc.
A variety of important environment variables actually represent :-delimited
arrays, such as PATH and LDPATH. These are called "path-like" in sh-ves.
To facilitate managing these, sh-ves has some specific functionality
related to adding and removing elements from these variables.
To add an entry to a path-like variable,
```bash
$ ves var-add [--env=] [--append]
```
will prepend `:` to the specified variable (or append `:`
with the `--append` flag, for fallback entries). If the variable is not
yet stored in the environment, it is seeded from the live shell value
first, so prepending to PATH never truncates it. To truncate PATH and
friends deliberately, create the environment with `--override`.
To remove an entry from a path-like variable,
```bash
ves var-rm [--env=]
```
will remove `:` from a path-like variable, if it is present.
ves will automatically expand `` to an absolute path using certain
rules, for convenience, if it does not begin with a `/` or a `./`. For example,
values added to the PATH will have,
```
$XDG_DATA_HOME/ves/bin/
```
prepended to them, and values added to LDPATH and LD_LIBRARY_PATH will have,
```
$XDG_DATA_HOME/ves/lib/
```
prepended. It is advisable to install binaries and libraries that you would
like to participate in ves environments into independent directories within
these two locations.
You can also list the contents of a path-like variable using,
```bash
$ ves list [--index]
```
which will list the contents of the variable, each on its own line,
in order of precedence. The `--index` flag will cause the command to
list a numeric (starting at 0) index before each entry. Note that `ves list`
reads from the live shell, so it reflects the current state of the variable,
whether or not an environment is active.
### List, copy, rename, and delete environments
To see all created environments,
```bash
$ ves envs
```
Environments can be duplicated and renamed with,
```bash
$ ves copy
$ ves rename
```
and deleted with,
```bash
$ ves delete
```
The currently active environment cannot be deleted or renamed; deactivate
it first.
## Potential Use-cases
sh-ves can be used to manage different projects requiring specified
versions of compilers or libraries in a fairly transparent manner. For
example, consider a project that is targeted to GCC version 4 and
requires libexample version 6.12.
Using distribution/application specific means, the proper versions of
these packages are installed to `~/.local/share/ves/bin/gcc-4/` and
`~/.local/share/ves/lib/libexample-6.12/` respectively. A ves environment
can be then set up for this project,
```
$ ves create example_project
$ ves activate example_project
$ ves var-add PATH gcc-4
$ ves var-add LDPATH libexample-6.12
```
## Shell prompt integration
sh-ves has a built in helper that will automatically generate a string to
be included in your POSIX compliant shell's PS1 string (or where-ever else
you want it to go).
```bash
$ ves prompt [symbol]
([symbol] )
```
This script doesn't do any color manipulation, so you can add color codes prior
to it within your prompt to configure it however you like. The prompt
string will only appear when an sh-ves environment is currently active.
In fish, use the quoted command substitution form within your fish_prompt
function, so that the empty output when no environment is active does not
swallow adjacent arguments,
```fish
function fish_prompt
echo -n "$(ves prompt) "(prompt_pwd)' $ '
end
```
## Testing
The test suite requires no external framework and can be run with,
```bash
$ make test
```
## License
sh-ves is licensed under the GNU Affero General Public License,
version 3. See the LICENSE file for details.
|