├── 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 | --------------------------------------------------------------------------------