Git Product home page Git Product logo

practicalli / project-templates Goto Github PK

View Code? Open in Web Editor NEW
29.0 2.0 3.0 311 KB

Clojure CLI Production level templates for seancorfield/deps-new

Home Page: https://practical.li/clojure/clojure-cli/projects/templates/

License: Creative Commons Attribution Share Alike 4.0 International

Clojure 54.95% Emacs Lisp 0.96% Dockerfile 4.53% Makefile 34.93% CSS 0.08% HTML 4.56%
clojure clojure-cli clojurescript deps-new template

project-templates's Introduction

Practicalli project templates

██████╗ ██████╗  █████╗  ██████╗████████╗██╗ ██████╗ █████╗ ██╗     ██╗     ██╗
██╔══██╗██╔══██╗██╔══██╗██╔════╝╚══██╔══╝██║██╔════╝██╔══██╗██║     ██║     ██║
██████╔╝██████╔╝███████║██║        ██║   ██║██║     ███████║██║     ██║     ██║
██╔═══╝ ██╔══██╗██╔══██║██║        ██║   ██║██║     ██╔══██║██║     ██║     ██║
██║     ██║  ██║██║  ██║╚██████╗   ██║   ██║╚██████╗██║  ██║███████╗███████╗██║
╚═╝     ╚═╝  ╚═╝╚═╝  ╚═╝ ╚═════╝   ╚═╝   ╚═╝ ╚═════╝╚═╝  ╚═╝╚══════╝╚══════╝╚═╝

Overview

Create new projects with a REPL driven development focus, including production level features where relevant. The templates are used by deps-new via a user or project alias.

Templates provide

  • :practicalli/minimal essential tools, libraries and example code
  • :practicalli/service production level web services with http-kit, reitit and swagger. Optional :component management with :donut or :integrant

Configuration

Latest Release

io.github.practicalli/project-templates {:git/tag "2024-07-07" :git/sha "0d842f4"}

Add alias

:project/create alias is provided by Practicalli Clojure CLI Config.

The project/create alias definition combines seancorfield/deps-new and practicalli/project-templates so that all Practicalli templates are available within one alias.

  :project/create
  {:replace-deps {io.github.seancorfield/deps-new
                  {:git/tag "v0.7.1" :git/sha "c1e42aa"}
                  io.github.practicalli/project-templates
                  {:git/tag "2024-07-07" :git/sha "0d842f4"}}
   :exec-fn      org.corfield.new/create
   :exec-args    {:template practicalli/application
                  :name practicalli/playground}}

Latest Release page includes the release :git/tag and :git/sha values for io.github.practicalli/project-templates

Usage

Create a new project using the :project/create alias from Practicalli Clojure CLI Config, using practicalli/minimal template by default

clojure -T:project/create

Override the defaults used to create a project using command line options

  • :template to specify a different template to create the project from, e.g. :template practicalli/service
  • :name and value to create a project with a different name, e.g. github-org/project-name
  • :target-dir to specify a directory to create the project in
  • :overwrite an existing project with the same :target-dir name, true updates, :delete deletes existing project and replaces it with new project
clojure -T:project/create :template practicalli/service \
:name practicalli/gameboard :target-dir gameboard-service

Templates Roadmap

🧰 General purpose

  • practicalli/service - production grade HTTP service, basic routing (reitit-ring & middleware)
    • :component :donut argument to manage system with donut-party/system
    • :component :integrant argument to manage system with Integrant and Integrant REPL
  • practicalli/application - general application, limited code
  • practicalli/minimal - Clojure CLI project, tools-build, kaocha test runner alias, Make tasks, GitHub quality checks workflow
  • TODO: practicalli/api - production grade API service (reitit-ring, clojure.spec validation)
  • TODO: practicalli/library - general library, deploymnent to Maven/Clojars
  • TODO: practicalli/blog - cryogen project with Practicalli Customisation
  • TODO: practicalli/jetty - basic web server
  • TODO: practicalli/httpkit - basic web server

