Improve command line helpers.

This commit is contained in:
Andrey Antukh 2020-08-17 15:04:21 +02:00
parent c0cd0d4a23
commit 2746d598b0
11 changed files with 106 additions and 87 deletions

View file

@ -74,6 +74,14 @@
mockery/mockery {:mvn/version "0.1.4"}} mockery/mockery {:mvn/version "0.1.4"}}
:extra-paths ["tests"]} :extra-paths ["tests"]}
:fn-media-loader
{:fn uxbox.cli.media-loader/run
:args {}}
:fn-fixtures
{:fn uxbox.cli.fixtures/run
:args {}}
:lint :lint
{:main-opts ["-m" "clj-kondo.main"]} {:main-opts ["-m" "clj-kondo.main"]}

View file

@ -29,6 +29,11 @@
<Logger name="io.lettuce" level="error" additivity="false" /> <Logger name="io.lettuce" level="error" additivity="false" />
<Logger name="uxbox.cli" level="debug" additivity="false">
<AppenderRef ref="console"/>
</Logger>
<Logger name="uxbox" level="debug" additivity="false"> <Logger name="uxbox" level="debug" additivity="false">
<AppenderRef ref="file-debug" level="debug" /> <AppenderRef ref="file-debug" level="debug" />
<AppenderRef ref="file" level="info" /> <AppenderRef ref="file" level="info" />

View file

@ -2,9 +2,12 @@
;; License, v. 2.0. If a copy of the MPL was not distributed with this ;; License, v. 2.0. If a copy of the MPL was not distributed with this
;; file, You can obtain one at http://mozilla.org/MPL/2.0/. ;; file, You can obtain one at http://mozilla.org/MPL/2.0/.
;; ;;
;; Copyright (c) 2019 Andrey Antukh <niwi@niwi.nz> ;; This Source Code Form is "Incompatible With Secondary Licenses", as
;; defined by the Mozilla Public License, v. 2.0.
;;
;; Copyright (c) 2020 UXBOX Labs SL
(ns uxbox.fixtures (ns uxbox.cli.fixtures
"A initial fixtures." "A initial fixtures."
(:require (:require
[clojure.tools.logging :as log] [clojure.tools.logging :as log]
@ -246,7 +249,7 @@
(assign-teams-and-profiles conn teams (map :id profiles)) (assign-teams-and-profiles conn teams (map :id profiles))
(run! (partial create-draft-files conn) profiles))))) (run! (partial create-draft-files conn) profiles)))))
(defn run (defn run*
[preset] [preset]
(let [preset (if (map? preset) (let [preset (if (map? preset)
preset preset
@ -257,13 +260,16 @@
preset-small))] preset-small))]
(impl-run preset))) (impl-run preset)))
(defn -main (defn run
[& args] [{:keys [preset]
:or {preset :small}}]
(try (try
(-> (mount/only #{#'uxbox.config/config (-> (mount/only #{#'uxbox.config/config
#'uxbox.db/pool #'uxbox.db/pool
#'uxbox.migrations/migrations}) #'uxbox.migrations/migrations})
(mount/start)) (mount/start))
(run (first args)) (run* preset)
(catch Exception e
(log/errorf e "Unhandled exception."))
(finally (finally
(mount/stop)))) (mount/stop))))

View file

