Git Product home page Git Product logo

kit's Introduction

Kit

Lightweight, modular framework for scalable production systems.

Goal

The goal of Kit is to provide a template for a robust, scalable Clojure web application. It hides common plumbing that is standard across projects via its libs system, while exposing code that tends to be customized in the clj-new template.

Thanks to integrant, and aero, the libs are simple skeletons with the bulk of the customization being done in the system configuration EDN file.

Quick start

Kit requires clj-new, installed preferably as a tool:

clojure -Ttools install com.github.seancorfield/clj-new '{:git/tag "v1.2.381"}' :as clj-new

To create a new Kit application:

clojure -Tclj-new create :template io.github.kit-clj :name yourname/app

Latest versions

Library Latest Version
io.github.kit-clj/kit-core Clojars Project
io.github.kit-clj/kit-hato Clojars Project
io.github.kit-clj/kit-metrics Clojars Project
io.github.kit-clj/kit-nrepl Clojars Project
io.github.kit-clj/kit-quartz Clojars Project
io.github.kit-clj/kit-redis Clojars Project
io.github.kit-clj/kit-repl Clojars Project
io.github.kit-clj/kit-selmer Clojars Project
io.github.kit-clj/kit-sql Clojars Project
io.github.kit-clj/kit-sql-conman Clojars Project
io.github.kit-clj/kit-sql-hikari Clojars Project
io.github.kit-clj/kit-sql-migratus Clojars Project
io.github.kit-clj/kit-postgres Clojars Project
io.github.kit-clj/kit-mysql Clojars Project
io.github.kit-clj/kit-xtdb Clojars Project
io.github.kit-clj/kit-generator Clojars Project
io.github.kit-clj/lein-template Clojars Project
io.github.kit-clj/deps-template Clojars Project

Profiles

Default libs included with no profile specified:

  • kit-core
  • kit-undertow

Additional profiles:

  • +xtdb - Adds the kit-xtdb lib
  • +hato - Adds the kit-hato lib
  • +metrics - Adds the kit-metrics lib
  • +quartz - Adds the kit-quartz lib
  • +redis - Adds the kit-redis lib
  • +selmer - Adds the kit-selmer lib
  • +nrepl - Adds the kit-nrepl lib
  • +socket-repl - Adds the kit-repl lib
  • +sql - Adds the default SQL libraries: kit-sql-conman , kit-sql-migratus, and kit-postgres libs
  • +conman - Adds the kit-sql-conman lib
  • +hikari - Adds the kit-sql-hikari lib
  • +migratus - Adds the kit-sql-migratus lib
  • +mysql - Adds the kit-sql-general and kit-mysql libs
  • +full - Adds the libs kit-xtdb, kit-hato , kit-metrics, kit-quartz, kit-redis, kit-selmer , kit-repl, kit-sql-conman, kit-postgres, and kit-sql-migratus

Libs

  • kit-core - basic utility functions used by some other libs
  • kit-xtdb - Simple binding to connect to a XTDB database node
  • kit-hato - HTTP client using hato
  • kit-nrepl - nREPL component for use in a running system. e.g. to connect to a production REPL
  • kit-metrics - Configurable metrics using iapetos
  • kit-quartz - Scheduler using cronut as an integrant binding for quartz. Exposes the cronut API, simply some extensions for aero and utilities
  • kit-redis - An extension of core.cache for Redis via carmine
  • kit-repl - Socket REPL integrant binding for use in a running system. e.g. to connect to a production REPL
  • kit-selmer - Templating configuration with selmer
  • kit-sql - Deprecated. Use kit-sql-conman and kit-sql-migratus. Pulls in both of these as generic SQL integrant binding. Uses conman , next.jdbc , hugsql, and migratus directly, or implicitly
  • kit-sql-conman - Uses conman , next.jdbc , hugsql,
  • kit-sql-hikari - General sql layer, just contains connection pooling ( via hikari-cp) and jdbc wrapper ( via next.jdbc) .
  • kit-sql-migratus - uses migratus for SQL migrations
  • kit-postgres - lib with data bindings and utilities for working with Postgres
  • kit-mysql - lib with data bindings and utilities for working with MySQL8+
  • kit-undertow - Server binding via ring-undertow-adapter

Build Tool Support

Presently only Clojure deps is supported, however there are plans to add Leiningen support.

Documentation

Documentation can be found here

Emacs Integration

An emacs package is available which provides a Magit-style interface to clj-new and deps-new and provides a command to create Kit web applications.

Inspiration and thanks to

License

Copyright © 2021

Released under the MIT license.

kit's People

Contributors

aisamu avatar ajakate avatar arca0 avatar borkdude avatar collc avatar danboykis avatar dspearson avatar eelkevanfoeken avatar gerdint avatar green-coder avatar ieugen avatar jaimesangcap avatar jiyouyou125 avatar jpe90 avatar keram avatar lacarmen avatar markokocic avatar martinklepsch avatar muthuishere avatar nikolap avatar philipmw avatar rads avatar seancorfield avatar sound2gd avatar vemv avatar walterl avatar whamtet avatar yogthos 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  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  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  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

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

