|
1 | 1 | (ns tasks.stitch-outbound-links |
2 | 2 | (:require [babashka.fs :as fs] |
3 | | - [clojure.string :as str])) |
| 3 | + [clj-yaml.core :as yaml] |
| 4 | + [clojure.string :as str] |
| 5 | + [clojure.walk :as walk] |
| 6 | + [tasks.util :as u])) |
4 | 7 |
|
5 | 8 | (def outbound-link-roots |
6 | 9 | #{"blog-authors" "case-studies" "cloud" "community-posts" "dashboards" "data" |
|
10 | 13 | "sales" "sass" "site" "start" "startup-guide" "talk-to-a-person" |
11 | 14 | "troubleshooting" "upgrade"}) |
12 | 15 |
|
13 | | -(defn- log [level message] (println (str level " " message))) |
| 16 | +(def outbound-link-roots-re |
| 17 | + (str "(" (str/join "|" outbound-link-roots) ")")) |
| 18 | + |
| 19 | +(def inline-pattern (re-pattern (str "(\\(\\s*)/" outbound-link-roots-re))) |
| 20 | +(def reference-pattern (re-pattern (str "(\\]\\:\\s*)/" outbound-link-roots-re))) |
| 21 | + |
| 22 | +(comment |
| 23 | + ;; How It Works: |
| 24 | + (update-links "[a](/gallery/x)") |
| 25 | + ;; => "[a](https://metabase.com/gallery/x)" |
| 26 | + (update-links "[a]: /gallery/x") |
| 27 | + ;; => "[a]: https://metabase.com/gallery/x" |
| 28 | + (update-links "[a]: /gallery/x") |
| 29 | + ;; => "[a]: https://metabase.com/gallery/x" |
| 30 | + ) |
14 | 31 |
|
15 | 32 | (defn- update-links |
16 | 33 | "Replaces occurrences of links starting with '/learn' with 'https://metabase.com/learn'. |
17 | 34 | It handles both inline links (e.g., [c](/learn/y)) and reference-style links (e.g., [b]: /learn/x)." |
18 | 35 | [content] |
19 | 36 | (-> content |
20 | | - (str/replace #"(\(\s*)/learn" "$1https://metabase.com/learn") |
21 | | - (str/replace #"(\]\:\s*)/learn" "$1https://metabase.com/learn"))) |
| 37 | + (str/replace inline-pattern "$1https://metabase.com/$2") |
| 38 | + (str/replace reference-pattern "$1https://metabase.com/$2"))) |
22 | 39 |
|
23 | | -(defn- process-file |
| 40 | +(defn- process-md |
24 | 41 | "Reads a markdown file, updates its content if necessary, and writes the updated content back. |
25 | 42 | When dry-run is enabled, logs the intended action instead of modifying the file." |
26 | | - [file dry-run?] |
27 | | - (log "π" (str "Processing file: " file)) |
28 | | - (let [content (slurp file) |
| 43 | + [path dry-run?] |
| 44 | + (u/log "π" (str "Processing file: " path)) |
| 45 | + (let [content (slurp path) |
29 | 46 | new-content (update-links content)] |
30 | 47 | (if (= content new-content) |
31 | | - (log "βΉοΈ" (str "No changes for file: " file)) |
32 | | - (do (if dry-run? |
33 | | - (log "π" (str "Dry run: Would update file: " file)) |
34 | | - (do |
35 | | - (spit file new-content) |
36 | | - (log "β
" (str "Updated file: " file)))))))) |
37 | | - |
38 | | -(defn- crawl-directory |
| 48 | + (u/log " βΉοΈ" (str "No changes for file: " path)) |
| 49 | + (if dry-run? |
| 50 | + (u/log " π" (str "Dry run: Would update file: " path)) |
| 51 | + (do |
| 52 | + (spit path new-content) |
| 53 | + (u/log " β
" (str "Updated file: " path))))))) |
| 54 | + |
| 55 | +(defn- crawl-md-directory |
39 | 56 | "Recursively finds all Markdown files in the given directory and processes each one." |
40 | 57 | [dir dry-run?] |
41 | 58 | (doseq [file (fs/glob dir "**/*.md")] |
42 | | - (prn (str file)) |
43 | | - (process-file (str file) dry-run?))) |
| 59 | + (process-md (str file) dry-run?))) |
| 60 | + |
| 61 | +(do |
| 62 | + (defn process-yaml [path dry-run?] |
| 63 | + (let [parsed (yaml/parse-string (slurp path)) |
| 64 | + updated (walk/postwalk |
| 65 | + (fn [node] |
| 66 | + (if (and (map? node) |
| 67 | + (contains? node :url) |
| 68 | + (some #(str/starts-with? (:url node) %) (map #(str "/" % "/") outbound-link-roots))) |
| 69 | + (update-in node [:url] #(str "https://metabase.com" %)) |
| 70 | + node)) |
| 71 | + parsed)] |
| 72 | + (if dry-run? |
| 73 | + (do (u/log " π" (str "Dry run: Would update file: " path)) |
| 74 | + updated) |
| 75 | + (do |
| 76 | + (spit path (yaml/generate-string updated :dumper-options {:flow-style :block})) |
| 77 | + (u/log " β
" (str "Updated file: " path)))))) |
| 78 | + (process-yaml "_data/docs/nav/latest.yml" true)) |
| 79 | + |
| 80 | + |
| 81 | +(defn- crawl-data-directory |
| 82 | + [dry-run?] |
| 83 | + (doseq [file (concat (fs/glob "_data" "**/*.yaml") (fs/glob "_data" "**/*.yml"))] |
| 84 | + (process-yaml (str file) dry-run?))) |
44 | 85 |
|
45 | 86 | (defn -main |
46 | 87 | "Entry point. Args are validated in bb.edn" |
47 | | - [{:keys [dry-run? dir]}] |
48 | | - (log "π" (str "Crawling directory: " dir (if dry-run? " (dry run mode)" ""))) |
49 | | - (crawl-directory dir dry-run?)) |
| 88 | + [{:keys [dry-run?]}] |
| 89 | + (u/log "π" (str "Crawling _docs directory: updating markdown links" (when dry-run? " (dry run mode)"))) |
| 90 | + (crawl-md-directory "_docs" dry-run?) |
| 91 | + (u/log "π" (str "Crawling _data directory: updating yaml links" (when dry-run? " (dry run mode)"))) |
| 92 | + (crawl-data-directory dry-run?)) |
0 commit comments