anchor.diff:  
   ifdef::env-github,env-browser[:outfilesuffix: .adoc]
   
  -== Rethinking the problem
  +== Rethinking Source Libs and Builds
   
  -Clojure has evolved over the years and countless individuals and organizations have contributed to the growing success of its ecosystem. Contributing to that success have been various takes on build systems for Clojure but until now there has not been a build solution packaged with the language. Previously, applications written in Clojure often did not strictly require build artifacts, but the community has adopted the Java host ecosystem’s artifact-focused approach. Instead, we took the approach that by default source-based dependencies would be the baseline model. To facilitate this model, significant work has gone into developing and releasing various capabilities and tools, starting with the release of Clojure 1.9.
  +Clojure has evolved over the years and countless individuals and organizations have contributed to the growing success of its ecosystem. While there have been many build systems for Clojure, there has never been a build system available with the language. We have been laying the groundwork for this since the release of Clojure 1.9:
   
  -- deps.edn and https://github.com/clojure/tools.deps.alpha/[tools.deps] - a structure for declaring dependencies and tools for building classpaths from them
  +- https://clojure.org/reference/deps_and_cli#_deps_edn[deps.edn] - a data structure for declaring dependencies
  +- https://github.com/clojure/tools.deps.alpha/[tools.deps] - a library for building classpaths from deps.edn
   - https://clojure.org/reference/deps_and_cli[CLI] - a command line Clojure program runner
  -- https://github.com/clojure/tools.gitlibs[tools.gitlibs] - a library for dealing with Git repositories
   
  -Herein we'll describe the latest effort to supply a "batteries-included" story for Clojure builds called https://github.com/clojure/tools.build[tools.build] and https://clojure.org/reference/deps_and_cli#tool_install[CLI support for tools].
  +Importantly, the facilities above embrace the idea of source-based libraries (as available from GitHub), as opposed to the more common artifact-centric approach of the Java host ecosystem (which we continue to support as well).  With today's release we are pushing that idea further with more support for source-based libs (particularly on git), a new "batteries-included" story for Clojure builds called https://github.com/clojure/tools.build[tools.build], and more CLI support for https://clojure.org/reference/deps_and_cli#tool_install[tools].
   
   == Improving Source Libs
   
  -Clojure’s dynamic nature allows us to rethink the way that new libraries and applications are created. That is, we’d rather work directly with source code as our dependencies than static deployed artifacts. Clojure’s new tools.build library leverages the tools.gitlib library to work with source repositories as dependencies. In addition to working with Git repositories on common hosting services (e.g. Github, Gitlab, etc.) application developers can depend on certain commit SHAs or tagged versions directly.
  +Clojure’s dynamic nature allows us to rethink the way that libraries and applications are created to work directly with source code as our dependencies than requiring deployed artifacts. While the Clojure CLI has long supported git-based deps, it has been somewhat cumbersome to define a git-based dependency: there was no library name convention, the library name often repeated much of the url, there was no support for developer-named versions via tags, etc. While the previous format is still supported, the new format defines a convention for git libraries to infer the url, and the ability to specify meaningful versions via git tags. The short sha prefix is still included to verify the tag has not moved since definition:
   
   ```clojure
  -{:deps {GIT-LIB {:git-tag "TAG" :git-sha "SHA"}
  +{:deps {GIT-LIB {:git/tag "TAG" :git/sha "SHA"}
   ```
   
  -In the dependency above we've settled on a standard way to indicate source dependencies using a service-specific library name coupled with a Git tag and prefix SHA, used for verification. In the case of the tools.build library itself, the Github tag (indicated above by `GIT_LIB`)  becomes `io.github.clojure/tools.build`. More information on specifying Git source dependencies is found in the https://clojure.org/reference/deps_and_cli#using-git-libraries[CLI and deps guide].
  +If GIT-LIB uses the naming convention, no `:git/url` is required. For example:
   
  -Occasionally, source dependencies will require preparation (e.g. compilation, text replacement, etc.) before they’re suitable for inclusion on the classpath. A common type of “prepable” dependency would be a Java source library that requires compilation before it’s usable as a dependency. Such a dependency is declared as below:
  +```clojure
  +{:deps {io.github.clojure/tools.deps.graph {:git/tag "v1.0.63" :git/sha "0b569d6"}}}
  +```
  +
  +Here, the reversed url of a repository's GitHub pages is used to infer the git url `"https://github.com/clojure/tools.deps.graph.git"`. Similar conventions exist for GitLab, Bitbucket, etc. Rather than supply the full 40 character git sha, it is sufficient here to use a meaningful git tag name and a short sha that is used to verify the tag location. More information on specifying Git source dependencies is found in the https://clojure.org/reference/deps_and_cli#using-git-libraries[CLI and deps guide].
  +
  +Occasionally, source dependencies will require preparation (e.g. compilation, text replacement, etc.) before they’re suitable for inclusion on the classpath. A common type of “unprepped” dependency is a Clojure library with some Java source requiring compilation. A source-based lib can declare how it should be prepped in its deps.edn:
   
   ```clojure
   {:deps/prep-lib {:alias :build
  
positive.code: 
  The CLI also provides a way to explore the available versions of tools with the `clj -X:deps find-versions` command that will list the tags available for that tool. There's more to the tools story including listing installed tools, uninstalling tools, and even exploring the available functions and their details for an installed tool using the https://clojure.org/reference/deps_and_cli#other-programs[help/doc and help/dir functions]. One additional feature added to the CLI is the ability to pass https://clojure.org/reference/deps_and_cli##trailing-map-argument[a trailing map] that represents new or augmenting key value pairs as the arguments to invoke functions.
  
  More information on the new https://clojure.org/reference/deps_and_cli#tool_install[tools support in the CLI is available in the reference docs on the Clojure site].
  
  == In summary
  
  The Clojure core team has worked hard to provide a story for builds and tooling, including:
  
  - tools.build - a new library for writing build programs (???[reference], ???[guide], ???[source], ???[issues])
  - Support for running multiple functions at the CLI and passing trailing maps as arguments
  - Source deps support - inferred git urls, tags for versions, lib prep
  - Tool support - tool installation and use, better introspection
  
  If you’d like to start using tools.build then the following information should help you along the path.
  
  **TODO: uninstall/install/version/etc.**
  
  ???[Alex Miller's talk about tools.build and tool support in the CLI]
  ???[Sample project]
  
  A https://clojure.org/guides/tools_build[more comprehensive discussion of the build.clj] file under discussion in this post is available on the Clojure website. Issues and bugs can be reported on the ???[tools.build Jira project].
  
negative.code:                  :ensure "target/classes"}}
  ```
  
  The Clojure CLI library will check for the presence of the `target/classes` directory and if it’s not found, program execution will not proceed. To tell the CLI to prepare this (and any other libraries), you can run the command:
  
  ```shell
  clj -X:deps prep
  ```
  
  This command will find unprepped libs, and run the `compile` function using the `:build` alias, presumably filling the `target/classes` directory with necessary classes on the classpath. More information on supporting unprepped dependencies is available in the https://clojure.org/reference/deps_and_cli#preparing-source-dependency-libs[Clojure CLI reference]. In the next section we'll talk about the new tools.build library which can be used to do that compilation when needed.
  
  == Builds as programs
  
  The new tools.build library provides a set of task functions constructing programs in a deps.edn based project. The _“task functions”_ define a logically coherent portion of a build process. To learn more about the tasks supplied by tools.build you can read the https://clojure.github.io/tools.build[API] and https://clojure.org/guides/tools_build[guide].footnote:[You can also run the CLI command `clj -X:deps:build help/doc` if tools.build is a dependency in your deps.edn file under the `build` alias.]
  
  Build programs are Clojure source programs that use the tools.build task function API and provide build-specific _"target functions"_, suitable for execution via `clj -T`. In some cases it will also make sense to make composite target functions that combine a set of build targets. An example of using tools.build task functions to build up project-specific target functions in a build program is given in the https://clojure.org/guides/tools_build#source-library-jar-build[tools.build guide].
  
  While building aggregate targets by defining functions in your build.clj file is convenient, there are times when you may want to execute ad-hoc pipelines of task and target functions. To perform this, the Clojure CLI allows you to describe and execute a pipeline of functions on the command line, as shown below:
  
  ```bash
  clj -T:build clean jar <key/value pairs>
  ```
  
  The new `-T` execution mode for tools is similar to `-X` (execute a function) but automatically removes the project deps and paths, and adds `"."` to the `:paths`. It can also be invoked with a tool name (see the next section) in addition to with an alias.
  
  The key->value params are passed at the end and will be used to invoke the first function, `clean`, then the return of that will be passed to `jar`. How and whether you paramterize your project build is up to you. An example of this is also given in the guide.
  
  == Tools
  
  In addition to the support for builds, the Clojure CLI was enhanced with the ability to explore, install, invoke, and introspect tools based on a set of conventions for tool creators. Installing a new tool such as Sean Corfield's https://github.com/seancorfield/clj-new[clj-new] library is a simple as running the following command:
  
  ```bash
  clj -Ttools install io.github.seancorfield/clj-new '{:git/tag "v1.1.309"}' :as new
  