2.7 KiB
Penpot Common – Agent Instructions
A shared module with code written in Clojure, ClojureScript and JavaScript. Contains multplatform code that can be used and executed from frontend, backend or exporter modules. It uses clojure reader conditionals for specify platform specific implementation.
General Guidelines
This is a golden rule for common module development. To ensure consistency across the penpot stack, all contributions must adhere to these criteria:
1. Testing & Validation
If code is added or modified in src/, corresponding tests in
test/common_tests/ must be added or updated.
- Environment: Tests should run in a JS (nodejs) and JVM
- Location: Place tests in the
test/common_tests/directory, following the namespace structure of the source code (e.g.,app.common.colors->common-tests.colors-test). - Execution: The tests should be executed on both: JS (nodejs) and JVM environments
- Isolated:
- JS: To run a focused ClojureScript unit test: edit the
test/common_tests/runner.cljsto narrow the test suite, thenpnpm run test:js. - JVM:
pnpm run test:jvm --focus common-tests.my-ns-test
- JS: To run a focused ClojureScript unit test: edit the
- Regression:
- JS: Run
pnpm run test:jswithout modifications on the runner (preferred) - JVM: Run
pnpm run test:jvm
- JS: Run
- Isolated:
2. Code Quality & Formatting
- Linting: All code changes must pass linter checks:
- Run
pnpm run lint:cljfor CLJ/CLJS/CLJC
- Run
- Formatting: All code changes must pass the formatting check
- Run
pnpm run check-fmt:cljfor CLJ/CLJS/CLJC - Run
pnpm run check-fmt:jsfor JS - Use the
pnpm run fmtfix all the formatting issues (pnpm run fmt:cljorpnpm run fmt:jsfor isolated formatting fix)
- Run
Code Conventions
Namespace Overview
The source is located under src directory and this is a general overview of
namespaces structure:
app.common.types.*– Shared data types for shapes, files, pages using Malli schemasapp.common.schema– Malli abstraction layer, exposes the most used functions from malliapp.common.geom.*– Geometry and shape transformation helpersapp.common.data– Generic helpers used around all applicationapp.common.math– Generic math helpers used around all aplicationapp.common.json– Generic JSON encoding/decoding helpersapp.common.data.macros– Performance macros used everywhere
Reader Conditionals
We use reader conditionals to target for differentiate an implementation depending on the target platform where code should run:
#?(:clj (import java.util.UUID)
:cljs (:require [cljs.core :as core]))
Both frontend and backend depend on common as a local library (penpot/common {:local/root "../common"}).