summaryrefslogtreecommitdiff
path: root/internal/processor/processor.go
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2026-04-27 08:37:20 +0300
committerPaul Buetow <paul@buetow.org>2026-04-27 08:37:20 +0300
commit8defd48636eeebb3916809fc3f21c2e3d7c9ef5b (patch)
tree3fba5ec27f49a788d5c753fcd4a3417a58c73ef5 /internal/processor/processor.go
parent257057748a2cf2070fbeb722a94772857b5d014f (diff)
processor: reject two markdown files claiming the same inbox image
The pre-scan claimedByMarkdown used to mark an image as claimed by any markdown that referenced it, but it did not prevent two different markdown files from referencing the same image. When that happened, the first file processed would copy the image into its post directory and then delete it from the inbox. The second file then failed because the source image was already gone. Fix: make image claiming exclusive. claimedByMarkdown now tracks the owning markdown filename for each claimed image and returns an error immediately during the pre-scan if a conflict is detected. This way no sources are removed and no partial posts are created. Also add tests: - twoMarkdownsClaimingSameImageFails (negative) - duplicateImageClaimsInSameMarkdownAllowed (positive)
Diffstat (limited to 'internal/processor/processor.go')
-rw-r--r--internal/processor/processor.go8
1 files changed, 8 insertions, 0 deletions
diff --git a/internal/processor/processor.go b/internal/processor/processor.go
index d781a8b..9cbc5a7 100644
--- a/internal/processor/processor.go
+++ b/internal/processor/processor.go
@@ -77,8 +77,12 @@ func Run(cfg *config.Config) (int, error) {
// claimedByMarkdown scans all .md entries in inputDir and returns a set of
// image filenames that are referenced within those markdown files.
// Those images should be embedded in the markdown post, not processed alone.
+// If two different markdown files claim the same image, an error is returned.
func claimedByMarkdown(entries []os.DirEntry, inputDir string) (map[string]bool, error) {
claimed := make(map[string]bool)
+ // owners tracks which markdown file first claimed each image so we can
+ // detect conflicts before processing begins.
+ owners := make(map[string]string)
for _, entry := range entries {
if entry.IsDir() || strings.ToLower(filepath.Ext(entry.Name())) != ".md" {
@@ -92,6 +96,10 @@ func claimedByMarkdown(entries []os.DirEntry, inputDir string) (map[string]bool,
}
for _, imgName := range findLocalImages(string(data), inputDir) {
+ if owner, exists := owners[imgName]; exists && owner != entry.Name() {
+ return nil, fmt.Errorf("image %q claimed by both %q and %q", imgName, owner, entry.Name())
+ }
+ owners[imgName] = entry.Name()
claimed[imgName] = true
}
}