Skip to content

Commit

Permalink
feat: Add passFields template function
Browse files Browse the repository at this point in the history
Co-authored-by: Alexis Lahouze <alexis@lahouze.org>
  • Loading branch information
twpayne and xals committed Dec 23, 2021
1 parent 35af862 commit b9aeae9
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 7 deletions.
32 changes: 32 additions & 0 deletions docs/REFERENCE.md
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ Manage your dotfiles across multiple machines, securely.
* [`onepasswordItemFields` *uuid* [*vault-uuid* [*account-name*]]](#onepassworditemfields-uuid-vault-uuid-account-name)
* [`output` *name* [*arg*...]](#output-name-arg)
* [`pass` *pass-name*](#pass-pass-name)
* [`passFields` *pass-name*](#passfields-pass-name)
* [`passRaw` *pass-name*](#passraw-pass-name)
* [`promptBool` *prompt* [*default*]](#promptbool-prompt-default)
* [`promptInt` *prompt* [*default*]](#promptint-prompt-default)
Expand Down Expand Up @@ -2535,6 +2536,37 @@ the same *pass-name* will only invoke `pass` once.

---

### `passFields` *pass-name*

`passFields` returns structured data stored in
[pass](https://www.passwordstore.org) using the pass CLI (`pass`). *pass-name*
is passed to `pass show <pass-name>` and the output is parsed as colon-separated
key-value pairs, one per line. The return value is a map of keys to values. For
example, given the output from `pass`:

```
GitHub
login: username
password: secret
```

the return value will be a map:

```json
{
"login": "username",
"password": "secret"
}
```

#### `passFields` examples

```
{{ (passFields "GitHub").password }}
```

---

### `passRaw` *pass-name*

`passRaw` returns passwords stored in [pass](https://www.passwordstore.org/)
Expand Down
1 change: 1 addition & 0 deletions internal/cmd/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -440,6 +440,7 @@ func newConfig(options ...configOption) (*Config, error) {
"onepasswordItemFields": c.onepasswordItemFieldsTemplateFunc,
"output": c.outputTemplateFunc,
"pass": c.passTemplateFunc,
"passFields": c.passFieldsTemplateFunc,
"passRaw": c.passRawTemplateFunc,
"secret": c.secretTemplateFunc,
"secretJSON": c.secretJSONTemplateFunc,
Expand Down
14 changes: 13 additions & 1 deletion internal/cmd/passtemplatefuncs.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package cmd

import (
"bytes"
"fmt"
"os/exec"

Expand Down Expand Up @@ -38,7 +39,18 @@ func (c *Config) passOutput(id string) []byte {

func (c *Config) passTemplateFunc(id string) string {
output, _, _ := chezmoi.CutBytes(c.passOutput(id), []byte{'\n'})
return string(output)
return string(bytes.TrimSpace(output))
}

func (c *Config) passFieldsTemplateFunc(id string) map[string]string {
output := c.passOutput(id)
result := make(map[string]string)
for _, line := range bytes.Split(output, []byte{'\n'}) {
if key, value, ok := chezmoi.CutBytes(line, []byte{':'}); ok {
result[string(bytes.TrimSpace(key))] = string(bytes.TrimSpace(value))
}
}
return result
}

func (c *Config) passRawTemplateFunc(id string) string {
Expand Down
19 changes: 13 additions & 6 deletions internal/cmd/testdata/scripts/pass.txt
Original file line number Diff line number Diff line change
@@ -1,22 +1,26 @@
[!windows] chmod 755 bin/pass
[windows] unix2dos bin/pass.cmd
[windows] unix2dos golden/pass-raw

# test pass template function
chezmoi execute-template '{{ pass "misc/example.com" }}'
stdout examplepassword
! stdout 'second line'
stdout ^examplepassword$

# test passFields template function
chezmoi execute-template '{{ (passFields "misc/example.com").login }}'
stdout ^examplelogin$

# test pass template function
chezmoi execute-template '{{ passRaw "misc/example.com" }}'
stdout 'second line'
cmp stdout golden/pass-raw

-- bin/pass --
#!/bin/sh

case "$*" in
"show misc/example.com")
echo "examplepassword"
echo "second line"
echo "login: examplelogin"
;;
*)
echo "pass: invalid command: $*"
Expand All @@ -25,10 +29,13 @@ esac
-- bin/pass.cmd --
@echo off
IF "%*" == "show misc/example.com" (
echo "examplepassword"
echo "second line"
echo.examplepassword
echo.login: examplelogin
exit /b 0
) ELSE (
echo pass: invalid command: %*
exit /b 1
)
-- golden/pass-raw --
examplepassword
login: examplelogin

0 comments on commit b9aeae9

Please sign in to comment.