CONTRIBUTING.md
8cc07ff6
 ## Getting Started
 
 ### Project Overview
 
 * Architecture:
 [Single Page Application (SPA)](https://en.wikipedia.org/wiki/Single-page_application)
 * Languages
   - Front end is [ClojureScript](https://clojurescript.org/) with ([re-frame](https://github.com/day8/re-frame))
   - CSS compilation is [Garden](https://github.com/noprompt/garden) with [Spade](https://github.com/dhleong/spade)
 * Dependencies
   - UI framework: [re-frame](https://github.com/day8/re-frame)
   ([docs](https://github.com/day8/re-frame/blob/master/docs/README.md),
   [FAQs](https://github.com/day8/re-frame/blob/master/docs/FAQs/README.md)) ->
   [Reagent](https://github.com/reagent-project/reagent) ->
   [React](https://github.com/facebook/react)
   - CSS rendering: [Garden](https://github.com/noprompt/garden)
 * Build tools
   - CLJS compilation, dependency management, REPL, & hot reload: [`shadow-cljs`](https://github.com/thheller/shadow-cljs)
 * Development tools
   - Debugging: [CLJS DevTools](https://github.com/binaryage/cljs-devtools),
   [`re-frame-10x`](https://github.com/day8/re-frame-10x)
   - Emacs integration: [CIDER](https://github.com/clojure-emacs/cider)
   - Linter: [clj-kondo](https://github.com/borkdude/clj-kondo)
 
 #### Directory structure
 
 * [`/`](/../../): project config files
 * [`.clj-kondo/`](.clj-kondo/): lint config and cache files (cache files are not tracked; see
 [`.gitignore`](.gitignore))
 * [`dev/`](dev/): source files compiled only with the [dev](#running-the-app) profile
   - [`user.cljs`](dev/cljs/user.cljs): symbols for use during development in the
 [ClojureScript REPL](#connecting-to-the-browser-repl-from-a-terminal)
 * [`resources/public/`](resources/public/): SPA root directory;
 [dev](#running-the-app) / [prod](#production) profile depends on the most recent build
   - [`index.html`](resources/public/index.html): SPA home page
     - Dynamic SPA content rendered in the following `div`:
         ```html
         <div id="app"></div>
         ```
     - Customizable; add headers, footers, links to other scripts and styles, etc.
   - Generated directories and files
     - Created on build with either the [dev](#running-the-app) or [prod](#production) profile
     - `js/compiled/`: compiled CLJS (`shadow-cljs`)
       - Not tracked in source control; see [`.gitignore`](.gitignore)
 * [`src/dm/styles.cljs`](src/dm/styles.cljs): CSS compilation source file (ClojureScript,
 [Garden](https://github.com/noprompt/garden))
 * [`src/dm/`](src/dm/): SPA source files (ClojureScript,
 [re-frame](https://github.com/Day8/re-frame))
   - [`core.cljs`](src/dm/core.cljs): contains the SPA entry point, `init`
 * [`.github/workflows/`](.github/workflows/): contains the
 [github actions](https://github.com/features/actions) pipelines.
   - [`test.yaml`](.github/workflows/test.yaml): Pipeline for testing.
 
 
 ### Editor/IDE
 
 Use your preferred editor or IDE that supports Clojure/ClojureScript development. See
 [Clojure tools](https://clojure.org/community/resources#_clojure_tools) for some popular options.
 
 ### Environment Setup
 
 1. Install [JDK 8 or later](https://openjdk.java.net/install/) (Java Development Kit)
 2. Install [Node.js](https://nodejs.org/) (JavaScript runtime environment) which should include
    [NPM](https://docs.npmjs.com/cli/npm) or if your Node.js installation does not include NPM also install it.
 4. Install [clj-kondo](https://github.com/borkdude/clj-kondo/blob/master/doc/install.md) (linter)
 5. Clone this repo and open a terminal in the `dm` project root directory
 6. (Optional) Setup [lint cache](https://github.com/borkdude/clj-kondo#project-setup):
     ```sh
     clj-kondo --lint "$(npx shadow-cljs classpath)"
     ```
 7. Setup
 [linting in your editor](https://github.com/borkdude/clj-kondo/blob/master/doc/editor-integration.md)
 
 ### Browser Setup
 
 Browser caching should be disabled when developer tools are open to prevent interference with
 [`shadow-cljs`](https://github.com/thheller/shadow-cljs) hot reloading.
 
 Custom formatters must be enabled in the browser before
 [CLJS DevTools](https://github.com/binaryage/cljs-devtools) can display ClojureScript data in the
 console in a more readable way.
 
 #### Chrome/Chromium
 
 1. Open [DevTools](https://developers.google.com/web/tools/chrome-devtools/) (Linux/Windows: `F12`
 or `Ctrl-Shift-I`; macOS: `⌘-Option-I`)
 2. Open DevTools Settings (Linux/Windows: `?` or `F1`; macOS: `?` or `Fn+F1`)
 3. Select `Preferences` in the navigation menu on the left, if it is not already selected
 4. Under the `Network` heading, enable the `Disable cache (while DevTools is open)` option
 5. Under the `Console` heading, enable the `Enable custom formatters` option
 
 #### Firefox
 
 1. Open [Developer Tools](https://developer.mozilla.org/en-US/docs/Tools) (Linux/Windows: `F12` or
 `Ctrl-Shift-I`; macOS: `⌘-Option-I`)
 2. Open [Developer Tools Settings](https://developer.mozilla.org/en-US/docs/Tools/Settings)
 (Linux/macOS/Windows: `F1`)
 3. Under the `Advanced settings` heading, enable the `Disable HTTP Cache (when toolbox is open)`
 option
 
 Unfortunately, Firefox does not yet support custom formatters in their devtools. For updates, follow
 the enhancement request in their bug tracker:
 [1262914 - Add support for Custom Formatters in devtools](https://bugzilla.mozilla.org/show_bug.cgi?id=1262914).
 
 
 ## Development
 
 ### Running the App
 
 Start a temporary local web server, build the app with the `dev` profile, and serve the app,
 browser test runner and karma test runner with hot reload:
 
 ```sh
 npm install
 npx shadow-cljs watch app
 ```
 
 Please be patient; it may take over 20 seconds to see any output, and over 40 seconds to complete.
 
 When `[:app] Build completed` appears in the output, browse to
 [http://localhost:8280/](http://localhost:8280/).
 
 [`shadow-cljs`](https://github.com/thheller/shadow-cljs) will automatically push ClojureScript code
 changes to your browser on save. To prevent a few common issues, see
 [Hot Reload in ClojureScript: Things to avoid](https://code.thheller.com/blog/shadow-cljs/2019/08/25/hot-reload-in-clojurescript.html#things-to-avoid).
 
 Opening the app in your browser starts a
 [ClojureScript browser REPL](https://clojurescript.org/reference/repl#using-the-browser-as-an-evaluation-environment),
 to which you may now connect.
 
 #### Connecting to the browser REPL from Emacs with CIDER
 
 Connect to the browser REPL:
 ```
 M-x cider-jack-in-cljs
 ```
 
 See
 [Shadow CLJS User's Guide: Emacs/CIDER](https://shadow-cljs.github.io/docs/UsersGuide.html#cider)
 for more information. Note that the mentioned [`.dir-locals.el`](.dir-locals.el) file has already
 been created for you.
 
 #### Connecting to the browser REPL from VS Code with Calva
 
 See the [re-frame-template README](https://github.com/day8/re-frame-template) for [Calva](https://github.com/BetterThanTomorrow/calva) instuctions. See also https://calva.io for Calva documentation.
 
 
 #### Connecting to the browser REPL from other editors
 
 See
 [Shadow CLJS User's Guide: Editor Integration](https://shadow-cljs.github.io/docs/UsersGuide.html#_editor_integration).
 Note that `npm run watch` runs `npx shadow-cljs watch` for you, and that this project's running build ids is
 `app`, `browser-test`, `karma-test`, or the keywords `:app`, `:browser-test`, `:karma-test` in a Clojure context.
 
 Alternatively, search the web for info on connecting to a `shadow-cljs` ClojureScript browser REPL
 from your editor and configuration.
 
 For example, in Vim / Neovim with `fireplace.vim`
 1. Open a `.cljs` file in the project to activate `fireplace.vim`
 2. In normal mode, execute the `Piggieback` command with this project's running build id, `:app`:
     ```vim
     :Piggieback :app
     ```
 
 #### Connecting to the browser REPL from a terminal
 
 1. Connect to the `shadow-cljs` nREPL:
     ```sh
     lein repl :connect localhost:8777
     ```
     The REPL prompt, `shadow.user=>`, indicates that is a Clojure REPL, not ClojureScript.
 
 2. In the REPL, switch the session to this project's running build id, `:app`:
     ```clj
     (shadow.cljs.devtools.api/nrepl-select :app)
     ```
     The REPL prompt changes to `cljs.user=>`, indicating that this is now a ClojureScript REPL.
 3. See [`user.cljs`](dev/cljs/user.cljs) for symbols that are immediately accessible in the REPL
 without needing to `require`.
 
 ### Running `shadow-cljs` Actions
 
 See a list of [`shadow-cljs CLI`](https://shadow-cljs.github.io/docs/UsersGuide.html#_command_line)
 actions:
 ```sh
 npx shadow-cljs --help
 ```
 
 Please be patient; it may take over 10 seconds to see any output. Also note that some actions shown
 may not actually be supported, outputting "Unknown action." when run.
 
 Run a shadow-cljs action on this project's build id (without the colon, just `app`):
 ```sh
 npx shadow-cljs <action> app
 ```
 ### Debug Logging
 
 The `debug?` variable in [`config.cljs`](src/cljs/dm/config.cljs) defaults to `true` in
 [`dev`](#running-the-app) builds, and `false` in [`prod`](#production) builds.
 
 Use `debug?` for logging or other tasks that should run only on `dev` builds:
 
 ```clj
 (ns dm.example
   (:require [dm.config :as config])
 
 (when config/debug?
   (println "This message will appear in the browser console only on dev builds."))
 ```
 
 ## Production
 
 Build the app with the `prod` profile:
 
 ```sh
 npm install
 npm run release
 ```
 
 Please be patient; it may take over 15 seconds to see any output, and over 30 seconds to complete.
 
 The `resources/public/js/compiled` directory is created, containing the compiled `app.js` and
 `manifest.edn` files.