feat: globbing

Signed-off-by: jolheiser <john.olheiser@gmail.com>
main
jolheiser 2023-08-23 22:50:08 -05:00
parent 26b581b5db
commit ad992cccc8
Signed by: jolheiser
GPG Key ID: B853ADA5DA7BBF7A
9 changed files with 111 additions and 42 deletions

View File

@ -1,4 +1,3 @@
"secrets/age.txt":
"secrets/*":
- age13nf8wry2lzyy0wtzq9qz0hkm2xumez074nuu0qwe8l0vsell2s2s6rgqch
"secrets/ssh.txt":
- ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIK6qVlew2gb+lb1f/9+XgHM4oy8wRlahFpm17Ul3ln9I git-age

2
.gitattributes vendored
View File

@ -1,2 +1,2 @@
secrets/** filter=git-age diff=git-age
secrets/* filter=git-age diff=git-age

View File

@ -50,8 +50,9 @@ func actionClean(ctx *cli.Context) error {
return err
}
_, rekey := os.LookupEnv(REKEY)
sum := hasher.Sum(nil)
if fmt.Sprintf("%x", existing) == fmt.Sprintf("%x", sum) {
if !rekey && fmt.Sprintf("%x", existing) == fmt.Sprintf("%x", sum) {
saved, err := os.ReadFile(filepath.Join(dir, "age"))
if err != nil {
return err
@ -76,7 +77,7 @@ func actionClean(ctx *cli.Context) error {
if err != nil {
return err
}
if string(headDecrypted) == stdin.String() {
if !rekey && string(headDecrypted) == stdin.String() {
ageFile.Write(headEncrypted)
os.Stdout.Write(headEncrypted)
return nil

View File

@ -12,6 +12,7 @@ import (
"filippo.io/age"
"filippo.io/age/agessh"
"github.com/bmatcuk/doublestar/v4"
"github.com/urfave/cli/v2"
)
@ -20,6 +21,8 @@ var (
debug = false
)
const REKEY = "GIT_AGE_REKEY"
func New() *cli.App {
app := cli.NewApp()
app.Name = "git-age"
@ -29,6 +32,7 @@ func New() *cli.App {
Clean,
Identity,
Init,
Rekey,
Smudge,
TextConv,
}
@ -78,11 +82,16 @@ func ageRecipients(file string) ([]age.Recipient, error) {
if err != nil {
return nil, err
}
val, ok := cfg[file]
if !ok {
return nil, fmt.Errorf("no config found for %q", file)
for glob, val := range cfg {
match, err := doublestar.Match(glob, file)
if err != nil {
return nil, fmt.Errorf("bad glob %q: %w", glob, err)
}
if match {
return val.Recipients()
}
}
return val.Recipients()
return nil, fmt.Errorf("no config found for %q", file)
}
var ErrNoIdentities = errors.New("no identities found")

View File

@ -12,7 +12,7 @@ import (
var Identity = &cli.Command{
Name: "identity",
Aliases: []string{"i", "ident"},
Aliases: []string{"ident"},
Description: "Manage identity files",
Flags: []cli.Flag{
&cli.BoolFlag{

View File

@ -9,6 +9,7 @@ import (
"os/exec"
"path/filepath"
"github.com/bmatcuk/doublestar/v4"
"github.com/urfave/cli/v2"
)
@ -53,45 +54,56 @@ func actionInit(ctx *cli.Context) error {
return err
}
for file := range cfg {
apn := filepath.Join(dir, file)
args := []string{"smudge", "-f", file}
if debug {
args = append([]string{"-d"}, args...)
for glob := range cfg {
files, err := doublestar.FilepathGlob(glob, doublestar.WithFilesOnly())
if err != nil {
return fmt.Errorf("bad glob %q: %w", glob, err)
}
if err := func() error {
content, err := os.ReadFile(apn)
if err != nil {
return err
}
var buf bytes.Buffer
c := exec.Command(exe, args...)
c.Stdin = bytes.NewReader(content)
c.Stdout = &buf
for _, file := range files {
apn := filepath.Join(dir, file)
args := []string{"smudge", "-f", file}
if debug {
c.Stderr = os.Stderr
args = append([]string{"-d"}, args...)
}
if err := c.Run(); err != nil {
if debug {
fmt.Fprintf(os.Stderr, "could not smudge file: %v\n", err)
if err := func() error {
content, err := os.ReadFile(apn)
if err != nil {
return err
}
var buf bytes.Buffer
c := exec.Command(exe, args...)
c.Stdin = bytes.NewReader(content)
c.Stdout = &buf
if debug {
c.Stderr = os.Stderr
}
if err := c.Run(); err != nil {
if debug {
fmt.Fprintf(os.Stderr, "could not smudge file: %v\n", err)
}
return nil
}
if buf.String() == "" {
// Blank content, exit
return nil
}
fi, err := os.Create(apn)
if err != nil {
return err
}
fi.Write(buf.Bytes())
if err := fi.Close(); err != nil {
return err
}
cmd("git", "add", "--renormalize", apn)
return nil
}
fi, err := os.Create(apn)
if err != nil {
}(); err != nil {
return err
}
fi.Write(buf.Bytes())
if err := fi.Close(); err != nil {
return err
}
cmd("git", "add", "--renormalize", apn)
return nil
}(); err != nil {
return err
}
}

45
cmd/rekey.go 100644
View File

@ -0,0 +1,45 @@
package cmd
import (
"errors"
"fmt"
"io/fs"
"os"
"path/filepath"
"github.com/bmatcuk/doublestar/v4"
"github.com/urfave/cli/v2"
)
var Rekey = &cli.Command{
Name: "rekey",
Aliases: []string{"r"},
Description: "Re-key secrets",
Action: actionRekey,
}
func actionRekey(ctx *cli.Context) error {
cfg, err := LoadConfig()
if err != nil {
if errors.Is(err, fs.ErrNotExist) {
return nil
}
return err
}
dir, err := gitBaseDir()
if err != nil {
return err
}
os.Setenv(REKEY, "1")
for glob := range cfg {
files, err := doublestar.FilepathGlob(glob, doublestar.WithFilesOnly())
if err != nil {
return fmt.Errorf("bad glob %q: %w", glob, err)
}
for _, file := range files {
cmd("git", "add", "--renormalize", filepath.Join(dir, file))
}
}
return nil
}

1
go.mod
View File

@ -4,6 +4,7 @@ go 1.20
require (
filippo.io/age v1.1.1
github.com/bmatcuk/doublestar/v4 v4.6.0
github.com/urfave/cli/v2 v2.25.7
gopkg.in/yaml.v3 v3.0.1
lukechampine.com/blake3 v1.2.1

2
go.sum
View File

@ -2,6 +2,8 @@ filippo.io/age v1.1.1 h1:pIpO7l151hCnQ4BdyBujnGP2YlUo0uj6sAVNHGBvXHg=
filippo.io/age v1.1.1/go.mod h1:l03SrzDUrBkdBx8+IILdnn2KZysqQdbEBUQ4p3sqEQE=
filippo.io/edwards25519 v1.0.0 h1:0wAIcmJUqRdI8IJ/3eGi5/HwXZWPujYXXlkrQogz0Ek=
filippo.io/edwards25519 v1.0.0/go.mod h1:N1IkdkCkiLB6tki+MYJoSx2JTY9NUlxZE7eHn5EwJns=
github.com/bmatcuk/doublestar/v4 v4.6.0 h1:HTuxyug8GyFbRkrffIpzNCSK4luc0TY3wzXvzIZhEXc=
github.com/bmatcuk/doublestar/v4 v4.6.0/go.mod h1:xBQ8jztBU6kakFMg+8WGxn0c6z1fTSPVIjEY1Wr7jzc=
github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w=
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/klauspost/cpuid/v2 v2.0.9 h1:lgaqFMSdTdQYdZ04uHyN2d/eKdOMyi2YLSvlQIBFYa4=