kit's Issues

syncing modules fails because git/git-clone is called wrongly?

(git/git-clone url {:path path
:remote-name "origin"
:branch-name (or tag "master")
:bare false
:clone-all-branches false})))

When I attempt to do

(sync-repository! "modules" {:url  "https://github.com/kit-clj/modules.git"
                             :tag  "master"
                             :name "kit-modules"})

this fails and gives the following error

failed to clone module: https://github.com/kit-clj/modules.git 
cause: No value supplied for key: {:path "modules/kit-modules", :remote-name "origin", :branch-name "master", :bare false, :clone-all-branches false}

When I remove the curly brackets it does work.

Expose query-fn for production use

It looks like the only way to access query-fn is to access integrant.repl.state. This is a dev dependency, and this means HugSQL can't be used in production.

I'm not sure if that was the intention. In Luminus, I used HugSQL queries in production. Maybe we should expose this function.

how to log the sql executed

hello, when i exec a fn like this

(query-fn :get-user-by-id {:id 0})

is there any way to log the final sql string it sends to db?

Not able to append-requires in cljs file when installing a module

I created a pull request kit-clj/modules#7 to add Sente support as a module for kit.

Steps to reproduce:

  1. Create a kit project with default parameters.
  2. update kit.edn to fetch modules from https://github.com/markokocic/modules sente branch
  3. Try to install :kit/sente module

When calling (kit/install-module :kit/sente), I get the following error:

user=> (kit/install-module :kit/sente)
java.lang.ClassCastException: class java.lang.String cannot be cast to class clojure.lang.IFn (java.lang.String is in module java.base of loader 'bootstrap'; clojure.lang.IFn is in unnamed module of loader 'app')
        at clojure.zip$end_QMARK_.invokeStatic(zip.clj:262)
        at clojure.zip$end_QMARK_.invoke(zip.clj:258)
        at rewrite_clj.custom_zipper.core$end_QMARK_.invokeStatic(core.cljc:263)
        at rewrite_clj.custom_zipper.core$end_QMARK_.invoke(core.cljc:263)
        at rewrite_clj.zip.move$end_QMARK_.invokeStatic(move.cljc:42)
        at rewrite_clj.zip.move$end_QMARK_.invoke(move.cljc:38)
        at clojure.core$complement$fn__5737.invoke(core.clj:1455)
        at clojure.core$take_while$fn__5986.invoke(core.clj:2923)
        at clojure.lang.LazySeq.sval(LazySeq.java:42)
        at clojure.lang.LazySeq.seq(LazySeq.java:51)
        at clojure.lang.RT.seq(RT.java:535)
        at clojure.core$seq__5467.invokeStatic(core.clj:139)
        at clojure.core$drop_while$step__6009.invoke(core.clj:2989)
        at clojure.core$drop_while$fn__6012.invoke(core.clj:2994)
        at clojure.lang.LazySeq.sval(LazySeq.java:42)
        at clojure.lang.LazySeq.seq(LazySeq.java:51)
        at clojure.lang.LazySeq.first(LazySeq.java:73)
        at clojure.lang.RT.first(RT.java:692)
        at clojure.core$first__5449.invokeStatic(core.clj:55)
        at clojure.core$first__5449.invoke(core.clj:55)
        at rewrite_clj.zip.findz$find.invokeStatic(findz.cljc:44)
        at rewrite_clj.zip.findz$find.invoke(findz.cljc:31)
        at rewrite_clj.zip.findz$find_token.invokeStatic(findz.cljc:119)
        at rewrite_clj.zip.findz$find_token.invoke(findz.cljc:110)
        at rewrite_clj.zip.findz$find_value.invokeStatic(findz.cljc:146)
        at rewrite_clj.zip.findz$find_value.invoke(findz.cljc:131)
        at rewrite_clj.zip$find_value.invokeStatic(zip.cljc:425)
        at rewrite_clj.zip$find_value.invoke(zip.cljc:415)
        at kit.generator.modules.injections$append_requires.invokeStatic(injections.clj:236)
        at kit.generator.modules.injections$append_requires.invoke(injections.clj:235)
        at kit.generator.modules.injections$eval10332$fn__10334.invoke(injections.clj:289)
        at clojure.lang.MultiFn.invoke(MultiFn.java:229)
        at kit.generator.modules.injections$inject_at_path$fn__10409.invoke(injections.clj:358)
        at clojure.lang.PersistentVector.reduce(PersistentVector.java:343)
        at clojure.core$reduce.invokeStatic(core.clj:6885)
        at clojure.core$reduce.invoke(core.clj:6868)
        at kit.generator.modules.injections$inject_at_path.invokeStatic(injections.clj:356)
        at kit.generator.modules.injections$inject_at_path.invoke(injections.clj:353)
        at kit.generator.modules.injections$inject_data.invokeStatic(injections.clj:375)
        at kit.generator.modules.injections$inject_data.invoke(injections.clj:368)
        at kit.generator.modules.generator$eval10523$fn__10525.invoke(generator.clj:66)
        at clojure.lang.MultiFn.invoke(MultiFn.java:234)
        at kit.generator.modules.generator$generate.invokeStatic(generator.clj:138)
        at kit.generator.modules.generator$generate.invoke(generator.clj:110)
        at kit.api$install_module.invokeStatic(api.clj:37)
        at kit.api$install_module.invoke(api.clj:27)
        at kit.api$install_module.invokeStatic(api.clj:29)
        at kit.api$install_module.invoke(api.clj:27)
        at user$eval30485.invokeStatic(NO_SOURCE_FILE:1)
        at user$eval30485.invoke(NO_SOURCE_FILE:1)
        at clojure.lang.Compiler.eval(Compiler.java:7194)
        at clojure.lang.Compiler.eval(Compiler.java:7149)
        at clojure.core$eval.invokeStatic(core.clj:3215)
        at clojure.core$eval.invoke(core.clj:3211)
        at nrepl.middleware.interruptible_eval$evaluate$fn__26216$fn__26217.invoke(interruptible_eval.clj:87)
        at clojure.lang.AFn.applyToHelper(AFn.java:152)
        at clojure.lang.AFn.applyTo(AFn.java:144)
        at clojure.core$apply.invokeStatic(core.clj:667)
        at clojure.core$with_bindings_STAR_.invokeStatic(core.clj:1990)
        at clojure.core$with_bindings_STAR_.doInvoke(core.clj:1990)
        at clojure.lang.RestFn.invoke(RestFn.java:425)
        at nrepl.middleware.interruptible_eval$evaluate$fn__26216.invoke(interruptible_eval.clj:87)
        at clojure.main$repl$read_eval_print__9206$fn__9209.invoke(main.clj:437)
        at clojure.main$repl$read_eval_print__9206.invoke(main.clj:437)
        at clojure.main$repl$fn__9215.invoke(main.clj:458)
        at clojure.main$repl.invokeStatic(main.clj:458)
        at clojure.main$repl.doInvoke(main.clj:368)
        at clojure.lang.RestFn.invoke(RestFn.java:1523)
        at nrepl.middleware.interruptible_eval$evaluate.invokeStatic(interruptible_eval.clj:84)
        at nrepl.middleware.interruptible_eval$evaluate.invoke(interruptible_eval.clj:56)
        at nrepl.middleware.interruptible_eval$interruptible_eval$fn__26249$fn__26253.invoke(interruptible_eval.clj:152)
        at clojure.lang.AFn.run(AFn.java:22)
        at nrepl.middleware.session$session_exec$main_loop__26319$fn__26323.invoke(session.clj:218)
        at nrepl.middleware.session$session_exec$main_loop__26319.invoke(session.clj:217)
        at clojure.lang.AFn.run(AFn.java:22)
        at java.base/java.lang.Thread.run(Thread.java:829)
