Skip to content

Commit 20ac295

Browse files
committed
feat: separate sign command, keyring from env
1 parent 4af1ce3 commit 20ac295

File tree

6 files changed

+92
-16
lines changed

6 files changed

+92
-16
lines changed

internal/pgp/cli.go

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package pgp
2+
3+
import (
4+
"encoding/base64"
5+
"fmt"
6+
"io"
7+
"os"
8+
"strings"
9+
)
10+
11+
type CLI struct {
12+
Keyring string `group:"Keyring" help:"Path to GPG keyring" type:"existingfile" env:"EZAPT_KEYRING"`
13+
KeyringBase64 string `group:"Keyring" help:"GPG keyring as base64" env:"EZAPT_KEYRING_BASE64"`
14+
}
15+
16+
func (c *CLI) Signer() (*Signer, error) {
17+
var keyringReader io.Reader
18+
if c.KeyringBase64 != "" {
19+
keyringReader = base64.NewDecoder(base64.StdEncoding, strings.NewReader(c.KeyringBase64))
20+
} else if c.Keyring != "" {
21+
fd, err := os.Open(c.Keyring)
22+
if err != nil {
23+
return nil, err
24+
}
25+
defer fd.Close()
26+
keyringReader = fd
27+
} else {
28+
return nil, fmt.Errorf("no keyring provided")
29+
}
30+
31+
return NewSigner(keyringReader)
32+
}

internal/publish/pgp.go internal/pgp/pgp.go

+7-7
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package publish
1+
package pgp
22

33
import (
44
"crypto"
@@ -12,13 +12,13 @@ import (
1212
openpgp "github.com/ProtonMail/go-crypto/openpgp/v2"
1313
)
1414

15-
type signer struct {
15+
type Signer struct {
1616
entities []*openpgp.Entity
1717
}
1818

19-
func newSigner(keychain io.Reader) (*signer, error) {
19+
func NewSigner(keychain io.Reader) (*Signer, error) {
2020
pr := packet.NewReader(keychain)
21-
s := &signer{}
21+
s := &Signer{}
2222
for {
2323
ent, err := openpgp.ReadEntity(pr)
2424
if err == io.EOF {
@@ -33,12 +33,12 @@ func newSigner(keychain io.Reader) (*signer, error) {
3333
return s, nil
3434
}
3535

36-
type seekable interface {
36+
type Seekable interface {
3737
io.Reader
3838
io.Seeker
3939
}
4040

41-
func (s *signer) DetachSign(in seekable, out io.Writer) error {
41+
func (s *Signer) DetachSign(in Seekable, out io.Writer) error {
4242
if len(s.entities) == 0 {
4343
return fmt.Errorf("no entities")
4444
}
@@ -51,7 +51,7 @@ func (s *signer) DetachSign(in seekable, out io.Writer) error {
5151
return nil
5252
}
5353

54-
func (s *signer) ClearSign(in seekable, out io.Writer) error {
54+
func (s *Signer) ClearSign(in Seekable, out io.Writer) error {
5555
if len(s.entities) == 0 {
5656
return fmt.Errorf("no entities")
5757
}

internal/publish/publish.go

+3-7
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,15 @@ import (
66
"os"
77
"path/filepath"
88

9+
"kastelo.dev/ezapt/internal/pgp"
910
"pault.ag/go/debian/deb"
1011
)
1112

1213
type CLI struct {
1314
Dists string `required:"" help:"Path to dists directory" type:"existingdir" env:"EZAPT_DISTS"`
1415
KeepVersions int `help:"Number of versions to keep" default:"2" env:"EZAPT_KEEP_VERSIONS"`
15-
Keyring string `required:"" help:"Path to GPG keyring" type:"existingfile" env:"EZAPT_KEYRING"`
1616
Add string `help:"Path to packages to add" type:"existingdir" env:"EZAPT_ADD"`
17+
pgp.CLI
1718
}
1819

1920
func (c *CLI) Run() error {
@@ -38,12 +39,7 @@ func (c *CLI) Run() error {
3839
return fmt.Errorf("publish: globbing: %w", err)
3940
}
4041

41-
fd, err := os.Open(c.Keyring)
42-
if err != nil {
43-
return fmt.Errorf("publish: %w", err)
44-
}
45-
sign, err := newSigner(fd)
46-
fd.Close()
42+
sign, err := c.Signer()
4743
if err != nil {
4844
return fmt.Errorf("publish: %w", err)
4945
}

internal/publish/release.go

+3-1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ import (
1010
"strings"
1111
"text/template"
1212
"time"
13+
14+
"kastelo.dev/ezapt/internal/pgp"
1315
)
1416

1517
type release struct {
@@ -143,7 +145,7 @@ func writeRelease(dist string) error {
143145
return nil
144146
}
145147

146-
func signRelease(dist string, s *signer) error {
148+
func signRelease(dist string, s *pgp.Signer) error {
147149
in, err := os.Open(filepath.Join(dist, "Release"))
148150
if err != nil {
149151
return err

internal/sign/publish.go

+40
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
package sign
2+
3+
import (
4+
"fmt"
5+
"os"
6+
7+
"kastelo.dev/ezapt/internal/pgp"
8+
)
9+
10+
type CLI struct {
11+
Files []string `arg:"" help:"Files to sign" type:"existingfile" env:"EZAPT_FILES"`
12+
pgp.CLI
13+
}
14+
15+
func (c *CLI) Run() error {
16+
sign, err := c.Signer()
17+
if err != nil {
18+
return fmt.Errorf("sign: %w", err)
19+
}
20+
21+
for _, file := range c.Files {
22+
in, err := os.Open(file)
23+
if err != nil {
24+
return fmt.Errorf("open: %w", err)
25+
}
26+
defer in.Close()
27+
out, err := os.Create(file + ".asc")
28+
if err != nil {
29+
return fmt.Errorf("create: %w", err)
30+
}
31+
if err := sign.ClearSign(in, out); err != nil {
32+
return fmt.Errorf("sign: %w", err)
33+
}
34+
if err := out.Close(); err != nil {
35+
return fmt.Errorf("close: %w", err)
36+
}
37+
}
38+
39+
return nil
40+
}

main.go

+7-1
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,16 @@ import (
66

77
"github.com/alecthomas/kong"
88
"kastelo.dev/ezapt/internal/publish"
9+
"kastelo.dev/ezapt/internal/sign"
910
)
1011

12+
type CLI struct {
13+
Publish publish.CLI `cmd:"" help:"Publish a repository." default:""`
14+
Sign sign.CLI `cmd:"" help:"Sign files."`
15+
}
16+
1117
func main() {
12-
var cli publish.CLI
18+
var cli CLI
1319
ctx := kong.Parse(&cli)
1420
if err := ctx.Run(); err != nil {
1521
slog.Error("Failed to run", "error", err)

0 commit comments

Comments
 (0)