diff --git a/resources/package.json b/resources/package.json index 389edd3e83..b340c31d3d 100644 --- a/resources/package.json +++ b/resources/package.json @@ -40,7 +40,8 @@ "posthog-js": "1.10.2", "@logseq/rsapi": "0.0.50", "electron-deeplink": "1.0.10", - "abort-controller": "3.0.0" + "abort-controller": "3.0.0", + "command-exists": "1.2.9" }, "devDependencies": { "@electron-forge/cli": "^6.0.0-beta.57", diff --git a/src/electron/electron/handler.cljs b/src/electron/electron/handler.cljs index 047f82f19c..069e0e4591 100644 --- a/src/electron/electron/handler.cljs +++ b/src/electron/electron/handler.cljs @@ -11,6 +11,8 @@ ["diff-match-patch" :as google-diff] ["/electron/utils" :as js-utils] ["abort-controller" :as AbortController] + ["child_process" :as child-process] + ["command-exists" :as command-exists] [electron.fs-watcher :as watcher] [electron.configs :as cfgs] [promesa.core :as p] @@ -411,6 +413,26 @@ (git/init!) (git/run-git2! (clj->js args)))) +(defmethod handle :runCli [window [_ {:keys [command args returnResult]}]] + (when command + (if ((.-sync command-exists) command) + (let [job (child-process/spawn (str command " " args) + #js [] + #js {:shell true :detached true}) + handler (fn [message] + (let [result (str "Running " command ": " message)] + (println result) + (when returnResult + (utils/send-to-renderer window "notification" + {:type "success" + :payload result}))))] + (.on (.-stderr job) "data" handler) + (.on (.-stdout job) "data" handler)) + (utils/send-to-renderer window "notification" + {:type "error" + :payload (str "Program " command " not found!")})) + nil)) + (defmethod handle :gitCommitAll [_ [_ message]] (git/add-all-and-commit! message)) diff --git a/src/main/frontend/handler/shell.cljs b/src/main/frontend/handler/shell.cljs index 05ff667b1f..7650f7442f 100644 --- a/src/main/frontend/handler/shell.cljs +++ b/src/main/frontend/handler/shell.cljs @@ -17,14 +17,15 @@ [command] (ipc/ipc "runGitWithinCurrentGraph" command)) -;; TODO: export to pdf/html/word -(defn run-pandoc-command! - [command] - (ipc/ipc "runPandoc" command)) +(defn run-cli-command! + [command args] + (ipc/ipc "runCli" {:command command + :args args + :returnResult true})) (defn wrap-notification! [command f args] - (p/let [result (f args)] + (p/let [result (f command args)] (notification/show! (if (string/blank? result) [:p [:code.mr-1 (str command " " args) ] @@ -33,22 +34,34 @@ :success false))) +(def commands-whitelist + #{"git" "pandoc" "ag" "grep" "alda"}) + +(def dangerous-commands + #{"rm" "move" "rename" "dd" ">" "command" "sudo"}) + (defn run-command! [command] (let [[command args] (gp-util/split-first " " command) command (and command (string/lower-case command))] (when (and (not (string/blank? command)) (not (string/blank? args))) (let [args (string/trim args)] - (case (keyword command) - :git - (wrap-notification! command run-git-command! args) + (cond + (contains? dangerous-commands command) + (notification/show! + [:div (str command " is too dangerous!")] + :error) - ;; :pandoc - ;; (wrap-notification! command run-pandoc-command! args) + (= "git" command) + (wrap-notification! command (fn [_ args] (run-git-command! args)) args) - (notification/show! - [:div (str command " is not supported yet!")] - :error)))))) + (contains? commands-whitelist command) + (run-cli-command! command args) + + :else + (notification/show! + [:div (str command " is not supported yet!")] + :error)))))) ;; git show $REV:$FILE (defn- get-versioned-file-content