:kit/sente requires following modules: [:kit/cljs]
:kit/cljs requires following modules: [:kit/html]
:kit/html requires following modules: nil
module :kit/html is already installed!
module :kit/cljs is already installed!
updating file: deps.edn
updating file: shadow-cljs.edn
updating file: resources/system.edn
updating file: src/clj/marko/sentem/core.clj
applying
 action: :append-requires
 value: ["[marko.sentem.web.routes.ws]"]
updating file: src/cljs/marko/sentem/core.cljs
applying
 action: :append-requires
 value: ["[marko.sentem.ws :as ws]"]
failed to install module :kit/sente
:done
user=>

Cleanup SQL profiles in lein-template project

We probably want a cleaner way to handle the matrix of SQL library combinations.

Perhaps if it gets too complicated we can boot some of them out of the template and leave that to individual teams to extend as they please so that Kit remains clean

Sente websocket integration / module

Just came across Sente library, which allows a two-way communication between a client and a server.

I'm already considering hooking it up to the re-frame even bus, and use in an application to communicate with the server instead of using the REST API.

Before I spend more time on this topic, I'd like to know is there a good example how it could fit in kit application architecture. A module to wire the basics would be even better.

Can't create a new project

Hello. I followed the docs and when I run

clojure -Tnew create :template io.github.kit-clj :name kit/guestbook
cd guestbook

I get

-T is no longer supported, use -A with repl, -M for main, or -X for exec

Then I switched to -M

clojure -Mnew create :template io.github.kit-clj :name kit/guestbook

And received:

Execution error (FileNotFoundException) at java.io.FileInputStream/open0 (FileInputStream.java:-2).
create (No such file or directory)

Full report at:
/tmp/clojure-5188057076386034437.edn
$ cat /tmp/clojure-5188057076386034437.edn

{:clojure.main/message
 "Execution error (FileNotFoundException) at java.io.FileInputStream/open0 (FileInputStream.java:-2).\ncreate (No such file or directory)\n",
 :clojure.main/triage
 {:clojure.error/class java.io.FileNotFoundException,
  :clojure.error/line -2,
  :clojure.error/cause "create (No such file or directory)",
  :clojure.error/symbol java.io.FileInputStream/open0,
  :clojure.error/source "FileInputStream.java",
  :clojure.error/phase :execution},
 :clojure.main/trace
 {:via
  [{:type java.io.FileNotFoundException,
    :message "create (No such file or directory)",
    :at [java.io.FileInputStream open0 "FileInputStream.java" -2]}],
  :trace
  [[java.io.FileInputStream open0 "FileInputStream.java" -2]
   [java.io.FileInputStream open "FileInputStream.java" 219]
   [java.io.FileInputStream <init> "FileInputStream.java" 157]
   [java.io.FileInputStream <init> "FileInputStream.java" 112]
   [clojure.lang.Compiler loadFile "Compiler.java" 7575]
   [clojure.main$load_script invokeStatic "main.clj" 475]
   [clojure.main$script_opt invokeStatic "main.clj" 535]
   [clojure.main$script_opt invoke "main.clj" 530]
   [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]],
  :cause "create (No such file or directory)"}}

I'm on Linux

Module sync issue - file module.edn modified after kit/sync-modules

Steps to reproduce:

  1. Create a new project, e.g deps -Tnew create :template io.github.kit-clj :name marko/testm
  2. start repl and sync modules (kit/sync-modules)
  3. go to modules/kit-modules directory
  4. git status shows modules.edn as modified file.
diff --git a/modules.edn b/modules.edn
index 324ac65..6953edb 100644
--- a/modules.edn
+++ b/modules.edn
@@ -1,20 +1 @@
-{:name "kit-modules"
- :modules
- {:kit/html
-  {:path "html"
-   :doc "adds support for HTML templating using Selmer"}
-  :kit/htmx
-  {:path "htmx"
-   :doc "adds support for HTMX using hiccup"}
-  :kit/metrics
-  {:path "metrics"
-   :doc "adds support for metrics using prometheus through iapetos"}
-  :kit/sql
-  {:path "sql"
-   :doc "adds support for SQL. Available profiles [ :postgres :sqlite ]. Default profile :sqlite"}
-  :kit/cljs
-  {:path "cljs"
-   :doc "adds support for cljs using shadow-cljs"}
-  :kit/nrepl
-  {:path "nrepl"
-   :doc "adds support for nREPL"}}}
+{:name "kit-modules", :modules {:kit/html {:path "html", :doc "adds support for HTML templating using Selmer"}, :kit/htmx {:path "htmx", :doc "adds support for HTMX using hiccup"}, :kit/metrics {:path "metrics", :doc "adds support for metrics using prometheus through iapetos"}, :kit/sql {:path "sql", :doc "adds support for SQL. Available profiles [ :postgres :sqlite ]. Default profile :sqlite"}, :kit/cljs {:path "cljs", :doc "adds support for cljs using shadow-cljs"}, :kit/nrepl {:path "nrepl", :doc "adds support for nREPL"}}, :module-root "kit-modules"}^M

Since the file is modified, further syncs fails.
This happens on windows.

After reverting modules.edn file using git checkout -- . it is not possible to install module

  1. restart repl and do, e.g (kit/install-module :kit/cljs)
  2. the following error appears
user=> (kit/install-module :kit/cljs)
Execution error (FileNotFoundException) at java.io.FileInputStream/open0 (FileInputStream.java:-2).
modules\cljs\config.edn (The system cannot find the path specified)
user=>

