nu_scripts/stdlib-candidate
Texas Toland 74ba060f55
[stdlib-candidate] set-env (#787)
Rewrite of nushell/nushell#12156 for jdx/mise#1763.

### Why?

Nushell philosophically omits a `set` list mutation. But `$env` is
inherently mutable leading to issues described in nushell/nushell#12148.
`set-env` provides such an operation exclusively for `$env`.

### What changed?

1. Explicit flag instead of implicit list concatenation
2. Expands updates to any `$env` field not only `$env.config`

### How is it used?

```yaml
❯ set-env -h
Gracefully set an environment variable or merge a nested option.

Examples:
  Set $env.NUPM_HOME
  > set-env NUPM_HOME $'($nu.home-path)/.local/share/nupm'

  Add to $env.NU_LIB_DIRS
  > set-env --append NU_LIB_DIRS $'($env.NUPM_HOME)/modules'

  Set a nested config option
  > set-env config.filesize.metric true

  Add a config hook
  > set-env -a config.hooks.pre_prompt 'ellie | print'

Usage:
  > main {flags} <field> <value>

Flags:
  -a, --append - Append to the previous value or wrap in a new list
  -h, --help - Display the help message for this command

Parameters:
  field <cell-path>: The environment variable name or nested option cell path
  value <any>: The value to set or append

Input/output types:
  ╭───┬─────────┬─────────╮
  │ # │  input  │ output  │
  ├───┼─────────┼─────────┤
  │ 0 │ nothing │ nothing │
  ╰───┴─────────┴─────────╯
```

### How does it work?

```nushell
export def --env main [
  field: cell-path
  value: any
  --append (-a)
]: nothing -> nothing {

  # just an alias
  def 'get or' [default field] {
    get --ignore-errors $field | default $default
  }

  let value = if $append {
    # append to the previous value or empty list
    $env | get or [] $field | append $value
  } else {
    $value
  }

  # work around nushell/nushell#12168
  let field = $field | to text | split row .
  let value = match $field {

    [_] => $value
    # if cell path is nested
    [$root, ..$field] => {
      let field = $field | into cell-path

      # reassigning $env would be an error
      # merging reserved names like PWD would be an error
      # so merge from 1 level deep instead
      $env | get or {} $root | upsert $field $value
    }
  }

  # avoid issues noted above
  load-env { ($field | first): $value }
}
```

### Where are the tests?

Pending next PR for nupm integration.
2024-03-12 10:55:07 -05:00
..
record Add record module (#679) 2023-11-29 09:12:23 -06:00
fs.nu add a "bulk rename" command to the stdlib candidates (#643) 2023-12-11 09:00:10 +01:00
README.md Add str append to stdlib-candidate (#626) 2023-09-30 17:13:46 -05:00
set-env.nu [stdlib-candidate] set-env (#787) 2024-03-12 10:55:07 -05:00
str.nu add tests to str.nu (#627) 2023-10-02 19:12:08 +02:00

std-lib candidate

This folder is where we can add scripts that might want to be in std-lib at some point. It can serve both as a holding place for scripts that are waiting on nushell changes, as well as a place to develop and discuss such scripts.