Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,15 @@ All notable changes to this project are documented here.

### Added

- `stack order --installed` stops the build order at modules already on
the machine. A file is a module listing and a directory is an Lmod
tree, read the same way as `stack gap --installed`. The version is the
full module version. A listed module is left out of the order, and so
are the dependencies that were installed with it. `--filter-deps`
still drops dependencies first. The modules that remain are chosen
with the synthetic GCC-family rule `recipe hierarchy --export`
prints. Stdout reports `installed=` as how many modules the walk
stopped at. `eb_stack_order` takes the same `installed` list.
- `stack shadow` reports a site-layer recipe that shadows a module the
EESSI base stack already provides. `--base` is an Lmod tree or a module
listing, loaded with the same inventory reader as `stack gap`. The same
Expand Down
19 changes: 19 additions & 0 deletions docs/orgmode/howto/solve-lock.org
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,25 @@ eb-stack stack order \
requirement. The hash file is one ~<sha256> <module>~ line per build.
See [[file:../reference/cli.org][the CLI reference]].

~--installed~ stops the walk at modules the site already has, the way
the robot does. ~--filter-deps~ still drops dependencies before that
walk. The two compose: a filtered dependency is gone, and a listed
module is a leaf whose own dependencies are not ordered.

#+begin_src bash
eb-stack stack order \
--easyconfigs fixtures/gromacs_2025_to_next/easyconfigs \
--root GROMACS \
--installed fixtures/stack_order_installed/installed.txt \
--filter-deps FFTW \
--out /tmp/build-order.txt
#+end_src

The order file has no ~OpenBLAS~ path and no ~FFTW~ path. ~GROMACS~ is
still in it. Standard output ends with ~installed=1~ and then
~order=/tmp/build-order.txt builds=~. ~installed=1~ is OpenBLAS. FFTW
was filtered, so it is not a leaf the walk stopped at.

* One lock per toolchain family