In order to fix this, I have to manually move content of kit-modules directly under modules directory. After that I am able to install a module.

  1. cd modules
  2. mv kit-modules/* .
  3. start repl and do (kit/install-module :kit/cljs),
  4. it works

Note: it's not related to :kit/cljs module. Same behaviour for any module

Btw, installing a module right after doing kit/sync-modules (without reverting the modified modules.edn file) works properly.

Could be that something gets messed up with path.

Reading .env or config.edn files by default

As a new user I've been struggling with this for a while. From what I can tell, system.edn uses aero to read environment variables, but it has no ability to read from actual .env files.

Since Integrant is so central to the kit workflow, it'd be great if there was already a bootstrap in place for reading from either .env or config.edn files. It's standard to have local environment files that aren't in version history. I, however, have had trouble finding a way to "export" these locally defined variables before integrant's config is read.

There doesn't appear to be anything for this at the moment.

Exception when adding postgresql query result w/ timestamp to session state

When I try to query a record that contains a timestamp from a postgres database and assoc it to the session, I'm getting an error that I couldn't make sense of (see below). If I dissoc the timestamp field before adding it to the session, or if I use sqlite, I don't get the error.

A minimal reproduction is available here: https://github.com/jpe90/kit-bug-demo. Accessing the root route at localhost:3000 will cause the app to try to add the user to the session and throw the following exception:

2022-03-02 14:47:52,448 [XNIO-1 task-1] ERROR io.undertow.request - UT005071: Undertow request failed HttpServerExchange{ POST /}
java.lang.AssertionError: Assert failed: (= x (deserialize % options))
	at ring.middleware.session.cookie$serialize.invokeStatic(cookie.clj:77)
	at ring.middleware.session.cookie$serialize.invoke(cookie.clj:77)
	at ring.middleware.session.cookie$seal.invokeStatic(cookie.clj:84)
	at ring.middleware.session.cookie$seal.invoke(cookie.clj:81)
	at ring.middleware.session.cookie.CookieStore.write_session(cookie.clj:100)
	at ring.middleware.session$bare_session_response.invokeStatic(session.clj:52)
	at ring.middleware.session$bare_session_response.invoke(session.clj:43)
	at ring.middleware.session$session_response.invokeStatic(session.clj:74)
	at ring.middleware.session$session_response.invoke(session.clj:66)
	at ring.middleware.session$wrap_session$fn__17005.invoke(session.clj:109)
	at ring.middleware.keyword_params$wrap_keyword_params$fn__17051.invoke(keyword_params.clj:53)
	at ring.middleware.nested_params$wrap_nested_params$fn__17109.invoke(nested_params.clj:89)
	at ring.middleware.multipart_params$wrap_multipart_params$fn__17407.invoke(multipart_params.clj:171)
	at ring.middleware.params$wrap_params$fn__17434.invoke(params.clj:75)
	at ring.middleware.cookies$wrap_cookies$fn__16884.invoke(cookies.clj:214)
	at ring.middleware.absolute_redirects$wrap_absolute_redirects$fn__17622.invoke(absolute_redirects.clj:47)
	at ring.middleware.resource$wrap_resource_prefer_resources$fn__17470.invoke(resource.clj:25)
	at ring.middleware.content_type$wrap_content_type$fn__17570.invoke(content_type.clj:34)
	at ring.middleware.default_charset$wrap_default_charset$fn__17594.invoke(default_charset.clj:31)
	at ring.middleware.not_modified$wrap_not_modified$fn__17536.invoke(not_modified.clj:61)
	at ring.middleware.x_headers$wrap_x_header$fn__16537.invoke(x_headers.clj:22)
	at ring.middleware.x_headers$wrap_x_header$fn__16537.invoke(x_headers.clj:22)
	at ring.middleware.x_headers$wrap_x_header$fn__16537.invoke(x_headers.clj:22)
	at clojure.lang.AFn.applyToHelper(AFn.java:154)
	at clojure.lang.AFn.applyTo(AFn.java:144)
	at clojure.lang.AFunction$1.doInvoke(AFunction.java:31)
	at clojure.lang.RestFn.invoke(RestFn.java:408)
	at kit.edge.server.undertow$eval16310$fn__16311$fn__16314.invoke(undertow.clj:29)
	at ring.adapter.undertow$undertow_handler$fn$reify__16251.handleRequest(undertow.clj:40)
	at io.undertow.server.session.SessionAttachmentHandler.handleRequest(SessionAttachmentHandler.java:68)
	at io.undertow.server.Connectors.executeRootHandler(Connectors.java:387)
	at io.undertow.server.HttpServerExchange$1.run(HttpServerExchange.java:852)
	at org.jboss.threads.ContextClassLoaderSavingRunnable.run(ContextClassLoaderSavingRunnable.java:35)
	at org.jboss.threads.EnhancedQueueExecutor.safeRun(EnhancedQueueExecutor.java:2019)
	at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.doRunTask(EnhancedQueueExecutor.java:1558)
	at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1449)
	at org.xnio.XnioWorker$WorkerThreadFactory$1$1.run(XnioWorker.java:1280)
	at java.base/java.lang.Thread.run(Thread.java:833)

Add support for `deps-new`

Overview

I'm working on a PR for neil (babashka/neil#51) which will make it possible to simplify the "Quick start" for Kit:

brew install clojure babashka/brew/neil
neil new io.github.kit-clj/kit yourname/app

Requirements

Performance

The neil new command is using babashka to run org.corfield.new/create which removes the JVM startup time. I haven't ported the lein-template to deps-new so I can't do a direct comparison yet. That said, with the built-in app template, the difference is significant (3s down to 0.1s):

$ time clojure -Tnew app :name yourname/app :force true
Generating a project called app based on the 'app' template.
clojure -Tnew app :name yourname/app :force true  3.04s user 0.13s system 205% cpu 1.542 total

$ time ./neil new app yourname/app --overwrite
Creating project from org.corfield.new/app in app
./neil new app yourname/app --overwrite  0.10s user 0.03s system 88% cpu 0.147 total

support for module migrations

Currently, modules write to install-log.edn whether the module was installed successfully or not. Instead, it would be better to create a map containing install information such as the version of the module that was installed as well as other metadata such as the files that were modified.

This would allow modules to provide a :migrations key under :actions. Migrations would work similarly to :injections, but would instead look for code generated by the previous version of the module and replace it with the updated code from the latest version.

Route paths don't work properly without final "/" - address bar is blank, web page not responsive

Hi,

I can't access routes mounted to "/example-route" .
It turns address bar blank and page does not work in Firefox.
I must use "/example-route/" .

I believe this is because routes, by default only listen to "/" and not to "" as well.
This might be a non issue for more seasoned devs, but to me it is.

How I got here:
I have a new porject started with html and htmx modules.
I got an error because both are trying to use the same route "/" so I decided to move htmx to "/htmx-clicked" .
I changed the entry to:

:reitit.routes/ui {:base-path "/htmx-clicked",
                    :env #ig/ref :system/env}

Opened http://localhost:3000/htmx-clicked and the address bar went blank and web page is not responding.
I can't even right click inside of it in FF.

Can't generate project from template

I am using windows, and I am unable to generate kit project.

> clojure --version
Clojure CLI version 1.10.3.1058

I installed and configured clj-new and tried to create a new kit project as per documentation:

> clojure -X:new :template io.github.kit-clj :name myname/guestbook
Execution error (IllegalArgumentException) at clojure.run.exec/apply-overrides$fn (exec.clj:56).
Key must be integer

I get the same error with both Java 11 and Java 17.

While looking at the clj-new documentation, I noticed that it's now deprecated, and it's recommended to use deps-new library from the same author instead. Maybe switching to it would be safer?

lein template compilation issue on Windows due to git symlinks

When I build and install lein-template on Windows and attempt to generate any project locally, version information for libraries is empty for any kit library in deps.edn file.

It appears that behaviour is broken due to introduction of symlinked versions.edn in 1bb1fbc
Apparently git on Windows doesn't support symlinks, instead it generates a file which contains a path to the original file.

There are few possible solutions:

  1. move versions.edn to lein-template project. Reference that file from the main build.clj script.
  2. keep two duplicate versions of versions.edn in project root directory and in libs/lein-template
  3. update build script for lein-template to include versions.edn from the root folder when building jar.

I would prefer solution 1. since 2. adds duplication and 3 is ugly.

What is the purpose of snippets?

What are snippets? I see the reference in the source, but no documentation or examples. The snippets repository is also missing.

Documentation/generating documentation

Usually my first step in understanding a new codebase is to write documentation for it :-)

I've been experimenting with integrating Codox and haven't yet found a satisfactory way to proceed. I'm raising this now because if you feel there is a better way to generate documentation I'd prefer to work on that, but if you agree that Codox is the right way to proceed I'll keep worrying at this until I do make it work.

Adding codox to the root deps.edn thus

:codox {:extra-deps {codox/codox {:mvn/version "0.10.8"}}
                   :exec-fn codox.main/generate-docs
                   :exec-args {:source-paths  ["libs/kit-core/src" ;; "libs/kit-generator/src" "libs/kit-hato/src"
                                               ]}}

feels like the right way to go because it would produce a single linked web of documentation, but I haven't (yet) made it work - it fails with multiple errors of the general form:

(base) simon@mason:~/workspace/kit$ clojure -X:codox
Could not generate clojure documentation for kit.config - root cause: java.io.FileNotFoundException Could not locate kit/config__init.class, kit/config.clj or kit/config.cljc on classpath.
java.io.FileNotFoundException: Could not locate kit/config__init.class, kit/config.clj or kit/config.cljc on classpath.

Adding codox thus to the deps.edn of individual libraries does work, but, of course, generates isolated documentation webs for the individual libraries instead of a single integrated web:

 :aliases {:codox {:extra-deps {codox/codox {:mvn/version "0.10.8"}}
                   :exec-fn codox.main/generate-docs
                   :exec-args {:source-paths  ["src"]}}}

Correct way of including complied app.js in HTML

It seems like the documentation is missing clear information on how to actually include your compiled JS in your application to start using reagent/cljs.

That is, there is information on the content of shadow-cljs.edn, and its content, specifically :output-dir and :asset-path, but it's not really clear what is the canonical way of adding the produced JS file to your HTML. In Luminus, the compiled JS file would be available in /js/app.js. In Kit, that does not seem to work. target/classes/cljsbuild/public/js is not included in :resources (should it be?).

As a result, the instruction to call (js/alert "Hi") from the REPL does not succeed, since there is no real JS runtime available.

incorrect cookie session config

Seems like the generated system.edn for :handler/ring does not match the expected key and shape in <project>.web.middleware.core

system.edn notice key :cookie-session-config

:handler/ring
 {:router                #ig/ref :router/core
  :api-path              "/api"
  :cookie-session-config {:cookie-secret          #or [#env COOKIE_SECRET "XLHSGXBMTTBTRCHU"]
                          :cookie-name            "io.klei.lms"
                          :cookie-default-max-age 86400}

In <project>.web.middleware.core
The (cookie/cookie-store cookie-session) expects the {:key "SECRET"} for the secrey key instead of :cookie-secret and data type as bytes instead of string?


(defn wrap-base
  [{:keys [metrics site-defaults-config cookie-session] :as opts}]
  (fn [handler]
    (cond-> ((:middleware env/defaults) handler opts)
            true (defaults/wrap-defaults
                   (assoc-in site-defaults-config [:session :store] (cookie/cookie-store cookie-session))))))

Happy to create a PR. If this is an actual issue. Seems it is a change in the lein-template?

default handlers (404, 405, 406) in the default project encodes string is base64 encoded

So, by default, the 404 response and probably the others in the example is base64 encoded in the response: UGFnZSBub3QgZm91bmQ= .

Base64 decode of the above is "Page not found" .

This is the code but not sure where this base64 encoding is done.

(ring/create-default-handler
     {:not-found
      (constantly {:status 404, :body "Page not found"})
      :method-not-allowed
      (constantly {:status 405, :body "Not allowed"})
      :not-acceptable
      (constantly {:status 406, :body "Not acceptable"})})

jar generation fails with project names containing dot

When the project name contains a dot, the jar build fails. For example, i had this project name: foo.bar

$ clj -Sforce -T:build all
Cleaning target
Writing Pom...
Execution error (ExceptionInfo) at clojure.tools.build.api/assert-specs (api.clj:53).
Invalid param :lib in call to write-pom: got foo.bar, expected clojure.core/qualified-ident?

It may be an issue with clojure CLI, but i think the getting started should mention what are project's naming conventions (if any), or maybe give a workaround in the Deployment section?

build fails with 'missing :sha'

Seriously, sadly. Master checked out this morning, no modifications:

(base) simon@mason:~/workspace/kit$ clj --version
Clojure CLI version 1.10.3.855
(base) simon@mason:~/workspace/kit$ clj -X:build 
WARNING: Use of :deps in aliases is deprecated - use :replace-deps instead
Error building classpath. Library io.github.clojure/tools.build has missing :sha in coordinate.
(base) simon@mason:~/workspace/kit$ clj -X:build make-jar
WARNING: Use of :deps in aliases is deprecated - use :replace-deps instead
Error building classpath. Library io.github.clojure/tools.build has missing :sha in coordinate.

I've tried replacing the key :git/sha with just :sha; I've verified the sha value ( 34727f7)

Not at all clear what is wrong here.

Help with plain websockets

Hello,

I have a base Kit-CLJ project up and running. It's fantastic.

I've reached the point where I require a straightforward websocket endpoint, but I'm unsure of how to integrate that. That is, without interfering with the automatic module installation process, defining the route, etc.

Am I correct in thinking that I should start with kit-undertow?

Thanks!

Support nrepl in projects

It would be nice if the default kit project template would include nrepl server support in addition to server repl.

Installation failed, could not locate the artifact for template

Hi,

Tried to install Kit following command:

clojure -Ttools install com.github.seancorfield/clj-new '{:git/tag "v1.2.381"}' :as new

and

clojure -Tnew create :template io.github.kit-clj :name self/kit

Second command failed due to the following error:

Downloading: com/hypirion/io/0.3.1/io-0.3.1.jar from clojars
Downloading: pedantic/pedantic/0.2.0/pedantic-0.2.0.jar from clojars

Failed with (underlying error, possibly from Maven):
Could not find artifact io.github.kit-clj:deps-template:jar:0.1.28 in central (https://repo1.maven.org/maven2/)

Execution error (ExceptionInfo) at clj-new.helpers/resolve-remote-template (helpers.clj:176).
Could not locate the artifact for template: io.github.kit-clj
Tried coordinates:
{io.github.kit-clj/clj-template #:mvn{:version "RELEASE"}}
[io.github.kit-clj/boot-template "RELEASE"]
[io.github.kit-clj/lein-template "RELEASE"]

Any idea when the template would be re-instated in maven repo? or it has been moved permanently somewhere else?

Consider version tagging repo

Hiya! I noticed that kit is using rewrite-clj.

Rewrite-clj runs the tests of libraries that use it against rewrite-clj main branch.
This helps me to discover when a change I make to rewrite-clj might break some existing lib that uses it.
To stay sane, I only run against the latest released version of libs.

If you were to start version tagging the kit GitHub repo when releasing kit, I could add it to the rewrite-clj suite. I think kit-generator is the lib of interest for rewrite-clj, ya?

If this is not interesting to you, that's totally fine too. Lemme know.

Missing or unclear documentation on profiles, modules and libraries

By looking at the documentation it's not clear what is the difference between profiles, modules, and libraries. Looks like they are used interchangeably.

Also, guestbook tutorial shows how to use (kit/list-modules) and (kit/install-module) to install one of the additional modules from /kit-clj/modules project.

But how to install additional modules that are located in libs? Application profiles documentation section mentions that it's possible to add a new library during the project creation time, but doesn't mention how to add it to an existing project.

A separate documentation section how to create a new module (library) using integrant may be also helpful, to deepen understanding of how it all works in kit.

Default REPL_HOST is open to the wide internet

Hi all!
I am playing with tutorial's guestbook example, the framework looks really promising to me as a beginner.

Though, If I understand correctly (see screenshot from generated system.edn) that default REPL host is 0.0.0.0 even for :prod profile? Shouldn't the default for :prod be something like 127.0.0.1, otherwise it's open for everyone to connect? My opsec knowledge is rudimentary, but I can imagine accidentally making an environment variable with a typo REPL_HSOT=127.0.0.1, and by default exposing a production system's security instead of just making remote REPL unusable.

Screen Shot 2022-01-21 at 22 22 21

As a fellow clojurist rcaze noticed, usually a "real" production system should also have a firewall, but an extra fool-proof layer of security is always nice.

Inconsistent documentation

The docs on https://kit-clj.github.io/docs/guestbook.html are inconsistent.

First it says application can be generated using clojure -X:new :template io.github.kit-clj :name yourname/guestbook and then it show application tree using yourname as a package name.

But later on tutorial switches to using kit.guestbook instead of yourname.guestbook which is a bit confusing.

The docs need to be aligned, either use yourname.guestbook or kit.guestbook throughout the example to avoid confusion.

kit/install-module fails to update system.edn

I tried to wrap kit/metrics library and wrap it into a new module. I have an issue when trying to install a new module using kit/install-module with the following error:

updating file: resources/system.edn
Execution error (AssertionError) at rewrite-clj.zip.seqz/get (seqz.cljc:146).
Assert failed: (or (map? zloc) (namespaced-map? zloc) (and (seq? zloc) (integer? k)))

When I comment out the lines containing non-empty target, install seems to work, but it's obviously not a solution.

I defined my module as following: https://github.com/markokocic/modules/blob/kit-metrics/metrics/config.edn

EDIT: The error message is also not very descriptive.

Clojurescript support for webpack

I am planning to create a module that adds support for webpack to Clojurescript. In some cases, it is required for packaging an app that uses dependencies that shadow_cljs can't handle. One example would be Ionic framework, as explained in this post, which doesn't work properly without webpack.

It can be implementing either as a separate profile on :kit/cljs module, or a separate module that builds on it, e.g :kit/webpack. I tend to prefer the second option, since in that case, the decision can be delayed until it's needed later in development.

Btw, it's a little bit confusing if we should file modules related tickets here, or in modules project. For me, it make sense here, since modules belong to kit project? In that case, you might want to disable tickets in modules project and add a Readme with a short note about it?

Re-Frame example

May I ask you to point me to real example using kit and re-frame (maybe with sente). Also example with Fulcro would be great. You know to provide full examples with SPA on top of Kit.

Thx!

kit/sync-modules fails without id_rsa, and fails with a different error after I create it or set id_ed25519

I use ed25519 instead of rsa, so when I try to dync modules:

user> (kit/sync-modules)
failed to clone module: [email protected]:kit-clj/modules.git 
cause: [email protected]:kit-clj/modules.git: java.io.FileNotFoundException: /Users/xxx/.ssh/id_rsa (No such file or directory)

So reading the code I found out about kit.git-config.edn where I can give the name of my key, but replacing id_rsa with id_ed25519, I get:

user> (kit/sync-modules)
failed to clone module: [email protected]:kit-clj/modules.git 
cause: [email protected]:kit-clj/modules.git: invalid privatekey: [B@4cf19be

Released app doesn't serve shadow-cljs generated script

Specifically, the build.clj generated file should first invoke the (build-cljs nil) function, and then the (b/uber ...) one like in the following example:

(defn uber [_]
  (b/compile-clj {:basis basis
                  :src-dirs ["src/clj" "env/prod/clj"]
                  :class-dir class-dir})
  (build-cljs nil) ;; <----- Before building jar to be picked up and packaged along with the other assets
  (println "Making uberjar...")
  (b/uber {:class-dir class-dir
           :uber-file uber-file
           :main main-cls
           :basis basis}))

Currently, the script generated by shadow-cljs returns 404, as it's not included in the already generated jar, happening one step ahead.

Build commands from kit-cljs module don't work on windows.

The default build.clj file is using commands that won't work on windows. This happens with the cljs module.

This is the line put in to build.clj

(defn build-cljs [] (println "npx shadow-cljs release app...") (let [{:keys [exit], :as s} (sh "npx" "shadow-cljs" "release" "app")] (when-not (zero? exit) (throw (ex-info "could not compile cljs" s))) (sh "cp" "-r" "target/classes/cljsbuild/public" "target/classes/")))

(sh "npx" "shadow-cljs" "release" "app") Should be replaced with (babashka.process/shell "npx shadow-cljs release app").

(sh "cp" "-r" "target/classes/cljsbuild/public" "target/classes/") should be replaced with (babashka.fs/copy-tree "target/classes/cljsbuild/public" "target/classes")

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.