Files
lasuite-drive/Makefile
T
rcutte df7431698e 🧑‍💻(project) install frontend dependencies via container in bootstrap
In the default compose setup, .
  /src/frontend/node_modules and
    ./src/frontend/apps/drive/node_modules are bind-mounted to the host
    filesystem. If these directories are empty, mounting them into the
    frontend-dev container masks the dependencies built into the Docker
    image, causing runtime failures (e.g. missing pdfjs-dist/package.json).

    This commit:
    - Uses the frontend-dev container (FRONTEND_YARN) to install
      dependencies via 'yarn install --frozen-lockfile' without requiring
      host Node.js or Yarn.
    - Adds the containerized yarn install step directly into the
      build-frontend target, ensuring host node_modules are populated during
      image build / make bootstrap.
    - Leaves frontend-development-install untouched for host-only developers.

Signed-off-by: rcutte <rcutte@student.42.fr>
2026-09-14 18:11:15 +02:00

443 lines
13 KiB
Makefile

# /!\ /!\ /!\ /!\ /!\ /!\ /!\ DISCLAIMER /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\
#
# This Makefile is only meant to be used for DEVELOPMENT purpose as we are
# changing the user id that will run in the container.
#
# PLEASE DO NOT USE IT FOR YOUR CI/PRODUCTION/WHATEVER...
#
# /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\
#
# Note to developers:
#
# While editing this file, please respect the following statements:
#
# 1. Every variable should be defined in the ad hoc VARIABLES section with a
# relevant subsection
# 2. Every new rule should be defined in the ad hoc RULES section with a
# relevant subsection depending on the targeted service
# 3. Rules should be sorted alphabetically within their section
# 4. When a rule has multiple dependencies, you should:
# - duplicate the rule name to add the help string (if required)
# - write one dependency per line to increase readability and diffs
# 5. .PHONY rule statement should be written after the corresponding rule
# ==============================================================================
# VARIABLES
BOLD := \033[1m
RESET := \033[0m
GREEN := \033[1;32m
SHELL := /usr/bin/env bash
# -- Docker
# Get the current user ID to use for docker run and docker exec commands
DOCKER_UID = $(shell id -u)
DOCKER_GID = $(shell id -g)
DOCKER_USER = $(DOCKER_UID):$(DOCKER_GID)
COMPOSE = DOCKER_USER=$(DOCKER_USER) docker compose
COMPOSE_EXEC = $(COMPOSE) exec
COMPOSE_EXEC_APP = $(COMPOSE_EXEC) app-dev
COMPOSE_RUN = $(COMPOSE) run --rm
COMPOSE_RUN_APP = $(COMPOSE_RUN) app-dev
COMPOSE_RUN_APP_NO_DEPS = $(COMPOSE_RUN) --no-deps app-dev
COMPOSE_RUN_CROWDIN = $(COMPOSE_RUN) crowdin crowdin
# -- Backend
MANAGE = $(COMPOSE_RUN_APP) python manage.py
MANAGE_EXEC = $(COMPOSE_EXEC_APP) python manage.py
MAIL_YARN = $(COMPOSE_RUN) -w /app/src/mail node yarn
PSQL = ./bin/psql
# -- Frontend
FRONTEND_PATH = ./src/frontend
DRIVE_APP_FRONTEND_PATH = $(FRONTEND_PATH)/apps/drive
CONSUMER_APP_FRONTEND_PATH = $(FRONTEND_PATH)/apps/sdk-consumer
DRIVE_SDK_FRONTEND_PATH = $(FRONTEND_PATH)/packages/sdk
FRONTEND_YARN = $(COMPOSE_RUN) frontend-dev yarn
# ==============================================================================
# RULES
default: help
data/media:
@mkdir -p data/media
data/static:
@mkdir -p data/static
data/postgresql.local:
@mkdir -p data/postgresql.local
data/postgresql.e2e:
@mkdir -p data/postgresql.e2e
env.d/development/crowdin.local:
@touch env.d/development/crowdin.local
env.d/development/common.local:
@touch env.d/development/common.local
env.d/development/postgresql.local:
@touch env.d/development/postgresql.local
env.d/development/kc_postgresql.local:
@touch env.d/development/kc_postgresql.local
src/frontend/node_modules:
@mkdir -p src/frontend/node_modules
src/frontend/apps/drive/node_modules:
@mkdir -p src/frontend/apps/drive/node_modules
src/frontend/apps/drive/out/index.html:
@mkdir -p src/frontend/apps/drive/out/
@touch src/frontend/apps/drive/out/index.html
# -- Project
create-dev-local-files: ## create local files and directories for development
create-dev-local-files: \
data/postgresql.local \
data/postgresql.e2e \
src/frontend/node_modules \
src/frontend/apps/drive/node_modules \
env.d/development/crowdin.local \
env.d/development/common.local \
env.d/development/postgresql.local \
env.d/development/kc_postgresql.local
.PHONY: create-dev-local-files
create-docker-network: ## create the docker network if it doesn't exist
@docker network create lasuite-network || true
.PHONY: create-docker-network
bootstrap: ## Prepare Docker images for the project
bootstrap: \
data/media \
data/static \
create-dev-local-files \
build \
create-docker-network \
migrate \
back-i18n-compile \
mails-install \
mails-build \
run
.PHONY: bootstrap
# -- Docker/compose
build: ## build the project containers
build: \
build-backend \
build-frontend
.PHONY: build
build-backend: cache ?=
build-backend: ## build the app-dev container
$(COMPOSE) build app-dev $(cache)
.PHONY: build-backend
build-frontend: cache ?=
build-frontend: ## build the frontend container
$(COMPOSE) build frontend-dev $(cache)
@$(FRONTEND_YARN) install --frozen-lockfile
.PHONY: build-frontend-development
down: ## stop and remove containers, networks, images, and volumes
@$(COMPOSE) down
rm -rf data/postgresql.*
.PHONY: down
logs: ## display app-dev logs (follow mode)
@$(COMPOSE) logs -f app-dev
.PHONY: logs
run-backend: ## start the backend container
@$(COMPOSE) up --force-recreate -d nginx
@$(MAKE) configure-wopi
.PHONY: run-backend
bootstrap-e2e: ## bootstrap the backend container for e2e tests, without frontend
bootstrap-e2e: \
data/media \
data/static \
create-dev-local-files \
build-backend \
create-docker-network \
back-i18n-compile \
migrate-e2e \
frontend-development-install
.PHONY: bootstrap-e2e
clear-db-e2e: ## quickly clears the database for e2e tests, used in the e2e tests
POSTGRES_DB=drive_e2e $(PSQL) < bin/clear_records.sql
.PHONY: clear-db-e2e
is-e2e-backend-running: ## check if the backend is running (with configured e2e database)
@CONTAINER_ID=$$($(COMPOSE) ps app-dev --filter status=running -q | grep -v "🐳"); \
docker inspect $$CONTAINER_ID --format "{{ range .Config.Env }}{{ println . }}{{ end }}" | \
grep DB_NAME=drive_e2e || \
(echo -e "e2e backend is not running. You should run the following command(s) first:\nmake bootstrap-e2e && make run-backend-e2e" && false)
.PHONY: is-e2e-backend-running
migrate-e2e: ## run backend migrations for the e2e database
$(COMPOSE) stop postgresql app-dev
ENV_OVERRIDE=e2e $(MAKE) migrate
.PHONY: migrate-e2e
run-backend-e2e: ## start the backend container for e2e tests, always remove the postgresql.e2e volume first
$(COMPOSE) stop postgresql app-dev
ENV_OVERRIDE=e2e $(MAKE) run-backend
.PHONY: run-backend-e2e
run-tests-e2e: ## run the e2e tests, example: make run-tests-e2e -- --project chromium --headed
run-tests-e2e: is-e2e-backend-running
@args="$(filter-out $@,$(MAKECMDGOALS))" && \
cd src/frontend/apps/e2e && yarn test $${args:-${1}}
.PHONY: run-tests-e2e
backend-exec-command: ## execute a command in the backend container
@args="$(filter-out $@,$(MAKECMDGOALS))" && \
$(MANAGE_EXEC) $${args}
.PHONY: backend-exec-command
run: ## start the development server and frontend development
run: run-backend
$(COMPOSE) up --force-recreate -d frontend-dev
.PHONY: run
status: ## an alias for "docker compose ps"
@$(COMPOSE) ps
.PHONY: status
stop: ## stop the development server using Docker
@$(COMPOSE) stop
.PHONY: stop
# -- Backend
demo: ## flush db then create a demo for load testing purpose
demo: resetdb
@$(MANAGE) create_demo
.PHONY: demo
reconciliation-demo: ## create demo data and a CSV to test user reconciliation via the admin
reconciliation-demo: resetdb
@$(MANAGE) create_reconciliation_demo
.PHONY: reconciliation-demo
index: ## index all files to remote search
@$(MANAGE) index
.PHONY: index
# Nota bene: Black should come after isort just in case they don't agree...
lint: ## lint back-end python sources
lint: \
lint-ruff-format \
lint-ruff-check-fix \
lint-pylint
.PHONY: lint
lint-ruff-format: ## format back-end python sources with ruff
@echo 'lint:ruff-format started…'
@$(COMPOSE_RUN_APP_NO_DEPS) ruff format .
.PHONY: lint-ruff-format
lint-ruff-check: ## lint back-end python sources with ruff
@echo 'lint:ruff-check started…'
@$(COMPOSE_RUN_APP_NO_DEPS) ruff check .
.PHONY: lint-ruff-check
lint-ruff-check-fix: ## fix back-end python sources with ruff
@echo 'lint:ruff-check-fix started…'
@$(COMPOSE_RUN_APP_NO_DEPS) ruff check . --fix
.PHONY: lint-ruff-check-fix
lint-pylint: ## lint back-end python sources with pylint only on changed files from main
@echo 'lint:pylint started…'
bin/pylint --diff-only=origin/main
.PHONY: lint-pylint
test: ## run project tests
@$(MAKE) test-back-parallel
.PHONY: test
test-back: ## run back-end tests
@args="$(filter-out $@,$(MAKECMDGOALS))" && \
bin/pytest $${args:-${1}}
.PHONY: test-back
test-back-parallel: ## run all back-end tests in parallel
@args="$(filter-out $@,$(MAKECMDGOALS))" && \
bin/pytest -n auto $${args:-${1}}
.PHONY: test-back-parallel
makemigrations: ## run django makemigrations for the drive project.
@echo "$(BOLD)Running makemigrations$(RESET)"
$(COMPOSE) up -d postgresql
$(MANAGE) makemigrations
.PHONY: makemigrations
migrate: ## run django migrations for the drive project.
@echo "$(BOLD)Running migrations$(RESET)"
$(COMPOSE) up -d postgresql
$(MANAGE) migrate
.PHONY: migrate
superuser: ## Create an admin superuser with password "admin"
@echo "$(BOLD)Creating a Django superuser$(RESET)"
@$(MANAGE) createsuperuser --email admin@example.com --password admin
.PHONY: superuser
configure-wopi: ## configure the wopi settings
@$(MANAGE) trigger_wopi_configuration
.PHONY: configure-wopi
back-i18n-compile: ## compile the gettext files
@$(MANAGE) compilemessages --ignore=".venv/**/*"
.PHONY: back-i18n-compile
back-i18n-generate: ## create the .pot files used for i18n
@$(MANAGE) makemessages -a --keep-pot --all
.PHONY: back-i18n-generate
shell: ## connect to django shell
@$(MANAGE) shell #_plus
.PHONY: dbshell
# -- Database
dbshell: ## connect to database shell
$(MANAGE_EXEC) dbshell
.PHONY: dbshell
resetdb: FLUSH_ARGS ?=
resetdb: ## flush database and create a superuser "admin"
@echo "$(BOLD)Flush database$(RESET)"
@$(MANAGE) flush $(FLUSH_ARGS)
@${MAKE} superuser
.PHONY: resetdb
# -- Internationalization
crowdin-download: ## Download translated message from crowdin
@$(COMPOSE_RUN_CROWDIN) download -c crowdin/config.yml
.PHONY: crowdin-download
crowdin-download-sources: ## Download sources from Crowdin
@$(COMPOSE_RUN_CROWDIN) download sources -c crowdin/config.yml
.PHONY: crowdin-download-sources
crowdin-upload: ## Upload source translations to crowdin
@$(COMPOSE_RUN_CROWDIN) upload sources -c crowdin/config.yml
.PHONY: crowdin-upload
i18n-compile: ## compile all translations
i18n-compile: \
back-i18n-compile \
frontend-i18n-compile
.PHONY: i18n-compile
i18n-generate: ## create the .pot files and extract frontend messages
i18n-generate: \
back-i18n-generate \
frontend-i18n-generate
.PHONY: i18n-generate
i18n-download-and-compile: ## download all translated messages and compile them to be used by all applications
i18n-download-and-compile: \
crowdin-download \
i18n-compile
.PHONY: i18n-download-and-compile
i18n-generate-and-upload: ## generate source translations for all applications and upload them to Crowdin
i18n-generate-and-upload: \
i18n-generate \
crowdin-upload
.PHONY: i18n-generate-and-upload
# -- Mail generator
mails-build: ## Convert mjml files to html and text
@$(MAIL_YARN) build
.PHONY: mails-build
mails-build-html-to-plain-text: ## Convert html files to text
@$(MAIL_YARN) build-html-to-plain-text
.PHONY: mails-build-html-to-plain-text
mails-build-mjml-to-html: ## Convert mjml files to html and text
@$(MAIL_YARN) build-mjml-to-html
.PHONY: mails-build-mjml-to-html
mails-install: ## install the mail generator
@$(MAIL_YARN) install
.PHONY: mails-install
# -- Misc
clean: ## restore repository state as it was freshly cloned
git clean -idx
.PHONY: clean
clean-media: ## remove all media files
rm -rf data/media/*
.PHONY: clean-media
help:
@echo "$(BOLD)drive Makefile"
@echo "Please use 'make $(BOLD)target$(RESET)' where $(BOLD)target$(RESET) is one of:"
@grep -E '^[a-zA-Z0-9_-]+:.*?## .*$$' $(firstword $(MAKEFILE_LIST)) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "$(GREEN)%-30s$(RESET) %s\n", $$1, $$2}'
.PHONY: help
# Front
frontend-development-install: ## install the frontend locally
cd $(DRIVE_APP_FRONTEND_PATH) && yarn
.PHONY: frontend-development-install
frontend-lint: ## run the frontend linter
cd $(FRONTEND_PATH) && yarn lint
.PHONY: frontend-lint
run-frontend-development: ## Run the frontend in development mode
@$(COMPOSE) stop frontend-dev
cd $(DRIVE_APP_FRONTEND_PATH) && yarn dev
.PHONY: run-frontend-development
run-frontend-sdk-development: ## Run the frontend SDK consumer in development mode
cd $(CONSUMER_APP_FRONTEND_PATH) && yarn dev
.PHONY: run-frontend-development
build-frontend-sdk: ## Build drive SDK package
cd $(DRIVE_SDK_FRONTEND_PATH) && yarn build
.PHONY: build-frontend-sdk
frontend-i18n-extract: ## Extract the frontend translation inside a json to be used for crowdin
cd $(FRONTEND_PATH) && yarn i18n:extract
.PHONY: frontend-i18n-extract
frontend-i18n-generate: ## Generate the frontend json files used for crowdin
frontend-i18n-generate: \
crowdin-download-sources \
frontend-i18n-extract
.PHONY: frontend-i18n-generate
frontend-i18n-compile: ## Format the crowin json files used deploy to the apps
cd $(FRONTEND_PATH) && yarn i18n:deploy
.PHONY: frontend-i18n-compile
ci-serve-frontend-build: ## service static build (used in the CI)
ci-serve-frontend-build: src/frontend/apps/drive/out/index.html
$(COMPOSE) up -d --wait static
.PHONY: ci-serve-frontend-build
# -- K8S
build-k8s-cluster: ## build the kubernetes cluster using kind
./bin/start-kind.sh
.PHONY: build-k8s-cluster
start-tilt: ## start the kubernetes cluster using kind
tilt up -f ./bin/Tiltfile
.PHONY: build-k8s-cluster