diff --git a/.clj-kondo/config.edn b/.clj-kondo/config.edn index 4ea9477..f6fd8f1 100644 --- a/.clj-kondo/config.edn +++ b/.clj-kondo/config.edn @@ -1,36 +1,44 @@ -{:output {:pattern "::{{level}} file={{filename}},line={{row}},col={{col}}::{{message}}"} - :linters {:aliased-namespace-symbol {:level :warning} - :consistent-alias {:aliases {clojure.edn edn - clojure.java.io io - clojure.math math - clojure.set set - clojure.walk walk - clojure.zip zip - clojure.core.async async - clojure.data.csv csv - clojure.data.xml xml - clojure.tools.cli cli - clojure.java.shell sh - clojure.pprint pp - clojure.spec.alpha spec - clojure.string str - clojure.core.matrix mat - clojure.tools.logging log - clojure.core.reducers r}} - :docstring-leading-trailing-whitespace {:level :warning} - :keyword-binding {:level :warning} - :main-without-gen-class {:level :warning} - :missing-docstring {:level :warning} - :namespace-name-mismatch {:level :warning} - :reduce-without-init {:level :warning} - :redundant-fn-wrapper {:level :warning} - :refer {:level :warning - :exclude #{clojure.test cljs.test doo.runner}} - :refer-all {:exclude #{clojure.test}} - :shadowed-var {:level :warning} - :single-key-in {:level :warning} - :unresolved-symbol {:exclude [(clojure.test/is [match?]) - clojure.test.check.clojure-test/defspec]} - :unsorted-required-namespaces {:level :warning} - :used-underscored-binding {:level :warning} - :unused-value {:level :warning}}} +{:exclude-files ".clj-kondo/imports/.*" + :output {:pattern "::{{level}} file={{filename}},line={{row}},col={{col}}::{{message}}"} + :ns-groups [{:pattern "\\*\\.experimental\\.\\*" + :name experimental-features} + {:pattern "\\*\\.impl" + :name implementation-only}] + :linters {:aliased-namespace-symbol {:level :warning} + :consistent-alias {:aliases {clojure.edn edn + clojure.java.io io + clojure.math math + clojure.set set + clojure.walk walk + clojure.zip zip + clojure.core.async async + clojure.data.csv csv + clojure.data.xml xml + clojure.tools.cli cli + clojure.java.shell sh + clojure.pprint pp + clojure.spec.alpha spec + clojure.string str + clojure.core.matrix mat + clojure.tools.logging log + clojure.core.reducers r}} + :discouraged-var {clojure.core/read-string {:message "Use `clojure.edn/read-string` instead of `read-string`."}} + :discouraged-namespace {experimental-features {:message "These functions are considered experimental and can break or change implementation in future releases."} + implementation-only {:message "These functions are considered internal implementation details and are not part of their respective public api."}} + :docstring-leading-trailing-whitespace {:level :warning} + :keyword-binding {:level :warning} + :main-without-gen-class {:level :warning} + :missing-docstring {:level :warning} + :namespace-name-mismatch {:level :warning} + :reduce-without-init {:level :warning} + :redundant-fn-wrapper {:level :warning} + :refer {:level :warning + :exclude #{clojure.test cljs.test doo.runner}} + :refer-all {:exclude #{clojure.test}} + :shadowed-var {:level :warning} + :single-key-in {:level :warning} + :unresolved-symbol {:exclude [(clojure.test/is [match?]) + clojure.test.check.clojure-test/defspec]} + :unsorted-required-namespaces {:level :warning} + :used-underscored-binding {:level :warning} + :unused-value {:level :warning}}} diff --git a/.cljstyle b/.cljstyle index 910e1da..1681189 100644 --- a/.cljstyle +++ b/.cljstyle @@ -1,3 +1,6 @@ {:files {:extensions #{"clj" "cljs" "cljc" "cljx" "edn"} - :ignore #{"target" ".git" ".idea" ".vscode" "node_modules"}} - :rules {:namespaces {:enabled? false}}} + :ignore #{"target" ".git" ".idea" ".vscode" "node_modules" ".clj-kondo" ".calva" ".lsp"}} + :rules {:namespaces {:enabled? false} + :indentation {:indents {#"defspec" [[:inner 0]] + #"defstate" [[:inner 0]] + #"for-all" [[:inner 0]]}}}} diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 50e6203..87d4136 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -1,11 +1,15 @@ # Proposed Changes +Quickly describe your change and the rationale behind it. +Please link to any relevant issues or discussions. + - Additions: - Updates: - Deletions: ## Pre-merge Checklist -- [ ] Write + run tests +- [ ] Read and agree to the Contribution Guidelines and Code of Conduct +- [ ] Write new tests for the changed functionality - [ ] Update CHANGELOG and increment version - [ ] Update README and relevant documentation diff --git a/CODEOWNERS b/CODEOWNERS index 9ae368a..15d8e32 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -1,2 +1,6 @@ # Barring any major exception, all Wall Brew Developers should be maintainers of any file * @Wall-Brew-Co/wall-brew-developers + +## This file was automatically copied and populated by rebroadcast + +## Do not edit this file directly, instead modify the source at diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md index fa9f122..81bb590 100644 --- a/CODE_OF_CONDUCT.md +++ b/CODE_OF_CONDUCT.md @@ -65,7 +65,7 @@ Representation of a project may be further defined and clarified by project main ## Enforcement -Any and all instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at contact@wallbrew.com. +Any and all instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at contact [at] wallbrew [dot] com. All complaints will be reviewed and investigated and will result in a response that is deemed necessary and appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 157f94e..a6edfdf 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -7,8 +7,8 @@ Wall Brew strives to make contributions as simple as possible while ensuring our - [Code of Conduct](#code-of-conduct) - [Our Pledge](#our-pledge) -- [Communicating Changes](#communicating-changes) - - [Read the Documentation](#read-the-documentation) +- [Prior to Contributing](#prior-to-contributing) +- [Communicating and Contributing Changes](#communicating-and-contributing-changes) - [Where To Start](#where-to-start) - [Pull Request](#pull-request) - [Restricted Files](#restricted-files) @@ -36,7 +36,13 @@ size, disability, ethnicity, gender identity and expression, level of experience A full copy of our code of conduct may be found in any Wall Brew repository. -## Communicating Changes +## Prior to Contributing + +Familiarize yourself with the documentation before you submit a Pull Request. +If you have questions which aren't in the documentation, open a ticket or submit a Pull Request to update the documentation. +Prior to starting development on an individual fork, we recommend executing the tests locally to confirm the library and your machine are working as expected. + +## Communicating and Contributing Changes For small issues, improvements, and bug fixes, feel free to fork any repository and publish a pull request. A Wall Brew maintainer will be automatically assigned for review, and help you understand any remaining steps to merge your changes. @@ -52,22 +58,17 @@ For issues, reports, and changes that span multiple repositories or would change Lastly, to effectively communicate changes to our consumers, please follow the conventions of each repository when writing documentation or adding annotative metadata to functionality. This allows us to cleanly and consistently provide our end-users with a high-quality development experience. -### Read the Documentation - -Familiarize yourself with the documentation before you submit a Pull Request. -If you have questions which aren't in the documentation, open a ticket or submit a Pull Request to update the documentation. - ### Where To Start If you're looking for ways to contribute, but don't know where to start, try adding additional tests. Additionally improving documentation or adding examples as you learn a new project can is an easy way to pitch in. -Finally, check the open [issues and feature requests](https://github.com/nnichols/clj-xml/issues) of the project and ask the maintainers if they are available to be taken on. +Finally, check the open [issues and feature requests](https://github.com/Wall-Brew-Co/clj-xml/issues) of the project and ask the maintainers if they are available to be taken on. ## Pull Request 1. Each Wall Brew library follows [SemVer](http://semver.org/ "The Semantic Versioning Scheme"). Please update the version number of any affected projects accordingly. -2. Update the project's [CHANGELOG.md](https://github.com/nnichols/clj-xml/blob/master/CHANGELOG.md) with the new version, date of changes, and a description of the modifications made -3. If any changes impact the external interface or use of the library, please update the [README](https://github.com/nnichols/clj-xml/blob/master/README.md) to reflect any relevant differences or with additional documentation. +2. Update the project's [CHANGELOG.md](https://github.com/Wall-Brew-Co/clj-xml/blob/master/CHANGELOG.md) with the new version, date of changes, and a description of the modifications made with [sealog](https://github.com/Wall-Brew-Co/lein-sealog) +3. If any changes impact the external interface or use of the library, please update the [README](https://github.com/Wall-Brew-Co/clj-xml/blob/master/README.md) to reflect any relevant differences or with additional documentation. 4. Be sure to write and update tests that reflect your changes, with good assertion descriptions, and that ensure future contributions will not cause your changes to regress in behavior. 5. Ensure all automated checks pass against your pull request, and make any updates to fix tests, linter warnings, etc. 6. A Wall Brew maintainer will be automatically assigned to review your Pull Request. Please consider any changes or enhancements they may suggest. In some cases, at the discretion of individual Wall Brew maintainers, these changes may be pushed onto your branch or added to any pull request. diff --git a/doc/clojure/patterns/symbolic_keywords.md b/doc/clojure/patterns/symbolic_keywords.md new file mode 100644 index 0000000..215b642 --- /dev/null +++ b/doc/clojure/patterns/symbolic_keywords.md @@ -0,0 +1,53 @@ +# Symbolic Keywords + +In many clojure libraries, the behavior of complex functions may be controlled by a map. +For example: + +```clojure +(:require [brewtility.units :as units]) +(units/display :volume 1.5 :liter) ;; => "1.5 l" +(units/display :volume 1.5 :liter {:suffix :full}) ;; => "1.5 liter" +``` + +This allows us to easily extend the definition of a single function to fulfill multiple complex needs; however, option maps come with considerable drawbacks. +When a map is keyed with keywords, it is easy to introduce subtle, hard-to-detect errors. +Since most of these functions select default values for keys not present, typos can lead to meaningful differences in behavior. +For example: + +```clojure +(:require [brewtility.units :as units]) +(units/display :volume 1.5 :liter) ;; => "1.5 l" + +;; Note the missing "f" in the key :sufix +(units/display :volume 1.5 :liter {:sufix :full}) ;; => "1.5 l" +``` + +Because keywords aren't picked up by the auto-complete features of most editors, they're vulnerable to all classes of transpositional errors. +Further, the options themselves are unable to carry metadata and documentation with them, making them little more than magic values. + +For this reason, it is helpful for libraries to include symbols which point to the "magic" keywords used in option maps. +This has several benefits: + +- Misspelled or incorrect option keys are compile-time errors, instead of runtime bugs +- Symbols can carry metadata like documentation, deprecation notices, and point to alternative options +- Context-aware editors can auto-complete options + +Here's an example: + +```clojure +(:require [brewtility.units :as units] + [brewtility.units.options :as options]) + +(units/display options/volume 1.5 options/liter) ;; => "1.5 l" +(units/display options/volume 1.5 options/liter {options/suffix options/full}) ;; => "1.5 liter" +``` + +These keywords are available in the namespaces ending in `.options`. +These files live as close to the code relying on them as possible; +for example, the options for all unit conversion operations (e.g. `brewtility.units`, `brewtility.units.time`, `brewtility.units.color`, etc.) are available in `brewtility.units.options`. + +Further, the keywords in these namespaces are strictly preferred for library development. +A single source of truth for the name of a common option, such as `precision`, limits the possibility of incorrectly retrieving the values used by that option. + + + diff --git a/doc/developing/001_required_tooling.md b/doc/developing/001_required_tooling.md new file mode 100644 index 0000000..725d910 --- /dev/null +++ b/doc/developing/001_required_tooling.md @@ -0,0 +1,109 @@ +# Required Tooling + +Development at Wall Brew currently spans two primary programming languages: [clojure](https://clojure.org/) and [javascript.](https://www.javascript.com/) +To build libraries and applications in those languages we use the two following build tools: + +* [Leiningen](https://leiningen.org/) +* [npm](https://www.npmjs.com/) + +We highly recommend using your operating system's preferred package manager to install the following dependencies. +If you do not have a preferred package manager, we currently recommend [Homebrew.](https://brew.sh/) + +For developers working on Windows machines, we strongly recommend the [Windows Subsystem for Linux (WSL).](https://learn.microsoft.com/en-us/windows/wsl/install) + +## Clojure Development + +### The Java Development Kit + +Since clojure is a hosted language within the JVM, a recent JDK is required. +We recommend and develop against [OpenJDK](https://openjdk.org/) distributions. +The following Homebrew command will install the most recent distribution: + +```sh +brew install openjdk +``` + +You can verify the installation with the following command: + +```sh +$ java --version +openjdk 21.0.2 2024-01-16 +OpenJDK Runtime Environment Homebrew (build 21.0.2) +OpenJDK 64-Bit Server VM Homebrew (build 21.0.2, mixed mode, sharing) +``` + +If you plan on developing against or regression testing functionality against older JDK versions, we recommend installing [jenv.](https://www.jenv.be/) +jenv can be installed with the following homebrew command: + +```sh +brew install jenv +``` + +You can verify the installation with the following command: + +```sh +$ jenv versions +* system (set by /some/local/path/.jenv/version) +``` + +### Leiningen + +Leiningen manages clojure dependencies and tooling, and can be installed with the following homebrew command: + +```sh +brew install leiningen +``` + +You can verify the installation with the following command: + +```sh +$ lein -v +Leiningen 2.11.2 on Java 21.0.2 OpenJDK 64-Bit Server VM +``` + +When working in a clojure repository, Leiningen will use a file named `project.clj` in the repository's root to declare library dependencies and tooling plugins. +Leiningen will automatically download these as-needed while using default commands; however, they can be pre-fetched with the following: + +```sh +lein deps +``` + +Individual developer tools should be installed in `.lein/profiles.clj` +A sample profile is provided below, but can be customized to your needs: + +```clj +{:user {:plugin-repositories [["clojars" {:url "https://clojars.org/repo"}]] + :git-dependencies [["https://github.com/tobyhede/monger.git"]] + :plugins [[com.jakemccrary/lein-test-refresh "0.23.0"] + [lein-cloverage "1.2.4"] + [com.github.liquidz/antq "RELEASE"] + [ns-sort "1.0.3"]] + :test-refresh {:notify-command ["terminal-notifier" "-title" "Tests" "-message"]}}} +``` + +Default developer tools will be installed in the `project.clj` file for each Wall Brew repository. + +## Clojurescript and Javascript Development + +### Node.js + +The Node Package Manager manages dependencies and tooling for our javascript projects and our clojurescript testing dependencies. +It can be installed with the following homebrew command: + +```sh +brew install node +``` + +You can verify the installation with the following command: + +```sh +$ npm version +{ + npm: '10.2.4', + node: '21.6.2', + ... +} +``` + + + diff --git a/doc/developing/002_managed_tooling.md b/doc/developing/002_managed_tooling.md new file mode 100644 index 0000000..b02e459 --- /dev/null +++ b/doc/developing/002_managed_tooling.md @@ -0,0 +1,53 @@ +# Managed Tooling + +The [Wall Brew Open Source Guidelines](https://github.com/Wall-Brew-Co/open-source) encourage a seamless and consistent developer experience. +While we often think about the work required to provide the tools, documentation, and automation behind that experience; we would do ourselves a disservice to ignore the cost of maintaining these files across a growing number of repositories. +To prevent individual repositories from falling out of sync, [rebroadcast](https://github.com/Wall-Brew-Co/rebroadcast) was established to be the primary source of truth for these files. +This requires a degree of standardization across repositories, including the use of the following tools which back the capabilities replicated by rebroadcast. +The below tools are automatically enabled in our CI/CD, and do not strictly require installation. + +## GitHub Actions + +Since all Wall Brew repositories are hosted on GitHub, we have adopted [GitHub Actions](https://docs.github.com/en/actions) for our CI/CD needs: + +- Executing tests against pull requests +- Enforcing style and formatting guides +- Releasing artifacts to public repositories + +## cljstyle + +[cljstyle](https://github.com/greglook/cljstyle) is used to automatically format all clojure(script) code at Wall Brew. +Further, each application uses the same cljstyle configuration to maintain as consistent of a look and feel as possible. +While the configuration is minimal, rebroadcasting the file minimizes the cost of any future extension or change. +Generally, the configuration should only ever change if it would break or interfere with other developer tools. + +Our GitHub actions will automatically apply this formatting against commits in open pull requests. +We recommend pulling these changes back to your local branch before continuing with further development. +If you wish to run the formatter locally, you can follow their [installation guide.](https://github.com/greglook/cljstyle?tab=readme-ov-file#installation) + +## clj-kondo + +[clj-kondo](https://github.com/clj-kondo/clj-kondo) is used as the primary linting too for clojure(script) code at Wall Brew. +Aside from a few special rules and hooks, most applications and all libraries, are generally able to leverage the same linter configuration. +The configuration is designed to cleanly integrate with code quality tools, and to push developers towards consistent coding standards. +Pull requests against Wall Brew repositories will report any linter violations to the author in pull request comments. + +Many language-aware editors and editor plugins have adopted clj-kondo as the default linter for clojure. +If your IDE does not have this option, you can [use the leiningen plugin.](https://github.com/clj-kondo/clj-kondo/blob/master/doc/jvm.md#leiningen) + +## sealog + +[Sealog](https://github.com/Wall-Brew-Co/lein-sealog) is the default changelog management tool used at Wall Brew. +All applications and libraries are able to leverage the same changelog configuration. +The configuration is designed to enforce consistent Changelog and versioning standards. +Prior to merging a releasable pull request, the author or a Wall Brew maintainer should increment the version, log notable changes, and regenerate the changelog. + +## Renovate + +Wall Brew currently uses [Renovate](https://docs.renovatebot.com/) to manage dependency updates. +The default configuration is language agnostic, and is therefore available on every repository. +It will automatically check for and submit pull requests for outdated libraries and tools. +The Renovate configuration will also update the jobs in our GitHub Action Workflows defined in `rebroadcast`. + + + diff --git a/doc/developing/003_contribution_guidelines.md b/doc/developing/003_contribution_guidelines.md new file mode 100644 index 0000000..665b336 --- /dev/null +++ b/doc/developing/003_contribution_guidelines.md @@ -0,0 +1,78 @@ +# Contribution Guidelines + +Human interaction is complex and subject to many different lenses of personal, contextual, and cultural influence. +Every individual has their own perception of what they consider to be helpful, harmful, professional, and casual conduct. +Differences in these perceptions can leady to unhealthy or harmful conflicts of opinion, which can cascade into real harm against a person's emotional, physical, and/or mental well-being. +Within a community, it is important to ensure that differences in opinion may be held without adversely impacting any community member. + +However, we each individually hold our own perceptions of what a community is and ought to be. +Enforcing any communal rules or standards requires a shared understanding of what is and is not considered acceptable behavior and language. +Without a shared context for a community, fair and even judgement, remediation, and enforcement of community rules and standards is impossible. + +Therefore, it is important to be explicit on what boundaries exist and what territory may be adjacent to those boundaries. +Those fostering communities must not only communicate their expectations clearly, but also take care to consistently and promptly enforce those expectations. +In some cases, that requires explicitly removing bad faith members of a community. + +Several of our philosophies manifest as concrete requirements that every Wall Brew library and maintainer must uphold. +These are policies and practices which cannot be superseded, ignored, or violated except in the most extreme of situations. +Maintainers are expected to kindly and professionally reinforce our requirements, and to help contributors make the adjustments necessary to meet them as well. +Consistent, intentional, or bad-faith violations of these requirements may be grounds to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions, or to ban temporarily or permanently any contributor or maintainer. + +Each repository contains a full-text copy of our [Code of Conduct](https://github.com/Wall-Brew-Co/rebroadcast/blob/master/sources/community/CODE_OF_CONDUCT.md), which must be followed at all times. + +## Prior to Contributing + +Familiarize yourself with the documentation before you submit a Pull Request. +If you have questions which aren't in the documentation, open a ticket or submit a Pull Request to update the documentation. +Prior to starting development on an individual fork, we recommend executing the tests locally to confirm the library and your machine are working as expected. + +## Communicating and Contributing Changes + +For small issues, improvements, and bug fixes, feel free to fork any repository and publish a pull request. +Please utilize the pull request template to communicate your changes and to ensure that all steps have been completed. +A Wall Brew maintainer will be automatically assigned for review, and help you understand any remaining steps to merge your changes. + +For larger changes, we ask that you please first discuss the change you wish to make prior to starting work. +This helps ensure the overall design of our libraries remains consistent, and that work is not being duplicated with any planned enhancements. +Once you have reached an agreement with a Wall Brew maintainer, feel free to fork any repository and publish a pull request. +A Wall Brew maintainer will be automatically assigned for review, and help you understand any remaining steps to merge your changes. + +For issues, requests, and changes scoped to this repository, please open an issue or a feature request in that repository. +For issues, reports, and changes that span multiple repositories or would change a common development standard, please start [a discussion.](https://github.com/Wall-Brew-Co/open-source/discussions) + +Lastly, to effectively communicate changes to our consumers, please follow the conventions of each repository when writing documentation or adding annotative metadata to functionality. +This allows us to cleanly and consistently provide our end-users with a high-quality development experience. + +### Pull Request + +1. Each Wall Brew library follows [SemVer](http://semver.org/ "The Semantic Versioning Scheme"). Please update the version number of any affected projects accordingly. +2. Update the project's CHANGELOG with the new version, date of changes, and a description of the modifications made with [sealog](https://github.com/Wall-Brew-Co/lein-sealog) +3. If any changes impact the external interface or use of the library, please update the README to reflect any relevant differences or with additional documentation. +4. Be sure to write and update tests that reflect your changes, with good assertion descriptions, and that ensure future contributions will not cause your changes to regress in behavior. +5. Ensure all automated checks pass against your pull request, and make any updates to fix tests, linter warnings, etc. +6. A Wall Brew maintainer will be automatically assigned to review your Pull Request. Please consider any changes or enhancements they may suggest. In some cases, at the discretion of individual Wall Brew maintainers, these changes may be pushed onto your branch or added to any pull request. + +### Restricted Files + +Wall Brew repositories automatically labels Pull Requests targeting a few select files as `restricted`. +These files are generally related to Wall Brew development policies and standards, and the majority are automatically generated by [rebroadcast.](https://github.com/Wall-Brew-Co/rebroadcast) +Changes to these files should be rare, and will generally only come from members of the Wall-Brew-Co organization. +In most cases, Pull Requests targeting these files will not be accepted until the state of those files is reverted. + +### Automatic Formatting + +Wall Brew repositories automatically re-format source and test code to match our internal style preferences. +You may forcefully push over these automated commits, but be aware our Pull Request automation will re-format files on each push. +Changes to our formatter configurations are generally considered restricted; however, if they conflict with your developer tooling (e.g. `parinfer`, screen readers) please contact a Wall Brew maintainer with the issue you are facing. +The configuration for code styling tools is automatically maintained by [rebroadcast.](https://github.com/Wall-Brew-Co/rebroadcast) + +## Legal Adherence + +To ensure Wall Brew libraries adhere to all applicable intellectual property laws, contributors must ensure: + +- Their contributions may, in whole, be submitted under the open source license included in the repository +- Their contributions, in any way, do not contain the intellectual property of any entity who has not agreed to the contribution be submitted under the open source license included in the repository +- They understand and agree to the fact that any contribution to this repository is public, and that records of the contribution are maintained indefinitely + + + diff --git a/pom.xml b/pom.xml index 922298f..49ed813 100644 --- a/pom.xml +++ b/pom.xml @@ -68,7 +68,7 @@ org.clojure clojure - 1.11.3 + 1.12.0 org.clojure diff --git a/project.clj b/project.clj index afb3392..1757996 100644 --- a/project.clj +++ b/project.clj @@ -10,9 +10,9 @@ :pom-addition [:organization [:name "Wall Brew Co."] [:url "https://wallbrew.com"]] - :dependencies [[org.clojure/clojure "1.11.3"] + :dependencies [[org.clojure/clojure "1.12.0"] [org.clojure/data.xml "0.2.0-alpha9"]] - :plugins [[com.github.clj-kondo/lein-clj-kondo "2024.05.24"] + :plugins [[com.github.clj-kondo/lein-clj-kondo "2024.08.29"] [com.wallbrew/lein-sealog "1.6.0"] [com.wallbrew/bouncer "1.0.0"] [mvxcvi/cljstyle "0.16.630"]]