fix(gitcli): keep a published repo when the directory sync fails
Also use the zerowrap.FromCtx logger value.
- commit
- 30815db4eeb02e034eb98b1e44669e1bccbc75f6
- author
- brice · · 2026-10-10 06:41 UTC
- parent
- b9b6781
- signature
- GPG Verified
CD88F9E564E0102646FB6077A1A07C7C7C3E349D· arch-gpg Verified for the committer email
1 file · +14 -6
M internal/adapters/gitcli/repos.go +14 -6
| @@ -49,11 +49,13 @@ func (g *Git) Stage(ctx context.Context) (ports.StagedID, error) { | |||
| 49 | 49 | } | |
| 50 | 50 | if err != nil { | |
| 51 | 51 | if rerr := os.RemoveAll(dir); rerr != nil { | |
| 52 | - | zerowrap.Ctx(ctx).Error().Err(rerr).Str("dir", dir).Msg("remove failed staging directory") | |
| 52 | + | log := zerowrap.FromCtx(ctx) | |
| 53 | + | log.Error().Err(rerr).Str("dir", dir).Msg("remove failed staging directory") | |
| 53 | 54 | } | |
| 54 | 55 | return "", fmt.Errorf("stage repository: %w", err) | |
| 55 | 56 | } | |
| 56 | - | zerowrap.Ctx(ctx).Debug().Str("staged", string(id)).Msg("repository staged") | |
| 57 | + | log := zerowrap.FromCtx(ctx) | |
| 58 | + | log.Debug().Str("staged", string(id)).Msg("repository staged") | |
| 57 | 59 | return id, nil | |
| 58 | 60 | } | |
| 59 | 61 | ||
| @@ -71,10 +73,14 @@ func (g *Git) Publish(ctx context.Context, id ports.StagedID, name domain.RepoNa | |||
| 71 | 73 | } | |
| 72 | 74 | return fmt.Errorf("publish repository %q: %w", name, err) | |
| 73 | 75 | } | |
| 76 | + | log := zerowrap.FromCtx(ctx) | |
| 77 | + | // The rename succeeded: the repository exists under its final name. A | |
| 78 | + | // failed sync only weakens crash durability; returning an error here | |
| 79 | + | // would make the caller roll back the metadata of a published directory. | |
| 74 | 80 | if err := syncDir(g.reposDir()); err != nil { | |
| 75 | - | return fmt.Errorf("publish repository %q: %w", name, err) | |
| 81 | + | log.Warn().Err(err).Str("repo", name.String()).Msg("sync repositories directory after publish") | |
| 76 | 82 | } | |
| 77 | - | zerowrap.Ctx(ctx).Debug().Str("repo", name.String()).Msg("repository published") | |
| 83 | + | log.Debug().Str("repo", name.String()).Msg("repository published") | |
| 78 | 84 | return nil | |
| 79 | 85 | } | |
| 80 | 86 | ||
| @@ -105,7 +111,8 @@ func (g *Git) PurgeStaging(ctx context.Context) error { | |||
| 105 | 111 | if err := os.RemoveAll(filepath.Join(g.stagingDir(), e.Name())); err != nil { | |
| 106 | 112 | return fmt.Errorf("remove staging leftover %s: %w", e.Name(), err) | |
| 107 | 113 | } | |
| 108 | - | zerowrap.Ctx(ctx).Info().Str("entry", e.Name()).Msg("removed staging leftover") | |
| 114 | + | log := zerowrap.FromCtx(ctx) | |
| 115 | + | log.Info().Str("entry", e.Name()).Msg("removed staging leftover") | |
| 109 | 116 | } | |
| 110 | 117 | return nil | |
| 111 | 118 | } | |
| @@ -160,7 +167,8 @@ func (g *Git) Trash(ctx context.Context, name domain.RepoName) error { | |||
| 160 | 167 | if err := syncDir(g.reposDir()); err != nil { | |
| 161 | 168 | return fmt.Errorf("trash repository %q: %w", name, err) | |
| 162 | 169 | } | |
| 163 | - | zerowrap.Ctx(ctx).Info().Str("repo", name.String()).Str("trash", filepath.Base(dst)).Msg("repository moved to trash") | |
| 170 | + | log := zerowrap.FromCtx(ctx) | |
| 171 | + | log.Info().Str("repo", name.String()).Str("trash", filepath.Base(dst)).Msg("repository moved to trash") | |
| 164 | 172 | return nil | |
| 165 | 173 | } | |
| 166 | 174 | return fmt.Errorf("trash repository %q: no free name in trash", name) | |
| @@ -49,11 +49,13 @@ func (g *Git) Stage(ctx context.Context) (ports.StagedID, error) { | |||||
| 49 | } | 49 | } | ||
| 50 | if err != nil { | 50 | if err != nil { | ||
| 51 | if rerr := os.RemoveAll(dir); rerr != nil { | 51 | if rerr := os.RemoveAll(dir); rerr != nil { | ||
| 52 | - | zerowrap.Ctx(ctx).Error().Err(rerr).Str("dir", dir).Msg("remove failed staging directory") | 52 | + | log := zerowrap.FromCtx(ctx) |
| 53 | + | log.Error().Err(rerr).Str("dir", dir).Msg("remove failed staging directory") | |||
| 53 | } | 54 | } | ||
| 54 | return "", fmt.Errorf("stage repository: %w", err) | 55 | return "", fmt.Errorf("stage repository: %w", err) | ||
| 55 | } | 56 | } | ||
| 56 | - | zerowrap.Ctx(ctx).Debug().Str("staged", string(id)).Msg("repository staged") | 57 | + | log := zerowrap.FromCtx(ctx) |
| 58 | + | log.Debug().Str("staged", string(id)).Msg("repository staged") | |||
| 57 | return id, nil | 59 | return id, nil | ||
| 58 | } | 60 | } | ||
| 59 | 61 | ||||
| @@ -71,10 +73,14 @@ func (g *Git) Publish(ctx context.Context, id ports.StagedID, name domain.RepoNa | |||||
| 71 | } | 73 | } | ||
| 72 | return fmt.Errorf("publish repository %q: %w", name, err) | 74 | return fmt.Errorf("publish repository %q: %w", name, err) | ||
| 73 | } | 75 | } | ||
| 76 | + | log := zerowrap.FromCtx(ctx) | |||
| 77 | + | // The rename succeeded: the repository exists under its final name. A | |||
| 78 | + | // failed sync only weakens crash durability; returning an error here | |||
| 79 | + | // would make the caller roll back the metadata of a published directory. | |||
| 74 | if err := syncDir(g.reposDir()); err != nil { | 80 | if err := syncDir(g.reposDir()); err != nil { | ||
| 75 | - | return fmt.Errorf("publish repository %q: %w", name, err) | 81 | + | log.Warn().Err(err).Str("repo", name.String()).Msg("sync repositories directory after publish") |
| 76 | } | 82 | } | ||
| 77 | - | zerowrap.Ctx(ctx).Debug().Str("repo", name.String()).Msg("repository published") | 83 | + | log.Debug().Str("repo", name.String()).Msg("repository published") |
| 78 | return nil | 84 | return nil | ||
| 79 | } | 85 | } | ||
| 80 | 86 | ||||
| @@ -105,7 +111,8 @@ func (g *Git) PurgeStaging(ctx context.Context) error { | |||||
| 105 | if err := os.RemoveAll(filepath.Join(g.stagingDir(), e.Name())); err != nil { | 111 | if err := os.RemoveAll(filepath.Join(g.stagingDir(), e.Name())); err != nil { | ||
| 106 | return fmt.Errorf("remove staging leftover %s: %w", e.Name(), err) | 112 | return fmt.Errorf("remove staging leftover %s: %w", e.Name(), err) | ||
| 107 | } | 113 | } | ||
| 108 | - | zerowrap.Ctx(ctx).Info().Str("entry", e.Name()).Msg("removed staging leftover") | 114 | + | log := zerowrap.FromCtx(ctx) |
| 115 | + | log.Info().Str("entry", e.Name()).Msg("removed staging leftover") | |||
| 109 | } | 116 | } | ||
| 110 | return nil | 117 | return nil | ||
| 111 | } | 118 | } | ||
| @@ -160,7 +167,8 @@ func (g *Git) Trash(ctx context.Context, name domain.RepoName) error { | |||||
| 160 | if err := syncDir(g.reposDir()); err != nil { | 167 | if err := syncDir(g.reposDir()); err != nil { | ||
| 161 | return fmt.Errorf("trash repository %q: %w", name, err) | 168 | return fmt.Errorf("trash repository %q: %w", name, err) | ||
| 162 | } | 169 | } | ||
| 163 | - | zerowrap.Ctx(ctx).Info().Str("repo", name.String()).Str("trash", filepath.Base(dst)).Msg("repository moved to trash") | 170 | + | log := zerowrap.FromCtx(ctx) |
| 171 | + | log.Info().Str("repo", name.String()).Str("trash", filepath.Base(dst)).Msg("repository moved to trash") | |||
| 164 | return nil | 172 | return nil | ||
| 165 | } | 173 | } | ||
| 166 | return fmt.Errorf("trash repository %q: no free name in trash", name) | 174 | return fmt.Errorf("trash repository %q: no free name in trash", name) | ||