Skip to content

Commit cc89b3c

Browse files
committed
feat: Add edit-encrypted command
1 parent a6820b3 commit cc89b3c

File tree

6 files changed

+125
-0
lines changed

6 files changed

+125
-0
lines changed
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# `edit-encrypted` *filename*...
2+
3+
Edit the encrypted files *filename*s.
4+
5+
Each *filename* is decrypted to a temporary directory, the editor is invoked on
6+
the decrypted files. After the editor returns, each the decrypted file is
7+
re-encrypted.
8+
9+
## Examples
10+
11+
```sh
12+
chezmoi edit-encrypted encrypted_file
13+
```

assets/chezmoi.io/mkdocs.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,7 @@ nav:
164164
- edit: reference/commands/edit.md
165165
- edit-config: reference/commands/edit-config.md
166166
- edit-config-template: reference/commands/edit-config-template.md
167+
- edit-encrypted: reference/commands/edit-encrypted.md
167168
- encrypt: reference/commands/encrypt.md
168169
- execute-template: reference/commands/execute-template.md
169170
- forget: reference/commands/forget.md

internal/cmd/config.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1912,6 +1912,7 @@ func (c *Config) newRootCmd() (*cobra.Command, error) {
19121912
c.newEditCmd(),
19131913
c.newEditConfigCmd(),
19141914
c.newEditConfigTemplateCmd(),
1915+
c.newEditEncryptedCmd(),
19151916
c.newEncryptCmd(),
19161917
c.newExecuteTemplateCmd(),
19171918
c.newForgetCmd(),

internal/cmd/editencryptedcmd.go

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
package cmd
2+
3+
import (
4+
"path/filepath"
5+
6+
"github.com/spf13/cobra"
7+
8+
"chezmoi.io/chezmoi/internal/chezmoi"
9+
)
10+
11+
func (c *Config) newEditEncryptedCmd() *cobra.Command {
12+
editEncryptedCmd := &cobra.Command{
13+
GroupID: groupIDEncryption,
14+
Use: "edit-encrypted filename...",
15+
Short: "Edit an encrypted file",
16+
Long: mustLongHelp("edit-encrypted"),
17+
Example: example("edit-encrypted"),
18+
Args: cobra.MinimumNArgs(1),
19+
RunE: c.runEditEncryptedCmd,
20+
Annotations: newAnnotations(
21+
modifiesSourceDirectory,
22+
persistentStateModeEmpty,
23+
runsCommands,
24+
),
25+
}
26+
return editEncryptedCmd
27+
}
28+
29+
func (c *Config) runEditEncryptedCmd(cmd *cobra.Command, args []string) error {
30+
type argument struct {
31+
ciphertextAbsPath chezmoi.AbsPath
32+
plaintextAbsPath chezmoi.AbsPath
33+
}
34+
35+
arguments := make([]argument, len(args))
36+
37+
// Write plaintexts to a temporary directory.
38+
tempDirAbsPath, err := c.tempDir("chezmoi-edit-encrypted")
39+
if err != nil {
40+
return err
41+
}
42+
for i, arg := range args {
43+
arg = filepath.Clean(arg)
44+
ciphertextAbsPath, err := chezmoi.NewAbsPathFromExtPath(arg, c.homeDirAbsPath)
45+
if err != nil {
46+
return err
47+
}
48+
arguments[i].ciphertextAbsPath = ciphertextAbsPath
49+
ciphertext, err := c.baseSystem.ReadFile(ciphertextAbsPath)
50+
if err != nil {
51+
return err
52+
}
53+
relPath := ciphertextAbsPath.MustTrimDirPrefix(c.homeDirAbsPath)
54+
plaintextAbsPath := tempDirAbsPath.Join(relPath)
55+
if err := c.encryption.DecryptToFile(plaintextAbsPath, ciphertext); err != nil {
56+
return err
57+
}
58+
arguments[i].plaintextAbsPath = plaintextAbsPath
59+
}
60+
61+
// Run the editor on the plaintexts.
62+
editorArgs := make([]string, len(arguments))
63+
for i, argument := range arguments {
64+
editorArgs[i] = argument.plaintextAbsPath.String()
65+
}
66+
if err := c.runEditor(editorArgs); err != nil {
67+
return err
68+
}
69+
70+
// Write the ciphertexts.
71+
//
72+
// FIXME only write the ciphertext if the plaintext has changed
73+
// FIXME preserve original plaintext file mode
74+
for _, argument := range arguments {
75+
ciphertext, err := c.encryption.EncryptFile(argument.plaintextAbsPath)
76+
if err != nil {
77+
return err
78+
}
79+
if err := c.baseSystem.WriteFile(argument.ciphertextAbsPath, ciphertext, 0o666&^c.Umask); err != nil {
80+
return err
81+
}
82+
}
83+
84+
return nil
85+
}

internal/cmd/helps.gen.go

Lines changed: 10 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
mkageconfig
2+
[windows] unix2dos golden/edited-plaintext
3+
[windows] unix2dos golden/plaintext
4+
5+
# test that chezmoi edit-encrypted edits encrypted files
6+
exec chezmoi encrypt -o $HOME/ciphertext golden/plaintext
7+
exec chezmoi edit-encrypted $HOME/ciphertext
8+
exec chezmoi decrypt $HOME/ciphertext
9+
cmp stdout golden/edited-plaintext
10+
11+
-- golden/edited-plaintext --
12+
# contents of plaintext
13+
# edited
14+
-- golden/plaintext --
15+
# contents of plaintext

0 commit comments

Comments
 (0)