mirror of
https://github.com/penpot/penpot.git
synced 2025-08-07 14:38:33 +02:00
Merge pull request #118 from uxbox/devenv-improvements
Docker/Devenv Improvements
This commit is contained in:
commit
c9d7de4022
17 changed files with 228 additions and 471 deletions
86
README.md
86
README.md
|
@ -30,25 +30,27 @@ editable in many other vector tools and easy to use on the web.
|
||||||
|
|
||||||
### Introduction ###
|
### Introduction ###
|
||||||
|
|
||||||
The development environment consists in a docker container that mounts
|
The main development environment consists in a docker compose
|
||||||
your local copy of the uxbox souce code directory tree and executes a
|
configuration that starts the external services and the development
|
||||||
tmux inside the container in order to facilitate execute multiple
|
container (called **devenv**).
|
||||||
processes inside.
|
|
||||||
|
We use tmux script in order to multiplex the signle terminal and run
|
||||||
|
both the backend and frontend in the same container.
|
||||||
|
|
||||||
|
|
||||||
### System requirements ###
|
### System requirements ###
|
||||||
|
|
||||||
You should have `docker` installed in your system in order to set up
|
You should have `docker` and `docker-compose` installed in your system
|
||||||
properly the uxbox development enviroment.
|
in order to set up properly the uxbox development enviroment.
|
||||||
|
|
||||||
In debian like linux distributions you can install it executing:
|
In debian like linux distributions you can install it executing:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
sudo apt-get install docker
|
sudo apt-get install docker docker-compose
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
### Start the docker container ###
|
### Start the devenv ###
|
||||||
|
|
||||||
**Requires a minimum knowledge of tmux usage in order to use that
|
**Requires a minimum knowledge of tmux usage in order to use that
|
||||||
development environment.**
|
development environment.**
|
||||||
|
@ -61,10 +63,9 @@ For start it, staying in this repository, execute:
|
||||||
|
|
||||||
This will do the following:
|
This will do the following:
|
||||||
|
|
||||||
- Build the image if it is not done before.
|
- Build the images if it is not done before.
|
||||||
- Download all repositories if them are not downloaded previously.
|
- Starts all the containers in the background.
|
||||||
- Start a container with predefined tmux layout.
|
- Attaches to the **devenv** container and executes the tmux session.
|
||||||
- Start all needed processes such as gulp and figwheel.
|
|
||||||
|
|
||||||
|
|
||||||
### First steps with tmux ###
|
### First steps with tmux ###
|
||||||
|
@ -82,36 +83,37 @@ current window.
|
||||||
|
|
||||||
#### UI ####
|
#### UI ####
|
||||||
|
|
||||||
The UI related tasks starts automatically so you do not need do anything. The
|
The UI related tasks starts automatically so you do not need do
|
||||||
**window 0** and **window 1** are used for the UI related environment.
|
anything. The **window 0** and **window 1** are used for the UI
|
||||||
|
related environment.
|
||||||
|
|
||||||
|
|
||||||
#### Backend ####
|
#### Backend ####
|
||||||
|
|
||||||
The backend related environment is located in the **window 2**, and you can go
|
The backend related environment is located in the **window 2**, and
|
||||||
directly to it using `ctrl+b 2` shortcut.
|
you can go directly to it using `ctrl+b 2` shortcut.
|
||||||
|
|
||||||
By default this tasks are performed:
|
By default the clojure repl will be executed, waiting you to run
|
||||||
|
commands or start the http server.
|
||||||
- Start postgresql.
|
|
||||||
- Load initial fixtures into the database.
|
|
||||||
|
|
||||||
The repl should be started automatically, if not, you can execute:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
clojure -Adev:repl
|
|
||||||
```
|
|
||||||
|
|
||||||
Then use `(start)` to start all the environment, `(stop)` for stoping
|
Then use `(start)` to start all the environment, `(stop)` for stoping
|
||||||
it and `(reset)` for restart with code reloading. If some exception is
|
it and `(reset)` for restart with code reloading. If some exception is
|
||||||
raised when code is reloaded, just use `(refresh)` in order to finish
|
raised when code is reloaded, just use `(repl/refresh)` in order to finish
|
||||||
correctly the code swaping and later use `(reset)` again.
|
correctly the code swaping and later use `(reset)` again.
|
||||||
|
|
||||||
|
If this is your first run, you maybe want to load fixtures first. Then
|
||||||
|
you can done this in two ways:
|
||||||
|
|
||||||
|
- In the same repl, require the `uxbox.fixtures` namespace and execute
|
||||||
|
`(uxbox.fixtures/-main [])`.
|
||||||
|
- Stop the repl with `Ctrl+c` and then execute `clojure -Adev -m
|
||||||
|
uxbox.fixtures`; then start the repl again with `clojure -Adev:repl`.
|
||||||
|
|
||||||
|
|
||||||
## Production (Docker)
|
## Production (Docker)
|
||||||
|
|
||||||
Docker is also used to build release images for backend and
|
Docker is also used to build release images for backend and
|
||||||
frontend. Use the helper script `manage.sh` to build the images. You
|
frontend. Use the helper script `manage.sh` to build the images. You
|
||||||
can run locally UXBOX through a docker-compose or by manually running
|
can run locally UXBOX through a docker-compose or by manually running
|
||||||
the containers.
|
the containers.
|
||||||
|
|
||||||
|
@ -129,35 +131,16 @@ uploads, etc). The docker daemon will store that data within the
|
||||||
docker directory `/var/lib/docker/volumes/...`. That means your data
|
docker directory `/var/lib/docker/volumes/...`. That means your data
|
||||||
is saved even if the container crashes, is stopped or deleted.
|
is saved even if the container crashes, is stopped or deleted.
|
||||||
|
|
||||||
To make your data persistent to upgrading and get access for backups
|
The default production docker-compose already handles it for you,
|
||||||
is using named docker volume or mount a host folder. To achieve this
|
but if you. So check the `docker/docker-compose.yml` file.
|
||||||
you need one volume for your database container.
|
|
||||||
|
|
||||||
Database:
|
|
||||||
- `/var/lib/postgresql/data` PostgreSQL Data
|
|
||||||
```console
|
|
||||||
$ docker run -d \
|
|
||||||
-v db:/var/lib/postgresql/data \
|
|
||||||
postgresql
|
|
||||||
```
|
|
||||||
|
|
||||||
You also need to persist the UXBOX backend public resources (media and
|
|
||||||
assets) to not lose images uploaded and allow the frontend to expose
|
|
||||||
assets.
|
|
||||||
|
|
||||||
- `/srv/uxbox/resources/public` UXBOX backend public resources
|
|
||||||
|
|
||||||
```console
|
|
||||||
$ docker run -d \
|
|
||||||
-v db:/srv/uxbox/resources/public \
|
|
||||||
monogramm/docker-uxbox-backend
|
|
||||||
```
|
|
||||||
|
|
||||||
### Auto configuration via environment variables
|
### Auto configuration via environment variables
|
||||||
|
|
||||||
The following environment variables are also honored for configuring
|
The following environment variables are also honored for configuring
|
||||||
your UXBOX instance:
|
your UXBOX instance:
|
||||||
|
|
||||||
|
|
||||||
#### Frontend
|
#### Frontend
|
||||||
|
|
||||||
**Only available at build time!**
|
**Only available at build time!**
|
||||||
|
@ -205,6 +188,7 @@ Available at runtime:
|
||||||
variables or the backend might try to interpret the values as symbols
|
variables or the backend might try to interpret the values as symbols
|
||||||
and have weird issues.
|
and have weird issues.
|
||||||
|
|
||||||
|
|
||||||
## Collections import
|
## Collections import
|
||||||
|
|
||||||
You can easily import icons and images as global stores with the
|
You can easily import icons and images as global stores with the
|
||||||
|
@ -243,6 +227,7 @@ clojure -Adev -m uxbox.cli.collimp ../media/config.edn
|
||||||
|
|
||||||
Take a look at the `sample_media` directory for a sample configuration.
|
Take a look at the `sample_media` directory for a sample configuration.
|
||||||
|
|
||||||
|
|
||||||
## Contributing ##
|
## Contributing ##
|
||||||
|
|
||||||
**Open to you!**
|
**Open to you!**
|
||||||
|
@ -253,6 +238,7 @@ and improve UXBOX. All your awesome ideas and code are welcome!
|
||||||
|
|
||||||
Please refer to the [Contributing Guide](./CONTRIBUTING.md)
|
Please refer to the [Contributing Guide](./CONTRIBUTING.md)
|
||||||
|
|
||||||
|
|
||||||
## License ##
|
## License ##
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
set -x
|
set -xe
|
||||||
|
sudo pg_ctlcluster 11 main start;
|
||||||
clj -Adev -m uxbox.tests.main
|
clojure -Adev -m uxbox.tests.main;
|
||||||
|
|
|
@ -126,7 +126,7 @@
|
||||||
(s/keys :req-un [::id]))
|
(s/keys :req-un [::id]))
|
||||||
|
|
||||||
(s/def ::retrieve-page-history|query
|
(s/def ::retrieve-page-history|query
|
||||||
(s/keys :req-un [::max
|
(s/keys :opt-un [::max
|
||||||
::since
|
::since
|
||||||
::pinned]))
|
::pinned]))
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
|
|
||||||
(s/def ::id ::us/uuid)
|
(s/def ::id ::us/uuid)
|
||||||
(s/def ::name string?)
|
(s/def ::name string?)
|
||||||
(s/def ::version (s/and int? pos?))
|
(s/def ::version int?)
|
||||||
|
|
||||||
;; --- List Projects
|
;; --- List Projects
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
(ns uxbox.http.middleware
|
(ns uxbox.http.middleware
|
||||||
(:require
|
(:require
|
||||||
[clojure.spec.alpha :as s]
|
[clojure.spec.alpha :as s]
|
||||||
|
[clojure.java.io :as io]
|
||||||
[cuerdas.core :as str]
|
[cuerdas.core :as str]
|
||||||
[promesa.core :as p]
|
[promesa.core :as p]
|
||||||
[reitit.ring :as rr]
|
[reitit.ring :as rr]
|
||||||
|
@ -208,7 +209,7 @@
|
||||||
|
|
||||||
(def format-response-middleware
|
(def format-response-middleware
|
||||||
(letfn [(process-response [{:keys [body] :as rsp}]
|
(letfn [(process-response [{:keys [body] :as rsp}]
|
||||||
(if body
|
(if (coll? body)
|
||||||
(let [body (t/encode body {:type :json-verbose})]
|
(let [body (t/encode body {:type :json-verbose})]
|
||||||
(-> rsp
|
(-> rsp
|
||||||
(assoc :body body)
|
(assoc :body body)
|
||||||
|
@ -226,11 +227,24 @@
|
||||||
(letfn [(get-content-type [request]
|
(letfn [(get-content-type [request]
|
||||||
(or (:content-type request)
|
(or (:content-type request)
|
||||||
(get (:headers request) "content-type")))
|
(get (:headers request) "content-type")))
|
||||||
|
|
||||||
|
(slurp-bytes [body]
|
||||||
|
(with-open [input (io/input-stream body)
|
||||||
|
output (java.io.ByteArrayOutputStream. (.available input))]
|
||||||
|
(io/copy input output)
|
||||||
|
(.toByteArray output)))
|
||||||
|
|
||||||
|
(parse-body [body]
|
||||||
|
(let [^bytes body (slurp-bytes body)]
|
||||||
|
(when (pos? (alength body))
|
||||||
|
(t/decode body))))
|
||||||
|
|
||||||
(process-request [request]
|
(process-request [request]
|
||||||
(let [ctype (get-content-type request)]
|
(let [ctype (get-content-type request)]
|
||||||
(if (= "application/transit+json" ctype)
|
(if (= "application/transit+json" ctype)
|
||||||
(try
|
(try
|
||||||
(assoc request :body-params (t/decode (:body request)))
|
(let [body (parse-body (:body request))]
|
||||||
|
(assoc request :body-params body))
|
||||||
(catch Exception e
|
(catch Exception e
|
||||||
(ex/raise :type :parse
|
(ex/raise :type :parse
|
||||||
:message "Unable to parse transit from request body."
|
:message "Unable to parse transit from request body."
|
||||||
|
@ -243,11 +257,11 @@
|
||||||
([request]
|
([request]
|
||||||
(handler (process-request request)))
|
(handler (process-request request)))
|
||||||
([request respond raise]
|
([request respond raise]
|
||||||
(try
|
(let [^HttpInput body (:body request)]
|
||||||
(let [request (process-request request)]
|
(try
|
||||||
(handler request respond raise))
|
(handler (process-request request) respond raise)
|
||||||
(catch Exception e
|
(catch Exception e
|
||||||
(raise e))))))}))
|
(raise e)))))))}))
|
||||||
|
|
||||||
(def middleware
|
(def middleware
|
||||||
[cors-middleware
|
[cors-middleware
|
||||||
|
|
|
@ -49,17 +49,28 @@
|
||||||
|
|
||||||
;; --- High-Level Api
|
;; --- High-Level Api
|
||||||
|
|
||||||
|
;; TODO: check performance of different options
|
||||||
|
|
||||||
(defn decode
|
(defn decode
|
||||||
([data]
|
([data]
|
||||||
(decode data nil))
|
(decode data nil))
|
||||||
([data opts]
|
([data opts]
|
||||||
(with-open [input (io/input-stream data)]
|
(cond
|
||||||
(read! (reader input opts)))))
|
(string? data)
|
||||||
|
(decode (.getBytes data "UTF-8") opts)
|
||||||
|
|
||||||
|
(bytes? data)
|
||||||
|
(with-open [input (ByteArrayInputStream. data)]
|
||||||
|
(read! (reader input opts)))
|
||||||
|
|
||||||
|
:else
|
||||||
|
(with-open [input (io/input-stream data)]
|
||||||
|
(read! (reader input opts))))))
|
||||||
|
|
||||||
(defn encode
|
(defn encode
|
||||||
([data]
|
(^bytes [data]
|
||||||
(encode data nil))
|
(encode data nil))
|
||||||
([data opts]
|
(^bytes [data opts]
|
||||||
(with-open [out (ByteArrayOutputStream.)]
|
(with-open [out (ByteArrayOutputStream.)]
|
||||||
(let [w (writer out opts)]
|
(let [w (writer out opts)]
|
||||||
(write! w data)
|
(write! w data)
|
||||||
|
|
|
@ -43,7 +43,7 @@
|
||||||
(let [uri (str th/+base-url+ "/api/projects/" (:id proj))
|
(let [uri (str th/+base-url+ "/api/projects/" (:id proj))
|
||||||
params {:body (assoc proj :name "proj2")}
|
params {:body (assoc proj :name "proj2")}
|
||||||
[status data] (th/http-put user uri params)]
|
[status data] (th/http-put user uri params)]
|
||||||
(prn "RESPONSE:" status data)
|
;; (prn "RESPONSE:" status data)
|
||||||
(t/is (= 200 status))
|
(t/is (= 200 status))
|
||||||
(t/is (= (:user data) (:id user)))
|
(t/is (= (:user data) (:id user)))
|
||||||
(t/is (= (:name data) "proj2")))))))
|
(t/is (= (:name data) "proj2")))))))
|
||||||
|
@ -55,6 +55,7 @@
|
||||||
(th/with-server {:handler @http/app}
|
(th/with-server {:handler @http/app}
|
||||||
(let [uri (str th/+base-url+ "/api/projects/" (:id proj))
|
(let [uri (str th/+base-url+ "/api/projects/" (:id proj))
|
||||||
[status data] (th/http-delete user uri)]
|
[status data] (th/http-delete user uri)]
|
||||||
|
;; (prn "RESPONSE:" status data)
|
||||||
(t/is (= 204 status))
|
(t/is (= 204 status))
|
||||||
(let [sqlv ["SELECT * FROM projects WHERE \"user\"=? AND deleted_at is null"
|
(let [sqlv ["SELECT * FROM projects WHERE \"user\"=? AND deleted_at is null"
|
||||||
(:id user)]
|
(:id user)]
|
||||||
|
|
|
@ -2,6 +2,7 @@ FROM ubuntu:bionic
|
||||||
LABEL maintainer="Andrey Antukh <niwi@niwi.nz>"
|
LABEL maintainer="Andrey Antukh <niwi@niwi.nz>"
|
||||||
|
|
||||||
ARG EXTERNAL_UID=1000
|
ARG EXTERNAL_UID=1000
|
||||||
|
ARG DEBIAN_FRONTEND=noninteractive
|
||||||
|
|
||||||
ENV NODE_VERSION=v10.16.3 \
|
ENV NODE_VERSION=v10.16.3 \
|
||||||
CLOJURE_VERSION=1.10.1.469 \
|
CLOJURE_VERSION=1.10.1.469 \
|
||||||
|
@ -37,7 +38,6 @@ RUN set -ex; \
|
||||||
echo "deb http://repos.azulsystems.com/ubuntu stable main" >> /etc/apt/sources.list.d/zulu.list; \
|
echo "deb http://repos.azulsystems.com/ubuntu stable main" >> /etc/apt/sources.list.d/zulu.list; \
|
||||||
echo "deb http://apt.postgresql.org/pub/repos/apt/ bionic-pgdg main" >> /etc/apt/sources.list.d/postgresql.list;
|
echo "deb http://apt.postgresql.org/pub/repos/apt/ bionic-pgdg main" >> /etc/apt/sources.list.d/postgresql.list;
|
||||||
|
|
||||||
ARG DEBIAN_FRONTEND=noninteractive
|
|
||||||
|
|
||||||
RUN set -ex; \
|
RUN set -ex; \
|
||||||
apt-get -qq update; \
|
apt-get -qq update; \
|
||||||
|
@ -86,9 +86,10 @@ RUN set -ex; \
|
||||||
COPY files/bashrc /home/uxbox/.bashrc
|
COPY files/bashrc /home/uxbox/.bashrc
|
||||||
COPY files/zshrc /home/uxbox/.zshrc
|
COPY files/zshrc /home/uxbox/.zshrc
|
||||||
COPY files/vimrc /home/uxbox/.vimrc
|
COPY files/vimrc /home/uxbox/.vimrc
|
||||||
COPY files/start.sh /home/uxbox/start-tmux.sh
|
COPY files/start.sh /home/uxbox/start.sh
|
||||||
COPY files/tmux.conf /home/uxbox/.tmux.conf
|
COPY files/tmux.conf /home/uxbox/.tmux.conf
|
||||||
COPY files/entrypoint.sh /home/uxbox/
|
COPY files/entrypoint.sh /home/uxbox/
|
||||||
|
COPY files/init.sh /home/uxbox/
|
||||||
|
|
||||||
ENTRYPOINT ["zsh", "/home/uxbox/entrypoint.sh"]
|
ENTRYPOINT ["zsh", "/home/uxbox/entrypoint.sh"]
|
||||||
CMD ["/home/uxbox/start-tmux.sh"]
|
CMD ["/home/uxbox/start.sh"]
|
||||||
|
|
55
docker/devenv/docker-compose.yaml
Normal file
55
docker/devenv/docker-compose.yaml
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
version: '3'
|
||||||
|
|
||||||
|
networks:
|
||||||
|
default:
|
||||||
|
driver: bridge
|
||||||
|
ipam:
|
||||||
|
config:
|
||||||
|
- subnet: 172.177.09.0/24
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
postgres_data:
|
||||||
|
user_data:
|
||||||
|
|
||||||
|
services:
|
||||||
|
uxbox:
|
||||||
|
privileged: true
|
||||||
|
build:
|
||||||
|
context: ./
|
||||||
|
hostname: 'uxbox-devenv'
|
||||||
|
container_name: 'uxbox-devenv'
|
||||||
|
command: "/home/uxbox/init.sh"
|
||||||
|
stop_signal: SIGINT
|
||||||
|
depends_on:
|
||||||
|
- postgres
|
||||||
|
volumes:
|
||||||
|
- "user_data:/home/uxbox/local"
|
||||||
|
- "${PWD}:/home/uxbox/uxbox"
|
||||||
|
- "${HOME}/.m2:/home/uxbox/.m2"
|
||||||
|
- "${HOME}/.gitconfig:/home/uxbox/.gitconfig"
|
||||||
|
|
||||||
|
ports:
|
||||||
|
- 3449:3449
|
||||||
|
- 6060:6060
|
||||||
|
|
||||||
|
environment:
|
||||||
|
- UXBOX_HTTP_SERVER_DEBUG=false
|
||||||
|
- UXBOX_DATABASE_URI="jdbc:postgresql://postgres/uxbox"
|
||||||
|
- UXBOX_DATABASE_USERNAME="uxbox"
|
||||||
|
- UXBOX_DATABASE_PASSWORD="uxbox_postgres_password"
|
||||||
|
|
||||||
|
postgres:
|
||||||
|
image: postgres:11
|
||||||
|
hostname: 'uxbox-devenv-postgres'
|
||||||
|
container_name: 'uxbox-devenv-postgres'
|
||||||
|
restart: always
|
||||||
|
stop_signal: SIGINT
|
||||||
|
ports:
|
||||||
|
- 5432:5432
|
||||||
|
environment:
|
||||||
|
- POSTGRES_INITDB_ARGS="--data-checksums"
|
||||||
|
- POSTGRES_DB=uxbox
|
||||||
|
- POSTGRES_USER=uxbox
|
||||||
|
- POSTGRES_PASSWORD=uxbox_postgres_password
|
||||||
|
volumes:
|
||||||
|
- postgres_data:/var/lib/postgresql/data
|
|
@ -1,5 +1,3 @@
|
||||||
#!/usr/bin/env zsh
|
#!/usr/bin/env zsh
|
||||||
set -ex
|
set -ex
|
||||||
sudo pg_ctlcluster 11 main start
|
|
||||||
|
|
||||||
exec "$@"
|
exec "$@"
|
||||||
|
|
8
docker/devenv/files/init.sh
Executable file
8
docker/devenv/files/init.sh
Executable file
|
@ -0,0 +1,8 @@
|
||||||
|
#!/usr/bin/env zsh
|
||||||
|
set -e;
|
||||||
|
|
||||||
|
echo "[init.sh] Setting up local permissions."
|
||||||
|
sudo chown -R uxbox /home/uxbox/local
|
||||||
|
|
||||||
|
echo "[init.sh] Ready!"
|
||||||
|
tail -f /dev/null
|
|
@ -10,7 +10,7 @@ tmux send-keys -t uxbox 'clojure -Adev tools.clj figwheel' enter
|
||||||
tmux new-window -t uxbox:2 -n 'backend'
|
tmux new-window -t uxbox:2 -n 'backend'
|
||||||
tmux select-window -t uxbox:2
|
tmux select-window -t uxbox:2
|
||||||
tmux send-keys -t uxbox 'cd uxbox/backend' enter C-l
|
tmux send-keys -t uxbox 'cd uxbox/backend' enter C-l
|
||||||
tmux send-keys -t uxbox 'clojure -Adev -m uxbox.fixtures' enter C-l
|
# tmux send-keys -t uxbox 'clojure -Adev -m uxbox.fixtures' enter C-l
|
||||||
tmux send-keys -t uxbox 'clojure -Adev:repl' enter
|
tmux send-keys -t uxbox 'clojure -Adev:repl' enter
|
||||||
|
|
||||||
tmux rename-window -t uxbox:0 'gulp'
|
tmux rename-window -t uxbox:0 'gulp'
|
||||||
|
|
|
@ -47,7 +47,7 @@ setopt NOBEEP
|
||||||
setopt INC_APPEND_HISTORY
|
setopt INC_APPEND_HISTORY
|
||||||
export HISTSIZE=100000
|
export HISTSIZE=100000
|
||||||
export SAVEHIST=100000
|
export SAVEHIST=100000
|
||||||
export HISTFILE=~/.zhistory
|
export HISTFILE=~/local/.zhistory
|
||||||
setopt hist_ignore_all_dups
|
setopt hist_ignore_all_dups
|
||||||
setopt hist_ignore_space
|
setopt hist_ignore_space
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,5 @@ source ~/.bashrc
|
||||||
set -ex;
|
set -ex;
|
||||||
|
|
||||||
npm ci
|
npm ci
|
||||||
|
clojure -Adev tools.clj build:tests
|
||||||
clojure -Adev tools.clj build-tests
|
|
||||||
|
|
||||||
node ./target/tests/main
|
node ./target/tests/main
|
||||||
|
|
|
@ -179,109 +179,6 @@
|
||||||
(t/is (= result expected))
|
(t/is (= result expected))
|
||||||
(t/is (vector? (get-in result [:pages 1 :shapes])))))
|
(t/is (vector? (get-in result [:pages 1 :shapes])))))
|
||||||
|
|
||||||
;; drop shape: move shape outside of group
|
|
||||||
|
|
||||||
(t/deftest drop-shape-test5
|
|
||||||
(let [initial {:workspace {:selected #{1}}
|
|
||||||
:pages {1 {:id 1 :shapes [1 3]}}
|
|
||||||
:shapes {1 {:id 1 :page 1 :type :group :items [2]}
|
|
||||||
2 {:id 2 :page 1 :group 1}
|
|
||||||
3 {:id 3 :page 1}}}
|
|
||||||
expected {:workspace {:selected #{}}
|
|
||||||
:pages {1 {:id 1, :shapes [3 2]}},
|
|
||||||
:shapes {2 {:id 2, :page 1},
|
|
||||||
3 {:id 3, :page 1}}}
|
|
||||||
result (impl/drop-shape initial 2 3 :after)]
|
|
||||||
;; (pprint expected)
|
|
||||||
;; (pprint result)
|
|
||||||
(t/is (= result expected))
|
|
||||||
(t/is (vector? (get-in result [:pages 1 :shapes])))))
|
|
||||||
|
|
||||||
;; drop shape: move group inside group
|
|
||||||
|
|
||||||
(t/deftest drop-shape-test6
|
|
||||||
(let [initial {:pages {1 {:id 1 :shapes [1 2]}}
|
|
||||||
:shapes {1 {:id 1 :page 1 :type :group :items [3]}
|
|
||||||
2 {:id 2 :page 1 :type :group :items [4]}
|
|
||||||
3 {:id 3 :page 1 :group 1}
|
|
||||||
4 {:id 4 :page 1 :group 2}}}
|
|
||||||
expected {:pages {1 {:id 1, :shapes [1]}},
|
|
||||||
:shapes {1 {:id 1, :page 1, :type :group, :items [3 2]},
|
|
||||||
2 {:id 2, :page 1, :type :group, :items [4], :group 1},
|
|
||||||
3 {:id 3, :page 1, :group 1},
|
|
||||||
4 {:id 4, :page 1, :group 2}}}
|
|
||||||
result (impl/drop-shape initial 2 3 :after)]
|
|
||||||
;; (pprint expected)
|
|
||||||
;; (pprint result)
|
|
||||||
(t/is (= result expected))
|
|
||||||
(t/is (vector? (get-in result [:pages 1 :shapes])))))
|
|
||||||
|
|
||||||
;; drop shape: move group outside group
|
|
||||||
|
|
||||||
(t/deftest drop-shape-test7
|
|
||||||
(let [initial {:workspace {:selected #{}}
|
|
||||||
:pages {1 {:id 1 :shapes [1 3]}}
|
|
||||||
:shapes {1 {:id 1 :page 1 :type :group :items [2]}
|
|
||||||
2 {:id 2 :page 1 :group 1 :type :group :items [4]}
|
|
||||||
3 {:id 3 :page 1}
|
|
||||||
4 {:id 4 :page 1 :group 2}}}
|
|
||||||
|
|
||||||
expected {:workspace {:selected #{}},
|
|
||||||
:pages {1 {:id 1, :shapes [2 3]}},
|
|
||||||
:shapes {2 {:id 2, :page 1, :type :group, :items [4]},
|
|
||||||
3 {:id 3, :page 1},
|
|
||||||
4 {:id 4, :page 1, :group 2}}}
|
|
||||||
result (impl/drop-shape initial 2 1 :after)]
|
|
||||||
;; (pprint expected)
|
|
||||||
;; (pprint result)
|
|
||||||
(t/is (= result expected))
|
|
||||||
(t/is (vector? (get-in result [:pages 1 :shapes])))))
|
|
||||||
|
|
||||||
;; drop shape: move shape to neested group
|
|
||||||
|
|
||||||
(t/deftest drop-shape-test8
|
|
||||||
(let [initial {:pages {1 {:id 1 :shapes [1 5 6]}}
|
|
||||||
:shapes {1 {:id 1 :page 1 :type :group :items [2]}
|
|
||||||
2 {:id 2 :page 1 :type :group :group 1 :items [3 4]}
|
|
||||||
3 {:id 3 :page 1 :group 2}
|
|
||||||
4 {:id 4 :page 1 :group 2}
|
|
||||||
5 {:id 5 :page 1}
|
|
||||||
6 {:id 6 :page 1}}}
|
|
||||||
|
|
||||||
expected {:pages {1 {:id 1, :shapes [1 5]}},
|
|
||||||
:shapes {1 {:id 1, :page 1, :type :group, :items [2]},
|
|
||||||
2 {:id 2, :page 1, :type :group, :group 1, :items [3 4 6]},
|
|
||||||
3 {:id 3, :page 1, :group 2},
|
|
||||||
4 {:id 4, :page 1, :group 2},
|
|
||||||
5 {:id 5, :page 1},
|
|
||||||
6 {:id 6, :page 1, :group 2}}}
|
|
||||||
result (impl/drop-shape initial 6 4 :after)]
|
|
||||||
;; (pprint expected)
|
|
||||||
;; (pprint result)
|
|
||||||
(t/is (= result expected))))
|
|
||||||
|
|
||||||
;; drop shape: move shape to neested group
|
|
||||||
|
|
||||||
(t/deftest drop-shape-test9
|
|
||||||
(let [initial {:pages {1 {:id 1 :shapes [1]}}
|
|
||||||
:shapes {1 {:id 1 :page 1 :type :group :items [2 5 6]}
|
|
||||||
2 {:id 2 :page 1 :type :group :group 1 :items [3 4]}
|
|
||||||
3 {:id 3 :page 1 :group 2}
|
|
||||||
4 {:id 4 :page 1 :group 2}
|
|
||||||
5 {:id 5 :page 1 :group 1}
|
|
||||||
6 {:id 6 :page 1 :group 1}}}
|
|
||||||
expected {:pages {1 {:id 1, :shapes [1]}},
|
|
||||||
:shapes {1 {:id 1, :page 1, :type :group, :items [2 5]},
|
|
||||||
2 {:id 2, :page 1, :type :group, :group 1, :items [3 4 6]},
|
|
||||||
3 {:id 3, :page 1, :group 2},
|
|
||||||
4 {:id 4, :page 1, :group 2},
|
|
||||||
5 {:id 5, :page 1, :group 1},
|
|
||||||
6 {:id 6, :page 1, :group 2}}}
|
|
||||||
result (impl/drop-shape initial 6 4 :after)]
|
|
||||||
;; (pprint expected)
|
|
||||||
;; (pprint result)
|
|
||||||
(t/is (= result expected))))
|
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
;; Delete Shape
|
;; Delete Shape
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
@ -306,244 +203,3 @@
|
||||||
;; (pprint expected)
|
;; (pprint expected)
|
||||||
;; (pprint result)
|
;; (pprint result)
|
||||||
(t/is (= result expected))))
|
(t/is (= result expected))))
|
||||||
|
|
||||||
;; delete shape: delete from group
|
|
||||||
|
|
||||||
(t/deftest delete-shape-test2
|
|
||||||
(let [initial {:workspace {:selected #{}}
|
|
||||||
:pages {1 {:id 1 :shapes [1 3 4]}}
|
|
||||||
:shapes {1 {:id 1 :page 1
|
|
||||||
:type :group
|
|
||||||
:items [2]}
|
|
||||||
2 {:id 2 :page 1 :group 1}
|
|
||||||
3 {:id 3 :page 1}
|
|
||||||
4 {:id 4 :page 1}}}
|
|
||||||
shape (get-in initial [:shapes 2])
|
|
||||||
expected {:workspace {:selected #{}}
|
|
||||||
:pages {1 {:id 1 :shapes [3 4]}}
|
|
||||||
:shapes {3 {:id 3 :page 1}
|
|
||||||
4 {:id 4 :page 1}}}
|
|
||||||
result (impl/dissoc-shape initial shape)]
|
|
||||||
;; (pprint expected)
|
|
||||||
;; (pprint result)
|
|
||||||
(t/is (= result expected))))
|
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
;; Group Shapes
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
|
|
||||||
;; group a shape
|
|
||||||
|
|
||||||
(t/deftest group-shapes-1
|
|
||||||
(let [initial {:pages {1 {:id 1 :shapes [1 2 3]}}
|
|
||||||
:shapes {1 {:id 1 :page 1}
|
|
||||||
2 {:id 2 :page 1}
|
|
||||||
3 {:id 3 :page 1}}}
|
|
||||||
|
|
||||||
expected {:pages {1 {:id 1 :shapes [1 4 3]}}
|
|
||||||
:shapes {1 {:id 1 :page 1}
|
|
||||||
2 {:id 2 :page 1 :group 4}
|
|
||||||
3 {:id 3 :page 1}
|
|
||||||
4 {:type :group :name "Group-1" :items [2] :id 4 :page 1}}
|
|
||||||
:workspace {:selected #{4}}}]
|
|
||||||
(with-redefs [uxbox.util.uuid/random (constantly 4)]
|
|
||||||
(let [result (impl/group-shapes initial [2] 1)]
|
|
||||||
;; (pprint expected)
|
|
||||||
;; (pprint result)
|
|
||||||
(t/is (= result expected))))))
|
|
||||||
|
|
||||||
;; group two shapes
|
|
||||||
|
|
||||||
(t/deftest group-shapes-2
|
|
||||||
(let [initial {:pages {1 {:id 1 :shapes [1 2 3]}}
|
|
||||||
:shapes {1 {:id 1 :page 1}
|
|
||||||
2 {:id 2 :page 1}
|
|
||||||
3 {:id 3 :page 1}}}
|
|
||||||
|
|
||||||
|
|
||||||
expected {:pages {1 {:id 1 :shapes [1 4]}}
|
|
||||||
:shapes {1 {:id 1 :page 1}
|
|
||||||
2 {:id 2 :page 1 :group 4}
|
|
||||||
3 {:id 3 :page 1 :group 4}
|
|
||||||
4 {:type :group :name "Group-1" :items [2 3] :id 4 :page 1}}
|
|
||||||
:workspace {:selected #{4}}}]
|
|
||||||
(with-redefs [uxbox.util.uuid/random (constantly 4)]
|
|
||||||
(let [result (impl/group-shapes initial [2 3] 1)]
|
|
||||||
;; (pprint expected)
|
|
||||||
;; (pprint result)
|
|
||||||
(t/is (= result expected))))))
|
|
||||||
|
|
||||||
;; group group
|
|
||||||
|
|
||||||
(t/deftest group-shapes-3
|
|
||||||
(let [initial {:pages {1 {:id 1 :shapes [1 2 3]}}
|
|
||||||
:shapes {1 {:id 1 :page 1}
|
|
||||||
2 {:id 2 :page 1}
|
|
||||||
3 {:id 3 :page 1 :type :group}}}
|
|
||||||
expected {:pages {1 {:id 1 :shapes [1 4]}}
|
|
||||||
:shapes {1 {:id 1 :page 1}
|
|
||||||
2 {:id 2 :page 1 :group 4}
|
|
||||||
3 {:id 3 :page 1 :type :group :group 4}
|
|
||||||
4 {:type :group :name "Group-1" :items [2 3] :id 4 :page 1}}
|
|
||||||
:workspace {:selected #{4}}}]
|
|
||||||
(with-redefs [uxbox.util.uuid/random (constantly 4)]
|
|
||||||
(let [result (impl/group-shapes initial [2 3] 1)]
|
|
||||||
;; (pprint expected)
|
|
||||||
;; (pprint result)
|
|
||||||
(t/is (= result expected))))))
|
|
||||||
|
|
||||||
;; group shapes inside a group
|
|
||||||
|
|
||||||
(t/deftest group-shapes-4
|
|
||||||
(let [initial {:pages {1 {:id 1 :shapes [1 3]}}
|
|
||||||
:shapes {1 {:id 1 :page 1}
|
|
||||||
2 {:id 2 :page 1 :group 3}
|
|
||||||
3 {:id 3 :page 1 :type :group}}}
|
|
||||||
|
|
||||||
expected {:pages {1 {:id 1 :shapes [1 3]}}
|
|
||||||
:shapes {1 {:id 1 :page 1}
|
|
||||||
2 {:id 2 :page 1 :group 4}
|
|
||||||
3 {:id 3 :page 1 :type :group :items [4]}
|
|
||||||
4 {:type :group
|
|
||||||
:name "Group-1"
|
|
||||||
:items [2]
|
|
||||||
:id 4
|
|
||||||
:page 1
|
|
||||||
:group 3}}
|
|
||||||
:workspace {:selected #{4}}}]
|
|
||||||
(with-redefs [uxbox.util.uuid/random (constantly 4)]
|
|
||||||
(let [result (impl/group-shapes initial [2] 1)]
|
|
||||||
;; (pprint expected)
|
|
||||||
;; (pprint result)
|
|
||||||
(t/is (= result expected))))))
|
|
||||||
|
|
||||||
;; group shapes in multiple groups
|
|
||||||
|
|
||||||
(t/deftest group-shapes-5
|
|
||||||
(let [initial {:pages {1 {:id 1 :shapes [3 4]}}
|
|
||||||
:shapes {1 {:id 1 :page 1 :group 4}
|
|
||||||
2 {:id 2 :page 1 :group 3}
|
|
||||||
3 {:id 3 :page 1 :type :group :items [2]}
|
|
||||||
4 {:id 4 :page 1 :type :group :imtes [3]}}}
|
|
||||||
|
|
||||||
expected (-> initial
|
|
||||||
(assoc-in [:workspace :selected] #{5})
|
|
||||||
(assoc-in [:pages 1 :shapes] [5])
|
|
||||||
(assoc-in [:shapes 1 :group] 5)
|
|
||||||
(assoc-in [:shapes 2 :group] 5)
|
|
||||||
(assoc-in [:shapes 5] {:type :group :name "Group-1"
|
|
||||||
:items [1 2] :id 5 :page 1})
|
|
||||||
(update-in [:shapes] dissoc 3)
|
|
||||||
(update-in [:shapes] dissoc 4))]
|
|
||||||
(with-redefs [uxbox.util.uuid/random (constantly 5)]
|
|
||||||
(let [result (impl/group-shapes initial [1 2] 1)]
|
|
||||||
;; (pprint expected)
|
|
||||||
;; (pprint result)
|
|
||||||
(t/is (= result expected))))))
|
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
;; Degroups
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
|
|
||||||
;; degroup a single group
|
|
||||||
|
|
||||||
(t/deftest degroup-shapes-1-0
|
|
||||||
(let [initial {:pages {1 {:id 1 :shapes [3]}}
|
|
||||||
:shapes {1 {:id 1 :page 1 :group 3}
|
|
||||||
2 {:id 2 :page 1 :group 3}
|
|
||||||
3 {:id 3 :page 1 :type :group :items [1 2]}}}
|
|
||||||
expected {:workspace {:selected #{1 2}}
|
|
||||||
:pages {1 {:id 1 :shapes [1 2]}}
|
|
||||||
:shapes {1 {:id 1 :page 1}
|
|
||||||
2 {:id 2 :page 1}}}]
|
|
||||||
(let [result (impl/degroup-shapes initial [3] 1)]
|
|
||||||
;; (pprint expected)
|
|
||||||
;; (pprint result)
|
|
||||||
(t/is (= result expected)))))
|
|
||||||
|
|
||||||
;; degroup single shape from group
|
|
||||||
|
|
||||||
(t/deftest degroup-shapes-1-1
|
|
||||||
(let [initial {:pages {1 {:id 1 :shapes [3]}}
|
|
||||||
:shapes {1 {:id 1 :page 1 :group 3}
|
|
||||||
2 {:id 2 :page 1 :group 3}
|
|
||||||
3 {:id 3 :page 1 :type :group :items [1 2]}}}
|
|
||||||
expected {:workspace {:selected #{1}}
|
|
||||||
:pages {1 {:id 1 :shapes [1 3]}}
|
|
||||||
:shapes {1 {:id 1 :page 1}
|
|
||||||
2 {:id 2 :page 1 :group 3}
|
|
||||||
3 {:id 3 :page 1 :type :group :items [2]}}}
|
|
||||||
result (impl/degroup-shapes initial [1] 1)]
|
|
||||||
;; (pprint expected)
|
|
||||||
;; (pprint result)
|
|
||||||
(t/is (= result expected))))
|
|
||||||
|
|
||||||
|
|
||||||
;; degroup all shapes from group
|
|
||||||
|
|
||||||
(t/deftest degroup-shapes-1-2
|
|
||||||
(let [initial {:pages {1 {:id 1 :shapes [3]}}
|
|
||||||
:shapes {1 {:id 1 :page 1 :group 3}
|
|
||||||
2 {:id 2 :page 1 :group 3}
|
|
||||||
3 {:id 3 :page 1 :type :group :items [1 2]}}}
|
|
||||||
expected {:workspace {:selected #{1 2}}
|
|
||||||
:pages {1 {:id 1 :shapes [1 2]}}
|
|
||||||
:shapes {1 {:id 1 :page 1}
|
|
||||||
2 {:id 2 :page 1}}}
|
|
||||||
result (impl/degroup-shapes initial [1 2] 1)]
|
|
||||||
;; (pprint expected)
|
|
||||||
;; (pprint result)
|
|
||||||
(t/is (= result expected))))
|
|
||||||
|
|
||||||
|
|
||||||
;; degroup all shapes from neested group
|
|
||||||
|
|
||||||
(t/deftest degroup-shapes-1-3
|
|
||||||
(let [initial {:pages {1 {:id 1 :shapes [4]}}
|
|
||||||
:shapes {1 {:id 1 :page 1 :group 3}
|
|
||||||
2 {:id 2 :page 1 :group 3}
|
|
||||||
3 {:id 3 :page 1 :group 4 :type :group :items [1 2]}
|
|
||||||
4 {:id 4 :page 1 :type :group :items [3]}}}
|
|
||||||
expected {:workspace {:selected #{1 2}}
|
|
||||||
:pages {1 {:id 1 :shapes [4]}}
|
|
||||||
:shapes {1 {:id 1 :page 1 :group 4}
|
|
||||||
2 {:id 2 :page 1 :group 4}
|
|
||||||
4 {:id 4 :page 1 :type :group :items [1 2]}}}
|
|
||||||
result (impl/degroup-shapes initial [1 2] 1)]
|
|
||||||
;; (pprint expected)
|
|
||||||
;; (pprint result)
|
|
||||||
(t/is (= result expected))))
|
|
||||||
|
|
||||||
;; degroup group inside a group
|
|
||||||
|
|
||||||
(t/deftest degroup-shapes-2
|
|
||||||
(let [initial {:pages {1 {:id 1 :shapes [1]}}
|
|
||||||
:shapes {1 {:id 1 :page 1 :type :group :items [2]}
|
|
||||||
2 {:id 2 :page 1 :type :group :items [3] :group 1}
|
|
||||||
3 {:id 3 :page 1 :group 2}}}
|
|
||||||
|
|
||||||
expected {:pages {1 {:id 1 :shapes [1]}}
|
|
||||||
:shapes {1 {:id 1 :page 1 :type :group :items [3]}
|
|
||||||
3 {:id 3 :page 1 :group 1}}
|
|
||||||
:workspace {:selected #{3}}}]
|
|
||||||
(let [result (impl/degroup-shapes initial [2] 1)]
|
|
||||||
;; (pprint expected)
|
|
||||||
;; (pprint result)
|
|
||||||
(t/is (= result expected)))))
|
|
||||||
|
|
||||||
;; degroup multiple groups not nested
|
|
||||||
|
|
||||||
(t/deftest degroup-shapes-3
|
|
||||||
(let [initial {:pages {1 {:id 1 :shapes [1 2]}}
|
|
||||||
:shapes {1 {:id 1 :page 1 :type :group :items [3]}
|
|
||||||
2 {:id 2 :page 1 :type :group :items [4]}
|
|
||||||
3 {:id 3 :page 1 :group 1}
|
|
||||||
4 {:id 4 :page 1 :group 2}}}
|
|
||||||
|
|
||||||
expected {:pages {1 {:id 1 :shapes [3 4]}}
|
|
||||||
:shapes {3 {:id 3 :page 1} 4 {:id 4 :page 1}}
|
|
||||||
:workspace {:selected #{4 3}}}]
|
|
||||||
(let [result (impl/degroup-shapes initial [1 2] 1)]
|
|
||||||
;; (pprint expected)
|
|
||||||
;; (pprint result)
|
|
||||||
(t/is (= result expected)))))
|
|
||||||
|
|
|
@ -130,12 +130,9 @@
|
||||||
(task ["dbg-dist:main"])
|
(task ["dbg-dist:main"])
|
||||||
(task ["dbg-dist:worker"]))
|
(task ["dbg-dist:worker"]))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
;; --- Tests Tasks
|
;; --- Tests Tasks
|
||||||
|
|
||||||
(defmethod task "build-tests"
|
(defmethod task "build:tests"
|
||||||
[& args]
|
[& args]
|
||||||
(api/build (api/inputs "src" "test")
|
(api/build (api/inputs "src" "test")
|
||||||
(assoc default-build-options
|
(assoc default-build-options
|
||||||
|
@ -147,6 +144,30 @@
|
||||||
:output-dir "target/tests/main"
|
:output-dir "target/tests/main"
|
||||||
:optimizations :none)))
|
:optimizations :none)))
|
||||||
|
|
||||||
|
(defmethod task "watch:tests"
|
||||||
|
[args]
|
||||||
|
(println "Start watch loop...")
|
||||||
|
(letfn [(run-tests []
|
||||||
|
(let [{:keys [out err]} (shell/sh "node" "target/tests/main.js")]
|
||||||
|
(println out err)))
|
||||||
|
(start-watch []
|
||||||
|
(try
|
||||||
|
(api/watch (api/inputs "src" "test")
|
||||||
|
(assoc default-build-options
|
||||||
|
:main 'uxbox.tests.main
|
||||||
|
:watch-fn run-tests
|
||||||
|
:target :nodejs
|
||||||
|
:source-map true
|
||||||
|
:output-to "target/tests/main.js"
|
||||||
|
:output-dir "target/tests/main"
|
||||||
|
:optimizations :none))
|
||||||
|
(catch Exception e
|
||||||
|
(println "ERROR:" e)
|
||||||
|
(Thread/sleep 2000)
|
||||||
|
start-watch)))]
|
||||||
|
(trampoline start-watch)))
|
||||||
|
|
||||||
|
|
||||||
;; --- Figwheel Config & Tasks
|
;; --- Figwheel Config & Tasks
|
||||||
|
|
||||||
(def figwheel-builds
|
(def figwheel-builds
|
||||||
|
|
100
manage.sh
100
manage.sh
|
@ -2,55 +2,42 @@
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
REV=`git log -n 1 --pretty=format:%h -- docker/`
|
REV=`git log -n 1 --pretty=format:%h -- docker/`
|
||||||
IMGNAME="uxbox-devenv"
|
IMGNAME="devenv_uxbox"
|
||||||
|
|
||||||
function kill-devenv-container {
|
|
||||||
echo "Cleaning development container $IMGNAME:$REV..."
|
|
||||||
docker ps -a -f name=$IMGNAME -q | xargs --no-run-if-empty docker kill
|
|
||||||
}
|
|
||||||
|
|
||||||
function remove-devenv-images {
|
function remove-devenv-images {
|
||||||
echo "Clean old development image $IMGNAME..."
|
echo "Clean old development image $IMGNAME..."
|
||||||
docker images $IMGNAME -q | awk '{print $3}' | xargs --no-run-if-empty docker rmi
|
docker images $IMGNAME -q | awk '{print $3}' | xargs --no-run-if-empty docker rmi
|
||||||
}
|
}
|
||||||
|
|
||||||
function build-devenv-image {
|
function build-devenv {
|
||||||
|
echo "Building development image $IMGNAME:latest with UID $EXTERNAL_UID..."
|
||||||
|
|
||||||
local EXTERNAL_UID=${1:-$(id -u)}
|
local EXTERNAL_UID=${1:-$(id -u)}
|
||||||
echo "Building development image $IMGNAME:$REV with UID $EXTERNAL_UID..."
|
docker-compose -f docker/devenv/docker-compose.yaml \
|
||||||
docker build --rm=true \
|
build --build-arg EXTERNAL_UID=$EXTERNAL_UID --force-rm;
|
||||||
-t $IMGNAME:$REV \
|
|
||||||
-t $IMGNAME:latest \
|
|
||||||
--build-arg EXTERNAL_UID=$EXTERNAL_UID \
|
|
||||||
--label="io.uxbox.devenv" \
|
|
||||||
docker/devenv
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function build-devenv-image-if-not-exists {
|
function build-devenv-if-not-exists {
|
||||||
if [[ ! $(docker images $IMGNAME:$REV -q) ]]; then
|
if [[ ! $(docker images $IMGNAME:latest -q) ]]; then
|
||||||
build-devenv-image $@
|
build-devenv $@
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function start-devenv {
|
||||||
|
build-devenv-if-not-exists $@;
|
||||||
|
docker-compose -f docker/devenv/docker-compose.yaml up -d;
|
||||||
|
}
|
||||||
|
|
||||||
|
function stop-devenv {
|
||||||
|
docker-compose -f docker/devenv/docker-compose.yaml stop -t 2;
|
||||||
|
}
|
||||||
|
|
||||||
function run-devenv {
|
function run-devenv {
|
||||||
kill-devenv-container;
|
if [[ ! $(docker ps -f "name=uxbox-devenv" -q) ]]; then
|
||||||
build-devenv-image-if-not-exists $@;
|
start-devenv
|
||||||
|
fi
|
||||||
|
|
||||||
mkdir -p $HOME/.m2
|
docker exec -ti uxbox-devenv /home/uxbox/start.sh;
|
||||||
rm -rf ./frontend/node_modules
|
|
||||||
mkdir -p \
|
|
||||||
./frontend/resources/public/css \
|
|
||||||
./frontend/resources/public/view/css
|
|
||||||
|
|
||||||
CONTAINER=$IMGNAME:latest
|
|
||||||
|
|
||||||
echo "Running development image $CONTAINER..."
|
|
||||||
docker run --rm -ti \
|
|
||||||
-v `pwd`:/home/uxbox/uxbox \
|
|
||||||
-v $HOME/.m2:/home/uxbox/.m2 \
|
|
||||||
-v $HOME/.gitconfig:/home/uxbox/.gitconfig \
|
|
||||||
-p 3449:3449 -p 6060:6060 -p 9090:9090 \
|
|
||||||
--name "uxbox-devenv" \
|
|
||||||
$CONTAINER
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function run-all-tests {
|
function run-all-tests {
|
||||||
|
@ -61,7 +48,7 @@ function run-all-tests {
|
||||||
}
|
}
|
||||||
|
|
||||||
function run-frontend-tests {
|
function run-frontend-tests {
|
||||||
build-devenv-image-if-not-exists $@;
|
build-devenv-if-not-exists $@;
|
||||||
|
|
||||||
CONTAINER=$IMGNAME:latest
|
CONTAINER=$IMGNAME:latest
|
||||||
|
|
||||||
|
@ -74,7 +61,7 @@ function run-frontend-tests {
|
||||||
}
|
}
|
||||||
|
|
||||||
function run-backend-tests {
|
function run-backend-tests {
|
||||||
build-devenv-image-if-not-exists $@;
|
build-devenv-if-not-exists $@;
|
||||||
|
|
||||||
CONTAINER=$IMGNAME:latest
|
CONTAINER=$IMGNAME:latest
|
||||||
|
|
||||||
|
@ -86,7 +73,7 @@ function run-backend-tests {
|
||||||
}
|
}
|
||||||
|
|
||||||
function build-frontend-local {
|
function build-frontend-local {
|
||||||
build-devenv-image-if-not-exists $@;
|
build-devenv-if-not-exists $@;
|
||||||
|
|
||||||
mkdir -p $HOME/.m2
|
mkdir -p $HOME/.m2
|
||||||
rm -rf ./frontend/node_modules
|
rm -rf ./frontend/node_modules
|
||||||
|
@ -158,6 +145,8 @@ function build-backend-image {
|
||||||
}
|
}
|
||||||
|
|
||||||
function build-images {
|
function build-images {
|
||||||
|
build-devenv-if-not-exists $@;
|
||||||
|
|
||||||
echo "Building frontend image ..."
|
echo "Building frontend image ..."
|
||||||
build-frontend-image || exit 1;
|
build-frontend-image || exit 1;
|
||||||
echo "Building frontend dbg image ..."
|
echo "Building frontend dbg image ..."
|
||||||
|
@ -197,11 +186,17 @@ function usage {
|
||||||
echo "USAGE: $0 OPTION"
|
echo "USAGE: $0 OPTION"
|
||||||
echo "Options:"
|
echo "Options:"
|
||||||
echo "- clean Stop and clean up docker containers"
|
echo "- clean Stop and clean up docker containers"
|
||||||
echo "- build-devenv-image Build docker container for development with tmux. Can specify external user id in parameter"
|
echo ""
|
||||||
echo "- run-devenv Run (and build if necessary) development container (frontend at localhost:3449, backend at localhost:6060). Can specify external user id in parameter"
|
echo "- build-devenv Build docker development oriented image; (can specify external user id in parameter)"
|
||||||
echo "- run-all-tests Execute unit tests for both backend and frontend. Can specify external user id in parameter"
|
echo "- start-devenv Start the development oriented docker-compose service."
|
||||||
echo "- run-frontend-tests Execute unit tests for frontend only. Can specify external user id in parameter"
|
echo "- stop-devenv Stops the development oriented docker-compose service."
|
||||||
echo "- run-backend-tests Execute unit tests for backend only. Can specify external user id in parameter"
|
echo "- run-devenv Attaches to the running devenv container and starts development environment"
|
||||||
|
echo " based on tmux (frontend at localhost:3449, backend at localhost:6060)."
|
||||||
|
echo ""
|
||||||
|
echo "- run-all-tests Execute unit tests for both backend and frontend."
|
||||||
|
echo "- run-frontend-tests Execute unit tests for frontend only."
|
||||||
|
echo "- run-backend-tests Execute unit tests for backend only."
|
||||||
|
echo ""
|
||||||
echo "- build-images Build a 'release ready' docker images for both backend and frontend"
|
echo "- build-images Build a 'release ready' docker images for both backend and frontend"
|
||||||
echo "- build-frontend-image Build a 'release ready' docker image for frontend (debug version)"
|
echo "- build-frontend-image Build a 'release ready' docker image for frontend (debug version)"
|
||||||
echo "- build-frontend-dbg-image Build a debug docker image for frontend"
|
echo "- build-frontend-dbg-image Build a debug docker image for frontend"
|
||||||
|
@ -213,15 +208,26 @@ function usage {
|
||||||
|
|
||||||
case $1 in
|
case $1 in
|
||||||
clean)
|
clean)
|
||||||
kill-devenv-container
|
|
||||||
remove-devenv-images
|
remove-devenv-images
|
||||||
;;
|
;;
|
||||||
build-devenv-image)
|
|
||||||
build-devenv-image ${@:2}
|
## devenv related commands
|
||||||
|
|
||||||
|
build-devenv)
|
||||||
|
build-devenv ${@:2}
|
||||||
|
;;
|
||||||
|
start-devenv)
|
||||||
|
start-devenv ${@:2}
|
||||||
;;
|
;;
|
||||||
run-devenv)
|
run-devenv)
|
||||||
run-devenv ${@:2}
|
run-devenv ${@:2}
|
||||||
;;
|
;;
|
||||||
|
stop-devenv)
|
||||||
|
stop-devenv ${@:2}
|
||||||
|
;;
|
||||||
|
|
||||||
|
## testin related commands
|
||||||
|
|
||||||
run-all-tests)
|
run-all-tests)
|
||||||
run-all-tests ${@:2}
|
run-all-tests ${@:2}
|
||||||
;;
|
;;
|
||||||
|
@ -232,6 +238,8 @@ case $1 in
|
||||||
run-backend-tests ${@:2}
|
run-backend-tests ${@:2}
|
||||||
;;
|
;;
|
||||||
|
|
||||||
|
# production related comands
|
||||||
|
|
||||||
build-images)
|
build-images)
|
||||||
build-images
|
build-images
|
||||||
;;
|
;;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue