# Req: Dependency manager for Racket projects

**URL:** <https://racket.discourse.group/t/req-dependency-manager-for-racket-projects/1277>\
**Category:** Show & Tell\
**Created:** [September 4, 2022, 5:46pm UTC](https://racket.discourse.group/t/req-dependency-manager-for-racket-projects/1277 "2022-09-04T17:46:23Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![xgqt](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/xgqt/32/592_2.png) [@xgqt](https://racket.discourse.group/u/xgqt)\
**Post date:** [September 4, 2022, 5:46pm UTC](https://racket.discourse.group/t/req-dependency-manager-for-racket-projects/1277/1 "2022-09-04T17:46:23Z")

</div>

Req is a spiritual successor or Python's `requirement.txt` files, but for Racket.  
The biggest problem with `requirement.txt` was that dependency listing was  
duplicated in that file and `setup.py`'s `install_requires`.  
In Req You list sub-packages of your projects and the dependencies are extracted from `info.rkt` files.  
Also, because we already have a config file we can put it to use and use it as a mini-configuration for other project's areas, so we can list the catalogs the project should use as well as extra dependencies used for repository maintenance.

Req offers a convenient way to manage dependencies of large Racket packages.

Using the raco req command You can, for example:

- install only external dependencies,
- install all local packages at once,
- use a special catalogs repository for the project,
- save the extra packages You use for repository maintenance.

This is the Req-file of Req itself:

```json
{
  "catalogs": [],
  "root": "./src",
  "local": [
    "req*"
  ],
  "dev": [
    "ziptie-monorepo"
  ]
}

```

Going though this config line by line:

- `catalogs` can specify alternative catalogs to be used for external dependency download,  
if it is not set or is an empty list, then the default catalogs are used,
- `root` specifies a root directory to find `local` packages in,
- `local` specifies what are the local packages,  
it takes either a path or a list composed of a path and a package name,  
it also accepts globs (if given a string),  
packages from this section can be installed one-by-one with `--local <pkg-name>`  
or all together with `--locals`,  
so, if I would execute `raco req --locals` Req will install `req`, `req-lib`, `req-doc` and `req-test`  
(because of glob expansion),
- finally any key that is not `catalogs`, `local` nor `root` is treated as a `extras` set,  
it defines a set name and external package associated with this set,  
for example a `dev` set can be defined hat will contain packages uses by project developers,  
to install a specific defined set execute `--extra <set-name>`  
or install all extra sets with `--extras`  
so, if I would execute `raco req --extra dev` the package `ziptie-monorepo` woudl be installed.

Current command line interface:  
`$ raco req -h`

```nohighlight
usage: req [<option> ...]

<option> is one of

/ -s, --show
| Show Req setting of the current project (default action)
| -d, --deps
| Install external dependencies of project's local packages
| -l <local-package-name>, --local <local-package-name>
| Install a local package
| -L, --locals
| Install all local packages
| -a, --all
| Install "deps" and "locals"
| -e <extra-set-name>, --extra <extra-set-name>
| Install an extra set (i.e. dev)
| -E, --extras
| Install all extra sets
| -A, --everything
\ Install "all" and "extras"
  -p <dir-path>, --project <dir-path>
     Path to the project directory
  -f <file-path>, --file <file-path>
     Path to the project's Req file in a supported format
  -v, --verbose
     Be verbose (detailed console output)
  -V, --version
     Show the version of this program and exit
  --help, -h
     Show this help

```

Install Req with raco: `raco pkg install --skip-installed --user req`

Upstream: [Maciej Barć / racket-req · GitLab](https://gitlab.com/xgqt/racket-req)

---

<div class="post-metadata">

**Author:** ![xgqt](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/xgqt/32/592_2.png) [@xgqt](https://racket.discourse.group/u/xgqt)\
**Post date:** [September 4, 2022, 5:49pm UTC](https://racket.discourse.group/t/req-dependency-manager-for-racket-projects/1277/2 "2022-09-04T17:49:26Z")

</div>

Originally the idea was to only accept JSON files but I like the concept of Emacs' Cask [1] too much to let go the idea of defining Req config via RKTD.  
So alternatively, the above JSON file can be represented as:

```scheme
((catalogs ())
 (root ./src)
 (local (req*))
 (dev (ziptie-monorepo)))

```

[1] [GitHub - cask/cask: Project management tool for Emacs](https://github.com/cask/cask)

---

<div class="post-metadata">

**Author:** ![xgqt](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/xgqt/32/592_2.png) [@xgqt](https://racket.discourse.group/u/xgqt)\
**Post date:** [September 4, 2022, 6:00pm UTC](https://racket.discourse.group/t/req-dependency-manager-for-racket-projects/1277/3 "2022-09-04T18:00:50Z")

</div>

I have shown configurations for bigger Racket projects that one could consider mono-repositories,  
but is is also possible to use Req for small packages such as `dirname`:

```json
{
  "local": [
    [".", "dirname"]
  ]
}

```

This is quite nice because the project name is `racket-dirname` so if You would do `raco pkg install` the pkg that will be installed would be named `racket-dirname`.  
The above config is equal to `raco pkg install --name dirname`.  
It is bit more convenient because You do not have to know how the author intended to expose the project package.

Essentially what I'm saying is that all packages with a Req config can be installed with `raco req -A`.

---

<div class="post-metadata">

**Author:** ![xgqt](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/xgqt/32/592_2.png) [@xgqt](https://racket.discourse.group/u/xgqt)\
**Post date:** [September 5, 2022, 10:16am UTC](https://racket.discourse.group/t/req-dependency-manager-for-racket-projects/1277/4 "2022-09-05T10:16:19Z")

</div>

There was recently a bug with pkg-install-command [1] that was fixed but I switched to use custom install commands composed of `pkg/lib` functions [2] for the sake of users not using a snapshot release.

[1] [pkg-catalogs issues with `pkg-install-command` · Issue #4427 · racket/racket · GitHub](https://github.com/racket/racket/issues/4427)  
[2] [req/install.rkt: do not use pkg-install-command nor pkg-remove-command (3e49e1fe) · Commits · Maciej Barć / racket-req · GitLab](https://gitlab.com/xgqt/racket-req/-/commit/3e49e1fe3bd86da91774c548ee7db6a951926790)

---

<div class="post-metadata">

**Author:** ![xgqt](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/xgqt/32/592_2.png) [@xgqt](https://racket.discourse.group/u/xgqt)\
**Post date:** [September 13, 2022, 5:02am UTC](https://racket.discourse.group/t/req-dependency-manager-for-racket-projects/1277/5 "2022-09-13T05:02:32Z")

</div>

Req 2.1.0 released, mainly including better documentation  
[https://xgqt.gitlab.io/racket-req/index.html](https://xgqt.gitlab.io/racket-req/index.html)
