poly libs
When we talk about poly libraries, we refer to 3rd-party library dependencies used by components, bases, and projects.
For poly brick dependencies, see Dependencies.
We explored brick dependencies using the Realworld example app; we’ll continue with the same workspace to explore libraries.
Ask poly to report on 3rd-party libraries:
poly libs
Notice that poly has reported on library usage across all:
projects in purple - rb is the alias for the realworld-backend project, and dev is the alias for the development project.
The dependencies for a project also include the dependencies for its bricks.
If different versions of a library are referenced, poly will use the latest version of that library.
components in green
bases in blue
An x means that the library is used from the src context, and t means that it’s only used from the test context.
The type column describes where the library is hosted. See Library Dependency Types.
The KB column shows the size of each library in kilobytes.
A - means poly could not calculate the library size because either:
the library has not been downloaded yet
If your workspace has many bricks, you may prefer a more compact report format.
You can either set :compact-views to #{"libs"} in your workspace.edn or specify the :compact argument:
poly libs :compact
If the list of libraries is long, there is the option to filter out a specific library you are interested in:
poly libs libraries:slugger/slugger
You can filter by more than one library, as well as libraries whose names start with, for example, "ring" or "s":
poly libs libraries:ring:s
Often you want each library to use the same version. You can configure the tool to warn if any library is inconsistent, in workspace.edn.
{...
:validations {:inconsistent-lib-versions {:type :warning
:exclude []}}}
Here, we use the inconsistent-libs workspace as an example:
poly libs
The clj-time/clj-time library appears in both versions 0.15.1 and 0.15.2, and is highlighted in yellow because the :type is set to :warning.
If we execute:
poly check
We get this warning:
If we set type to :error:
{...
:validations {:inconsistent-lib-versions {:type :error
:exclude []}}}
The libraries are instead highlighted in red, and the check reports an error:
It’s possible to exclude selected libraries from validation, or to disable validation of inconsistent libraries altogether:
{...
:validations {:inconsistent-lib-versions {:type :error
:exclude [clj-time/clj-time]}}}
{...
:validations {:inconsistent-lib-versions {:type :none
:exclude []}}}
You can list outdated libraries:
poly libs :outdated
Your output will differ. Here’s an example output where some libraries were out of date:
You can ask poly to update all libraries to the latest version in all deps.edn and package.json files, for all bricks and projects via:
poly libs :update
To update specific libraries:
poly libs :update libraries:djblue/portal:com.taoensso/timbre
When using the shell, poly will, after a short pause, offer autocomplete suggestions for libraries!
|
To skip updating specific libraries, specify :keep-lib-versions in your workspace.edn, e.g.:
{...
:bricks {"article" {:keep-lib-versions [djblue/portal]}}}
:projects {"realworld-backend" {:alias "rb"
:keep-lib-versions [clj-jwt/clj-jwt clj-time/clj-time]}}
By default, poly libs only lists the libraries that bricks and projects declare
in their deps.edn files.
A library that a project only gets transitively (pulled in by another library) is
not shown for that project, which can hide version drift between projects.
We use the transitive-lib-deps
workspace as an example.
It has four components, brick1 to brick4, and (besides development) four projects,
project-a, project-b, project-c and project-d (aliases a, b, c and d):
brick1 declares com.stuartsierra/component version 0.2.3, which pulls in
com.stuartsierra/dependency version 0.1.1 transitively.
brick2 declares com.stuartsierra/dependency directly, at the newer version 1.0.0.
brick3 declares a local library, local/lib-a, which in turn declares
com.stuartsierra/component version 0.1.0 (pulling in com.stuartsierra/dependency
version 0.1.1 transitively - two levels deep, and through a :local/root dependency
rather than a Maven one) and medley/medley version 1.0.0, a library that no brick
or project declares anywhere else in the workspace.
brick4 declares com.stuartsierra/component directly, at version 1.0.0.
project-a contains brick1 and brick2, project-b only brick1.
project-c contains brick3 and brick4, project-d only brick3.
poly libs
com.stuartsierra/dependency only shows up for a and dev (both include brick2).
It’s missing entirely for b, c and d, even though they do have the library on
their classpath: project-b gets version 0.1.1 transitively via brick1, and
project-c gets version 1.0.0 transitively via brick4. project-d is missing both
com.stuartsierra/component and com.stuartsierra/dependency, which it only gets
transitively via brick3’s `local/lib-a.
Pass :transitive to resolve each project’s full dependency tree:
poly libs :transitive
Three new rows appear - com.stuartsierra/component 0.1.0, com.stuartsierra/dependency
0.1.1 and medley/medley 1.0.0 - plus a ` for `c` on the existing
`com.stuartsierra/dependency 1.0.0` row.
A ` means the project only gets that library+version transitively (x / t are
still used for a directly declared library, - for "not on the classpath"):
project-b resolves com.stuartsierra/dependency to 0.1.1, transitively via brick1.
project-c resolves com.stuartsierra/dependency to 1.0.0, transitively via brick4
(the same version project-a declares directly, so it merges into that row).
project-d resolves com.stuartsierra/component to 0.1.0 and
com.stuartsierra/dependency to 0.1.1, both transitively via brick3’s
`local/lib-a - proving that the dependency tree is followed through local
libraries too, not just Maven ones.
project-c, project-d and dev all resolve medley/medley to 1.0.0, transitively
via brick3’s `local/lib-a - even though nothing in the workspace declares
medley/medley directly. A library that is only ever reached through a
:local/root dependency, with no directly declared occurrence to compare it
against, is still shown: that is exactly the kind of hidden, vendored-in library
version that :transitive is meant to surface.
com.stuartsierra/component and com.stuartsierra/dependency are both highlighted
because inconsistent library versions are configured as a warning in this
workspace. medley/medley isn’t, since it only resolves to a single version here.
Libraries are added to the :transitive view when either a declared version of them
exists somewhere in the workspace (so a drift between the declared and the resolved
version becomes visible, as for com.stuartsierra/component and
com.stuartsierra/dependency above), or when they are only reachable through a
:local/root library (as for medley/medley above). Everything else - ordinary
Maven-only transitive plumbing like org.clojure/spec.alpha, which every project gets
via org.clojure/clojure - is left out, to keep the view focused.
:transitive needs Maven metadata (network access, or a fully primed
~/.m2) and resolves every project, so it is slower than the default view.
|
You can specify libraries in three ways in tools.deps deps.edn files:
| Type | Description |
|---|---|
Maven | As a Maven dependency, e.g.:
The key is the Maven |
Local | As a local dependency, e.g.:
The key is an arbitrary identifier. A local dependency is a path to a local jar file or directory. See also: Local Dependencies. |
Git | As a Git dependency, e.g.:
The |
NPM dependencies are specified in package.json files:
| Type | Description |
|---|---|
NPM | An NPM dependency, e.g.:
|
3rd-party tools.deps library dependencies are specified in deps.edn for each component, base, and project:
| Entity | File | Scope | Location in File |
|---|---|---|---|
Components |
| src |
|
test |
| ||
Bases |
| src |
|
test |
| ||
Deployable projects |
| src |
|
test |
| ||
Development project |
| src |
|
test |
|
Third-party NPM dependencies are specified in the package.json file of each component, base, and project, located alongside the corresponding deps.edn file.
Source dependencies go under the "dependencies" key, while test dependencies go under the "devDependencies" key (see this file as an example).
You’ll remember that you also specify bricks and projects as :local/root dependencies.
The poly tool distinguishes brick dependencies from local 3rd-party library dependencies by their paths.
The poly tool understands that when a :local/root path starts with:
../../bases/ or ../../components/ for deployable projects
or bases/ or components/ for the development project
that it is a poly brick dependency; otherwise, it is considered a 3rd-party library dependency.
When using the tools.deps CLI (i.e. clojure or clj), :local/root dependencies only inherit :src dependencies; :test dependencies are ignored.
The poly tool builds upon tools.deps but has its own test runner that it invokes for the test command.
Unlike the tools.deps CLI, the poly also inherits dependencies from the test context for :local/root dependencies.
If you want to run your tests directly from a project using the tools.deps CLI tool, you must duplicate test library dependencies from the bricks to the project’s deps.edn file under :aliases > :test > :extra-deps.
If you only run tests with the built-in test command, you don’t have to worry about this.
The library dependencies for a project are the sum of all library dependencies that are indirectly included via its bricks, together with dependencies declared by the project itself.
If different versions of the same library dependency exist, then poly will use the latest version.
You can override the library version used for a project in its deps.edn file.
For example:
{...
:deps {poly/article {:local/root "../../components/article"}
poly/comment {:local/root "../../components/comment"}
poly/database {:local/root "../../components/database"}
...
:override-deps {clj-time/clj-time {:mvn/version "0.15.1"}} (1)
...
}
| 1 | Override version of clj-time/clj-time for this project |
If you re-run the libs command:
Notice that two versions of clj-time are listed and that the realworld-backend project now uses version 0.15.1.
You can override project library dependencies for projects via :override-deps in the following places:
| Entity | File | Scope | Location in File |
|---|---|---|---|
Deployable projects |
| src |
|
test |
| ||
Development project |
| src |
|
test |
|
Overriding a library in the src scope will also affect the test scope.
If you override a library in the test scope, it will only affect the test scope.
Can you improve this documentation? These fine people already did:
Joakim Tengstrand & Furkan BayraktarEdit on GitHub
cljdoc builds & hosts documentation for Clojure/Script libraries
| Ctrl+k | Jump to recent docs |
| ← | Move to previous article |
| → | Move to next article |
| Ctrl+/ | Jump to the search field |