|
12 | 12 | [clojure.java.io :as io] |
13 | 13 | [clojure.string :as string] |
14 | 14 | [eca.cache :as cache] |
| 15 | + [eca.config :as config] |
15 | 16 | [eca.features.agents :as agents] |
16 | 17 | [eca.logger :as logger] |
17 | 18 | [eca.shared :as shared])) |
|
340 | 341 | :source-name source-name |
341 | 342 | :source-url source-url |
342 | 343 | :installed? (contains? installed-set (:name plugin))}))))) |
| 344 | + |
| 345 | +(defn ^:private parse-plugin-arg |
| 346 | + "Parses a plugin install argument. Supports 'plugin-name' or 'plugin-name@marketplace'. |
| 347 | + Returns {:plugin-name ... :marketplace ...} where :marketplace may be nil." |
| 348 | + [^String arg] |
| 349 | + (let [parts (string/split arg #"@" 2)] |
| 350 | + {:plugin-name (first parts) |
| 351 | + :marketplace (when (= 2 (count parts)) (second parts))})) |
| 352 | + |
| 353 | +(defn ^:private find-plugin-in-marketplaces |
| 354 | + "Finds a plugin by name across all resolved marketplaces, optionally filtered by source name. |
| 355 | + Returns {:name :source-name :source-url} or nil." |
| 356 | + [plugins-config plugin-name marketplace-filter] |
| 357 | + (let [sources (parse-sources plugins-config)] |
| 358 | + (first |
| 359 | + (for [[source-name source-url] sources |
| 360 | + :when (or (nil? marketplace-filter) (= marketplace-filter source-name)) |
| 361 | + :let [source-dir (resolve-source! source-url)] |
| 362 | + :when source-dir |
| 363 | + :let [marketplace (read-marketplace source-dir)] |
| 364 | + :when marketplace |
| 365 | + :let [entry (find-plugin-entry plugin-name marketplace)] |
| 366 | + :when entry] |
| 367 | + {:name plugin-name |
| 368 | + :source-name source-name |
| 369 | + :source-url source-url})))) |
| 370 | + |
| 371 | +(defn install-plugin! |
| 372 | + "Installs a plugin by adding it to the global config install list. |
| 373 | + `input` is either 'plugin-name' or 'plugin-name@marketplace'. |
| 374 | + Returns {:status :ok/:error, :message ...}." |
| 375 | + [plugins-config ^String input] |
| 376 | + (let [{:keys [plugin-name marketplace]} (parse-plugin-arg input) |
| 377 | + sources (parse-sources plugins-config) |
| 378 | + current-install (set (get plugins-config :install []))] |
| 379 | + (cond |
| 380 | + (empty? sources) |
| 381 | + {:status :error |
| 382 | + :message "No plugin marketplaces configured. Add plugin sources to your config under the `plugins` key."} |
| 383 | + |
| 384 | + (contains? current-install plugin-name) |
| 385 | + {:status :error |
| 386 | + :message (str "Plugin `" plugin-name "` is already installed.")} |
| 387 | + |
| 388 | + :else |
| 389 | + (if-let [found (find-plugin-in-marketplaces plugins-config plugin-name marketplace)] |
| 390 | + (let [new-install (vec (sort (conj current-install plugin-name)))] |
| 391 | + (config/update-global-config! {:plugins {:install new-install}}) |
| 392 | + {:status :ok |
| 393 | + :message (str "Plugin `" plugin-name "` installed from **" (:source-name found) "**. Restart ECA to activate it.")}) |
| 394 | + {:status :error |
| 395 | + :message (if marketplace |
| 396 | + (str "Plugin `" plugin-name "` not found in marketplace `" marketplace "`.") |
| 397 | + (str "Plugin `" plugin-name "` not found in any configured marketplace."))})))) |
0 commit comments