repo.cljs 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625
  1. (ns frontend.handler.repo
  2. (:refer-clojure :exclude [clone])
  3. (:require [frontend.util :as util :refer-macros [profile]]
  4. [frontend.fs :as fs]
  5. [promesa.core :as p]
  6. [lambdaisland.glogi :as log]
  7. [frontend.state :as state]
  8. [frontend.db :as db]
  9. [frontend.idb :as idb]
  10. [frontend.git :as git]
  11. [cljs-bean.core :as bean]
  12. [frontend.date :as date]
  13. [frontend.config :as config]
  14. [frontend.format :as format]
  15. [frontend.search :as search]
  16. [frontend.handler.ui :as ui-handler]
  17. [frontend.handler.git :as git-handler]
  18. [frontend.handler.file :as file-handler]
  19. [frontend.handler.notification :as notification]
  20. [frontend.handler.route :as route-handler]
  21. [frontend.handler.common :as common-handler]
  22. [frontend.handler.extract :as extract-handler]
  23. [frontend.ui :as ui]
  24. [clojure.string :as string]
  25. [frontend.dicts :as dicts]
  26. [frontend.spec :as spec]))
  27. ;; Project settings should be checked in two situations:
  28. ;; 1. User changes the config.edn directly in logseq.com (fn: alter-file)
  29. ;; 2. Git pulls the new change (fn: load-files)
  30. (defn show-install-error!
  31. [repo-url title]
  32. (spec/validate :repos/url repo-url)
  33. (notification/show!
  34. [:p.content
  35. title
  36. [:span.mr-2
  37. (util/format
  38. "Please make sure that you've installed the logseq app for the repo %s on GitHub. "
  39. repo-url)
  40. (ui/button
  41. "Install Logseq on GitHub"
  42. :href (str "https://github.com/apps/" config/github-app-name "/installations/new"))]]
  43. :error
  44. false))
  45. (defn create-config-file-if-not-exists
  46. [repo-url]
  47. (spec/validate :repos/url repo-url)
  48. (let [repo-dir (util/get-repo-dir repo-url)
  49. app-dir config/app-name
  50. dir (str repo-dir "/" app-dir)]
  51. (p/let [_ (fs/mkdir-if-not-exists dir)]
  52. (let [default-content config/config-default-content]
  53. (p/let [file-exists? (fs/create-if-not-exists repo-url repo-dir (str app-dir "/" config/config-file) default-content)]
  54. (let [path (str app-dir "/" config/config-file)
  55. old-content (when file-exists?
  56. (db/get-file repo-url path))
  57. content (or old-content default-content)]
  58. (file-handler/reset-file! repo-url path content)
  59. (common-handler/reset-config! repo-url content)
  60. (when-not (= content old-content)
  61. (git-handler/git-add repo-url path))))))))
  62. (defn create-contents-file
  63. [repo-url]
  64. (spec/validate :repos/url repo-url)
  65. (let [repo-dir (util/get-repo-dir repo-url)
  66. format (state/get-preferred-format)
  67. path (str (state/get-pages-directory)
  68. "/contents."
  69. (config/get-file-extension format))
  70. file-path (str "/" path)
  71. default-content (util/default-content-with-title format "contents")]
  72. (p/let [_ (fs/mkdir-if-not-exists (str repo-dir "/" (state/get-pages-directory)))
  73. file-exists? (fs/create-if-not-exists repo-url repo-dir file-path default-content)]
  74. (when-not file-exists?
  75. (file-handler/reset-file! repo-url path default-content)
  76. (git-handler/git-add repo-url path)))))
  77. (defn create-custom-theme
  78. [repo-url]
  79. (spec/validate :repos/url repo-url)
  80. (let [repo-dir (util/get-repo-dir repo-url)
  81. path (str config/app-name "/" config/custom-css-file)
  82. file-path (str "/" path)
  83. default-content ""]
  84. (p/let [_ (fs/mkdir-if-not-exists (str repo-dir "/" config/app-name))
  85. file-exists? (fs/create-if-not-exists repo-url repo-dir file-path default-content)]
  86. (when-not file-exists?
  87. (file-handler/reset-file! repo-url path default-content)
  88. (git-handler/git-add repo-url path)))))
  89. (defn create-dummy-notes-page
  90. [repo-url content]
  91. (spec/validate :repos/url repo-url)
  92. (let [repo-dir (util/get-repo-dir repo-url)
  93. path (str (config/get-pages-directory) "/how_to_make_dummy_notes.md")
  94. file-path (str "/" path)]
  95. (p/let [_ (fs/mkdir-if-not-exists (str repo-dir "/" (config/get-pages-directory)))
  96. _file-exists? (fs/create-if-not-exists repo-url repo-dir file-path content)]
  97. (file-handler/reset-file! repo-url path content))))
  98. (defn create-today-journal-if-not-exists
  99. ([repo-url]
  100. (create-today-journal-if-not-exists repo-url nil))
  101. ([repo-url content]
  102. (spec/validate :repos/url repo-url)
  103. (let [repo-dir (util/get-repo-dir repo-url)
  104. format (state/get-preferred-format repo-url)
  105. title (date/today)
  106. file-name (date/journal-title->default title)
  107. default-content (util/default-content-with-title format title false)
  108. template (state/get-journal-template)
  109. template (if (and template
  110. (not (string/blank? template)))
  111. template)
  112. content (cond
  113. content
  114. content
  115. template
  116. (str default-content template)
  117. :else
  118. (util/default-content-with-title format title true))
  119. path (str config/default-journals-directory "/" file-name "."
  120. (config/get-file-extension format))
  121. file-path (str "/" path)
  122. page-exists? (db/entity repo-url [:page/name (string/lower-case title)])
  123. empty-blocks? (empty? (db/get-page-blocks-no-cache repo-url (string/lower-case title)))]
  124. (when (or empty-blocks?
  125. (not page-exists?))
  126. (p/let [_ (fs/check-directory-permission! repo-url)
  127. _ (fs/mkdir-if-not-exists (str repo-dir "/" config/default-journals-directory))
  128. file-exists? (fs/create-if-not-exists repo-url repo-dir file-path content)]
  129. (when-not file-exists?
  130. (file-handler/reset-file! repo-url path content)
  131. (ui-handler/re-render-root!)
  132. (git-handler/git-add repo-url path)))))))
  133. (defn create-today-journal!
  134. []
  135. (state/set-today! (date/today))
  136. (when-let [repo (state/get-current-repo)]
  137. (when (or (db/cloned? repo)
  138. (and (config/local-db? repo)
  139. ;; config file exists
  140. (db/get-file (str config/app-name "/" config/config-file))))
  141. (let [today-page (string/lower-case (date/today))]
  142. (when (empty? (db/get-page-blocks-no-cache repo today-page))
  143. (create-today-journal-if-not-exists repo))))))
  144. (defn create-default-files!
  145. [repo-url]
  146. (spec/validate :repos/url repo-url)
  147. (create-config-file-if-not-exists repo-url)
  148. (create-today-journal-if-not-exists repo-url)
  149. (create-contents-file repo-url)
  150. (create-custom-theme repo-url))
  151. (defn- reset-contents-and-blocks!
  152. [repo-url files blocks-pages delete-files delete-blocks]
  153. (db/transact-files-db! repo-url files)
  154. (let [files (map #(select-keys % [:file/path]) files)
  155. all-data (-> (concat delete-files delete-blocks files blocks-pages)
  156. (util/remove-nils))]
  157. (db/transact! repo-url all-data)))
  158. (defn parse-files-and-load-to-db!
  159. [repo-url files {:keys [first-clone? delete-files delete-blocks re-render? re-render-opts] :as opts
  160. :or {re-render? true}}]
  161. (state/set-loading-files! false)
  162. (state/set-importing-to-db! true)
  163. (let [file-paths (map :file/path files)
  164. parsed-files (filter
  165. (fn [file]
  166. (let [format (format/get-format (:file/path file))]
  167. (contains? config/mldoc-support-formats format)))
  168. files)
  169. blocks-pages (if (seq parsed-files)
  170. (extract-handler/extract-all-blocks-pages repo-url parsed-files)
  171. [])]
  172. (reset-contents-and-blocks! repo-url files blocks-pages delete-files delete-blocks)
  173. (let [config-file (str config/app-name "/" config/config-file)]
  174. (if (contains? (set file-paths) config-file)
  175. (when-let [content (some #(when (= (:file/path %) config-file)
  176. (:file/content %)) files)]
  177. (file-handler/restore-config! repo-url content true))))
  178. (when first-clone? (create-default-files! repo-url))
  179. (when re-render?
  180. (ui-handler/re-render-root! re-render-opts))
  181. (state/set-importing-to-db! false)))
  182. (defn load-repo-to-db!
  183. [repo-url {:keys [first-clone? diffs nfs-files]
  184. :as opts}]
  185. (spec/validate :repos/url repo-url)
  186. (let [load-contents (fn [files option]
  187. (file-handler/load-files-contents!
  188. repo-url
  189. files
  190. (fn [files-contents]
  191. (parse-files-and-load-to-db! repo-url files-contents option))))]
  192. (cond
  193. (and (not (seq diffs)) nfs-files)
  194. (parse-files-and-load-to-db! repo-url nfs-files {:first-clone? true})
  195. (and first-clone? (not nfs-files))
  196. (->
  197. (p/let [files (file-handler/load-files repo-url)]
  198. (load-contents files {:first-clone? first-clone?}))
  199. (p/catch (fn [error]
  200. (println "loading files failed: ")
  201. (js/console.dir error)
  202. ;; Empty repo
  203. (create-default-files! repo-url)
  204. (state/set-loading-files! false))))
  205. :else
  206. (when (seq diffs)
  207. (let [filter-diffs (fn [type] (->> (filter (fn [f] (= type (:type f))) diffs)
  208. (map :path)))
  209. remove-files (filter-diffs "remove")
  210. modify-files (filter-diffs "modify")
  211. add-files (filter-diffs "add")
  212. delete-files (if (seq remove-files)
  213. (db/delete-files remove-files))
  214. delete-blocks (db/delete-blocks repo-url (concat remove-files modify-files))
  215. delete-pages (if (seq remove-files)
  216. (db/delete-pages-by-files remove-files)
  217. [])
  218. add-or-modify-files (some->>
  219. (concat modify-files add-files)
  220. (util/remove-nils))
  221. options {:first-clone? first-clone?
  222. :delete-files (concat delete-files delete-pages)
  223. :delete-blocks delete-blocks
  224. :re-render? true}]
  225. (if (seq nfs-files)
  226. (parse-files-and-load-to-db! repo-url nfs-files
  227. (assoc options :re-render-opts {:clear-all-query-state? true}))
  228. (load-contents add-or-modify-files options)))))))
  229. (defn load-db-and-journals!
  230. [repo-url diffs first-clone?]
  231. (spec/validate :repos/url repo-url)
  232. (when (or diffs first-clone?)
  233. (load-repo-to-db! repo-url {:first-clone? first-clone?
  234. :diffs diffs})))
  235. (defn rebuild-page-blocks-children
  236. "For performance reason, we can update the :block/children value after every operation,
  237. but it's hard to make sure that it's correct, also it needs more time to implement it.
  238. We can improve it if the performance is really an issue."
  239. [repo page]
  240. (let [blocks (->>
  241. (db/get-page-blocks-no-cache repo page {:pull-keys '[:db/id :block/uuid :block/level :block/pre-block? :block/meta]})
  242. (remove :block/pre-block?)
  243. (map #(select-keys % [:db/id :block/uuid :block/level]))
  244. (reverse))
  245. original-blocks blocks]
  246. (loop [blocks blocks
  247. tx []
  248. children {}
  249. last-level 10000]
  250. (if (seq blocks)
  251. (let [[{:block/keys [uuid level] :as block} & others] blocks
  252. [tx children] (cond
  253. (< level last-level) ; parent
  254. (let [cur-children (get children last-level)
  255. tx (if (seq cur-children)
  256. (vec
  257. (concat
  258. tx
  259. (map
  260. (fn [child]
  261. [:db/add (:db/id block) :block/children [:block/uuid child]])
  262. cur-children)))
  263. tx)
  264. children (-> children
  265. (dissoc last-level)
  266. (update level conj uuid))]
  267. [tx children])
  268. (> level last-level) ; child of sibling
  269. (let [children (update children level conj uuid)]
  270. [tx children])
  271. :else ; sibling
  272. (let [children (update children last-level conj uuid)]
  273. [tx children]))]
  274. (recur others tx children level))
  275. ;; TODO: add top-level children to the "Page" block (we might remove the Page from db schema)
  276. (when (seq tx)
  277. (let [delete-tx (map (fn [block]
  278. [:db/retract (:db/id block) :block/children])
  279. original-blocks)]
  280. (->> (concat delete-tx tx)
  281. (remove nil?))))))))
  282. (defn transact-react-and-alter-file!
  283. [repo tx transact-option files]
  284. (spec/validate :repos/url repo)
  285. (let [files (remove nil? files)
  286. pages (->> (map db/get-file-page (map first files))
  287. (remove nil?))]
  288. (db/transact-react!
  289. repo
  290. tx
  291. transact-option)
  292. (when (seq pages)
  293. (let [children-tx (mapcat #(rebuild-page-blocks-children repo %) pages)]
  294. (when (seq children-tx)
  295. (db/transact! repo children-tx))))
  296. (when (seq files)
  297. (file-handler/alter-files repo files {}))))
  298. (declare push)
  299. (defn get-diff-result
  300. [repo-url]
  301. (p/let [remote-latest-commit (common-handler/get-remote-ref repo-url)
  302. local-latest-commit (common-handler/get-ref repo-url)]
  303. (git/get-diffs repo-url local-latest-commit remote-latest-commit)))
  304. (defn pull
  305. [repo-url {:keys [force-pull? show-diff? try-times]
  306. :or {force-pull? false
  307. show-diff? false
  308. try-times 2}
  309. :as opts}]
  310. (spec/validate :repos/url repo-url)
  311. (when (and
  312. (db/get-conn repo-url true)
  313. (db/cloned? repo-url))
  314. (p/let [remote-latest-commit (common-handler/get-remote-ref repo-url)
  315. local-latest-commit (common-handler/get-ref repo-url)
  316. descendent? (git/descendent? repo-url local-latest-commit remote-latest-commit)]
  317. (when (or (= local-latest-commit remote-latest-commit)
  318. (nil? local-latest-commit)
  319. (not descendent?)
  320. force-pull?)
  321. (p/let [files (js/window.workerThread.getChangedFiles (util/get-repo-dir repo-url))]
  322. (when (empty? files)
  323. (let [status (db/get-key-value repo-url :git/status)]
  324. (when (or
  325. force-pull?
  326. (and
  327. (not= status :pushing)
  328. (not (state/get-edit-input-id))
  329. (not (state/in-draw-mode?))
  330. ;; don't pull if git conflicts not resolved yet
  331. (or
  332. show-diff?
  333. (and (not show-diff?)
  334. (empty? @state/diffs)))))
  335. (git-handler/set-git-status! repo-url :pulling)
  336. (->
  337. (p/let [token (common-handler/get-github-token repo-url)
  338. result (git/fetch repo-url token)]
  339. (let [{:keys [fetchHead]} (bean/->clj result)]
  340. (-> (git/merge repo-url)
  341. (p/then (fn [result]
  342. (-> (git/checkout repo-url)
  343. (p/then (fn [result]
  344. (git-handler/set-git-status! repo-url nil)
  345. (git-handler/set-git-last-pulled-at! repo-url)
  346. (when (and local-latest-commit fetchHead
  347. (not= local-latest-commit fetchHead))
  348. (p/let [diffs (git/get-diffs repo-url local-latest-commit fetchHead)]
  349. (when (seq diffs)
  350. (load-db-and-journals! repo-url diffs false))))
  351. (common-handler/check-changed-files-status repo-url)))
  352. (p/catch (fn [error]
  353. (git-handler/set-git-status! repo-url :checkout-failed)
  354. (git-handler/set-git-error! repo-url error))))))
  355. (p/catch (fn [error]
  356. (println "Git pull error:")
  357. (js/console.error error)
  358. (git-handler/set-git-status! repo-url :merge-failed)
  359. (git-handler/set-git-error! repo-url error)
  360. (p/let [result (get-diff-result repo-url)]
  361. (if (seq result)
  362. (do
  363. (notification/show!
  364. [:p.content
  365. "Failed to merge, please "
  366. [:span.font-bold
  367. "resolve any diffs first."]]
  368. :error)
  369. (route-handler/redirect! {:to :diff}))
  370. (push repo-url {:merge-push-no-diff? true
  371. :commit-message "Merge push without diffed files"}))))))))
  372. (p/catch
  373. (fn [error]
  374. (cond
  375. (string/includes? (str error) "404")
  376. (do (log/error :git/pull-error error)
  377. (show-install-error! repo-url (util/format "Failed to fetch %s." repo-url)))
  378. (string/includes? (str error) "401")
  379. (let [remain-times (dec try-times)]
  380. (if (> remain-times 0)
  381. (let [new-opts (merge opts {:try-times remain-times})]
  382. (pull repo-url new-opts))
  383. (let [error-msg
  384. (util/format "Failed to fetch %s. It may be caused by token expiration or missing." repo-url)]
  385. (log/error :git/pull-error error)
  386. (notification/show! error-msg :error false))))
  387. :else
  388. (log/error :git/pull-error error)))))))))))))
  389. (defn push
  390. [repo-url {:keys [commit-message merge-push-no-diff? custom-commit?]
  391. :or {custom-commit false
  392. commit-message "Logseq auto save"
  393. merge-push-no-diff? false}}]
  394. (spec/validate :repos/url repo-url)
  395. (let [status (db/get-key-value repo-url :git/status)]
  396. (if (and
  397. (db/cloned? repo-url)
  398. (state/input-idle? repo-url)
  399. (or (not= status :pushing)
  400. custom-commit?))
  401. (-> (p/let [files (git/add-all (state/get-current-repo))]
  402. (when (or (seq files) merge-push-no-diff?)
  403. ;; auto commit if there are any un-committed changes
  404. (let [commit-message (if (string/blank? commit-message)
  405. "Logseq auto save"
  406. commit-message)]
  407. (p/let [commit-oid (git/commit repo-url commit-message)
  408. token (common-handler/get-github-token repo-url)
  409. status (db/get-key-value repo-url :git/status)]
  410. (when (and token (or (not= status :pushing)
  411. custom-commit?))
  412. (git-handler/set-git-status! repo-url :pushing)
  413. (util/p-handle
  414. (git/push repo-url token merge-push-no-diff?)
  415. (fn [result]
  416. (git-handler/set-git-status! repo-url nil)
  417. (git-handler/set-git-error! repo-url nil)
  418. (common-handler/check-changed-files-status repo-url))
  419. (fn [error]
  420. (log/error :git/push-error error)
  421. (js/console.error error)
  422. (common-handler/check-changed-files-status repo-url)
  423. (do
  424. (git-handler/set-git-status! repo-url :push-failed)
  425. (git-handler/set-git-error! repo-url error)
  426. (when (state/online?)
  427. (pull repo-url {:force-pull? true
  428. :show-diff? true}))))))))))
  429. (p/catch (fn [error]
  430. (log/error :git/get-changed-files-error error)
  431. (git-handler/set-git-status! repo-url :push-failed)
  432. (git-handler/set-git-error! repo-url error)
  433. (js/console.dir error)))))))
  434. (defn push-if-auto-enabled!
  435. [repo]
  436. (spec/validate :repos/url repo)
  437. (when (state/get-git-auto-push? repo)
  438. (push repo nil)))
  439. (defn pull-current-repo
  440. []
  441. (when-let [repo (state/get-current-repo)]
  442. (pull repo {:force-pull? true})))
  443. (defn- clone
  444. [repo-url]
  445. (spec/validate :repos/url repo-url)
  446. (p/let [token (common-handler/get-github-token repo-url)]
  447. (when token
  448. (util/p-handle
  449. (do
  450. (state/set-cloning! true)
  451. (git/clone repo-url token))
  452. (fn [result]
  453. (state/set-current-repo! repo-url)
  454. (db/start-db-conn! (state/get-me) repo-url)
  455. (db/mark-repo-as-cloned! repo-url))
  456. (fn [e]
  457. (println "Clone failed, error: ")
  458. (js/console.error e)
  459. (state/set-cloning! false)
  460. (git-handler/set-git-status! repo-url :clone-failed)
  461. (git-handler/set-git-error! repo-url e)
  462. (show-install-error! repo-url (util/format "Failed to clone %s." repo-url)))))))
  463. (defn set-config-content!
  464. [repo path new-content]
  465. (file-handler/alter-file repo path new-content {:reset? false
  466. :re-render-root? false}))
  467. (defn remove-repo!
  468. [{:keys [id url] :as repo}]
  469. (spec/validate :repos/repo repo)
  470. (let [delete-db-f (fn []
  471. (db/remove-conn! url)
  472. (db/remove-db! url)
  473. (db/remove-files-db! url)
  474. (fs/rmdir (util/get-repo-dir url))
  475. (state/delete-repo! repo))]
  476. (if (config/local-db? url)
  477. (p/let [_ (idb/clear-local-db! url)] ; clear file handles
  478. (delete-db-f))
  479. (util/delete (str config/api "repos/" id)
  480. delete-db-f
  481. (fn [error]
  482. (prn "Delete repo failed, error: " error))))))
  483. (defn start-repo-db-if-not-exists!
  484. [repo option]
  485. (state/set-current-repo! repo)
  486. (db/start-db-conn! nil repo option))
  487. (defn setup-local-repo-if-not-exists!
  488. []
  489. (if js/window.pfs
  490. (let [repo config/local-repo]
  491. (p/do! (fs/mkdir-if-not-exists (str "/" repo))
  492. (state/set-current-repo! repo)
  493. (db/start-db-conn! nil repo)
  494. (when-not config/publishing?
  495. (let [dummy-notes (get-in dicts/dicts [:en :tutorial/dummy-notes])]
  496. (create-dummy-notes-page repo dummy-notes)))
  497. (when-not config/publishing?
  498. (let [tutorial (get-in dicts/dicts [:en :tutorial/text])
  499. tutorial (string/replace-first tutorial "$today" (date/today))]
  500. (create-today-journal-if-not-exists repo tutorial)))
  501. (create-config-file-if-not-exists repo)
  502. (create-contents-file repo)
  503. (create-custom-theme repo)
  504. (state/set-db-restoring! false)))
  505. (js/setTimeout setup-local-repo-if-not-exists! 100)))
  506. (defn periodically-pull-current-repo
  507. []
  508. (js/setInterval
  509. (fn []
  510. (p/let [repo-url (state/get-current-repo)
  511. token (common-handler/get-github-token repo-url)]
  512. (when token
  513. (pull repo-url nil))))
  514. (* (config/git-pull-secs) 1000)))
  515. (defn periodically-push-current-repo
  516. []
  517. (js/setInterval #(push-if-auto-enabled! (state/get-current-repo))
  518. (* (config/git-push-secs) 1000)))
  519. (defn create-repo!
  520. [repo-url]
  521. (spec/validate :repos/url repo-url)
  522. (util/post (str config/api "repos")
  523. {:url repo-url
  524. :branch "main"}
  525. (fn [result]
  526. (if (:installation_id result)
  527. (set! (.-href js/window.location) config/website)
  528. (set! (.-href js/window.location) (str "https://github.com/apps/" config/github-app-name "/installations/new"))))
  529. (fn [error]
  530. (println "Something wrong!")
  531. (js/console.dir error))))
  532. (defn- clone-and-load-db
  533. [repo-url]
  534. (spec/validate :repos/url repo-url)
  535. (->
  536. (p/let [_ (clone repo-url)
  537. _ (git-handler/git-set-username-email! repo-url (state/get-me))]
  538. (load-db-and-journals! repo-url nil true))
  539. (p/catch (fn [error]
  540. (js/console.error error)))))
  541. (defn clone-and-pull-repos
  542. [me]
  543. (spec/validate :state/me me)
  544. (if (and js/window.git js/window.pfs)
  545. (do
  546. (doseq [{:keys [id url]} (:repos me)]
  547. (let [repo url]
  548. (p/let [config-exists? (fs/file-exists?
  549. (util/get-repo-dir url)
  550. ".git/config")]
  551. (if (and config-exists?
  552. (db/cloned? repo))
  553. (p/do!
  554. (git-handler/git-set-username-email! repo me)
  555. (pull repo nil))
  556. (p/do!
  557. (clone-and-load-db repo))))))
  558. (periodically-pull-current-repo)
  559. (periodically-push-current-repo))
  560. (js/setTimeout (fn []
  561. (clone-and-pull-repos me))
  562. 500)))
  563. (defn rebuild-index!
  564. [url]
  565. (when url
  566. (search/reset-indice! url)
  567. (db/remove-conn! url)
  568. (db/clear-query-state!)
  569. (-> (p/do! (db/remove-db! url)
  570. (db/remove-files-db! url)
  571. (fs/rmdir (util/get-repo-dir url))
  572. (clone-and-load-db url))
  573. (p/catch (fn [error]
  574. (prn "Delete repo failed, error: " error))))))
  575. (defn git-commit-and-push!
  576. [commit-message]
  577. (when-let [repo (state/get-current-repo)]
  578. (push repo {:commit-message commit-message
  579. :custom-commit? true})))
  580. (defn get-repo-name
  581. [url]
  582. (last (string/split url #"/")))