🕸️ Web UI

  • DONE: #15 practicalli/landing-page - a simple landing page with figwheel and Bulma.io CSS
  • TODO: practicalli/single-page-app - a simple landing page with figwheel and Bulma.io CSS
  • TODO: practicalli/catalog - a catalog front-end webapp with firebase persistence, user OAuth authentication, figwheel, Reagent, Bulma.io CSS
  • TODO: practicalli/store-front - a catalog front-end webapp with stripe integration, firebase persistence, OAuth authentication, figwheel, Reagent, Bulma.io CSS

🔬 Data Science ‍

  • TODO: practicalli/notebook - clerk or notespace projects
  • TODO: practicalli/dashboard - visualising data sources to communicate information and concepts
  • TODO: practicalli/visualisation - oz or hanami projects
  • TODO: practicalli/data-transform - tablecloth & code for data set manipulation

🐈 Miscellaneous

  • TODO: practicalli/zulip-bot
  • TODO: practicalli/slack-bot
  • TODO: practicalli/mastodon-bot

3rd party templates

Sponsor Practicalli

Sponsor practicalli-johnny

The majority of my work is focused on the Practicalli series of books and videos and supporting projects.

Thank you to Cognitect, Nubank and a wide range of other sponsors for your continued support

Development

List all the available project tasks using the make help

make

This project uses make tasks to run the Clojure tests, kaocha test runner and package the service into an uberjar. The Makefile uses clojure commands and arguments that can be used directly if not using make.

Start a Clojure REPL process with a rich terminal UI, nREPL server for editor connection and including the build.clj script on the class path

make repl

Run kaocha unit test runner to check the template configuration against the seancorfield/deps-new template specification

make test

Run tests when ever there are file changes using kaocha watch (requires :test/watch from Practicalli Clojure CLI Config)

make test-watch

Practicalli Blog: Create deps-new template for Clojure CLI projects

License

Copyright © 2023 Practicalli

Creative Commons Attribution Share-Alike 4.0 International

project-templates's People

Contributors

practicalli-johnny avatar snyk-bot avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

project-templates's Issues

[docker] postgres image healthcheck

The docker compose healthcheck for the postgres image is not currently functioning (and there seems to be many ideas on how it should work on the internet 😞

  • review the configuration in compose.yaml
  • test variations found on the internet and on the PR #8
  • update service and application templates with new configuration

Bonus feature: add a condition to the Clojure service to wait for healthy postgres container

[docker] container reports unhealthy even when working

When building the service image and running it in a container, the container status is reporting unhealthy even though the service is operational (working through the embedded swagger UI)

The container is run via docker compose

docker compose up --build

The healthcheck command is defined in the Dockerfile

HEALTHCHECK --interval=30s --timeout=30s --start-period=5s --retries=3 \
  CMD [ "curl --fail http://localhost:8080 || exit 1" ]
❯ docker ps
CONTAINER ID   IMAGE                           COMMAND                  CREATED              STATUS                                 PORTS                    NAMES
cb13307b08e2   practicalli-gameboard-service   "/usr/bin/dumb-init …"   About a minute ago   Up About a minute (health: starting)   0.0.0.0:8080->8080/tcp   practicalli-gameboard-service-1
❯ docker ps
CONTAINER ID   IMAGE                           COMMAND                  CREATED         STATUS                     PORTS                    NAMES
cb13307b08e2   practicalli-gameboard-service   "/usr/bin/dumb-init …"   2 minutes ago   Up 2 minutes (unhealthy)   0.0.0.0:8080->8080/tcp   practicalli-gameboard-service-1

Cryogen Blog template with staging and Practicalli theme

Create a Cryogen template to create a new blog project that includes

  • publishing pull requests to a staging blog
    • modified src.cryogen.core/-main to take a config file via the command line
    • GitHub workflow to publish to a separate staging repository
  • include practicalli theme
  • option to select the default theme ??

Cryogen includes a deps-new template that simply copies from the Leiningen template

Code modifications

Allow a configuration file to be passed to the -main function, which is used to build and publish the Cryogen blog

TODO: refactor the code so that the zero argument branch calls the config-file branch, e.g.

(defn -main
  "Start Cryogen with optional configuration file"
  ([]
   (-main "content/config.edn") ;; TODO: test this approach works and path to config file is correct
   ;; (load-plugins)
   ;; (compile-assets-timed )
   ;; (System/exit 0))
  ([config-file]
   (load-plugins)

   ;; Would edn reader be better than read-string?
   (compile-assets-timed (read-string (slurp config-file)))
   (System/exit 0)))

Publish Staging Website GitHub workflow

---
name: Publish Blog Staging

on: [pull_request]
jobs:
  publish:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v3

      - name: Prepare java
        uses: actions/[email protected]
        with:
          distribution: 'temurin'
          java-version: '17'

      - name: 'Cache Clojure Dependencies'
        uses: actions/cache@v3
        with:
          path: |
            ~/.m2/repository
            ~/.gitlibs
          key: cache-clojure-deps-${{ hashFiles('**/deps.edn') }}
          restore-keys: cache-clojure-deps-

      - name: Install clojure tools
        uses: DeLaGuardo/[email protected]
        with:
          cli: 1.11.1.1165

      - name: Build Blog site
        run: clojure -M:build content/config-staging.edn

      - name: Publish to GitHub Pages
        # Publish to a separate repository as GitHub pages can only be served from one branch
        # The GitHub repository for staging the website must be created before running this workflow
        # Requires developer token as deploying across repositories
        uses: JamesIves/[email protected]
        with:
          repository-name: practicalli/blog-staging
          token: ${{ secrets.CRYOGEN_PUBLISH_TOKEN }}
          branch: gh-pages # The branch the action should deploy to.
          folder: public/blog-staging # The folder the action should deploy.
          commit-message: ${{ github.event.head_commit.message }}
          single-commit: yes

Related: practicalli/clojure#404

Docker image build caching

Hello. Thank you for creating Practicalli and for project templates in particular! IMO, these resources are very beneficial to new and returning clojure developers. Keep up the good work!

Now, to the issue. I was migrating an older project from boot-clj to your template and noticed, that many dependencies are being downloaded over and over during the build uberjar step. After some fiddling around I've figured out the following:

  • make deps uses :build alias to preload deps
  • :build alias replaces all project dependencies with just clojure/tools.build, which makes sense for -T:build
    :build
    {:replace-paths ["."]
    :replace-deps {io.github.clojure/tools.build
                  {:git/tag "v0.9.4" :git/sha "76b78fe"}}
    :ns-default build}
    

So, referring to the Dockerfile:

--- cut ---
# Cache and install Clojure dependencies
# Add before copying code to cache the layer even if code changes
COPY deps.edn Makefile /build/
RUN make deps                              <-- this step only downloads deps for :build alias

# Copy project to working directory
# .dockerignore file excludes all but essential files
COPY ./ /build


# ------------------------
# Test and Package application via Makefile
# `make all` calls `deps`, `test-ci`, `dist` and `clean` tasks
# using shared library cache mounted by pipeline process


# `dist` task packages Clojure service as an uberjar
# - creates: /build/practicalli-gameboard-api-service.jar
# - uses command `clojure -T:build uberjar`
RUN make dist                              <-- real project dependencies are downloaded here
--- cut ---

For my purposes, I've changed the Makefile deps target to the following to fetch all deps on make deps step:

  deps: deps.edn  ## Prepare dependencies for test and dist targets
  	$(info --------- Download test and service libraries ---------)
-  	clojure -P -X:build
+  	clojure -P -T:build
+  	clojure -P -M:run

Is it the intended behaviour to only fetch build tooling deps?

[template] ClojureScript static landing-page

Create a deps-new template for a landing page application driven by static data (similar to Practicalli and ClojureBridge London websites)

Features

  • data driven content (static, no atom)
  • example components
  • bulma.io menu

template: minimal project

Create a minimal template

  • Clojure CLI deps.edn
    • minimal libraries
    • :test/run and :test/env aliases to configure and run tests
    • :build to create an uberjar to run project via java command
  • Makefile with repl, test, lint and format tasks
  • Minimal code example
  • Code Quality GitHub workflow

[template] ClojureScript Landing Page

practicalli/landing-page

Single page application with figwheel-main, reagent and Bulma.io CSS

Includes example data structure used by components

Provides example landing page as used for London Clojurians and Practical.li

service template with component configuration

Modify the practicalli/service template to create a Clojure web service using a component library to manage system components

  • :component :donut donut-party/system
  • :component :integrant Integrant & Integrant REPL

Pass :component and either :donut or :integrant on the command line when creating a new project

Without a component value, an atom-based approach is used to support restarts in the REPL workflow.

Reference

Create service template

Create practicalli/service template for use with seancorfield/deps-new project

dev/user.clj for development tools ✅

  • hotloading libraries with add-libs
  • portal data inspector
  • mulog and tap publisher
  • make tasks for consistent UI over all projects

Library dependencies ✅

  • Latest Clojure release (version substitution)
  • kaocha test runner
  • kaochatests.edn configuration
  • mulog for logging
  • Integrant & areo for system configuration
  • add-libs for hot-loading (Clojure 11 & 12)
  • reitit & reitit-ring for routing (basic API)
  • Practicalli middleware (mulog trace events)

Editor support ✅

  • Emacs .dir-locals.el configuration with recommended aliases

Build.tools configuration ✅

Include project alias for tools.build and a build.clj built tasks

  • clean
  • uberjar

Docker configuration ✅

  • multi-stage Dockerfile - build using tools.build script and run on OpenJDK image (with service healthcheck)
  • compose.yaml for local development (optional postgres database & service conditional start)

Common aliases ✅

  • :run/service - run the project using clojure.exec
  • :dev/reloaded - include dev/user.clj file and associated development tools
  • :test/env - paths and deps for test runners
  • :test/run - run kaocha test runner
  • :test/watch - run kaocha test runner in watch mode

Optional parts

+postgres - adds next.jdbc, honeysql, postgresql driver. Example code for clojure.specs that matches the example database schema. Example persistence layer. Tools to generate spec from dB schema (and vice versa)

Related: practicalli/clojure#404

[service] add specification for scoreboard api route

The response verification in the practicalli.service-name/api/scoreboard.clj requires a specification to function correctly

Caused by: clojure.lang.ExceptionInfo: -- Router creation failed --------------------------reitit.ring:77 -- 
data-spec collection [] should be homogeneous, 6 values found
--------------------------------------------------------------------------------

cyclic dependencies when restarting project from practicalli/service template

Cyclic load dependency using (restart) during repl driven development

Image

Assumptions

  • different versions of clojure tools.deps.alpha are being loaded and conflicting

Suggestions

Drop find-deps dependency from :repl/reloaded alias in Practicalli Clojure CLI Config

user=> (restart)
{
    "local-time": "2023-04-12T11:46:36.047176706",
    "mulog/namespace": "practicalli.gameboard.service",
    "app-name": "Practicalli Service",
    "env": "dev",
    "mulog/timestamp": 1681296396047,
    "version": "0.1.0",
    "mulog/trace-id": "4pJe9W0y9zYS9ybMfALIfuSL_Oj6jSVY",
    "publisher-object": "com.brunobonacci.mulog.core$start_publisher_BANG_$stop_publisher__11973@21924934",
    "mulog/event-name": "practicalli.gameboard.service/log-publish-component-shutdown"
}
:reloading (clojure.tools.deps.alpha.specs clojure.tools.deps.alpha.extensions clojure.tools.deps.alpha.extensions.git clojure.tools.deps.alpha.util.coll clojure.tools.deps.alpha.util.io clojure.tools.deps.alpha.reader clojure.tools.deps.alpha.extensions.deps clojure.tools.deps.alpha.util.maven clojure.tools.deps.alpha.extensions.pom clojure.tools.deps.alpha.extensions.local clojure.tools.deps.alpha.extensions.maven clojure.tools.deps.alpha clojure.tools.deps.alpha.script.print-tree clojure.tools.deps.alpha.tool clojure.tools.deps.alpha.script.parse clojure.tools.deps.alpha.gen.pom clojure.tools.deps.alpha.tree clojure.tools.deps.alpha.script.make-classpath2 clojure.tools.deps.alpha.script.generate-manifest2 clojure.tools.deps.alpha.script.make-classpath clojure.tools.deps.alpha.script.generate-manifest practicalli.gameboard.middleware clojure.tools.deps.alpha.util.session clojure.tools.deps.alpha.util.s3-transporter find-deps.search find-deps.rank find-deps.core practicalli.gameboard.api.scoreboard practicalli.gameboard.parse-system clojure.tools.deps.alpha.util.s3-aws-client system clojure.tools.deps.alpha.repl find-deps.links find-deps.alpha practicalli.gameboard.api.system-admin practicalli.gameboard.router practicalli.gameboard.service clojure.tools.cli.help mulog-publisher user clojure.tools.deps.alpha.script.resolve-tags practicalli.gameboard.service-test clojure.tools.deps.alpha.util.dir clojure.tools.cli.api clojure.tools.deps.alpha.util.concurrent)
:error-while-loading clojure.tools.deps.alpha.extensions.deps
#error {
 :cause "Cyclic load dependency: [ /clojure/tools/deps/alpha/extensions/deps ]->/clojure/tools/deps/alpha->[ /clojure/tools/deps/alpha/extensions/deps ]"
 :via
 [{:type clojure.lang.Compiler$CompilerException
   :message "Syntax error compiling at (clojure/tools/deps/alpha.clj:819:1)."
   :data #:clojure.error{:phase :compile-syntax-check, :line 819, :column 1, :source "clojure/tools/deps/alpha.clj"}
   :at [clojure.core$throw_if invokeStatic "core.clj" 5892]}
  {:type java.lang.Exception
   :message "Cyclic load dependency: [ /clojure/tools/deps/alpha/extensions/deps ]->/clojure/tools/deps/alpha->[ /clojure/tools/deps/alpha/extensions/deps ]"
   :at [clojure.tools.deps.alpha$eval29443 invokeStatic "alpha.clj" 819]}]
 :trace
 [[clojure.tools.deps.alpha$eval29443 invokeStatic "alpha.clj" 819]
  [clojure.tools.deps.alpha$eval29443 invoke "alpha.clj" 819]
  [clojure.lang.Compiler eval "Compiler.java" 7194]
  [clojure.lang.Compiler load "Compiler.java" 7653]
  [clojure.lang.RT loadResourceScript "RT.java" 381]
  [clojure.lang.RT loadResourceScript "RT.java" 372]
  [clojure.lang.RT load "RT.java" 459]
  [clojure.lang.RT load "RT.java" 424]
  [clojure.core$load$fn__6908 invoke "core.clj" 6161]
  [clojure.core$load invokeStatic "core.clj" 6160]
  [clojure.core$load doInvoke "core.clj" 6144]
  [clojure.lang.RestFn invoke "RestFn.java" 408]
  [clojure.core$load_one invokeStatic "core.clj" 5933]
  [clojure.core$load_one invoke "core.clj" 5928]
  [clojure.core$load_lib$fn__6850 invoke "core.clj" 5975]
  [clojure.core$load_lib invokeStatic "core.clj" 5974]
  [clojure.core$load_lib doInvoke "core.clj" 5953]
  [clojure.lang.RestFn applyTo "RestFn.java" 142]
  [clojure.core$apply invokeStatic "core.clj" 669]
  [clojure.core$load_libs invokeStatic "core.clj" 6016]
  [clojure.core$load_libs doInvoke "core.clj" 6000]
  [clojure.lang.RestFn applyTo "RestFn.java" 137]
  [clojure.core$apply invokeStatic "core.clj" 669]
  [clojure.core$require invokeStatic "core.clj" 6038]
  [clojure.core$require doInvoke "core.clj" 6038]
  [clojure.lang.RestFn invoke "RestFn.java" 512]
  [clojure.tools.deps.alpha.extensions.deps$eval28497$loading__6789__auto____28498 invoke "deps.clj" 9]
  [clojure.tools.deps.alpha.extensions.deps$eval28497 invokeStatic "deps.clj" 9]
  [clojure.tools.deps.alpha.extensions.deps$eval28497 invoke "deps.clj" 9]
  [clojure.lang.Compiler eval "Compiler.java" 7194]
  [clojure.lang.Compiler eval "Compiler.java" 7183]
  [clojure.lang.Compiler load "Compiler.java" 7653]
  [clojure.lang.RT loadResourceScript "RT.java" 381]
  [clojure.lang.RT loadResourceScript "RT.java" 372]
  [clojure.lang.RT load "RT.java" 459]
  [clojure.lang.RT load "RT.java" 424]
  [clojure.core$load$fn__6908 invoke "core.clj" 6161]
  [clojure.core$load invokeStatic "core.clj" 6160]
  [clojure.core$load doInvoke "core.clj" 6144]
  [clojure.lang.RestFn invoke "RestFn.java" 408]
  [clojure.core$load_one invokeStatic "core.clj" 5933]
  [clojure.core$load_one invoke "core.clj" 5928]
  [clojure.core$load_lib$fn__6850 invoke "core.clj" 5975]
  [clojure.core$load_lib invokeStatic "core.clj" 5974]
  [clojure.core$load_lib doInvoke "core.clj" 5953]
  [clojure.lang.RestFn applyTo "RestFn.java" 142]
  [clojure.core$apply invokeStatic "core.clj" 669]
  [clojure.core$load_libs invokeStatic "core.clj" 6016]
  [clojure.core$load_libs doInvoke "core.clj" 6000]
  [clojure.lang.RestFn applyTo "RestFn.java" 137]
  [clojure.core$apply invokeStatic "core.clj" 669]
  [clojure.core$require invokeStatic "core.clj" 6038]
  [clojure.core$require doInvoke "core.clj" 6038]
  [clojure.lang.RestFn invoke "RestFn.java" 421]
  [clojure.tools.namespace.reload$track_reload_one invokeStatic "reload.clj" 35]
  [clojure.tools.namespace.reload$track_reload_one invoke "reload.clj" 21]
  [clojure.tools.namespace.reload$track_reload invokeStatic "reload.clj" 52]
  [clojure.tools.namespace.reload$track_reload invoke "reload.clj" 43]
  [clojure.lang.AFn applyToHelper "AFn.java" 154]
  [clojure.lang.AFn applyTo "AFn.java" 144]
  [clojure.lang.Var alterRoot "Var.java" 308]
  [clojure.core$alter_var_root invokeStatic "core.clj" 5535]
  [clojure.core$alter_var_root doInvoke "core.clj" 5530]
  [clojure.lang.RestFn invoke "RestFn.java" 425]
  [clojure.tools.namespace.repl$do_refresh invokeStatic "repl.clj" 94]
  [clojure.tools.namespace.repl$do_refresh invoke "repl.clj" 83]
  [clojure.tools.namespace.repl$refresh invokeStatic "repl.clj" 145]
  [clojure.tools.namespace.repl$refresh doInvoke "repl.clj" 128]
  [clojure.lang.RestFn invoke "RestFn.java" 421]
  [integrant.repl$reset invokeStatic "repl.clj" 90]
  [integrant.repl$reset invoke "repl.clj" 88]
  [system$restart invokeStatic "system.clj" 66]
  [system$restart invoke "system.clj" 62]
  [system$restart invokeStatic "system.clj" 65]
  [system$restart invoke "system.clj" 62]
  [user$eval28002 invokeStatic "NO_SOURCE_FILE" 1]
  [user$eval28002 invoke "NO_SOURCE_FILE" 1]
  [clojure.lang.Compiler eval "Compiler.java" 7194]
  [clojure.lang.Compiler eval "Compiler.java" 7149]
  [clojure.core$eval invokeStatic "core.clj" 3215]
  [clojure.core$eval invoke "core.clj" 3211]
  [clojure.main$repl$read_eval_print__9206$fn__9209 invoke "main.clj" 437]
  [clojure.main$repl$read_eval_print__9206 invoke "main.clj" 437]
  [clojure.main$repl$fn__9215 invoke "main.clj" 458]
  [clojure.main$repl invokeStatic "main.clj" 458]
  [clojure.main$repl doInvoke "main.clj" 368]
  [clojure.lang.RestFn applyTo "RestFn.java" 137]
  [clojure.core$apply invokeStatic "core.clj" 667]
  [clojure.core$apply invoke "core.clj" 662]
  [rebel_readline.clojure.main$eval15434$repl_STAR___15435 invoke "main.clj" 82]
  [rebel_readline.clojure.main$repl invokeStatic "main.clj" 91]
  [rebel_readline.clojure.main$repl doInvoke "main.clj" 90]
  [clojure.lang.RestFn invoke "RestFn.java" 397]
  [rebel_readline.clojure.main$_main invokeStatic "main.clj" 112]
  [rebel_readline.clojure.main$_main doInvoke "main.clj" 111]
  [clojure.lang.RestFn applyTo "RestFn.java" 137]
  [clojure.core$apply invokeStatic "core.clj" 667]
  [clojure.core$apply invoke "core.clj" 662]
  [rebel_readline.main$_main invokeStatic "main.clj" 6]
  [rebel_readline.main$_main doInvoke "main.clj" 5]
  [clojure.lang.RestFn invoke "RestFn.java" 436]
  [clojure.lang.Var invoke "Var.java" 393]
  [nrepl.cmdline$interactive_repl invokeStatic "cmdline.clj" 402]
  [nrepl.cmdline$interactive_repl invoke "cmdline.clj" 385]
  [nrepl.cmdline$dispatch_commands invokeStatic "cmdline.clj" 486]
  [nrepl.cmdline$dispatch_commands invoke "cmdline.clj" 473]
  [nrepl.cmdline$_main invokeStatic "cmdline.clj" 496]
  [nrepl.cmdline$_main doInvoke "cmdline.clj" 491]
  [clojure.lang.RestFn applyTo "RestFn.java" 137]
  [clojure.lang.Var applyTo "Var.java" 705]
  [clojure.core$apply invokeStatic "core.clj" 667]
  [clojure.main$main_opt invokeStatic "main.clj" 514]
  [clojure.main$main_opt invoke "main.clj" 510]
  [clojure.main$main invokeStatic "main.clj" 664]
  [clojure.main$main doInvoke "main.clj" 616]
  [clojure.lang.RestFn applyTo "RestFn.java" 137]
  [clojure.lang.Var applyTo "Var.java" 705]
  [clojure.main main "main.java" 40]]}

Approach for programmatic transformation

How to effectively work with the seancorfield/deps-new programmatic transformation

I assume the simplest way is to have different files used as the source where code should be different based on a give option.
It seems a more involved approach to rewrite template files, although depending on the changes this may make a simpler template to maintain

One thing that is not so clear from the docs is the difference between data and edn - although I added a println function to show the respective values in each when running the template (I am assuming data is keys from the template and edn is the template plus the project basis, maybe some other bits)

data-fn

updating keys in the overall template.edn file seems pretty straight forward via the data-fn

Very basic example that creates another key/value based on the value of an existing value in the template

(defn data-fn
  "Transform key/value pairs in the template
  Return: hash-map to be merged into the data by deps-new"
  [data]
  ;; returning nil means no changes to options data
  (when (= (data :component) "integrant")
    {:integrant-repl true})
 )

transform-fn

Effective ways to transform the :transform [[,,,]] data based on the template.edn key/values

Are there helpers that simplify transforming the [[ ,,, ]] structure

Libraries to review

References:
https://clojurians.slack.com/archives/C019ZQSPYG6/p1681126973615799

#21

[template] single page app

Create a template to generate a project to build a single page app using ClojureScript, Reagent and Figwheel-main

If significant overlap in code & configuration, consider combining SPA functionality into the practicalli/landing-page template

