feat: e opens a repo's SOPS or .env file, in nvim, sops edit or your editor
CI / Checks (pull_request) Successful in 26s
PR title / Conventional title (pull_request) Successful in 1s

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
kebandClaude Opus 5.5 committed 2026-10-11 00:09:45 +02:00
1 parent 6fab41703e
commit c29319b821
11 files changed
+395 -12

No files matched your search

+37 -5
View File
@@ -412,6 +412,37 @@ func (p *Provider) Value(ctx context.Context, o provider.Object) (provider.Secre
return provider.NewSecretValue(stdout.Bytes()), nil
}
// File is the file c is, and the line o's key is on.
func (p *Provider) File(c provider.Container, o *provider.Object) (provider.File, error) {
path := c.ID
if path == "" { // made from a link
path = filepath.Join(c.Source.ID, filepath.FromSlash(c.Name))
}
f := provider.File{Path: path}
if _, isSops := readMeta(path); isSops {
f.Sops = p.s.Sops
}
if o == nil {
return f, nil
}
b, err := os.ReadFile(path)
if err != nil {
return f, err
}
keys, err := parseKeys(path, b)
if err != nil {
return f, nil // still worth opening, at the top
}
_, extract, _ := strings.Cut(o.ID, "\x00")
for _, k := range keys {
if k.extract == extract || (extract == "" && k.name == o.Name) {
f.Line = k.line
break
}
}
return f, nil
}
// sopsError is sops' own message, whole: which keys it tried and why
// each failed can all matter.
func sopsError(stderr string, err error) string {
@@ -871,6 +902,7 @@ type key struct {
name string // db.password, list[0]
extract string // sops --extract: ["db"]["password"]
encrypted bool
line int // 1-based
}
// parseKeys lists a sops file's keys without decrypting anything.
@@ -889,18 +921,18 @@ func parseKeys(file string, b []byte) ([]key, error) {
return out, nil
case "dotenv":
var out []key
for _, line := range strings.Split(string(b), "\n") {
for i, line := range strings.Split(string(b), "\n") {
k, v, ok := envLine(line)
if !ok || strings.HasPrefix(k, "sops_") {
continue
}
out = append(out, key{name: k, extract: quote(k), encrypted: strings.HasPrefix(v, "ENC[")})
out = append(out, key{name: k, extract: quote(k), encrypted: strings.HasPrefix(v, "ENC["), line: i + 1})
}
return out, nil
case "ini":
var out []key
section := ""
for _, line := range strings.Split(string(b), "\n") {
for i, line := range strings.Split(string(b), "\n") {
line = strings.TrimSpace(line)
switch {
case line == "" || strings.HasPrefix(line, "#") || strings.HasPrefix(line, ";"):
@@ -912,7 +944,7 @@ func parseKeys(file string, b []byte) ([]key, error) {
continue
}
k, v = strings.TrimSpace(k), strings.TrimSpace(v)
out = append(out, key{name: section + "." + k, extract: quote(section) + quote(k), encrypted: strings.HasPrefix(v, "ENC[")})
out = append(out, key{name: section + "." + k, extract: quote(section) + quote(k), encrypted: strings.HasPrefix(v, "ENC["), line: i + 1})
}
}
return out, nil
@@ -944,7 +976,7 @@ func walk(n *yaml.Node, name, extract string, top bool, out *[]key) {
walk(n.Alias, name, extract, false, out)
}
default:
*out = append(*out, key{name: name, extract: extract, encrypted: strings.HasPrefix(n.Value, "ENC[")})
*out = append(*out, key{name: name, extract: extract, encrypted: strings.HasPrefix(n.Value, "ENC["), line: n.Line})
}
}