A foss solve only sees the foss hierarchy.
Expand Down
22 changes: 20 additions & 2 deletions docs/orgmode/reference/cli.org
Original file line number Diff line number Diff line change
Expand Up @@ -432,6 +432,7 @@ eb-stack stack order \
--easyconfigs TREE [--easyconfigs OVERLAY]... \
--root NAME [--root NAME==VERSION]... \
[--filter-deps NAME,NAME...] \
[--installed LIST]... \
[--out /tmp/build-order.txt] \
[--oldest] \
[--easystack-out /tmp/order.yml] \
Expand Down Expand Up @@ -644,7 +645,20 @@ not repin a recipe. See [[file:../howto/solve-lock.org][Order every pinned build
~name==version~ pins one build. ~--filter-deps~ drops each named
dependency before that order is built, together with the subtree under
it, using the same matching as ~stack solve~; when the flag is absent
the command reads ~EASYBUILD_FILTER_DEPS~. ~--oldest~ takes the oldest
the command reads ~EASYBUILD_FILTER_DEPS~. ~--installed~ repeats. A file
is ~module -t avail~, ~module spider -t~, or ~Name/version~, and a
directory is an Lmod tree, both read the same way as
~stack gap --installed~. The version is the full module version,
~1.3.1-GCCcore-15.2.0~, the spelling under ~modules/all~. A system
toolchain contributes no toolchain segment. A listed module is a leaf:
it stays out of the order, and so do the dependencies that were
installed with it. A dependency the tree cannot resolve is still an
error. The walk that remains uses the synthetic GCC-family rule
~recipe hierarchy --export~ prints, so an unpinned dependency of a
~GCC~ or ~GCCcore~ recipe stays in that family. ~--filter-deps~ is
applied first, so a filtered dependency is not counted as a leaf. The
line ~installed=<N>~ just before ~order=~ is how many distinct modules
the walk stopped at. ~--oldest~ takes the oldest
admissible version of an unpinned requirement, and the default is the
newest. ~--out~ is one easyconfig path per line (default
~build-order.txt~). ~--easystack-out~ writes that same sequence as an
Expand Down Expand Up @@ -1792,8 +1806,12 @@ table and the derived-key rules. ~eb_recipe_hierarchy~ takes ~export~.
The plain call prints the fixture generations. ~export~ true adds the
synthetic GCC-family rule, the same split as ~recipe hierarchy --export~.
~eb_stack_order~ requires ~easyconfigs~ and ~root~, and takes ~out~,
~oldest~, ~easystack_out~, ~hashes_out~, and ~filter_deps~.
~oldest~, ~easystack_out~, ~hashes_out~, ~filter_deps~, and ~installed~.
~filter_deps~ drops the same dependencies ~--filter-deps~ drops.
~installed~ is the module list or Lmod tree ~--installed~ reads. A
module it names is left out of the order. The result field ~installed~
is how many modules the walk stopped at, and is null when the argument
is omitted.
~eb_stack_easystack~ requires ~lock~ and takes ~out~ and ~option~, each
option a ~<file.eb>:<option>=<value>~ string, and ~eessi_version~,
~easybuild_version~, ~generation~, and ~out_dir~ for the software-layer
Expand Down
9 changes: 6 additions & 3 deletions docs/orgmode/reference/formats.org
Original file line number Diff line number Diff line change
Expand Up @@ -219,16 +219,19 @@ solver selection, not a scan of installed software.

One easyconfig path per line, in dependency order. A name EasyBuild
installs twice lists both paths: another toolchain, a system bootstrap
pair, or a build-only tool. ~--oldest~ changes which unpinned version is
chosen; it does not change the file shape. When runtime requirements of
pair, or a build-only tool. ~--installed~ leaves a listed module, and
the dependencies that were installed with it, out of this file.
~--oldest~ changes which unpinned version is chosen; it does not change
the file shape. When runtime requirements of
one name at one toolchain have no version that satisfies every one of
them, the command writes no file and exits 1. Standard error names each
requester and the version it resolved. The file is not a place where a
pin is rewritten.

Stdout names a co-installable repeated build as
~multiple builds of <name>: <ver-tc>, ...~ and ends with
~order=<path> builds=<N>~.
~order=<path> builds=<N>~. When ~--installed~ is set, the line before
that is ~installed=<N>~, how many listed modules the walk stopped at.

* Input hashes (~--hashes-out~)

Expand Down
2 changes: 2 additions & 0 deletions fixtures/stack_order_installed/installed.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# OpenBLAS is already installed. The version is the full module version.
OpenBLAS/0.3.27-foss-2025b
50 changes: 45 additions & 5 deletions llms-full.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1877,6 +1877,25 @@ eb-stack stack order \
requirement. The hash file is one `<sha256> <module>` line per build.
See [the CLI reference](https://eb-stack.rgoswami.me/../reference/cli.html.md).

`--installed` stops the walk at modules the site already has, the way
the robot does. `--filter-deps` still drops dependencies before that
walk. The two compose: a filtered dependency is gone, and a listed
module is a leaf whose own dependencies are not ordered.

```bash
eb-stack stack order \
--easyconfigs fixtures/gromacs_2025_to_next/easyconfigs \
--root GROMACS \
--installed fixtures/stack_order_installed/installed.txt \
--filter-deps FFTW \
--out /tmp/build-order.txt
```

The order file has no `OpenBLAS` path and no `FFTW` path. `GROMACS` is
still in it. Standard output ends with `installed=1` and then
`order=/tmp/build-order.txt builds=`. `installed=1` is OpenBLAS. FFTW
was filtered, so it is not a leaf the walk stopped at.

# One lock per toolchain family

A foss solve only sees the foss hierarchy.
Expand Down Expand Up @@ -6534,6 +6553,7 @@ eb-stack stack order \
--easyconfigs TREE [--easyconfigs OVERLAY]... \
--root NAME [--root NAME==VERSION]... \
[--filter-deps NAME,NAME...] \
[--installed LIST]... \
[--out /tmp/build-order.txt] \
[--oldest] \
[--easystack-out /tmp/order.yml] \
Expand Down Expand Up @@ -6746,7 +6766,20 @@ not repin a recipe. See [Order every pinned build](https://eb-stack.rgoswami.me/
`name==version` pins one build. `--filter-deps` drops each named
dependency before that order is built, together with the subtree under
it, using the same matching as `stack solve`; when the flag is absent
the command reads `EASYBUILD_FILTER_DEPS`. `--oldest` takes the oldest
the command reads `EASYBUILD_FILTER_DEPS`. `--installed` repeats. A file
is `module -t avail`, `module spider -t`, or `Name/version`, and a
directory is an Lmod tree, both read the same way as
`stack gap --installed`. The version is the full module version,
`1.3.1-GCCcore-15.2.0`, the spelling under `modules/all`. A system
toolchain contributes no toolchain segment. A listed module is a leaf:
it stays out of the order, and so do the dependencies that were
installed with it. A dependency the tree cannot resolve is still an
error. The walk that remains uses the synthetic GCC-family rule
`recipe hierarchy --export` prints, so an unpinned dependency of a
`GCC` or `GCCcore` recipe stays in that family. `--filter-deps` is
applied first, so a filtered dependency is not counted as a leaf. The
line `installed=<N>` just before `order=` is how many distinct modules
the walk stopped at. `--oldest` takes the oldest
admissible version of an unpinned requirement, and the default is the
newest. `--out` is one easyconfig path per line (default
`build-order.txt`). `--easystack-out` writes that same sequence as an
Expand Down Expand Up @@ -7894,8 +7927,12 @@ table and the derived-key rules. `eb_recipe_hierarchy` takes `export`.
The plain call prints the fixture generations. `export` true adds the
synthetic GCC-family rule, the same split as `recipe hierarchy --export`.
`eb_stack_order` requires `easyconfigs` and `root`, and takes `out`,
`oldest`, `easystack_out`, `hashes_out`, and `filter_deps`.
`oldest`, `easystack_out`, `hashes_out`, `filter_deps`, and `installed`.
`filter_deps` drops the same dependencies `--filter-deps` drops.
`installed` is the module list or Lmod tree `--installed` reads. A
module it names is left out of the order. The result field `installed`
is how many modules the walk stopped at, and is null when the argument
is omitted.
`eb_stack_easystack` requires `lock` and takes `out` and `option`, each
option a `<file.eb>:<option>=<value>` string, and `eessi_version`,
`easybuild_version`, `generation`, and `out_dir` for the software-layer
Expand Down Expand Up @@ -9239,16 +9276,19 @@ solver selection, not a scan of installed software.

One easyconfig path per line, in dependency order. A name EasyBuild
installs twice lists both paths: another toolchain, a system bootstrap
pair, or a build-only tool. `--oldest` changes which unpinned version is
chosen; it does not change the file shape. When runtime requirements of
pair, or a build-only tool. `--installed` leaves a listed module, and
the dependencies that were installed with it, out of this file.
`--oldest` changes which unpinned version is chosen; it does not change
the file shape. When runtime requirements of
one name at one toolchain have no version that satisfies every one of
them, the command writes no file and exits 1. Standard error names each
requester and the version it resolved. The file is not a place where a
pin is rewritten.

Stdout names a co-installable repeated build as
`multiple builds of <name>: <ver-tc>, ...` and ends with
`order=<path> builds=<N>`.
`order=<path> builds=<N>`. When `--installed` is set, the line before
that is `installed=<N>`, how many listed modules the walk stopped at.

# Input hashes (`--hashes-out`)

Expand Down
Loading
Loading