Aspects

  • dynamic landing page with Reitit front-end navigation which toggles components for different views

[dev] multiple portal windows on refresh

Portal window opens automatically on REPL startup when dev is on the class path, e.g. via :repl/reloaded or :dev/reloaded aliases from Practicalli Clojure CLI Config.

However, when reloading namespaces the user namespace that launches Portal is reloaded as its on the classpath, causing a second portal window to be opened

Discover if it possible to detect if Portal is already running and only run portal again if it is not.

Reference

Create application template

Create practicalli/application template for use with seancorfield/deps-new project

dev/user.clj for development tools ✅

  • hotloading libraries with add-libs
  • portal data inspector
  • mulog and tap publisher
  • find-deps library search

Common dependencies ✅

  • Latest Clojure release
  • mulog for logging

clojure-version is set to latest stable release in the template.edn file and can be passed a specific Clojure version for the new project

clojure -T:project/create :clojure-version '"1.12.0-alpha"'

REPL Reloaded workflow

  • kaocha test runner & kaochatests.edn configuration
  • namespace reloading (tools.namespace)
  • add-libs for hot-loading (Clojure 1.11.x and 1.12.x supported)
  • portal data inspector & mulog portal publisher
  • GitHub Workflows for configuration lint and code quality checks
  • Dockerfile and compose configurations

