Environment variables

i

NOTE

To allow deno to access environment variables the --allow-env=<allow-env> flag is required. If the --allow-env flag is not provided, environment variables will be ignored if not marked as required.

Environment variables added with the .env() method will be validated when the command is executed. Only environment variables that are available for the executed command will be validated. Valid environment variables will be stored in the options object and for invalid or missing environment variables an error is thrown. They are also shown in the auto generated help.

Environment variable names will be camel cased. For example SOME_ENV_VAR=true will be parsed to { someEnvVar: true }.

i

NOTE

If an option with the same name is defined, the option will override the environment variable.

i

NOTE

An option can also read its value from an environment variable with the env option. See environment variables on the options page.

import { Command } from "@cliffy/command";

await new Command()
  .env("SOME_ENV_VAR=<value:number>", "Description ...")
  .action((options) => console.log(options))
  .parse();
$ SOME_ENV_VAR=abc deno run --allow-env=SOME_ENV_VAR https://cliffy.io/examples/v1.3.1/command/environment_variables.ts
Error: Environment variable "SOME_ENV_VAR" must be of type "number", but got "abc".

$ SOME_ENV_VAR=1 deno run --allow-env=SOME_ENV_VAR https://cliffy.io/examples/v1.3.1/command/environment_variables.ts
{ someEnvVar: 1 }

Global environment variables

Global environment variables are also available on all sub commands. You can add global environment variables either with the .env() method and the global option or with the .globalEnv() method.

import { Command } from "@cliffy/command";

await new Command()
  .env("SOME_ENV_VAR=<value:number>", "Description ...", { global: true })
  .globalEnv("SOME_OTHER_ENV_VAR=<value:number>", "Description ...")
  .action((options) => console.log(options))
  .command("hello", "world ...")
  .action((options) => console.log(options))
  .parse();

Required environment variables

Required environment variables can be added with the required option. If a required environment variable is not defined on command line an error is thrown.

import { Command } from "@cliffy/command";

await new Command()
  .env("SOME_ENV_VAR=<value:number>", "Description ...", { required: true })
  .action((options) => console.log(options))
  .parse();
$ deno run https://cliffy.io/examples/v1.3.1/command/environment_variables.ts
error: Missing required environment variable "SOME_ENV_VAR".

$ SOME_ENV_VAR=abc deno run --allow-env=SOME_ENV_VAR https://cliffy.io/examples/v1.3.1/command/environment_variables.ts
Error: Environment variable "SOME_ENV_VAR" must be of type "number", but got "abc".

$ SOME_ENV_VAR=1 deno run --allow-env=SOME_ENV_VAR https://cliffy.io/examples/v1.3.1/command/environment_variables.ts
{ someEnvVar: 1 }

Hidden environment variables

Hidden environment variables can be added with the hidden option and will be not displayed in the auto generated help.

import { Command } from "@cliffy/command";

await new Command()
  .env("SOME_ENV_VAR=<value:number>", "Description ...", { hidden: true })
  .action((options) => console.log(options))
  .parse();

Prefix

It is very common to prefix environment variables with a name like DENO_DIR and DENO_INSTALL_ROOT. With the prefix option you can ensure the prefix is removed before the value is added to the options object. This works also in combination with options.

import { Command } from "@cliffy/command";

await new Command()
  .env(
    "DENO_INSTALL_ROOT=<path:string>",
    "Set install root.",
    { prefix: "DENO_" },
  )
  .option(
    "--install-root <path:string>",
    "Set install root.",
  )
  .action((options) => console.log(options))
  .parse();
$ DENO_INSTALL_ROOT=foo/bar deno run --allow-env=DENO_INSTALL_ROOT https://cliffy.io/examples/v1.3.1/command/environment_variables_prefix.ts
{ installRoot: "foo/bar" }

Negatable environment variables

A variable like NO_CACHE expresses the negation of a value. With the negatable option the NO_ prefix is stripped from the property name and the boolean is inverted, the same way a negatable option works. NO_CACHE=true becomes { cache: false }.

import { Command } from "@cliffy/command";

await new Command()
  .env("NO_CACHE=<value:boolean>", "Disable the cache.", { negatable: true })
  .action((options) => console.log(options))
  .parse();
$ NO_CACHE=true deno run --allow-env=NO_CACHE https://cliffy.io/examples/v1.3.1/command/negatable_environment_variables.ts
{ cache: false }

$ NO_CACHE=false deno run --allow-env=NO_CACHE https://cliffy.io/examples/v1.3.1/command/negatable_environment_variables.ts
{ cache: true }

$ deno run --allow-env=NO_CACHE https://cliffy.io/examples/v1.3.1/command/negatable_environment_variables.ts
{}

Unlike a negatable flag, the variable carries a value, so NO_CACHE=false turns the property on.

The name must start with NO_ and the value must be of type boolean, otherwise an error is thrown.

This also works with the prefix option, where the NO_ has to follow the prefix, for example MYCLI_NO_CACHE with { prefix: "MYCLI_" }.

If a variable and its negated counterpart are both defined and set, the negated one wins.

import { Command } from "@cliffy/command";

await new Command()
  .env("CACHE=<value:boolean>", "Enable the cache.")
  .env("NO_CACHE=<value:boolean>", "Disable the cache.", { negatable: true })
  .action((options) => console.log(options))
  .parse();
$ CACHE=true NO_CACHE=true deno run --allow-env https://cliffy.io/examples/v1.3.1/command/negatable_environment_variables.ts
{ cache: false }
i

NOTE

The option is opt-in for backwards compatibility. Without it, NO_CACHE=true is camel cased like any other name and results in { noCache: true }. In v2 this becomes the default for boolean NO_* environment variables and the option is removed.

i

NOTE

Variables that follow a presence-based convention, NO_COLOR and NODE_DISABLE_COLORS among them, are disabled by any non-empty value, whatever the value is. Declaring them as a boolean parses the value and reaches the opposite conclusion for NO_COLOR=false. Declare them with the presence type instead, or read the color state with getColorEnabled() from @std/fmt/colors, which is what cliffy uses for its own help output.