├── resources
└── practicalli
│ ├── application
│ ├── root
│ │ ├── resources
│ │ │ └── .keep
│ │ ├── .github
│ │ │ ├── config
│ │ │ │ ├── trivyignore
│ │ │ │ ├── markdown-lint-check.json
│ │ │ │ ├── secretlintrc.json
│ │ │ │ ├── markdown-link-check.json
│ │ │ │ └── megalinter.yaml
│ │ │ ├── CODEOWNERS
│ │ │ ├── FUNDING.yaml
│ │ │ ├── pull_request_template.md
│ │ │ └── workflows
│ │ │ │ ├── changelog-check.yaml
│ │ │ │ ├── lint-review.yaml
│ │ │ │ ├── scheduled-version-check.yaml
│ │ │ │ ├── quality-checks.yaml
│ │ │ │ ├── scheduled-stale-check.yaml
│ │ │ │ └── megalinter.yaml
│ │ ├── doc
│ │ │ └── intro.md
│ │ ├── .dir-locals.el
│ │ ├── .gitattributes
│ │ ├── dev
│ │ │ ├── design_journal.clj
│ │ │ ├── portal.clj
│ │ │ └── mulog_events.clj
│ │ ├── tests.edn
│ │ ├── .dockerignore
│ │ ├── CHANGELOG.md
│ │ ├── swagger-compose.yaml
│ │ ├── .gitignore
│ │ ├── compose.yaml
│ │ └── .cljstyle
│ ├── test
│ │ └── app_test.clj.template
│ ├── build
│ │ └── deps.edn.template
│ ├── template.edn
│ └── src
│ │ └── app.clj.template
│ ├── landing_page
│ ├── root
│ │ ├── docs
│ │ │ ├── css
│ │ │ │ └── style.css
│ │ │ └── index.html
│ │ ├── .github
│ │ │ ├── config
│ │ │ │ ├── trivyignore
│ │ │ │ ├── markdown-lint-check.json
│ │ │ │ ├── secretlintrc.json
│ │ │ │ ├── markdown-link-check.json
│ │ │ │ └── megalinter.yaml
│ │ │ ├── CODEOWNERS
│ │ │ ├── FUNDING.yaml
│ │ │ ├── pull_request_template.md
│ │ │ └── workflows
│ │ │ │ ├── changelog-check.yaml
│ │ │ │ ├── lint-review.yaml
│ │ │ │ ├── scheduled-version-check.yaml
│ │ │ │ ├── quality-checks.yaml
│ │ │ │ ├── scheduled-stale-check.yaml
│ │ │ │ └── megalinter.yaml
│ │ ├── resources
│ │ │ └── public
│ │ │ │ ├── css
│ │ │ │ └── style.css
│ │ │ │ ├── test.html
│ │ │ │ └── index.html
│ │ ├── .gitattributes
│ │ ├── dev
│ │ │ └── design_journal.cljs
│ │ ├── .dir-locals.el
│ │ ├── CHANGELOG.md
│ │ ├── tests.edn
│ │ ├── .gitignore
│ │ └── README.md
│ ├── build
│ │ ├── dev.cljs.edn.template
│ │ ├── github-pages.cljs.edn.template
│ │ ├── test.cljs.edn.template
│ │ ├── figwheel-main.edn
│ │ └── deps.edn.template
│ ├── test
│ │ ├── test_runner.cljs.template
│ │ └── main_page_test.cljs.template
│ ├── src
│ │ ├── data.cljs.template
│ │ └── main_page.cljs.template
│ └── template.edn
│ ├── service
│ ├── root
│ │ ├── .github
│ │ │ ├── config
│ │ │ │ ├── trivyignore
│ │ │ │ ├── markdown-lint-check.json
│ │ │ │ ├── secretlintrc.json
│ │ │ │ ├── markdown-link-check.json
│ │ │ │ └── megalinter.yaml
│ │ │ ├── CODEOWNERS
│ │ │ ├── FUNDING.yaml
│ │ │ ├── pull_request_template.md
│ │ │ └── workflows
│ │ │ │ ├── changelog-check.yaml
│ │ │ │ ├── lint-review.yaml
│ │ │ │ ├── scheduled-version-check.yaml
│ │ │ │ ├── quality-checks.yaml
│ │ │ │ ├── scheduled-stale-check.yaml
│ │ │ │ └── megalinter.yaml
│ │ ├── doc
│ │ │ └── intro.md
│ │ ├── .dir-locals.el
│ │ ├── .gitattributes
│ │ ├── tests.edn
│ │ ├── .dockerignore
│ │ ├── CHANGELOG.md
│ │ ├── swagger-compose.yaml
│ │ ├── .gitignore
│ │ ├── pom.xml
│ │ └── .cljstyle
│ ├── dev
│ │ ├── design_journal.clj
│ │ ├── portal.clj
│ │ ├── system_repl.clj.template
│ │ ├── mulog_events.clj
│ │ ├── system_repl_donut.clj.template
│ │ └── system_repl_integrant.clj.template
│ ├── docker
│ │ ├── compose-service.yaml.template
│ │ └── compose-service-postgres.yaml.template
│ ├── src
│ │ ├── parse_system.clj.template
│ │ ├── spec.clj.template
│ │ ├── middleware.clj.template
│ │ ├── parse_system_integrant.clj.template
│ │ ├── service_donut.clj.template
│ │ ├── service.clj.template
│ │ └── service_integrant.clj.template
│ ├── test
│ │ └── service_test.clj.template
│ ├── api
│ │ ├── system_admin.clj.template
│ │ ├── scoreboard.clj.template
│ │ └── scoreboard_config.clj.template
│ ├── build
│ │ ├── deps.edn.template
│ │ ├── deps_donut.edn.template
│ │ └── deps_integrant.edn.template
│ ├── template.edn
│ └── resources
│ │ └── config_donut_env.edn.template
│ └── minimal
│ ├── root
│ ├── .dir-locals.el
│ ├── .gitattributes
│ ├── dev
│ │ ├── design_journal.clj
│ │ ├── portal.clj
│ │ └── mulog_events.clj
│ ├── tests.edn
│ ├── CHANGELOG.md
│ ├── .gitignore
│ ├── .github
│ │ └── workflows
│ │ │ ├── lint-review.yaml
│ │ │ └── scheduled-stale-check.yaml
│ └── .cljstyle
│ ├── test
│ └── app_test.clj.template
│ ├── src
│ └── app.clj.template
│ ├── template.edn
│ └── build
│ ├── deps.edn.template
│ └── build.clj.template
├── .github
├── config
│ ├── trivyignore
│ ├── markdown-lint-check.json
│ ├── secretlintrc.json
│ ├── markdown-link-check.json
│ └── megalinter.yaml
├── CODEOWNERS
├── pull_request_template.md
└── workflows
│ ├── lint-review.yaml
│ ├── changelog-check.yaml
│ ├── scheduled-version-check.yaml
│ ├── quality-checks.yaml
│ ├── scheduled-stale-check.yaml
│ └── megalinter.yaml
├── .dir-locals.el
├── .gitattributes
├── tests.edn
├── deps.edn
├── test
└── practicalli
│ ├── minimal_test.clj
│ ├── application_test.clj
│ ├── landing_page_test.clj
│ └── service_test.clj
├── .gitignore
├── src
└── practicalli
│ ├── minimal.clj
│ ├── application.clj
│ ├── landing_page.clj
│ └── service.clj
├── pom.xml
└── .cljstyle
/resources/practicalli/application/root/resources/.keep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/.github/config/trivyignore:
--------------------------------------------------------------------------------
1 | # Accept the risk
2 | CVE-2024-22871
3 |
--------------------------------------------------------------------------------
/resources/practicalli/landing_page/root/docs/css/style.css:
--------------------------------------------------------------------------------
1 | /* some style */
2 |
3 |
--------------------------------------------------------------------------------
/resources/practicalli/service/root/.github/config/trivyignore:
--------------------------------------------------------------------------------
1 | # Accept the risk
2 | CVE-2024-22871
3 |
--------------------------------------------------------------------------------
/resources/practicalli/application/root/.github/config/trivyignore:
--------------------------------------------------------------------------------
1 | # Accept the risk
2 | CVE-2024-22871
3 |
--------------------------------------------------------------------------------
/resources/practicalli/landing_page/root/.github/config/trivyignore:
--------------------------------------------------------------------------------
1 | # Accept the risk
2 | CVE-2024-22871
3 |
--------------------------------------------------------------------------------
/resources/practicalli/landing_page/root/resources/public/css/style.css:
--------------------------------------------------------------------------------
1 | /* some style */
2 |
3 | /* Copy changes to docs/css/style.css */
4 |
--------------------------------------------------------------------------------
/.dir-locals.el:
--------------------------------------------------------------------------------
1 | ((clojure-mode . ((cider-preferred-build-tool . clojure-cli)
2 | (cider-clojure-cli-aliases . ":test/env:dev/reloaded"))))
3 |
--------------------------------------------------------------------------------
/resources/practicalli/application/root/doc/intro.md:
--------------------------------------------------------------------------------
1 | # Introduction to {{raw-name}}
2 |
3 | TODO: write [great documentation](http://jacobian.org/writing/what-to-write/)
4 |
--------------------------------------------------------------------------------
/resources/practicalli/service/root/doc/intro.md:
--------------------------------------------------------------------------------
1 | # Introduction to {{raw-name}}
2 |
3 | TODO: write [great documentation](http://jacobian.org/writing/what-to-write/)
4 |
--------------------------------------------------------------------------------
/resources/practicalli/minimal/root/.dir-locals.el:
--------------------------------------------------------------------------------
1 | ((clojure-mode . ((cider-preferred-build-tool . clojure-cli)
2 | (cider-clojure-cli-aliases . ":test/env:dev/reloaded"))))
3 |
--------------------------------------------------------------------------------
/resources/practicalli/service/root/.dir-locals.el:
--------------------------------------------------------------------------------
1 | ((clojure-mode . ((cider-preferred-build-tool . clojure-cli)
2 | (cider-clojure-cli-aliases . ":build:test/env:dev/reloaded"))))
3 |
--------------------------------------------------------------------------------
/resources/practicalli/application/root/.dir-locals.el:
--------------------------------------------------------------------------------
1 | ((clojure-mode . ((cider-preferred-build-tool . clojure-cli)
2 | (cider-clojure-cli-aliases . ":build:test/env:dev/reloaded"))))
3 |
--------------------------------------------------------------------------------
/.github/CODEOWNERS:
--------------------------------------------------------------------------------
1 | # Codeowners
2 |
3 | # Default owner accounts for the current repository
4 | # Automatically added as a reviewr to all pull requests (not including drafts)
5 |
6 | * @practicalli-johnny
7 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Git Attributes
2 |
3 | # reclassifies `.edn` as Clojure files for Linguist statistics
4 | # https://github.com/github/linguist/blob/master/docs/overrides.md
5 | **/*.edn linguist-language=Clojure
6 |
--------------------------------------------------------------------------------
/resources/practicalli/service/root/.github/CODEOWNERS:
--------------------------------------------------------------------------------
1 | # Codeowners
2 |
3 | # Default owner accounts for the current repository
4 | # Automatically added as a reviewr to all pull requests (not including drafts)
5 |
6 | * @{{developer}}
7 |
--------------------------------------------------------------------------------
/resources/practicalli/application/root/.github/CODEOWNERS:
--------------------------------------------------------------------------------
1 | # Codeowners
2 |
3 | # Default owner accounts for the current repository
4 | # Automatically added as a reviewr to all pull requests (not including drafts)
5 |
6 | * @{{developer}}
7 |
--------------------------------------------------------------------------------
/resources/practicalli/landing_page/root/.github/CODEOWNERS:
--------------------------------------------------------------------------------
1 | # Codeowners
2 |
3 | # Default owner accounts for the current repository
4 | # Automatically added as a reviewr to all pull requests (not including drafts)
5 |
6 | * @{{developer}}
7 |
--------------------------------------------------------------------------------
/resources/practicalli/landing_page/root/resources/public/test.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Test host page
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/resources/practicalli/minimal/root/.gitattributes:
--------------------------------------------------------------------------------
1 | # Git Attributes
2 |
3 | # reclassifies `.edn` as Clojure files for Linguist statistics
4 | # https://github.com/github/linguist/blob/master/docs/overrides.md
5 | **/*.edn linguist-language=Clojure
6 |
--------------------------------------------------------------------------------
/resources/practicalli/service/root/.gitattributes:
--------------------------------------------------------------------------------
1 | # Git Attributes
2 |
3 | # reclassifies `.edn` as Clojure files for Linguist statistics
4 | # https://github.com/github/linguist/blob/master/docs/overrides.md
5 | **/*.edn linguist-language=Clojure
6 |
--------------------------------------------------------------------------------
/.github/config/markdown-lint-check.json:
--------------------------------------------------------------------------------
1 | {
2 | "projectBaseUrl": "https://practical.li/clojure-web-services",
3 | "replacementPatterns": [
4 | {
5 | "pattern": "^/",
6 | "replacement": "/github/workspace/"
7 | }
8 | ]
9 | }
10 |
--------------------------------------------------------------------------------
/resources/practicalli/application/root/.gitattributes:
--------------------------------------------------------------------------------
1 | # Git Attributes
2 |
3 | # reclassifies `.edn` as Clojure files for Linguist statistics
4 | # https://github.com/github/linguist/blob/master/docs/overrides.md
5 | **/*.edn linguist-language=Clojure
6 |
--------------------------------------------------------------------------------
/resources/practicalli/landing_page/root/.gitattributes:
--------------------------------------------------------------------------------
1 | # Git Attributes
2 |
3 | # reclassifies `.edn` as Clojure files for Linguist statistics
4 | # https://github.com/github/linguist/blob/master/docs/overrides.md
5 | **/*.edn linguist-language=Clojure
6 |
--------------------------------------------------------------------------------
/resources/practicalli/service/root/.github/config/markdown-lint-check.json:
--------------------------------------------------------------------------------
1 | {
2 | "projectBaseUrl": "https://practical.li/clojure-web-services",
3 | "replacementPatterns": [
4 | {
5 | "pattern": "^/",
6 | "replacement": "/github/workspace/"
7 | }
8 | ]
9 | }
10 |
--------------------------------------------------------------------------------
/resources/practicalli/application/root/.github/config/markdown-lint-check.json:
--------------------------------------------------------------------------------
1 | {
2 | "projectBaseUrl": "https://practical.li/clojure-web-services",
3 | "replacementPatterns": [
4 | {
5 | "pattern": "^/",
6 | "replacement": "/github/workspace/"
7 | }
8 | ]
9 | }
10 |
--------------------------------------------------------------------------------
/resources/practicalli/landing_page/root/.github/config/markdown-lint-check.json:
--------------------------------------------------------------------------------
1 | {
2 | "projectBaseUrl": "https://practical.li/clojure-web-services",
3 | "replacementPatterns": [
4 | {
5 | "pattern": "^/",
6 | "replacement": "/github/workspace/"
7 | }
8 | ]
9 | }
10 |
--------------------------------------------------------------------------------
/tests.edn:
--------------------------------------------------------------------------------
1 | ;; ---------------------------------------------------------
2 | ;; Kaocha test runner configuration
3 | ;;
4 | ;; Default configuration
5 | ;; - show current config using either command:
6 | ;;
7 | ;; make test-config
8 | ;;
9 | ;; clojure -M:test/env:test/run --print-config
10 |
11 | ;; ---------------------------------------------------------
12 |
13 | #kaocha/v1 {}
14 |
--------------------------------------------------------------------------------
/resources/practicalli/service/dev/design_journal.clj:
--------------------------------------------------------------------------------
1 | ;; ---------------------------------------------------------
2 | ;; Design Journal
3 | ;;
4 | ;; Capturing design experiments and decisions whilst developing the project
5 | ;; ---------------------------------------------------------
6 |
7 | (ns design-journal)
8 |
9 | (comment
10 | ;; Capture important design decisions
11 |
12 | #_())
13 |
--------------------------------------------------------------------------------
/resources/practicalli/minimal/root/dev/design_journal.clj:
--------------------------------------------------------------------------------
1 | ;; ---------------------------------------------------------
2 | ;; Design Journal
3 | ;;
4 | ;; Capturing design experiments and decisions whilst developing the project
5 | ;; ---------------------------------------------------------
6 |
7 | (ns design-journal)
8 |
9 | (comment
10 | ;; Capture important design decisions
11 |
12 | #_())
13 |
--------------------------------------------------------------------------------
/resources/practicalli/application/root/dev/design_journal.clj:
--------------------------------------------------------------------------------
1 | ;; ---------------------------------------------------------
2 | ;; Design Journal
3 | ;;
4 | ;; Capturing design experiments and decisions whilst developing the project
5 | ;; ---------------------------------------------------------
6 |
7 | (ns design-journal)
8 |
9 | (comment
10 | ;; Capture important design decisions
11 |
12 | #_())
13 |
--------------------------------------------------------------------------------
/resources/practicalli/landing_page/root/dev/design_journal.cljs:
--------------------------------------------------------------------------------
1 | ;; ---------------------------------------------------------
2 | ;; Design Journal
3 | ;;
4 | ;; Capturing design experiments and decisions whilst developing the project
5 | ;; ---------------------------------------------------------
6 |
7 | (ns design-journal)
8 |
9 | (comment
10 | ;; Capture important design decisions
11 |
12 | #_())
13 |
--------------------------------------------------------------------------------
/resources/practicalli/minimal/root/tests.edn:
--------------------------------------------------------------------------------
1 | ;; ---------------------------------------------------------
2 | ;; Kaocha test runner configuration
3 | ;;
4 | ;; Default configuration
5 | ;; - show current config using either command:
6 | ;;
7 | ;; make test-config
8 | ;;
9 | ;; clojure -M:test/env:test/run --print-config
10 |
11 | ;; ---------------------------------------------------------
12 |
13 | #kaocha/v1 {}
14 |
--------------------------------------------------------------------------------
/resources/practicalli/service/root/tests.edn:
--------------------------------------------------------------------------------
1 | ;; ---------------------------------------------------------
2 | ;; Kaocha test runner configuration
3 | ;;
4 | ;; Default configuration
5 | ;; - show current config using either command:
6 | ;;
7 | ;; make test-config
8 | ;;
9 | ;; clojure -M:test/env:test/run --print-config
10 |
11 | ;; ---------------------------------------------------------
12 |
13 | #kaocha/v1 {}
14 |
--------------------------------------------------------------------------------
/resources/practicalli/application/root/tests.edn:
--------------------------------------------------------------------------------
1 | ;; ---------------------------------------------------------
2 | ;; Kaocha test runner configuration
3 | ;;
4 | ;; Default configuration
5 | ;; - show current config using either command:
6 | ;;
7 | ;; make test-config
8 | ;;
9 | ;; clojure -M:test/env:test/run --print-config
10 |
11 | ;; ---------------------------------------------------------
12 |
13 | #kaocha/v1 {}
14 |
--------------------------------------------------------------------------------
/resources/practicalli/landing_page/build/dev.cljs.edn.template:
--------------------------------------------------------------------------------
1 | ;; ---------------------------------------------------------
2 | ;; Development Build
3 | ;;
4 | ;; Watch src, text and css directories and reload on file saves
5 | ;; ---------------------------------------------------------
6 |
7 | ^{:watch-dirs ["test" "src"]
8 | :css-dirs ["resources/public/css"]
9 | :auto-testing true}
10 | {:main {{top/ns}}.{{main/ns}}}
11 |
--------------------------------------------------------------------------------
/.github/config/secretlintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "rules": [
3 | {
4 | "id": "@secretlint/secretlint-rule-basicauth",
5 | "options": {
6 | "allows": [
7 | "hostname.domain.com",
8 | "jdbc:postgresql://:port/?user=&password=",
9 | "postgres://postgres://username:password@hostname.domain.com:1234/database-name"
10 | ]
11 | }
12 | }
13 | ]
14 | }
15 |
--------------------------------------------------------------------------------
/resources/practicalli/landing_page/root/.dir-locals.el:
--------------------------------------------------------------------------------
1 | ((clojurescript-mode . ((cider-preferred-build-tool . clojure-cli)
2 | (cider-clojure-cli-aliases . ":test/env:figwheel/env:dev/reloaded-cljs")
3 | (cider-default-cljs-repl . figwheel-main)
4 | (cider-figwheel-main-default-options . "dev")
5 | (cider-repl-display-help-banner . nil))))
6 |
--------------------------------------------------------------------------------
/resources/practicalli/service/root/.github/config/secretlintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "rules": [
3 | {
4 | "id": "@secretlint/secretlint-rule-basicauth",
5 | "options": {
6 | "allows": [
7 | "hostname.domain.com",
8 | "jdbc:postgresql://:port/?user=&password=",
9 | "postgres://postgres://username:password@hostname.domain.com:1234/database-name"
10 | ]
11 | }
12 | }
13 | ]
14 | }
15 |
--------------------------------------------------------------------------------
/resources/practicalli/application/root/.github/config/secretlintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "rules": [
3 | {
4 | "id": "@secretlint/secretlint-rule-basicauth",
5 | "options": {
6 | "allows": [
7 | "hostname.domain.com",
8 | "jdbc:postgresql://:port/?user=&password=",
9 | "postgres://postgres://username:password@hostname.domain.com:1234/database-name"
10 | ]
11 | }
12 | }
13 | ]
14 | }
15 |
--------------------------------------------------------------------------------
/resources/practicalli/landing_page/root/.github/config/secretlintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "rules": [
3 | {
4 | "id": "@secretlint/secretlint-rule-basicauth",
5 | "options": {
6 | "allows": [
7 | "hostname.domain.com",
8 | "jdbc:postgresql://:port/?user=&password=",
9 | "postgres://postgres://username:password@hostname.domain.com:1234/database-name"
10 | ]
11 | }
12 | }
13 | ]
14 | }
15 |
--------------------------------------------------------------------------------
/resources/practicalli/landing_page/test/test_runner.cljs.template:
--------------------------------------------------------------------------------
1 | ;; ---------------------------------------------------------
2 | ;; {{top/ns}}.{{main/ns}}.test-runner
3 | ;;
4 | ;; Command Line test runner
5 | ;; - require `-test` namespace to include its tests in the runner
6 | ;; ---------------------------------------------------------
7 |
8 |
9 | (ns {{top/ns}}.test-runner
10 | (:require
11 | [{{top/ns}}.{{main/ns}}-test]
12 | [figwheel.main.testing :refer [run-tests-async]]))
13 |
14 | (defn -main [& args]
15 | (run-tests-async 5000))
16 |
--------------------------------------------------------------------------------
/.github/config/markdown-link-check.json:
--------------------------------------------------------------------------------
1 | {
2 | "ignorePatterns": [
3 | {
4 | "pattern": "^http://localhost"
5 | },
6 | {
7 | "pattern": "^mailto:*"
8 | },
9 | {
10 | "pattern": "^#*"
11 | },
12 | {
13 | "pattern": "^https://127.0.0.0/"
14 | }
15 | ],
16 | "timeout": "20s",
17 | "retryOn429": true,
18 | "retryCount": 5,
19 | "fallbackRetryDelay": "30s",
20 | "aliveStatusCodes": [
21 | 200,
22 | 206
23 | ]
24 | }
25 |
--------------------------------------------------------------------------------
/resources/practicalli/landing_page/build/github-pages.cljs.edn.template:
--------------------------------------------------------------------------------
1 | ;; ---------------------------------------------------------
2 | ;; Prepare for GitHub pages
3 | ;;
4 | ;; Deploy ClojureScript build in `/docs` directory
5 | ;; to be served by GitHub pages
6 | ;;
7 | ;; Configure the repository GitHub pages to serve from ``/docs``
8 | ;; ---------------------------------------------------------
9 |
10 | ^{:watch-dirs ["test" "src"]
11 | :css-dirs ["resources/public/css"]
12 | :auto-testing true}
13 | {:main {{top/ns}}.{{main/ns}}
14 | :output-to "docs/js/{{top/ns}}.{{main/ns}}.js"}
15 |
--------------------------------------------------------------------------------
/resources/practicalli/service/root/.github/config/markdown-link-check.json:
--------------------------------------------------------------------------------
1 | {
2 | "ignorePatterns": [
3 | {
4 | "pattern": "^http://localhost"
5 | },
6 | {
7 | "pattern": "^mailto:*"
8 | },
9 | {
10 | "pattern": "^#*"
11 | },
12 | {
13 | "pattern": "^https://127.0.0.0/"
14 | }
15 | ],
16 | "timeout": "20s",
17 | "retryOn429": true,
18 | "retryCount": 5,
19 | "fallbackRetryDelay": "30s",
20 | "aliveStatusCodes": [
21 | 200,
22 | 206
23 | ]
24 | }
25 |
--------------------------------------------------------------------------------
/resources/practicalli/application/root/.github/config/markdown-link-check.json:
--------------------------------------------------------------------------------
1 | {
2 | "ignorePatterns": [
3 | {
4 | "pattern": "^http://localhost"
5 | },
6 | {
7 | "pattern": "^mailto:*"
8 | },
9 | {
10 | "pattern": "^#*"
11 | },
12 | {
13 | "pattern": "^https://127.0.0.0/"
14 | }
15 | ],
16 | "timeout": "20s",
17 | "retryOn429": true,
18 | "retryCount": 5,
19 | "fallbackRetryDelay": "30s",
20 | "aliveStatusCodes": [
21 | 200,
22 | 206
23 | ]
24 | }
25 |
--------------------------------------------------------------------------------
/resources/practicalli/landing_page/root/.github/config/markdown-link-check.json:
--------------------------------------------------------------------------------
1 | {
2 | "ignorePatterns": [
3 | {
4 | "pattern": "^http://localhost"
5 | },
6 | {
7 | "pattern": "^mailto:*"
8 | },
9 | {
10 | "pattern": "^#*"
11 | },
12 | {
13 | "pattern": "^https://127.0.0.0/"
14 | }
15 | ],
16 | "timeout": "20s",
17 | "retryOn429": true,
18 | "retryCount": 5,
19 | "fallbackRetryDelay": "30s",
20 | "aliveStatusCodes": [
21 | 200,
22 | 206
23 | ]
24 | }
25 |
--------------------------------------------------------------------------------
/resources/practicalli/application/root/.dockerignore:
--------------------------------------------------------------------------------
1 | # ------------------------
2 | # Docker Ignore file patterns
3 | # https://docs.docker.com/engine/reference/builder/#dockerignore-file
4 | #
5 | # Ignore local files that match any pattern when using the COPY command in Dockerfile
6 | # reducing the amount of time required to copy files
7 | # ------------------------
8 |
9 |
10 | # ------------------------
11 | # Ignore all files
12 | *
13 |
14 | # ------------------------
15 | # Include Clojure code and config
16 | !deps.edn
17 | !build.clj
18 | !Makefile
19 | !src/
20 | !test/
21 | !test-data/
22 | !resources/
23 |
--------------------------------------------------------------------------------
/resources/practicalli/service/root/.dockerignore:
--------------------------------------------------------------------------------
1 | # ------------------------
2 | # Docker Ignore file patterns
3 | # https://docs.docker.com/engine/reference/builder/#dockerignore-file
4 | #
5 | # Ignore local files that match any pattern when using the COPY command in Dockerfile
6 | # reducing the amount of time required to copy files
7 | # ------------------------
8 |
9 |
10 | # ------------------------
11 | # Ignore all files
12 | *
13 |
14 | # ------------------------
15 | # Include Clojure code and config
16 | !deps.edn
17 | !build.clj
18 | !Makefile
19 | !src/
20 | !test/
21 | !test-data/
22 | !resources/
23 |
--------------------------------------------------------------------------------
/resources/practicalli/landing_page/build/test.cljs.edn.template:
--------------------------------------------------------------------------------
1 | ;; ---------------------------------------------------------
2 | ;; Test Runner configuration
3 | ;; ---------------------------------------------------------
4 |
5 | ^{
6 | ;; use an alternative landing page for the tests so that we don't
7 | ;; launch the application
8 | :open-url "http://[[server-hostname]]:[[server-port]]/test.html"
9 |
10 | ;; uncomment to launch tests in a headless environment
11 | ;; you will have to figure out the path to chrome on your system
12 | ;; :launch-js ["/Applications/Google Chrome.app/Contents/MacOS/Google Chrome" "--headless" "--disable-gpu" "--repl" :open-url]
13 | }
14 | {:main {{top/ns}}.test-runner}
15 |
--------------------------------------------------------------------------------
/resources/practicalli/service/root/.github/FUNDING.yaml:
--------------------------------------------------------------------------------
1 | ---
2 | # GitHub Supported funding model platforms
3 |
4 | github: [{ { developer } }]
5 | # patreon: # Replace with a single Patreon username
6 | # open_collective: # Replace with a single Open Collective username
7 | # ko_fi: # Replace with a single Ko-fi username
8 | # tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
9 | # community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
10 | # liberapay: # Replace with a single Liberapay username
11 | # issuehunt: # Replace with a single IssueHunt username
12 | # otechie: # Replace with a single Otechie username
13 | # custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
14 |
--------------------------------------------------------------------------------
/resources/practicalli/application/root/.github/FUNDING.yaml:
--------------------------------------------------------------------------------
1 | ---
2 | # GitHub Supported funding model platforms
3 |
4 | github: [{ { developer } }]
5 | # patreon: # Replace with a single Patreon username
6 | # open_collective: # Replace with a single Open Collective username
7 | # ko_fi: # Replace with a single Ko-fi username
8 | # tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
9 | # community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
10 | # liberapay: # Replace with a single Liberapay username
11 | # issuehunt: # Replace with a single IssueHunt username
12 | # otechie: # Replace with a single Otechie username
13 | # custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
14 |
--------------------------------------------------------------------------------
/resources/practicalli/landing_page/root/.github/FUNDING.yaml:
--------------------------------------------------------------------------------
1 | ---
2 | # GitHub Supported funding model platforms
3 |
4 | github: [{ { developer } }]
5 | # patreon: # Replace with a single Patreon username
6 | # open_collective: # Replace with a single Open Collective username
7 | # ko_fi: # Replace with a single Ko-fi username
8 | # tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
9 | # community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
10 | # liberapay: # Replace with a single Liberapay username
11 | # issuehunt: # Replace with a single IssueHunt username
12 | # otechie: # Replace with a single Otechie username
13 | # custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
14 |
--------------------------------------------------------------------------------
/resources/practicalli/application/root/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # {{raw-name}} Changelog
2 |
3 | All notable changes to this project will be documented in this file.
4 | The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
5 |
6 | * **Added** for new features
7 | * **Changed** for changes in existing functionality
8 | * **Deprecated** for soon-to-be removed features
9 | * **Resolved** resolved issue
10 | * **Security** vulnerability related change
11 |
12 | ## [Unreleased]
13 |
14 | ### Changed
15 |
16 | ## 0.1.0 - {{now/date}}
17 |
18 | ### Added
19 |
20 | * [#1](https://github.com/practicalli/clojure/issues/1) Created {{raw-name}} project with deps-new using practicalli.template/service
21 |
22 | [Unreleased]: https://{{scm/domain}}/{{scm/user}}/{{scm/repo}}/compare/0.1.1...HEAD
23 |
--------------------------------------------------------------------------------
/resources/practicalli/minimal/root/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # {{raw-name}} Changelog
2 |
3 | All notable changes to this project will be documented in this file.
4 | The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
5 |
6 | * **Added** for new features
7 | * **Changed** for changes in existing functionality
8 | * **Deprecated** for soon-to-be removed features
9 | * **Resolved** resolved issue
10 | * **Security** vulnerability related change
11 |
12 | ## [Unreleased]
13 |
14 | ### Changed
15 |
16 | ## 0.1.0 - {{now/date}}
17 |
18 | ### Added
19 |
20 | * [#1](https://github.com/practicalli/clojure/issues/1) Created {{raw-name}} project with deps-new using practicalli.template/service
21 |
22 | [Unreleased]: https://{{scm/domain}}/{{scm/user}}/{{scm/repo}}/compare/0.1.1...HEAD
23 |
--------------------------------------------------------------------------------
/resources/practicalli/service/root/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # {{raw-name}} Changelog
2 |
3 | All notable changes to this project will be documented in this file.
4 | The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
5 |
6 | * **Added** for new features
7 | * **Changed** for changes in existing functionality
8 | * **Deprecated** for soon-to-be removed features
9 | * **Resolved** resolved issue
10 | * **Security** vulnerability related change
11 |
12 | ## [Unreleased]
13 |
14 | ### Changed
15 |
16 | ## 0.1.0 - {{now/date}}
17 |
18 | ### Added
19 |
20 | * [#1](https://github.com/practicalli/clojure/issues/1) Created {{raw-name}} project with deps-new using practicalli.template/service
21 |
22 | [Unreleased]: https://{{scm/domain}}/{{scm/user}}/{{scm/repo}}/compare/0.1.1...HEAD
23 |
--------------------------------------------------------------------------------
/resources/practicalli/landing_page/root/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # {{raw-name}} Changelog
2 |
3 | All notable changes to this project will be documented in this file.
4 | The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
5 |
6 | * **Added** for new features
7 | * **Changed** for changes in existing functionality
8 | * **Deprecated** for soon-to-be removed features
9 | * **Resolved** resolved issue
10 | * **Security** vulnerability related change
11 |
12 | ## [Unreleased]
13 |
14 | ### Changed
15 |
16 | ## 0.1.0 - {{now/date}}
17 |
18 | ### Added
19 |
20 | * [#1](https://github.com/practicalli/clojure/issues/1) Created {{raw-name}} project with deps-new using practicalli.template/service
21 |
22 | [Unreleased]: https://{{scm/domain}}/{{scm/user}}/{{scm/repo}}/compare/0.1.1...HEAD
23 |
--------------------------------------------------------------------------------
/resources/practicalli/service/docker/compose-service.yaml.template:
--------------------------------------------------------------------------------
1 | ---
2 | # --- Docker Compose Configuration --- #
3 | # - Docker Compose V2
4 | # - https://docs.docker.com/compose/compose-file/
5 | #
6 | # Build the Clojure Service from source code
7 | # and run on port 8080
8 | #
9 | # Examples of persistence with Postgres and mysql docker images
10 | # and local data storage to facilitate data restoration
11 |
12 | name: "{{top/ns}}"
13 |
14 | services:
15 | # --- Clojure Service --- #
16 | {{main/ns}}-service:
17 | platform: linux/amd64
18 | # Build using Dockerfile - relative path or Git repository
19 | build:
20 | context: ./ # Use Dockerfile in project root
21 | environment: # host:container
22 | - COMPOSE_PROJECT_NAME
23 | ports: # host:container
24 | - 8080:8080
25 |
--------------------------------------------------------------------------------
/deps.edn:
--------------------------------------------------------------------------------
1 | {:paths ["src" "resources"]
2 |
3 | :deps
4 | {org.clojure/clojure {:mvn/version "1.12.3"}}
5 |
6 | :aliases
7 | {;; Add libraries and paths to support additional test tools
8 | :test/env
9 | {:extra-paths ["test"]
10 | :extra-deps {org.clojure/test.check {:mvn/version "1.1.1"}
11 | ;; https://github.com/seancorfield/deps-new/
12 | io.github.seancorfield/deps-new
13 | {:git/tag "v0.10.1" :git/sha "a90029c"}}}
14 |
15 | ;; Test runner - local and CI
16 | ;; call with `:watch? true` argument to start file watcher and re-run tests on saved changes
17 | :test/run
18 | {:extra-paths ["test"]
19 | :extra-deps {lambdaisland/kaocha {:mvn/version "1.91.1392"}}
20 | :main-opts ["-m" "kaocha.runner"]
21 | :exec-fn kaocha.runner/exec-fn
22 | :exec-args {:randomize? false
23 | :fail-fast? true}}}}
24 |
--------------------------------------------------------------------------------
/.github/pull_request_template.md:
--------------------------------------------------------------------------------
1 | 📓 Description
2 |
3 | # _Summary of the change and link to any relevant tickets. New aliases should include details of why they are valuable_
4 |
5 | # GitHub issues:
6 | # Resolve #
7 | # Refer #
8 |
9 | :octocat Type of change
10 |
11 | - [ ] New feature
12 | - [ ] Deprecate feature
13 | - [ ] Development workflow
14 | - [ ] Documentation
15 | - [ ] Continuous integration workflow
16 |
17 | :beetle How Has This Been Tested?
18 |
19 | - [ ] unit test
20 | - [ ] linter check
21 | - [x] GitHub Action checkers
22 |
23 | :eyes Checklist
24 |
25 | - [ ] Commits should be cryptographically signed (SSH or GPG)
26 | - [ ] Code follows the [Practicalli cljstyle configuration](https://practical.li/clojure/clojure-cli/clojure-style/#cljstyle)
27 | - [ ] Add / update alias docs and README where relevant
28 | - [ ] Changelog entry describing notable changes
29 | - [ ] Request maintainers review the PR
30 |
--------------------------------------------------------------------------------
/resources/practicalli/landing_page/root/tests.edn:
--------------------------------------------------------------------------------
1 | ;; ---------------------------------------------------------
2 | ;; Kaocha test runner configuration
3 | ;; - https://github.com/lambdaisland/kaocha-cljs
4 | ;;
5 | ;; Default configuration
6 | ;; - show current config using either command:
7 | ;;
8 | ;; make test-config
9 | ;;
10 | ;; clojure -M:test/env:test/run --print-config
11 |
12 | ;; ---------------------------------------------------------
13 |
14 | #kaocha/v1
15 | {:tests [{:id :unit-cljs
16 | :type :kaocha.type/cljs
17 | :test-paths ["test"]
18 | ;; :cljs/timeout 10000 ; 10 seconds, the default
19 |
20 | ;; REPL environment - node, web, figwheel
21 | ;; :cljs/repl-env cljs.repl.node/repl-env ; node is the default
22 | :cljs/repl-env cljs.repl.browser/repl-env
23 | ;; :cljs/repl-env figwheel.repl/repl-env
24 | }]}
25 |
--------------------------------------------------------------------------------
/resources/practicalli/service/root/swagger-compose.yaml:
--------------------------------------------------------------------------------
1 | ---
2 | # --- OpenAPI Swagger Compose Configuration --- #
3 | # - Docker Compose V2
4 | # - https://docs.docker.com/compose/compose-file/
5 | # - https://hub.docker.com/r/swaggerapi/swagger-editor
6 | #
7 | # Run the Swagger editor in docker to test API specifications
8 | # in JSON or YAML formats
9 | #
10 | # Alternatively use: https://editor-next.swagger.io/
11 | # --------------------------------------------- #
12 |
13 |
14 | # --------------------------------------------- #
15 | # Using Swagger Editor
16 | #
17 | # make swagger-editor
18 | # make swagger-editor-down
19 | #
20 | # Open: http://localhost:8282 and paste OpenAPI specification
21 | # --------------------------------------------- #
22 |
23 | # Local OpenAPI (Swagger) Editor to debug swagger open api definition
24 | services:
25 | swagger-editor:
26 | image: "swaggerapi/swagger-editor:latest"
27 | ports:
28 | - "8282:8080"
29 |
--------------------------------------------------------------------------------
/resources/practicalli/application/root/swagger-compose.yaml:
--------------------------------------------------------------------------------
1 | ---
2 | # --- OpenAPI Swagger Compose Configuration --- #
3 | # - Docker Compose V2
4 | # - https://docs.docker.com/compose/compose-file/
5 | # - https://hub.docker.com/r/swaggerapi/swagger-editor
6 | #
7 | # Run the Swagger editor in docker to test API specifications
8 | # in JSON or YAML formats
9 | #
10 | # Alternatively use: https://editor-next.swagger.io/
11 | # --------------------------------------------- #
12 |
13 |
14 | # --------------------------------------------- #
15 | # Using Swagger Editor
16 | #
17 | # make swagger-editor
18 | # make swagger-editor-down
19 | #
20 | # Open: http://localhost:8282 and paste OpenAPI specification
21 | # --------------------------------------------- #
22 |
23 | # Local OpenAPI (Swagger) Editor to debug swagger open api definition
24 | services:
25 | swagger-editor:
26 | image: "swaggerapi/swagger-editor:latest"
27 | ports:
28 | - "8282:8080"
29 |
--------------------------------------------------------------------------------
/resources/practicalli/service/root/.github/pull_request_template.md:
--------------------------------------------------------------------------------
1 | 📓 Description
2 |
3 | _Summary of the change and link to any relevant tickets. New aliases should include details of why they are valuable_
4 |
5 | # GitHub issues:
6 | # Resolve #
7 | # Refer #
8 |
9 | :octocat Type of change
10 |
11 | - [ ] New feature
12 | - [ ] Deprecate feature
13 | - [ ] Development workflow
14 | - [ ] Documentation
15 | - [ ] Continuous integration workflow
16 |
17 | :beetle How Has This Been Tested?
18 |
19 | - [ ] unit test
20 | - [ ] linter check
21 | - [x] GitHub Action checkers
22 |
23 | :eyes Checklist
24 |
25 | - [ ] Commits should be cryptographically signed (SSH or GPG)
26 | - [ ] Code follows the [Practicalli cljstyle configuration](https://practical.li/clojure/clojure-cli/clojure-style/#cljstyle)
27 | - [ ] Add / update alias docs and README where relevant
28 | - [ ] Changelog entry describing notable changes
29 | - [ ] Request maintainers review the PR
30 |
--------------------------------------------------------------------------------
/resources/practicalli/application/root/.github/pull_request_template.md:
--------------------------------------------------------------------------------
1 | 📓 Description
2 |
3 | # _Summary of the change and link to any relevant tickets. New aliases should include details of why they are valuable_
4 |
5 | # GitHub issues:
6 | # Resolve #
7 | # Refer #
8 |
9 | :octocat Type of change
10 |
11 | - [ ] New feature
12 | - [ ] Deprecate feature
13 | - [ ] Development workflow
14 | - [ ] Documentation
15 | - [ ] Continuous integration workflow
16 |
17 | :beetle How Has This Been Tested?
18 |
19 | - [ ] unit test
20 | - [ ] linter check
21 | - [x] GitHub Action checkers
22 |
23 | :eyes Checklist
24 |
25 | - [ ] Commits should be cryptographically signed (SSH or GPG)
26 | - [ ] Code follows the [Practicalli cljstyle configuration](https://practical.li/clojure/clojure-cli/clojure-style/#cljstyle)
27 | - [ ] Add / update alias docs and README where relevant
28 | - [ ] Changelog entry describing notable changes
29 | - [ ] Request maintainers review the PR
30 |
--------------------------------------------------------------------------------
/resources/practicalli/landing_page/root/.github/pull_request_template.md:
--------------------------------------------------------------------------------
1 | 📓 Description
2 |
3 | _Summary of the change and link to any relevant tickets. New aliases should include details of why they are valuable_
4 |
5 | # GitHub issues:
6 | # Resolve #
7 | # Refer #
8 |
9 | :octocat Type of change
10 |
11 | - [ ] New feature
12 | - [ ] Deprecate feature
13 | - [ ] Development workflow
14 | - [ ] Documentation
15 | - [ ] Continuous integration workflow
16 |
17 | :beetle How Has This Been Tested?
18 |
19 | - [ ] unit test
20 | - [ ] linter check
21 | - [x] GitHub Action checkers
22 |
23 | :eyes Checklist
24 |
25 | - [ ] Commits should be cryptographically signed (SSH or GPG)
26 | - [ ] Code follows the [Practicalli cljstyle configuration](https://practical.li/clojure/clojure-cli/clojure-style/#cljstyle)
27 | - [ ] Add / update alias docs and README where relevant
28 | - [ ] Changelog entry describing notable changes
29 | - [ ] Request maintainers review the PR
30 |
--------------------------------------------------------------------------------
/resources/practicalli/landing_page/test/main_page_test.cljs.template:
--------------------------------------------------------------------------------
1 | ;; ---------------------------------------------------------
2 | ;; {{top/ns}}.{{main/ns}}-test
3 | ;;
4 | ;; Example unit tests for {{top/ns}}.{{main/ns}}
5 | ;;
6 | ;; - `deftest` - test a specific function
7 | ;; - `testing` logically group assertions within a function test
8 | ;; - `is` assertion: expected value then function call
9 | ;; ---------------------------------------------------------
10 |
11 | (ns {{top/ns}}.{{main/ns}}-test
12 | (:require
13 | [cljs.test :refer-macros [deftest is testing]]
14 | [{{top/ns}}.{{main/ns}} :as {{main/ns}}]))
15 |
16 |
17 | (deftest main-page-test
18 | (testing "TODO: Group together assertions in a meaningful scenario"
19 | (is (true? true))
20 | ))
21 |
22 |
23 | ;; Possible tests
24 | ;; - structure of landing page, e.g. are all sections present
25 | ;; - important pieces of data, e.g. last updated has a correct form of value
26 |
--------------------------------------------------------------------------------
/test/practicalli/minimal_test.clj:
--------------------------------------------------------------------------------
1 | ;; ---------------------------------------------------------
2 | ;; Unit and specification tests for practicalli/application template
3 | ;;
4 | ;; Test the template.edn file of the application template
5 | ;; using the deps-new specification
6 | ;; ---------------------------------------------------------
7 |
8 |
9 | (ns practicalli.minimal-test
10 | (:require
11 | [clojure.edn :as edn]
12 | [clojure.java.io :as io]
13 | [clojure.spec.alpha :as spec]
14 | [clojure.test :refer [deftest is testing]]
15 | [org.corfield.new]
16 | ;; deps-new Specs
17 | #_[practicalli.application :as application]))
18 |
19 | (deftest valid-template-test
20 | (testing "template.edn is valid."
21 | (let [template (edn/read-string (slurp (io/resource "practicalli/application/template.edn")))]
22 | (is (spec/valid? :org.corfield.new/template template)
23 | (spec/explain-str :org.corfield.new/template template)))))
24 |
--------------------------------------------------------------------------------
/resources/practicalli/service/dev/portal.clj:
--------------------------------------------------------------------------------
1 | (ns portal
2 | (:require
3 | ;; Data inspector
4 | [portal.api :as inspect]))
5 |
6 |
7 | ;; ---------------------------------------------------------
8 | ;; Start Portal and capture all evaluation results
9 |
10 | ;; Open Portal window in browser with dark theme
11 | ;; https://cljdoc.org/d/djblue/portal/0.37.1/doc/ui-concepts/themes
12 | ;; Portal options:
13 | ;; - light theme {:portal.colors/theme :portal.colors/solarized-light}
14 | ;; - dark theme {:portal.colors/theme :portal.colors/gruvbox}
15 |
16 | (def instance
17 | "Open portal window if no portal sessions have been created.
18 | A portal session is created when opening a portal window"
19 | (or (seq (inspect/sessions))
20 | (inspect/open {:portal.colors/theme :portal.colors/gruvbox})))
21 |
22 | ;; Add portal as tapsource (add to clojure.core/tapset)
23 | (add-tap #'portal.api/submit)
24 | ;; ---------------------------------------------------------
25 |
--------------------------------------------------------------------------------
/test/practicalli/application_test.clj:
--------------------------------------------------------------------------------
1 | ;; ---------------------------------------------------------
2 | ;; Unit and specification tests for practicalli/application template
3 | ;;
4 | ;; Test the template.edn file of the application template
5 | ;; using the deps-new specification
6 | ;; ---------------------------------------------------------
7 |
8 |
9 | (ns practicalli.application-test
10 | (:require
11 | [clojure.edn :as edn]
12 | [clojure.java.io :as io]
13 | [clojure.spec.alpha :as spec]
14 | [clojure.test :refer [deftest is testing]]
15 | [org.corfield.new]
16 | ;; deps-new Specs
17 | #_[practicalli.application :as application]))
18 |
19 |
20 | (deftest valid-template-test
21 | (testing "template.edn is valid."
22 | (let [template (edn/read-string (slurp (io/resource "practicalli/application/template.edn")))]
23 | (is (spec/valid? :org.corfield.new/template template)
24 | (spec/explain-str :org.corfield.new/template template)))))
25 |
--------------------------------------------------------------------------------
/resources/practicalli/application/root/dev/portal.clj:
--------------------------------------------------------------------------------
1 | (ns portal
2 | (:require
3 | ;; Data inspector
4 | [portal.api :as inspect]))
5 |
6 | ;; ---------------------------------------------------------
7 | ;; Start Portal and capture all evaluation results
8 |
9 | ;; Open Portal window in browser with dark theme
10 | ;; https://cljdoc.org/d/djblue/portal/0.37.1/doc/ui-concepts/themes
11 | ;; Portal options:
12 | ;; - light theme {:portal.colors/theme :portal.colors/solarized-light}
13 | ;; - dark theme {:portal.colors/theme :portal.colors/gruvbox}
14 |
15 | (def instance
16 | "Open portal window if no portal sessions have been created.
17 | A portal session is created when opening a portal window"
18 | (or (seq (inspect/sessions))
19 | (inspect/open {:portal.colors/theme :portal.colors/gruvbox})))
20 |
21 | ;; Add portal as tapsource (add to clojure.core/tapset)
22 | (add-tap #'portal.api/submit)
23 | ;; ---------------------------------------------------------
24 |
--------------------------------------------------------------------------------
/resources/practicalli/minimal/root/dev/portal.clj:
--------------------------------------------------------------------------------
1 | (ns portal
2 | (:require
3 | ;; Data inspector
4 | [portal.api :as inspect]))
5 |
6 |
7 | ;; ---------------------------------------------------------
8 | ;; Start Portal and capture all evaluation results
9 |
10 | ;; Open Portal window in browser with dark theme
11 | ;; https://cljdoc.org/d/djblue/portal/0.37.1/doc/ui-concepts/themes
12 | ;; Portal options:
13 | ;; - light theme {:portal.colors/theme :portal.colors/solarized-light}
14 | ;; - dark theme {:portal.colors/theme :portal.colors/gruvbox}
15 |
16 | (def instance
17 | "Open portal window if no portal sessions have been created.
18 | A portal session is created when opening a portal window"
19 | (or (seq (inspect/sessions))
20 | (inspect/open {:portal.colors/theme :portal.colors/gruvbox})))
21 |
22 | ;; Add portal as tapsource (add to clojure.core/tapset)
23 | (add-tap #'portal.api/submit)
24 | ;; ---------------------------------------------------------
25 |
--------------------------------------------------------------------------------
/test/practicalli/landing_page_test.clj:
--------------------------------------------------------------------------------
1 | ;; ---------------------------------------------------------
2 | ;; Unit and specification tests for practicalli/application template
3 | ;;
4 | ;; Test the template.edn file of the application template
5 | ;; using the deps-new specification
6 | ;; ---------------------------------------------------------
7 |
8 |
9 | (ns practicalli.landing-page-test
10 | (:require
11 | [clojure.edn :as edn]
12 | [clojure.java.io :as io]
13 | [clojure.spec.alpha :as spec]
14 | [clojure.test :refer [deftest is testing]]
15 | [org.corfield.new]
16 | ;; deps-new Specs
17 | #_[practicalli.application :as application]))
18 |
19 |
20 | (deftest valid-template-test
21 | (testing "template.edn is valid."
22 | (let [template (edn/read-string (slurp (io/resource "practicalli/application/template.edn")))]
23 | (is (spec/valid? :org.corfield.new/template template)
24 | (spec/explain-str :org.corfield.new/template template)))))
25 |
--------------------------------------------------------------------------------
/resources/practicalli/service/src/parse_system.clj.template:
--------------------------------------------------------------------------------
1 | ;; --------------------------------------------------
2 | ;; Prepare system configuration with juxt/aero
3 | ;; --------------------------------------------------
4 |
5 | (ns {{top/ns}}.{{main/ns}}.parse-system
6 | (:require
7 | [aero.core :as aero]
8 | [clojure.java.io :as io]
9 |
10 | ;; Debug aero parsing - comment by default
11 | ;; [com.brunobonacci.mulog :as mulog]
12 | ))
13 |
14 | ;; --------------------------------------------------
15 | ;; Parse system configuration
16 | ;; - update system configuration with respect to a given profile
17 |
18 | (defn aero-config
19 | "Profile specific configuration for all services.
20 | Profiles supported: :dev :test :prod"
21 | [profile]
22 | ;; (mulog/log ::aero-parse-config :profile profile :local-time (java.time.LocalDateTime/now)
23 | (aero/read-config (io/resource "config.edn") {:profile profile}))
24 |
25 | ;; End of Aero Parsing
26 | ;; ---------------------------------------------------------
27 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # ------------------------
2 | # Clojure Project Git Ignore file patterns
3 | #
4 | # Ignore all except patterns starting with !
5 | # Add comments on separate lines, not same line as pattern
6 | # ------------------------
7 |
8 | # ------------------------
9 | # Ignore everthing in root directory
10 | /*
11 |
12 | # ------------------------
13 | # Common project files
14 | !CHANGELOG.md
15 | !README.md
16 | !LICENSE
17 |
18 | # ------------------------
19 | # Include Clojure project & config
20 | !build.clj
21 | !deps.edn
22 | !pom.xml
23 | !dev/
24 | !docs/
25 | !resources/
26 | !src/
27 | !test/
28 |
29 | # ------------------------
30 | # Include Clojure tools
31 | !.cljstyle
32 | !.dir-locals.el
33 | !compose.yaml
34 | !Dockerfile
35 | !.dockerignore
36 | !**/.clj-kondo/config.edn
37 | !Makefile
38 | !tests.edn
39 |
40 | # ------------------------
41 | # Include Git & CI workflow
42 | !.gitattributes
43 | !.gitignore
44 | !.github/
45 |
46 | # ------------------------
47 | # Include ClojureScript Figwheel
48 | !figwheel-main.edn
49 | !*.cljs.edn
50 |
--------------------------------------------------------------------------------
/resources/practicalli/minimal/root/.gitignore:
--------------------------------------------------------------------------------
1 | # ------------------------
2 | # Clojure Project Git Ignore file patterns
3 | #
4 | # Ignore all except patterns starting with !
5 | # Add comments on separate lines, not same line as pattern
6 | # ------------------------
7 |
8 | # ------------------------
9 | # Ignore everthing in root directory
10 | /*
11 |
12 | # ------------------------
13 | # Common project files
14 | !CHANGELOG.md
15 | !README.md
16 | !LICENSE
17 |
18 | # ------------------------
19 | # Include Clojure project & config
20 | !build.clj
21 | !deps.edn
22 | !pom.xml
23 | !dev/
24 | !docs/
25 | !resources/
26 | !src/
27 | !test/
28 |
29 | # ------------------------
30 | # Include Clojure tools
31 | !.cljstyle
32 | !.dir-locals.el
33 | !compose.yaml
34 | !Dockerfile
35 | !.dockerignore
36 | !Makefile
37 | !tests.edn
38 |
39 | # ------------------------
40 | # Include Git & CI workflow
41 | !.gitattributes
42 | !.gitignore
43 | !.github/
44 |
45 | # ------------------------
46 | # Include ClojureScript Figwheel
47 | !figwheel-main.edn
48 | !*.cljs.edn
49 |
--------------------------------------------------------------------------------
/resources/practicalli/application/root/.gitignore:
--------------------------------------------------------------------------------
1 | # ------------------------
2 | # Clojure Project Git Ignore file patterns
3 | #
4 | # Ignore all except patterns starting with !
5 | # Add comments on separate lines, not same line as pattern
6 | # ------------------------
7 |
8 | # ------------------------
9 | # Ignore everthing in root directory
10 | /*
11 |
12 | # ------------------------
13 | # Common project files
14 | !CHANGELOG.md
15 | !README.md
16 | !LICENSE
17 |
18 | # ------------------------
19 | # Include Clojure project & config
20 | !build.clj
21 | !deps.edn
22 | !pom.xml
23 | !dev/
24 | !docs/
25 | !resources/
26 | !src/
27 | !test/
28 |
29 | # ------------------------
30 | # Include Clojure tools
31 | !.cljstyle
32 | !.dir-locals.el
33 | !compose.yaml
34 | !Dockerfile
35 | !.dockerignore
36 | !Makefile
37 | !tests.edn
38 |
39 | # ------------------------
40 | # Include Git & CI workflow
41 | !.gitattributes
42 | !.gitignore
43 | !.github/
44 |
45 | # ------------------------
46 | # Include ClojureScript Figwheel
47 | !figwheel-main.edn
48 | !*.cljs.edn
49 |
--------------------------------------------------------------------------------
/resources/practicalli/landing_page/root/.gitignore:
--------------------------------------------------------------------------------
1 | # ------------------------
2 | # Clojure Project Git Ignore file patterns
3 | #
4 | # Ignore all except patterns starting with !
5 | # Add comments on separate lines, not same line as pattern
6 | # ------------------------
7 |
8 | # ------------------------
9 | # Ignore everthing in root directory
10 | /*
11 |
12 | # ------------------------
13 | # Common project files
14 | !CHANGELOG.md
15 | !README.md
16 | !LICENSE
17 |
18 | # ------------------------
19 | # Include Clojure project & config
20 | !build.clj
21 | !deps.edn
22 | !pom.xml
23 | !dev/
24 | !docs/
25 | !resources/
26 | !src/
27 | !test/
28 |
29 | # ------------------------
30 | # Include Clojure tools
31 | !.cljstyle
32 | !.dir-locals.el
33 | !compose.yaml
34 | !Dockerfile
35 | !.dockerignore
36 | !Makefile
37 | !tests.edn
38 |
39 | # ------------------------
40 | # Include Git & CI workflow
41 | !.gitattributes
42 | !.gitignore
43 | !.github/
44 |
45 | # ------------------------
46 | # Include ClojureScript Figwheel
47 | !figwheel-main.edn
48 | !*.cljs.edn
49 |
--------------------------------------------------------------------------------
/resources/practicalli/service/root/.gitignore:
--------------------------------------------------------------------------------
1 | # ------------------------
2 | # Clojure Project Git Ignore file patterns
3 | #
4 | # Ignore all except patterns starting with !
5 | # Add comments on separate lines, not same line as pattern
6 | # ------------------------
7 |
8 | # ------------------------
9 | # Ignore everthing in root directory
10 | /*
11 |
12 | # ------------------------
13 | # Common project files
14 | !CHANGELOG.md
15 | !README.md
16 | !LICENSE
17 |
18 | # ------------------------
19 | # Include Clojure project & config
20 | !build.clj
21 | !deps.edn
22 | !pom.xml
23 | !dev/
24 | !docs/
25 | !resources/
26 | !src/
27 | !test/
28 |
29 | # ------------------------
30 | # Include Clojure tools
31 | !.cljstyle
32 | !.dir-locals.el
33 | !compose.yaml
34 | !Dockerfile
35 | !.dockerignore
36 | !.clj-kondo/config.edn
37 | !Makefile
38 | !tests.edn
39 |
40 | # ------------------------
41 | # Include Git & CI workflow
42 | !.gitattributes
43 | !.gitignore
44 | !.github/
45 |
46 | # ------------------------
47 | # Include ClojureScript Figwheel
48 | !figwheel-main.edn
49 | !*.cljs.edn
50 |
--------------------------------------------------------------------------------
/resources/practicalli/service/src/spec.clj.template:
--------------------------------------------------------------------------------
1 | ;; ---------------------------------------------------------
2 | ;; {{top/ns}}.{{main/ns}}.spec
3 | ;;
4 | ;; Value specifications for {{main/ns}}
5 | ;; - API request / response validation
6 | ;;
7 | ;; Used in
8 | ;; - `{{top/ns}}.{{main/ns}}.api/scoreboard`
9 | ;; ---------------------------------------------------------
10 |
11 |
12 | (ns {{top/ns}}.{{main/ns}}.spec
13 | (:require [clojure.spec.alpha :as spec]))
14 |
15 | ;; ---------------------------------------------------
16 | ;; Value specifications
17 |
18 | (spec/def ::game-id string?)
19 | (spec/def ::game-name string?)
20 | (spec/def ::high-score string?)
21 | (spec/def ::comment string?)
22 |
23 |
24 | (spec/def ::scoreboard
25 | (spec/coll-of
26 | (spec/keys
27 | :req [::game-id ::game-name ::high-score]
28 | :opt [::comment])))
29 | ;; ---------------------------------------------------
30 |
31 |
32 | (comment
33 |
34 | ;; true example
35 | (spec/valid? ::scoreboard [{::game-id "12345" ::game-name "Polybus" ::high-score "99999999997"}])
36 |
37 | #_()) ; End of rich comment
38 |
--------------------------------------------------------------------------------
/resources/practicalli/minimal/test/app_test.clj.template:
--------------------------------------------------------------------------------
1 | ;; ---------------------------------------------------------
2 | ;; {{top/ns}}.{{main/ns}}.-test
3 | ;;
4 | ;; Example unit tests for {{top/ns}}.{{main/ns}}
5 | ;;
6 | ;; - `deftest` - test a specific function
7 | ;; - `testing` logically group assertions within a function test
8 | ;; - `is` assertion: expected value then function call
9 | ;; ---------------------------------------------------------
10 |
11 |
12 | (ns {{top/ns}}.{{main/ns}}-test
13 | (:require
14 | [clojure.test :refer [deftest is testing]]
15 | [{{top/ns}}.{{main/ns}} :as {{main/ns}}]))
16 |
17 |
18 | (deftest application-test
19 | (testing "TODO: Start with a failing test, make it pass, then refactor"
20 |
21 | ;; TODO: fix greet function to pass test
22 | (is (= "{{top/ns}} application developed by the secret engineering team"
23 | ({{main/ns}}/greet)))
24 |
25 | ;; TODO: fix test by calling greet with {:team-name "Practicalli Engineering"}
26 | (is (= ({{main/ns}}/greet "Practicalli Engineering")
27 | "{{top/ns}} service developed by the Practicalli Engineering team"))))
28 |
--------------------------------------------------------------------------------
/resources/practicalli/application/test/app_test.clj.template:
--------------------------------------------------------------------------------
1 | ;; ---------------------------------------------------------
2 | ;; {{top/ns}}.{{main/ns}}.-test
3 | ;;
4 | ;; Example unit tests for {{top/ns}}.{{main/ns}}
5 | ;;
6 | ;; - `deftest` - test a specific function
7 | ;; - `testing` logically group assertions within a function test
8 | ;; - `is` assertion: expected value then function call
9 | ;; ---------------------------------------------------------
10 |
11 |
12 | (ns {{top/ns}}.{{main/ns}}-test
13 | (:require
14 | [clojure.test :refer [deftest is testing]]
15 | [{{top/ns}}.{{main/ns}} :as {{main/ns}}]))
16 |
17 |
18 | (deftest application-test
19 | (testing "TODO: Start with a failing test, make it pass, then refactor"
20 |
21 | ;; TODO: fix greet function to pass test
22 | (is (= "{{top/ns}} application developed by the secret engineering team"
23 | ({{main/ns}}/greet)))
24 |
25 | ;; TODO: fix test by calling greet with {:team-name "Practicalli Engineering"}
26 | (is (= ({{main/ns}}/greet "Practicalli Engineering")
27 | "{{top/ns}} service developed by the Practicalli Engineering team"))))
28 |
--------------------------------------------------------------------------------
/resources/practicalli/service/test/service_test.clj.template:
--------------------------------------------------------------------------------
1 | ;; ---------------------------------------------------------
2 | ;; {{top/ns}}.{{main/ns}}.service-test
3 | ;;
4 | ;; Example unit tests for {{top/ns}}.{{main/ns}}
5 | ;;
6 | ;; - `deftest` - test a specific function
7 | ;; - `testing` logically group assertions within a function test
8 | ;; - `is` assertion: expected value then function call
9 | ;; ---------------------------------------------------------
10 |
11 | (ns {{top/ns}}.{{main/ns}}.service-test
12 | (:require [clojure.test :refer [deftest is testing]]
13 | [{{top/ns}}.{{main/ns}}.service :as {{main/ns}}]))
14 |
15 | (deftest service-test
16 | (testing "TODO: Start with a failing test, make it pass, then refactor"
17 |
18 | ;; TODO: fix greet function to pass test
19 | (is (= "{{top/ns}} {{main/ns}} service developed by the secret engineering team"
20 | ({{main/ns}}/greet)))
21 |
22 | ;; TODO: fix test by calling greet with {:team-name "Practicalli Engineering"}
23 | (is (= ({{main/ns}}/greet "Practicalli Engineering")
24 | "{{top/ns}} {{main/ns}} service developed by the Practicalli Engineering team"))))
25 |
--------------------------------------------------------------------------------
/test/practicalli/service_test.clj:
--------------------------------------------------------------------------------
1 | ;; ---------------------------------------------------------
2 | ;; Unit and specification tests for practicalli/service template
3 | ;;
4 | ;; Test the template.edn file of the application template
5 | ;; using the deps-new specification
6 | ;; ---------------------------------------------------------
7 |
8 |
9 | (ns practicalli.service-test
10 | (:require
11 | [clojure.edn :as edn]
12 | [clojure.java.io :as io]
13 | [clojure.spec.alpha :as spec]
14 | [clojure.test :refer [deftest is testing]]
15 | [org.corfield.new]
16 | ;; deps-new Specs
17 | #_[practicalli.service :as service]))
18 |
19 |
20 | (def project-template
21 | "Project template hash-map"
22 | (edn/read-string (slurp (io/resource "practicalli/service/template.edn"))))
23 |
24 |
25 | (deftest valid-template-test
26 | (testing "template.edn is valid."
27 | (is (spec/valid? :org.corfield.new/template project-template)
28 | (spec/explain-str :org.corfield.new/template project-template))))
29 |
30 |
31 | (deftest template-options-test
32 | (testing "Check correct values for optional keys are correct"
33 | (is (contains? #{"integrant" "mount" "donut" nil} (project-template :component)))
34 | (is (contains? #{"postgresql" "h2" "xtdb" "mariadb" nil} (project-template :persistence)))))
35 |
--------------------------------------------------------------------------------
/resources/practicalli/application/root/.github/workflows/changelog-check.yaml:
--------------------------------------------------------------------------------
1 | ---
2 | # Check CHANGELOG.md file updated for every pull request
3 |
4 | name: Changelog Check
5 | on:
6 | pull_request:
7 | paths-ignore:
8 | - "README.md"
9 | types: [opened, synchronize, reopened, ready_for_review, labeled, unlabeled]
10 |
11 | jobs:
12 | changelog:
13 | name: Changelog Update Check
14 | runs-on: ubuntu-latest
15 | steps:
16 | - run: echo "🚀 Job automatically triggered by ${{ github.event_name }}"
17 | - run: echo "🐧 Job running on ${{ runner.os }} server"
18 | - run: echo "🐙 Using ${{ github.ref }} branch from ${{ github.repository }} repository"
19 |
20 | # Git Checkout
21 | - name: Checkout Code
22 | uses: actions/checkout@v5
23 | with:
24 | fetch-depth: 0
25 | - run: echo "🐙 ${{ github.repository }} repository was cloned to the runner."
26 |
27 | # Changelog Enforcer
28 | - name: Changelog Enforcer
29 | uses: dangoslen/changelog-enforcer@v3
30 | with:
31 | changeLogPath: "CHANGELOG.md"
32 | skipLabels: "skip-changelog-check"
33 |
34 | # Summary and status
35 | - run: echo "🎨 Changelog Enforcer quality checks completed"
36 | - run: echo "🍏 Job status is ${{ job.status }}."
37 |
--------------------------------------------------------------------------------
/resources/practicalli/service/root/.github/workflows/changelog-check.yaml:
--------------------------------------------------------------------------------
1 | ---
2 | # Check CHANGELOG.md file updated for every pull request
3 |
4 | name: Changelog Check
5 | on:
6 | pull_request:
7 | paths-ignore:
8 | - "README.md"
9 | types: [opened, synchronize, reopened, ready_for_review, labeled, unlabeled]
10 |
11 | jobs:
12 | changelog:
13 | name: Changelog Update Check
14 | runs-on: ubuntu-latest
15 | steps:
16 | - run: echo "🚀 Job automatically triggered by ${{ github.event_name }}"
17 | - run: echo "🐧 Job running on ${{ runner.os }} server"
18 | - run: echo "🐙 Using ${{ github.ref }} branch from ${{ github.repository }} repository"
19 |
20 | # Git Checkout
21 | - name: Checkout Code
22 | uses: actions/checkout@v5
23 | with:
24 | fetch-depth: 0
25 | - run: echo "🐙 ${{ github.repository }} repository was cloned to the runner."
26 |
27 | # Changelog Enforcer
28 | - name: Changelog Enforcer
29 | uses: dangoslen/changelog-enforcer@v3
30 | with:
31 | changeLogPath: "CHANGELOG.md"
32 | skipLabels: "skip-changelog-check"
33 |
34 | # Summary and status
35 | - run: echo "🎨 Changelog Enforcer quality checks completed"
36 | - run: echo "🍏 Job status is ${{ job.status }}."
37 |
--------------------------------------------------------------------------------
/resources/practicalli/landing_page/root/.github/workflows/changelog-check.yaml:
--------------------------------------------------------------------------------
1 | ---
2 | # Check CHANGELOG.md file updated for every pull request
3 |
4 | name: Changelog Check
5 | on:
6 | pull_request:
7 | paths-ignore:
8 | - "README.md"
9 | types: [opened, synchronize, reopened, ready_for_review, labeled, unlabeled]
10 |
11 | jobs:
12 | changelog:
13 | name: Changelog Update Check
14 | runs-on: ubuntu-latest
15 | steps:
16 | - run: echo "🚀 Job automatically triggered by ${{ github.event_name }}"
17 | - run: echo "🐧 Job running on ${{ runner.os }} server"
18 | - run: echo "🐙 Using ${{ github.ref }} branch from ${{ github.repository }} repository"
19 |
20 | # Git Checkout
21 | - name: Checkout Code
22 | uses: actions/checkout@v5
23 | with:
24 | fetch-depth: 0
25 | - run: echo "🐙 ${{ github.repository }} repository was cloned to the runner."
26 |
27 | # Changelog Enforcer
28 | - name: Changelog Enforcer
29 | uses: dangoslen/changelog-enforcer@v3
30 | with:
31 | changeLogPath: "CHANGELOG.md"
32 | skipLabels: "skip-changelog-check"
33 |
34 | # Summary and status
35 | - run: echo "🎨 Changelog Enforcer quality checks completed"
36 | - run: echo "🍏 Job status is ${{ job.status }}."
37 |
--------------------------------------------------------------------------------
/.github/workflows/lint-review.yaml:
--------------------------------------------------------------------------------
1 | ---
2 | # Clojure Lint with clj-kondo and reviewdog
3 | #
4 | # Lint errors raised as comments on pull request conversation
5 |
6 | name: Lint Review
7 | on: [pull_request]
8 |
9 | jobs:
10 | clj-kondo:
11 | name: runner / clj-kondo
12 | runs-on: ubuntu-latest
13 | steps:
14 | - run: echo "🚀 Job automatically triggered by ${{ github.event_name }}"
15 | - run: echo "🐧 Job running on ${{ runner.os }} server"
16 | - run: echo "🐙 Using ${{ github.ref }} branch from ${{ github.repository }} repository"
17 |
18 | # Git Checkout
19 | - name: Checkout Code
20 | uses: actions/checkout@v6
21 | with:
22 | token: "${{ secrets.PAT || secrets.GITHUB_TOKEN }}"
23 | - run: echo "🐙 ${{ github.repository }} repository was cloned to the runner."
24 |
25 | - name: clj-kondo
26 | uses: nnichols/clojure-lint-action@v6
27 | with:
28 | pattern: "*.clj"
29 | clj_kondo_config: ".clj-kondo/config-ci.edn"
30 | level: "error"
31 | exclude: ".cljstyle"
32 | github_token: ${{ secrets.github_token }}
33 | reporter: github-pr-review
34 |
35 | # Summary and status
36 | - run: echo "🎨 Lint Review checks completed"
37 | - run: echo "🍏 Job status is ${{ job.status }}."
38 |
--------------------------------------------------------------------------------
/resources/practicalli/service/root/.github/workflows/lint-review.yaml:
--------------------------------------------------------------------------------
1 | ---
2 | # Clojure Lint with clj-kondo and reviewdog
3 | #
4 | # Lint errors raised as comments on pull request conversation
5 |
6 | name: Lint Review
7 | on: [pull_request]
8 |
9 | jobs:
10 | clj-kondo:
11 | name: runner / clj-kondo
12 | runs-on: ubuntu-latest
13 | steps:
14 | - run: echo "🚀 Job automatically triggered by ${{ github.event_name }}"
15 | - run: echo "🐧 Job running on ${{ runner.os }} server"
16 | - run: echo "🐙 Using ${{ github.ref }} branch from ${{ github.repository }} repository"
17 |
18 | # Git Checkout
19 | - name: Checkout Code
20 | uses: actions/checkout@v5
21 | with:
22 | token: "${{ secrets.PAT || secrets.GITHUB_TOKEN }}"
23 | - run: echo "🐙 ${{ github.repository }} repository was cloned to the runner."
24 |
25 | - name: clj-kondo
26 | uses: nnichols/clojure-lint-action@v6
27 | with:
28 | pattern: "*.clj"
29 | clj_kondo_config: ".clj-kondo/config-ci.edn"
30 | level: "error"
31 | exclude: ".cljstyle"
32 | github_token: ${{ secrets.github_token }}
33 | reporter: github-pr-review
34 |
35 | # Summary and status
36 | - run: echo "🎨 Lint Review checks completed"
37 | - run: echo "🍏 Job status is ${{ job.status }}."
38 |
--------------------------------------------------------------------------------
/resources/practicalli/application/root/.github/workflows/lint-review.yaml:
--------------------------------------------------------------------------------
1 | ---
2 | # Clojure Lint with clj-kondo and reviewdog
3 | #
4 | # Lint errors raised as comments on pull request conversation
5 |
6 | name: Lint Review
7 | on: [pull_request]
8 |
9 | jobs:
10 | clj-kondo:
11 | name: runner / clj-kondo
12 | runs-on: ubuntu-latest
13 | steps:
14 | - run: echo "🚀 Job automatically triggered by ${{ github.event_name }}"
15 | - run: echo "🐧 Job running on ${{ runner.os }} server"
16 | - run: echo "🐙 Using ${{ github.ref }} branch from ${{ github.repository }} repository"
17 |
18 | # Git Checkout
19 | - name: Checkout Code
20 | uses: actions/checkout@v5
21 | with:
22 | token: "${{ secrets.PAT || secrets.GITHUB_TOKEN }}"
23 | - run: echo "🐙 ${{ github.repository }} repository was cloned to the runner."
24 |
25 | - name: clj-kondo
26 | uses: nnichols/clojure-lint-action@v6
27 | with:
28 | pattern: "*.clj"
29 | clj_kondo_config: ".clj-kondo/config-ci.edn"
30 | level: "error"
31 | exclude: ".cljstyle"
32 | github_token: ${{ secrets.github_token }}
33 | reporter: github-pr-review
34 |
35 | # Summary and status
36 | - run: echo "🎨 Lint Review checks completed"
37 | - run: echo "🍏 Job status is ${{ job.status }}."
38 |
--------------------------------------------------------------------------------
/resources/practicalli/landing_page/root/.github/workflows/lint-review.yaml:
--------------------------------------------------------------------------------
1 | ---
2 | # Clojure Lint with clj-kondo and reviewdog
3 | #
4 | # Lint errors raised as comments on pull request conversation
5 |
6 | name: Lint Review
7 | on: [pull_request]
8 |
9 | jobs:
10 | clj-kondo:
11 | name: runner / clj-kondo
12 | runs-on: ubuntu-latest
13 | steps:
14 | - run: echo "🚀 Job automatically triggered by ${{ github.event_name }}"
15 | - run: echo "🐧 Job running on ${{ runner.os }} server"
16 | - run: echo "🐙 Using ${{ github.ref }} branch from ${{ github.repository }} repository"
17 |
18 | # Git Checkout
19 | - name: Checkout Code
20 | uses: actions/checkout@v5
21 | with:
22 | token: "${{ secrets.PAT || secrets.GITHUB_TOKEN }}"
23 | - run: echo "🐙 ${{ github.repository }} repository was cloned to the runner."
24 |
25 | - name: clj-kondo
26 | uses: nnichols/clojure-lint-action@v6
27 | with:
28 | pattern: "*.clj"
29 | clj_kondo_config: ".clj-kondo/config-ci.edn"
30 | level: "error"
31 | exclude: ".cljstyle"
32 | github_token: ${{ secrets.github_token }}
33 | reporter: github-pr-review
34 |
35 | # Summary and status
36 | - run: echo "🎨 Lint Review checks completed"
37 | - run: echo "🍏 Job status is ${{ job.status }}."
38 |
--------------------------------------------------------------------------------
/resources/practicalli/minimal/root/.github/workflows/lint-review.yaml:
--------------------------------------------------------------------------------
1 | ---
2 | # Clojure Lint with clj-kondo and reviewdog
3 | #
4 | # Lint errors raised as comments on pull request conversation
5 |
6 | name: Lint Review
7 | on: [pull_request]
8 |
9 | jobs:
10 | clj-kondo:
11 | name: runner / clj-kondo
12 | runs-on: ubuntu-latest
13 | steps:
14 | - run: echo "🚀 Job automatically triggered by ${{ github.event_name }}"
15 | - run: echo "🐧 Job running on ${{ runner.os }} server"
16 | - run: echo "🐙 Using ${{ github.ref }} branch from ${{ github.repository }} repository"
17 |
18 | # Git Checkout
19 | - name: Checkout Code
20 | uses: actions/checkout@v5
21 | with:
22 | token: "${{ secrets.PAT || secrets.GITHUB_TOKEN }}"
23 | - run: echo "🐙 ${{ github.repository }} repository was cloned to the runner."
24 |
25 | - name: clj-kondo
26 | uses: nnichols/clojure-lint-action@v6
27 | with:
28 | pattern: "*.clj"
29 | clj_kondo_config: ".github/config/clj-kondo-ci-config.edn"
30 | level: "error"
31 | exclude: ".cljstyle"
32 | github_token: ${{ secrets.github_token }}
33 | reporter: github-pr-review
34 |
35 | # Summary and status
36 | - run: echo "🎨 Lint Review checks completed"
37 | - run: echo "🍏 Job status is ${{ job.status }}."
38 |
--------------------------------------------------------------------------------
/resources/practicalli/application/build/deps.edn.template:
--------------------------------------------------------------------------------
1 | {:paths
2 | ["src" "resources"]
3 |
4 | :deps
5 | {;; Application
6 | org.clojure/clojure {:mvn/version "{{clojure-version}}"}
7 |
8 | ;; Logging
9 | ;; create events and send to publisher
10 | com.brunobonacci/mulog {:mvn/version "0.9.0"}
11 | ;; JSON Console out support
12 | com.brunobonacci/mulog-adv-console {:mvn/version "0.9.0"}}
13 |
14 | :aliases
15 | {;; Clojure.main execution of application
16 | :run/app
17 | {:main-opts ["-m" "{{top/ns}}.{{main/ns}}"]}
18 |
19 | ;; Clojure.exec execution of specified function
20 | :run/greet
21 | {:exec-fn {{top/ns}}.{{main/ns}}/greet
22 | :exec-args {:name "Clojure"}}
23 |
24 | ;; Add libraries and paths to support additional test tools
25 | :test/env
26 | {}
27 |
28 | ;; Test runner - local and CI
29 | ;; call with :watch? true to start file watcher and re-run tests on saved changes
30 | :test/run
31 | {:extra-paths ["test"]
32 | :extra-deps {lambdaisland/kaocha {:mvn/version "1.91.1392"}}
33 | :main-opts ["-m" "kaocha.runner"]
34 | :exec-fn kaocha.runner/exec-fn
35 | :exec-args {:randomize? false
36 | :fail-fast? true}}
37 |
38 | ;; tools.build `build.clj` built script
39 | :build
40 | {:replace-paths ["."]
41 | :replace-deps {io.github.clojure/tools.build {:mvn/version "0.10.3"}}
42 | :ns-default build}}}
43 |
--------------------------------------------------------------------------------
/resources/practicalli/service/src/middleware.clj.template:
--------------------------------------------------------------------------------
1 | (ns {{top/ns}}.{{main/ns}}.middleware
2 | (:require
3 | [com.brunobonacci.mulog :as mulog]))
4 |
5 |
6 | ;; --------------------------------------------------
7 | ;; Logging middleware
8 | ;; https://github.com/BrunoBonacci/mulog/blob/master/doc/ring-tracking.md
9 |
10 |
11 | (defn wrap-trace-events
12 | "Log event trace for each api event with mulog/log."
13 | [handler id]
14 | (fn [request]
15 | ;; Add context of each request to all trace events generated for the specific request
16 | (mulog/with-context
17 | {:uri (get request :uri)
18 | :request-method (get request :request-method)}
19 |
20 | ;; track the request duration and outcome
21 | (mulog/trace :io.redefine.datawarp/http-request
22 | ;; add key/value pairs for tracking event only
23 | {:pairs [:content-type (get-in request [:headers "content-type"])
24 | :content-encoding (get-in request [:headers "content-encoding"])
25 | :middleware id]
26 | ;; capture http status code from the response
27 | :capture (fn [{:keys [status]}] {:http-status status})}
28 |
29 | ;; call the request handler
30 | (handler request)))))
31 |
32 | ;; --------------------------------------------------
33 |
--------------------------------------------------------------------------------
/resources/practicalli/minimal/src/app.clj.template:
--------------------------------------------------------------------------------
1 | ;; ---------------------------------------------------------
2 | ;; {{top/ns}}.{{main/ns}}
3 | ;;
4 | ;; {{description}}
5 | ;; ---------------------------------------------------------
6 |
7 | (ns {{top/ns}}.{{main/ns}}
8 | (:gen-class)
9 | (:require
10 | [com.brunobonacci.mulog :as mulog]))
11 |
12 | ;; ---------------------------------------------------------
13 | ;; Application
14 |
15 | (defn greet
16 | "Greeting message via Clojure CLI clojure.exec"
17 | ([] (greet {:team-name "secret engineering"}))
18 | ([{:keys [team-name]}]
19 | (str "{{top/ns}} {{main/ns}} service developed by the " team-name " team")))
20 |
21 |
22 | (defn -main
23 | "Entry point into the application via clojure.main -M"
24 | [& args]
25 | (let [team (first args)]
26 | (mulog/set-global-context!
27 | {:app-name "{{top/ns}} {{main/ns}}" :version "{{version}}"})
28 | (mulog/log ::application-starup :arguments args)
29 | (if team
30 | (println (greet team))
31 | (println (greet)))))
32 |
33 | ;; ---------------------------------------------------------
34 |
35 |
36 | ;; ---------------------------------------------------------
37 | ;; Rick Comment
38 | (comment
39 |
40 | (-main)
41 | (-main {:team-name "Clojure Engineering"})
42 |
43 | #_()) ; End of rich comment block
44 | ;; ---------------------------------------------------------
45 |
--------------------------------------------------------------------------------
/.github/workflows/changelog-check.yaml:
--------------------------------------------------------------------------------
1 | ---
2 | # Check CHANGELOG.md file updated for every pull request
3 |
4 | name: Changelog Check
5 | on:
6 | pull_request:
7 | paths-ignore:
8 | - "README.md"
9 | types: [opened, synchronize, reopened, ready_for_review, labeled, unlabeled]
10 |
11 | jobs:
12 | changelog:
13 | name: Changelog Update Check
14 | runs-on: ubuntu-latest
15 | steps:
16 | - run: echo "🚀 Job automatically triggered by ${{ github.event_name }}"
17 | - run: echo "🐧 Job running on ${{ runner.os }} server"
18 | - run: echo "🐙 Using ${{ github.ref }} branch from ${{ github.repository }} repository"
19 |
20 | # Git Checkout
21 | - name: Checkout Code
22 | uses: actions/checkout@v6
23 | with:
24 | fetch-depth: 0
25 | sparse-checkout: |
26 | docs
27 | overrides
28 | .github
29 | CHANGELOG.md
30 | - run: echo "🐙 Sparse Checkout of ${{ github.repository }} repository to the CI runner."
31 |
32 | # Changelog Enforcer
33 | - name: Changelog Enforcer
34 | uses: dangoslen/changelog-enforcer@v3
35 | with:
36 | changeLogPath: "CHANGELOG.md"
37 | skipLabels: "skip-changelog-check"
38 |
39 | # Summary and status
40 | - run: echo "🎨 Changelog Enforcer quality checks completed"
41 | - run: echo "🍏 Job status is ${{ job.status }}."
42 |
--------------------------------------------------------------------------------
/resources/practicalli/service/api/system_admin.clj.template:
--------------------------------------------------------------------------------
1 | ;; --------------------------------------------------
2 | ;; System Administration and Status check
3 | ;;
4 | ;; - return service status response
5 | ;; --------------------------------------------------
6 |
7 |
8 | (ns {{top/ns}}.{{main/ns}}.api.system-admin
9 | "Gameboard API system administration handlers"
10 | (:require [ring.util.response :refer [response]]))
11 |
12 |
13 | ;; --------------------------------------------------
14 | ;; Status of Service
15 |
16 | (def status
17 | "Simple status report for external monitoring services, e.g. Pingdom
18 | Return:
19 | - `constantly` returns an anonymous function that returns a ring response hash-map"
20 | (constantly (response {:application "{{top/ns}} {{main/ns}} Service" :status "Alive"})))
21 |
22 | ;; --------------------------------------------------
23 |
24 |
25 | ;; --------------------------------------------------
26 | ;; Router
27 |
28 | (defn routes
29 | "Reitit route configuration for system-admin endpoint"
30 | []
31 | ["/system-admin"
32 | {:swagger {:tags ["Application Support"]}}
33 | ["/status"
34 | {:get {:summary "Status of {{top/ns}} {{main/ns}} service"
35 | :description "Ping {{top/ns}} {{main/ns}} service to see if is responding to a simple request and therefore alive"
36 | :responses {200 {:body {:application string? :status string?}}}
37 | :handler status}}]])
38 |
39 | ;; --------------------------------------------------
40 |
--------------------------------------------------------------------------------
/resources/practicalli/landing_page/build/figwheel-main.edn:
--------------------------------------------------------------------------------
1 | ;; ---------------------------------------------------------
2 | ;; Figwheel configuration
3 | ;;
4 | ;; Figwheel-main default configuration options
5 | ;; https://figwheel.org/config-options
6 | ;;
7 | ;; Build metadata configuration will override matching figwheel defaults
8 | ;; ---------------------------------------------------------
9 |
10 | {;; Set the server port https://figwheel.org/config-options#ring-server-options
11 | ;; :ring-server-options {:port 9500}
12 |
13 | ;; Target directory https://figwheel.org/config-options#target-dir
14 | ;; you may want to set this to resources if you are using Leiningen
15 | ;; :target-dir "resources"
16 |
17 | ;; Server Ring Handler (optional) https://figwheel.org/docs/ring-handler.html
18 | ;; If you want to embed a ring handler into the figwheel server, this
19 | ;; is for simple ring servers
20 | ;; :ring-handler hello_world.server/handler
21 |
22 | ;; To be able to open files in your editor from the heads up display
23 | ;; you will need to put a script on your path. This script will have
24 | ;; to take a file path and a line number ie.
25 | ;; in ~/bin/myfile-opener:
26 | ;;
27 | ;; #! /bin/sh
28 | ;; emacsclient -n +$2:$3 $1
29 | ;;
30 | ;; :open-file-command "myfile-opener"
31 |
32 | ;; if you are using emacsclient you can just use
33 | ;; :open-file-command "emacsclient"
34 |
35 | ;; Logging output gets printed to the REPL, if you want to redirect it to a file:
36 | ;; :log-file "figwheel-main.log"
37 | }
38 |
--------------------------------------------------------------------------------
/resources/practicalli/minimal/template.edn:
--------------------------------------------------------------------------------
1 | {;; Values to pass into the template
2 | :description "TODO: Provide a meaningful description of the project"
3 |
4 | ;; ---------------------------------------------------------
5 | ;; Version substitutions
6 |
7 | :clojure-version "1.12.3"
8 | ;; ---------------------------------------------------------
9 |
10 | ;; ---------------------------------------------------------
11 | ;; Optional features
12 | ;; - used by programatic transformation
13 | ;; - not implemented yet
14 | ;; ---------------------------------------------------------
15 |
16 | ;; ---------------------------------------------------------
17 | ;; Programatic Transformation functions
18 |
19 | :data-fn practicalli.minimal/substitutions
20 |
21 | :template-fn practicalli.minimal/template-edn
22 | ;; ---------------------------------------------------------
23 |
24 | ;; ---------------------------------------------------------
25 | ;; Declarative Transformation rules
26 | ;; - can be updated by programmatic transformation
27 | ;;
28 | ;; Form:
29 | ;; [["directory-name" "default-path"
30 | ;; {"source-file.extension.template" "destination-file.extension"}]]
31 |
32 | :transform
33 | [["build" ""
34 | {"build.clj.template" "build.clj"
35 | "deps.edn.template" "deps.edn"}]
36 | ["src" "src/{{top/file}}"
37 | {"app.clj.template" "{{main/file}}.clj"}]
38 | ["test" "test/{{top/file}}"
39 | {"app_test.clj.template" "{{main/file}}_test.clj"}]]}
40 | ;; ---------------------------------------------------------
41 |
--------------------------------------------------------------------------------
/resources/practicalli/application/template.edn:
--------------------------------------------------------------------------------
1 | {;; Values to pass into the template
2 | :description "TODO: Provide a meaningful description of the project"
3 |
4 | ;; ---------------------------------------------------------
5 | ;; Version substitutions
6 |
7 | :clojure-version "1.12.3"
8 | ;; ---------------------------------------------------------
9 |
10 | ;; ---------------------------------------------------------
11 | ;; Optional features
12 | ;; - used by programatic transformation
13 | ;; - not implemented yet
14 | ;; ---------------------------------------------------------
15 |
16 | ;; ---------------------------------------------------------
17 | ;; Programatic Transformation functions
18 |
19 | :data-fn practicalli.application/substitutions
20 |
21 | :template-fn practicalli.application/template-edn
22 | ;; ---------------------------------------------------------
23 |
24 | ;; ---------------------------------------------------------
25 | ;; Declarative Transformation rules
26 | ;; - can be updated by programmatic transformation
27 | ;;
28 | ;; Form:
29 | ;; [["directory-name" "default-path"
30 | ;; {"source-file.extension.template" "destination-file.extension"}]]
31 |
32 | :transform
33 | [["build" ""
34 | {"build.clj.template" "build.clj"
35 | "deps.edn.template" "deps.edn"}]
36 | ["src" "src/{{top/file}}"
37 | {"app.clj.template" "{{main/file}}.clj"}]
38 | ["test" "test/{{top/file}}"
39 | {"app_test.clj.template" "{{main/file}}_test.clj"}]]}
40 | ;; ---------------------------------------------------------
41 |
--------------------------------------------------------------------------------
/src/practicalli/minimal.clj:
--------------------------------------------------------------------------------
1 | ;; ---------------------------------------------------------
2 | ;; Programatic Transformation
3 | ;;
4 | ;; Define transformations based on data in the template and
5 | ;; passed via the command line
6 | ;;
7 | ;; `data-fn` enrich template data
8 | ;; `template-fn` modify declarative template rules
9 | ;; ---------------------------------------------------------
10 |
11 |
12 | (ns practicalli.minimal
13 | "Programmatic transformation of template substitution data
14 | and declarative transformation rules")
15 |
16 | #_{:clj-kondo/ignore [:clojure-lsp/unused-public-var]}
17 | (defn substitutions
18 | "Update keys & values available in the substitution data,
19 | from the template.edn, derived values and command line options
20 | Return:
21 | - hash-map to be merged into the existing substitution data"
22 | [data]
23 |
24 | ;; Simple example:
25 | #_(when (= (data :specification) "clojure.spec")
26 | {:clojure-spec true})
27 |
28 | nil) ; returning nil means no changes to options data
29 |
30 | #_{:clj-kondo/ignore [:clojure-lsp/unused-public-var]}
31 | (defn template-edn
32 | "Update data in the template.edn configuration.
33 | E.g. derive new declarative transformation rules from
34 | template substitutions, derived values and values passed
35 | to the template via the command line
36 | Return
37 | - new template.edn configuration"
38 | [edn data]
39 |
40 | ;; Link to Practicalli Clojure Project Templates guide
41 | (println "Template guide: https://practical.li/clojure/clojure-cli/projects/templates/")
42 | edn)
43 |
--------------------------------------------------------------------------------
/src/practicalli/application.clj:
--------------------------------------------------------------------------------
1 | ;; ---------------------------------------------------------
2 | ;; Programatic Transformation
3 | ;;
4 | ;; Define transformations based on data in the template and
5 | ;; passed via the command line
6 | ;;
7 | ;; `data-fn` enrich template data
8 | ;; `template-fn` modify declarative template rules
9 | ;; ---------------------------------------------------------
10 |
11 |
12 | (ns practicalli.application
13 | "Programmatic transformation of template substitution data
14 | and declarative transformation rules")
15 |
16 |
17 | #_{:clj-kondo/ignore [:clojure-lsp/unused-public-var]}
18 | (defn substitutions
19 | "Update keys & values available in the substitution data,
20 | from the template.edn, derived values and command line options
21 | Return:
22 | - hash-map to be merged into the existing substitution data"
23 | [data]
24 |
25 | ;; Simple example:
26 | #_(when (= (data :specification) "clojure.spec")
27 | {:clojure-spec true})
28 |
29 | nil) ; returning nil means no changes to options data
30 |
31 |
32 | #_{:clj-kondo/ignore [:clojure-lsp/unused-public-var]}
33 | (defn template-edn
34 | "Update data in the template.edn configuration.
35 | E.g. derive new declarative transformation rules from
36 | template substitutions, derived values and values passed
37 | to the template via the command line
38 | Return
39 | - new template.edn configuration"
40 | [edn data]
41 |
42 | ;; Link to Practicalli Clojure Project Templates guide
43 | (println "Template guide: https://practical.li/clojure/clojure-cli/projects/templates/")
44 | edn)
45 |
--------------------------------------------------------------------------------
/.github/workflows/scheduled-version-check.yaml:
--------------------------------------------------------------------------------
1 | ---
2 | # ------------------------------------------
3 | # Scheduled check of versions
4 | # - use as non-urgent report on versions
5 | # - Uses POSIX Cron syntax
6 | # - Minute [0,59]
7 | # - Hour [0,23]
8 | # - Day of the month [1,31]
9 | # - Month of the year [1,12]
10 | # - Day of the week ([0,6] with 0=Sunday)
11 | #
12 | # Using liquidz/anta to check:
13 | # - GitHub workflows
14 | # - deps.edn
15 | # ------------------------------------------
16 |
17 | name: "Scheduled Version Check"
18 | on:
19 | schedule:
20 | # - cron: "0 4 * * *" # at 04:04:04 ever day
21 | # - cron: "0 4 * * 5" # at 04:04:04 ever Friday
22 | - cron: "0 4 1 * *" # at 04:04:04 on first day of month
23 | workflow_dispatch: # Run manually via GitHub Actions Workflow page
24 |
25 | jobs:
26 | scheduled-version-check:
27 | name: "Scheduled Version Check"
28 | runs-on: ubuntu-latest
29 | steps:
30 | - run: echo "🚀 Job automatically triggered by ${{ github.event_name }}"
31 | - run: echo "🐧 Job running on ${{ runner.os }} server"
32 | - run: echo "🐙 Using ${{ github.ref }} branch from ${{ github.repository }} repository"
33 |
34 | - name: Checkout Code
35 | uses: actions/checkout@v6
36 | - run: echo "🐙 ${{ github.repository }} repository sparse-checkout to the CI runner."
37 | - name: Antq Check Version
38 | uses: liquidz/antq-action@main
39 | with:
40 | excludes: "org.clojure/tools.deps.alpha"
41 | skips: "boot shadow-cljs leiningen"
42 |
43 | # Summary
44 | - run: echo "🎨 library versions checked with liquidz/antq"
45 | - run: echo "🍏 Job status is ${{ job.status }}."
46 |
--------------------------------------------------------------------------------
/src/practicalli/landing_page.clj:
--------------------------------------------------------------------------------
1 | ;; ---------------------------------------------------------
2 | ;; Programatic Transformation
3 | ;;
4 | ;; Define transformations based on data in the template and
5 | ;; passed via the command line
6 | ;;
7 | ;; `data-fn` enrich template data
8 | ;; `template-fn` modify declarative template rules
9 | ;; ---------------------------------------------------------
10 |
11 |
12 | (ns practicalli.landing-page
13 | "Programmatic transformation of template substitution data
14 | and declarative transformation rules"
15 | (:require
16 | [clojure.pprint :as print]))
17 |
18 |
19 | #_{:clj-kondo/ignore [:clojure-lsp/unused-public-var]}
20 | (defn substitutions
21 | "Update keys & values available in the substitution data,
22 | from the template.edn, derived values and command line options
23 | Return:
24 | - hash-map to be merged into the existing substitution data"
25 | [data]
26 |
27 | ;; Simple example:
28 | #_(when (= (data :specification) "clojure.spec")
29 | {:clojure-spec true})
30 |
31 | nil) ; returning nil means no changes to options data
32 |
33 |
34 | #_{:clj-kondo/ignore [:clojure-lsp/unused-public-var]}
35 | (defn template-edn
36 | "Update data in the template.edn configuration.
37 | E.g. derive new declarative transformation rules from
38 | template substitutions, derived values and values passed
39 | to the template via the command line
40 | Return
41 | - new template.edn configuration"
42 | [edn data]
43 | ;; (println "Data used in template-edn")
44 | ;; (print/pprint data)
45 |
46 | ;; Link to Practicalli Clojure Project Templates guide
47 | (println "Template guide: https://practical.li/clojure/clojure-cli/projects/templates/")
48 | edn)
49 |
--------------------------------------------------------------------------------
/resources/practicalli/minimal/build/deps.edn.template:
--------------------------------------------------------------------------------
1 | {;; ---------------------------------------------------------
2 | :paths
3 | ["src" "resources"]
4 | ;; ---------------------------------------------------------
5 |
6 | ;; ---------------------------------------------------------
7 | :deps
8 | {;; Application
9 | org.clojure/clojure {:mvn/version "{{clojure-version}}"}
10 | com.brunobonacci/mulog {:mvn/version "0.9.0"}}
11 | ;; ---------------------------------------------------------
12 |
13 | ;; ---------------------------------------------------------
14 | :aliases
15 | {;; ------------
16 | ;; Clojure.main execution of application
17 | :run/app
18 | {:main-opts ["-m" "{{top/ns}}.{{main/ns}}"]}
19 |
20 | ;; Clojure.exec execution of specified function
21 | :run/greet
22 | {:exec-fn {{top/ns}}.{{main/ns}}/greet
23 | :exec-args {:name "Clojure"}}
24 | ;; ------------
25 |
26 | ;; ------------
27 | ;; Add libraries and paths to support additional test tools
28 | :test/env
29 | {}
30 |
31 | ;; Test runner - local and CI
32 | ;; call with :watch? true to start file watcher and re-run tests on saved changes
33 | :test/run
34 | {:extra-paths ["test"]
35 | :extra-deps {lambdaisland/kaocha {:mvn/version "1.91.1392"}}
36 | :main-opts ["-m" "kaocha.runner"]
37 | :exec-fn kaocha.runner/exec-fn
38 | :exec-args {:randomize? false
39 | :fail-fast? true}}
40 | ;; ------------
41 |
42 | ;; ------------
43 | ;; tools.build `build.clj` built script
44 | :build/task
45 | {:replace-paths ["."]
46 | :replace-deps {io.github.clojure/tools.build {:mvn/version "0.10.3"}}
47 | :ns-default build}}}
48 | ;; ------------
49 | ;; ---------------------------------------------------------
50 |
--------------------------------------------------------------------------------
/resources/practicalli/service/root/.github/workflows/scheduled-version-check.yaml:
--------------------------------------------------------------------------------
1 | ---
2 | # ------------------------------------------
3 | # Scheduled check of versions
4 | # - use as non-urgent report on versions
5 | # - Uses POSIX Cron syntax
6 | # - Minute [0,59]
7 | # - Hour [0,23]
8 | # - Day of the month [1,31]
9 | # - Month of the year [1,12]
10 | # - Day of the week ([0,6] with 0=Sunday)
11 | #
12 | # Using liquidz/anta to check:
13 | # - GitHub workflows
14 | # - deps.edn
15 | # ------------------------------------------
16 |
17 | name: "Scheduled Version Check"
18 | on:
19 | schedule:
20 | # - cron: "0 4 * * *" # at 04:04:04 ever day
21 | # - cron: "0 4 * * 5" # at 04:04:04 ever Friday
22 | - cron: "0 4 1 * *" # at 04:04:04 on first day of month
23 | workflow_dispatch: # Run manually via GitHub Actions Workflow page
24 |
25 | jobs:
26 | scheduled-version-check:
27 | name: "Scheduled Version Check"
28 | runs-on: ubuntu-latest
29 | steps:
30 | - run: echo "🚀 Job automatically triggered by ${{ github.event_name }}"
31 | - run: echo "🐧 Job running on ${{ runner.os }} server"
32 | - run: echo "🐙 Using ${{ github.ref }} branch from ${{ github.repository }} repository"
33 |
34 | - name: Checkout Code
35 | uses: actions/checkout@v5
36 | - run: echo "🐙 ${{ github.repository }} repository sparse-checkout to the CI runner."
37 | - name: Antq Check Version
38 | uses: liquidz/antq-action@main
39 | with:
40 | excludes: "org.clojure/tools.deps.alpha"
41 | skips: "boot shadow-cljs leiningen"
42 |
43 | # Summary
44 | - run: echo "🎨 library versions checked with liquidz/antq"
45 | - run: echo "🍏 Job status is ${{ job.status }}."
46 |
--------------------------------------------------------------------------------
/resources/practicalli/application/root/.github/workflows/scheduled-version-check.yaml:
--------------------------------------------------------------------------------
1 | ---
2 | # ------------------------------------------
3 | # Scheduled check of versions
4 | # - use as non-urgent report on versions
5 | # - Uses POSIX Cron syntax
6 | # - Minute [0,59]
7 | # - Hour [0,23]
8 | # - Day of the month [1,31]
9 | # - Month of the year [1,12]
10 | # - Day of the week ([0,6] with 0=Sunday)
11 | #
12 | # Using liquidz/anta to check:
13 | # - GitHub workflows
14 | # - deps.edn
15 | # ------------------------------------------
16 |
17 | name: "Scheduled Version Check"
18 | on:
19 | schedule:
20 | # - cron: "0 4 * * *" # at 04:04:04 ever day
21 | # - cron: "0 4 * * 5" # at 04:04:04 ever Friday
22 | - cron: "0 4 1 * *" # at 04:04:04 on first day of month
23 | workflow_dispatch: # Run manually via GitHub Actions Workflow page
24 |
25 | jobs:
26 | scheduled-version-check:
27 | name: "Scheduled Version Check"
28 | runs-on: ubuntu-latest
29 | steps:
30 | - run: echo "🚀 Job automatically triggered by ${{ github.event_name }}"
31 | - run: echo "🐧 Job running on ${{ runner.os }} server"
32 | - run: echo "🐙 Using ${{ github.ref }} branch from ${{ github.repository }} repository"
33 |
34 | - name: Checkout Code
35 | uses: actions/checkout@v5
36 | - run: echo "🐙 ${{ github.repository }} repository sparse-checkout to the CI runner."
37 | - name: Antq Check Version
38 | uses: liquidz/antq-action@main
39 | with:
40 | excludes: "org.clojure/tools.deps.alpha"
41 | skips: "boot shadow-cljs leiningen"
42 |
43 | # Summary
44 | - run: echo "🎨 library versions checked with liquidz/antq"
45 | - run: echo "🍏 Job status is ${{ job.status }}."
46 |
--------------------------------------------------------------------------------
/resources/practicalli/landing_page/root/.github/workflows/scheduled-version-check.yaml:
--------------------------------------------------------------------------------
1 | ---
2 | # ------------------------------------------
3 | # Scheduled check of versions
4 | # - use as non-urgent report on versions
5 | # - Uses POSIX Cron syntax
6 | # - Minute [0,59]
7 | # - Hour [0,23]
8 | # - Day of the month [1,31]
9 | # - Month of the year [1,12]
10 | # - Day of the week ([0,6] with 0=Sunday)
11 | #
12 | # Using liquidz/anta to check:
13 | # - GitHub workflows
14 | # - deps.edn
15 | # ------------------------------------------
16 |
17 | name: "Scheduled Version Check"
18 | on:
19 | schedule:
20 | # - cron: "0 4 * * *" # at 04:04:04 ever day
21 | # - cron: "0 4 * * 5" # at 04:04:04 ever Friday
22 | - cron: "0 4 1 * *" # at 04:04:04 on first day of month
23 | workflow_dispatch: # Run manually via GitHub Actions Workflow page
24 |
25 | jobs:
26 | scheduled-version-check:
27 | name: "Scheduled Version Check"
28 | runs-on: ubuntu-latest
29 | steps:
30 | - run: echo "🚀 Job automatically triggered by ${{ github.event_name }}"
31 | - run: echo "🐧 Job running on ${{ runner.os }} server"
32 | - run: echo "🐙 Using ${{ github.ref }} branch from ${{ github.repository }} repository"
33 |
34 | - name: Checkout Code
35 | uses: actions/checkout@v5
36 | - run: echo "🐙 ${{ github.repository }} repository sparse-checkout to the CI runner."
37 | - name: Antq Check Version
38 | uses: liquidz/antq-action@main
39 | with:
40 | excludes: "org.clojure/tools.deps.alpha"
41 | skips: "boot shadow-cljs leiningen"
42 |
43 | # Summary
44 | - run: echo "🎨 library versions checked with liquidz/antq"
45 | - run: echo "🍏 Job status is ${{ job.status }}."
46 |
--------------------------------------------------------------------------------
/resources/practicalli/service/dev/system_repl.clj.template:
--------------------------------------------------------------------------------
1 | ;; ---------------------------------------------------------
2 | ;; System REPL - Atom Restart
3 | ;;
4 | ;; Tools for REPl workflow with Aton reference to HTTP server
5 | ;; https://practical.li/clojure-web-services/app-servers/simple-restart/
6 | ;; ---------------------------------------------------------
7 |
8 | (ns system-repl
9 | (:require
10 | [clojure.tools.namespace.repl :refer [refresh]]
11 | [{{top/ns}}.{{main/ns}}.service :as service]))
12 |
13 | ;; ---------------------------------------------------------
14 | ;; HTTP Server State
15 |
16 | (defonce http-server-instance (atom nil))
17 | ;; ---------------------------------------------------------
18 |
19 |
20 | ;; ---------------------------------------------------------
21 | ;; REPL workflow commands
22 |
23 | (defn stop
24 | "Gracefully shutdown the server, waiting 100ms"
25 | []
26 | (when-not (nil? @http-server-instance)
27 | (@http-server-instance :timeout 100)
28 | (reset! http-server-instance nil)
29 | (println "INFO: HTTP server shutting down...")))
30 |
31 | (defn start
32 | "Start the application server and run the application"
33 | [& port]
34 | (let [port (Integer/parseInt
35 | (or (first port)
36 | (System/getenv "PORT")
37 | "8080"))]
38 | (println "INFO: Starting server on port:" port)
39 |
40 | (reset! http-server-instance
41 | (service/http-server-start port))))
42 |
43 |
44 | (defn restart
45 | "Stop the http server, refresh changed namespace and start the http server again"
46 | []
47 | (stop)
48 | (refresh) ;; Refresh changed namespaces
49 | (start))
50 | ;; ---------------------------------------------------------
51 |
52 |
--------------------------------------------------------------------------------
/resources/practicalli/landing_page/src/data.cljs.template:
--------------------------------------------------------------------------------
1 | ;; ---------------------------------------------------------
2 | ;; {{top/ns}}.data
3 | ;;
4 | ;; Data used to generate components that make up the main page
5 | ;; ---------------------------------------------------------
6 |
7 | (ns {{top/ns}}.data)
8 |
9 | (def assets
10 | "Information used to generate content, enabling use across multiple components
11 | and avoiding hard-coded component data"
12 | {:organisation {:logo "https://placehold.co/120x120/EEE/31343C?font=open-sans&text=logo"
13 | :banner "https://placehold.co/820x200/EEE/31343C?font=open-sans&text=Clojure"
14 | :website "https://practical.li"
15 | :status "https://status.practical.li/"
16 | :repository "https://github.com/{{developer}}"}
17 |
18 | :catalog
19 | [{:name "Practicalli Clojure"
20 | :description "Clojure development workflow and tools"
21 | :reference "https://practical.li/clojure"
22 | :image "https://placehold.co/640x400/EEE/31343C?font=open-sans&text=Clojure"}
23 | {:name "Practicalli ClojureScript"
24 | :description "Learn ClojureScript the practical way"
25 | :reference "https://practical.li/clojurescript"
26 | :image "https://placehold.co/640x400/EEE/31343C?font=open-sans&text=ClojureScript"}]
27 |
28 | :support
29 | {:youtube-subscribe
30 | {:url "https://www.youtube.com/practicalli?sub_confirmation=1"
31 | :logo "https://raw.githubusercontent.com/practicalli/graphic-design/live/buttons/practicalli-youtube-channel-subscribe-button.png"}
32 |
33 | :github-sponsors
34 | {:url "https://github.com/sponsors/{{developer}}/"
35 | :logo "https://raw.githubusercontent.com/practicalli/graphic-design/live/buttons/practicalli-github-sponsors-button.png"}}})
36 |
--------------------------------------------------------------------------------
/resources/practicalli/application/src/app.clj.template:
--------------------------------------------------------------------------------
1 | ;; ---------------------------------------------------------
2 | ;; {{top/ns}}.{{main/ns}}
3 | ;;
4 | ;; {{description}}
5 | ;; ---------------------------------------------------------
6 |
7 |
8 | (ns {{top/ns}}.{{main/ns}}
9 | (:gen-class)
10 | (:require
11 | [com.brunobonacci.mulog :as mulog]))
12 |
13 |
14 | ;; ---------------------------------------------------------
15 | ;; Start Mulog publisher - only once
16 | (defonce mulog-publisher
17 | (mulog/start-publisher! {:type :console :pretty? true}))
18 | ;; ---------------------------------------------------------
19 |
20 |
21 | ;; ---------------------------------------------------------
22 | ;; Application
23 |
24 | #_{:clj-kondo/ignore [:clojure-lsp/unused-public-var]}
25 | (defn greet
26 | "Greeting message via Clojure CLI clojure.exec"
27 | ([] (greet {:team-name "secret engineering"}))
28 | ([{:keys [team-name]}]
29 | (str "{{top/ns}} {{main/ns}} service developed by the " team-name " team")))
30 |
31 |
32 | (defn -main
33 | "Entry point into the application via clojure.main -M"
34 | [& args]
35 | (let [team (first args)]
36 | (mulog/set-global-context!
37 | {:app-name "{{top/ns}} {{main/ns}}" :version "{{version}}"})
38 | (mulog/log ::application-starup :arguments args)
39 | (if team
40 | (greet team)
41 | (greet))))
42 |
43 | ;; ---------------------------------------------------------
44 |
45 |
46 | ;; ---------------------------------------------------------
47 | ;; Rick Comment
48 | #_{:clj-kondo/ignore [:redefined-var]}
49 | (comment
50 |
51 | (-main)
52 | (-main {:team-name "Clojure Engineering"})
53 |
54 | ;; Stop mulog publisher
55 | (mulog-publisher)
56 |
57 | #_()) ; End of rich comment block
58 | ;; ---------------------------------------------------------
59 |
--------------------------------------------------------------------------------
/resources/practicalli/landing_page/template.edn:
--------------------------------------------------------------------------------
1 | {;; Values to pass into the template
2 | :description "TODO: Provide a meaningful description of the project"
3 |
4 | ;; ---------------------------------------------------------
5 | ;; Version substitutions
6 |
7 | :clojure-version "1.12.3"
8 | ;; ---------------------------------------------------------
9 |
10 | ;; ---------------------------------------------------------
11 | ;; Optional features
12 | ;; - used by programatic transformation
13 | ;; - not implemented yet
14 | ;; ---------------------------------------------------------
15 |
16 | ;; ---------------------------------------------------------
17 | ;; Programatic Transformation functions
18 |
19 | :data-fn practicalli.landing-page/substitutions
20 |
21 | :template-fn practicalli.landing-page/template-edn
22 | ;; ---------------------------------------------------------
23 |
24 | ;; ---------------------------------------------------------
25 | ;; Declarative Transformation rules
26 | ;; - can be updated by programmatic transformation
27 | ;;
28 | ;; Form:
29 | ;; [["directory-name" "default-path"
30 | ;; {"source-file.extension.template" "destination-file.extension"}]]
31 |
32 | :transform
33 | [["build" ""
34 | {"deps.edn.template" "deps.edn"
35 | "dev.cljs.edn.template" "dev.cljs.edn"
36 | "github-pages.cljs.edn.template" "github-pages.cljs.edn"
37 | "test.cljs.edn.template" "test.cljs.edn"}]
38 | ["src" "src/{{top/file}}"
39 | {"main_page.cljs.template" "{{main/file}}.cljs"
40 | "data.cljs.template" "data.cljs"
41 | "component.cljs.template" "component.cljs"}]
42 | ["test" "test/{{top/file}}"
43 | {"main_page_test.cljs.template" "{{main/file}}_test.cljs"
44 | "test_runner.cljs.template" "test_runner.cljs"}]]}
45 | ;; ---------------------------------------------------------
46 |
--------------------------------------------------------------------------------
/.github/workflows/quality-checks.yaml:
--------------------------------------------------------------------------------
1 | ---
2 | name: "Quality Checks"
3 | on:
4 | pull_request:
5 | push:
6 | branches:
7 | - main
8 | jobs:
9 | check-code-quality:
10 | name: "Check Code Quality"
11 | runs-on: ubuntu-latest
12 | steps:
13 | - run: echo "🚀 Job automatically triggered by ${{ github.event_name }}"
14 | - run: echo "🐧 Job running on ${{ runner.os }} server"
15 | - run: echo "🐙 Using ${{ github.ref }} branch from ${{ github.repository }} repository"
16 |
17 | - name: "Checkout code"
18 | uses: actions/checkout@v6
19 | with:
20 | fetch-depth: 0
21 | - run: echo "🐙 ${{ github.repository }} repository was cloned to the runner."
22 |
23 | - name: "Prepare Java runtime"
24 | uses: actions/setup-java@v5
25 | with:
26 | distribution: "temurin"
27 | java-version: "21"
28 |
29 | - name: "Cache Clojure Dependencies"
30 | uses: actions/cache@v4
31 | with:
32 | path: |
33 | ~/.m2/repository
34 | ~/.gitlibs
35 | key: clojure-deps-${{ hashFiles('**/deps.edn') }}
36 | restore-keys: clojure-deps-
37 |
38 | - name: "Install tools"
39 | uses: DeLaGuardo/setup-clojure@13.4
40 | with:
41 | cli: 1.12.3.1577 # Clojure CLI
42 | cljstyle: 0.17.642
43 | clj-kondo: 2025.10.23
44 |
45 | - name: "Kaocha test runner"
46 | run: clojure -X:test/env:test/run
47 |
48 | - name: "Lint Clojure"
49 | run: clj-kondo --lint deps.edn --config '{:output {:pattern "::{{level}} file={{filename}},line={{row}},col={{col}}::{{message}}"}}'
50 |
51 | - name: "Check Clojure Style"
52 | run: cljstyle check --report
53 |
54 | - run: echo "🎨 style and format of Clojure code checked"
55 |
56 | - run: echo "🍏 Job status is ${{ job.status }}."
57 |
--------------------------------------------------------------------------------
/resources/practicalli/service/dev/mulog_events.clj:
--------------------------------------------------------------------------------
1 | ;; ---------------------------------------------------------
2 | ;; Mulog Global Context and Custom Publisher
3 | ;;
4 | ;; - tap publisher for use with Portal and other tap sources
5 | ;; - publish all mulog events to Portal tap source
6 | ;;
7 | ;; NOTE: Mulog global context set in system configuration
8 | ;; ---------------------------------------------------------
9 |
10 | (ns mulog-events
11 | (:require
12 | [com.brunobonacci.mulog :as mulog]
13 | [com.brunobonacci.mulog.buffer :as mulog-buffer]))
14 |
15 | ;; ---------------------------------------------------------
16 | ;; Mulog event publishing
17 |
18 | (deftype TapPublisher
19 | [buffer transform]
20 | com.brunobonacci.mulog.publisher.PPublisher
21 | (agent-buffer [_] buffer)
22 | (publish-delay [_] 200)
23 | (publish [_ buffer]
24 | (doseq [item (transform (map second (mulog-buffer/items buffer)))]
25 | (tap> item))
26 | (mulog-buffer/clear buffer)))
27 |
28 | #_{:clj-kondo/ignore [:unused-private-var]}
29 | (defn ^:private tap-events
30 | [{:keys [transform] :as _config}]
31 | (TapPublisher. (mulog-buffer/agent-buffer 10000) (or transform identity)))
32 |
33 | (def tap-publisher
34 | "Start mulog custom tap publisher to send all events to Portal
35 | and other tap sources
36 | `mulog-tap-publisher` to stop publisher"
37 | (mulog/start-publisher!
38 | {:type :custom, :fqn-function "mulog-events/tap-events"}))
39 |
40 | #_{:clj-kondo/ignore [:unused-public-var]}
41 | (defn stop
42 | "Stop mulog tap publisher to ensure multiple publishers are not started
43 | Recommended before using `(restart)` or evaluating the `user` namespace"
44 | []
45 | tap-publisher)
46 |
47 | ;; Example mulog event message
48 | ;; (mulog/log ::dev-user-ns :message "Example event message" :ns (ns-publics *ns*))
49 | ;; ---------------------------------------------------------
50 |
--------------------------------------------------------------------------------
/resources/practicalli/service/root/.github/workflows/quality-checks.yaml:
--------------------------------------------------------------------------------
1 | ---
2 | name: "Quality Checks"
3 | on:
4 | pull_request:
5 | push:
6 | branches:
7 | - main
8 | jobs:
9 | check-code-quality:
10 | name: "Check Code Quality"
11 | runs-on: ubuntu-latest
12 | steps:
13 | - run: echo "🚀 Job automatically triggered by ${{ github.event_name }}"
14 | - run: echo "🐧 Job running on ${{ runner.os }} server"
15 | - run: echo "🐙 Using ${{ github.ref }} branch from ${{ github.repository }} repository"
16 |
17 | - name: "Checkout code"
18 | uses: actions/checkout@v5
19 | with:
20 | fetch-depth: 0
21 | - run: echo "🐙 ${{ github.repository }} repository was cloned to the runner."
22 |
23 | - name: "Prepare Java runtime"
24 | uses: actions/setup-java@v5
25 | with:
26 | distribution: "temurin"
27 | java-version: "21"
28 |
29 | - name: "Cache Clojure Dependencies"
30 | uses: actions/cache@v4
31 | with:
32 | path: |
33 | ~/.m2/repository
34 | ~/.gitlibs
35 | key: clojure-deps-${{ hashFiles('**/deps.edn') }}
36 | restore-keys: clojure-deps-
37 |
38 | - name: "Install tools"
39 | uses: DeLaGuardo/setup-clojure@13.4
40 | with:
41 | cli: 1.12.2.1565 # Clojure CLI
42 | cljstyle: 0.17.642
43 | clj-kondo: 2025.07.28
44 |
45 | - name: "Kaocha test runner"
46 | run: clojure -X:test/env:test/run
47 |
48 | - name: "Lint Clojure"
49 | run: clj-kondo --lint deps.edn --config '{:output {:pattern "::{{level}} file={{filename}},line={{row}},col={{col}}::{{message}}"}}'
50 |
51 | - name: "Check Clojure Style"
52 | run: cljstyle check --report
53 |
54 | - run: echo "🎨 style and format of Clojure code checked"
55 |
56 | - run: echo "🍏 Job status is ${{ job.status }}."
57 |
--------------------------------------------------------------------------------
/resources/practicalli/application/root/.github/workflows/quality-checks.yaml:
--------------------------------------------------------------------------------
1 | ---
2 | name: "Quality Checks"
3 | on:
4 | pull_request:
5 | push:
6 | branches:
7 | - main
8 | jobs:
9 | check-code-quality:
10 | name: "Check Code Quality"
11 | runs-on: ubuntu-latest
12 | steps:
13 | - run: echo "🚀 Job automatically triggered by ${{ github.event_name }}"
14 | - run: echo "🐧 Job running on ${{ runner.os }} server"
15 | - run: echo "🐙 Using ${{ github.ref }} branch from ${{ github.repository }} repository"
16 |
17 | - name: "Checkout code"
18 | uses: actions/checkout@v5
19 | with:
20 | fetch-depth: 0
21 | - run: echo "🐙 ${{ github.repository }} repository was cloned to the runner."
22 |
23 | - name: "Prepare Java runtime"
24 | uses: actions/setup-java@v5
25 | with:
26 | distribution: "temurin"
27 | java-version: "21"
28 |
29 | - name: "Cache Clojure Dependencies"
30 | uses: actions/cache@v4
31 | with:
32 | path: |
33 | ~/.m2/repository
34 | ~/.gitlibs
35 | key: clojure-deps-${{ hashFiles('**/deps.edn') }}
36 | restore-keys: clojure-deps-
37 |
38 | - name: "Install tools"
39 | uses: DeLaGuardo/setup-clojure@13.4
40 | with:
41 | cli: 1.12.2.1565 # Clojure CLI
42 | cljstyle: 0.17.642
43 | clj-kondo: 2025.07.28
44 |
45 | - name: "Kaocha test runner"
46 | run: clojure -X:test/env:test/run
47 |
48 | - name: "Lint Clojure"
49 | run: clj-kondo --lint deps.edn --config '{:output {:pattern "::{{level}} file={{filename}},line={{row}},col={{col}}::{{message}}"}}'
50 |
51 | - name: "Check Clojure Style"
52 | run: cljstyle check --report
53 |
54 | - run: echo "🎨 style and format of Clojure code checked"
55 |
56 | - run: echo "🍏 Job status is ${{ job.status }}."
57 |
--------------------------------------------------------------------------------
/resources/practicalli/landing_page/root/.github/workflows/quality-checks.yaml:
--------------------------------------------------------------------------------
1 | ---
2 | name: "Quality Checks"
3 | on:
4 | pull_request:
5 | push:
6 | branches:
7 | - main
8 | jobs:
9 | check-code-quality:
10 | name: "Check Code Quality"
11 | runs-on: ubuntu-latest
12 | steps:
13 | - run: echo "🚀 Job automatically triggered by ${{ github.event_name }}"
14 | - run: echo "🐧 Job running on ${{ runner.os }} server"
15 | - run: echo "🐙 Using ${{ github.ref }} branch from ${{ github.repository }} repository"
16 |
17 | - name: "Checkout code"
18 | uses: actions/checkout@v5
19 | with:
20 | fetch-depth: 0
21 | - run: echo "🐙 ${{ github.repository }} repository was cloned to the runner."
22 |
23 | - name: "Prepare Java runtime"
24 | uses: actions/setup-java@v5
25 | with:
26 | distribution: "temurin"
27 | java-version: "21"
28 |
29 | - name: "Cache Clojure Dependencies"
30 | uses: actions/cache@v4
31 | with:
32 | path: |
33 | ~/.m2/repository
34 | ~/.gitlibs
35 | key: clojure-deps-${{ hashFiles('**/deps.edn') }}
36 | restore-keys: clojure-deps-
37 |
38 | - name: "Install tools"
39 | uses: DeLaGuardo/setup-clojure@13.4
40 | with:
41 | cli: 1.12.2.1565 # Clojure CLI
42 | cljstyle: 0.17.642
43 | clj-kondo: 2025.07.28
44 |
45 | - name: "Kaocha test runner"
46 | run: clojure -X:test/env:test/run
47 |
48 | - name: "Lint Clojure"
49 | run: clj-kondo --lint deps.edn --config '{:output {:pattern "::{{level}} file={{filename}},line={{row}},col={{col}}::{{message}}"}}'
50 |
51 | - name: "Check Clojure Style"
52 | run: cljstyle check --report
53 |
54 | - run: echo "🎨 style and format of Clojure code checked"
55 |
56 | - run: echo "🍏 Job status is ${{ job.status }}."
57 |
--------------------------------------------------------------------------------
/resources/practicalli/service/docker/compose-service-postgres.yaml.template:
--------------------------------------------------------------------------------
1 | ---
2 | # --- Docker Compose Configuration --- #
3 | # - Docker Compose V2
4 | # - https://docs.docker.com/compose/compose-file/
5 | #
6 | # Build the Clojure Service from source code
7 | # and run on port 8080
8 | #
9 | # Examples of persistence with Postgres and mysql docker images
10 | # and local data storage to facilitate data restoration
11 |
12 | name: "{{top/ns}}"
13 |
14 | services:
15 | # --- Clojure Service --- #
16 | {{main/ns}}-service:
17 | platform: linux/amd64
18 | # Build using Dockerfile - relative path or Git repository
19 | build:
20 | context: ./ # Use Dockerfile in project root
21 | environment: # host:container
22 | - COMPOSE_PROJECT_NAME
23 | ports: # host:container
24 | - 8080:8080
25 | depends_on:
26 | postgres-database:
27 | condition: service_healthy
28 |
29 |
30 | # --- Persistence Services --- #
31 |
32 | # --- Postgres Relational Database --- #
33 | # https://github.com/docker-library/docs/blob/master/postgres/README.md
34 | postgres-database:
35 | image: postgres:15.2-alpine
36 | environment:
37 | # superuser password - must not be empty
38 | POSTGRES_PASSWORD: "$DOCKER_POSTGRES_ROOT_PASSWORD"
39 | # Set User Credentials - optional
40 | POSTGRES_USER: "$DOCKER_POSTGRES_USER"
41 | POSTGRES_DB: "$DOCKER_POSTGRES_SCHEMA"
42 | healthcheck:
43 | test: [ "CMD", "pg_isready" ]
44 | timeout: 45s
45 | interval: 10s
46 | retries: 10
47 | ports:
48 | - 5432:5432
49 | # Persist Postgres database schema in a docker volume
50 | volumes:
51 | - postgres-data:/var/lib/postgres/data
52 | # Mount project root
53 | volumes:
54 | postgres-data:
55 |
56 | # postgres web-based administration tool
57 | postgres-adminer:
58 | image: adminer
59 | restart: always
60 | ports:
61 | - 8080:8080
62 |
--------------------------------------------------------------------------------
/resources/practicalli/application/root/compose.yaml:
--------------------------------------------------------------------------------
1 | ---
2 | # --- Docker Compose Configuration --- #
3 | # - Docker Compose V2
4 | # - https://docs.docker.com/compose/compose-file/
5 | #
6 | # Build the Clojure Service from source code
7 | # and run on port 8080
8 | #
9 | # Examples of persistence with Postgres and mysql docker images
10 | # and local data storage to facilitate data restoration
11 |
12 | name: "{{top/ns}}"
13 |
14 | services:
15 | # --- Clojure Service --- #
16 | {{main/ns}}:
17 | platform: linux/amd64
18 | # Build using Dockerfile - relative path or Git repository
19 | build:
20 | context: ./ # Use Dockerfile in project root
21 | environment: # host:container
22 | - COMPOSE_PROJECT_NAME
23 | ports: # host:container
24 | - 8080:8080
25 | # depends_on:
26 | # postgres-database:
27 | # condition: service_healthy
28 |
29 |
30 | # --- Persistence Services --- #
31 |
32 | # --- Postgres Relational Database --- #
33 | # https://github.com/docker-library/docs/blob/master/postgres/README.md
34 | # postgres-database:
35 | # image: postgres:15.2-alpine
36 | # environment:
37 | # # superuser password - must not be empty
38 | # POSTGRES_PASSWORD: "$DOCKER_POSTGRES_ROOT_PASSWORD"
39 | # # Set User Credentials - optional
40 | # POSTGRES_USER: "$DOCKER_POSTGRES_USER"
41 | # POSTGRES_DB: "$DOCKER_POSTGRES_SCHEMA"
42 | # healthcheck:
43 | # test: [ "CMD", "pg_isready" ]
44 | # timeout: 45s
45 | # interval: 10s
46 | # retries: 10
47 | # ports:
48 | # - 5432:5432
49 | # Persist Postgres database schema in a docker volume
50 | # volumes:
51 | # - postgres-data:/var/lib/postgres/data
52 | # Mount project root
53 | # volumes:
54 | # postgres-data:
55 |
56 | # postgres web-based administration tool
57 | # postgres-adminer:
58 | # image: adminer
59 | # restart: always
60 | # ports:
61 | # - 8080:8080
62 |
--------------------------------------------------------------------------------
/resources/practicalli/service/api/scoreboard.clj.template:
--------------------------------------------------------------------------------
1 | ;; --------------------------------------------------
2 | ;; {{top/ns}}.{{main/ns}}.api.scoreboard
3 | ;;
4 | ;; Example route and handler function
5 | ;; using clojure.spec response validation
6 | ;; --------------------------------------------------
7 |
8 |
9 | (ns {{top/ns}}.{{main/ns}}.api.scoreboard
10 | "Gameboard API Scoreboard across all games"
11 | (:require
12 | [ring.util.response :refer [response]]
13 | [clojure.spec.alpha :as spec]))
14 |
15 |
16 | ;; --------------------------------------------------
17 | ;; Value Specifications
18 | (spec/def ::game-id string?)
19 | (spec/def ::game-name string?)
20 | (spec/def ::high-score string?)
21 | ;; --------------------------------------------------
22 |
23 |
24 | ;; --------------------------------------------------
25 | ;; Mock scores for the Gameboard service
26 |
27 | (def scores
28 | "Simple status report for external monitoring services, e.g. Pingdom
29 | Return:
30 | - `constantly` returns an anonymous function that returns a ring response hash-map"
31 | (constantly (response {::game-id "347938472938439487492"
32 | ::game-name "Polymous"
33 | ::high-score "344398799666"})))
34 | ;; --------------------------------------------------
35 |
36 |
37 | ;; --------------------------------------------------
38 | ;; Routes
39 |
40 | (defn routes
41 | "Reitit route configuration for scoreboard endpoints
42 | Responses validated with {{top/ns}}.{{main/ns}}.spec clojure.spec"
43 | []
44 | ["/scoreboard"
45 | {:swagger {:tags ["Scoreboard Endpoints"]}
46 | :get {:summary "Scoreboard across all games"
47 | :description "Return all the high scores for every game registered"
48 | :handler scores
49 | :responses
50 | {200
51 | {:body (spec/keys :req [::game-id ::game-name ::high-score])}}}}])
52 | ;; --------------------------------------------------
53 |
--------------------------------------------------------------------------------
/resources/practicalli/service/api/scoreboard_config.clj.template:
--------------------------------------------------------------------------------
1 | ;; --------------------------------------------------
2 | ;; {{top/ns}}.{{main/ns}}.api.scoreboard
3 | ;;
4 | ;; Example route and handler function
5 | ;; using clojure.spec response validation
6 | ;; --------------------------------------------------
7 |
8 |
9 | (ns {{top/ns}}.{{main/ns}}.api.scoreboard
10 | "Gameboard API Scoreboard across all games"
11 | (:require
12 | [ring.util.response :refer [response]]
13 | [clojure.spec.alpha :as spec]))
14 |
15 |
16 | ;; --------------------------------------------------
17 | ;; Value Specifications
18 | (spec/def ::game-id string?)
19 | (spec/def ::game-name string?)
20 | (spec/def ::high-score string?)
21 | ;; --------------------------------------------------
22 |
23 |
24 | ;; --------------------------------------------------
25 | ;; Mock scores for the Gameboard service
26 |
27 | (def scores
28 | "Simple status report for external monitoring services, e.g. Pingdom
29 | Return:
30 | - `constantly` returns an anonymous function that returns a ring response hash-map"
31 | (constantly (response {::game-id "347938472938439487492"
32 | ::game-name "Polymous"
33 | ::high-score "344398799666"})))
34 | ;; --------------------------------------------------
35 |
36 |
37 | ;; --------------------------------------------------
38 | ;; Routes
39 |
40 | (defn routes
41 | "Reitit route configuration for scoreboard endpoints
42 | Responses validated with {{top/ns}}.{{main/ns}}.spec clojure.spec"
43 | [system-config]
44 | ["/scoreboard"
45 | {:swagger {:tags ["Scoreboard Endpoints"]}
46 | :get {:summary "Scoreboard across all games"
47 | :description "Return all the high scores for every game registered"
48 | :handler scores
49 | :responses
50 | {200
51 | {:body (spec/keys :req [::game-id ::game-name ::high-score])}}}}])
52 | ;; --------------------------------------------------
53 |
--------------------------------------------------------------------------------
/resources/practicalli/landing_page/root/README.md:
--------------------------------------------------------------------------------
1 | # {{top/ns}} {{main/ns}}
2 |
3 | {{description}}
4 |
5 | ## Development Workflows
6 |
7 | Drive a Browser connected REPL from an Editor or via a rich terminal UI (rebel)
8 |
9 | ### Emacs & CIDER
10 |
11 | Open a ClojureScript (*.cljs) or Clojure file (e.g. deps.edn) in Emacs.
12 |
13 | `cider-jack-in-cljs` command will launch a REPL process and start Figwheel.
14 |
15 | > `.dir-locals.el` Emacs project configuration specifies `figwheel-main` as the build tool and `dev` as the build task to run.
16 | >
17 | > [Practicalli Spacemacs - ClojureScript Projects](https://practical.li/spacemacs/clojure-repl/clojurescript-repl/) walks through the steps to start a REPL with Figwheel-main
18 |
19 | ### Rich Terminal workflow
20 |
21 | Starts a rich terminal UI REPL which also launches and controls the figwheel tool.
22 |
23 | ```shell
24 | make repl
25 | ```
26 |
27 | > The make repl task calls the command `clojure -M:figwheel/env:build/dev`
28 |
29 | ### Figwheel workflow
30 |
31 | Once the REPL and Fighweel have started:
32 |
33 | - ClojureScript code is compiled into JavaScript
34 | - a browser tab/window is opened
35 | - the index.html page with JavaScript app link is sent to the opened browser and rendered
36 |
37 | Saved changes to the ClojureScript code and CSS will auto compile and resulting JavaScript sent to the browser without the need to reload.
38 |
39 | Once the compilation process is complete, try evaluate code to test the Browser Connected REPL.
40 |
41 | ```clojure
42 | (js/alert "Am I connected?")
43 | ```
44 |
45 | An alert box should appear in the browser window.
46 |
47 | ### Clean build
48 |
49 | To clean all compiled files:
50 |
51 | ```shell
52 | make build-clean
53 | ```
54 |
55 | Create an application build that can be deployed to GitHub pages
56 |
57 | ```shell
58 | make dist
59 | ```
60 |
61 | ## License
62 |
63 | Copyright © 2023 {{developer}}
64 |
65 | Distributed under the Creative Commons Attribution Share-Alike 4.0 International
66 |
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 4.0.0
4 | practicalli.template
5 | service
6 | 0.1.0-SNAPSHOT
7 | practicalli.template/service
8 | FIXME: my new template.
9 | https://github.com/practicalli.template/service
10 |
11 |
12 | Eclipse Public License
13 | http://www.eclipse.org/legal/epl-v10.html
14 |
15 |
16 |
17 |
18 | Practicalli
19 |
20 |
21 |
22 | https://github.com/practicalli.template/service
23 | scm:git:git://github.com/practicalli.template/service.git
24 | scm:git:ssh://git@github.com/practicalli.template/service.git
25 | v0.1.0-SNAPSHOT
26 |
27 |
28 |
29 | org.clojure
30 | clojure
31 | 1.12.3
32 |
33 |
34 |
35 | src
36 |
37 |
38 |
39 | clojars
40 | https://repo.clojars.org/
41 |
42 |
43 | sonatype
44 | https://oss.sonatype.org/content/repositories/snapshots/
45 |
46 |
47 |
48 |
49 | clojars
50 | Clojars repository
51 | https://clojars.org/repo
52 |
53 |
54 |
55 |
--------------------------------------------------------------------------------
/resources/practicalli/service/root/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 4.0.0
4 | {{group/id}}
5 | {{artifact/id}}
6 | {{version}}
7 | {{raw-name}}
8 | {{description}}
9 | https://{{scm/domain}}/{{scm/user}}/{{scm/repo}}
10 |
11 |
12 | Eclipse Public License
13 | http://www.eclipse.org/legal/epl-v10.html
14 |
15 |
16 |
17 |
18 | {{developer}}
19 |
20 |
21 |
22 | https://{{scm/domain}}/{{scm/user}}/{{scm/repo}}
23 | scm:git:git://{{scm/domain}}/{{scm/user}}/{{scm/repo}}.git
24 | scm:git:ssh://git@{{scm/domain}}/{{scm/user}}/{{scm/repo}}.git
25 | v{{version}}
26 |
27 |
28 |
29 | org.clojure
30 | clojure
31 | {{clojure-version}}
32 |
33 |
34 |
35 | src
36 |
37 |
38 |
39 | clojars
40 | https://repo.clojars.org/
41 |
42 |
43 | sonatype
44 | https://oss.sonatype.org/content/repositories/snapshots/
45 |
46 |
47 |
48 |
49 | clojars
50 | Clojars repository
51 | https://clojars.org/repo
52 |
53 |
54 |
55 |
--------------------------------------------------------------------------------
/src/practicalli/service.clj:
--------------------------------------------------------------------------------
1 | ;; ---------------------------------------------------------
2 | ;; Service template programatic Transformation
3 | ;;
4 | ;; Define transformations based on data in the template and
5 | ;; passed via the command line
6 | ;;
7 | ;; `data-fn` enrich substitution data
8 | ;; `template-fn` modify template.edn, e.g. declarative template rules
9 | ;; ---------------------------------------------------------
10 |
11 |
12 | (ns practicalli.service
13 | "Programmatic transformation of template data transformation rules"
14 | (:require
15 | [clojure.pprint :as pprint]
16 | [practicalli.rules :as rules]))
17 |
18 | #_{:clj-kondo/ignore [:clojure-lsp/unused-public-var]}
19 | (defn substitutions
20 | "Update keys & values available in the substitution data,
21 | from the template.edn, derived values and command line options
22 | Return:
23 | - hash-map to be merged into the existing substitution data"
24 | [data]
25 | ;; Simple example:
26 | #_(when (= (data :component) "integrant")
27 | {:integrant-repl true})
28 | ;; (println "Calculating substitutions...")
29 | ;; (pprint/pprint data)
30 | nil) ; returning nil means no changes to options data
31 |
32 | #_{:clj-kondo/ignore [:clojure-lsp/unused-public-var]}
33 | (defn template-edn
34 | "Update data in the template.edn configuration.
35 | E.g. derive new declarative transformation rules from
36 | template substitutions, derived values and values passed
37 | to the template via the command line
38 | Return
39 | - new template.edn configuration"
40 | [edn data]
41 |
42 | ;; Link to Practicalli Clojure Project Templates guide
43 | (println "Template guide: https://practical.li/clojure/clojure-cli/projects/templates/")
44 |
45 | ;; (println "Component" (data :component))
46 | (let [updated-template
47 | (cond
48 | (= :donut (data :component)) (assoc edn :transform rules/donut)
49 | (= :integrant (data :component)) (assoc edn :transform rules/integrant)
50 | :else edn)]
51 |
52 | ;; (println "Updated template...")
53 | ;; (pprint/pprint updated-template)
54 | updated-template))
55 |
--------------------------------------------------------------------------------
/.github/workflows/scheduled-stale-check.yaml:
--------------------------------------------------------------------------------
1 | # ----------------------------------------
2 | # Scheduled stale issue & pull request check
3 | #
4 | # Adds 'stale' label after a set piece of time,
5 | # then closes stale issues & pull requests a short period after
6 | #
7 | # Using "Close Stale Issues" action
8 | # https://github.com/marketplace/actions/close-stale-issues
9 | # ----------------------------------------
10 |
11 | name: 'Scheduled stale check'
12 | on:
13 | workflow_dispatch:
14 | schedule:
15 | - cron: "0 1 1 * *" # at 01:00 on first day of month
16 |
17 | jobs:
18 | stale:
19 | runs-on: ubuntu-latest
20 | steps:
21 | - run: echo "🚀 Job automatically triggered by ${{ github.event_name }}"
22 | - run: echo "🐧 Job running on ${{ runner.os }} server"
23 | - run: echo "🐙 Using ${{ github.ref }} branch from ${{ github.repository }} repository"
24 |
25 | - uses: actions/stale@v10
26 | with:
27 | stale-issue-message: 'After 30 days with no activity, the issue was automatically marked stale. Remove stale label or add a comment to prevent the issue being closed in 5 days.'
28 | stale-pr-message: 'After 45 days with no activity, the Pull Request was automatically marked stale. Remove stale label or comment to prevent the PR being closed in 10 days.'
29 | close-issue-message: 'This issue was closed because it has been stalled for 5 days with no activity.'
30 | close-pr-message: 'This PR was closed because it has been stalled for 10 days with no activity.'
31 | days-before-issue-stale: 30
32 | days-before-pr-stale: 45
33 | days-before-issue-close: 5
34 | days-before-pr-close: 10
35 | start-date: '2025-04-05T00:00:00Z' # only affect issues/PRs from date created (ISO 8601 or RFC 2822 format)
36 | any-of-labels: 'future,keep' # labels to keep
37 | exempt-issue-assignees: 'practicalli-johnny'
38 | exempt-pr-assignees: 'practicalli-johnny'
39 |
40 | # Summary
41 | - run: echo "🎨 Issues & Pull Request checked with actions/stale"
42 | - run: echo "🍏 Job status is ${{ job.status }}."
43 |
--------------------------------------------------------------------------------
/resources/practicalli/minimal/root/.github/workflows/scheduled-stale-check.yaml:
--------------------------------------------------------------------------------
1 | # ----------------------------------------
2 | # Scheduled stale issue & pull request check
3 | #
4 | # Adds 'stale' label after a set piece of time,
5 | # then closes stale issues & pull requests a short period after
6 | #
7 | # Using "Close Stale Issues" action
8 | # https://github.com/marketplace/actions/close-stale-issues
9 | # ----------------------------------------
10 |
11 | name: 'Scheduled stale check'
12 | on:
13 | workflow_dispatch:
14 | schedule:
15 | - cron: "0 1 1 * *" # at 01:00 on first day of month
16 |
17 | jobs:
18 | stale:
19 | runs-on: ubuntu-latest
20 | steps:
21 | - run: echo "🚀 Job automatically triggered by ${{ github.event_name }}"
22 | - run: echo "🐧 Job running on ${{ runner.os }} server"
23 | - run: echo "🐙 Using ${{ github.ref }} branch from ${{ github.repository }} repository"
24 |
25 | - uses: actions/stale@v9
26 | with:
27 | stale-issue-message: 'After 30 days with no activity, the issue was automatically marked stale. Remove stale label or add a comment to prevent the issue being closed in 5 days.'
28 | stale-pr-message: 'After 45 days with no activity, the Pull Request was automatically marked stale. Remove stale label or comment to prevent the PR being closed in 10 days.'
29 | close-issue-message: 'This issue was closed because it has been stalled for 5 days with no activity.'
30 | close-pr-message: 'This PR was closed because it has been stalled for 10 days with no activity.'
31 | days-before-issue-stale: 30
32 | days-before-pr-stale: 45
33 | days-before-issue-close: 5
34 | days-before-pr-close: 10
35 | start-date: '2025-04-05T00:00:00Z' # only affect issues/PRs from date created (ISO 8601 or RFC 2822 format)
36 | any-of-labels: 'future,keep' # labels to keep
37 | exempt-issue-assignees: 'practicalli-johnny'
38 | exempt-pr-assignees: 'practicalli-johnny'
39 |
40 | # Summary
41 | - run: echo "🎨 Issues & Pull Request checked with actions/stale"
42 | - run: echo "🍏 Job status is ${{ job.status }}."
43 |
--------------------------------------------------------------------------------
/resources/practicalli/service/root/.github/workflows/scheduled-stale-check.yaml:
--------------------------------------------------------------------------------
1 | # ----------------------------------------
2 | # Scheduled stale issue & pull request check
3 | #
4 | # Adds 'stale' label after a set piece of time,
5 | # then closes stale issues & pull requests a short period after
6 | #
7 | # Using "Close Stale Issues" action
8 | # https://github.com/marketplace/actions/close-stale-issues
9 | # ----------------------------------------
10 |
11 | name: 'Scheduled stale check'
12 | on:
13 | workflow_dispatch:
14 | schedule:
15 | - cron: "0 1 1 * *" # at 01:00 on first day of month
16 |
17 | jobs:
18 | stale:
19 | runs-on: ubuntu-latest
20 | steps:
21 | - run: echo "🚀 Job automatically triggered by ${{ github.event_name }}"
22 | - run: echo "🐧 Job running on ${{ runner.os }} server"
23 | - run: echo "🐙 Using ${{ github.ref }} branch from ${{ github.repository }} repository"
24 |
25 | - uses: actions/stale@v9
26 | with:
27 | stale-issue-message: 'After 30 days with no activity, the issue was automatically marked stale. Remove stale label or add a comment to prevent the issue being closed in 5 days.'
28 | stale-pr-message: 'After 45 days with no activity, the Pull Request was automatically marked stale. Remove stale label or comment to prevent the PR being closed in 10 days.'
29 | close-issue-message: 'This issue was closed because it has been stalled for 5 days with no activity.'
30 | close-pr-message: 'This PR was closed because it has been stalled for 10 days with no activity.'
31 | days-before-issue-stale: 30
32 | days-before-pr-stale: 45
33 | days-before-issue-close: 5
34 | days-before-pr-close: 10
35 | start-date: '2025-04-05T00:00:00Z' # only affect issues/PRs from date created (ISO 8601 or RFC 2822 format)
36 | any-of-labels: 'future,keep' # labels to keep
37 | exempt-issue-assignees: 'practicalli-johnny'
38 | exempt-pr-assignees: 'practicalli-johnny'
39 |
40 | # Summary
41 | - run: echo "🎨 Issues & Pull Request checked with actions/stale"
42 | - run: echo "🍏 Job status is ${{ job.status }}."
43 |
--------------------------------------------------------------------------------
/resources/practicalli/application/root/.github/workflows/scheduled-stale-check.yaml:
--------------------------------------------------------------------------------
1 | # ----------------------------------------
2 | # Scheduled stale issue & pull request check
3 | #
4 | # Adds 'stale' label after a set piece of time,
5 | # then closes stale issues & pull requests a short period after
6 | #
7 | # Using "Close Stale Issues" action
8 | # https://github.com/marketplace/actions/close-stale-issues
9 | # ----------------------------------------
10 |
11 | name: 'Scheduled stale check'
12 | on:
13 | workflow_dispatch:
14 | schedule:
15 | - cron: "0 1 1 * *" # at 01:00 on first day of month
16 |
17 | jobs:
18 | stale:
19 | runs-on: ubuntu-latest
20 | steps:
21 | - run: echo "🚀 Job automatically triggered by ${{ github.event_name }}"
22 | - run: echo "🐧 Job running on ${{ runner.os }} server"
23 | - run: echo "🐙 Using ${{ github.ref }} branch from ${{ github.repository }} repository"
24 |
25 | - uses: actions/stale@v9
26 | with:
27 | stale-issue-message: 'After 30 days with no activity, the issue was automatically marked stale. Remove stale label or add a comment to prevent the issue being closed in 5 days.'
28 | stale-pr-message: 'After 45 days with no activity, the Pull Request was automatically marked stale. Remove stale label or comment to prevent the PR being closed in 10 days.'
29 | close-issue-message: 'This issue was closed because it has been stalled for 5 days with no activity.'
30 | close-pr-message: 'This PR was closed because it has been stalled for 10 days with no activity.'
31 | days-before-issue-stale: 30
32 | days-before-pr-stale: 45
33 | days-before-issue-close: 5
34 | days-before-pr-close: 10
35 | start-date: '2025-04-05T00:00:00Z' # only affect issues/PRs from date created (ISO 8601 or RFC 2822 format)
36 | any-of-labels: 'future,keep' # labels to keep
37 | exempt-issue-assignees: 'practicalli-johnny'
38 | exempt-pr-assignees: 'practicalli-johnny'
39 |
40 | # Summary
41 | - run: echo "🎨 Issues & Pull Request checked with actions/stale"
42 | - run: echo "🍏 Job status is ${{ job.status }}."
43 |
--------------------------------------------------------------------------------
/resources/practicalli/landing_page/root/.github/workflows/scheduled-stale-check.yaml:
--------------------------------------------------------------------------------
1 | # ----------------------------------------
2 | # Scheduled stale issue & pull request check
3 | #
4 | # Adds 'stale' label after a set piece of time,
5 | # then closes stale issues & pull requests a short period after
6 | #
7 | # Using "Close Stale Issues" action
8 | # https://github.com/marketplace/actions/close-stale-issues
9 | # ----------------------------------------
10 |
11 | name: 'Scheduled stale check'
12 | on:
13 | workflow_dispatch:
14 | schedule:
15 | - cron: "0 1 1 * *" # at 01:00 on first day of month
16 |
17 | jobs:
18 | stale:
19 | runs-on: ubuntu-latest
20 | steps:
21 | - run: echo "🚀 Job automatically triggered by ${{ github.event_name }}"
22 | - run: echo "🐧 Job running on ${{ runner.os }} server"
23 | - run: echo "🐙 Using ${{ github.ref }} branch from ${{ github.repository }} repository"
24 |
25 | - uses: actions/stale@v9
26 | with:
27 | stale-issue-message: 'After 30 days with no activity, the issue was automatically marked stale. Remove stale label or add a comment to prevent the issue being closed in 5 days.'
28 | stale-pr-message: 'After 45 days with no activity, the Pull Request was automatically marked stale. Remove stale label or comment to prevent the PR being closed in 10 days.'
29 | close-issue-message: 'This issue was closed because it has been stalled for 5 days with no activity.'
30 | close-pr-message: 'This PR was closed because it has been stalled for 10 days with no activity.'
31 | days-before-issue-stale: 30
32 | days-before-pr-stale: 45
33 | days-before-issue-close: 5
34 | days-before-pr-close: 10
35 | start-date: '2025-04-05T00:00:00Z' # only affect issues/PRs from date created (ISO 8601 or RFC 2822 format)
36 | any-of-labels: 'future,keep' # labels to keep
37 | exempt-issue-assignees: 'practicalli-johnny'
38 | exempt-pr-assignees: 'practicalli-johnny'
39 |
40 | # Summary
41 | - run: echo "🎨 Issues & Pull Request checked with actions/stale"
42 | - run: echo "🍏 Job status is ${{ job.status }}."
43 |
--------------------------------------------------------------------------------
/resources/practicalli/service/build/deps.edn.template:
--------------------------------------------------------------------------------
1 | {;; ---------------------------------------------------------
2 | :paths
3 | ["src" "resources"]
4 | ;; ---------------------------------------------------------
5 |
6 | ;; ---------------------------------------------------------
7 | :deps
8 | {;; Service
9 | http-kit/http-kit {:mvn/version "2.8.0"}
10 | metosin/reitit {:mvn/version "0.7.0"}
11 | metosin/reitit-dev {:mvn/version "0.7.0"} ; human readable exceptions
12 |
13 | ;; Logging
14 | ;; create events and send to publisher
15 | com.brunobonacci/mulog {:mvn/version "0.9.0"}
16 | ;; JSON Console out support
17 | com.brunobonacci/mulog-adv-console {:mvn/version "0.9.0"}
18 | ;; Optional: suppress slf4j warning
19 | ;; org.slf4j/slf4j-nop {:mvn/version "1.7.32"}
20 |
21 | ;; System
22 | org.clojure/clojure {:mvn/version "{{clojure-version}}"}}
23 | ;; ---------------------------------------------------------
24 |
25 | ;; ---------------------------------------------------------
26 | :aliases
27 | {;; ------------
28 | ;; Clojure.main execution of application
29 | :run/service
30 | {:main-opts ["-m" "{{top/ns}}.{{main/ns}}.service"]}
31 |
32 | ;; Clojure.exec execution of specified function
33 | :run/greet
34 | {:exec-fn {{top/ns}}.{{main/ns}}.service/greet
35 | :exec-args {:name "Clojure"}}
36 | ;; ------------
37 |
38 | ;; ------------
39 | ;; Add libraries and paths to support additional test tools
40 | :test/env
41 | {}
42 |
43 | ;; Test runner - local and CI
44 | ;; call with :watch? true to start file watcher and re-run tests on saved changes
45 | :test/run
46 | {:extra-paths ["test"]
47 | :extra-deps {lambdaisland/kaocha {:mvn/version "1.91.1392"}}
48 | :main-opts ["-m" "kaocha.runner"]
49 | :exec-fn kaocha.runner/exec-fn
50 | :exec-args {:randomize? false
51 | :fail-fast? true}}
52 | ;; ------------
53 |
54 | ;; ------------
55 | ;; tools.build `build.clj` built script
56 | :build/task
57 | {:replace-paths ["."]
58 | :replace-deps {io.github.clojure/tools.build {:mvn/version "0.10.3"}}
59 | :ns-default build}}}
60 | ;; ------------
61 | ;; ---------------------------------------------------------
62 |
--------------------------------------------------------------------------------
/resources/practicalli/minimal/root/dev/mulog_events.clj:
--------------------------------------------------------------------------------
1 | ;; ---------------------------------------------------------
2 | ;; Mulog Global Context and Custom Publisher
3 | ;;
4 | ;; - set event log global context
5 | ;; - tap publisher for use with Portal and other tap sources
6 | ;; - publish all mulog events to Portal tap source
7 | ;; ---------------------------------------------------------
8 |
9 | (ns mulog-events
10 | (:require
11 | [com.brunobonacci.mulog :as mulog]
12 | [com.brunobonacci.mulog.buffer :as mulog-buffer]))
13 |
14 | ;; ---------------------------------------------------------
15 | ;; Set event global context
16 | ;; - information added to every event for REPL workflow
17 | (mulog/set-global-context! {:app-name "{{main/ns}} Service",
18 | :version "0.1.0", :env "dev"})
19 | ;; ---------------------------------------------------------
20 |
21 | ;; ---------------------------------------------------------
22 | ;; Mulog event publishing
23 |
24 | (deftype TapPublisher
25 | [buffer transform]
26 | com.brunobonacci.mulog.publisher.PPublisher
27 | (agent-buffer [_] buffer)
28 | (publish-delay [_] 200)
29 | (publish [_ buffer]
30 | (doseq [item (transform (map second (mulog-buffer/items buffer)))]
31 | (tap> item))
32 | (mulog-buffer/clear buffer)))
33 |
34 | #_{:clj-kondo/ignore [:unused-private-var]}
35 | (defn ^:private tap-events
36 | [{:keys [transform] :as _config}]
37 | (TapPublisher. (mulog-buffer/agent-buffer 10000) (or transform identity)))
38 |
39 | (def tap-publisher
40 | "Start mulog custom tap publisher to send all events to Portal
41 | and other tap sources
42 | `mulog-tap-publisher` to stop publisher"
43 | (mulog/start-publisher!
44 | {:type :custom, :fqn-function "mulog-events/tap-events"}))
45 |
46 | #_{:clj-kondo/ignore [:unused-public-var]}
47 | (defn stop
48 | "Stop mulog tap publisher to ensure multiple publishers are not started
49 | Recommended before using `(restart)` or evaluating the `user` namespace"
50 | []
51 | tap-publisher)
52 |
53 | ;; Example mulog event message
54 | ;; (mulog/log ::dev-user-ns :message "Example event message" :ns (ns-publics *ns*))
55 | ;; ---------------------------------------------------------
56 |
--------------------------------------------------------------------------------
/resources/practicalli/application/root/dev/mulog_events.clj:
--------------------------------------------------------------------------------
1 | ;; ---------------------------------------------------------
2 | ;; Mulog Global Context and Custom Publisher
3 | ;;
4 | ;; - set event log global context
5 | ;; - tap publisher for use with Portal and other tap sources
6 | ;; - publish all mulog events to Portal tap source
7 | ;; ---------------------------------------------------------
8 |
9 | (ns mulog-events
10 | (:require
11 | [com.brunobonacci.mulog :as mulog]
12 | [com.brunobonacci.mulog.buffer :as mulog-buffer]))
13 |
14 | ;; ---------------------------------------------------------
15 | ;; Set event global context
16 | ;; - information added to every event for REPL workflow
17 | (mulog/set-global-context! {:app-name "{{main/ns}} Service",
18 | :version "0.1.0", :env "dev"})
19 | ;; ---------------------------------------------------------
20 |
21 | ;; ---------------------------------------------------------
22 | ;; Mulog event publishing
23 |
24 | (deftype TapPublisher
25 | [buffer transform]
26 | com.brunobonacci.mulog.publisher.PPublisher
27 | (agent-buffer [_] buffer)
28 | (publish-delay [_] 200)
29 | (publish [_ buffer]
30 | (doseq [item (transform (map second (mulog-buffer/items buffer)))]
31 | (tap> item))
32 | (mulog-buffer/clear buffer)))
33 |
34 | #_{:clj-kondo/ignore [:unused-private-var]}
35 | (defn ^:private tap-events
36 | [{:keys [transform] :as _config}]
37 | (TapPublisher. (mulog-buffer/agent-buffer 10000) (or transform identity)))
38 |
39 | (def tap-publisher
40 | "Start mulog custom tap publisher to send all events to Portal
41 | and other tap sources
42 | `mulog-tap-publisher` to stop publisher"
43 | (mulog/start-publisher!
44 | {:type :custom, :fqn-function "mulog-events/tap-events"}))
45 |
46 | #_{:clj-kondo/ignore [:unused-public-var]}
47 | (defn stop
48 | "Stop mulog tap publisher to ensure multiple publishers are not started
49 | Recommended before using `(restart)` or evaluating the `user` namespace"
50 | []
51 | tap-publisher)
52 |
53 | ;; Example mulog event message
54 | ;; (mulog/log ::dev-user-ns :message "Example event message" :ns (ns-publics *ns*))
55 | ;; ---------------------------------------------------------
56 |
--------------------------------------------------------------------------------
/resources/practicalli/landing_page/root/docs/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
53 |
54 |
55 |
--------------------------------------------------------------------------------
/resources/practicalli/service/dev/system_repl_donut.clj.template:
--------------------------------------------------------------------------------
1 | ;; ---------------------------------------------------------
2 | ;; Donut System REPL
3 | ;;
4 | ;; Tools for REPl workflow with Donut system components
5 | ;; ---------------------------------------------------------
6 |
7 | (ns system-repl
8 | "Tools for REPl workflow with Donut system components"
9 | (:require
10 | [donut.system :as donut]
11 | [donut.system.repl :as donut-repl]
12 | [donut.system.repl.state :as donut-repl-state]
13 | [{{top/ns}}.{{main/ns}}.system :as system]))
14 |
15 |
16 | ;; ---------------------------------------------------------
17 | ;; Donut named systems
18 | ;; `:donut.system/repl` is default named system,
19 | ;; bound to `{{top/ns}}.{{main/ns}}.system` configuration
20 | (defmethod donut/named-system :donut.system/repl
21 | [_] system/main)
22 |
23 | ;; `dev` system, partially overriding main system configuration
24 | ;; to support the development workflow
25 | (defmethod donut/named-system :dev
26 | [_] (donut/system :donut.system/repl
27 | {[:env :app-env] "dev"
28 | [:env :app-version] "0.0.0-SNAPSHOT"
29 | [:services :http-server ::donut/config :options :join?] false
30 | [:services :event-log-publisher ::donut/config]
31 | {:publisher {:type :console :pretty? true}}}))
32 | ;; ---------------------------------------------------------
33 |
34 | ;; ---------------------------------------------------------
35 | ;; Donut REPL workflow helper functions
36 |
37 | (defn start
38 | "Start services using a named-system configuration,
39 | use `:dev` named-system by default"
40 | ([] (start :dev))
41 | ([named-system] (donut-repl/start named-system)))
42 |
43 | (defn stop
44 | "Stop the currently running system"
45 | [] (donut-repl/stop))
46 |
47 | (defn restart
48 | "Restart the system with donut repl,
49 | Uses clojure.tools.namespace.repl to reload namespaces
50 | `(clojure.tools.namespace.repl/refresh :after 'donut.system.repl/start)`"
51 | [] (donut-repl/restart))
52 |
53 | (defn system
54 | "Return: fully qualified hash-map of system state"
55 | [] donut-repl-state/system)
56 | ;; ---------------------------------------------------------
57 |
--------------------------------------------------------------------------------
/resources/practicalli/service/root/.github/workflows/megalinter.yaml:
--------------------------------------------------------------------------------
1 | ---
2 | # MegaLinter GitHub Action configuration file
3 | # More info at https://megalinter.io
4 | # All variables described in https://megalinter.io/latest/config-file/
5 |
6 | name: MegaLinter
7 | on:
8 | workflow_dispatch:
9 | pull_request:
10 | branches: [main]
11 | push:
12 | branches: [main]
13 |
14 | # Run Linters in parallel
15 | # Cancel running job if new job is triggered
16 | concurrency:
17 | group: "${{ github.ref }}-${{ github.workflow }}"
18 | cancel-in-progress: true
19 |
20 | jobs:
21 | megalinter:
22 | name: MegaLinter
23 | runs-on: ubuntu-latest
24 | steps:
25 | - run: echo "🚀 Job automatically triggered by ${{ github.event_name }}"
26 | - run: echo "🐧 Job running on ${{ runner.os }} server"
27 | - run: echo "🐙 Using ${{ github.ref }} branch from ${{ github.repository }} repository"
28 |
29 | # Git Checkout
30 | - name: Checkout Code
31 | uses: actions/checkout@v5
32 | with:
33 | fetch-depth: 0
34 | - run: echo "🐙 ${{ github.repository }} repository was cloned to the runner."
35 |
36 | # MegaLinter Configuration
37 | - name: MegaLinter Run
38 | id: ml
39 | ## latest release of major version
40 | uses: oxsecurity/megalinter/flavors/java@v9
41 | env:
42 | # ADD CUSTOM ENV VARIABLES OR DEFINE IN MEGALINTER_CONFIG file
43 | MEGALINTER_CONFIG: .github/config/megalinter.yaml
44 |
45 | GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}" # report individual linter status
46 | # Validate all source when push on main, else just the git diff with live.
47 | VALIDATE_ALL_CODEBASE: >-
48 | ${{ github.event_name == 'push' && github.ref == 'refs/heads/main'}}
49 |
50 | # Upload MegaLinter artifacts
51 | - name: Archive production artifacts
52 | if: ${{ success() }} || ${{ failure() }}
53 | uses: actions/upload-artifact@v4
54 | with:
55 | name: MegaLinter reports
56 | path: |
57 | megalinter-reports
58 | mega-linter.log
59 |
60 | # Summary and status
61 | - run: echo "🎨 MegaLinter quality checks completed"
62 | - run: echo "🍏 Job status is ${{ job.status }}."
63 |
--------------------------------------------------------------------------------
/resources/practicalli/application/root/.github/workflows/megalinter.yaml:
--------------------------------------------------------------------------------
1 | ---
2 | # MegaLinter GitHub Action configuration file
3 | # More info at https://megalinter.io
4 | # All variables described in https://megalinter.io/latest/config-file/
5 |
6 | name: MegaLinter
7 | on:
8 | workflow_dispatch:
9 | pull_request:
10 | branches: [main]
11 | push:
12 | branches: [main]
13 |
14 | # Run Linters in parallel
15 | # Cancel running job if new job is triggered
16 | concurrency:
17 | group: "${{ github.ref }}-${{ github.workflow }}"
18 | cancel-in-progress: true
19 |
20 | jobs:
21 | megalinter:
22 | name: MegaLinter
23 | runs-on: ubuntu-latest
24 | steps:
25 | - run: echo "🚀 Job automatically triggered by ${{ github.event_name }}"
26 | - run: echo "🐧 Job running on ${{ runner.os }} server"
27 | - run: echo "🐙 Using ${{ github.ref }} branch from ${{ github.repository }} repository"
28 |
29 | # Git Checkout
30 | - name: Checkout Code
31 | uses: actions/checkout@v5
32 | with:
33 | fetch-depth: 0
34 | - run: echo "🐙 ${{ github.repository }} repository was cloned to the runner."
35 |
36 | # MegaLinter Configuration
37 | - name: MegaLinter Run
38 | id: ml
39 | ## latest release of major version
40 | uses: oxsecurity/megalinter/flavors/java@v9
41 | env:
42 | # ADD CUSTOM ENV VARIABLES OR DEFINE IN MEGALINTER_CONFIG file
43 | MEGALINTER_CONFIG: .github/config/megalinter.yaml
44 |
45 | GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}" # report individual linter status
46 | # Validate all source when push on main, else just the git diff with live.
47 | VALIDATE_ALL_CODEBASE: >-
48 | ${{ github.event_name == 'push' && github.ref == 'refs/heads/main'}}
49 |
50 | # Upload MegaLinter artifacts
51 | - name: Archive production artifacts
52 | if: ${{ success() }} || ${{ failure() }}
53 | uses: actions/upload-artifact@v4
54 | with:
55 | name: MegaLinter reports
56 | path: |
57 | megalinter-reports
58 | mega-linter.log
59 |
60 | # Summary and status
61 | - run: echo "🎨 MegaLinter quality checks completed"
62 | - run: echo "🍏 Job status is ${{ job.status }}."
63 |
--------------------------------------------------------------------------------
/resources/practicalli/landing_page/root/.github/workflows/megalinter.yaml:
--------------------------------------------------------------------------------
1 | ---
2 | # MegaLinter GitHub Action configuration file
3 | # More info at https://megalinter.io
4 | # All variables described in https://megalinter.io/latest/config-file/
5 |
6 | name: MegaLinter
7 | on:
8 | workflow_dispatch:
9 | pull_request:
10 | branches: [main]
11 | push:
12 | branches: [main]
13 |
14 | # Run Linters in parallel
15 | # Cancel running job if new job is triggered
16 | concurrency:
17 | group: "${{ github.ref }}-${{ github.workflow }}"
18 | cancel-in-progress: true
19 |
20 | jobs:
21 | megalinter:
22 | name: MegaLinter
23 | runs-on: ubuntu-latest
24 | steps:
25 | - run: echo "🚀 Job automatically triggered by ${{ github.event_name }}"
26 | - run: echo "🐧 Job running on ${{ runner.os }} server"
27 | - run: echo "🐙 Using ${{ github.ref }} branch from ${{ github.repository }} repository"
28 |
29 | # Git Checkout
30 | - name: Checkout Code
31 | uses: actions/checkout@v5
32 | with:
33 | fetch-depth: 0
34 | - run: echo "🐙 ${{ github.repository }} repository was cloned to the runner."
35 |
36 | # MegaLinter Configuration
37 | - name: MegaLinter Run
38 | id: ml
39 | ## latest release of major version
40 | uses: oxsecurity/megalinter/flavors/java@v9
41 | env:
42 | # ADD CUSTOM ENV VARIABLES OR DEFINE IN MEGALINTER_CONFIG file
43 | MEGALINTER_CONFIG: .github/config/megalinter.yaml
44 |
45 | GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}" # report individual linter status
46 | # Validate all source when push on main, else just the git diff with live.
47 | VALIDATE_ALL_CODEBASE: >-
48 | ${{ github.event_name == 'push' && github.ref == 'refs/heads/main'}}
49 |
50 | # Upload MegaLinter artifacts
51 | - name: Archive production artifacts
52 | if: ${{ success() }} || ${{ failure() }}
53 | uses: actions/upload-artifact@v4
54 | with:
55 | name: MegaLinter reports
56 | path: |
57 | megalinter-reports
58 | mega-linter.log
59 |
60 | # Summary and status
61 | - run: echo "🎨 MegaLinter quality checks completed"
62 | - run: echo "🍏 Job status is ${{ job.status }}."
63 |
--------------------------------------------------------------------------------
/resources/practicalli/service/build/deps_donut.edn.template:
--------------------------------------------------------------------------------
1 | {;; ---------------------------------------------------------
2 | :paths
3 | ["src" "resources"]
4 | ;; ---------------------------------------------------------
5 |
6 | ;; ---------------------------------------------------------
7 | :deps
8 | {;; Service
9 | http-kit/http-kit {:mvn/version "2.8.0"} ; latest "2.7.0-alpha1"
10 | metosin/reitit {:mvn/version "0.7.0"}
11 | metosin/reitit-dev {:mvn/version "0.7.0"} ; human readable exceptions
12 |
13 | ;; Logging
14 | ;; create events and send to publisher
15 | com.brunobonacci/mulog {:mvn/version "0.9.0"}
16 | ;; JSON Console out support
17 | com.brunobonacci/mulog-adv-console {:mvn/version "0.9.0"}
18 | ;; Optional: suppress slf4j warning
19 | ;; org.slf4j/slf4j-nop {:mvn/version "1.7.32"}
20 |
21 | ;; System
22 | aero/aero {:mvn/version "1.1.6"}
23 | party.donut/system {:mvn/version "0.0.241"}
24 | org.clojure/clojure {:mvn/version "{{clojure-version}}"}}
25 | ;; ---------------------------------------------------------
26 |
27 | ;; ---------------------------------------------------------
28 | :aliases
29 | {;; ------------
30 | ;; Clojure.main execution of application
31 | :run/service
32 | {:main-opts ["-m" "{{top/ns}}.{{main/ns}}.service"]}
33 |
34 | ;; Clojure.exec execution of specified function
35 | :run/greet
36 | {:exec-fn {{top/ns}}.{{main/ns}}.service/greet
37 | :exec-args {:name "Clojure"}}
38 | ;; ------------
39 |
40 | ;; ------------
41 | ;; Add libraries and paths to support additional test tools
42 | :test/env
43 | {}
44 |
45 | ;; Test runner - local and CI
46 | ;; call with :watch? true to start file watcher and re-run tests on saved changes
47 | :test/run
48 | {:extra-paths ["test"]
49 | :extra-deps {lambdaisland/kaocha {:mvn/version "1.91.1392"}}
50 | :main-opts ["-m" "kaocha.runner"]
51 | :exec-fn kaocha.runner/exec-fn
52 | :exec-args {:randomize? false
53 | :fail-fast? true}}
54 | ;; ------------
55 |
56 | ;; ------------
57 | ;; tools.build `build.clj` built script
58 | :build/task
59 | {:replace-paths ["."]
60 | :replace-deps {io.github.clojure/tools.build {:mvn/version "0.10.3"}}
61 | :ns-default build}}}
62 | ;; ------------
63 | ;; ---------------------------------------------------------
64 |
--------------------------------------------------------------------------------
/.github/workflows/megalinter.yaml:
--------------------------------------------------------------------------------
1 | ---
2 | # MegaLinter GitHub Action configuration file
3 | # More info at https://megalinter.io
4 | # All variables described in https://megalinter.io/latest/config-file/
5 |
6 | name: MegaLinter
7 | on:
8 | workflow_dispatch:
9 | pull_request:
10 | branches: [main]
11 | push:
12 | branches: [main]
13 |
14 | # Run Linters in parallel
15 | # Cancel running job if new job is triggered
16 | concurrency:
17 | group: "${{ github.ref }}-${{ github.workflow }}"
18 | cancel-in-progress: true
19 |
20 | jobs:
21 | megalinter:
22 | name: MegaLinter
23 | runs-on: ubuntu-latest
24 | steps:
25 | - run: echo "🚀 Job automatically triggered by ${{ github.event_name }}"
26 | - run: echo "🐧 Job running on ${{ runner.os }} server"
27 | - run: echo "🐙 Using ${{ github.ref }} branch from ${{ github.repository }} repository"
28 |
29 | # Git Checkout
30 | - name: Checkout Code
31 | uses: actions/checkout@v6
32 | with:
33 | fetch-depth: 0
34 | sparse-checkout: |
35 | docs
36 | overrides
37 | .github
38 | - run: echo "🐙 Sparse Checkout of ${{ github.repository }} repository to the CI runner."
39 |
40 | # MegaLinter Configuration
41 | - name: MegaLinter Run
42 | id: ml
43 | ## latest release of major version
44 | uses: oxsecurity/megalinter/flavors/java@v9
45 | env:
46 | # ADD CUSTOM ENV VARIABLES OR DEFINE IN MEGALINTER_CONFIG file
47 | MEGALINTER_CONFIG: .github/config/megalinter.yaml
48 |
49 | GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}" # report individual linter status
50 | # Validate all source when push on main, else just the git diff with live.
51 | VALIDATE_ALL_CODEBASE: >-
52 | ${{ github.event_name == 'push' && github.ref == 'refs/heads/main'}}
53 |
54 | # Upload MegaLinter artifacts
55 | - name: Archive production artifacts
56 | if: ${{ success() }} || ${{ failure() }}
57 | uses: actions/upload-artifact@v5
58 | with:
59 | name: MegaLinter reports
60 | path: |
61 | megalinter-reports
62 | mega-linter.log
63 |
64 | # Summary and status
65 | - run: echo "🎨 MegaLinter quality checks completed"
66 | - run: echo "🍏 Job status is ${{ job.status }}."
67 |
--------------------------------------------------------------------------------
/resources/practicalli/service/build/deps_integrant.edn.template:
--------------------------------------------------------------------------------
1 | {;; ---------------------------------------------------------
2 | :paths
3 | ["src" "resources"]
4 | ;; ---------------------------------------------------------
5 |
6 | ;; ---------------------------------------------------------
7 | :deps
8 | {;; Service
9 | http-kit/http-kit {:mvn/version "2.8.0"} ; latest "2.7.0-alpha1"
10 | metosin/reitit {:mvn/version "0.7.0"}
11 | metosin/reitit-dev {:mvn/version "0.7.0"} ; human readable exceptions
12 |
13 | ;; Logging
14 | ;; create events and send to publisher
15 | com.brunobonacci/mulog {:mvn/version "0.9.0"}
16 | ;; JSON Console out support
17 | com.brunobonacci/mulog-adv-console {:mvn/version "0.9.0"}
18 | ;; Optional: suppress slf4j warning
19 | ;; org.slf4j/slf4j-nop {:mvn/version "1.7.32"}
20 |
21 | ;; System
22 | aero/aero {:mvn/version "1.1.6"}
23 | integrant/integrant {:mvn/version "0.8.0"}
24 | integrant/repl {:mvn/version "0.3.3"}
25 | org.clojure/clojure {:mvn/version "{{clojure-version}}"}}
26 | ;; ---------------------------------------------------------
27 |
28 | ;; ---------------------------------------------------------
29 | :aliases
30 | {;; ------------
31 | ;; Clojure.main execution of application
32 | :run/service
33 | {:main-opts ["-m" "{{top/ns}}.{{main/ns}}.service"]}
34 |
35 | ;; Clojure.exec execution of specified function
36 | :run/greet
37 | {:exec-fn {{top/ns}}.{{main/ns}}.service/greet
38 | :exec-args {:name "Clojure"}}
39 | ;; ------------
40 |
41 | ;; ------------
42 | ;; Add libraries and paths to support additional test tools
43 | :test/env
44 | {}
45 |
46 | ;; Test runner - local and CI
47 | ;; call with :watch? true to start file watcher and re-run tests on saved changes
48 | :test/run
49 | {:extra-paths ["test"]
50 | :extra-deps {lambdaisland/kaocha {:mvn/version "1.91.1392"}}
51 | :main-opts ["-m" "kaocha.runner"]
52 | :exec-fn kaocha.runner/exec-fn
53 | :exec-args {:randomize? false
54 | :fail-fast? true}}
55 | ;; ------------
56 |
57 | ;; ------------
58 | ;; tools.build `build.clj` built script
59 | :build/task
60 | {:replace-paths ["."]
61 | :replace-deps {io.github.clojure/tools.build {:mvn/version "0.10.3"}}
62 | :ns-default build}}}
63 | ;; ------------
64 | ;; ---------------------------------------------------------
65 |
--------------------------------------------------------------------------------
/resources/practicalli/service/src/parse_system_integrant.clj.template:
--------------------------------------------------------------------------------
1 | ;; --------------------------------------------------
2 | ;; Prepare system configuration with juxt/aero
3 | ;;
4 | ;; aero parsing of Integrant configuration from `user` and `service` namespaces
5 | ;;
6 | ;; Integrant and Integrant-repl are separate workflows for managing system components
7 | ;; however they share the same parsing of the system configuration code with Aero
8 | ;; - Integrant manages components when the service is run via `main` function
9 | ;; - Integrant REPL manages components during development from `user` namespace
10 | ;; --------------------------------------------------
11 |
12 |
13 | (ns {{top/ns}}.{{main/ns}}.parse-system
14 | (:require
15 | [aero.core :as aero]
16 | [clojure.java.io :as io]
17 | [integrant.core :as ig]
18 |
19 | ;; Debug aero parsing - comment by default
20 | ;; [com.brunobonacci.mulog :as mulog]
21 | ))
22 |
23 | ;; --------------------------------------------------
24 | ;; Parse system configuration
25 | ;; - update system configuration with respect to a given profile
26 |
27 | ;; Parse Integrant key with with aero tag literals
28 | ;; returning key/value from given profile value
29 | #_{:clj-kondo/ignore [:unused-binding]}
30 | (defmethod aero/reader 'ig/ref
31 | [_ tag value]
32 | ;; (mulog/log ::aero-parse-key :key _ :tag tag :value value :local-time (java.time.LocalDateTime/now)
33 | (ig/ref value))
34 |
35 | (defn aero-config
36 | "Profile specific configuration for all services.
37 | Profiles supported: :dev :test :prod"
38 | [profile]
39 | ;; (mulog/log ::aero-parse-config :profile profile :local-time (java.time.LocalDateTime/now)
40 | (aero/read-config (io/resource "config.edn") {:profile profile}))
41 |
42 | (defn aero-prep
43 | "Parse the system config and update values for the given profile (:dev, :test :prod)
44 | Top-level keys in `config.edn` use fully qualified namespace name for `ig/init-key` defmethod
45 | `ig/load-namespaces` automatically loads each namespace referenced by a top-level key
46 | Return: configuration hash-map for specified profile (:dev :test :prod) with aero tags resolved"
47 | [profile]
48 | (let [config (aero-config profile)]
49 | ;; (mulog/log ::integrant-load-namespaces :config config :local-time (java.time.LocalDateTime/now)
50 | (ig/load-namespaces config)
51 | config))
52 |
53 | ;; End of Aero Parsing
54 | ;; ---------------------------------------------------------
55 |
--------------------------------------------------------------------------------
/resources/practicalli/service/src/service_donut.clj.template:
--------------------------------------------------------------------------------
1 | ;; ---------------------------------------------------------
2 | ;; {{top/ns}}.{{main/ns}}
3 | ;;
4 | ;; {{description}}
5 | ;;
6 | ;; Start the service using donut system configuration
7 | ;; defined in `system.clj`
8 | ;;
9 | ;; The service consist of
10 | ;; - httpkit web application server
11 | ;; - metosin/reitit for routing and ring for request / response management
12 | ;; - mulog event logging service
13 | ;;
14 | ;; Related namespaces
15 | ;; `{{top/ns}}.{{main/ns}}/system` donut system configuration
16 | ;; ---------------------------------------------------------
17 |
18 |
19 | (ns {{top/ns}}.{{main/ns}}.service
20 | "Gameboard service component lifecycle management"
21 | (:gen-class)
22 | (:require
23 | ;; Component system
24 | [donut.system :as donut]
25 | [{{top/ns}}.{{main/ns}}.system :as system]))
26 |
27 |
28 | ;; --------------------------------------------------
29 | ;; Service entry point
30 |
31 | (defn -main
32 | "{{top/ns}} {{main/ns}} service managed by donut system,
33 | Aero is used to configure the donut system configuration based on profile (dev, test, prod),
34 | allowing environment specific configuration, e.g. mulog publisher
35 | The shutdown hook gracefully stops the service on receipt of a SIGTERM from the infrastructure,
36 | giving the application 30 seconds before forced termination."
37 | []
38 | (let [profile (or (keyword (System/getenv "SERVICE_PROFILE"))
39 | :dev)
40 |
41 | ;; Reference to running system for shutdown hook
42 | running-system (donut/start (or (profile :profile) :prod))]
43 |
44 | ;; Shutdown system components on SIGTERM
45 | (.addShutdownHook
46 | (Runtime/getRuntime)
47 | (Thread. ^Runnable #(donut/signal running-system ::donut/stop)))))
48 | ;; --------------------------------------------------
49 |
50 |
51 | ;; --------------------------------------------------
52 | ;; Example clojure.exec function
53 |
54 | (defn greet
55 | "Greeting message via Clojure CLI clojure.exec"
56 | ;; TODO: call greet with hash-map argument
57 | ([] (greet "secret engineering"))
58 | ([{:keys [team-name]}]
59 | (str "{{top/ns}} {{main/ns}} service developed by the " team-name " team")))
60 |
61 |
62 | (comment
63 | ;; --------------------------------------------------
64 | ;; REPL workflow commands
65 |
66 | (greet {:team-name "{{developer}}"}))
67 |
68 | ; End of rich comment
69 |
--------------------------------------------------------------------------------
/resources/practicalli/service/template.edn:
--------------------------------------------------------------------------------
1 | {;; Values to pass into the template
2 | :description "TODO: Provide a meaningful description of the project"
3 |
4 | ;; ---------------------------------------------------------
5 | ;; Version substitutions
6 |
7 | :clojure-version "1.12.3"
8 |
9 | ;; ---------------------------------------------------------
10 |
11 | ;; ---------------------------------------------------------
12 | ;; Optional features
13 | ;; - used by programatic transformation
14 | ;; - not implemented yet
15 | :cache nil ; one of "redis" "dynamodb"
16 | :component nil ; one of "integrant" "mount" "donut"
17 | :persistence nil ; one of "postgres" "h2" "xtdb" "mariadb"
18 | :router nil ; one of "reitit"
19 | ;; ---------------------------------------------------------
20 |
21 | ;; ---------------------------------------------------------
22 | ;; Programatic Transformation functions
23 |
24 | :data-fn practicalli.service/substitutions
25 |
26 | :template-fn practicalli.service/template-edn
27 | ;; ---------------------------------------------------------
28 |
29 | ;; ---------------------------------------------------------
30 | ;; Declarative Transformation rules
31 | ;; - can be updated by programmatic transformation
32 | ;;
33 | ;; Form:
34 | ;; [["directory-name" "default-path"
35 | ;; {"source-file.extension.template" "destination-file.extension"}]]
36 |
37 | :transform
38 | [["api" "src/{{top/file}}/{{main/file}}/api"
39 | {"system_admin.clj.template" "system_admin.clj"
40 | "scoreboard.clj.template" "scoreboard.clj"}]
41 | ["build" ""
42 | {"build.clj.template" "build.clj"
43 | "deps.edn.template" "deps.edn"}
44 | :only]
45 | ["dev" "dev"
46 | {"mulog_events.clj" "mulog_events.clj"
47 | "portal.clj" "portal.clj"
48 | "system_repl.clj.template" "system_repl.clj"
49 | "user.clj.template" "user.clj"}
50 | :only]
51 | ["docker" ""
52 | {"compose-service.yaml.template" "compose.yaml"
53 | "compose-service-postgres.yaml.template" "compose-service-postgres.yaml"
54 | "Dockerfile.template" "Dockerfile"}]
55 | ["src" "src/{{top/file}}/{{main/file}}"
56 | {"middleware.clj.template" "middleware.clj"
57 | "router.clj.template" "router.clj"
58 | "service.clj.template" "service.clj"
59 | "spec.clj.template" "spec.clj"}
60 | :only]
61 | ["test" "test/{{top/file}}/{{main/file}}"
62 | {"service_test.clj.template" "service_test.clj"}]]}
63 | ;; ---------------------------------------------------------
64 |
--------------------------------------------------------------------------------
/resources/practicalli/landing_page/build/deps.edn.template:
--------------------------------------------------------------------------------
1 | ;; ---------------------------------------------------------
2 | ;; Project Configuration
3 | ;;
4 | ;; - paths to add to the classpath
5 | ;; - dependencies for project libraries
6 | ;; - aliases to support the development workflow
7 | ;; ---------------------------------------------------------
8 |
9 | {:paths ["src" "resources"]
10 |
11 | ;; ---------------------------------------------------------
12 | :deps {org.clojure/clojure {:mvn/version "{{clojure-version}}"}
13 | org.clojure/clojurescript {:mvn/version "1.11.60"}
14 | cljsjs/react {:mvn/version "18.2.0-1"}
15 | cljsjs/react-dom {:mvn/version "18.2.0-1"}
16 | reagent/reagent {:mvn/version "1.2.0"}}
17 | ;; ---------------------------------------------------------
18 |
19 | :aliases
20 | {;; ---------------------------------------------------------
21 | ;; Figwheel tool and dependencies
22 | :figwheel/env
23 | {:extra-deps
24 | {com.bhauman/rebel-readline-cljs {:mvn/version "0.1.4"}
25 | org.slf4j/slf4j-nop {:mvn/version "2.0.7"}
26 | com.bhauman/figwheel-main {:mvn/version "0.2.18"}}
27 | :extra-paths ["target" "test"]}
28 |
29 | ;; ---------------------------------------------------------
30 | ;; Figwheel Built Tasks
31 | ;; - `:dev` defined in `dev.cljs.edn`
32 | ;; - `:test` defined in `test.cljs.edn`
33 | ;; - `:github-pages` defined in `github-pages.cljs.edn`
34 |
35 | :build/dev
36 | {:main-opts ["-m" "figwheel.main"
37 | "--build" "dev"
38 | "--repl"]}
39 |
40 | :build/minify
41 | {:main-opts ["-m" "figwheel.main"
42 | "-O" "advanced" "-bo" "dev"]}
43 |
44 | :build/github-pages
45 | {:main-opts ["-m" "figwheel.main"
46 | "-O" "advanced" "-bo" "github-pages"]}
47 |
48 | :test/figwheel
49 | {:main-opts ["-m" "figwheel.main"
50 | "-co" "test.cljs.edn"
51 | "-m" "{{top/ns}}.test-runner"]}
52 |
53 | :test/run
54 | {:extra-paths ["test"]
55 | :extra-deps
56 | {com.lambdaisland/kaocha-cljs {:mvn/version "1.5.154"}}
57 | :main-opts ["-m" "kaocha.runner"]}
58 | ;; ---------------------------------------------------------
59 |
60 | ;; ---------------------------------------------------------
61 | ;; Add libraries and paths to support additional test tools
62 | :test/env
63 | {}
64 | ;; ---------------------------------------------------------
65 | }}
66 |
--------------------------------------------------------------------------------
/resources/practicalli/service/src/service.clj.template:
--------------------------------------------------------------------------------
1 | ;; ---------------------------------------------------------
2 | ;; {{top/ns}}.{{main/ns}}
3 | ;;
4 | ;; {{description}}
5 | ;;
6 | ;; Start the service using `(start)` in the rich comment form
7 | ;;
8 | ;; The service consist of
9 | ;; - httpkit web application server
10 | ;; - metosin/reitit for routing and ring for request / response management
11 | ;; - mulog event logging service
12 | ;; ---------------------------------------------------------
13 |
14 | (ns {{top/ns}}.{{main/ns}}.service
15 | "Gameboard service"
16 | (:gen-class)
17 | (:require
18 | ;; Requests
19 | [{{top/ns}}.{{main/ns}}.router :as router]
20 |
21 | ;; System dependencies
22 | [org.httpkit.server :as http-server]
23 | [com.brunobonacci.mulog :as mulog]))
24 |
25 | ;; ---------------------------------------------------------
26 | ;; HTTP Server
27 |
28 | (defn http-server-start
29 | "Start the application server and run the application"
30 | [port]
31 | (http-server/run-server #'router/app {:port port}))
32 |
33 | ;; End of HTTP Server
34 | ;; ---------------------------------------------------------
35 |
36 |
37 | ;; --------------------------------------------------
38 | ;; Application entry point
39 |
40 | (defn -main
41 | "{{top/ns}} {{main/ns}} service providing the foundation of an API.
42 | The shutdown hook gracefully stops the service on receipt of a SIGTERM from the infrastructure,
43 | giving the application 30 seconds before forced termination."
44 | [& port]
45 |
46 | (mulog/set-global-context!
47 | {:app-name "{{top/ns}} {{main/ns}} service" :version "0.1.0"})
48 |
49 | (let [port (Integer. (or (first port)
50 | (System/getenv "PORT")
51 | 8080))
52 |
53 | running-system (http-server-start port)]
54 |
55 | (.addShutdownHook
56 | (Runtime/getRuntime)
57 | (Thread. ^Runnable #(running-system :timeout 100)))))
58 | ;; --------------------------------------------------
59 |
60 |
61 | ;; --------------------------------------------------
62 | ;; Example clojure.exec function
63 |
64 | (defn greet
65 | "Greeting message via Clojure CLI clojure.exec"
66 | ;; TODO: call greet with hash-map argument
67 | ([] (greet "secret engineering"))
68 | ([{:keys [team-name]}]
69 | (str "{{top/ns}} {{main/ns}} service developed by the " team-name " team")))
70 |
71 |
72 | (comment
73 | ;; --------------------------------------------------
74 | ;; REPL workflow commands
75 |
76 | (greet {:team-name "{{developer}}"}))
77 |
78 | ; End of rich comment
79 |
--------------------------------------------------------------------------------
/resources/practicalli/landing_page/root/resources/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
71 |
72 |
73 |
--------------------------------------------------------------------------------
/resources/practicalli/minimal/build/build.clj.template:
--------------------------------------------------------------------------------
1 | ;; ---------------------------------------------------------
2 | ;; Build Script
3 | ;;
4 | ;; Build project and package for deployment
5 | ;; - `uberjar` - packaged application for deployment
6 | ;; - `clean` remove all build assets and jar files
7 | ;;
8 | ;; All functions are passed command line arguments
9 | ;; - `nil` is passed if there are no arguments
10 | ;;
11 | ;;
12 | ;; tools.build API commands
13 | ;; - `create-basis` create a project basis
14 | ;; - `copy-dir` copy Clojure source and resources into a working dir
15 | ;; - `compile-clj` compile Clojure source code to classes
16 | ;; - `delete` - remove path from file space
17 | ;; - `write-pom` - write pom.xml and pom.properties files
18 | ;; - `jar` - to jar up the working dir into a jar file
19 | ;;
20 | ;; ---------------------------------------------------------
21 |
22 | (ns build
23 | (:require
24 | [clojure.tools.build.api :as build-api]
25 | [clojure.pprint :as pprint]))
26 |
27 | ;; ---------------------------------------------------------
28 | ;; Project configuration
29 |
30 | (def project-config
31 | "Project configuration to support all tasks"
32 | {:class-directory "target/classes"
33 | :main-namespace '{{top/ns}}/{{main/ns}}
34 | :project-basis (build-api/create-basis)
35 | :uberjar-file "target/{{top/ns}}-{{main/ns}}-standalone.jar"})
36 |
37 | (defn config
38 | "Display build configuration"
39 | [config]
40 | (pprint/pprint (or config project-config)))
41 |
42 | ;; End of Build configuration
43 | ;; ---------------------------------------------------------
44 |
45 | ;; ---------------------------------------------------------
46 | ;; Build tasks
47 |
48 | (defn clean
49 | "Remove a directory
50 | - `:path '\"directory-name\"'` for a specific directory
51 | - `nil` (or no command line arguments) to delete `target` directory
52 | `target` is the default directory for build artefacts
53 | Checks that `.` and `/` directories are not deleted"
54 | [directory]
55 | (when (not (contains? #{"." "/"} directory))
56 | (build-api/delete {:path (or (:path directory) "target")})))
57 |
58 |
59 | (defn uberjar
60 | "Create an archive containing Clojure and the build of the project
61 | Merge command line configuration to the default project config"
62 | [options]
63 | (let [config (merge project-config options)
64 | {:keys [class-directory main-namespace project-basis uberjar-file]} config]
65 |
66 | (clean "target")
67 |
68 | (build-api/copy-dir {:src-dirs ["src" "resources"]
69 | :target-dir class-directory})
70 |
71 | (build-api/compile-clj {:basis project-basis
72 | :class-dir class-directory
73 | :src-dirs ["src"]})
74 |
75 | (build-api/uber {:basis project-basis
76 | :class-dir class-directory
77 | :main main-namespace
78 | :uber-file uberjar-file})))
79 |
80 | ;; End of Build tasks
81 | ;; ---------------------------------------------------------
82 |
--------------------------------------------------------------------------------
/resources/practicalli/landing_page/src/main_page.cljs.template:
--------------------------------------------------------------------------------
1 | ;; ---------------------------------------------------------
2 | ;; {{top/ns}} {{main/ns}}
3 | ;;
4 | ;; ClojureScript project with reagent
5 | ;; - hash-maps for common data
6 | ;; - functions for reagent components
7 | ;; - Bulma.io CSS library for styles
8 | ;;
9 | ;; Author(s): {{developer}}
10 | ;; ---------------------------------------------------------
11 |
12 | (ns ^:figwheel-hooks {{top/ns}}.{{main/ns}}
13 | (:require
14 | [goog.dom :as goog-dom]
15 | [reagent.dom :as reagent-dom]
16 | ;; [reagent.core :as reagent]
17 |
18 | [{{top/ns}}.component :as component]
19 | [{{top/ns}}.data :as data]))
20 |
21 | ;; ---------------------------------------------------------
22 | ;; Tooling / Debug
23 |
24 | (println (js/Date.) "Reloading: src/{{top/file}}_{{main/file}}_page.cljs")
25 |
26 | ;; End of Tooling / Debug
27 | ;; ---------------------------------------------------------
28 |
29 | ;; ---------------------------------------------------------
30 | ;; Application State (not used)
31 |
32 | ;; define app-state once to avoid being over-written on figwheel reload
33 | ;; (defonce app-state (reagent/atom {:text "Hello REPL Reloaded world!"}))
34 |
35 | ;; End of Application State
36 | ;; ---------------------------------------------------------
37 |
38 | ;; ---------------------------------------------------------
39 | ;; Web page structure
40 |
41 | (defn main-page
42 | "The layout of components on the main page."
43 | []
44 | [:div
45 | [component/navigation (data/assets :organisation)]
46 |
47 | [component/title-banner (-> data/assets :organisation :logo)]
48 |
49 | ;; [component/separator "catalog"]
50 | ;; [component/catalog (data/assets :catalog)]
51 |
52 | [component/separator "support"]
53 | [component/support (data/assets :support)]
54 |
55 | [component/separator "resources"]
56 | [component/resources]])
57 |
58 | ;; End of Web page structure
59 | ;; ---------------------------------------------------------
60 |
61 | ;; ---------------------------------------------------------
62 | ;; System Configuration
63 |
64 | (defn get-app-element
65 | "Reference to app id in index.html page"
66 | [] (goog-dom/getElement "app"))
67 |
68 | (defn mount
69 | "Render the main reagent component so it is ready to be used"
70 | [element] (reagent-dom/render [main-page] element))
71 |
72 | (defn mount-app-element
73 | "Mount the ClojureScript app in the web page"
74 | []
75 | (when-let [element (get-app-element)]
76 | (mount element)))
77 |
78 | ;; conditionally start your application based on the presence of an "app" element
79 | ;; this is particularly helpful for testing this ns without launching the app
80 | (mount-app-element)
81 |
82 | ;; specify reload hook with ^;after-load metadata
83 | (defn ^:after-load on-reload []
84 | (mount-app-element)
85 | ;; optionally touch your app-state to force rerendering depending on
86 | ;; your application
87 | ;; (swap! app-state update-in [:__figwheel_counter] inc)
88 | )
89 | ;; End of System Configuration
90 | ;; ---------------------------------------------------------
91 |
--------------------------------------------------------------------------------
/resources/practicalli/service/src/service_integrant.clj.template:
--------------------------------------------------------------------------------
1 | ;; ---------------------------------------------------------
2 | ;; {{top/ns}}.{{main/ns}}
3 | ;;
4 | ;; {{description}}
5 | ;;
6 | ;; Start the service using Integrant configuration and an environment profile.
7 | ;; A profile is injected into the configuration in the `practicalli.gameboard.environment` namespace
8 | ;; and the resulting configuration is used by Integrant to start the system components
9 | ;;
10 | ;; The service consist of
11 | ;; - httpkit web application server
12 | ;; - metosin/reitit for routing and ring for request / response management
13 | ;; - mulog event logging service
14 | ;;
15 | ;; Related namespaces
16 | ;; `resources/config.edn` system configuration with environment #profile placeholders
17 | ;; `{{top/ns}}.environment` injects profile & other aero tag values into a resulting configuration
18 | ;; ---------------------------------------------------------
19 |
20 |
21 | (ns {{top/ns}}.{{main/ns}}.service
22 | "Gameboard service component lifecycle management"
23 | (:gen-class)
24 | (:require
25 |
26 | ;; Component system
27 | [{{top/ns}}.{{main/ns}}.system :as system]
28 |
29 | ;; System dependencies
30 | [org.httpkit.server :as http-server]
31 | [integrant.core :as ig]
32 | [com.brunobonacci.mulog :as mulog]))
33 |
34 | ;; --------------------------------------------------
35 | ;; Application entry point
36 |
37 | (defn -main
38 | "{{top/ns}} {{main/ns}} service is started with `ig/init` and the Integrant configuration,
39 | with the return value bound to the namespace level `system` name.
40 | Aero is used to configure Integrant configuration based on profile (dev, test, prod),
41 | allowing environment specific configuration, e.g. mulog publisher
42 | The shutdown hook calling a zero arity function, gracefully stopping the service
43 | on receipt of a SIGTERM from the infrastructure, giving the application 30 seconds before forced termination."
44 | []
45 |
46 | (let [profile (or (keyword (System/getenv "SERVICE_PROFILE"))
47 | :dev)
48 |
49 | ;; Add keys to every event / publish profile use to start the service
50 | _ (mulog/set-global-context!
51 | {:app-name "{{top/ns}} {{main/ns}} service" :version "0.1.0" :env profile})
52 |
53 | running-system (system/initialise profile)
54 |
55 | _ (mulog/log ::gameboard-system :system-config running-system)]
56 |
57 | ;; TODO: capture the reason for the shutdown - i.e. can we capture the sigterm
58 | (.addShutdownHook (Runtime/getRuntime) (Thread. ^Runnable #(system/stop running-system)))))
59 |
60 | ;; --------------------------------------------------
61 | ;; Example clojure.exec function
62 |
63 | (defn greet
64 | "Greeting message via Clojure CLI clojure.exec"
65 | ;; TODO: call greet with hash-map argument
66 | ([] (greet "secret engineering"))
67 | ([{:keys [team-name]}]
68 | (str "{{top/ns}} {{main/ns}} service developed by the " team-name " team")))
69 |
70 |
71 | (comment
72 | ;; --------------------------------------------------
73 | ;; REPL workflow commands
74 |
75 | (greet {:team-name "{{developer}}"}))
76 |
77 | ; End of rich comment
78 |
--------------------------------------------------------------------------------
/resources/practicalli/service/resources/config_donut_env.edn.template:
--------------------------------------------------------------------------------
1 | ;; --------------------------------------------------
2 | ;; Donut System environment configuration
3 | ;;
4 | ;; - Event logging with mulog
5 | ;; - HTTP Server
6 | ;; - Request routing (reitit)
7 | ;; - Persistence (relational) connection
8 | ;;
9 | ;; Components managed in {{top/ns}}.{{main/ns}}.service namespace
10 | ;;
11 | ;; #profile used by aero to select the configuration to use for a given profile (dev, test, prod)
12 | ;; #long defines Long Integer type (required for Java HTTP server port)
13 | ;; #env reads the environment variable of the given name
14 | ;; #or uses first non nil value in sequence
15 | ;;
16 | ;; Environment variables should be defined locally and in deployment provisioner tooling
17 | ;; --------------------------------------------------
18 |
19 | {:env
20 | {:http-server
21 | #profile
22 | {:dev {:port #or [#env "HTTP_PORT" "8080"]}
23 | :prod {:port #env "PORT"}}
24 | :persistence
25 | #profile
26 | {:dev
27 | {:database-host #or [#env "POSTGRES_HOST" "http://localhost"]
28 | :database-port #or [#env "POSTGRES_PORT" "5432"]
29 | :database-username #or [#env "POSTGRES_USERNAME" "clojure"]
30 | :database-password #or [#env "POSTGRES_PASSWORD" "clojure"]
31 | :database-schema #or [#env "POSTGRES_SCHEMA" "clojure"]}
32 | :prod
33 | {:database-host #env "POSTGRES_HOST"
34 | :database-port #env "POSTGRES_PORT"
35 | :database-username #env "POSTGRES_USERNAME"
36 | :database-password #env "POSTGRES_PASSWORD"
37 | :database-schema #env "POSTGRES_SCHEMA"}}
38 |
39 | ;; Type of publisher to use for mulog events
40 | ;; Publish json format logs, captured by fluentd and exposed via OpenDirectory
41 | :mulog
42 | #profile
43 | {:dev
44 | {:type :console-json :pretty? true}
45 |
46 | ;; Multiple publishers using Open Zipkin service (started via docker-compose)
47 | :docker
48 | {:type :multi
49 | :publishers
50 | [{:type :console-json :pretty? false}
51 | {:type :zipkin :url "http://localhost:9411/"}]}
52 |
53 | :prod
54 | {:type :console-json :pretty? false}}
55 |
56 | ;; Configure data API connections
57 | :data-api
58 | #profile
59 | {:dev
60 | {:game-service-base-url #or [#env GAME_SERVICE_BASE_URL "http://localhost"]
61 | :llamasoft-api-uri #or [#env LAMASOFT_API_URI "http://localhost"]
62 |
63 | :polybus-report-uri "/report/polybus"
64 | :moose-life-report-uri "/api/v1/report/moose-life"
65 | :minotaur-arcade-report-uri "/api/v2/minotar-arcade"
66 | :gridrunner-revolution-report-uri "/api/v1.1/gridrunner"
67 | :space-giraffe-report-uri "/api/v1/games/space-giraffe"}
68 |
69 | :prod
70 | {:game-service-base-url #or [#env GAME_SERVICE_BASE_URL "http://localhost"]
71 | :llamasoft-api-uri #or [#env LAMASOFT_API_URI "http://localhost"]
72 |
73 | :polybus-report-uri "/report/polybus"
74 | :moose-life-report-uri "/api/v1/report/moose-life"
75 | :minotaur-arcade-report-uri "/api/v2/minotar-arcade"
76 | :gridrunner-revolution-report-uri "/api/v1.1/gridrunner"
77 | :space-giraffe-report-uri "/api/v1/games/space-giraffe"}}}}
78 |
79 |
80 |
--------------------------------------------------------------------------------
/.cljstyle:
--------------------------------------------------------------------------------
1 | ;; cljstyle configuration
2 | {:files
3 | {:extensions #{"cljc" "cljs" "clj" "cljx" "edn"},
4 | :ignore #{"checkouts" "dev" ".hg" "target" ".git" "mulog_events.clj"}},
5 | :rules
6 | {:namespaces
7 | {:enabled? false,
8 | :indent-size 2,
9 | :break-libs? true,
10 | :import-break-width 60},
11 | :whitespace
12 | {:enabled? true,
13 | :remove-surrounding? true,
14 | :remove-trailing? true,
15 | :insert-missing? true},
16 | :comments
17 | {:enabled? true,
18 | :inline-prefix " ", :leading-prefix "; "},
19 | :functions {:enabled? true},
20 | :eof-newline {:enabled? true},
21 | :types
22 | {:enabled? true,
23 | :types? true,
24 | :protocols? true,
25 | :reifies? true,
26 | :proxies? true},
27 | :blank-lines
28 | {:enabled? true,
29 | :trim-consecutive? true,
30 | :max-consecutive 2,
31 | :insert-padding? false,
32 | :padding-lines 2},
33 | :indentation
34 | {:enabled? true,
35 | :list-indent 1,
36 | :indents
37 | {
38 | #"^def" [[:inner 0]],
39 | #"^with-" [[:inner 0]],
40 | alt! [[:block 0]],
41 | alt!! [[:block 0]],
42 | are [[:block 2]],
43 | as-> [[:block 1]],
44 | binding [[:block 1]],
45 | bound-fn [[:inner 0]],
46 | case [[:block 1]],
47 | catch [[:block 2]],
48 | comment [[:block 0]],
49 | cond [[:block 0]],
50 | cond-> [[:block 1]],
51 | cond->> [[:block 1]],
52 | condp [[:block 2]],
53 | def [[:inner 0]]},
54 | defmacro [[:inner 0]],
55 | defmethod [[:inner 0]],
56 | defmulti [[:inner 0]],
57 | defn [[:inner 0]],
58 | defn- [[:inner 0]],
59 | defonce [[:inner 0]],
60 | defprotocol [[:block 1] [:inner 1]],
61 | defrecord [[:block 1] [:inner 1]],
62 | defstruct [[:block 1]],
63 | deftest [[:inner 0]],
64 | deftype [[:block 1] [:inner 1]],
65 | do [[:block 0]],
66 | doseq [[:block 1]],
67 | dotimes [[:block 1]],
68 | doto [[:block 1]],
69 | extend [[:block 1]],
70 | extend-protocol [[:block 1] [:inner 1]],
71 | extend-type [[:block 1] [:inner 1]],
72 | finally [[:block 0]],
73 | fn [[:inner 0]],
74 | for [[:block 1]],
75 | future [[:block 0]],
76 | go [[:block 0]],
77 | go-loop [[:block 1]],
78 | if [[:block 1]],
79 | if-let [[:block 1]],
80 | if-not [[:block 1]],
81 | if-some [[:block 1]],
82 | let [[:block 1]],
83 | letfn [[:block 1] [:inner 2 0]],
84 | locking [[:block 1]],
85 | loop [[:block 1]],
86 | match [[:block 1]],
87 | ns [[:block 1]],
88 | proxy [[:block 2] [:inner 1]],
89 | reify [[:inner 0] [:inner 1]],
90 | struct-map [[:block 1]],
91 | testing [[:block 1]],
92 | thread [[:block 0]],
93 | thrown-with-msg? [[:block 2]],
94 | thrown? [[:block 1]],
95 | try [[:block 0]],
96 | use-fixtures [[:inner 0]],
97 | when [[:block 1]],
98 | when-first [[:block 1]],
99 | when-let [[:block 1]],
100 | when-not [[:block 1]],
101 | when-some [[:block 1]],
102 | while [[:block 1]],
103 | with-local-vars [[:block 1]],
104 | with-open [[:block 1]],
105 | with-out-str [[:block 0]],
106 | with-precision [[:block 1]],
107 | with-redefs [[:block 1]]}},
108 | :vars
109 | {:enabled? false}}}
110 |
--------------------------------------------------------------------------------
/.github/config/megalinter.yaml:
--------------------------------------------------------------------------------
1 | ---
2 | # Configuration file for MegaLinter
3 | #
4 | # General configuration:
5 | # https://megalinter.io/latest/config-file/
6 | #
7 | # Specific Linters:
8 | # https://megalinter.io/latest/supported-linters/
9 |
10 | # ------------------------
11 | # Linters
12 |
13 | # Run linters in parallel
14 | PARALLEL: true
15 |
16 | # ENABLE specific linters, all other linters automatically disabled
17 | ENABLE:
18 | - CLOJURE
19 | - CREDENTIALS
20 | - DOCKERFILE
21 | - MAKEFILE
22 | - MARKDOWN
23 | - GIT
24 | - SPELL
25 | - YAML
26 | - REPOSITORY
27 |
28 | # Linter specific configuration
29 |
30 | CLOJURE_CLJ_KONDO_CONFIG_FILE: ".github/config/clj-kondo-ci-config.edn"
31 | # CLOJURE_CLJ_KONDO_ARGUMENTS: "--lint deps.edn"
32 | # CLOJURE_CLJ_KONDO_FILTER_REGEX_EXCLUDE: "dev|develop"
33 | CLOJURE_CLJ_KONDO_FILTER_REGEX_EXCLUDE: "resources"
34 |
35 | # CREDENTIALS_SECRETLINT_DISABLE_ERRORS: true
36 | CREDENTIALS_SECRETLINT_CONFIG_FILE: ".github/config/secretlintrc.json"
37 |
38 | MARKDOWN_MARKDOWNLINT_CONFIG_FILE: ".github/config/markdown-lint.jsonc"
39 | MARKDOWN_MARKDOWNLINT_FILTER_REGEX_EXCLUDE: ".github/pull_request_template.md|CHANGELOG.md"
40 | # MARKDOWN_MARKDOWNLINT_DISABLE_ERRORS: true
41 | MARKDOWN_MARKDOWN_LINK_CHECK_CONFIG_FILE: ".github/config/markdown-link-check.json"
42 | # MARKDOWN_MARKDOWN_LINK_CHECK_CLI_LINT_MODE: "project"
43 | # MARKDOWN_MARKDOWN_LINK_CHECK_DISABLE_ERRORS: true
44 | MARKDOWN_REMARK_LINT_DISABLE_ERRORS: true
45 | # MARKDOWN_MARKDOWN_TABLE_FORMATTER_DISABLE_ERRORS: true
46 |
47 | REPOSITORY_TRUFFLEHOG_DISABLE_ERRORS: true # Errors only as warnings
48 | # REPOSITORY_TRIVY_DISABLE_ERRORS: true # Errors only as warnings
49 | REPOSITORY_TRIVY_ARGUMENTS: --ignorefile ".github/config/trivyignore"
50 |
51 | # SPELL_CSPELL_DISABLE_ERRORS: true
52 | SPELL_MISSPELL_DISABLE_ERRORS: true
53 | SPELL_LYCHEE_DISABLE_ERRORS: true # Errors are only warnings
54 |
55 | # YAML_PRETTIER_FILTER_REGEX_EXCLUDE: (docs/)
56 | # YAML_YAMLLINT_FILTER_REGEX_EXCLUDE: (docs/)
57 |
58 | # Explicitly disable linters to ensure they are never run
59 | # DISABLE:
60 | # - COPYPASTE # checks for excessive copy-pastes
61 | # - SPELL # spell checking - often creates many false positives
62 | # - CSS #
63 |
64 | # Disable linter features
65 | DISABLE_LINTERS:
66 | - YAML_PRETTIER # draconian format rules
67 | - SPELL_CSPELL # many clojure references causing false positives
68 | - YAML_YAMLLINT # vague error mesages, investigation required
69 | - REPOSITORY_GIT_DIFF # warnings about LF to CRLF
70 | - REPOSITORY_SECRETLINT # reporting errors in its own config file
71 | # - REPOSITORY_DEVSKIM # unnecessary URL TLS checks
72 | - REPOSITORY_CHECKOV # fails on root user in Dockerfile
73 | - REPOSITORY_SECRETLINT
74 |
75 | # Ignore all errors and return without error status
76 | # DISABLE_ERRORS: true
77 |
78 | # ------------------------
79 |
80 | # ------------------------
81 | # Reporting
82 |
83 | # Activate sources reporter
84 | UPDATED_SOURCES_REPORTER: false
85 |
86 | # Show Linter timings in summary table at end of run
87 | SHOW_ELAPSED_TIME: true
88 |
89 | # Upload reports to file.io
90 | FILEIO_REPORTER: false
91 | # ------------------------
92 |
93 | # ------------------------
94 | # Over-ride errors
95 |
96 | # detect errors but do not block CI passing
97 | # DISABLE_ERRORS: true
98 | # ------------------------
99 |
--------------------------------------------------------------------------------
/resources/practicalli/minimal/root/.cljstyle:
--------------------------------------------------------------------------------
1 | ;; cljstyle configuration
2 | {:files
3 | {:extensions #{"cljc" "cljs" "clj" "cljx" "edn"},
4 | :ignore #{"checkouts" "dev" ".hg" "target" ".git" "mulog_publisher.clj"}},
5 | :rules
6 | {:namespaces
7 | {:enabled? false,
8 | :indent-size 2,
9 | :break-libs? true,
10 | :import-break-width 60},
11 | :whitespace
12 | {:enabled? true,
13 | :remove-surrounding? true,
14 | :remove-trailing? true,
15 | :insert-missing? true},
16 | :comments
17 | {:enabled? true,
18 | :inline-prefix " ", :leading-prefix "; "},
19 | :functions {:enabled? true},
20 | :eof-newline {:enabled? true},
21 | :types
22 | {:enabled? true,
23 | :types? true,
24 | :protocols? true,
25 | :reifies? true,
26 | :proxies? true},
27 | :blank-lines
28 | {:enabled? true,
29 | :trim-consecutive? true,
30 | :max-consecutive 2,
31 | :insert-padding? false,
32 | :padding-lines 2},
33 | :indentation
34 | {:enabled? true,
35 | :list-indent 1,
36 | :indents
37 | {
38 | #"^def" [[:inner 0]],
39 | #"^with-" [[:inner 0]],
40 | alt! [[:block 0]],
41 | alt!! [[:block 0]],
42 | are [[:block 2]],
43 | as-> [[:block 1]],
44 | binding [[:block 1]],
45 | bound-fn [[:inner 0]],
46 | case [[:block 1]],
47 | catch [[:block 2]],
48 | comment [[:block 0]],
49 | cond [[:block 0]],
50 | cond-> [[:block 1]],
51 | cond->> [[:block 1]],
52 | condp [[:block 2]],
53 | def [[:inner 0]]},
54 | defmacro [[:inner 0]],
55 | defmethod [[:inner 0]],
56 | defmulti [[:inner 0]],
57 | defn [[:inner 0]],
58 | defn- [[:inner 0]],
59 | defonce [[:inner 0]],
60 | defprotocol [[:block 1] [:inner 1]],
61 | defrecord [[:block 1] [:inner 1]],
62 | defstruct [[:block 1]],
63 | deftest [[:inner 0]],
64 | deftype [[:block 1] [:inner 1]],
65 | do [[:block 0]],
66 | doseq [[:block 1]],
67 | dotimes [[:block 1]],
68 | doto [[:block 1]],
69 | extend [[:block 1]],
70 | extend-protocol [[:block 1] [:inner 1]],
71 | extend-type [[:block 1] [:inner 1]],
72 | finally [[:block 0]],
73 | fn [[:inner 0]],
74 | for [[:block 1]],
75 | future [[:block 0]],
76 | go [[:block 0]],
77 | go-loop [[:block 1]],
78 | if [[:block 1]],
79 | if-let [[:block 1]],
80 | if-not [[:block 1]],
81 | if-some [[:block 1]],
82 | let [[:block 1]],
83 | letfn [[:block 1] [:inner 2 0]],
84 | locking [[:block 1]],
85 | loop [[:block 1]],
86 | match [[:block 1]],
87 | ns [[:block 1]],
88 | proxy [[:block 2] [:inner 1]],
89 | reify [[:inner 0] [:inner 1]],
90 | struct-map [[:block 1]],
91 | testing [[:block 1]],
92 | thread [[:block 0]],
93 | thrown-with-msg? [[:block 2]],
94 | thrown? [[:block 1]],
95 | try [[:block 0]],
96 | use-fixtures [[:inner 0]],
97 | when [[:block 1]],
98 | when-first [[:block 1]],
99 | when-let [[:block 1]],
100 | when-not [[:block 1]],
101 | when-some [[:block 1]],
102 | while [[:block 1]],
103 | with-local-vars [[:block 1]],
104 | with-open [[:block 1]],
105 | with-out-str [[:block 0]],
106 | with-precision [[:block 1]],
107 | with-redefs [[:block 1]]}},
108 | :vars
109 | {:enabled? false}}}
110 |
--------------------------------------------------------------------------------
/resources/practicalli/service/root/.cljstyle:
--------------------------------------------------------------------------------
1 | ;; cljstyle configuration
2 | {:files
3 | {:extensions #{"cljc" "cljs" "clj" "cljx" "edn"},
4 | :ignore #{"checkouts" "dev" ".hg" "target" ".git" "mulog_publisher.clj"}},
5 | :rules
6 | {:namespaces
7 | {:enabled? false,
8 | :indent-size 2,
9 | :break-libs? true,
10 | :import-break-width 60},
11 | :whitespace
12 | {:enabled? true,
13 | :remove-surrounding? true,
14 | :remove-trailing? true,
15 | :insert-missing? true},
16 | :comments
17 | {:enabled? true,
18 | :inline-prefix " ", :leading-prefix "; "},
19 | :functions {:enabled? true},
20 | :eof-newline {:enabled? true},
21 | :types
22 | {:enabled? true,
23 | :types? true,
24 | :protocols? true,
25 | :reifies? true,
26 | :proxies? true},
27 | :blank-lines
28 | {:enabled? true,
29 | :trim-consecutive? true,
30 | :max-consecutive 2,
31 | :insert-padding? false,
32 | :padding-lines 2},
33 | :indentation
34 | {:enabled? true,
35 | :list-indent 1,
36 | :indents
37 | {
38 | #"^def" [[:inner 0]],
39 | #"^with-" [[:inner 0]],
40 | alt! [[:block 0]],
41 | alt!! [[:block 0]],
42 | are [[:block 2]],
43 | as-> [[:block 1]],
44 | binding [[:block 1]],
45 | bound-fn [[:inner 0]],
46 | case [[:block 1]],
47 | catch [[:block 2]],
48 | comment [[:block 0]],
49 | cond [[:block 0]],
50 | cond-> [[:block 1]],
51 | cond->> [[:block 1]],
52 | condp [[:block 2]],
53 | def [[:inner 0]]},
54 | defmacro [[:inner 0]],
55 | defmethod [[:inner 0]],
56 | defmulti [[:inner 0]],
57 | defn [[:inner 0]],
58 | defn- [[:inner 0]],
59 | defonce [[:inner 0]],
60 | defprotocol [[:block 1] [:inner 1]],
61 | defrecord [[:block 1] [:inner 1]],
62 | defstruct [[:block 1]],
63 | deftest [[:inner 0]],
64 | deftype [[:block 1] [:inner 1]],
65 | do [[:block 0]],
66 | doseq [[:block 1]],
67 | dotimes [[:block 1]],
68 | doto [[:block 1]],
69 | extend [[:block 1]],
70 | extend-protocol [[:block 1] [:inner 1]],
71 | extend-type [[:block 1] [:inner 1]],
72 | finally [[:block 0]],
73 | fn [[:inner 0]],
74 | for [[:block 1]],
75 | future [[:block 0]],
76 | go [[:block 0]],
77 | go-loop [[:block 1]],
78 | if [[:block 1]],
79 | if-let [[:block 1]],
80 | if-not [[:block 1]],
81 | if-some [[:block 1]],
82 | let [[:block 1]],
83 | letfn [[:block 1] [:inner 2 0]],
84 | locking [[:block 1]],
85 | loop [[:block 1]],
86 | match [[:block 1]],
87 | ns [[:block 1]],
88 | proxy [[:block 2] [:inner 1]],
89 | reify [[:inner 0] [:inner 1]],
90 | struct-map [[:block 1]],
91 | testing [[:block 1]],
92 | thread [[:block 0]],
93 | thrown-with-msg? [[:block 2]],
94 | thrown? [[:block 1]],
95 | try [[:block 0]],
96 | use-fixtures [[:inner 0]],
97 | when [[:block 1]],
98 | when-first [[:block 1]],
99 | when-let [[:block 1]],
100 | when-not [[:block 1]],
101 | when-some [[:block 1]],
102 | while [[:block 1]],
103 | with-local-vars [[:block 1]],
104 | with-open [[:block 1]],
105 | with-out-str [[:block 0]],
106 | with-precision [[:block 1]],
107 | with-redefs [[:block 1]]}},
108 | :vars
109 | {:enabled? false}}}
110 |
--------------------------------------------------------------------------------
/resources/practicalli/application/root/.cljstyle:
--------------------------------------------------------------------------------
1 | ;; cljstyle configuration
2 | {:files
3 | {:extensions #{"cljc" "cljs" "clj" "cljx" "edn"},
4 | :ignore #{"checkouts" "dev" ".hg" "target" ".git" "mulog_publisher.clj"}},
5 | :rules
6 | {:namespaces
7 | {:enabled? false,
8 | :indent-size 2,
9 | :break-libs? true,
10 | :import-break-width 60},
11 | :whitespace
12 | {:enabled? true,
13 | :remove-surrounding? true,
14 | :remove-trailing? true,
15 | :insert-missing? true},
16 | :comments
17 | {:enabled? true,
18 | :inline-prefix " ", :leading-prefix "; "},
19 | :functions {:enabled? true},
20 | :eof-newline {:enabled? true},
21 | :types
22 | {:enabled? true,
23 | :types? true,
24 | :protocols? true,
25 | :reifies? true,
26 | :proxies? true},
27 | :blank-lines
28 | {:enabled? true,
29 | :trim-consecutive? true,
30 | :max-consecutive 2,
31 | :insert-padding? false,
32 | :padding-lines 2},
33 | :indentation
34 | {:enabled? true,
35 | :list-indent 1,
36 | :indents
37 | {
38 | #"^def" [[:inner 0]],
39 | #"^with-" [[:inner 0]],
40 | alt! [[:block 0]],
41 | alt!! [[:block 0]],
42 | are [[:block 2]],
43 | as-> [[:block 1]],
44 | binding [[:block 1]],
45 | bound-fn [[:inner 0]],
46 | case [[:block 1]],
47 | catch [[:block 2]],
48 | comment [[:block 0]],
49 | cond [[:block 0]],
50 | cond-> [[:block 1]],
51 | cond->> [[:block 1]],
52 | condp [[:block 2]],
53 | def [[:inner 0]]},
54 | defmacro [[:inner 0]],
55 | defmethod [[:inner 0]],
56 | defmulti [[:inner 0]],
57 | defn [[:inner 0]],
58 | defn- [[:inner 0]],
59 | defonce [[:inner 0]],
60 | defprotocol [[:block 1] [:inner 1]],
61 | defrecord [[:block 1] [:inner 1]],
62 | defstruct [[:block 1]],
63 | deftest [[:inner 0]],
64 | deftype [[:block 1] [:inner 1]],
65 | do [[:block 0]],
66 | doseq [[:block 1]],
67 | dotimes [[:block 1]],
68 | doto [[:block 1]],
69 | extend [[:block 1]],
70 | extend-protocol [[:block 1] [:inner 1]],
71 | extend-type [[:block 1] [:inner 1]],
72 | finally [[:block 0]],
73 | fn [[:inner 0]],
74 | for [[:block 1]],
75 | future [[:block 0]],
76 | go [[:block 0]],
77 | go-loop [[:block 1]],
78 | if [[:block 1]],
79 | if-let [[:block 1]],
80 | if-not [[:block 1]],
81 | if-some [[:block 1]],
82 | let [[:block 1]],
83 | letfn [[:block 1] [:inner 2 0]],
84 | locking [[:block 1]],
85 | loop [[:block 1]],
86 | match [[:block 1]],
87 | ns [[:block 1]],
88 | proxy [[:block 2] [:inner 1]],
89 | reify [[:inner 0] [:inner 1]],
90 | struct-map [[:block 1]],
91 | testing [[:block 1]],
92 | thread [[:block 0]],
93 | thrown-with-msg? [[:block 2]],
94 | thrown? [[:block 1]],
95 | try [[:block 0]],
96 | use-fixtures [[:inner 0]],
97 | when [[:block 1]],
98 | when-first [[:block 1]],
99 | when-let [[:block 1]],
100 | when-not [[:block 1]],
101 | when-some [[:block 1]],
102 | while [[:block 1]],
103 | with-local-vars [[:block 1]],
104 | with-open [[:block 1]],
105 | with-out-str [[:block 0]],
106 | with-precision [[:block 1]],
107 | with-redefs [[:block 1]]}},
108 | :vars
109 | {:enabled? false}}}
110 |
--------------------------------------------------------------------------------
/resources/practicalli/service/root/.github/config/megalinter.yaml:
--------------------------------------------------------------------------------
1 | ---
2 | # Configuration file for MegaLinter
3 | #
4 | # General configuration:
5 | # https://megalinter.io/latest/config-file/
6 | #
7 | # Specific Linters:
8 | # https://megalinter.io/latest/supported-linters/
9 |
10 | # ------------------------
11 | # Linters
12 |
13 | # Run linters in parallel
14 | PARALLEL: true
15 |
16 | # ENABLE specific linters, all other linters automatically disabled
17 | ENABLE:
18 | - CLOJURE
19 | - CREDENTIALS
20 | - DOCKERFILE
21 | - MAKEFILE
22 | - MARKDOWN
23 | - GIT
24 | - SPELL
25 | - YAML
26 | - REPOSITORY
27 |
28 | # Linter specific configuration
29 |
30 | CLOJURE_CLJ_KONDO_CONFIG_FILE: ".github/config/clj-kondo-ci-config.edn"
31 | # CLOJURE_CLJ_KONDO_ARGUMENTS: "--lint deps.edn"
32 | # CLOJURE_CLJ_KONDO_FILTER_REGEX_EXCLUDE: "dev|develop"
33 | CLOJURE_CLJ_KONDO_FILTER_REGEX_EXCLUDE: "resources"
34 |
35 | # CREDENTIALS_SECRETLINT_DISABLE_ERRORS: true
36 | CREDENTIALS_SECRETLINT_CONFIG_FILE: ".github/config/secretlintrc.json"
37 |
38 | MARKDOWN_MARKDOWNLINT_CONFIG_FILE: ".github/config/markdown-lint.jsonc"
39 | MARKDOWN_MARKDOWNLINT_FILTER_REGEX_EXCLUDE: ".github/pull_request_template.md|CHANGELOG.md"
40 | # MARKDOWN_MARKDOWNLINT_DISABLE_ERRORS: true
41 | MARKDOWN_MARKDOWN_LINK_CHECK_CONFIG_FILE: ".github/config/markdown-link-check.json"
42 | # MARKDOWN_MARKDOWN_LINK_CHECK_CLI_LINT_MODE: "project"
43 | # MARKDOWN_MARKDOWN_LINK_CHECK_DISABLE_ERRORS: true
44 | MARKDOWN_REMARK_LINT_DISABLE_ERRORS: true
45 | # MARKDOWN_MARKDOWN_TABLE_FORMATTER_DISABLE_ERRORS: true
46 |
47 | REPOSITORY_TRUFFLEHOG_DISABLE_ERRORS: true # Errors only as warnings
48 | # REPOSITORY_TRIVY_DISABLE_ERRORS: true # Errors only as warnings
49 | REPOSITORY_TRIVY_ARGUMENTS: --ignorefile ".github/config/trivyignore"
50 |
51 | # SPELL_CSPELL_DISABLE_ERRORS: true
52 | SPELL_MISSPELL_DISABLE_ERRORS: true
53 | SPELL_LYCHEE_DISABLE_ERRORS: true # Errors are only warnings
54 |
55 | # YAML_PRETTIER_FILTER_REGEX_EXCLUDE: (docs/)
56 | # YAML_YAMLLINT_FILTER_REGEX_EXCLUDE: (docs/)
57 |
58 | # Explicitly disable linters to ensure they are never run
59 | # DISABLE:
60 | # - COPYPASTE # checks for excessive copy-pastes
61 | # - SPELL # spell checking - often creates many false positives
62 | # - CSS #
63 |
64 | # Disable linter features
65 | DISABLE_LINTERS:
66 | - YAML_PRETTIER # draconian format rules
67 | - SPELL_CSPELL # many clojure references causing false positives
68 | - YAML_YAMLLINT # vague error mesages, investigation required
69 | - REPOSITORY_GIT_DIFF # warnings about LF to CRLF
70 | - REPOSITORY_SECRETLINT # reporting errors in its own config file
71 | # - REPOSITORY_DEVSKIM # unnecessary URL TLS checks
72 | - REPOSITORY_CHECKOV # fails on root user in Dockerfile
73 | - REPOSITORY_SECRETLINT
74 |
75 | # Ignore all errors and return without error status
76 | # DISABLE_ERRORS: true
77 |
78 | # ------------------------
79 |
80 | # ------------------------
81 | # Reporting
82 |
83 | # Activate sources reporter
84 | UPDATED_SOURCES_REPORTER: false
85 |
86 | # Show Linter timings in summary table at end of run
87 | SHOW_ELAPSED_TIME: true
88 |
89 | # Upload reports to file.io
90 | FILEIO_REPORTER: false
91 | # ------------------------
92 |
93 | # ------------------------
94 | # Over-ride errors
95 |
96 | # detect errors but do not block CI passing
97 | # DISABLE_ERRORS: true
98 | # ------------------------
99 |
--------------------------------------------------------------------------------
/resources/practicalli/application/root/.github/config/megalinter.yaml:
--------------------------------------------------------------------------------
1 | ---
2 | # Configuration file for MegaLinter
3 | #
4 | # General configuration:
5 | # https://megalinter.io/latest/config-file/
6 | #
7 | # Specific Linters:
8 | # https://megalinter.io/latest/supported-linters/
9 |
10 | # ------------------------
11 | # Linters
12 |
13 | # Run linters in parallel
14 | PARALLEL: true
15 |
16 | # ENABLE specific linters, all other linters automatically disabled
17 | ENABLE:
18 | - CLOJURE
19 | - CREDENTIALS
20 | - DOCKERFILE
21 | - MAKEFILE
22 | - MARKDOWN
23 | - GIT
24 | - SPELL
25 | - YAML
26 | - REPOSITORY
27 |
28 | # Linter specific configuration
29 |
30 | CLOJURE_CLJ_KONDO_CONFIG_FILE: ".github/config/clj-kondo-ci-config.edn"
31 | # CLOJURE_CLJ_KONDO_ARGUMENTS: "--lint deps.edn"
32 | # CLOJURE_CLJ_KONDO_FILTER_REGEX_EXCLUDE: "dev|develop"
33 | CLOJURE_CLJ_KONDO_FILTER_REGEX_EXCLUDE: "resources"
34 |
35 | # CREDENTIALS_SECRETLINT_DISABLE_ERRORS: true
36 | CREDENTIALS_SECRETLINT_CONFIG_FILE: ".github/config/secretlintrc.json"
37 |
38 | MARKDOWN_MARKDOWNLINT_CONFIG_FILE: ".github/config/markdown-lint.jsonc"
39 | MARKDOWN_MARKDOWNLINT_FILTER_REGEX_EXCLUDE: ".github/pull_request_template.md|CHANGELOG.md"
40 | # MARKDOWN_MARKDOWNLINT_DISABLE_ERRORS: true
41 | MARKDOWN_MARKDOWN_LINK_CHECK_CONFIG_FILE: ".github/config/markdown-link-check.json"
42 | # MARKDOWN_MARKDOWN_LINK_CHECK_CLI_LINT_MODE: "project"
43 | # MARKDOWN_MARKDOWN_LINK_CHECK_DISABLE_ERRORS: true
44 | MARKDOWN_REMARK_LINT_DISABLE_ERRORS: true
45 | # MARKDOWN_MARKDOWN_TABLE_FORMATTER_DISABLE_ERRORS: true
46 |
47 | REPOSITORY_TRUFFLEHOG_DISABLE_ERRORS: true # Errors only as warnings
48 | # REPOSITORY_TRIVY_DISABLE_ERRORS: true # Errors only as warnings
49 | REPOSITORY_TRIVY_ARGUMENTS: --ignorefile ".github/config/trivyignore"
50 |
51 | # SPELL_CSPELL_DISABLE_ERRORS: true
52 | SPELL_MISSPELL_DISABLE_ERRORS: true
53 | SPELL_LYCHEE_DISABLE_ERRORS: true # Errors are only warnings
54 |
55 | # YAML_PRETTIER_FILTER_REGEX_EXCLUDE: (docs/)
56 | # YAML_YAMLLINT_FILTER_REGEX_EXCLUDE: (docs/)
57 |
58 | # Explicitly disable linters to ensure they are never run
59 | # DISABLE:
60 | # - COPYPASTE # checks for excessive copy-pastes
61 | # - SPELL # spell checking - often creates many false positives
62 | # - CSS #
63 |
64 | # Disable linter features
65 | DISABLE_LINTERS:
66 | - YAML_PRETTIER # draconian format rules
67 | - SPELL_CSPELL # many clojure references causing false positives
68 | - YAML_YAMLLINT # vague error mesages, investigation required
69 | - REPOSITORY_GIT_DIFF # warnings about LF to CRLF
70 | - REPOSITORY_SECRETLINT # reporting errors in its own config file
71 | # - REPOSITORY_DEVSKIM # unnecessary URL TLS checks
72 | - REPOSITORY_CHECKOV # fails on root user in Dockerfile
73 | - REPOSITORY_SECRETLINT
74 |
75 | # Ignore all errors and return without error status
76 | # DISABLE_ERRORS: true
77 |
78 | # ------------------------
79 |
80 | # ------------------------
81 | # Reporting
82 |
83 | # Activate sources reporter
84 | UPDATED_SOURCES_REPORTER: false
85 |
86 | # Show Linter timings in summary table at end of run
87 | SHOW_ELAPSED_TIME: true
88 |
89 | # Upload reports to file.io
90 | FILEIO_REPORTER: false
91 | # ------------------------
92 |
93 | # ------------------------
94 | # Over-ride errors
95 |
96 | # detect errors but do not block CI passing
97 | # DISABLE_ERRORS: true
98 | # ------------------------
99 |
--------------------------------------------------------------------------------
/resources/practicalli/landing_page/root/.github/config/megalinter.yaml:
--------------------------------------------------------------------------------
1 | ---
2 | # Configuration file for MegaLinter
3 | #
4 | # General configuration:
5 | # https://megalinter.io/latest/config-file/
6 | #
7 | # Specific Linters:
8 | # https://megalinter.io/latest/supported-linters/
9 |
10 | # ------------------------
11 | # Linters
12 |
13 | # Run linters in parallel
14 | PARALLEL: true
15 |
16 | # ENABLE specific linters, all other linters automatically disabled
17 | ENABLE:
18 | - CLOJURE
19 | - CREDENTIALS
20 | - DOCKERFILE
21 | - MAKEFILE
22 | - MARKDOWN
23 | - GIT
24 | - SPELL
25 | - YAML
26 | - REPOSITORY
27 |
28 | # Linter specific configuration
29 |
30 | CLOJURE_CLJ_KONDO_CONFIG_FILE: ".github/config/clj-kondo-ci-config.edn"
31 | # CLOJURE_CLJ_KONDO_ARGUMENTS: "--lint deps.edn"
32 | # CLOJURE_CLJ_KONDO_FILTER_REGEX_EXCLUDE: "dev|develop"
33 | CLOJURE_CLJ_KONDO_FILTER_REGEX_EXCLUDE: "resources"
34 |
35 | # CREDENTIALS_SECRETLINT_DISABLE_ERRORS: true
36 | CREDENTIALS_SECRETLINT_CONFIG_FILE: ".github/config/secretlintrc.json"
37 |
38 | MARKDOWN_MARKDOWNLINT_CONFIG_FILE: ".github/config/markdown-lint.jsonc"
39 | MARKDOWN_MARKDOWNLINT_FILTER_REGEX_EXCLUDE: ".github/pull_request_template.md|CHANGELOG.md"
40 | # MARKDOWN_MARKDOWNLINT_DISABLE_ERRORS: true
41 | MARKDOWN_MARKDOWN_LINK_CHECK_CONFIG_FILE: ".github/config/markdown-link-check.json"
42 | # MARKDOWN_MARKDOWN_LINK_CHECK_CLI_LINT_MODE: "project"
43 | # MARKDOWN_MARKDOWN_LINK_CHECK_DISABLE_ERRORS: true
44 | MARKDOWN_REMARK_LINT_DISABLE_ERRORS: true
45 | # MARKDOWN_MARKDOWN_TABLE_FORMATTER_DISABLE_ERRORS: true
46 |
47 | REPOSITORY_TRUFFLEHOG_DISABLE_ERRORS: true # Errors only as warnings
48 | # REPOSITORY_TRIVY_DISABLE_ERRORS: true # Errors only as warnings
49 | REPOSITORY_TRIVY_ARGUMENTS: --ignorefile ".github/config/trivyignore"
50 |
51 | # SPELL_CSPELL_DISABLE_ERRORS: true
52 | SPELL_MISSPELL_DISABLE_ERRORS: true
53 | SPELL_LYCHEE_DISABLE_ERRORS: true # Errors are only warnings
54 |
55 | # YAML_PRETTIER_FILTER_REGEX_EXCLUDE: (docs/)
56 | # YAML_YAMLLINT_FILTER_REGEX_EXCLUDE: (docs/)
57 |
58 | # Explicitly disable linters to ensure they are never run
59 | # DISABLE:
60 | # - COPYPASTE # checks for excessive copy-pastes
61 | # - SPELL # spell checking - often creates many false positives
62 | # - CSS #
63 |
64 | # Disable linter features
65 | DISABLE_LINTERS:
66 | - YAML_PRETTIER # draconian format rules
67 | - SPELL_CSPELL # many clojure references causing false positives
68 | - YAML_YAMLLINT # vague error mesages, investigation required
69 | - REPOSITORY_GIT_DIFF # warnings about LF to CRLF
70 | - REPOSITORY_SECRETLINT # reporting errors in its own config file
71 | # - REPOSITORY_DEVSKIM # unnecessary URL TLS checks
72 | - REPOSITORY_CHECKOV # fails on root user in Dockerfile
73 | - REPOSITORY_SECRETLINT
74 |
75 | # Ignore all errors and return without error status
76 | # DISABLE_ERRORS: true
77 |
78 | # ------------------------
79 |
80 | # ------------------------
81 | # Reporting
82 |
83 | # Activate sources reporter
84 | UPDATED_SOURCES_REPORTER: false
85 |
86 | # Show Linter timings in summary table at end of run
87 | SHOW_ELAPSED_TIME: true
88 |
89 | # Upload reports to file.io
90 | FILEIO_REPORTER: false
91 | # ------------------------
92 |
93 | # ------------------------
94 | # Over-ride errors
95 |
96 | # detect errors but do not block CI passing
97 | # DISABLE_ERRORS: true
98 | # ------------------------
99 |
--------------------------------------------------------------------------------
/resources/practicalli/service/dev/system_repl_integrant.clj.template:
--------------------------------------------------------------------------------
1 | ;; ---------------------------------------------------
2 | ;; System component management for REPL workflow
3 | ;;
4 | ;; System config components defined in `resources/config.edn`
5 | ;;
6 | ;; `system` namespace automatically loaded via the `dev/user.clj` namespace
7 | ;;
8 | ;; Commands:
9 | ;; `(start)` starts all components in system config
10 | ;; `(restart)` reads system config, reloads changed namespaces & restarts system
11 | ;; `(restart-all)` as above with all namespaces reloaded
12 | ;; `(stop)` shutdown all components in the system (gracefully where appropriate)
13 | ;; `(system)` show configuration of the running system
14 | ;; `(config)` system configuration
15 | ;;
16 | ;; NOTE: standard IntegrantREPL code, maintenance should not be required
17 | ;; ---------------------------------------------------
18 |
19 |
20 | (ns system-repl
21 | "Configure the system components and provide Integrant REPL convenience functions
22 | to start/stop/restart components and show system configuration"
23 | (:require
24 | ;; REPL workflow
25 | [integrant.repl :as ig-repl]
26 | [integrant.repl.state :as ig-state]
27 | [clojure.pprint :as pprint]
28 |
29 | [{{top/ns}}.{{main/ns}}.parse-system :as parse-system]))
30 |
31 |
32 | (println "Loading system namespace for Integrant REPL")
33 |
34 |
35 | ;; ---------------------------------------------------------
36 | ;; System Configuration
37 | ;; - `resources/config.edn` Integrant & Aero system configuration
38 |
39 | (defn environment-prep!
40 | "Parse system configuration with aero-reader and apply the given profile values
41 | Return: Integrant configuration to be used to start the system
42 | integrant.repl/set-prep! takes an anonymous function that returns an integrant configuration
43 | Arguments: profile - a keyword determining the environment - :dev :test :stage :live"
44 |
45 | [profile]
46 | (ig-repl/set-prep! #(parse-system/aero-prep profile)))
47 |
48 | ;; ---------------------------------------------------------
49 |
50 |
51 | ;; ---------------------------------------------------------
52 | ;; Integrant REPL convenience functions
53 | ;; - enable use of aero profiles (`dev`, `stage`, `prod`)
54 | ;; - simplify Integrant REPL commands for managing the system
55 |
56 | (defn start
57 | "Prepare configuration and start the system services with Integrant-repl"
58 | ([] (start :dev))
59 | ([profile] (environment-prep! profile) (ig-repl/go)))
60 |
61 |
62 | (defn restart
63 | "Read updates from the system configuration, reloads changed namespaces
64 | and restart the system services with Integrant-repl"
65 | ([] (restart :dev))
66 | ([profile] (environment-prep! profile) (ig-repl/reset)))
67 |
68 |
69 | (defn restart-all
70 | "Read updates from the configuration, reloads all namespaces
71 | and restart the system services with Integrant-repl"
72 | ([] (restart-all :dev))
73 | ([profile] (environment-prep! profile) (ig-repl/reset-all)))
74 |
75 |
76 | (defn stop
77 | "Shutdown all services"
78 | []
79 | (ig-repl/halt))
80 |
81 |
82 | (defn system
83 | "The running system configuration,
84 | including component references and specific profile values"
85 | []
86 | ig-state/system)
87 |
88 |
89 | (defn config
90 | "The current system configuration used by Integrant"
91 | []
92 | (pprint/pprint ig-state/config))
93 |
94 | ;; End of Integrant REPL convenience functions
95 | ;; ---------------------------------------------------------
96 |
--------------------------------------------------------------------------------