# envf

envf runs a program with modified environment variables (and working directory).
It is similar to Unix `env` but also supports reading from `dotenv`-style files.

The dotenv file parser currently used is [`dotenvy`](https://crates.io/crates/dotenvy); please refer to its documentation for the file syntax.

**envf project links:** [homepage](https://gitlab.com/sjohannes/envf), [crates.io](https://crates.io/crates/envf).

## Usage

envf takes any number of `NAME=VALUE` environment variable definitions, followed by the program you wish to run and its arguments.

```sh
$ envf NAME=VALUE sh -c 'echo $NAME'
VALUE
```

To read from a `dotenv`/`.env`-style file, use the `-f` option followed by the file path.
Unlike some similar programs, envf will not automatically read environment variables from `.env` files, because explicit is better than implicit.

```sh
$ echo NAME=VALUE > my-env

$ envf -f my-env sh -c 'echo $NAME'
VALUE
```

If run with no program specified, envf shows the environment variables that would be used if you were to specify a program.

```sh
$ envf NAME=VALUE
...
NAME=VALUE
```

For full usage documentation, see the envf manpage or [the output of `envf --help`](generated/help.txt).

# Compatibility

envf supports the `-i` option from [POSIX `env`](https://pubs.opengroup.org/onlinepubs/9799919799/utilities/env.html), as well as the `-0`, `-C`, and `-u` extensions that are present on [GNU](https://www.gnu.org/software/coreutils/manual/html_node/env-invocation.html) and [FreeBSD](<https://man.freebsd.org/env(1)>).

Although envf mimics many of the behaviors and options of POSIX `env` (and some `env` implementations), it is not a compatible implementation and is not intended to be one.

The most visible difference is that envf quotes problematic variable names and values when printing them.

```bash
$ envf -i NAME1=VALUE1 $'NAME2=\nVALUE2' 'NAME3="VALUE3"'
NAME1=VALUE1
NAME2="\nVALUE2"
NAME3="\"VALUE3\""
```

In addition, envf permits specifying command-line options after variable definitions.
This allows values specified in the command line to be overridden by those specified in a file.

```sh
$ echo NAME=VALUE2 > my-env

$ envf NAME=VALUE1 -f my-env sh -c 'echo $NAME'
VALUE2
```

# Building and packaging

#### Building envf

Requires: Rust toolchain.
See the `rust-version` field in `Cargo.toml` for the minimum version.

Run `cargo build --release`.

#### Generating the full license file

Requires: [cargo-about](https://github.com/EmbarkStudios/cargo-about).

Run `cargo about generate -o target/LICENSE.html data/license-template.hbs`.

#### Regenerating the `--help` message

This is only needed if you modify the manpage.

Requires: Python, groff.

Run `tools/prerelease.py` and then rebuild envf.

#### Testing

Requires: Python, pytest.

Run `cargo test && pytest test.py`.

#### Packaging

These are the files that you may want to include in the package:

- `target/release/envf[.exe]`.
- `target/LICENSE.html`.
- `envf.1`.

# Contributing

By contributing, you agree to license your contributions under the same license as this project (see the `license` field in `Cargo.toml`).
