{"id":19140071,"url":"https://github.com/circleci/lein-deps-plus","last_synced_at":"2025-09-01T03:14:53.515Z","repository":{"id":46166080,"uuid":"415120780","full_name":"circleci/lein-deps-plus","owner":"circleci","description":null,"archived":false,"fork":false,"pushed_at":"2025-08-22T20:35:53.000Z","size":60,"stargazers_count":4,"open_issues_count":2,"forks_count":4,"subscribers_count":41,"default_branch":"main","last_synced_at":"2025-08-22T22:53:54.748Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Clojure","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"epl-1.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/circleci.png","metadata":{"files":{"readme":"README.adoc","changelog":"CHANGELOG.adoc","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":"CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2021-10-08T20:36:55.000Z","updated_at":"2025-08-04T09:51:26.000Z","dependencies_parsed_at":"2025-01-20T12:21:19.216Z","dependency_job_id":"382b2478-99d7-45b6-a784-67d8c261114f","html_url":"https://github.com/circleci/lein-deps-plus","commit_stats":{"total_commits":4,"total_committers":3,"mean_commits":"1.3333333333333333","dds":0.5,"last_synced_commit":"41c9f81c8138bbe90652cf0f6a166346673735e1"},"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/circleci/lein-deps-plus","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/circleci%2Flein-deps-plus","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/circleci%2Flein-deps-plus/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/circleci%2Flein-deps-plus/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/circleci%2Flein-deps-plus/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/circleci","download_url":"https://codeload.github.com/circleci/lein-deps-plus/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/circleci%2Flein-deps-plus/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":273068859,"owners_count":25039911,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-09-01T02:00:09.058Z","response_time":120,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-09T07:16:09.674Z","updated_at":"2025-09-01T03:14:53.506Z","avatar_url":"https://github.com/circleci.png","language":"Clojure","funding_links":[],"categories":[],"sub_categories":[],"readme":"= deps-plus plugin\n\ndeps-plus is a Leiningen plugin designed to help with analyzing project dependencies and reviewing dependency changes.\n\n== Installation\n\nAdd `+[com.circleci/deps-plus \"0.1.0-SNAPSHOT\"]+` to your `+:user+` profile plugins in `+~/.lein/profiles.clj+`. For example,\n\n[source,clj]\n....\n{:user {:plugins [[com.circleci/deps-plus \"0.1.0-SNAPSHOT\"]]}}\n....\n\n== Usage\n\nTo run a deps-plus task simply run `+lein deps-plus \u003ctask name\u003e+` from a Leiningen project.\n\n=== Tasks\n\n* *list* - Lists all dependencies of the current project.\n* *list-save* - Save the project dependency list to \"deps.list\".\n* *list-diff* - Compare project dependencies to those previously saved with `+list-save+`.\n* *why* - Shows all paths to given dependency as a tree. This is similar to `+lein deps :why+`, but instead of only showing the single resolved path to dependency chosen by Maven, all copies and paths to the dependency (including those excluded by conflict resolution) are shown.\n\n=== Checks\n\n* link:#check-classpath-conflicts[*check-classpath-conflicts*] - Checks for classpath conflicts.\n* link:#check-downgraded[*check-downgraded*] - Checks for dependencies which have been downgraded.\n* link:#check-families[*check-families*] - Checks for inconsistent dependency versions within families.\n* link:#check-forbidden-dependencies[*check-forbidden-dependencies*] - Checks dependencies to ensure none of them are listed in :forbidden-dependencies.\n* link:#check-management-conflicts[*check-management-conflicts*] - Checks for dependency management conflicts.\n* link:#check-pedantic[*check-pedantic*] - Checks for version conflicts and version ranges.\n\n==== check-classpath-conflicts\n\nChecks for classpath conflicts. Classpath conflicts occur when resources which should be unique\n(e.g. Java class files, Clojure namespaces, etc) are found in multiple dependencies. Classpath\nconflicts can lead to unpredictable behavior at runtime as the version of the resource which is loaded\ncan depend on subtle factors like the ordering of JARs on the classpath, or the order in which JARs\nare merged into an uberjar. Classpath conflicts are often caused by dependencies being duplicated\n(e.g. two versions of a dependency with different Maven coordinates) or dependencies which bundle\nother dependencies (e.g. shaded JARs). In these cases the conflict can be resolved by replacing the\noffending dependency with a more appropriate one (e.g. a non-shaded version).\n\n_Example: Apache logging classes_\n\n....\nFound 6 classpath conflicts between commons-logging:commons-logging:jar:1.2:compile and org.slf4j:jcl-over-slf4j:jar:1.7.30:compile\n  org/apache/commons/logging/Log.class\n  org/apache/commons/logging/LogConfigurationException.class\n  org/apache/commons/logging/LogFactory.class\n  org/apache/commons/logging/impl/NoOpLog.class\n  org/apache/commons/logging/impl/SimpleLog$1.class\n  org/apache/commons/logging/impl/SimpleLog.class\n....\n\nThese packages both implement the same classes, but the latter implements the former with SLF4J.\n\n_Solution:_ Pick which package should be chosen (there's no practical way to tell which version of\nthe class has been chosen in the past).  In this case, we'll pick `org.slf4j/jcl-over-slf4j`.  So we\nadd a top level exclusion for `commons-logging/commons-logging`, preventing _any_ dependency from\npulling it in:\n\n[source,clj]\n....\n  :exclusions [... commons-logging/commons-logging ...]\n....\n\n_Example: com.google.javascript:closure-compiler_\n\nThe jar for the Closure Compiler includes a shaded version of https://github.com/google/gson[Gson]\nwithout renaming the classes:\n\n....\n$ jar tf ~/.m2/repository/com/google/javascript/closure-compiler/v20160315/closure-compiler-v20160315.jar | grep 'com/google/gson'\ncom/google/gson/\ncom/google/gson/Gson$5.class\ncom/google/gson/JsonNull.class\n...\n....\n\nThis always causes classpath conflicts when we also declare a direct dependency on Gson, even if the\nversion of Gson is the same in both places.  You'll have to deal with this type of conflict on a case\nby case basis.  Here, there is an\nhttps://mvnrepository.com/artifact/com.google.javascript/closure-compiler-unshaded[_unshaded_ version]\nof the Closure Compiler available that does not include the Gson classes.\n\n==== check-downgraded\n\nA dependency is considered \"downgraded\" if the resolved version is older than the version specified by\nsome other included dependency. This can occur if `:managed-dependencies` is used to pin a dependency\nversion or if Maven conflict resolution happens to not select the latest version.\n\n==== check-families\n\nChecks for inconsistent dependency versions within families. Dependencies families are sets of\ndependencies which share a common group ID and version. Inconsistent family versions can occur if the\n`:managed-dependencies` for a family are incomplete or inconsistent. This situation can also occur\nwhen different family members are brought in through different transitive dependency paths. To fix\nthis issue consider adding a complete set of `:managed-dependencies` entries for the family.\n\n_Example: io.netty family_\n....\nSuspicious combination, io.netty:netty-codec-socks:jar:4.1.34.Final:compile and io.netty:netty-buffer:jar:4.1.50.Final:compile\nSuspicious combination, io.netty:netty-codec-socks:jar:4.1.34.Final:compile and io.netty:netty-codec:jar:4.1.50.Final:compile\nSuspicious combination, io.netty:netty-codec-socks:jar:4.1.34.Final:compile and io.netty:netty-common:jar:4.1.50.Final:compile\nSuspicious combination, io.netty:netty-codec-socks:jar:4.1.34.Final:compile and io.netty:netty-transport:jar:4.1.50.Final:compile\nSuspicious combination, io.netty:netty-handler-proxy:jar:4.1.34.Final:compile and io.netty:netty-buffer:jar:4.1.50.Final:compile\nSuspicious combination, io.netty:netty-handler-proxy:jar:4.1.34.Final:compile and io.netty:netty-codec-http:jar:4.1.50.Final:compile\nSuspicious combination, io.netty:netty-handler-proxy:jar:4.1.34.Final:compile and io.netty:netty-codec:jar:4.1.50.Final:compile\nSuspicious combination, io.netty:netty-handler-proxy:jar:4.1.34.Final:compile and io.netty:netty-common:jar:4.1.50.Final:compile\nSuspicious combination, io.netty:netty-handler-proxy:jar:4.1.34.Final:compile and io.netty:netty-transport:jar:4.1.50.Final:compile\n....\n\nThese netty dependencies are all in the same family, but they have different versions (`4.1.34.Final`\nvs. `4.1.50.Final`).  In this case, the `project.clj` declares a managed dependency on\n`io.netty/netty-codec-http2` but not the other members of the family:\n\n[source,clj]\n....\n  :managed-dependencies [... [io.netty/netty-codec-http2 \"4.1.50.Final\"] ...]\n....\nThe related projects are coming in through transitive dependencies, and have different versions:\n....\n$ lein deps-plus why io.netty:netty-codec-socks:jar:4.1.34.Final\n...\n   ;; +- [circleci/my-project \"0.1.0\"]\n...\n   ;; |  \\- [io.grpc/grpc-netty \"1.20.0\"]\n   ;; |     \\- [io.netty/netty-handler-proxy \"4.1.34.Final\"]\n   ;; |        \\- [io.netty/netty-codec-socks \"4.1.34.Final\"] (chosen)\n...\n....\n\n_Solution:_ add a managed dependency for the family.  Pick the desired version for the family (in\nthis case, we'll pick `4.1.50.Final`).  At a minimum, for every package mentioned in the list of\nsuspicious combinations that has the _undesired_ version, add an entry in the `:managed-dependencies`:\n\n[source,clj]\n....\n  :managed-dependencies [[io.netty/netty-codec-socks \"4.1.50.Final\"]\n                         [io.netty/netty-handler-proxy \"4.1.50.Final\"]\n                         ...]\n....\n\nFor completeness, you can add _every_ member of the family the project uses to managed dependencies.\n\n==== check-forbidden-dependencies\n\nA dependency is considered \"forbidden\" if it's listed at the `:forbidden-dependencies` key in\n`project.clj`. While it's possible to use a global `:exclusions` to remove a dependency from the\ndependency tree, Leiningen copies those exclusions into every dependency reference. If that list\nbecomes sufficiently large then Leiningen begins to struggle. Even with relatively small amounts of\nitems in `:exclusions` it can clutter `lein deps :tree` output to the point of unreadability.\n\n[source,clj]\n....\n  :forbidden-dependencies [io.grpc/grpc-all] ; Force specific gRPC dependencies\n....\n\n....\n$ lein deps-plus check-forbidden-dependencies\n[ERROR] Forbidden dependency: io.grpc/grpc-all\n....\n\n==== check-management-conflicts\n\nChecks for dependency management conflicts. A dependency management conflict occurs when a dependency\nhas versions specified in both `:dependencies` and `:managed-dependencies`. To resolve this issue you\ncan remove the version number from `:dependencies`. If you wish to override a managed dependency\nversion inherited from a parent project you should do so in your own `:managed-dependencies` section.\n\n_Example: org.clojure/core.async_\n\n....\norg.clojure:core.async:jar:1.2.603 conflicts with managed dependency org.clojure:core.async:jar:1.3.610\n....\n\n_Solution 1:_ if the exact version of `core.async` does not matter, remove the version number from\nthe `org.clojure/core.async` version in your dependencies to automatically get the version provided by\nclj-parent:\n\n[source,clj]\n....\n  :dependencies [... [org.clojure/core.async] ...]\n....\n\nThis solution also applies when the versions are identical:\n....\norg.clojure:core.async:jar:1.3.610 conflicts with managed dependency org.clojure:core.async:jar:1.3.610\n....\n\n_Solution 2:_ if it is necessary to pin the version `1.2.603`, move the dependency to the managed\ndependencies:\n\n[source,clj]\n....\n  :managed-dependencies [... [org.clojure/core.async \"1.2.603\"] ...]\n....\n\n==== check-pedantic\n\nChecks for version conflicts and version ranges. This check is similar to Leiningen’s `:pedantic?\n:abort` mode, but suggests `+:managed-dependencies+` instead of `:exclusions`.  In general, expect to\nsee warnings when:\n\n1. A top-level dependency is overridden by another version\n2. A transitive dependency is overridden by an _older_ version\n\nUnlike Leiningen, this task ignores plugin dependencies since these are unaffected by managed\ndependencies. By default, each suggested managed dependency is shown alongside a dependency tree\nfor the conflict. Pass the `:quiet` flag to suppress the output of these trees.\n\n_Example: cheshire_\n\n....\nFound 7 dependency conflicts.\nConsidering adding the following :managed-dependencies,\n\n...\n   ;; +- [cheshire/cheshire \"5.9.0\"] (chosen)\n...\n   ;; \\- [circleci/my-project \"0.1.0\"]\n   ;;    +- [circleci/the-other-project \"0.1.0\"]\n   ;;    |  +- [circleci/rollcage \"1.0.203\"]\n   ;;    |  |  \\- [cheshire/cheshire \"5.8.1\"] (omitted)\n   ;;    |  +- [cheshire/cheshire \"5.10.0\"] (omitted)\n   ;;    |  \\- [amperity/vault-clj \"0.7.0\"]\n   ;;    |     \\- [cheshire/cheshire \"5.8.1\"] (omitted)\n   ;;    \\- [cheshire/cheshire \"5.10.0\"] (omitted)\n   [cheshire/cheshire \"5.9.0\"]\n...\n....\n\nThis shows all of the different versions of `cheshire/cheshire`, including which versions were chosen\n(would actually be used when the program runs) vs. which were excluded.  check-pedantic complains\nbecause multiple dependencies ask for different versions of `cheshire/cheshire`, and the newest version\n(transitively `\"5.10.0\"`), is omitted.\n\n_Solution 1:_ if the version of `cheshire/cheshire` from the `:dependencies` is not required for\ncorrectness, remove it as an explicit dependency and retry.  If the warning disappears, you can see\nthat the newest version wins with `why`:\n\n....\n$ lein deps-plus why cheshire\n   ;; +- [circleci/the-other-project \"0.1.0\"]\n   ;; |  +- [circleci/rollcage \"1.0.203\"]\n   ;; |  |  \\- [cheshire/cheshire \"5.8.1\"] (omitted)\n   ;; |  +- [cheshire/cheshire \"5.10.0\"] (chosen)\n   ;; |  \\- [amperity/vault-clj \"0.7.0\"]\n   ;; |     \\- [cheshire/cheshire \"5.8.1\"] (omitted)\n...\n....\n\n_Solution 2:_ add a managed dependency for the preferred version.  Pick the version that should be\nincluded (in this case, we'll pick `\"5.9.0\"`).  This is the version `check-pedantic` suggests at the\nbottom of the dependency knot.  It's also the version that the project explicitly requires as a\n`:dependency`.  Move it to a managed dependency:\n\n[source,clj]\n....\n  :managed-dependencies [... [cheshire/cheshire \"5.9.0\"] ...]\n....\n\nReleasing\n---------\n\ndeps-plus is pushed to https://clojars.org/com.circleci/deps-plus[clojars.org] as a SNAPSHOT release.\n\nBump the version *only* when backwards-incompatible changes are made.\n\nThe following should be updated on the `main` branch if there are new releases:\n\n- `project.clj` - version\n- `README.adoc` - dependency coordinates\n- `CHANGELOG.adoc` - summary of changes\n\nLicense\n-------\n\nDistributed under the http://www.eclipse.org/legal/epl-v10.html[Eclipse Public License].\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcircleci%2Flein-deps-plus","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcircleci%2Flein-deps-plus","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcircleci%2Flein-deps-plus/lists"}