Make page rewrite optional

This commit is contained in:
2026-05-07 19:35:10 +02:00
parent 73743ced78
commit 892e4860b4
4 changed files with 80 additions and 40 deletions
+34 -30
View File
@@ -10,10 +10,11 @@ import (
"strings"
)
// handleMove moves the folder at srcFsPath (wiki URL srcURL) to dstURL and
// rewrites every [[...]] wiki link across the tree that targets the old path
// or any descendant. All rewritten files are held in memory for rollback.
func (h *handler) handleMove(w http.ResponseWriter, r *http.Request, srcURL, srcFsPath, dstURL string) {
// handleMove moves the folder at srcFsPath (wiki URL srcURL) to dstURL. When
// updateLinks is true it also rewrites every [[...]] wiki link across the
// tree that targets the old path or any descendant; rewritten files are held
// in memory for rollback.
func (h *handler) handleMove(w http.ResponseWriter, r *http.Request, srcURL, srcFsPath, dstURL string, updateLinks bool) {
oldPath := normalizeMovePath(srcURL)
if oldPath == "/" {
http.Error(w, "cannot move wiki root", http.StatusBadRequest)
@@ -44,35 +45,38 @@ func (h *handler) handleMove(w http.ResponseWriter, r *http.Request, srcURL, src
return
}
// Phase 1: walk the tree and rewrite every index.md that references the
// moved path. Keep the pre-rewrite bytes in memory so we can revert on
// failure. The walker only reads directory listings and files literally
// named index.md; hidden directories are pruned. A cheap substring check
// skips parsing files that cannot contain a relevant link.
// Phase 1: optionally walk the tree and rewrite every index.md that
// references the moved path. Keep the pre-rewrite bytes in memory so we
// can revert on failure. The walker only reads directory listings and
// files literally named index.md; hidden directories are pruned. A cheap
// substring check skips parsing files that cannot contain a relevant
// link.
rewritten := map[string][]byte{}
needle := []byte("[[" + oldPath)
walkErr := walkIndexFiles(h.root, func(fsPath string) error {
orig, err := os.ReadFile(fsPath)
if err != nil {
return err
}
if !bytes.Contains(orig, needle) {
if updateLinks {
needle := []byte("[[" + oldPath)
walkErr := walkIndexFiles(h.root, func(fsPath string) error {
orig, err := os.ReadFile(fsPath)
if err != nil {
return err
}
if !bytes.Contains(orig, needle) {
return nil
}
updated, changed := rewriteWikiLinks(orig, oldPath, newPath)
if !changed {
return nil
}
if err := writeFileAtomic(fsPath, updated, 0644); err != nil {
return fmt.Errorf("write %s: %w", fsPath, err)
}
rewritten[fsPath] = orig
return nil
})
if walkErr != nil {
rollbackRewrites(rewritten)
http.Error(w, "rewrite failed: "+walkErr.Error(), http.StatusInternalServerError)
return
}
updated, changed := rewriteWikiLinks(orig, oldPath, newPath)
if !changed {
return nil
}
if err := writeFileAtomic(fsPath, updated, 0644); err != nil {
return fmt.Errorf("write %s: %w", fsPath, err)
}
rewritten[fsPath] = orig
return nil
})
if walkErr != nil {
rollbackRewrites(rewritten)
http.Error(w, "rewrite failed: "+walkErr.Error(), http.StatusInternalServerError)
return
}
// Phase 2: create intermediate parent folders for the destination.