detached 067ccd6

fix(gitpush): log a failed removal of the temporary key directory and simplify the refspec check

commit
067ccd6a6bf0f9be62c0536cd1d13c79957cb708
author
brice · · 2026-10-20 12:13 UTC
parent
0c0449b
signature
GPG VerifiedCD88F9E564E0102646FB6077A1A07C7C7C3E349D · arch-gpg Verified for the committer email
checks
8/8
1 file · +10 -2
M internal/adapters/gitpush/gitpush.go +10 -2
@@ -18,6 +18,7 @@ import (
1818
1919 "bnema.dev/ermite/internal/domain"
2020 "bnema.dev/ermite/internal/ports"
21+ "github.com/bnema/zerowrap"
2122 "golang.org/x/crypto/ssh"
2223 )
2324
@@ -52,7 +53,7 @@ func quote(s string) string { return "'" + strings.ReplaceAll(s, "'", "'\"'\"'")
5253 // Empty sources, wildcards, force prefixes and revision expressions never reach git.
5354 func validRefspec(s string) bool {
5455 a, b, ok := strings.Cut(s, ":")
55- if !ok || a != b || !(strings.HasPrefix(a, "refs/heads/") || strings.HasPrefix(a, "refs/tags/")) {
56+ if !ok || a != b || !strings.HasPrefix(a, "refs/heads/") && !strings.HasPrefix(a, "refs/tags/") {
5657 return false
5758 }
5859 if strings.ContainsAny(a, "+*?[:\\^~ ") || strings.Contains(a, "..") || strings.Contains(a, "@{") || strings.Contains(a, "//") || strings.HasSuffix(a, "/") || strings.HasSuffix(a, ".") {
@@ -104,7 +105,14 @@ func (p *Pusher) Push(parent context.Context, req ports.MirrorPush) (result port
104105 if e != nil {
105106 return result, internal("create temporary mirror directory")
106107 }
107- defer os.RemoveAll(dir)
108+ defer func() {
109+ // The directory holds the private key: a leftover is reported, and resetRunDir wipes it at
110+ // the next start.
111+ if e := os.RemoveAll(dir); e != nil {
112+ log := zerowrap.FromCtx(parent)
113+ log.Warn().Err(e).Msg("remove the temporary mirror key directory")
114+ }
115+ }()
108116 block, e := ssh.MarshalPrivateKey(req.PrivateKey, "")
109117 if e != nil {
110118 return result, internal("encode mirror private key")
@@ -18,6 +18,7 @@ import (
18 18
19 "bnema.dev/ermite/internal/domain"19 "bnema.dev/ermite/internal/domain"
20 "bnema.dev/ermite/internal/ports"20 "bnema.dev/ermite/internal/ports"
21+ "github.com/bnema/zerowrap"
21 "golang.org/x/crypto/ssh"22 "golang.org/x/crypto/ssh"
22 )23 )
23 24
@@ -52,7 +53,7 @@ func quote(s string) string { return "'" + strings.ReplaceAll(s, "'", "'\"'\"'")
52 // Empty sources, wildcards, force prefixes and revision expressions never reach git.53 // Empty sources, wildcards, force prefixes and revision expressions never reach git.
53 func validRefspec(s string) bool {54 func validRefspec(s string) bool {
54 a, b, ok := strings.Cut(s, ":")55 a, b, ok := strings.Cut(s, ":")
55- if !ok || a != b || !(strings.HasPrefix(a, "refs/heads/") || strings.HasPrefix(a, "refs/tags/")) {56+ if !ok || a != b || !strings.HasPrefix(a, "refs/heads/") && !strings.HasPrefix(a, "refs/tags/") {
56 return false57 return false
57 }58 }
58 if strings.ContainsAny(a, "+*?[:\\^~ ") || strings.Contains(a, "..") || strings.Contains(a, "@{") || strings.Contains(a, "//") || strings.HasSuffix(a, "/") || strings.HasSuffix(a, ".") {59 if strings.ContainsAny(a, "+*?[:\\^~ ") || strings.Contains(a, "..") || strings.Contains(a, "@{") || strings.Contains(a, "//") || strings.HasSuffix(a, "/") || strings.HasSuffix(a, ".") {
@@ -104,7 +105,14 @@ func (p *Pusher) Push(parent context.Context, req ports.MirrorPush) (result port
104 if e != nil {105 if e != nil {
105 return result, internal("create temporary mirror directory")106 return result, internal("create temporary mirror directory")
106 }107 }
107- defer os.RemoveAll(dir)108+ defer func() {
109+ // The directory holds the private key: a leftover is reported, and resetRunDir wipes it at
110+ // the next start.
111+ if e := os.RemoveAll(dir); e != nil {
112+ log := zerowrap.FromCtx(parent)
113+ log.Warn().Err(e).Msg("remove the temporary mirror key directory")
114+ }
115+ }()
108 block, e := ssh.MarshalPrivateKey(req.PrivateKey, "")116 block, e := ssh.MarshalPrivateKey(req.PrivateKey, "")
109 if e != nil {117 if e != nil {
110 return result, internal("encode mirror private key")118 return result, internal("encode mirror private key")

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 2

Tags 45

↑↓ moveenter openesc close