Commit Graph

7374 Commits

Author SHA1 Message Date
Alec Scott
ff26d2f833
spack env track command (#41897)
This PR adds a sub-command to `spack env` (`track`) which allows users to add/link
anonymous environments into their installation as named environments. This allows
users to more easily track their installed packages and the environments they're
dependencies of. For example, with the addition of #41731 it's now easier to remove
all packages not required by any environments with,

```
spack gc -bE
```

#### Usage
```
spack env track /path/to/env
==> Linked environment in /path/to/env
==> You can activate this environment with:
==>     spack env activate env
```

By default `track /path/to/env` will use the last directory in the path as the name of 
the environment. However users may customize the name of the linked environment
with `-n | --name`. Shown below.
```
spack env track /path/to/env --name foo 
==> Tracking environment in /path/to/env
==> You can activate this environment with:
==>     spack env activate foo
```

When removing a linked environment, Spack will remove the link to the environment
but will keep the structure of the environment within the directory. This will allow
users to remove a linked environment from their installation without deleting it from
a shared repository.

There is a `spack env untrack` command that can be used to *only* untrack a tracked
environment -- it will fail if it is used on a managed environment.  Users can also use
`spack env remove` to untrack an environment.

This allows users to continue to share environments in git repositories  while also having
the dependencies of those environments be remembered by Spack.

---------

Co-authored-by: Todd Gamblin <tgamblin@llnl.gov>
2024-11-08 00:16:01 -08:00
Harmen Stoppels
ed916ffe6c Revert "filesystem.py: add max_depth argument to find (#41945)"
This reverts commit 38c8069ab4.
2024-11-07 13:09:10 -08:00
Harmen Stoppels
4fbdf2f2c0 Revert "llnl.util.filesystem.find: restore old error handling (#47463)"
This reverts commit a31c525778.
2024-11-07 13:09:10 -08:00
Harmen Stoppels
60ba61f6b2 Revert "llnl.util.filesystem.find: multiple entrypoints (#47436)"
This reverts commit 73219e4b02.
2024-11-07 13:09:10 -08:00
Harmen Stoppels
0d817878ea
spec.py: fix comparison with multivalued variants (#47485) 2024-11-07 19:29:37 +00:00
Harmen Stoppels
73219e4b02
llnl.util.filesystem.find: multiple entrypoints (#47436)
You can now provide multiple roots to a single `find()` call and all of
them will be searched. The roots can overlap (e.g. can be parents of one
another).

This also adds a library function for taking a set of regular expression
patterns and creating a single OR expression (and that library function
is used in `find` to improve its performance).
2024-11-06 15:22:26 -08:00
Massimiliano Culpo
e62cf9c45b
Fix spack -c <override> when env active (#47403)
Set command line scopes last in _main, so they are higher scopes

Restore the global configuration in a spawned process by inspecting
the result of ctx.get_start_method()

Add the ability to pass a mp.context to PackageInstallContext.

Add shell-tests to check overriding the configuration:
- Using both -c and -C from command line
- With and without an environment active
2024-11-06 17:18:58 +01:00
Harmen Stoppels
d09b185522
Fix various bootstrap/concretizer import issues (#47467) 2024-11-06 14:35:04 +00:00
Harmen Stoppels
a31c525778
llnl.util.filesystem.find: restore old error handling (#47463) 2024-11-06 11:49:14 +01:00
Richarda Butler
0c164d2740
Feature: Allow variants to propagate if not available in source pkg (#42931)
Variants can now be propagated from a dependent package to (transitive) dependencies, 
even if the source or transitive dependencies have the propagated variants.

For example, here `zlib` doesn't have a `guile` variant, but `gmake` does:
```
$ spack spec zlib++guile
 -   zlib@1.3%gcc@12.2.0+optimize+pic+shared build_system=makefile arch=linux-rhel8-broadwell
 -       ^gcc-runtime@12.2.0%gcc@12.2.0 build_system=generic arch=linux-rhel8-broadwell
 -       ^gmake@4.4.1%gcc@12.2.0+guile build_system=generic arch=linux-rhel8-broadwell
```

Adding this property has some strange ramifications for `satisfies()`. In particular:
* The abstract specs `pkg++variant` and `pkg+variant`  do not intersect, because `+variant`
  implies that `pkg` *has* the variant, but `++variant` does not.
* This means that `spec.satisfies("++foo")` is `True` if:
    * for concrete specs: `spec` and its dependencies all have `foo` set if it exists
    * for abstract specs: no dependency of `spec`  has `~foo` (i.e. no dependency contradicts `++foo`).
* This also means that `Spec("++foo").satisfies("+foo")` is `False` -- we only know after concretization.

The `satisfies()` semantics may be surprising, but this is the cost of introducing non-subset
semantics (which are more useful than proper subsets here).

- [x] Change checks for variants
- [x] Resolve conflicts
- [x] Add tests
- [x] Add documentation

---------

Co-authored-by: Gregory Becker <becker33@llnl.gov>
Co-authored-by: Massimiliano Culpo <massimiliano.culpo@gmail.com>
2024-11-06 00:53:52 -08:00
Harmen Stoppels
dadb30f0e2
libc.py: detect glibc also in chinese locale (#47434) 2024-11-05 12:30:32 +01:00
Harmen Stoppels
d45f682573
Revert "Ci generate on change (#47318)" (#47431)
This reverts commit 1462c35761.
2024-11-05 10:51:12 +01:00
Massimiliano Culpo
14bc900e9d
spack.concretize: add type-hints, remove kwargs (#47382)
Also remove find_spec, which was used by the old concretizer.
Currently, it seems to be used only in tests.
2024-11-05 07:46:49 +01:00
Peter Scheibel
38c8069ab4
filesystem.py: add max_depth argument to find (#41945)
* `find(..., max_depth=...)` can be used to control how many directories at most to descend into below the starting point
* `find` now enters every unique (symlinked) directory once at the lowest depth
* `find` is now repeatable: it traverses the directory tree in a deterministic order
2024-11-04 20:31:57 +01:00
Todd Gamblin
5cc07522ab cc: parse RPATHs when in ld mode
In the pure `ld` case, we weren't actually parsing `RPATH` arguments separately as we
do for `ccld`. Fix this by adding *another* nested case statement for raw `RPATH`
parsing.

There are now 3 places where we deal with `-rpath` and friends, but I don't see a great
way to unify them, as `-Wl,`, `-Xlinker`, and raw `-rpath` arguments are all ever so
slightly different.

Also, this Fixes ordering of assertions to make `pytest` diffs more intelligible.
The meaning of `+` and `-` in diffs changed in `pytest` 6.0 and the "preferred" order
for assertions became `assert actual == expected` instead of the other way around.

Signed-off-by: Todd Gamblin <tgamblin@llnl.gov>
2024-11-04 19:52:08 +01:00
Todd Gamblin
575a006ca3 cc: simplify ordered list handling
`cc` divides most paths up into system paths, spack managed paths, and other paths.
This gets really repetitive and makes the code hard to read. Simplify the script
by adding some functions to do most of the redundant work for us.

Signed-off-by: Todd Gamblin <tgamblin@llnl.gov>
2024-11-04 19:52:08 +01:00
John Gouwar
23ac56edfb
Times spec building and timing to public concretizer API (#47310)
This PR has two small contributions:
- It adds another phase to the timer for concrectization, "construct_specs", to actually see the time the concretizer spends interpreting the `clingo` output to build the Python object for a concretized spec. 
- It adds the method `Solver.solve_with_stats` to expose the timers that were already in the concretizer to the public solver API. `Solver.solve` just becomes a special case of `Solver.solve_with_stats` that throws away the timing output (which is what it was already doing).  

These changes will make it easier to benchmark concretizer performance and provide a more complete picture of the time spent in the concretizer by including the time spent interpreting clingo output.
2024-11-04 09:48:18 -08:00
Harmen Stoppels
8d0856d1cc
packaging_guide.rst: explain forward and backward compat before the less common cases (#47402)
The idea is to go from most to least used: backward compat -> forward compat -> pinning on major or major.minor version -> pinning specific, concrete versions.

Further, the following

```python
   # backward compatibility with Python
   depends_on("python@3.8:")
   depends_on("python@3.9:", when="@1.2:")
   depends_on("python@3.10:", when="@1.4:")

   # forward compatibility with Python
   depends_on("python@:3.12", when="@:1.10")
   depends_on("python@:3.13", when="@:1.12")
   depends_on("python@:3.14")
```

is better than disjoint when ranges causing repetition of the rules on dependencies, and requiring frequent editing of existing lines after new releases are done:

```python
   depends_on("python@3.8:3.12", when="@:1.1")
   depends_on("python@3.9:3.12", when="@1.2:1.3")
   depends_on("python@3.10:3.12", when="@1.4:1.10")
   depends_on("python@3.10:3.13", when="@1.11:1.12")
   depends_on("python@3.10:3.14", when="@1.13:")
2024-11-04 13:52:05 +01:00
Massimiliano Culpo
395c911689
Specs: propagated variants affect == equality (#47376)
This PR changes the semantic of == for spec so that:

hdf5++mpi == hdf5+mpi

won't hold true anymore. It also changes the constrain semantic, so that a
non-propagating variant always override a propagating variant. This means:

(hdf5++mpi).constrain(hdf5+mpi) -> hdf5+mpi

Before we had a very weird semantic, that was supposed to be tested by unit-tests:

(libelf++debug).constrain(libelf+debug+foo) -> libelf++debug++foo

This semantic has been dropped, as it was never really tested due to the == bug.
2024-11-03 22:35:16 -08:00
Tamara Dahlgren
b8461f3d2d
Remove ignored config:install_missing_compilers from unit tests (#47357) 2024-11-02 09:36:05 +01:00
Massimiliano Culpo
133895e785
Rework the schema for reusing environments (#47364)
Currently, the schema reads:

  from:
    - type:
        environment: path_or_name

but this can't be extended easily to other types, e.g. to buildcaches,
without duplicating the extension keys. Use instead:

  from:
    - type: environment
      path: path_or_name
2024-11-02 09:03:42 +01:00
dependabot[bot]
19e3ab83cf
build(deps): bump python-levenshtein in /lib/spack/docs (#47372)
Bumps [python-levenshtein](https://github.com/rapidfuzz/python-Levenshtein) from 0.26.0 to 0.26.1.
- [Release notes](https://github.com/rapidfuzz/python-Levenshtein/releases)
- [Changelog](https://github.com/rapidfuzz/python-Levenshtein/blob/main/HISTORY.md)
- [Commits](https://github.com/rapidfuzz/python-Levenshtein/compare/v0.26.0...v0.26.1)

---
updated-dependencies:
- dependency-name: python-levenshtein
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-11-01 23:55:18 +00:00
Greg Becker
e42a4a8bac
parse_specs: unify specs based on concretizer:unify (#44843)
Currently, the `concretizer:unify:` config option only affects environments.

With this PR, it now affects any group of specs given to a command using the `parse_specs(*, concretize=True)` interface.

- [x] implementation in `parse_specs`
- [x] tests
- [x] ensure all commands that accept multiple specs and concretize use `parse_specs` interface

---------

Co-authored-by: Todd Gamblin <tgamblin@llnl.gov>
Signed-off-by: Todd Gamblin <tgamblin@llnl.gov>
2024-11-01 23:49:26 +00:00
kwryankrattiger
1462c35761
Ci generate on change (#47318)
* don't concretize in CI if changed packages are not in stacks

Signed-off-by: Todd Gamblin <tgamblin@llnl.gov>

* Generate noop job when no specs to rebuild due to untouched pruning

* Add test to verify skipping generate creates a noop job

* Changed debug for early exit

---------

Signed-off-by: Todd Gamblin <tgamblin@llnl.gov>
Co-authored-by: Todd Gamblin <tgamblin@llnl.gov>
2024-11-01 22:07:23 +00:00
Massimiliano Culpo
0cf8cb70f4
Fix pickle round-trip of specs propagating variants (#47351)
This changes `Spec` serialization to include information about propagation for abstract specs.
This was previously not included in the JSON representation for abstract specs, and couldn't be
stored.

Now, there is a separate `propagate` dictionary alongside the `parameters` dictionary. This isn't
beautiful, but when we bump the spec version for Spack `v0.24`, we can clean up this and other
aspects of the schema.
2024-11-01 13:43:16 -07:00
dependabot[bot]
5df7dc88fc
build(deps): bump docutils from 0.20.1 to 0.21.2 in /lib/spack/docs (#45592)
Bumps [docutils](https://docutils.sourceforge.io) from 0.20.1 to 0.21.2.

---
updated-dependencies:
- dependency-name: docutils
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-11-01 06:23:10 -05:00
Harmen Stoppels
e3aca49e25
database.py: remove process unsafe update_explicit (#47358)
Fixes an issue reported where `spack env depfile` + `make -j` would
non-deterministically refuse to mark all environment roots explicit.

`update_explicit` had the pattern

```python
rec = self._data[key]
with self.write_transaction():
    rec.explicit = explicit
```

but `write_transaction` may reinitialize `self._data`, meaning that
mutating `rec` won't mutate `self._data`, and the changes won't be
persisted.

Instead, use `mark` which has a correct implementation.

Also avoids the essentially incorrect early return in `update_explicit`
which is a pattern I don't think belongs in database.py: it branches on
possibly stale data to realize there is nothing to change, but in reality
it requires a write transaction to know that for a fact, but that would
defeat the purpose. So, leave this optimization to the call site.
2024-10-31 13:58:42 -07:00
kwryankrattiger
0c00a297e1
Concretize reuse: reuse specs from environment (#45139)
The already concrete specs in an environment are now among the reusable specs for the concretizer.

This includes concrete specs from all include_concrete environments.

In addition to this change to the default reuse, `environment` is added as a reuse type for 
the concretizer config. This allows users to specify:

spack:
  concretizer:
    # Reuse from this environment (including included concrete) but not elsewhere
    reuse:
      from:
      - type: environment
    # or reuse from only my_env included environment
    reuse:
      from:
      - type:
          environment: my_env
    # or reuse from everywhere
    reuse: true

If reuse is specified from a specific environment, only specs from that environment will be reused.
If the reused environment is not specified via include_concrete, the concrete specs will be retried
at concretization time to be reused.

Signed-off-by: Ryan Krattiger <ryan.krattiger@kitware.com>
Co-authored-by: Gregory Becker <becker33@llnl.gov>
2024-10-31 10:31:34 -07:00
Adam J. Stewart
6ab92b119d
Docs: remove reference to pyspack (#47346) 2024-10-31 11:15:51 +01:00
Harmen Stoppels
c3435b4e7d
hooks: run in clear, fixed order (#47329)
Currently the order in which hooks are run is arbitrary.

This can be fixed by sorted(list_modules(...)) but I think it is much
more clear to just have a static list.

Hooks are not extensible other than modifying Spack code, which
means it's unlikely people maintain custom hooks since they'd have
to fork Spack. And if they fork Spack, they might as well add an entry
to the list when they're continuously rebasing.
2024-10-30 18:57:49 +00:00
Harmen Stoppels
8892c878ce
types: remove singleton union in globals (#47282) 2024-10-30 13:48:32 +01:00
Harmen Stoppels
cbf4d3967a
add std_pip_args global to the audit list (#47320) 2024-10-30 13:14:15 +01:00
Harmen Stoppels
8bc0b2e086
Spec.__str__: use full hash (#47322)
The idea is that `spack -e env add ./concrete-spec.json` would list the
full hash in the specs, so that (a) it's not ambiguous and (b) it could
in principle results in constant time lookup instead of linear time
substring match in large build caches.
2024-10-30 12:44:51 +01:00
Massimiliano Culpo
354615d491
Spec.dependencies: allow to filter on virtuals (#47284)
Signed-off-by: Massimiliano Culpo <massimiliano.culpo@gmail.com>
2024-10-30 12:15:01 +01:00
Alex Hedges
34b2f28a5e
Fix malformed RST link in documentation (#47309) 2024-10-30 09:40:35 +01:00
Massimiliano Culpo
b8e3246e89
llnl.util.lang: add classes to help with deprecations (#47279)
* Add a descriptor to have a class level constant

This descriptor helps intercept places where we set a value on instances.
It does not really behave like "const" in C-like languages, but is the
simplest implementation that might still be useful.

* Add a descriptor to deprecate properties/attributes of an object

This descriptor is used as a base class. Derived classes may implement a
factory to return an adaptor to the attribute being deprecated. The
descriptor can either warn, or raise an error, when usage of the deprecated
attribute is intercepted.

---------

Co-authored-by: Harmen Stoppels <me@harmenstoppels.nl>
2024-10-29 19:06:26 +01:00
Harmen Stoppels
ea1aa0714b
bootstrap: do not consider source when metadata file missing (#47278) 2024-10-29 10:57:31 +01:00
Harmen Stoppels
7af1a3d240
std_meson_args: deprecate (#47259) 2024-10-29 07:54:28 +01:00
Harmen Stoppels
962115b386
builder.py: builder_cls should be associated to spack.pkg module (#47269) 2024-10-29 07:53:06 +01:00
Harmen Stoppels
f81ca0cd89
directives_meta.py: use startswith to test module part of spack.pkg (#47270) 2024-10-29 07:51:36 +01:00
Greg Becker
e81ce18cad
cmd/solve: use interface from cmd/spec (#47182)
Currently, `spack solve` has different spec selection semantics than `spack spec`.
`spack solve` currently does not allow specifying a single spec when an environment is active.

This PR modifies `spack solve` to inherit the interface from `spack spec`, and to use
the same spec selection logic. This will allow for better use of `spack solve --show opt`
for debugging.

---------

Co-authored-by: Todd Gamblin <tgamblin@llnl.gov>
2024-10-28 19:28:03 -07:00
Harmen Stoppels
2ec4281c4f
Remove a few redundant imports (#47250)
* remove self-imports

* remove unused imports
2024-10-27 15:40:05 -06:00
Greg Becker
47e70c5c3a
explicit splice: do not fail for bad config replacement if target not matched (#46925)
Originally, concretization failed if the splice config points to an invalid replacement.

This PR defers the check until we know the splice is needed, so that irrelevant splices
with bad config cannot stop concretization.

While I was at it, I improved an error message from an assert to a ValueError.
2024-10-27 11:35:10 -07:00
Todd Gamblin
c8bebff7f5
Add -t short option for spack --backtrace (#47227)
Signed-off-by: Todd Gamblin <tgamblin@llnl.gov>
2024-10-26 09:16:31 +02:00
John W. Parent
7b27aed4c8
Normalize Spack Win entry points (#38648)
* Normalize Spack Win entrypoints

Currently Spack has multiple entrypoints on Windows that in addition to
differing from *nix implementations, differ from shell to shell on
Windows. This is a bit confusing for new users and in general
unnecessary.
This PR adds a normal setup script for the batch shell while preserving
the previous "click from file explorer for spack shell" behavior.
Additionally adds a shell title to both powershell and cmd letting users
know this is a Spack shell

* remove doskeys
2024-10-25 15:23:29 -04:00
Dom Heinzeller
ad0b256407
Intel/Oneapi compilers: suppress warnings when using Cray wrappers (#47046)
#44588 we added logic to suppress deprecation warnings for the
Intel classic compilers. This depended on matching against 

* The compiler names (looking for icc, icpc, ifort)
* The compiler version

When using an Intel compiler with fortran wrappers, the first check
always fails. To support using the fortran wrappers (in combination
with the classic Intel compilers), we remove the first check and
suppress if just the version matches. This works because:

* The newer compilers like icx can handle (ignore) the flags that
  suppress deprecation warnings
* The Cray wrappers pass the underlying compiler version (e.g. they
  report what icc would report)
2024-10-25 12:17:49 -07:00
Harmen Stoppels
7d86670826 ensure write_fd.close() isn't called when sys.std* cannot be redirected 2024-10-25 10:16:44 -07:00
Harmen Stoppels
ae306b73c3 Avoid a socket to communicate effectively a bit 2024-10-25 10:16:44 -07:00
Harmen Stoppels
b63cbe4e6e Replace MultiProcessFd with Connection objects
Connection objects are Python version, platform and multiprocessing
start method independent, so better to use those than a mix of plain
file descriptors and inadequate guesses in the child process whether it
was forked or not.

This also allows us to delete the now redundant MultiProcessFd class,
hopefully making things a bit easier to follow.
2024-10-25 10:16:44 -07:00
Harmen Stoppels
e86a3b68f7
file_cache.py: allow read transaction on uninitialized cache (#47212)
This allows the following

```python
cache.init_entry("my/cache")
with cache.read_transaction("my/cache") as f:
    data = f.read() if f is not None else None
```

mirroring `write_transaction`, which returns a tuple `(old, new)` where
`old` is `None` if the cache file did not exist yet.

The alternative that requires less defensive programming on the call
site would be to create the "old" file upon first read, but I did not
want to think about how to safely atomically create the file, and it's
not unthinkable that an empty file is an invalid format (for instance
the call site may expect a json file, which requires at least {} bytes).
2024-10-25 17:10:14 +02:00