@ -7,36 +7,27 @@
;; ;;
;; Copyright (c) 2016-2020 Andrey Antukh <niwi@niwi.nz> ;; Copyright (c) 2016-2020 Andrey Antukh <niwi@niwi.nz>
(ns uxbox.media-loader (ns uxbox.cli.media-loader
"Media libraries importer (command line helper)." "Media libraries importer (command line helper)."
(:require (:require
[clojure.tools.logging :as log] [clojure.tools.logging :as log]
[clojure.spec.alpha :as s] [clojure.spec.alpha :as s]
[clojure.pprint :refer [pprint]]
[clojure.java.io :as io] [clojure.java.io :as io]
[clojure.edn :as edn]
[mount.core :as mount] [mount.core :as mount]
[datoteka.core :as fs] [datoteka.core :as fs]
[cuerdas.core :as str]
[uxbox.config] [uxbox.config]
[uxbox.common.spec :as us] [uxbox.common.spec :as us]
[uxbox.db :as db] [uxbox.db :as db]
[uxbox.http] [uxbox.media]
[uxbox.media-storage]
[uxbox.migrations] [uxbox.migrations]
[uxbox.util.svg :as svg]
[uxbox.util.transit :as t]
[uxbox.util.blob :as blob]
[uxbox.common.uuid :as uuid] [uxbox.common.uuid :as uuid]
[uxbox.util.data :as data]
[uxbox.services.mutations.projects :as projects] [uxbox.services.mutations.projects :as projects]
[uxbox.services.mutations.files :as files] [uxbox.services.mutations.files :as files]
[uxbox.services.mutations.colors :as colors] [uxbox.services.mutations.colors :as colors]
[uxbox.services.mutations.media :as media] [uxbox.services.mutations.media :as media])
[uxbox.util.storage :as ust])
(:import (:import
java.io.Reader java.io.PushbackReader))
java.io.PushbackReader
org.im4java.core.Info))
;; --- Constants & Helpers ;; --- Constants & Helpers
@ -65,7 +56,6 @@
([code] ([code]
(System/exit code))) (System/exit code)))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Graphics Importer ;; Graphics Importer
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@ -109,7 +99,7 @@
media-object-id)) media-object-id))
(defn- import-graphics (defn- import-graphics
[conn file-id {:keys [path regex] :as graphics}] [conn file-id {:keys [path regex]}]
(run! (fn [fpath] (run! (fn [fpath]
(when (re-matches regex (str fpath)) (when (re-matches regex (str fpath))
(import-media-object-if-not-exists conn file-id fpath))) (import-media-object-if-not-exists conn file-id fpath)))
@ -151,7 +141,7 @@
(if row true false))) (if row true false)))
(defn- create-library-file-if-not-exists (defn- create-library-file-if-not-exists
[conn project-id {:keys [name] :as library-file}] [conn project-id {:keys [name]}]
(let [id (uuid/namespaced +colors-uuid-ns+ name)] (let [id (uuid/namespaced +colors-uuid-ns+ name)]
(when-not (library-file-exists? conn id) (when-not (library-file-exists? conn id)
(log/info "Creating library-file:" name) (log/info "Creating library-file:" name)
@ -164,7 +154,7 @@
id)) id))
(defn- process-library (defn- process-library
[conn basedir project-id {:keys [name graphics colors] :as library}] [conn basedir project-id {:keys [graphics colors] :as library}]
(us/verify ::import-library library) (us/verify ::import-library library)
(let [library-file-id (create-library-file-if-not-exists conn project-id library)] (let [library-file-id (create-library-file-if-not-exists conn project-id library)]
(when graphics (when graphics
@ -197,6 +187,8 @@
(defn- validate-path (defn- validate-path
[path] [path]
(let [path (if (symbol? path) (str path) path)]
(log/infof "Trying to load config from '%s'." path)
(when-not path (when-not path
(log/error "No path is provided") (log/error "No path is provided")
(exit! -1)) (exit! -1))
@ -206,36 +198,36 @@
(when (fs/directory? path) (when (fs/directory? path)
(log/error "The provided path is a directory.") (log/error "The provided path is a directory.")
(exit! -1)) (exit! -1))
(fs/path path)) (fs/path path)))
(defn- read-file (defn- read-file
[path] [path]
(let [reader (java.io.PushbackReader. (io/reader path))] (let [reader (PushbackReader. (io/reader path))]
[(fs/parent path) [(fs/parent path)
(read reader)])) (read reader)]))
(defn- start-system (defn run*
[]
(-> (mount/except #{#'uxbox.http/server})
(mount/start)))
(defn- stop-system
[]
(mount/stop))
(defn run
[path] [path]
(let [[basedir libraries] (read-file path)] (let [[basedir libraries] (read-file path)]
(db/with-atomic [conn db/pool] (db/with-atomic [conn db/pool]
(let [project-id (create-project-if-not-exists conn {:name "System libraries"})] (let [project-id (create-project-if-not-exists conn {:name "System libraries"})]
(run! #(process-library conn basedir project-id %) libraries))))) (run! #(process-library conn basedir project-id %) libraries)))))
(defn -main (defn run
[& [path]] [{:keys [path] :as params}]
(log/infof "Starting media loader.")
(let [path (validate-path path)] (let [path (validate-path path)]
(try
(start-system) (try
(run path) (-> (mount/only #{#'uxbox.config/config
(finally #'uxbox.db/pool
(stop-system))))) #'uxbox.migrations/migrations
#'uxbox.media/semaphore
#'uxbox.media-storage/media-storage})
(mount/start))
(run* path)
(catch Exception e
(log/errorf e "Unhandled exception."))
(finally
(mount/stop)))))

View file

@ -85,18 +85,6 @@
{:unresolved-symbol {:unresolved-symbol
{:exclude ['(uxbox.services.mutations/defmutation) {:exclude ['(uxbox.services.mutations/defmutation)
'(uxbox.services.queries/defquery) '(uxbox.services.queries/defquery)
'(uxbox.db/with-atomic)
'(promesa.core/let)]}}}}) '(promesa.core/let)]}}}})
(kondo/print!)))) (kondo/print!))))
;; (defn red
;; [items]
;; (as-> items $$
;; (reduce (fn [acc item]
;; (cp/process-changes acc (:changes item)))
;; cp/default-page-data
;; $$)))
;; (defn update-page-data
;; [id data]
;; (let [data (blob/encode data)]
;; (db/query-one db/pool ["update page set data=$1 where id=$2" data id])))

View file

@ -14,9 +14,7 @@
[uxbox.services.mutations.teams :as teams] [uxbox.services.mutations.teams :as teams]
[uxbox.services.mutations.files :as files] [uxbox.services.mutations.files :as files]
[uxbox.services.mutations.pages :as pages] [uxbox.services.mutations.pages :as pages]
;; [uxbox.services.mutations.icons :as icons]
[uxbox.services.mutations.colors :as colors] [uxbox.services.mutations.colors :as colors]
[uxbox.fixtures :as fixtures]
[uxbox.migrations] [uxbox.migrations]
[uxbox.media] [uxbox.media]
[uxbox.media-storage] [uxbox.media-storage]

View file

@ -4,7 +4,7 @@ LABEL maintainer="Andrey Antukh <niwi@niwi.nz>"
ARG DEBIAN_FRONTEND=noninteractive ARG DEBIAN_FRONTEND=noninteractive
ENV NODE_VERSION=v12.18.3 \ ENV NODE_VERSION=v12.18.3 \
CLOJURE_VERSION=1.10.1.619 \ CLOJURE_VERSION=1.10.1.641 \
LANG=en_US.UTF-8 \ LANG=en_US.UTF-8 \
LC_ALL=C.UTF-8 LC_ALL=C.UTF-8

View file

@ -89,29 +89,39 @@ additional tasks.
### Frontend ### ### Frontend ###
The frontend build process and the http server is located on the tmux The frontend build process is located on the tmux **window 1**.
**window 1**. **Shadow-cljs** is used for build and serve the frontend **Shadow-cljs** is used for build and serve the frontend code. For
code. For more information, please refer to `02-Frontend-Developer-Guide.md`. more information, please refer to `02-Frontend-Developer-Guide.md`.
By default the **window 1** executes the shadow-cljs watch process, that starts By default the **window 1** executes the shadow-cljs watch process,
a new JVM/Clojure instance if there is no one running. But you may also execute that starts a new JVM/Clojure instance if there is no one running.
`shadow-cljs server`, that starts only the instance. And then, open another
window with `Ctrl+c` and execute `shadow-cljs watch main` there. This way, the
process that watches and recompiles connects to it and it restarts faster when
your code changes.
Finally, you can start a REPL linked to the instance and the current connected Finally, you can start a REPL linked to the instance and the current
browser, by opening a third window with `Ctrl+c` and running connected browser, by opening a third window with `Ctrl+c` and running
`shadow-cljs cljs-repl main`. `npx shadow-cljs cljs-repl main`.
### Exporter ###
The exporter app (clojurescript app running in nodejs) is located in
**window 2**, and you can go directly to it using `ctrl+b 2` shortcut.
There you will found the window split in two slices. On the top slice
you will have the build process (using shadow-cljs in the same way as
frontend application), and on the bot slice the script that launeches
the node process.
If some reason scripts does not stars correctly, you can manually
execute `node target/app.js ` to start the exporter app.
### Backend ### ### Backend ###
The backend related environment is located in the tmux **window 2**, The backend related environment is located in the tmux **window 3**,
and you can go directly to it using `ctrl+b 2` shortcut. and you can go directly to it using `ctrl+b 2` shortcut.
By default the backend will be started in non-interactive mode for By default the backend will be started in non-interactive mode for
convenience but you can just press `Ctrl+c` and execute `./bin/repl` convenience but you can just press `Ctrl+c` and execute `./scripts/repl`
for start the repl. for start the repl.
On the REPL you have this helper functions: On the REPL you have this helper functions:

View file

@ -3,6 +3,7 @@
This guide intends to explain the essential details of the frontend This guide intends to explain the essential details of the frontend
application. application.
## Access to clojure from javascript console ## Access to clojure from javascript console
The uxbox namespace of the main application is exported, so that is The uxbox namespace of the main application is exported, so that is
@ -15,6 +16,7 @@ console (there is autocompletion for help):
uxbox.main.store.emit_BANG_(uxbox.main.data.workspace.reset_zoom) uxbox.main.store.emit_BANG_(uxbox.main.data.workspace.reset_zoom)
``` ```
## Visual debug mode and utilities ## Visual debug mode and utilities
Debugging a problem in the viewport algorithms for grouping and Debugging a problem in the viewport algorithms for grouping and
@ -37,6 +39,7 @@ uxbox.util.debug.debug_all()
uxbox.util.debug.debug_none() uxbox.util.debug.debug_none()
``` ```
## Debug state and objects ## Debug state and objects
There are also some useful functions to visualize the global state or There are also some useful functions to visualize the global state or

View file

@ -11,12 +11,12 @@ good amount of content (usually used for just test the application or
perform performance tweaks on queries). perform performance tweaks on queries).
In order to load fixtures, enter to the REPL environment executing the In order to load fixtures, enter to the REPL environment executing the
`bin/repl` script, and then execute `(uxbox.fixtures/run :small)`. `bin/repl` script, and then execute `(uxbox.fixtures/run {:preset :small})`.
You also can execute this as a standalone script with: You also can execute this as a standalone script with:
```bash ```bash
clojure -Adev -m uxbox.fixtures clojure -Adev -X:fn-fixtures
``` ```
NOTE: It is an optional step because the application can start with an NOTE: It is an optional step because the application can start with an
@ -37,3 +37,11 @@ from there:
(require 'uxbox.fixtures) (require 'uxbox.fixtures)
(uxbox.fixtures/run :small) (uxbox.fixtures/run :small)
``` ```
To access to the running process repl you usually will execute this
command:
```bash
rlwrap netcat localhost 5555
```

View file

@ -22,7 +22,7 @@ This is a probably incomplete list of available options (with
respective defaults): respective defaults):
- `UXBOX_HTTP_SERVER_PORT=6060` - `UXBOX_HTTP_SERVER_PORT=6060`
- `UXBOX_PUBLIC_URI=http://localhost:3449/` - `UXBOX_PUBLIC_URI=http://localhost:3449`
- `UXBOX_DATABASE_USERNAME=` (default undefined, used from uri) - `UXBOX_DATABASE_USERNAME=` (default undefined, used from uri)
- `UXBOX_DATABASE_PASSWORD=` (default undefined, used from uri) - `UXBOX_DATABASE_PASSWORD=` (default undefined, used from uri)
- `UXBOX_DATABASE_URI=postgresql://127.0.0.1/uxbox` - `UXBOX_DATABASE_URI=postgresql://127.0.0.1/uxbox`
@ -57,6 +57,7 @@ respective defaults):
- `UXBOX_LDAP_AUTH_FULLNAME_ATTRIBUTE=displayName` - `UXBOX_LDAP_AUTH_FULLNAME_ATTRIBUTE=displayName`
- `UXBOX_LDAP_AUTH_AVATAR_ATTRIBUTE=jpegPhoto` - `UXBOX_LDAP_AUTH_AVATAR_ATTRIBUTE=jpegPhoto`
## REPL ## ## REPL ##
The production environment by default starts a server REPL where you The production environment by default starts a server REPL where you
@ -95,12 +96,12 @@ has all the material design icon collections).
Then, you need to execute: Then, you need to execute:
```bash ```bash
clojure -Adev -m uxbox.media-loader ../path/to/config.edn clojure -Adev -X:fn-media-loader :path ../path/to/config.edn
``` ```
If you have a REPL access to the running process, you can execute it from there: If you have a REPL access to the running process, you can execute it from there:
```clojure ```clojure
(require 'uxbox.media-loader) (require 'uxbox.media-loader)
@(uxbox.media-loader/run "/path/to/config.edn") (uxbox.media-loader/run* "/path/to/config.edn")
``` ```