|
@@ -1,32 +1,51 @@
|
|
|
-## Description
|
|
|
+# Logseq Dev Practices
|
|
|
+
|
|
|
+## description
|
|
|
|
|
|
This page describes development practices for this codebase.
|
|
|
|
|
|
## Linting
|
|
|
|
|
|
-Most of our linters require babashka. Before running them, please install
|
|
|
-https://github.com/babashka/babashka#installation. To invoke all the linters in
|
|
|
-this section, run `bb dev:lint`.
|
|
|
+Most of our linters require babashka. Before running them,
|
|
|
+please install babashka. To invoke all the linters in
|
|
|
+this section, run
|
|
|
+
|
|
|
+```sh
|
|
|
+bb dev:lint
|
|
|
+```
|
|
|
|
|
|
### Clojure code
|
|
|
|
|
|
To lint:
|
|
|
+
|
|
|
```sh
|
|
|
clojure -M:clj-kondo --parallel --lint src --cache false
|
|
|
```
|
|
|
|
|
|
-We lint our Clojure(Script) code with https://github.com/clj-kondo/clj-kondo/. If you need to configure specific linters, see [this documentation](https://github.com/clj-kondo/clj-kondo/blob/master/doc/linters.md). Where possible, a global linting configuration is used and namespace specific configuration is avoided.
|
|
|
+We lint our Clojure(Script) code with
|
|
|
+[clj-kondo](https://github.com/clj-kondo/clj-kondo).
|
|
|
+If you need to configure specific linters, see
|
|
|
+[clj-kondo linters documentation](https://github.com/clj-kondo/clj-kondo/blob/master/doc/linters.md).
|
|
|
+Where possible, a global linting configuration is used and namespace specific
|
|
|
+configuration is avoided.
|
|
|
|
|
|
-There are outstanding linting items that are currently ignored to allow linting the rest of the codebase in CI. These outstanding linting items should be addressed at some point:
|
|
|
+There are outstanding linting items that are currently ignored to allow linting
|
|
|
+the rest of the codebase in CI.
|
|
|
+
|
|
|
+These outstanding linting items should be addressed at some point:
|
|
|
|
|
|
* Comments starting with `TODO:lint`
|
|
|
-* Code marked with `#_:clj-kondo/ignore` require a good understanding of the context to address as they usually involve something with a side effect or require changing multiple fns up the call stack.
|
|
|
+* Code marked with `#_:clj-kondo/ignore` require a good understanding of the
|
|
|
+ context to address as they usually involve something with a side effect or
|
|
|
+ require changing multiple fns up the call stack.
|
|
|
|
|
|
### Unused vars
|
|
|
|
|
|
-We use https://github.com/borkdude/carve to detect unused vars in our codebase.
|
|
|
+We use [borkdude/carve](https://github.com/borkdude/carve) to detect unused vars
|
|
|
+in our codebase.
|
|
|
|
|
|
To run this linter:
|
|
|
+
|
|
|
```sh
|
|
|
bb lint:carve
|
|
|
```
|
|
@@ -46,6 +65,7 @@ why a var is ignored to help others understand why it's unused.
|
|
|
|
|
|
Large vars have a lot of complexity and make it hard for the team to maintain
|
|
|
and understand them. To run this linter:
|
|
|
+
|
|
|
```sh
|
|
|
bb lint:large-vars
|
|
|
```
|
|
@@ -54,7 +74,10 @@ To configure the linter, see the `[:tasks/config :large-vars]` path of bb.edn.
|
|
|
|
|
|
### Document namespaces
|
|
|
|
|
|
-Documentation helps teams share their knowledge and enables more individuals to contribute to the codebase. Documenting our namespaces is a good first step to improving our documentation. To run this linter:
|
|
|
+Documentation helps teams share their knowledge and enables more individuals to
|
|
|
+contribute to the codebase. Documenting our namespaces is a good first step to
|
|
|
+improving our documentation. To run this linter:
|
|
|
+
|
|
|
```sh
|
|
|
bb lint:ns-docstrings
|
|
|
```
|
|
@@ -81,8 +104,13 @@ We have unit, performance and end to end tests.
|
|
|
|
|
|
### End to End Tests
|
|
|
|
|
|
-Even though we have a nightly release channel, it's hard for testing users (thanks to the brave users!) to notice all issues in a limited time, as Logseq is covering so many features.
|
|
|
-The only solution is automatic end-to-end tests - adding tests for GUI software is always painful but necessary. See https://github.com/logseq/logseq/pulls?q=E2E for e2e test examples.
|
|
|
+Even though we have a nightly release channel, it's hard for testing users
|
|
|
+(thanks to the brave users!) to notice all issues in a limited time, as Logseq
|
|
|
+is covering so many features.
|
|
|
+The only solution is automatic end-to-end tests - adding tests for GUI software
|
|
|
+is always painful but necessary.
|
|
|
+See [pull requests tagged with `E2E`](https://github.com/logseq/logseq/pulls?q=E2E)
|
|
|
+ for E2E test examples.
|
|
|
|
|
|
To run end to end tests
|
|
|
|
|
@@ -93,16 +121,16 @@ yarn e2e-test # or npx playwright test
|
|
|
```
|
|
|
|
|
|
If e2e failed after first running:
|
|
|
-- `rm -rdf ~/.logseq`
|
|
|
-- `rm -rdf ~/.config/Logseq`
|
|
|
-- `rm -rdf <repo dir>/tmp/`
|
|
|
-- Windows: `rmdir /s %APPDATA%/Electron` (Reference: https://www.electronjs.org/de/docs/latest/api/app#appgetpathname)
|
|
|
|
|
|
-There's a `traceAll()` helper function to enable playwright trace file dump for specific test files https://github.com/logseq/logseq/pull/8332
|
|
|
+* `rm -rdf ~/.logseq`
|
|
|
+* `rm -rdf ~/.config/Logseq`
|
|
|
+* `rm -rdf <repo dir>/tmp/`
|
|
|
+* Windows: `rmdir /s %APPDATA%/Electron` ([Reference: Electron API docs](https://www.electronjs.org/de/docs/latest/api/app#appgetpathname))
|
|
|
|
|
|
-If e2e tests fail in the file, they can be debugged by examining a trace dump with [the
|
|
|
-playwright trace
|
|
|
-viewer](https://playwright.dev/docs/trace-viewer#recording-a-trace).
|
|
|
+There's a `traceAll()` helper function to enable playwright trace file dump for specific test files (https://github.com/logseq/logseq/pull/8332)
|
|
|
+
|
|
|
+If E2E tests fail in the file, they can be debugged by examining a trace dump
|
|
|
+with [the playwright trace viewer](https://playwright.dev/docs/trace-viewer#recording-a-trace).
|
|
|
|
|
|
Locally this will get dumped into e2e-dump/.
|
|
|
|
|
@@ -113,7 +141,7 @@ https://github.com/logseq/logseq/actions/runs/3574600322.
|
|
|
|
|
|
Our unit tests use the [shadow-cljs test-runner](https://shadow-cljs.github.io/docs/UsersGuide.html#_testing). To run them:
|
|
|
|
|
|
-```bash
|
|
|
+```sh
|
|
|
yarn test
|
|
|
```
|
|
|
|
|
@@ -132,12 +160,15 @@ For this workflow:
|
|
|
|
|
|
1. Run `clj -M:test watch test` in one shell
|
|
|
2. Focus tests:
|
|
|
- 1. Add `^:focus` metadata flags to tests e.g. `(deftest ^:focus test-name ...)`.
|
|
|
- 2. In another shell, run `node static/tests.js -i focus` to only run those
|
|
|
- tests. To run all tests except those tests run `node static/tests.js -e focus`.
|
|
|
-3. Or focus namespaces: Using the regex option `-r`, run tests for `frontend.util.page-property-test` with `node static/tests.js -r page-property`.
|
|
|
|
|
|
-Multiple options can be specified to AND selections. For example, to run all `frontend.util.page-property-test` tests except for the focused one: `node static/tests.js -r page-property -e focus`
|
|
|
+ * Add `^:focus` metadata flags to tests e.g. `(deftest ^:focus test-name ...)`.
|
|
|
+ * In another shell, run `node static/tests.js -i focus` to only run those
|
|
|
+ tests. To run all tests except those tests run `node static/tests.js -e focus`.
|
|
|
+ * Or focus namespaces: Using the regex option `-r`, run tests for `frontend.util.page-property-test` with `node static/tests.js -r page-property`.
|
|
|
+
|
|
|
+Multiple options can be specified to AND selections. For example,
|
|
|
+to run all `frontend.util.page-property-test` tests except for the focused one:
|
|
|
+ `node static/tests.js -r page-property -e focus`
|
|
|
|
|
|
For help on more options, run `node static/tests.js -h`.
|
|
|
|
|
@@ -158,11 +189,13 @@ To write a test that uses a datascript db:
|
|
|
* For the repo argument that most fns take, pass it `test-helper/test-db`
|
|
|
|
|
|
#### Performance tests
|
|
|
+
|
|
|
To write a performance test:
|
|
|
|
|
|
* Use `frontend.util/with-time-number` to get the time in ms.
|
|
|
|
|
|
* Example:
|
|
|
+
|
|
|
```clojure
|
|
|
(are [x timeout] (>= timeout (:time (util/with-time-number (block/normalize-block x true))))
|
|
|
... )
|
|
@@ -173,13 +206,13 @@ For examples of these tests, see `frontend.db.query-dsl-test` and `frontend.db.m
|
|
|
### Async Unit Testing
|
|
|
|
|
|
Async unit testing is well supported in ClojureScript.
|
|
|
-https://clojurescript.org/tools/testing#async-testing is a good guide for how to
|
|
|
+[clojurescript.org/tools/testing#async-testing](https://clojurescript.org/tools/testing#async-testing) is a good guide for how to
|
|
|
do this. We have a couple of test helpers that make testing async easier:
|
|
|
|
|
|
-- `frontend.test.helper/deftest-async` - `deftest` for async tests that ensures
|
|
|
+* `frontend.test.helper/deftest-async` - `deftest` for async tests that ensures
|
|
|
uncaught exceptions don't abruptly end the test suite. If you don't use this
|
|
|
macro for async tests, you are expected to handle unexpected failures in your test
|
|
|
-- `frontend.test.helper/with-reset` - A version of `with-redefs` that works for
|
|
|
+* `frontend.test.helper/with-reset` - A version of `with-redefs` that works for
|
|
|
async contexts
|
|
|
|
|
|
## Accessibility
|
|
@@ -188,7 +221,7 @@ Please refer to our [accessibility guidelines](accessibility.md).
|
|
|
|
|
|
## Logging
|
|
|
|
|
|
-For logging, we use https://github.com/lambdaisland/glogi. When in development,
|
|
|
+For logging, we use [lambdaisland/glogi](https://github.com/lambdaisland/glogi). When in development,
|
|
|
be sure to have [enabled custom
|
|
|
formatters](https://github.com/binaryage/cljs-devtools/blob/master/docs/installation.md#enable-custom-formatters-in-chrome)
|
|
|
in the desktop app and browser. Without this enabled, most of the log messages
|
|
@@ -225,7 +258,15 @@ page](https://github.com/metosin/malli/blob/master/docs/clojurescript-function-i
|
|
|
|
|
|
## Auto-formatting
|
|
|
|
|
|
-Currently the codebase is not formatted/indented consistently. We loosely follow https://github.com/bbatsov/clojure-style-guide. [cljfmt](https://cljdoc.org/d/cljfmt/) is a common formatter used for Clojure, analogous to Prettier for other languages. You can do so easily with the [Calva](https://marketplace.visualstudio.com/items?itemName=betterthantomorrow.calva) extension in [VSCode](https://code.visualstudio.com/): It will (mostly) indent your code correctly as you type, and you can move your cursor to the start of the line(s) you've written and press `Tab` to auto-indent all Clojure forms nested under the one starting on the current line.
|
|
|
+Currently the codebase is not formatted/indented consistently. We loosely follow
|
|
|
+[clojure style guide](https://github.com/bbatsov/clojure-style-guide).
|
|
|
+[cljfmt](https://cljdoc.org/d/cljfmt/) is a common formatter used for Clojure,
|
|
|
+analogous to Prettier for other languages. You can do so easily with the
|
|
|
+[Calva](https://marketplace.visualstudio.com/items?itemName=betterthantomorrow.calva)
|
|
|
+extension in [VSCode](https://code.visualstudio.com/): It will (mostly) indent
|
|
|
+your code correctly as you type, and you can move your cursor to the start of
|
|
|
+the line(s) you've written and press `Tab` to auto-indent all Clojure forms
|
|
|
+nested under the one starting on the current line.
|
|
|
|
|
|
## Development Tools
|
|
|
|
|
@@ -236,16 +277,20 @@ docs](https://github.com/logseq/bb-tasks#logseqbb-tasksnbbwatch) for more info.
|
|
|
## FAQ
|
|
|
|
|
|
If dev app launch failed after electron upgrade:
|
|
|
+
|
|
|
```sh
|
|
|
yarn
|
|
|
yarn watch
|
|
|
```
|
|
|
+
|
|
|
In another window:
|
|
|
+
|
|
|
```sh
|
|
|
cd static
|
|
|
yarn
|
|
|
cd ..
|
|
|
yarn dev-electron-app
|
|
|
```
|
|
|
+
|
|
|
and kill all electron process
|
|
|
Then a normal start happens via `yarn dev-electron-app`
|