Editor support ✅

  • Emacs .dir-locals.el configuration with recommended aliases

Common aliases ✅

  • :run/service - run the project using clojure.exec
  • :dev/reloaded - include dev/user.clj file and associated development tools
  • :test/env - paths and deps for test runners
  • :test/run - run kaocha test runner (pass :watch? true to enable automated test runs locally)

Related: practicalli/clojure#404

Can't repro readme

Hi @practicalli-johnny ,

first time user here, not sure if I did something wrong.

~ $ clojure -Ttools install io.github.seancorfield/deps-new '{:git/tag "v0.5.2"}'  :as project-create
Cloning: https://github.com/seancorfield/deps-new.git
Checking out: https://github.com/seancorfield/deps-new.git at 253f32af67a87bc4f6d7f60e2a7353ca220a9d81
project-create: Installed io.github.seancorfield/deps-new v0.5.2
~ $ clojure -Tproject-create practicalli/service :name practicalli.gameboard/service
Cloning: https://github.com/clojure/tools.build.git
Checking out: https://github.com/clojure/tools.build.git at fe6b1405ba888720c813c7488c03880be73bbe20
Namespace could not be loaded: practicalli

Thanks - V

[format] template updates from cljstyle

cljstyle is still finding some format and style issues, with a couple of false positives for the mulog tap publisher

  • Review the outstanding cljstyle report
  • Update formatting in dev/mulog-publisher.clj
  • Modify cljstyle rules that are not supporting readable code

[service] docker compose container exits

When running a project via docker compose up --builld the container exists with status zero

The container should continue to run and not exit until docker compose down is called (or Ctrl-c is pressed)

review rewrite-clj to generate template files

Minimise duplicate code and configuration between template option variants by using a base set of code and configuration files that are re-written using rewrite-clj to add or change code and config that makes up the new project

References:
https://clojurians.slack.com/archives/C019ZQSPYG6/p1681126973615799

Related #3

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.