Compare commits
2 Commits
develop-20
...
hs/ci/regr
Author | SHA1 | Date | |
---|---|---|---|
![]() |
6c5711e7b6 | ||
![]() |
f772d97865 |
74
.github/workflows/audit.yaml
vendored
74
.github/workflows/audit.yaml
vendored
@@ -1,74 +0,0 @@
|
||||
name: audit
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
inputs:
|
||||
with_coverage:
|
||||
required: true
|
||||
type: string
|
||||
python_version:
|
||||
required: true
|
||||
type: string
|
||||
|
||||
concurrency:
|
||||
group: audit-${{inputs.python_version}}-${{github.ref}}-${{github.event.pull_request.number || github.run_number}}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
# Run audits on all the packages in the built-in repository
|
||||
package-audits:
|
||||
runs-on: ${{ matrix.system.os }}
|
||||
strategy:
|
||||
matrix:
|
||||
system:
|
||||
- { os: windows-latest, shell: 'powershell Invoke-Expression -Command "./share/spack/qa/windows_test_setup.ps1"; {0}' }
|
||||
- { os: ubuntu-latest, shell: bash }
|
||||
- { os: macos-latest, shell: bash }
|
||||
defaults:
|
||||
run:
|
||||
shell: ${{ matrix.system.shell }}
|
||||
steps:
|
||||
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332
|
||||
- uses: actions/setup-python@f677139bbe7f9c59b41e40162b753c062f5d49a3
|
||||
with:
|
||||
python-version: ${{inputs.python_version}}
|
||||
- name: Install Python packages
|
||||
run: |
|
||||
pip install --upgrade pip setuptools pytest coverage[toml]
|
||||
- name: Setup for Windows run
|
||||
if: runner.os == 'Windows'
|
||||
run: |
|
||||
python -m pip install --upgrade pywin32
|
||||
- name: Package audits (with coverage)
|
||||
env:
|
||||
COVERAGE_FILE: coverage/.coverage-audits-${{ matrix.system.os }}
|
||||
if: ${{ inputs.with_coverage == 'true' && runner.os != 'Windows' }}
|
||||
run: |
|
||||
. share/spack/setup-env.sh
|
||||
coverage run $(which spack) audit packages
|
||||
coverage run $(which spack) audit configs
|
||||
coverage run $(which spack) -d audit externals
|
||||
coverage combine
|
||||
- name: Package audits (without coverage)
|
||||
if: ${{ inputs.with_coverage == 'false' && runner.os != 'Windows' }}
|
||||
run: |
|
||||
. share/spack/setup-env.sh
|
||||
spack -d audit packages
|
||||
spack -d audit configs
|
||||
spack -d audit externals
|
||||
- name: Package audits (without coverage)
|
||||
if: ${{ runner.os == 'Windows' }}
|
||||
run: |
|
||||
. share/spack/setup-env.sh
|
||||
spack -d audit packages
|
||||
./share/spack/qa/validate_last_exit.ps1
|
||||
spack -d audit configs
|
||||
./share/spack/qa/validate_last_exit.ps1
|
||||
spack -d audit externals
|
||||
./share/spack/qa/validate_last_exit.ps1
|
||||
- uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874
|
||||
if: ${{ inputs.with_coverage == 'true' && runner.os != 'Windows' }}
|
||||
with:
|
||||
name: coverage-audits-${{ matrix.system.os }}
|
||||
path: coverage
|
||||
include-hidden-files: true
|
201
.github/workflows/bootstrap.yml
vendored
201
.github/workflows/bootstrap.yml
vendored
@@ -1,201 +0,0 @@
|
||||
name: Bootstrapping
|
||||
|
||||
on:
|
||||
# This Workflow can be triggered manually
|
||||
workflow_dispatch:
|
||||
workflow_call:
|
||||
schedule:
|
||||
# nightly at 2:16 AM
|
||||
- cron: '16 2 * * *'
|
||||
|
||||
concurrency:
|
||||
group: bootstrap-${{github.ref}}-${{github.event.pull_request.number || github.run_number}}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
distros-clingo-sources:
|
||||
runs-on: ubuntu-latest
|
||||
container: ${{ matrix.image }}
|
||||
strategy:
|
||||
matrix:
|
||||
image: ["fedora:latest", "opensuse/leap:latest"]
|
||||
steps:
|
||||
- name: Setup Fedora
|
||||
if: ${{ matrix.image == 'fedora:latest' }}
|
||||
run: |
|
||||
dnf install -y \
|
||||
bzip2 curl file gcc-c++ gcc gcc-gfortran git gzip \
|
||||
make patch unzip which xz python3 python3-devel tree \
|
||||
cmake bison bison-devel libstdc++-static
|
||||
- name: Setup OpenSUSE
|
||||
if: ${{ matrix.image == 'opensuse/leap:latest' }}
|
||||
run: |
|
||||
# Harden CI by applying the workaround described here: https://www.suse.com/support/kb/doc/?id=000019505
|
||||
zypper update -y || zypper update -y
|
||||
zypper install -y \
|
||||
bzip2 curl file gcc-c++ gcc gcc-fortran tar git gpg2 gzip \
|
||||
make patch unzip which xz python3 python3-devel tree \
|
||||
cmake bison
|
||||
- name: Checkout
|
||||
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Bootstrap clingo
|
||||
run: |
|
||||
source share/spack/setup-env.sh
|
||||
spack bootstrap disable github-actions-v0.5
|
||||
spack bootstrap disable github-actions-v0.4
|
||||
spack external find cmake bison
|
||||
spack -d solve zlib
|
||||
tree ~/.spack/bootstrap/store/
|
||||
|
||||
clingo-sources:
|
||||
runs-on: ${{ matrix.runner }}
|
||||
strategy:
|
||||
matrix:
|
||||
runner: ['macos-13', 'macos-14', "ubuntu-latest", "windows-latest"]
|
||||
steps:
|
||||
- name: Setup macOS
|
||||
if: ${{ matrix.runner != 'ubuntu-latest' && matrix.runner != 'windows-latest' }}
|
||||
run: |
|
||||
brew install cmake bison tree
|
||||
- name: Checkout
|
||||
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- uses: actions/setup-python@f677139bbe7f9c59b41e40162b753c062f5d49a3
|
||||
with:
|
||||
python-version: "3.12"
|
||||
- name: Bootstrap clingo
|
||||
env:
|
||||
SETUP_SCRIPT_EXT: ${{ matrix.runner == 'windows-latest' && 'ps1' || 'sh' }}
|
||||
SETUP_SCRIPT_SOURCE: ${{ matrix.runner == 'windows-latest' && './' || 'source ' }}
|
||||
USER_SCOPE_PARENT_DIR: ${{ matrix.runner == 'windows-latest' && '$env:userprofile' || '$HOME' }}
|
||||
VALIDATE_LAST_EXIT: ${{ matrix.runner == 'windows-latest' && './share/spack/qa/validate_last_exit.ps1' || '' }}
|
||||
run: |
|
||||
${{ env.SETUP_SCRIPT_SOURCE }}share/spack/setup-env.${{ env.SETUP_SCRIPT_EXT }}
|
||||
spack bootstrap disable github-actions-v0.5
|
||||
spack bootstrap disable github-actions-v0.4
|
||||
spack external find --not-buildable cmake bison
|
||||
spack -d solve zlib
|
||||
${{ env.VALIDATE_LAST_EXIT }}
|
||||
tree ${{ env.USER_SCOPE_PARENT_DIR }}/.spack/bootstrap/store/
|
||||
|
||||
gnupg-sources:
|
||||
runs-on: ${{ matrix.runner }}
|
||||
strategy:
|
||||
matrix:
|
||||
runner: [ 'macos-13', 'macos-14', "ubuntu-latest" ]
|
||||
steps:
|
||||
- name: Setup macOS
|
||||
if: ${{ matrix.runner != 'ubuntu-latest' }}
|
||||
run: |
|
||||
brew install tree gawk
|
||||
sudo rm -rf $(command -v gpg gpg2)
|
||||
- name: Setup Ubuntu
|
||||
if: ${{ matrix.runner == 'ubuntu-latest' }}
|
||||
run: sudo rm -rf $(command -v gpg gpg2 patchelf)
|
||||
- name: Checkout
|
||||
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Bootstrap GnuPG
|
||||
run: |
|
||||
source share/spack/setup-env.sh
|
||||
spack solve zlib
|
||||
spack bootstrap disable github-actions-v0.5
|
||||
spack bootstrap disable github-actions-v0.4
|
||||
spack -d gpg list
|
||||
tree ~/.spack/bootstrap/store/
|
||||
|
||||
from-binaries:
|
||||
runs-on: ${{ matrix.runner }}
|
||||
strategy:
|
||||
matrix:
|
||||
runner: ['macos-13', 'macos-14', "ubuntu-latest", "windows-latest"]
|
||||
steps:
|
||||
- name: Setup macOS
|
||||
if: ${{ matrix.runner != 'ubuntu-latest' && matrix.runner != 'windows-latest'}}
|
||||
run: |
|
||||
brew install tree
|
||||
# Remove GnuPG since we want to bootstrap it
|
||||
sudo rm -rf /usr/local/bin/gpg
|
||||
- name: Setup Ubuntu
|
||||
if: ${{ matrix.runner == 'ubuntu-latest' }}
|
||||
run: |
|
||||
sudo rm -rf $(which gpg) $(which gpg2) $(which patchelf)
|
||||
- name: Setup Windows
|
||||
if: ${{ matrix.runner == 'windows-latest' }}
|
||||
run: |
|
||||
Remove-Item -Path (Get-Command gpg).Path
|
||||
Remove-Item -Path (Get-Command file).Path
|
||||
- name: Checkout
|
||||
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- uses: actions/setup-python@f677139bbe7f9c59b41e40162b753c062f5d49a3
|
||||
with:
|
||||
python-version: |
|
||||
3.8
|
||||
3.9
|
||||
3.10
|
||||
3.11
|
||||
3.12
|
||||
- name: Set bootstrap sources
|
||||
env:
|
||||
SETUP_SCRIPT_EXT: ${{ matrix.runner == 'windows-latest' && 'ps1' || 'sh' }}
|
||||
SETUP_SCRIPT_SOURCE: ${{ matrix.runner == 'windows-latest' && './' || 'source ' }}
|
||||
run: |
|
||||
${{ env.SETUP_SCRIPT_SOURCE }}share/spack/setup-env.${{ env.SETUP_SCRIPT_EXT }}
|
||||
spack bootstrap disable github-actions-v0.4
|
||||
- name: Disable from source bootstrap
|
||||
if: ${{ matrix.runner != 'windows-latest' }}
|
||||
run: |
|
||||
source share/spack/setup-env.sh
|
||||
spack bootstrap disable spack-install
|
||||
- name: Bootstrap clingo
|
||||
# No binary clingo on Windows yet
|
||||
if: ${{ matrix.runner != 'windows-latest' }}
|
||||
run: |
|
||||
set -e
|
||||
for ver in '3.8' '3.9' '3.10' '3.11' '3.12' ; do
|
||||
not_found=1
|
||||
ver_dir="$(find $RUNNER_TOOL_CACHE/Python -wholename "*/${ver}.*/*/bin" | grep . || true)"
|
||||
if [[ -d "$ver_dir" ]] ; then
|
||||
echo "Testing $ver_dir"
|
||||
if $ver_dir/python --version ; then
|
||||
export PYTHON="$ver_dir/python"
|
||||
not_found=0
|
||||
old_path="$PATH"
|
||||
export PATH="$ver_dir:$PATH"
|
||||
./bin/spack-tmpconfig -b ./.github/workflows/bin/bootstrap-test.sh
|
||||
export PATH="$old_path"
|
||||
fi
|
||||
fi
|
||||
if (($not_found)) ; then
|
||||
echo Required python version $ver not found in runner!
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
- name: Bootstrap GnuPG
|
||||
env:
|
||||
SETUP_SCRIPT_EXT: ${{ matrix.runner == 'windows-latest' && 'ps1' || 'sh' }}
|
||||
SETUP_SCRIPT_SOURCE: ${{ matrix.runner == 'windows-latest' && './' || 'source ' }}
|
||||
USER_SCOPE_PARENT_DIR: ${{ matrix.runner == 'windows-latest' && '$env:userprofile' || '$HOME' }}
|
||||
VALIDATE_LAST_EXIT: ${{ matrix.runner == 'windows-latest' && './share/spack/qa/validate_last_exit.ps1' || '' }}
|
||||
run: |
|
||||
${{ env.SETUP_SCRIPT_SOURCE }}share/spack/setup-env.${{ env.SETUP_SCRIPT_EXT }}
|
||||
spack -d gpg list
|
||||
${{ env.VALIDATE_LAST_EXIT }}
|
||||
tree ${{ env.USER_SCOPE_PARENT_DIR }}/.spack/bootstrap/store/
|
||||
- name: Bootstrap File
|
||||
env:
|
||||
SETUP_SCRIPT_EXT: ${{ matrix.runner == 'windows-latest' && 'ps1' || 'sh' }}
|
||||
SETUP_SCRIPT_SOURCE: ${{ matrix.runner == 'windows-latest' && './' || 'source ' }}
|
||||
USER_SCOPE_PARENT_DIR: ${{ matrix.runner == 'windows-latest' && '$env:userprofile' || '$HOME' }}
|
||||
VALIDATE_LAST_EXIT: ${{ matrix.runner == 'windows-latest' && './share/spack/qa/validate_last_exit.ps1' || '' }}
|
||||
run: |
|
||||
${{ env.SETUP_SCRIPT_SOURCE }}share/spack/setup-env.${{ env.SETUP_SCRIPT_EXT }}
|
||||
spack -d python share/spack/qa/bootstrap-file.py
|
||||
${{ env.VALIDATE_LAST_EXIT }}
|
||||
tree ${{ env.USER_SCOPE_PARENT_DIR }}/.spack/bootstrap/store/
|
133
.github/workflows/build-containers.yml
vendored
133
.github/workflows/build-containers.yml
vendored
@@ -1,133 +0,0 @@
|
||||
name: Containers
|
||||
|
||||
on:
|
||||
# This Workflow can be triggered manually
|
||||
workflow_dispatch:
|
||||
# Build new Spack develop containers nightly.
|
||||
schedule:
|
||||
- cron: '34 0 * * *'
|
||||
# Run on pull requests that modify this file
|
||||
pull_request:
|
||||
branches:
|
||||
- develop
|
||||
paths:
|
||||
- '.github/workflows/build-containers.yml'
|
||||
- 'share/spack/docker/*'
|
||||
- 'share/spack/templates/container/*'
|
||||
- 'lib/spack/spack/container/*'
|
||||
# Let's also build & tag Spack containers on releases.
|
||||
release:
|
||||
types: [published]
|
||||
|
||||
concurrency:
|
||||
group: build_containers-${{github.ref}}-${{github.event.pull_request.number || github.run_number}}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
deploy-images:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
packages: write
|
||||
strategy:
|
||||
# Even if one container fails to build we still want the others
|
||||
# to continue their builds.
|
||||
fail-fast: false
|
||||
# A matrix of Dockerfile paths, associated tags, and which architectures
|
||||
# they support.
|
||||
matrix:
|
||||
# Meaning of the various items in the matrix list
|
||||
# 0: Container name (e.g. ubuntu-bionic)
|
||||
# 1: Platforms to build for
|
||||
# 2: Base image (e.g. ubuntu:22.04)
|
||||
dockerfile: [[amazon-linux, 'linux/amd64,linux/arm64', 'amazonlinux:2'],
|
||||
[centos-stream9, 'linux/amd64,linux/arm64,linux/ppc64le', 'centos:stream9'],
|
||||
[leap15, 'linux/amd64,linux/arm64,linux/ppc64le', 'opensuse/leap:15'],
|
||||
[ubuntu-focal, 'linux/amd64,linux/arm64,linux/ppc64le', 'ubuntu:20.04'],
|
||||
[ubuntu-jammy, 'linux/amd64,linux/arm64,linux/ppc64le', 'ubuntu:22.04'],
|
||||
[ubuntu-noble, 'linux/amd64,linux/arm64,linux/ppc64le', 'ubuntu:24.04'],
|
||||
[almalinux8, 'linux/amd64,linux/arm64,linux/ppc64le', 'almalinux:8'],
|
||||
[almalinux9, 'linux/amd64,linux/arm64,linux/ppc64le', 'almalinux:9'],
|
||||
[rockylinux8, 'linux/amd64,linux/arm64', 'rockylinux:8'],
|
||||
[rockylinux9, 'linux/amd64,linux/arm64', 'rockylinux:9'],
|
||||
[fedora39, 'linux/amd64,linux/arm64,linux/ppc64le', 'fedora:39'],
|
||||
[fedora40, 'linux/amd64,linux/arm64,linux/ppc64le', 'fedora:40']]
|
||||
name: Build ${{ matrix.dockerfile[0] }}
|
||||
if: github.repository == 'spack/spack'
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332
|
||||
|
||||
- uses: docker/metadata-action@8e5442c4ef9f78752691e2d8f8d19755c6f78e81
|
||||
id: docker_meta
|
||||
with:
|
||||
images: |
|
||||
ghcr.io/${{ github.repository_owner }}/${{ matrix.dockerfile[0] }}
|
||||
${{ github.repository_owner }}/${{ matrix.dockerfile[0] }}
|
||||
tags: |
|
||||
type=schedule,pattern=nightly
|
||||
type=schedule,pattern=develop
|
||||
type=semver,pattern={{version}}
|
||||
type=semver,pattern={{major}}.{{minor}}
|
||||
type=semver,pattern={{major}}
|
||||
type=ref,event=branch
|
||||
type=ref,event=pr
|
||||
|
||||
- name: Generate the Dockerfile
|
||||
env:
|
||||
SPACK_YAML_OS: "${{ matrix.dockerfile[2] }}"
|
||||
run: |
|
||||
.github/workflows/bin/generate_spack_yaml_containerize.sh
|
||||
. share/spack/setup-env.sh
|
||||
mkdir -p dockerfiles/${{ matrix.dockerfile[0] }}
|
||||
spack containerize --last-stage=bootstrap | tee dockerfiles/${{ matrix.dockerfile[0] }}/Dockerfile
|
||||
printf "Preparing to build ${{ env.container }} from dockerfiles/${{ matrix.dockerfile[0] }}/Dockerfile"
|
||||
if [ ! -f "dockerfiles/${{ matrix.dockerfile[0] }}/Dockerfile" ]; then
|
||||
printf "dockerfiles/${{ matrix.dockerfile[0] }}/Dockerfile does not exist"
|
||||
exit 1;
|
||||
fi
|
||||
|
||||
- name: Upload Dockerfile
|
||||
uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874
|
||||
with:
|
||||
name: dockerfiles_${{ matrix.dockerfile[0] }}
|
||||
path: dockerfiles
|
||||
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@49b3bc8e6bdd4a60e6116a5414239cba5943d3cf
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@988b5a0280414f521da01fcc63a27aeeb4b104db
|
||||
|
||||
- name: Log in to GitHub Container Registry
|
||||
uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Log in to DockerHub
|
||||
if: github.event_name != 'pull_request'
|
||||
uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
|
||||
- name: Build & Deploy ${{ matrix.dockerfile[0] }}
|
||||
uses: docker/build-push-action@5cd11c3a4ced054e52742c5fd54dca954e0edd85
|
||||
with:
|
||||
context: dockerfiles/${{ matrix.dockerfile[0] }}
|
||||
platforms: ${{ matrix.dockerfile[1] }}
|
||||
push: ${{ github.event_name != 'pull_request' }}
|
||||
tags: ${{ steps.docker_meta.outputs.tags }}
|
||||
labels: ${{ steps.docker_meta.outputs.labels }}
|
||||
|
||||
merge-dockerfiles:
|
||||
runs-on: ubuntu-latest
|
||||
needs: deploy-images
|
||||
steps:
|
||||
- name: Merge Artifacts
|
||||
uses: actions/upload-artifact/merge@50769540e7f4bd5e21e526ee35c689e35e0d6874
|
||||
with:
|
||||
name: dockerfiles
|
||||
pattern: dockerfiles_*
|
||||
delete-merged: true
|
38
.github/workflows/ci.yaml
vendored
38
.github/workflows/ci.yaml
vendored
@@ -74,41 +74,3 @@ jobs:
|
||||
# job outputs: https://docs.github.com/en/actions/reference/workflow-syntax-for-github-actions#jobsjob_idoutputs
|
||||
# setting environment variables from earlier steps: https://docs.github.com/en/actions/reference/workflow-commands-for-github-actions#setting-an-environment-variable
|
||||
#
|
||||
bootstrap:
|
||||
if: ${{ github.repository == 'spack/spack' && needs.changes.outputs.bootstrap == 'true' }}
|
||||
needs: [ prechecks, changes ]
|
||||
uses: ./.github/workflows/bootstrap.yml
|
||||
secrets: inherit
|
||||
unit-tests:
|
||||
if: ${{ github.repository == 'spack/spack' && needs.changes.outputs.core == 'true' }}
|
||||
needs: [ prechecks, changes ]
|
||||
uses: ./.github/workflows/unit_tests.yaml
|
||||
secrets: inherit
|
||||
upload-coverage:
|
||||
needs: [ unit-tests, prechecks ]
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Download coverage files
|
||||
uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16
|
||||
with:
|
||||
pattern: coverage-*
|
||||
path: coverage
|
||||
merge-multiple: true
|
||||
- run: pip install --upgrade coverage
|
||||
- run: ls -la coverage
|
||||
- run: coverage combine -a coverage/.coverage*
|
||||
- run: coverage xml
|
||||
- name: "Upload coverage"
|
||||
uses: codecov/codecov-action@e28ff129e5465c2c0dcc6f003fc735cb6ae0c673
|
||||
with:
|
||||
token: ${{ secrets.CODECOV_TOKEN }}
|
||||
verbose: true
|
||||
all:
|
||||
needs: [ upload-coverage, bootstrap ]
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Success
|
||||
run: "true"
|
||||
|
31
.github/workflows/nightly-win-builds.yml
vendored
31
.github/workflows/nightly-win-builds.yml
vendored
@@ -1,31 +0,0 @@
|
||||
name: Windows Paraview Nightly
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: '0 2 * * *' # Run at 2 am
|
||||
|
||||
defaults:
|
||||
run:
|
||||
shell:
|
||||
powershell Invoke-Expression -Command "./share/spack/qa/windows_test_setup.ps1"; {0}
|
||||
|
||||
|
||||
jobs:
|
||||
build-paraview-deps:
|
||||
runs-on: windows-latest
|
||||
steps:
|
||||
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- uses: actions/setup-python@f677139bbe7f9c59b41e40162b753c062f5d49a3
|
||||
with:
|
||||
python-version: 3.9
|
||||
- name: Install Python packages
|
||||
run: |
|
||||
python -m pip install --upgrade pip six pywin32 setuptools coverage
|
||||
- name: Build Test
|
||||
run: |
|
||||
spack compiler find
|
||||
spack external find cmake ninja win-sdk win-wdk wgl msmpi
|
||||
spack -d install -y --cdash-upload-url https://cdash.spack.io/submit.php?project=Spack+on+Windows --cdash-track Nightly --only dependencies paraview
|
||||
exit 0
|
250
.github/workflows/unit_tests.yaml
vendored
250
.github/workflows/unit_tests.yaml
vendored
@@ -1,250 +0,0 @@
|
||||
name: unit tests
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
workflow_call:
|
||||
|
||||
concurrency:
|
||||
group: unit_tests-${{github.ref}}-${{github.event.pull_request.number || github.run_number}}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
# Run unit tests with different configurations on linux
|
||||
ubuntu:
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-latest]
|
||||
python-version: ['3.7', '3.8', '3.9', '3.10', '3.11', '3.12']
|
||||
on_develop:
|
||||
- ${{ github.ref == 'refs/heads/develop' }}
|
||||
include:
|
||||
- python-version: '3.6'
|
||||
os: ubuntu-20.04
|
||||
on_develop: ${{ github.ref == 'refs/heads/develop' }}
|
||||
exclude:
|
||||
- python-version: '3.7'
|
||||
os: ubuntu-latest
|
||||
on_develop: false
|
||||
- python-version: '3.8'
|
||||
os: ubuntu-latest
|
||||
on_develop: false
|
||||
- python-version: '3.9'
|
||||
os: ubuntu-latest
|
||||
on_develop: false
|
||||
- python-version: '3.10'
|
||||
os: ubuntu-latest
|
||||
on_develop: false
|
||||
- python-version: '3.11'
|
||||
os: ubuntu-latest
|
||||
on_develop: false
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- uses: actions/setup-python@f677139bbe7f9c59b41e40162b753c062f5d49a3
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
- name: Install System packages
|
||||
run: |
|
||||
sudo apt-get -y update
|
||||
# Needed for unit tests
|
||||
sudo apt-get -y install \
|
||||
coreutils cvs gfortran graphviz gnupg2 mercurial ninja-build \
|
||||
cmake bison libbison-dev kcov
|
||||
- name: Install Python packages
|
||||
run: |
|
||||
pip install --upgrade pip setuptools pytest pytest-xdist pytest-cov
|
||||
pip install --upgrade flake8 "isort>=4.3.5" "mypy>=0.900" "click" "black"
|
||||
- name: Setup git configuration
|
||||
run: |
|
||||
# Need this for the git tests to succeed.
|
||||
git --version
|
||||
. .github/workflows/bin/setup_git.sh
|
||||
- name: Bootstrap clingo
|
||||
if: ${{ matrix.concretizer == 'clingo' }}
|
||||
env:
|
||||
SPACK_PYTHON: python
|
||||
run: |
|
||||
. share/spack/setup-env.sh
|
||||
spack bootstrap disable spack-install
|
||||
spack bootstrap now
|
||||
spack -v solve zlib
|
||||
- name: Run unit tests
|
||||
env:
|
||||
SPACK_PYTHON: python
|
||||
SPACK_TEST_PARALLEL: 2
|
||||
COVERAGE: true
|
||||
COVERAGE_FILE: coverage/.coverage-${{ matrix.os }}-python${{ matrix.python-version }}
|
||||
UNIT_TEST_COVERAGE: ${{ matrix.python-version == '3.11' }}
|
||||
run: |
|
||||
share/spack/qa/run-unit-tests
|
||||
- uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874
|
||||
with:
|
||||
name: coverage-${{ matrix.os }}-python${{ matrix.python-version }}
|
||||
path: coverage
|
||||
include-hidden-files: true
|
||||
# Test shell integration
|
||||
shell:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- uses: actions/setup-python@f677139bbe7f9c59b41e40162b753c062f5d49a3
|
||||
with:
|
||||
python-version: '3.11'
|
||||
- name: Install System packages
|
||||
run: |
|
||||
sudo apt-get -y update
|
||||
# Needed for shell tests
|
||||
sudo apt-get install -y coreutils kcov csh zsh tcsh fish dash bash
|
||||
- name: Install Python packages
|
||||
run: |
|
||||
pip install --upgrade pip setuptools pytest coverage[toml] pytest-xdist
|
||||
- name: Setup git configuration
|
||||
run: |
|
||||
# Need this for the git tests to succeed.
|
||||
git --version
|
||||
. .github/workflows/bin/setup_git.sh
|
||||
- name: Run shell tests
|
||||
env:
|
||||
COVERAGE: true
|
||||
run: |
|
||||
share/spack/qa/run-shell-tests
|
||||
- uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874
|
||||
with:
|
||||
name: coverage-shell
|
||||
path: coverage
|
||||
include-hidden-files: true
|
||||
|
||||
# Test RHEL8 UBI with platform Python. This job is run
|
||||
# only on PRs modifying core Spack
|
||||
rhel8-platform-python:
|
||||
runs-on: ubuntu-latest
|
||||
container: registry.access.redhat.com/ubi8/ubi
|
||||
steps:
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
dnf install -y \
|
||||
bzip2 curl file gcc-c++ gcc gcc-gfortran git gnupg2 gzip \
|
||||
make patch tcl unzip which xz
|
||||
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332
|
||||
- name: Setup repo and non-root user
|
||||
run: |
|
||||
git --version
|
||||
git config --global --add safe.directory /__w/spack/spack
|
||||
git fetch --unshallow
|
||||
. .github/workflows/bin/setup_git.sh
|
||||
useradd spack-test
|
||||
chown -R spack-test .
|
||||
- name: Run unit tests
|
||||
shell: runuser -u spack-test -- bash {0}
|
||||
run: |
|
||||
source share/spack/setup-env.sh
|
||||
spack -d bootstrap now --dev
|
||||
spack unit-test -k 'not cvs and not svn and not hg' -x --verbose
|
||||
# Test for the clingo based solver (using clingo-cffi)
|
||||
clingo-cffi:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- uses: actions/setup-python@f677139bbe7f9c59b41e40162b753c062f5d49a3
|
||||
with:
|
||||
python-version: '3.11'
|
||||
- name: Install System packages
|
||||
run: |
|
||||
sudo apt-get -y update
|
||||
sudo apt-get -y install coreutils cvs gfortran graphviz gnupg2 mercurial ninja-build kcov
|
||||
- name: Install Python packages
|
||||
run: |
|
||||
pip install --upgrade pip setuptools pytest coverage[toml] pytest-cov clingo pytest-xdist
|
||||
pip install --upgrade flake8 "isort>=4.3.5" "mypy>=0.900" "click" "black"
|
||||
- name: Setup git configuration
|
||||
run: |
|
||||
# Need this for the git tests to succeed.
|
||||
git --version
|
||||
. .github/workflows/bin/setup_git.sh
|
||||
- name: Run unit tests (full suite with coverage)
|
||||
env:
|
||||
COVERAGE: true
|
||||
COVERAGE_FILE: coverage/.coverage-clingo-cffi
|
||||
run: |
|
||||
share/spack/qa/run-unit-tests
|
||||
- uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874
|
||||
with:
|
||||
name: coverage-clingo-cffi
|
||||
path: coverage
|
||||
include-hidden-files: true
|
||||
# Run unit tests on MacOS
|
||||
macos:
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
matrix:
|
||||
os: [macos-13, macos-14]
|
||||
python-version: ["3.11"]
|
||||
steps:
|
||||
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- uses: actions/setup-python@f677139bbe7f9c59b41e40162b753c062f5d49a3
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
- name: Install Python packages
|
||||
run: |
|
||||
pip install --upgrade pip setuptools
|
||||
pip install --upgrade pytest coverage[toml] pytest-xdist pytest-cov
|
||||
- name: Setup Homebrew packages
|
||||
run: |
|
||||
brew install dash fish gcc gnupg2 kcov
|
||||
- name: Run unit tests
|
||||
env:
|
||||
SPACK_TEST_PARALLEL: 4
|
||||
COVERAGE_FILE: coverage/.coverage-${{ matrix.os }}-python${{ matrix.python-version }}
|
||||
run: |
|
||||
git --version
|
||||
. .github/workflows/bin/setup_git.sh
|
||||
. share/spack/setup-env.sh
|
||||
$(which spack) bootstrap disable spack-install
|
||||
$(which spack) solve zlib
|
||||
common_args=(--dist loadfile --tx '4*popen//python=./bin/spack-tmpconfig python -u ./bin/spack python' -x)
|
||||
$(which spack) unit-test --verbose --cov --cov-config=pyproject.toml --cov-report=xml:coverage.xml "${common_args[@]}"
|
||||
- uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874
|
||||
with:
|
||||
name: coverage-${{ matrix.os }}-python${{ matrix.python-version }}
|
||||
path: coverage
|
||||
include-hidden-files: true
|
||||
# Run unit tests on Windows
|
||||
windows:
|
||||
defaults:
|
||||
run:
|
||||
shell:
|
||||
powershell Invoke-Expression -Command "./share/spack/qa/windows_test_setup.ps1"; {0}
|
||||
runs-on: windows-latest
|
||||
steps:
|
||||
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- uses: actions/setup-python@f677139bbe7f9c59b41e40162b753c062f5d49a3
|
||||
with:
|
||||
python-version: 3.9
|
||||
- name: Install Python packages
|
||||
run: |
|
||||
python -m pip install --upgrade pip pywin32 setuptools pytest-cov clingo
|
||||
- name: Create local develop
|
||||
run: |
|
||||
./.github/workflows/bin/setup_git.ps1
|
||||
- name: Unit Test
|
||||
env:
|
||||
COVERAGE_FILE: coverage/.coverage-windows
|
||||
run: |
|
||||
spack unit-test -x --verbose --cov --cov-config=pyproject.toml
|
||||
./share/spack/qa/validate_last_exit.ps1
|
||||
- uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874
|
||||
with:
|
||||
name: coverage-windows
|
||||
path: coverage
|
||||
include-hidden-files: true
|
91
.github/workflows/valid-style.yml
vendored
91
.github/workflows/valid-style.yml
vendored
@@ -54,95 +54,4 @@ jobs:
|
||||
- name: Run style tests
|
||||
run: |
|
||||
share/spack/qa/run-style-tests
|
||||
audit:
|
||||
uses: ./.github/workflows/audit.yaml
|
||||
secrets: inherit
|
||||
with:
|
||||
with_coverage: ${{ inputs.with_coverage }}
|
||||
python_version: '3.11'
|
||||
# Check that spack can bootstrap the development environment on Python 3.6 - RHEL8
|
||||
bootstrap-dev-rhel8:
|
||||
runs-on: ubuntu-latest
|
||||
container: registry.access.redhat.com/ubi8/ubi
|
||||
steps:
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
dnf install -y \
|
||||
bzip2 curl file gcc-c++ gcc gcc-gfortran git gnupg2 gzip \
|
||||
make patch tcl unzip which xz
|
||||
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332
|
||||
- name: Setup repo and non-root user
|
||||
run: |
|
||||
git --version
|
||||
git config --global --add safe.directory /__w/spack/spack
|
||||
git fetch --unshallow
|
||||
. .github/workflows/bin/setup_git.sh
|
||||
useradd spack-test
|
||||
chown -R spack-test .
|
||||
- name: Bootstrap Spack development environment
|
||||
shell: runuser -u spack-test -- bash {0}
|
||||
run: |
|
||||
source share/spack/setup-env.sh
|
||||
spack debug report
|
||||
spack -d bootstrap now --dev
|
||||
spack style -t black
|
||||
spack unit-test -V
|
||||
import-check:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: julia-actions/setup-julia@v2
|
||||
with:
|
||||
version: '1.10'
|
||||
- uses: julia-actions/cache@v2
|
||||
|
||||
# PR: use the base of the PR as the old commit
|
||||
- name: Checkout PR base commit
|
||||
if: github.event_name == 'pull_request'
|
||||
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332
|
||||
with:
|
||||
ref: ${{ github.event.pull_request.base.sha }}
|
||||
path: old
|
||||
# not a PR: use the previous commit as the old commit
|
||||
- name: Checkout previous commit
|
||||
if: github.event_name != 'pull_request'
|
||||
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332
|
||||
with:
|
||||
fetch-depth: 2
|
||||
path: old
|
||||
- name: Checkout previous commit
|
||||
if: github.event_name != 'pull_request'
|
||||
run: git -C old reset --hard HEAD^
|
||||
|
||||
- name: Checkout new commit
|
||||
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332
|
||||
with:
|
||||
path: new
|
||||
- name: Install circular import checker
|
||||
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332
|
||||
with:
|
||||
repository: haampie/circular-import-fighter
|
||||
ref: 555519c6fd5564fd2eb844e7b87e84f4d12602e2
|
||||
path: circular-import-fighter
|
||||
- name: Install dependencies
|
||||
working-directory: circular-import-fighter
|
||||
run: make -j dependencies
|
||||
- name: Import cycles before
|
||||
working-directory: circular-import-fighter
|
||||
run: make SPACK_ROOT=../old && cp solution solution.old
|
||||
- name: Import cycles after
|
||||
working-directory: circular-import-fighter
|
||||
run: make clean-graph && make SPACK_ROOT=../new && cp solution solution.new
|
||||
- name: Compare import cycles
|
||||
working-directory: circular-import-fighter
|
||||
run: |
|
||||
edges_before="$(grep -oP 'edges to delete: \K\d+' solution.old)"
|
||||
edges_after="$(grep -oP 'edges to delete: \K\d+' solution.new)"
|
||||
if [ "$edges_after" -gt "$edges_before" ]; then
|
||||
printf '\033[1;31mImport check failed: %s imports need to be deleted, ' "$edges_after"
|
||||
printf 'previously this was %s\033[0m\n' "$edges_before"
|
||||
printf 'Compare \033[1;97m"Import cycles before"\033[0m and '
|
||||
printf '\033[1;97m"Import cycles after"\033[0m to see problematic imports.\n'
|
||||
exit 1
|
||||
else
|
||||
printf '\033[1;32mImport check passed: %s <= %s\033[0m\n' "$edges_after" "$edges_before"
|
||||
fi
|
||||
|
@@ -5,9 +5,9 @@
|
||||
|
||||
.. chain:
|
||||
|
||||
=============================================
|
||||
Chaining Spack Installations (upstreams.yaml)
|
||||
=============================================
|
||||
============================
|
||||
Chaining Spack Installations
|
||||
============================
|
||||
|
||||
You can point your Spack installation to another installation to use any
|
||||
packages that are installed there. To register the other Spack instance,
|
||||
|
@@ -893,8 +893,9 @@ The valid variables for a ``when`` clause are:
|
||||
|
||||
#. ``env``. The user environment (usually ``os.environ`` in Python).
|
||||
|
||||
#. ``hostname``. The hostname of the system (if ``hostname`` is an
|
||||
executable in the user's PATH).
|
||||
#. ``hostname``. The hostname of the system.
|
||||
|
||||
#. ``full_hostname``. The fully qualified hostname of the system.
|
||||
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
SpecLists as Constraints
|
||||
|
2
lib/spack/external/__init__.py
vendored
2
lib/spack/external/__init__.py
vendored
@@ -18,7 +18,7 @@
|
||||
|
||||
* Homepage: https://pypi.python.org/pypi/archspec
|
||||
* Usage: Labeling, comparison and detection of microarchitectures
|
||||
* Version: 0.2.5-dev (commit cbb1fd5eb397a70d466e5160b393b87b0dbcc78f)
|
||||
* Version: 0.2.5-dev (commit 7e6740012b897ae4a950f0bba7e9726b767e921f)
|
||||
|
||||
astunparse
|
||||
----------------
|
||||
|
@@ -2844,7 +2844,8 @@
|
||||
"asimdrdm",
|
||||
"lrcpc",
|
||||
"dcpop",
|
||||
"asimddp"
|
||||
"asimddp",
|
||||
"ssbs"
|
||||
],
|
||||
"compilers" : {
|
||||
"gcc": [
|
||||
@@ -2941,6 +2942,7 @@
|
||||
"uscat",
|
||||
"ilrcpc",
|
||||
"flagm",
|
||||
"ssbs",
|
||||
"dcpodp",
|
||||
"svei8mm",
|
||||
"svebf16",
|
||||
@@ -3008,7 +3010,7 @@
|
||||
},
|
||||
{
|
||||
"versions": "11:",
|
||||
"flags" : "-march=armv8.4-a+sve+fp16+bf16+crypto+i8mm+rng"
|
||||
"flags" : "-march=armv8.4-a+sve+ssbs+fp16+bf16+crypto+i8mm+rng"
|
||||
},
|
||||
{
|
||||
"versions": "12:",
|
||||
@@ -3064,6 +3066,7 @@
|
||||
"uscat",
|
||||
"ilrcpc",
|
||||
"flagm",
|
||||
"ssbs",
|
||||
"sb",
|
||||
"dcpodp",
|
||||
"sve2",
|
||||
@@ -3176,6 +3179,7 @@
|
||||
"uscat",
|
||||
"ilrcpc",
|
||||
"flagm",
|
||||
"ssbs",
|
||||
"sb",
|
||||
"dcpodp",
|
||||
"sve2",
|
||||
|
@@ -3,13 +3,6 @@
|
||||
#
|
||||
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
|
||||
|
||||
import os
|
||||
import re
|
||||
from typing import Optional
|
||||
|
||||
import spack.paths
|
||||
import spack.util.git
|
||||
|
||||
#: PEP440 canonical <major>.<minor>.<micro>.<devN> string
|
||||
__version__ = "0.23.0.dev0"
|
||||
spack_version = __version__
|
||||
@@ -26,47 +19,4 @@ def __try_int(v):
|
||||
spack_version_info = tuple([__try_int(v) for v in __version__.split(".")])
|
||||
|
||||
|
||||
def get_spack_commit() -> Optional[str]:
|
||||
"""Get the Spack git commit sha.
|
||||
|
||||
Returns:
|
||||
(str or None) the commit sha if available, otherwise None
|
||||
"""
|
||||
git_path = os.path.join(spack.paths.prefix, ".git")
|
||||
if not os.path.exists(git_path):
|
||||
return None
|
||||
|
||||
git = spack.util.git.git()
|
||||
if not git:
|
||||
return None
|
||||
|
||||
rev = git(
|
||||
"-C",
|
||||
spack.paths.prefix,
|
||||
"rev-parse",
|
||||
"HEAD",
|
||||
output=str,
|
||||
error=os.devnull,
|
||||
fail_on_error=False,
|
||||
)
|
||||
if git.returncode != 0:
|
||||
return None
|
||||
|
||||
match = re.match(r"[a-f\d]{7,}$", rev)
|
||||
return match.group(0) if match else None
|
||||
|
||||
|
||||
def get_version() -> str:
|
||||
"""Get a descriptive version of this instance of Spack.
|
||||
|
||||
Outputs '<PEP440 version> (<git commit sha>)'.
|
||||
|
||||
The commit sha is only added when available.
|
||||
"""
|
||||
commit = get_spack_commit()
|
||||
if commit:
|
||||
return f"{spack_version} ({commit})"
|
||||
return spack_version
|
||||
|
||||
|
||||
__all__ = ["spack_version_info", "spack_version", "get_version", "get_spack_commit"]
|
||||
__all__ = ["spack_version_info", "spack_version"]
|
||||
|
@@ -51,10 +51,9 @@ def _search_duplicate_compilers(error_cls):
|
||||
|
||||
import llnl.util.lang
|
||||
|
||||
import spack.builder
|
||||
import spack.config
|
||||
import spack.fetch_strategy
|
||||
import spack.patch
|
||||
import spack.paths
|
||||
import spack.repo
|
||||
import spack.spec
|
||||
import spack.util.crypto
|
||||
@@ -282,7 +281,7 @@ def _avoid_mismatched_variants(error_cls):
|
||||
pkg_cls = spack.repo.PATH.get_pkg_class(pkg_name)
|
||||
for variant in current_spec.variants.values():
|
||||
# Variant does not exist at all
|
||||
if variant.name not in pkg_cls.variant_names():
|
||||
if variant.name not in pkg_cls.variants:
|
||||
summary = (
|
||||
f"Setting a preference for the '{pkg_name}' package to the "
|
||||
f"non-existing variant '{variant.name}'"
|
||||
@@ -291,8 +290,9 @@ def _avoid_mismatched_variants(error_cls):
|
||||
continue
|
||||
|
||||
# Variant cannot accept this value
|
||||
s = spack.spec.Spec(pkg_name)
|
||||
try:
|
||||
spack.variant.prevalidate_variant_value(pkg_cls, variant, strict=True)
|
||||
s.update_variant_validate(variant.name, variant.value)
|
||||
except Exception:
|
||||
summary = (
|
||||
f"Setting the variant '{variant.name}' of the '{pkg_name}' package "
|
||||
@@ -662,15 +662,9 @@ def _ensure_env_methods_are_ported_to_builders(pkgs, error_cls):
|
||||
errors = []
|
||||
for pkg_name in pkgs:
|
||||
pkg_cls = spack.repo.PATH.get_pkg_class(pkg_name)
|
||||
|
||||
# values are either Value objects (for conditional values) or the values themselves
|
||||
build_system_names = set(
|
||||
v.value if isinstance(v, spack.variant.Value) else v
|
||||
for _, variant in pkg_cls.variant_definitions("build_system")
|
||||
for v in variant.values
|
||||
)
|
||||
builder_cls_names = [spack.builder.BUILDER_CLS[x].__name__ for x in build_system_names]
|
||||
|
||||
buildsystem_variant, _ = pkg_cls.variants["build_system"]
|
||||
buildsystem_names = [getattr(x, "value", x) for x in buildsystem_variant.values]
|
||||
builder_cls_names = [spack.builder.BUILDER_CLS[x].__name__ for x in buildsystem_names]
|
||||
module = pkg_cls.module
|
||||
has_builders_in_package_py = any(
|
||||
getattr(module, name, False) for name in builder_cls_names
|
||||
@@ -937,22 +931,20 @@ def check_virtual_with_variants(spec, msg):
|
||||
|
||||
# check variants
|
||||
dependency_variants = dep.spec.variants
|
||||
for name, variant in dependency_variants.items():
|
||||
for name, value in dependency_variants.items():
|
||||
try:
|
||||
spack.variant.prevalidate_variant_value(
|
||||
dependency_pkg_cls, variant, dep.spec, strict=True
|
||||
)
|
||||
v, _ = dependency_pkg_cls.variants[name]
|
||||
v.validate_or_raise(value, pkg_cls=dependency_pkg_cls)
|
||||
except Exception as e:
|
||||
summary = (
|
||||
f"{pkg_name}: wrong variant used for dependency in 'depends_on()'"
|
||||
)
|
||||
|
||||
error_msg = str(e)
|
||||
if isinstance(e, KeyError):
|
||||
error_msg = (
|
||||
f"variant {str(e).strip()} does not exist in package {dep_name}"
|
||||
f" in package '{dep_name}'"
|
||||
)
|
||||
error_msg += f" in package '{dep_name}'"
|
||||
|
||||
errors.append(
|
||||
error_cls(summary=summary, details=[error_msg, f"in {filename}"])
|
||||
@@ -964,38 +956,39 @@ def check_virtual_with_variants(spec, msg):
|
||||
@package_directives
|
||||
def _ensure_variant_defaults_are_parsable(pkgs, error_cls):
|
||||
"""Ensures that variant defaults are present and parsable from cli"""
|
||||
|
||||
def check_variant(pkg_cls, variant, vname):
|
||||
# bool is a subclass of int in python. Permitting a default that is an instance
|
||||
# of 'int' means both foo=false and foo=0 are accepted. Other falsish values are
|
||||
# not allowed, since they can't be parsed from CLI ('foo=')
|
||||
default_is_parsable = isinstance(variant.default, int) or variant.default
|
||||
|
||||
if not default_is_parsable:
|
||||
msg = f"Variant '{vname}' of package '{pkg_cls.name}' has an unparsable default value"
|
||||
return [error_cls(msg, [])]
|
||||
|
||||
try:
|
||||
vspec = variant.make_default()
|
||||
except spack.variant.MultipleValuesInExclusiveVariantError:
|
||||
msg = f"Can't create default value for variant '{vname}' in package '{pkg_cls.name}'"
|
||||
return [error_cls(msg, [])]
|
||||
|
||||
try:
|
||||
variant.validate_or_raise(vspec, pkg_cls.name)
|
||||
except spack.variant.InvalidVariantValueError:
|
||||
msg = "Default value of variant '{vname}' in package '{pkg.name}' is invalid"
|
||||
question = "Is it among the allowed values?"
|
||||
return [error_cls(msg, [question])]
|
||||
|
||||
return []
|
||||
|
||||
errors = []
|
||||
for pkg_name in pkgs:
|
||||
pkg_cls = spack.repo.PATH.get_pkg_class(pkg_name)
|
||||
for vname in pkg_cls.variant_names():
|
||||
for _, variant_def in pkg_cls.variant_definitions(vname):
|
||||
errors.extend(check_variant(pkg_cls, variant_def, vname))
|
||||
for variant_name, entry in pkg_cls.variants.items():
|
||||
variant, _ = entry
|
||||
default_is_parsable = (
|
||||
# Permitting a default that is an instance on 'int' permits
|
||||
# to have foo=false or foo=0. Other falsish values are
|
||||
# not allowed, since they can't be parsed from cli ('foo=')
|
||||
isinstance(variant.default, int)
|
||||
or variant.default
|
||||
)
|
||||
if not default_is_parsable:
|
||||
error_msg = "Variant '{}' of package '{}' has a bad default value"
|
||||
errors.append(error_cls(error_msg.format(variant_name, pkg_name), []))
|
||||
continue
|
||||
|
||||
try:
|
||||
vspec = variant.make_default()
|
||||
except spack.variant.MultipleValuesInExclusiveVariantError:
|
||||
error_msg = "Cannot create a default value for the variant '{}' in package '{}'"
|
||||
errors.append(error_cls(error_msg.format(variant_name, pkg_name), []))
|
||||
continue
|
||||
|
||||
try:
|
||||
variant.validate_or_raise(vspec, pkg_cls=pkg_cls)
|
||||
except spack.variant.InvalidVariantValueError:
|
||||
error_msg = (
|
||||
"The default value of the variant '{}' in package '{}' failed validation"
|
||||
)
|
||||
question = "Is it among the allowed values?"
|
||||
errors.append(error_cls(error_msg.format(variant_name, pkg_name), [question]))
|
||||
|
||||
return errors
|
||||
|
||||
|
||||
@@ -1005,11 +998,11 @@ def _ensure_variants_have_descriptions(pkgs, error_cls):
|
||||
errors = []
|
||||
for pkg_name in pkgs:
|
||||
pkg_cls = spack.repo.PATH.get_pkg_class(pkg_name)
|
||||
for name in pkg_cls.variant_names():
|
||||
for when, variant in pkg_cls.variant_definitions(name):
|
||||
if not variant.description:
|
||||
msg = f"Variant '{name}' in package '{pkg_name}' is missing a description"
|
||||
errors.append(error_cls(msg, []))
|
||||
for variant_name, entry in pkg_cls.variants.items():
|
||||
variant, _ = entry
|
||||
if not variant.description:
|
||||
error_msg = "Variant '{}' in package '{}' is missing a description"
|
||||
errors.append(error_cls(error_msg.format(variant_name, pkg_name), []))
|
||||
|
||||
return errors
|
||||
|
||||
@@ -1066,26 +1059,29 @@ def _version_constraints_are_satisfiable_by_some_version_in_repo(pkgs, error_cls
|
||||
|
||||
|
||||
def _analyze_variants_in_directive(pkg, constraint, directive, error_cls):
|
||||
variant_exceptions = (
|
||||
spack.variant.InconsistentValidationError,
|
||||
spack.variant.MultipleValuesInExclusiveVariantError,
|
||||
spack.variant.InvalidVariantValueError,
|
||||
KeyError,
|
||||
)
|
||||
errors = []
|
||||
variant_names = pkg.variant_names()
|
||||
summary = f"{pkg.name}: wrong variant in '{directive}' directive"
|
||||
filename = spack.repo.PATH.filename_for_package_name(pkg.name)
|
||||
|
||||
for name, v in constraint.variants.items():
|
||||
if name not in variant_names:
|
||||
msg = f"variant {name} does not exist in {pkg.name}"
|
||||
errors.append(error_cls(summary=summary, details=[msg, f"in {filename}"]))
|
||||
continue
|
||||
|
||||
try:
|
||||
spack.variant.prevalidate_variant_value(pkg, v, constraint, strict=True)
|
||||
except (
|
||||
spack.variant.InconsistentValidationError,
|
||||
spack.variant.MultipleValuesInExclusiveVariantError,
|
||||
spack.variant.InvalidVariantValueError,
|
||||
) as e:
|
||||
msg = str(e).strip()
|
||||
errors.append(error_cls(summary=summary, details=[msg, f"in {filename}"]))
|
||||
variant, _ = pkg.variants[name]
|
||||
variant.validate_or_raise(v, pkg_cls=pkg)
|
||||
except variant_exceptions as e:
|
||||
summary = pkg.name + ': wrong variant in "{0}" directive'
|
||||
summary = summary.format(directive)
|
||||
filename = spack.repo.PATH.filename_for_package_name(pkg.name)
|
||||
|
||||
error_msg = str(e).strip()
|
||||
if isinstance(e, KeyError):
|
||||
error_msg = "the variant {0} does not exist".format(error_msg)
|
||||
|
||||
err = error_cls(summary=summary, details=[error_msg, "in " + filename])
|
||||
|
||||
errors.append(err)
|
||||
|
||||
return errors
|
||||
|
||||
@@ -1123,10 +1119,9 @@ def _extracts_errors(triggers, summary):
|
||||
for dname in dnames
|
||||
)
|
||||
|
||||
for when, variants_by_name in pkg_cls.variants.items():
|
||||
for vname, variant in variants_by_name.items():
|
||||
summary = f"{pkg_name}: wrong 'when=' condition for the '{vname}' variant"
|
||||
errors.extend(_extracts_errors([when], summary))
|
||||
for vname, (variant, triggers) in pkg_cls.variants.items():
|
||||
summary = f"{pkg_name}: wrong 'when=' condition for the '{vname}' variant"
|
||||
errors.extend(_extracts_errors(triggers, summary))
|
||||
|
||||
for when, providers, details in _error_items(pkg_cls.provided):
|
||||
errors.extend(
|
||||
|
@@ -33,6 +33,7 @@
|
||||
from llnl.util.symlink import readlink
|
||||
|
||||
import spack.caches
|
||||
import spack.cmd
|
||||
import spack.config as config
|
||||
import spack.database as spack_db
|
||||
import spack.error
|
||||
@@ -43,9 +44,9 @@
|
||||
import spack.oci.image
|
||||
import spack.oci.oci
|
||||
import spack.oci.opener
|
||||
import spack.paths
|
||||
import spack.platforms
|
||||
import spack.relocate as relocate
|
||||
import spack.repo
|
||||
import spack.spec
|
||||
import spack.stage
|
||||
import spack.store
|
||||
@@ -1446,9 +1447,7 @@ def _oci_push_pkg_blob(
|
||||
filename = os.path.join(tmpdir, f"{spec.dag_hash()}.tar.gz")
|
||||
|
||||
# Create an oci.image.layer aka tarball of the package
|
||||
compressed_tarfile_checksum, tarfile_checksum = _do_create_tarball(
|
||||
filename, spec.prefix, get_buildinfo_dict(spec)
|
||||
)
|
||||
compressed_tarfile_checksum, tarfile_checksum = spack.oci.oci.create_tarball(spec, filename)
|
||||
|
||||
blob = spack.oci.oci.Blob(
|
||||
Digest.from_sha256(compressed_tarfile_checksum),
|
||||
@@ -2698,9 +2697,6 @@ def get_keys(install=False, trust=False, force=False, mirrors=None):
|
||||
|
||||
for mirror in mirror_collection.values():
|
||||
fetch_url = mirror.fetch_url
|
||||
# TODO: oci:// does not support signing.
|
||||
if fetch_url.startswith("oci://"):
|
||||
continue
|
||||
keys_url = url_util.join(
|
||||
fetch_url, BUILD_CACHE_RELATIVE_PATH, BUILD_CACHE_KEYS_RELATIVE_PATH
|
||||
)
|
||||
|
@@ -14,7 +14,6 @@
|
||||
import spack.compilers
|
||||
import spack.config
|
||||
import spack.environment
|
||||
import spack.modules
|
||||
import spack.paths
|
||||
import spack.platforms
|
||||
import spack.repo
|
||||
|
@@ -37,10 +37,16 @@
|
||||
import spack.binary_distribution
|
||||
import spack.config
|
||||
import spack.detection
|
||||
import spack.environment
|
||||
import spack.modules
|
||||
import spack.paths
|
||||
import spack.platforms
|
||||
import spack.platforms.linux
|
||||
import spack.repo
|
||||
import spack.spec
|
||||
import spack.store
|
||||
import spack.user_environment
|
||||
import spack.util.environment
|
||||
import spack.util.executable
|
||||
import spack.util.path
|
||||
import spack.util.spack_yaml
|
||||
|
@@ -14,9 +14,9 @@
|
||||
from llnl.util import tty
|
||||
|
||||
import spack.environment
|
||||
import spack.spec
|
||||
import spack.tengine
|
||||
import spack.util.path
|
||||
import spack.util.cpus
|
||||
import spack.util.executable
|
||||
|
||||
from ._common import _root_spec
|
||||
from .config import root_path, spec_for_current_python, store_path
|
||||
|
@@ -53,7 +53,6 @@
|
||||
from llnl.util.tty.color import cescape, colorize
|
||||
from llnl.util.tty.log import MultiProcessFd
|
||||
|
||||
import spack.build_systems._checks
|
||||
import spack.build_systems.cmake
|
||||
import spack.build_systems.meson
|
||||
import spack.build_systems.python
|
||||
@@ -62,20 +61,26 @@
|
||||
import spack.config
|
||||
import spack.deptypes as dt
|
||||
import spack.error
|
||||
import spack.multimethod
|
||||
import spack.main
|
||||
import spack.package_base
|
||||
import spack.paths
|
||||
import spack.platforms
|
||||
import spack.repo
|
||||
import spack.schema.environment
|
||||
import spack.spec
|
||||
import spack.stage
|
||||
import spack.store
|
||||
import spack.subprocess_context
|
||||
import spack.user_environment
|
||||
import spack.util.executable
|
||||
import spack.util.path
|
||||
import spack.util.pattern
|
||||
from spack import traverse
|
||||
from spack.context import Context
|
||||
from spack.error import InstallError, NoHeadersError, NoLibrariesError
|
||||
from spack.error import NoHeadersError, NoLibrariesError
|
||||
from spack.install_test import spack_install_test_log
|
||||
from spack.installer import InstallError
|
||||
from spack.util.cpus import determine_number_of_jobs
|
||||
from spack.util.environment import (
|
||||
SYSTEM_DIR_CASE_ENTRY,
|
||||
EnvironmentModifications,
|
||||
@@ -450,7 +455,7 @@ def set_wrapper_variables(pkg, env):
|
||||
env.set(SPACK_DEBUG, "TRUE")
|
||||
env.set(SPACK_SHORT_SPEC, pkg.spec.short_spec)
|
||||
env.set(SPACK_DEBUG_LOG_ID, pkg.spec.format("{name}-{hash:7}"))
|
||||
env.set(SPACK_DEBUG_LOG_DIR, spack.paths.spack_working_dir)
|
||||
env.set(SPACK_DEBUG_LOG_DIR, spack.main.spack_working_dir)
|
||||
|
||||
if spack.config.get("config:ccache"):
|
||||
# Enable ccache in the compiler wrapper
|
||||
@@ -557,7 +562,7 @@ def set_package_py_globals(pkg, context: Context = Context.BUILD):
|
||||
module.std_meson_args = spack.build_systems.meson.MesonBuilder.std_args(pkg)
|
||||
module.std_pip_args = spack.build_systems.python.PythonPipBuilder.std_args(pkg)
|
||||
|
||||
jobs = spack.config.determine_number_of_jobs(parallel=pkg.parallel)
|
||||
jobs = determine_number_of_jobs(parallel=pkg.parallel)
|
||||
module.make_jobs = jobs
|
||||
|
||||
# TODO: make these build deps that can be installed if not found.
|
||||
@@ -1134,7 +1139,7 @@ def _setup_pkg_and_run(
|
||||
return_value = function(pkg, kwargs)
|
||||
write_pipe.send(return_value)
|
||||
|
||||
except spack.error.StopPhase as e:
|
||||
except StopPhase as e:
|
||||
# Do not create a full ChildError from this, it's not an error
|
||||
# it's a control statement.
|
||||
write_pipe.send(e)
|
||||
@@ -1295,7 +1300,7 @@ def exitcode_msg(p):
|
||||
p.join()
|
||||
|
||||
# If returns a StopPhase, raise it
|
||||
if isinstance(child_result, spack.error.StopPhase):
|
||||
if isinstance(child_result, StopPhase):
|
||||
# do not print
|
||||
raise child_result
|
||||
|
||||
@@ -1504,6 +1509,17 @@ def _make_child_error(msg, module, name, traceback, log, log_type, context):
|
||||
return ChildError(msg, module, name, traceback, log, log_type, context)
|
||||
|
||||
|
||||
class StopPhase(spack.error.SpackError):
|
||||
"""Pickle-able exception to control stopped builds."""
|
||||
|
||||
def __reduce__(self):
|
||||
return _make_stop_phase, (self.message, self.long_message)
|
||||
|
||||
|
||||
def _make_stop_phase(msg, long_msg):
|
||||
return StopPhase(msg, long_msg)
|
||||
|
||||
|
||||
def write_log_summary(out, log_type, log, last=None):
|
||||
errors, warnings = parse_log_events(log)
|
||||
nerr = len(errors)
|
||||
|
@@ -8,7 +8,7 @@
|
||||
import llnl.util.lang
|
||||
|
||||
import spack.builder
|
||||
import spack.error
|
||||
import spack.installer
|
||||
import spack.relocate
|
||||
import spack.spec
|
||||
import spack.store
|
||||
@@ -34,7 +34,7 @@ def check_paths(path_list, filetype, predicate):
|
||||
if not predicate(abs_path):
|
||||
msg = "Install failed for {0}. No such {1} in prefix: {2}"
|
||||
msg = msg.format(pkg.name, filetype, path)
|
||||
raise spack.error.InstallError(msg)
|
||||
raise spack.installer.InstallError(msg)
|
||||
|
||||
check_paths(pkg.sanity_check_is_file, "file", os.path.isfile)
|
||||
check_paths(pkg.sanity_check_is_dir, "directory", os.path.isdir)
|
||||
@@ -42,7 +42,7 @@ def check_paths(path_list, filetype, predicate):
|
||||
ignore_file = llnl.util.lang.match_predicate(spack.store.STORE.layout.hidden_file_regexes)
|
||||
if all(map(ignore_file, os.listdir(pkg.prefix))):
|
||||
msg = "Install failed for {0}. Nothing was installed!"
|
||||
raise spack.error.InstallError(msg.format(pkg.name))
|
||||
raise spack.installer.InstallError(msg.format(pkg.name))
|
||||
|
||||
|
||||
def apply_macos_rpath_fixups(builder: spack.builder.Builder):
|
||||
|
@@ -13,7 +13,6 @@
|
||||
|
||||
import spack.build_environment
|
||||
import spack.builder
|
||||
import spack.error
|
||||
import spack.package_base
|
||||
from spack.directives import build_system, conflicts, depends_on
|
||||
from spack.multimethod import when
|
||||
@@ -249,7 +248,7 @@ def runs_ok(script_abs_path):
|
||||
|
||||
# An external gnuconfig may not not have a prefix.
|
||||
if gnuconfig_dir is None:
|
||||
raise spack.error.InstallError(
|
||||
raise spack.build_environment.InstallError(
|
||||
"Spack could not find substitutes for GNU config files because no "
|
||||
"prefix is available for the `gnuconfig` package. Make sure you set a "
|
||||
"prefix path instead of modules for external `gnuconfig`."
|
||||
@@ -269,7 +268,7 @@ def runs_ok(script_abs_path):
|
||||
msg += (
|
||||
" or the `gnuconfig` package prefix is misconfigured as" " an external package"
|
||||
)
|
||||
raise spack.error.InstallError(msg)
|
||||
raise spack.build_environment.InstallError(msg)
|
||||
|
||||
# Filter working substitutes
|
||||
candidates = [f for f in candidates if runs_ok(f)]
|
||||
@@ -294,7 +293,9 @@ def runs_ok(script_abs_path):
|
||||
and set the prefix to the directory containing the `config.guess` and
|
||||
`config.sub` files.
|
||||
"""
|
||||
raise spack.error.InstallError(msg.format(", ".join(to_be_found), self.name))
|
||||
raise spack.build_environment.InstallError(
|
||||
msg.format(", ".join(to_be_found), self.name)
|
||||
)
|
||||
|
||||
# Copy the good files over the bad ones
|
||||
for abs_path in to_be_patched:
|
||||
@@ -687,8 +688,9 @@ def _activate_or_not(
|
||||
|
||||
variant = variant or name
|
||||
|
||||
# Defensively look that the name passed as argument is among variants
|
||||
if not self.pkg.has_variant(variant):
|
||||
# Defensively look that the name passed as argument is among
|
||||
# variants
|
||||
if variant not in self.pkg.variants:
|
||||
msg = '"{0}" is not a variant of "{1}"'
|
||||
raise KeyError(msg.format(variant, self.pkg.name))
|
||||
|
||||
@@ -697,19 +699,27 @@ def _activate_or_not(
|
||||
|
||||
# Create a list of pairs. Each pair includes a configuration
|
||||
# option and whether or not that option is activated
|
||||
vdef = self.pkg.get_variant(variant)
|
||||
if set(vdef.values) == set((True, False)):
|
||||
variant_desc, _ = self.pkg.variants[variant]
|
||||
if set(variant_desc.values) == set((True, False)):
|
||||
# BoolValuedVariant carry information about a single option.
|
||||
# Nonetheless, for uniformity of treatment we'll package them
|
||||
# in an iterable of one element.
|
||||
options = [(name, f"+{variant}" in spec)]
|
||||
condition = "+{name}".format(name=variant)
|
||||
options = [(name, condition in spec)]
|
||||
else:
|
||||
condition = "{variant}={value}"
|
||||
# "feature_values" is used to track values which correspond to
|
||||
# features which can be enabled or disabled as understood by the
|
||||
# package's build system. It excludes values which have special
|
||||
# meanings and do not correspond to features (e.g. "none")
|
||||
feature_values = getattr(vdef.values, "feature_values", None) or vdef.values
|
||||
options = [(value, f"{variant}={value}" in spec) for value in feature_values]
|
||||
feature_values = (
|
||||
getattr(variant_desc.values, "feature_values", None) or variant_desc.values
|
||||
)
|
||||
|
||||
options = [
|
||||
(value, condition.format(variant=variant, value=value) in spec)
|
||||
for value in feature_values
|
||||
]
|
||||
|
||||
# For each allowed value in the list of values
|
||||
for option_value, activated in options:
|
||||
|
@@ -89,7 +89,7 @@ def define_cmake_cache_from_variant(self, cmake_var, variant=None, comment=""):
|
||||
if variant is None:
|
||||
variant = cmake_var.lower()
|
||||
|
||||
if not self.pkg.has_variant(variant):
|
||||
if variant not in self.pkg.variants:
|
||||
raise KeyError('"{0}" is not a variant of "{1}"'.format(variant, self.pkg.name))
|
||||
|
||||
if variant not in self.pkg.spec.variants:
|
||||
|
@@ -15,7 +15,6 @@
|
||||
import spack.build_environment
|
||||
import spack.builder
|
||||
import spack.deptypes as dt
|
||||
import spack.error
|
||||
import spack.package_base
|
||||
from spack.directives import build_system, conflicts, depends_on, variant
|
||||
from spack.multimethod import when
|
||||
@@ -146,7 +145,6 @@ def _values(x):
|
||||
default=default,
|
||||
values=_values,
|
||||
description="the build system generator to use",
|
||||
when="build_system=cmake",
|
||||
)
|
||||
for x in not_used:
|
||||
conflicts(f"generator={x}")
|
||||
@@ -346,7 +344,7 @@ def std_args(pkg, generator=None):
|
||||
msg = "Invalid CMake generator: '{0}'\n".format(generator)
|
||||
msg += "CMakePackage currently supports the following "
|
||||
msg += "primary generators: '{0}'".format("', '".join(valid_primary_generators))
|
||||
raise spack.error.InstallError(msg)
|
||||
raise spack.package_base.InstallError(msg)
|
||||
|
||||
try:
|
||||
build_type = pkg.spec.variants["build_type"].value
|
||||
@@ -506,7 +504,7 @@ def define_from_variant(self, cmake_var, variant=None):
|
||||
if variant is None:
|
||||
variant = cmake_var.lower()
|
||||
|
||||
if not self.pkg.has_variant(variant):
|
||||
if variant not in self.pkg.variants:
|
||||
raise KeyError('"{0}" is not a variant of "{1}"'.format(variant, self.pkg.name))
|
||||
|
||||
if variant not in self.pkg.spec.variants:
|
||||
|
@@ -14,7 +14,6 @@
|
||||
|
||||
import spack.compiler
|
||||
import spack.package_base
|
||||
import spack.util.executable
|
||||
|
||||
# Local "type" for type hints
|
||||
Path = Union[str, pathlib.Path]
|
||||
|
@@ -22,10 +22,9 @@
|
||||
install,
|
||||
)
|
||||
|
||||
import spack.builder
|
||||
import spack.error
|
||||
from spack.build_environment import dso_suffix
|
||||
from spack.error import InstallError
|
||||
from spack.package_base import InstallError
|
||||
from spack.util.environment import EnvironmentModifications
|
||||
from spack.util.executable import Executable
|
||||
from spack.util.prefix import Prefix
|
||||
|
@@ -15,7 +15,7 @@
|
||||
import spack.util.path
|
||||
from spack.build_environment import dso_suffix
|
||||
from spack.directives import conflicts, license, redistribute, variant
|
||||
from spack.error import InstallError
|
||||
from spack.package_base import InstallError
|
||||
from spack.util.environment import EnvironmentModifications
|
||||
from spack.util.executable import Executable
|
||||
|
||||
|
@@ -24,8 +24,6 @@
|
||||
import spack.detection
|
||||
import spack.multimethod
|
||||
import spack.package_base
|
||||
import spack.platforms
|
||||
import spack.repo
|
||||
import spack.spec
|
||||
import spack.store
|
||||
from spack.directives import build_system, depends_on, extends
|
||||
|
@@ -11,9 +11,9 @@
|
||||
|
||||
import spack.builder
|
||||
from spack.build_environment import SPACK_NO_PARALLEL_MAKE
|
||||
from spack.config import determine_number_of_jobs
|
||||
from spack.directives import build_system, extends, maintainers
|
||||
from spack.package_base import PackageBase
|
||||
from spack.util.cpus import determine_number_of_jobs
|
||||
from spack.util.environment import env_flag
|
||||
from spack.util.executable import Executable, ProcessError
|
||||
|
||||
|
@@ -10,7 +10,7 @@
|
||||
|
||||
from llnl.util import lang
|
||||
|
||||
import spack.error
|
||||
import spack.build_environment
|
||||
import spack.multimethod
|
||||
|
||||
#: Builder classes, as registered by the "builder" decorator
|
||||
@@ -461,13 +461,15 @@ def _on_phase_start(self, instance):
|
||||
# If a phase has a matching stop_before_phase attribute,
|
||||
# stop the installation process raising a StopPhase
|
||||
if getattr(instance, "stop_before_phase", None) == self.name:
|
||||
raise spack.error.StopPhase("Stopping before '{0}' phase".format(self.name))
|
||||
raise spack.build_environment.StopPhase(
|
||||
"Stopping before '{0}' phase".format(self.name)
|
||||
)
|
||||
|
||||
def _on_phase_exit(self, instance):
|
||||
# If a phase has a matching last_phase attribute,
|
||||
# stop the installation process raising a StopPhase
|
||||
if getattr(instance, "last_phase", None) == self.name:
|
||||
raise spack.error.StopPhase("Stopping at '{0}' phase".format(self.name))
|
||||
raise spack.build_environment.StopPhase("Stopping at '{0}' phase".format(self.name))
|
||||
|
||||
def copy(self):
|
||||
return copy.deepcopy(self)
|
||||
|
@@ -11,7 +11,9 @@
|
||||
from llnl.util.filesystem import mkdirp
|
||||
|
||||
import spack.config
|
||||
import spack.error
|
||||
import spack.fetch_strategy
|
||||
import spack.mirror
|
||||
import spack.paths
|
||||
import spack.util.file_cache
|
||||
import spack.util.path
|
||||
|
@@ -31,7 +31,6 @@
|
||||
|
||||
import spack
|
||||
import spack.binary_distribution as bindist
|
||||
import spack.concretize
|
||||
import spack.config as cfg
|
||||
import spack.environment as ev
|
||||
import spack.main
|
||||
@@ -39,6 +38,7 @@
|
||||
import spack.paths
|
||||
import spack.repo
|
||||
import spack.spec
|
||||
import spack.stage
|
||||
import spack.util.git
|
||||
import spack.util.gpg as gpg_util
|
||||
import spack.util.spack_yaml as syaml
|
||||
@@ -1219,8 +1219,8 @@ def main_script_replacements(cmd):
|
||||
# Capture the version of Spack used to generate the pipeline, that can be
|
||||
# passed to `git checkout` for version consistency. If we aren't in a Git
|
||||
# repository, presume we are a Spack release and use the Git tag instead.
|
||||
spack_version = spack.get_version()
|
||||
version_to_clone = spack.get_spack_commit() or f"v{spack.spack_version}"
|
||||
spack_version = spack.main.get_version()
|
||||
version_to_clone = spack.main.get_spack_commit() or f"v{spack.spack_version}"
|
||||
|
||||
output_object["variables"] = {
|
||||
"SPACK_ARTIFACTS_ROOT": rel_artifacts_root,
|
||||
|
@@ -17,7 +17,7 @@
|
||||
from llnl.util.tty.colify import colify
|
||||
from llnl.util.tty.color import colorize
|
||||
|
||||
import spack.config # breaks a cycle.
|
||||
import spack.config
|
||||
import spack.environment as ev
|
||||
import spack.error
|
||||
import spack.extensions
|
||||
|
@@ -11,7 +11,6 @@
|
||||
import llnl.util.tty.color as color
|
||||
|
||||
import spack.platforms
|
||||
import spack.spec
|
||||
|
||||
description = "print architecture information about this machine"
|
||||
section = "system"
|
||||
|
@@ -16,11 +16,11 @@
|
||||
import spack.bootstrap.config
|
||||
import spack.bootstrap.core
|
||||
import spack.config
|
||||
import spack.main
|
||||
import spack.mirror
|
||||
import spack.spec
|
||||
import spack.stage
|
||||
import spack.util.path
|
||||
import spack.util.spack_yaml
|
||||
from spack.cmd.common import arguments
|
||||
|
||||
description = "manage bootstrap configuration"
|
||||
|
@@ -23,9 +23,14 @@
|
||||
import spack.error
|
||||
import spack.mirror
|
||||
import spack.oci.oci
|
||||
import spack.oci.opener
|
||||
import spack.relocate
|
||||
import spack.repo
|
||||
import spack.spec
|
||||
import spack.stage
|
||||
import spack.store
|
||||
import spack.user_environment
|
||||
import spack.util.crypto
|
||||
import spack.util.parallel
|
||||
import spack.util.url as url_util
|
||||
import spack.util.web as web_util
|
||||
|
@@ -4,7 +4,6 @@
|
||||
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
|
||||
|
||||
import spack.cmd
|
||||
import spack.spec
|
||||
from spack.cmd.common import arguments
|
||||
|
||||
description = "change an existing spec in an environment"
|
||||
|
@@ -15,6 +15,7 @@
|
||||
import spack.repo
|
||||
import spack.spec
|
||||
import spack.stage
|
||||
import spack.util.crypto
|
||||
import spack.util.web as web_util
|
||||
from spack.cmd.common import arguments
|
||||
from spack.package_base import (
|
||||
|
@@ -19,6 +19,7 @@
|
||||
import spack.cmd.buildcache as buildcache
|
||||
import spack.config as cfg
|
||||
import spack.environment as ev
|
||||
import spack.environment.depfile
|
||||
import spack.hash_types as ht
|
||||
import spack.mirror
|
||||
import spack.util.gpg as gpg_util
|
||||
|
@@ -10,9 +10,11 @@
|
||||
import llnl.util.filesystem
|
||||
import llnl.util.tty as tty
|
||||
|
||||
import spack.bootstrap
|
||||
import spack.caches
|
||||
import spack.cmd
|
||||
import spack.cmd.test
|
||||
import spack.config
|
||||
import spack.repo
|
||||
import spack.stage
|
||||
import spack.store
|
||||
import spack.util.path
|
||||
|
@@ -17,7 +17,6 @@
|
||||
from llnl.util.tty.colify import colify
|
||||
|
||||
import spack.cmd
|
||||
import spack.config
|
||||
import spack.main
|
||||
import spack.paths
|
||||
import spack.platforms
|
||||
|
@@ -15,6 +15,7 @@
|
||||
import spack.deptypes as dt
|
||||
import spack.environment as ev
|
||||
import spack.mirror
|
||||
import spack.modules
|
||||
import spack.reporters
|
||||
import spack.spec
|
||||
import spack.store
|
||||
|
@@ -9,7 +9,6 @@
|
||||
import llnl.util.tty as tty
|
||||
|
||||
import spack.cmd
|
||||
import spack.spec
|
||||
|
||||
display_args = {"long": True, "show_flags": False, "variants": False, "indent": 4}
|
||||
|
||||
|
@@ -10,6 +10,7 @@
|
||||
import spack.cmd
|
||||
import spack.deptypes as dt
|
||||
import spack.error
|
||||
import spack.paths
|
||||
import spack.spec
|
||||
import spack.store
|
||||
from spack import build_environment, traverse
|
||||
|
@@ -13,9 +13,9 @@
|
||||
|
||||
import spack.config
|
||||
import spack.environment as ev
|
||||
import spack.error
|
||||
import spack.repo
|
||||
import spack.schema.env
|
||||
import spack.spec
|
||||
import spack.schema.packages
|
||||
import spack.store
|
||||
import spack.util.spack_yaml as syaml
|
||||
from spack.cmd.common import arguments
|
||||
@@ -256,7 +256,7 @@ def config_remove(args):
|
||||
existing.pop(value, None)
|
||||
else:
|
||||
# This should be impossible to reach
|
||||
raise spack.error.ConfigError("Config has nested non-dict values")
|
||||
raise spack.config.ConfigError("Config has nested non-dict values")
|
||||
|
||||
spack.config.set(path, existing, scope)
|
||||
|
||||
@@ -340,7 +340,7 @@ def _config_change(config_path, match_spec_str=None):
|
||||
if not changed:
|
||||
existing_requirements = spack.config.get(key_path)
|
||||
if isinstance(existing_requirements, str):
|
||||
raise spack.error.ConfigError(
|
||||
raise spack.config.ConfigError(
|
||||
"'config change' needs to append a requirement,"
|
||||
" but existing require: config is not a list"
|
||||
)
|
||||
@@ -536,11 +536,11 @@ def config_prefer_upstream(args):
|
||||
# Get and list all the variants that differ from the default.
|
||||
variants = []
|
||||
for var_name, variant in spec.variants.items():
|
||||
if var_name in ["patches"] or not spec.package.has_variant(var_name):
|
||||
if var_name in ["patches"] or var_name not in spec.package.variants:
|
||||
continue
|
||||
|
||||
vdef = spec.package.get_variant(var_name)
|
||||
if variant.value != vdef.default:
|
||||
variant_desc, _ = spec.package.variants[var_name]
|
||||
if variant.value != variant_desc.default:
|
||||
variants.append(str(variant))
|
||||
variants.sort()
|
||||
variants = " ".join(variants)
|
||||
|
@@ -13,6 +13,7 @@
|
||||
|
||||
import spack.repo
|
||||
import spack.stage
|
||||
import spack.util.web
|
||||
from spack.spec import Spec
|
||||
from spack.url import (
|
||||
UndetectableNameError,
|
||||
|
@@ -13,12 +13,11 @@
|
||||
import llnl.util.tty as tty
|
||||
from llnl.util.filesystem import working_dir
|
||||
|
||||
import spack
|
||||
import spack.config
|
||||
import spack.paths
|
||||
import spack.platforms
|
||||
import spack.spec
|
||||
import spack.store
|
||||
import spack.util.git
|
||||
from spack.main import get_version
|
||||
from spack.util.executable import which
|
||||
|
||||
description = "debugging commands for troubleshooting Spack"
|
||||
@@ -90,7 +89,7 @@ def report(args):
|
||||
host_os = host_platform.operating_system("frontend")
|
||||
host_target = host_platform.target("frontend")
|
||||
architecture = spack.spec.ArchSpec((str(host_platform), str(host_os), str(host_target)))
|
||||
print("* **Spack:**", spack.get_version())
|
||||
print("* **Spack:**", get_version())
|
||||
print("* **Python:**", platform.python_version())
|
||||
print("* **Platform:**", architecture)
|
||||
|
||||
|
@@ -11,6 +11,7 @@
|
||||
import spack.cmd
|
||||
import spack.environment as ev
|
||||
import spack.package_base
|
||||
import spack.repo
|
||||
import spack.store
|
||||
from spack.cmd.common import arguments
|
||||
|
||||
|
@@ -8,9 +8,7 @@
|
||||
|
||||
import llnl.util.tty as tty
|
||||
|
||||
import spack.build_environment
|
||||
import spack.cmd
|
||||
import spack.cmd.common.arguments
|
||||
import spack.config
|
||||
import spack.repo
|
||||
from spack.cmd.common import arguments
|
||||
|
@@ -10,6 +10,7 @@
|
||||
import spack.cmd
|
||||
import spack.config
|
||||
import spack.fetch_strategy
|
||||
import spack.package_base
|
||||
import spack.repo
|
||||
import spack.spec
|
||||
import spack.stage
|
||||
|
@@ -12,6 +12,7 @@
|
||||
import spack.cmd
|
||||
import spack.environment as ev
|
||||
import spack.solver.asp as asp
|
||||
import spack.util.environment
|
||||
import spack.util.spack_json as sjson
|
||||
from spack.cmd.common import arguments
|
||||
|
||||
|
@@ -21,12 +21,15 @@
|
||||
import spack.cmd
|
||||
import spack.cmd.common
|
||||
import spack.cmd.common.arguments
|
||||
import spack.cmd.install
|
||||
import spack.cmd.modules
|
||||
import spack.cmd.uninstall
|
||||
import spack.config
|
||||
import spack.environment as ev
|
||||
import spack.environment.depfile as depfile
|
||||
import spack.environment.environment
|
||||
import spack.environment.shell
|
||||
import spack.schema.env
|
||||
import spack.spec
|
||||
import spack.tengine
|
||||
from spack.cmd.common import arguments
|
||||
from spack.util.environment import EnvironmentModifications
|
||||
|
@@ -18,9 +18,9 @@
|
||||
import spack.cray_manifest as cray_manifest
|
||||
import spack.detection
|
||||
import spack.error
|
||||
import spack.package_base
|
||||
import spack.repo
|
||||
import spack.spec
|
||||
import spack.util.environment
|
||||
from spack.cmd.common import arguments
|
||||
|
||||
description = "manage external packages in Spack configuration"
|
||||
|
@@ -8,6 +8,7 @@
|
||||
import spack.cmd
|
||||
import spack.config
|
||||
import spack.environment as ev
|
||||
import spack.repo
|
||||
import spack.traverse
|
||||
from spack.cmd.common import arguments
|
||||
|
||||
|
@@ -10,11 +10,10 @@
|
||||
import llnl.util.tty as tty
|
||||
import llnl.util.tty.color as color
|
||||
|
||||
import spack.bootstrap
|
||||
import spack.cmd as cmd
|
||||
import spack.config
|
||||
import spack.environment as ev
|
||||
import spack.repo
|
||||
import spack.spec
|
||||
import spack.store
|
||||
from spack.cmd.common import arguments
|
||||
from spack.database import InstallStatuses
|
||||
|
@@ -16,7 +16,6 @@
|
||||
import spack.install_test
|
||||
import spack.repo
|
||||
import spack.spec
|
||||
import spack.variant
|
||||
import spack.version
|
||||
from spack.cmd.common import arguments
|
||||
from spack.package_base import preferred_version
|
||||
@@ -334,6 +333,26 @@ def _fmt_variant(variant, max_name_default_len, indent, when=None, out=None):
|
||||
out.write("\n")
|
||||
|
||||
|
||||
def _variants_by_name_when(pkg):
|
||||
"""Adaptor to get variants keyed by { name: { when: { [Variant...] } }."""
|
||||
# TODO: replace with pkg.variants_by_name(when=True) when unified directive dicts are merged.
|
||||
variants = {}
|
||||
for name, (variant, whens) in sorted(pkg.variants.items()):
|
||||
for when in whens:
|
||||
variants.setdefault(name, {}).setdefault(when, []).append(variant)
|
||||
return variants
|
||||
|
||||
|
||||
def _variants_by_when_name(pkg):
|
||||
"""Adaptor to get variants keyed by { when: { name: Variant } }"""
|
||||
# TODO: replace with pkg.variants when unified directive dicts are merged.
|
||||
variants = {}
|
||||
for name, (variant, whens) in pkg.variants.items():
|
||||
for when in whens:
|
||||
variants.setdefault(when, {})[name] = variant
|
||||
return variants
|
||||
|
||||
|
||||
def _print_variants_header(pkg):
|
||||
"""output variants"""
|
||||
|
||||
@@ -344,22 +363,32 @@ def _print_variants_header(pkg):
|
||||
color.cprint("")
|
||||
color.cprint(section_title("Variants:"))
|
||||
|
||||
variants_by_name = _variants_by_name_when(pkg)
|
||||
|
||||
# Calculate the max length of the "name [default]" part of the variant display
|
||||
# This lets us know where to print variant values.
|
||||
max_name_default_len = max(
|
||||
color.clen(_fmt_name_and_default(variant))
|
||||
for name in pkg.variant_names()
|
||||
for _, variant in pkg.variant_definitions(name)
|
||||
for name, when_variants in variants_by_name.items()
|
||||
for variants in when_variants.values()
|
||||
for variant in variants
|
||||
)
|
||||
|
||||
return max_name_default_len
|
||||
return max_name_default_len, variants_by_name
|
||||
|
||||
|
||||
def _unconstrained_ver_first(item):
|
||||
"""sort key that puts specs with open version ranges first"""
|
||||
spec, _ = item
|
||||
return (spack.version.any_version not in spec.versions, spec)
|
||||
|
||||
|
||||
def print_variants_grouped_by_when(pkg):
|
||||
max_name_default_len = _print_variants_header(pkg)
|
||||
max_name_default_len, _ = _print_variants_header(pkg)
|
||||
|
||||
indent = 4
|
||||
for when, variants_by_name in pkg.variant_items():
|
||||
variants = _variants_by_when_name(pkg)
|
||||
for when, variants_by_name in sorted(variants.items(), key=_unconstrained_ver_first):
|
||||
padded_values = max_name_default_len + 4
|
||||
start_indent = indent
|
||||
|
||||
@@ -377,14 +406,15 @@ def print_variants_grouped_by_when(pkg):
|
||||
|
||||
|
||||
def print_variants_by_name(pkg):
|
||||
max_name_default_len = _print_variants_header(pkg)
|
||||
max_name_default_len, variants_by_name = _print_variants_header(pkg)
|
||||
max_name_default_len += 4
|
||||
|
||||
indent = 4
|
||||
for name in pkg.variant_names():
|
||||
for when, variant in pkg.variant_definitions(name):
|
||||
_fmt_variant(variant, max_name_default_len, indent, when, out=sys.stdout)
|
||||
sys.stdout.write("\n")
|
||||
for name, when_variants in variants_by_name.items():
|
||||
for when, variants in sorted(when_variants.items(), key=_unconstrained_ver_first):
|
||||
for variant in variants:
|
||||
_fmt_variant(variant, max_name_default_len, indent, when, out=sys.stdout)
|
||||
sys.stdout.write("\n")
|
||||
|
||||
|
||||
def print_variants(pkg, args):
|
||||
|
@@ -13,15 +13,18 @@
|
||||
from llnl.string import plural
|
||||
from llnl.util import lang, tty
|
||||
|
||||
import spack.build_environment
|
||||
import spack.cmd
|
||||
import spack.config
|
||||
import spack.environment as ev
|
||||
import spack.fetch_strategy
|
||||
import spack.package_base
|
||||
import spack.paths
|
||||
import spack.report
|
||||
import spack.spec
|
||||
import spack.store
|
||||
from spack.cmd.common import arguments
|
||||
from spack.error import InstallError, SpackError
|
||||
from spack.error import SpackError
|
||||
from spack.installer import PackageInstaller
|
||||
|
||||
description = "build and install packages"
|
||||
@@ -284,7 +287,7 @@ def require_user_confirmation_for_overwrite(concrete_specs, args):
|
||||
tty.die("Reinstallation aborted.")
|
||||
|
||||
|
||||
def _dump_log_on_error(e: InstallError):
|
||||
def _dump_log_on_error(e: spack.build_environment.InstallError):
|
||||
e.print_context()
|
||||
assert e.pkg, "Expected InstallError to include the associated package"
|
||||
if not os.path.exists(e.pkg.log_path):
|
||||
@@ -349,7 +352,7 @@ def reporter_factory(specs):
|
||||
install_with_active_env(env, args, install_kwargs, reporter_factory)
|
||||
else:
|
||||
install_without_active_env(args, install_kwargs, reporter_factory)
|
||||
except InstallError as e:
|
||||
except spack.build_environment.InstallError as e:
|
||||
if args.show_log_on_error:
|
||||
_dump_log_on_error(e)
|
||||
raise
|
||||
|
@@ -6,10 +6,11 @@
|
||||
import sys
|
||||
|
||||
import spack.cmd
|
||||
import spack.cmd.common
|
||||
import spack.cmd.find
|
||||
import spack.environment as ev
|
||||
import spack.store
|
||||
import spack.user_environment as uenv
|
||||
import spack.util.environment
|
||||
from spack.cmd.common import arguments
|
||||
|
||||
description = "add package to the user environment"
|
||||
|
@@ -8,6 +8,9 @@
|
||||
from llnl.util import tty
|
||||
|
||||
import spack.cmd
|
||||
import spack.error
|
||||
import spack.package_base
|
||||
import spack.repo
|
||||
import spack.store
|
||||
from spack.cmd.common import arguments
|
||||
from spack.database import InstallStatuses
|
||||
|
@@ -17,6 +17,7 @@
|
||||
import spack.mirror
|
||||
import spack.repo
|
||||
import spack.spec
|
||||
import spack.util.path
|
||||
import spack.util.web as web_util
|
||||
from spack.cmd.common import arguments
|
||||
from spack.error import SpackError
|
||||
|
@@ -15,7 +15,6 @@
|
||||
|
||||
import spack.cmd
|
||||
import spack.config
|
||||
import spack.error
|
||||
import spack.modules
|
||||
import spack.modules.common
|
||||
import spack.repo
|
||||
@@ -125,13 +124,13 @@ def check_module_set_name(name):
|
||||
names = [k for k in modules if k != "prefix_inspections"]
|
||||
|
||||
if not names:
|
||||
raise spack.error.ConfigError(
|
||||
raise spack.config.ConfigError(
|
||||
f"Module set configuration is missing. Cannot use module set '{name}'"
|
||||
)
|
||||
|
||||
pretty_names = "', '".join(names)
|
||||
|
||||
raise spack.error.ConfigError(
|
||||
raise spack.config.ConfigError(
|
||||
f"Cannot use invalid module set '{name}'.",
|
||||
f"Valid module set names are: '{pretty_names}'.",
|
||||
)
|
||||
|
@@ -9,6 +9,7 @@
|
||||
import spack.config
|
||||
import spack.environment as ev
|
||||
import spack.package_base
|
||||
import spack.repo
|
||||
import spack.traverse
|
||||
from spack.cmd.common import arguments
|
||||
|
||||
|
@@ -12,6 +12,7 @@
|
||||
from llnl.util.tty.colify import colify
|
||||
|
||||
import spack.cmd
|
||||
import spack.paths
|
||||
import spack.repo
|
||||
import spack.util.executable as exe
|
||||
import spack.util.package_hash as ph
|
||||
|
@@ -78,8 +78,8 @@ def python(parser, args, unknown_args):
|
||||
|
||||
# Run user choice of interpreter
|
||||
if args.python_interpreter == "ipython":
|
||||
return ipython_interpreter(args)
|
||||
return python_interpreter(args)
|
||||
return spack.cmd.python.ipython_interpreter(args)
|
||||
return spack.cmd.python.python_interpreter(args)
|
||||
|
||||
|
||||
def ipython_interpreter(args):
|
||||
|
@@ -6,6 +6,7 @@
|
||||
import llnl.util.tty as tty
|
||||
|
||||
import spack.cmd
|
||||
import spack.repo
|
||||
from spack.cmd.common import arguments
|
||||
|
||||
description = "revert checked out package source code"
|
||||
|
@@ -12,12 +12,11 @@
|
||||
|
||||
import spack
|
||||
import spack.cmd
|
||||
import spack.cmd.common.arguments
|
||||
import spack.config
|
||||
import spack.environment
|
||||
import spack.hash_types as ht
|
||||
import spack.package_base
|
||||
import spack.solver.asp as asp
|
||||
import spack.spec
|
||||
from spack.cmd.common import arguments
|
||||
|
||||
description = "concretize a specs using an ASP solver"
|
||||
|
@@ -14,7 +14,6 @@
|
||||
import spack.hash_types as ht
|
||||
import spack.spec
|
||||
import spack.store
|
||||
import spack.traverse
|
||||
from spack.cmd.common import arguments
|
||||
|
||||
description = "show what would be installed, given a spec"
|
||||
|
@@ -11,6 +11,8 @@
|
||||
import spack.config
|
||||
import spack.environment as ev
|
||||
import spack.package_base
|
||||
import spack.repo
|
||||
import spack.stage
|
||||
import spack.traverse
|
||||
from spack.cmd.common import arguments
|
||||
|
||||
|
@@ -9,8 +9,8 @@
|
||||
import llnl.util.tty as tty
|
||||
import llnl.util.tty.colify as colify
|
||||
|
||||
import spack.environment
|
||||
import spack.repo
|
||||
import spack.store
|
||||
import spack.tag
|
||||
|
||||
description = "show package tags and associated packages"
|
||||
|
@@ -15,12 +15,11 @@
|
||||
from llnl.util.tty import colify
|
||||
|
||||
import spack.cmd
|
||||
import spack.config
|
||||
import spack.environment as ev
|
||||
import spack.install_test
|
||||
import spack.package_base
|
||||
import spack.repo
|
||||
import spack.report
|
||||
import spack.store
|
||||
from spack.cmd.common import arguments
|
||||
|
||||
description = "run spack's tests for an install"
|
||||
|
@@ -10,7 +10,6 @@
|
||||
from llnl.util.filesystem import working_dir
|
||||
|
||||
import spack
|
||||
import spack.cmd
|
||||
import spack.config
|
||||
import spack.paths
|
||||
import spack.util.git
|
||||
|
@@ -6,7 +6,6 @@
|
||||
import llnl.util.tty as tty
|
||||
|
||||
import spack.cmd
|
||||
import spack.config
|
||||
from spack.cmd.common import arguments
|
||||
|
||||
description = "remove specs from an environment"
|
||||
|
@@ -10,8 +10,6 @@
|
||||
import re
|
||||
import sys
|
||||
|
||||
import spack.extensions
|
||||
|
||||
try:
|
||||
import pytest
|
||||
except ImportError:
|
||||
|
@@ -7,10 +7,9 @@
|
||||
import sys
|
||||
|
||||
import spack.cmd
|
||||
import spack.cmd.common
|
||||
import spack.error
|
||||
import spack.store
|
||||
import spack.user_environment as uenv
|
||||
import spack.util.environment
|
||||
from spack.cmd.common import arguments
|
||||
|
||||
description = "remove package from the user environment"
|
||||
|
@@ -6,7 +6,6 @@
|
||||
|
||||
import llnl.util.tty as tty
|
||||
|
||||
import spack.cmd
|
||||
import spack.environment as ev
|
||||
import spack.store
|
||||
import spack.verify
|
||||
|
@@ -25,6 +25,7 @@
|
||||
import spack.platforms
|
||||
import spack.repo
|
||||
import spack.spec
|
||||
import spack.version
|
||||
from spack.operating_systems import windows_os
|
||||
from spack.util.environment import get_path
|
||||
from spack.util.naming import mod_to_class
|
||||
|
@@ -8,6 +8,7 @@
|
||||
|
||||
import spack.compiler
|
||||
import spack.compilers.clang
|
||||
import spack.util.executable
|
||||
from spack.version import Version
|
||||
|
||||
|
||||
|
@@ -8,8 +8,16 @@
|
||||
from contextlib import contextmanager
|
||||
from itertools import chain
|
||||
|
||||
import spack.compilers
|
||||
import spack.config
|
||||
import spack.environment
|
||||
import spack.error
|
||||
import spack.platforms
|
||||
import spack.repo
|
||||
import spack.spec
|
||||
import spack.target
|
||||
import spack.tengine
|
||||
import spack.util.path
|
||||
|
||||
CHECK_COMPILER_EXISTENCE = True
|
||||
|
||||
|
@@ -39,7 +39,6 @@
|
||||
|
||||
from llnl.util import filesystem, lang, tty
|
||||
|
||||
import spack.error
|
||||
import spack.paths
|
||||
import spack.platforms
|
||||
import spack.schema
|
||||
@@ -49,19 +48,17 @@
|
||||
import spack.schema.compilers
|
||||
import spack.schema.concretizer
|
||||
import spack.schema.config
|
||||
import spack.schema.definitions
|
||||
import spack.schema.develop
|
||||
import spack.schema.env
|
||||
import spack.schema.mirrors
|
||||
import spack.schema.modules
|
||||
import spack.schema.packages
|
||||
import spack.schema.repos
|
||||
import spack.schema.upstreams
|
||||
import spack.schema.view
|
||||
|
||||
# Hacked yaml for configuration files preserves line numbers.
|
||||
import spack.util.spack_yaml as syaml
|
||||
import spack.util.web as web_util
|
||||
from spack.error import SpackError
|
||||
from spack.util.cpus import cpus_available
|
||||
|
||||
#: Dict from section names -> schema for that section
|
||||
@@ -168,7 +165,7 @@ def get_section(self, section: str) -> Optional[YamlConfigDict]:
|
||||
|
||||
def _write_section(self, section: str) -> None:
|
||||
if not self.writable:
|
||||
raise spack.error.ConfigError(f"Cannot write to immutable scope {self}")
|
||||
raise ConfigError(f"Cannot write to immutable scope {self}")
|
||||
|
||||
filename = self.get_section_filename(section)
|
||||
data = self.get_section(section)
|
||||
@@ -280,7 +277,7 @@ def get_section(self, section: str) -> Optional[YamlConfigDict]:
|
||||
|
||||
def _write_section(self, section: str) -> None:
|
||||
if not self.writable:
|
||||
raise spack.error.ConfigError(f"Cannot write to immutable scope {self}")
|
||||
raise ConfigError(f"Cannot write to immutable scope {self}")
|
||||
data_to_write: Optional[YamlConfigDict] = self._raw_data
|
||||
|
||||
# If there is no existing data, this section SingleFileScope has never
|
||||
@@ -708,7 +705,7 @@ def print_section(self, section: str, blame: bool = False, *, scope=None) -> Non
|
||||
data[section] = self.get_config(section, scope=scope)
|
||||
syaml.dump_config(data, stream=sys.stdout, default_flow_style=False, blame=blame)
|
||||
except (syaml.SpackYAMLError, OSError) as e:
|
||||
raise spack.error.ConfigError(f"cannot read '{section}' configuration") from e
|
||||
raise ConfigError(f"cannot read '{section}' configuration") from e
|
||||
|
||||
|
||||
@contextlib.contextmanager
|
||||
@@ -810,7 +807,7 @@ def _add_command_line_scopes(
|
||||
_add_platform_scope(cfg, name, path, writable=False)
|
||||
continue
|
||||
else:
|
||||
raise spack.error.ConfigError(f"Invalid configuration scope: {path}")
|
||||
raise ConfigError(f"Invalid configuration scope: {path}")
|
||||
|
||||
for scope in manifest.env_config_scopes:
|
||||
scope.name = f"{name}:{scope.name}"
|
||||
@@ -1022,7 +1019,7 @@ def change_or_add(
|
||||
|
||||
if found:
|
||||
update_fn(section)
|
||||
CONFIG.set(section_name, section, scope=scope)
|
||||
spack.config.set(section_name, section, scope=scope)
|
||||
return
|
||||
|
||||
# If no scope meets the criteria specified by ``find_fn``,
|
||||
@@ -1035,14 +1032,14 @@ def change_or_add(
|
||||
break
|
||||
|
||||
if found:
|
||||
CONFIG.set(section_name, section, scope=scope)
|
||||
spack.config.set(section_name, section, scope=scope)
|
||||
return
|
||||
|
||||
# If no scopes define any config for the named section, then
|
||||
# modify the highest-priority scope.
|
||||
scope, section = configs_by_section[0]
|
||||
update_fn(section)
|
||||
CONFIG.set(section_name, section, scope=scope)
|
||||
spack.config.set(section_name, section, scope=scope)
|
||||
|
||||
|
||||
def update_all(section_name: str, change_fn: Callable[[str], bool]) -> None:
|
||||
@@ -1054,7 +1051,7 @@ def update_all(section_name: str, change_fn: Callable[[str], bool]) -> None:
|
||||
for scope, section in configs_by_section:
|
||||
modified = change_fn(section)
|
||||
if modified:
|
||||
CONFIG.set(section_name, section, scope=scope)
|
||||
spack.config.set(section_name, section, scope=scope)
|
||||
|
||||
|
||||
def _validate_section_name(section: str) -> None:
|
||||
@@ -1228,7 +1225,7 @@ def get_valid_type(path):
|
||||
return types[schema_type]()
|
||||
else:
|
||||
return type(None)
|
||||
raise spack.error.ConfigError(f"Cannot determine valid type for path '{path}'.")
|
||||
raise ConfigError(f"Cannot determine valid type for path '{path}'.")
|
||||
|
||||
|
||||
def remove_yaml(dest, source):
|
||||
@@ -1271,7 +1268,7 @@ def they_are(t):
|
||||
unmerge = sk in dest
|
||||
old_dest_value = dest.pop(sk, None)
|
||||
|
||||
if unmerge and not _override(sk):
|
||||
if unmerge and not spack.config._override(sk):
|
||||
dest[sk] = remove_yaml(old_dest_value, sv)
|
||||
|
||||
return dest
|
||||
@@ -1708,48 +1705,40 @@ def get_mark_from_yaml_data(obj):
|
||||
return mark
|
||||
|
||||
|
||||
def determine_number_of_jobs(
|
||||
*,
|
||||
parallel: bool = False,
|
||||
max_cpus: int = cpus_available(),
|
||||
config: Optional[Configuration] = None,
|
||||
) -> int:
|
||||
def parse_spec_from_yaml_string(string: str) -> "spack.spec.Spec":
|
||||
"""Parse a spec from YAML and add file/line info to errors, if it's available.
|
||||
|
||||
Parse a ``Spec`` from the supplied string, but also intercept any syntax errors and
|
||||
add file/line information for debugging using file/line annotations from the string.
|
||||
|
||||
Arguments:
|
||||
string: a string representing a ``Spec`` from config YAML.
|
||||
|
||||
"""
|
||||
Packages that require sequential builds need 1 job. Otherwise we use the
|
||||
number of jobs set on the command line. If not set, then we use the config
|
||||
defaults (which is usually set through the builtin config scope), but we
|
||||
cap to the number of CPUs available to avoid oversubscription.
|
||||
|
||||
Parameters:
|
||||
parallel: true when package supports parallel builds
|
||||
max_cpus: maximum number of CPUs to use (defaults to cpus_available())
|
||||
config: configuration object (defaults to global config)
|
||||
"""
|
||||
if not parallel:
|
||||
return 1
|
||||
|
||||
cfg = config or CONFIG
|
||||
|
||||
# Command line overrides all
|
||||
try:
|
||||
command_line = cfg.get("config:build_jobs", default=None, scope="command_line")
|
||||
if command_line is not None:
|
||||
return command_line
|
||||
except ValueError:
|
||||
pass
|
||||
|
||||
return min(max_cpus, cfg.get("config:build_jobs", 16))
|
||||
spec = spack.spec.Spec(string)
|
||||
return spec
|
||||
except spack.parser.SpecSyntaxError as e:
|
||||
mark = spack.config.get_mark_from_yaml_data(string)
|
||||
if mark:
|
||||
msg = f"{mark.name}:{mark.line + 1}: {str(e)}"
|
||||
raise spack.parser.SpecSyntaxError(msg) from e
|
||||
raise e
|
||||
|
||||
|
||||
class ConfigSectionError(spack.error.ConfigError):
|
||||
class ConfigError(SpackError):
|
||||
"""Superclass for all Spack config related errors."""
|
||||
|
||||
|
||||
class ConfigSectionError(ConfigError):
|
||||
"""Error for referring to a bad config section name in a configuration."""
|
||||
|
||||
|
||||
class ConfigFileError(spack.error.ConfigError):
|
||||
class ConfigFileError(ConfigError):
|
||||
"""Issue reading or accessing a configuration file."""
|
||||
|
||||
|
||||
class ConfigFormatError(spack.error.ConfigError):
|
||||
class ConfigFormatError(ConfigError):
|
||||
"""Raised when a configuration format does not match its schema."""
|
||||
|
||||
def __init__(
|
||||
|
@@ -6,7 +6,6 @@
|
||||
convenience functions.
|
||||
"""
|
||||
import copy
|
||||
import shlex
|
||||
from collections import namedtuple
|
||||
from typing import Optional
|
||||
|
||||
@@ -16,7 +15,7 @@
|
||||
import spack.tengine as tengine
|
||||
import spack.util.spack_yaml as syaml
|
||||
|
||||
from .images import (
|
||||
from ..images import (
|
||||
bootstrap_template_for,
|
||||
build_info,
|
||||
checkout_command,
|
||||
@@ -309,54 +308,7 @@ def __call__(self):
|
||||
return t.render(**self.to_dict())
|
||||
|
||||
|
||||
@writer("docker")
|
||||
class DockerContext(PathContext):
|
||||
"""Context used to instantiate a Dockerfile"""
|
||||
|
||||
#: Name of the template used for Dockerfiles
|
||||
template_name = "container/Dockerfile"
|
||||
|
||||
@tengine.context_property
|
||||
def manifest(self):
|
||||
manifest_str = super().manifest
|
||||
# Docker doesn't support HEREDOC, so we need to resort to
|
||||
# a horrible echo trick to have the manifest in the Dockerfile
|
||||
echoed_lines = []
|
||||
for idx, line in enumerate(manifest_str.split("\n")):
|
||||
quoted_line = shlex.quote(line)
|
||||
if idx == 0:
|
||||
echoed_lines.append("&& (echo " + quoted_line + " \\")
|
||||
continue
|
||||
echoed_lines.append("&& echo " + quoted_line + " \\")
|
||||
|
||||
echoed_lines[-1] = echoed_lines[-1].replace(" \\", ")")
|
||||
|
||||
return "\n".join(echoed_lines)
|
||||
|
||||
|
||||
@writer("singularity")
|
||||
class SingularityContext(PathContext):
|
||||
"""Context used to instantiate a Singularity definition file"""
|
||||
|
||||
#: Name of the template used for Singularity definition files
|
||||
template_name = "container/singularity.def"
|
||||
|
||||
@property
|
||||
def singularity_config(self):
|
||||
return self.container_config.get("singularity", {})
|
||||
|
||||
@tengine.context_property
|
||||
def runscript(self):
|
||||
return self.singularity_config.get("runscript", "")
|
||||
|
||||
@tengine.context_property
|
||||
def startscript(self):
|
||||
return self.singularity_config.get("startscript", "")
|
||||
|
||||
@tengine.context_property
|
||||
def test(self):
|
||||
return self.singularity_config.get("test", "")
|
||||
|
||||
@tengine.context_property
|
||||
def help(self):
|
||||
return self.singularity_config.get("help", "")
|
||||
# Import after function definition all the modules in this package,
|
||||
# so that registration of writers will happen automatically
|
||||
from . import docker # noqa: F401 E402
|
||||
from . import singularity # noqa: F401 E402
|
34
lib/spack/spack/container/writers/docker.py
Normal file
34
lib/spack/spack/container/writers/docker.py
Normal file
@@ -0,0 +1,34 @@
|
||||
# Copyright 2013-2024 Lawrence Livermore National Security, LLC and other
|
||||
# Spack Project Developers. See the top-level COPYRIGHT file for details.
|
||||
#
|
||||
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
|
||||
import shlex
|
||||
|
||||
import spack.tengine as tengine
|
||||
|
||||
from . import PathContext, writer
|
||||
|
||||
|
||||
@writer("docker")
|
||||
class DockerContext(PathContext):
|
||||
"""Context used to instantiate a Dockerfile"""
|
||||
|
||||
#: Name of the template used for Dockerfiles
|
||||
template_name = "container/Dockerfile"
|
||||
|
||||
@tengine.context_property
|
||||
def manifest(self):
|
||||
manifest_str = super().manifest
|
||||
# Docker doesn't support HEREDOC, so we need to resort to
|
||||
# a horrible echo trick to have the manifest in the Dockerfile
|
||||
echoed_lines = []
|
||||
for idx, line in enumerate(manifest_str.split("\n")):
|
||||
quoted_line = shlex.quote(line)
|
||||
if idx == 0:
|
||||
echoed_lines.append("&& (echo " + quoted_line + " \\")
|
||||
continue
|
||||
echoed_lines.append("&& echo " + quoted_line + " \\")
|
||||
|
||||
echoed_lines[-1] = echoed_lines[-1].replace(" \\", ")")
|
||||
|
||||
return "\n".join(echoed_lines)
|
35
lib/spack/spack/container/writers/singularity.py
Normal file
35
lib/spack/spack/container/writers/singularity.py
Normal file
@@ -0,0 +1,35 @@
|
||||
# Copyright 2013-2024 Lawrence Livermore National Security, LLC and other
|
||||
# Spack Project Developers. See the top-level COPYRIGHT file for details.
|
||||
#
|
||||
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
|
||||
import spack.tengine as tengine
|
||||
|
||||
from . import PathContext, writer
|
||||
|
||||
|
||||
@writer("singularity")
|
||||
class SingularityContext(PathContext):
|
||||
"""Context used to instantiate a Singularity definition file"""
|
||||
|
||||
#: Name of the template used for Singularity definition files
|
||||
template_name = "container/singularity.def"
|
||||
|
||||
@property
|
||||
def singularity_config(self):
|
||||
return self.container_config.get("singularity", {})
|
||||
|
||||
@tengine.context_property
|
||||
def runscript(self):
|
||||
return self.singularity_config.get("runscript", "")
|
||||
|
||||
@tengine.context_property
|
||||
def startscript(self):
|
||||
return self.singularity_config.get("startscript", "")
|
||||
|
||||
@tengine.context_property
|
||||
def test(self):
|
||||
return self.singularity_config.get("test", "")
|
||||
|
||||
@tengine.context_property
|
||||
def help(self):
|
||||
return self.singularity_config.get("help", "")
|
@@ -132,7 +132,7 @@ def spec_from_entry(entry):
|
||||
variant_strs = list()
|
||||
for name, value in entry["parameters"].items():
|
||||
# TODO: also ensure that the variant value is valid?
|
||||
if not pkg_cls.has_variant(name):
|
||||
if not (name in pkg_cls.variants):
|
||||
tty.debug(
|
||||
"Omitting variant {0} for entry {1}/{2}".format(
|
||||
name, entry["name"], entry["hash"][:7]
|
||||
|
@@ -25,10 +25,8 @@
|
||||
import llnl.util.tty
|
||||
|
||||
import spack.config
|
||||
import spack.error
|
||||
import spack.operating_systems.windows_os as winOs
|
||||
import spack.spec
|
||||
import spack.util.environment
|
||||
import spack.util.spack_yaml
|
||||
import spack.util.windows_registry
|
||||
|
||||
|
@@ -18,12 +18,10 @@
|
||||
import llnl.util.lang
|
||||
import llnl.util.tty
|
||||
|
||||
import spack.spec
|
||||
import spack.util.elf as elf_utils
|
||||
import spack.util.environment
|
||||
import spack.util.environment as environment
|
||||
import spack.util.ld_so_conf
|
||||
import spack.util.parallel
|
||||
|
||||
from .common import (
|
||||
WindowsCompilerExternalPaths,
|
||||
@@ -408,7 +406,7 @@ def by_path(
|
||||
|
||||
result = collections.defaultdict(list)
|
||||
repository = spack.repo.PATH.ensure_unwrapped()
|
||||
with spack.util.parallel.make_concurrent_executor(max_workers, require_fork=False) as executor:
|
||||
with concurrent.futures.ProcessPoolExecutor(max_workers=max_workers) as executor:
|
||||
for pkg in packages_to_search:
|
||||
executable_future = executor.submit(
|
||||
executables_finder.find,
|
||||
|
@@ -40,8 +40,10 @@ class OpenMpi(Package):
|
||||
import llnl.util.tty.color
|
||||
|
||||
import spack.deptypes as dt
|
||||
import spack.error
|
||||
import spack.patch
|
||||
import spack.spec
|
||||
import spack.url
|
||||
import spack.util.crypto
|
||||
import spack.variant
|
||||
from spack.dependency import Dependency
|
||||
@@ -78,6 +80,7 @@ class OpenMpi(Package):
|
||||
"redistribute",
|
||||
]
|
||||
|
||||
|
||||
_patch_order_index = 0
|
||||
|
||||
|
||||
@@ -673,25 +676,22 @@ def _raise_default_not_set(pkg):
|
||||
|
||||
def _execute_variant(pkg):
|
||||
when_spec = _make_when_spec(when)
|
||||
when_specs = [when_spec]
|
||||
|
||||
if not re.match(spack.spec.IDENTIFIER_RE, name):
|
||||
directive = "variant"
|
||||
msg = "Invalid variant name in {0}: '{1}'"
|
||||
raise DirectiveError(directive, msg.format(pkg.name, name))
|
||||
|
||||
# variants are stored by condition then by name (so only the last variant of a
|
||||
# given name takes precedence *per condition*).
|
||||
# NOTE: variant defaults and values can conflict if when conditions overlap.
|
||||
variants_by_name = pkg.variants.setdefault(when_spec, {})
|
||||
variants_by_name[name] = spack.variant.Variant(
|
||||
name=name,
|
||||
default=default,
|
||||
description=description,
|
||||
values=values,
|
||||
multi=multi,
|
||||
validator=validator,
|
||||
sticky=sticky,
|
||||
precedence=pkg.num_variant_definitions(),
|
||||
if name in pkg.variants:
|
||||
# We accumulate when specs, but replace the rest of the variant
|
||||
# with the newer values
|
||||
_, orig_when = pkg.variants[name]
|
||||
when_specs += orig_when
|
||||
|
||||
pkg.variants[name] = (
|
||||
spack.variant.Variant(name, default, description, values, multi, validator, sticky),
|
||||
when_specs,
|
||||
)
|
||||
|
||||
return _execute_variant
|
||||
|
@@ -16,9 +16,7 @@
|
||||
|
||||
import spack.config
|
||||
import spack.hash_types as ht
|
||||
import spack.projections
|
||||
import spack.spec
|
||||
import spack.store
|
||||
import spack.util.spack_json as sjson
|
||||
from spack.error import SpackError
|
||||
|
||||
|
@@ -24,23 +24,25 @@
|
||||
from llnl.util.link_tree import ConflictingSpecsError
|
||||
from llnl.util.symlink import readlink, symlink
|
||||
|
||||
import spack
|
||||
import spack.caches
|
||||
import spack.cmd
|
||||
import spack.compilers
|
||||
import spack.concretize
|
||||
import spack.config
|
||||
import spack.deptypes as dt
|
||||
import spack.environment
|
||||
import spack.error
|
||||
import spack.fetch_strategy
|
||||
import spack.filesystem_view as fsv
|
||||
import spack.hash_types as ht
|
||||
import spack.hooks
|
||||
import spack.main
|
||||
import spack.paths
|
||||
import spack.repo
|
||||
import spack.schema.env
|
||||
import spack.schema.merged
|
||||
import spack.spec
|
||||
import spack.spec_list
|
||||
import spack.stage
|
||||
import spack.store
|
||||
import spack.subprocess_context
|
||||
import spack.user_environment as uenv
|
||||
import spack.util.cpus
|
||||
import spack.util.environment
|
||||
@@ -51,6 +53,7 @@
|
||||
import spack.util.spack_json as sjson
|
||||
import spack.util.spack_yaml as syaml
|
||||
import spack.util.url
|
||||
import spack.version
|
||||
from spack import traverse
|
||||
from spack.installer import PackageInstaller
|
||||
from spack.schema.env import TOP_LEVEL_KEY
|
||||
@@ -1648,7 +1651,7 @@ def _concretize_separately(self, tests=False):
|
||||
|
||||
# Solve the environment in parallel on Linux
|
||||
start = time.time()
|
||||
num_procs = min(len(args), spack.config.determine_number_of_jobs(parallel=True))
|
||||
num_procs = min(len(args), spack.util.cpus.determine_number_of_jobs(parallel=True))
|
||||
|
||||
# TODO: support parallel concretization on macOS and Windows
|
||||
msg = "Starting concretization"
|
||||
@@ -2176,7 +2179,7 @@ def _to_lockfile_dict(self):
|
||||
root_specs = self._concrete_roots_dict()
|
||||
|
||||
spack_dict = {"version": spack.spack_version}
|
||||
spack_commit = spack.get_spack_commit()
|
||||
spack_commit = spack.main.get_spack_commit()
|
||||
if spack_commit:
|
||||
spack_dict["type"] = "git"
|
||||
spack_dict["commit"] = spack_commit
|
||||
|
@@ -132,60 +132,3 @@ def __init__(self, provided, required, constraint_type):
|
||||
|
||||
class FetchError(SpackError):
|
||||
"""Superclass for fetch-related errors."""
|
||||
|
||||
|
||||
class NoSuchPatchError(SpackError):
|
||||
"""Raised when a patch file doesn't exist."""
|
||||
|
||||
|
||||
class PatchDirectiveError(SpackError):
|
||||
"""Raised when the wrong arguments are suppled to the patch directive."""
|
||||
|
||||
|
||||
class PatchLookupError(NoSuchPatchError):
|
||||
"""Raised when a patch file cannot be located from sha256."""
|
||||
|
||||
|
||||
class SpecSyntaxError(Exception):
|
||||
"""Base class for Spec syntax errors"""
|
||||
|
||||
|
||||
class PackageError(SpackError):
|
||||
"""Raised when something is wrong with a package definition."""
|
||||
|
||||
def __init__(self, message, long_msg=None):
|
||||
super().__init__(message, long_msg)
|
||||
|
||||
|
||||
class NoURLError(PackageError):
|
||||
"""Raised when someone tries to build a URL for a package with no URLs."""
|
||||
|
||||
def __init__(self, cls):
|
||||
super().__init__("Package %s has no version with a URL." % cls.__name__)
|
||||
|
||||
|
||||
class InstallError(SpackError):
|
||||
"""Raised when something goes wrong during install or uninstall.
|
||||
|
||||
The error can be annotated with a ``pkg`` attribute to allow the
|
||||
caller to get the package for which the exception was raised.
|
||||
"""
|
||||
|
||||
def __init__(self, message, long_msg=None, pkg=None):
|
||||
super().__init__(message, long_msg)
|
||||
self.pkg = pkg
|
||||
|
||||
|
||||
class ConfigError(SpackError):
|
||||
"""Superclass for all Spack config related errors."""
|
||||
|
||||
|
||||
class StopPhase(SpackError):
|
||||
"""Pickle-able exception to control stopped builds."""
|
||||
|
||||
def __reduce__(self):
|
||||
return _make_stop_phase, (self.message, self.long_message)
|
||||
|
||||
|
||||
def _make_stop_phase(msg, long_msg):
|
||||
return StopPhase(msg, long_msg)
|
||||
|
@@ -17,7 +17,6 @@
|
||||
|
||||
import llnl.util.lang
|
||||
|
||||
import spack.cmd
|
||||
import spack.config
|
||||
import spack.error
|
||||
import spack.util.path
|
||||
|
@@ -46,6 +46,7 @@
|
||||
import spack.config
|
||||
import spack.error
|
||||
import spack.oci.opener
|
||||
import spack.url
|
||||
import spack.util.archive
|
||||
import spack.util.crypto as crypto
|
||||
import spack.util.git
|
||||
@@ -1541,7 +1542,7 @@ def _extrapolate(pkg, version):
|
||||
"""Create a fetcher from an extrapolated URL for this version."""
|
||||
try:
|
||||
return URLFetchStrategy(url=pkg.url_for_version(version), fetch_options=pkg.fetch_options)
|
||||
except spack.error.NoURLError:
|
||||
except spack.package_base.NoURLError:
|
||||
raise ExtrapolationError(
|
||||
f"Can't extrapolate a URL for version {version} because "
|
||||
f"package {pkg.name} defines no URLs"
|
||||
|
@@ -46,7 +46,6 @@
|
||||
import spack.repo
|
||||
import spack.spec
|
||||
import spack.tengine
|
||||
import spack.traverse
|
||||
|
||||
|
||||
def find(seq, predicate):
|
||||
|
@@ -17,23 +17,14 @@
|
||||
|
||||
import llnl.util.filesystem as fs
|
||||
import llnl.util.tty as tty
|
||||
import llnl.util.tty.log
|
||||
from llnl.string import plural
|
||||
from llnl.util.lang import nullcontext
|
||||
from llnl.util.tty.color import colorize
|
||||
|
||||
import spack.build_environment
|
||||
import spack.builder
|
||||
import spack.config
|
||||
import spack.error
|
||||
import spack.package_base
|
||||
import spack.paths
|
||||
import spack.repo
|
||||
import spack.spec
|
||||
import spack.util.executable
|
||||
import spack.util.path
|
||||
import spack.util.spack_json as sjson
|
||||
from spack.error import InstallError
|
||||
from spack.installer import InstallError
|
||||
from spack.spec import Spec
|
||||
from spack.util.prefix import Prefix
|
||||
|
||||
@@ -51,7 +42,7 @@
|
||||
|
||||
|
||||
ListOrStringType = Union[str, List[str]]
|
||||
LogType = Union[llnl.util.tty.log.nixlog, llnl.util.tty.log.winlog]
|
||||
LogType = Union["tty.log.nixlog", "tty.log.winlog"]
|
||||
|
||||
Pb = TypeVar("Pb", bound="spack.package_base.PackageBase")
|
||||
PackageObjectOrClass = Union[Pb, Type[Pb]]
|
||||
@@ -119,7 +110,7 @@ def cache_extra_test_sources(pkg: Pb, srcs: ListOrStringType):
|
||||
location(s) under the install testing directory.
|
||||
|
||||
Raises:
|
||||
spack.error.InstallError: if any of the source paths are absolute
|
||||
spack.installer.InstallError: if any of the source paths are absolute
|
||||
or do not exist
|
||||
under the build stage
|
||||
"""
|
||||
@@ -289,7 +280,7 @@ def __init__(self, pkg: Pb):
|
||||
def logger(self) -> Optional[LogType]:
|
||||
"""The current logger or, if none, sets to one."""
|
||||
if not self._logger:
|
||||
self._logger = llnl.util.tty.log.log_output(self.test_log_file)
|
||||
self._logger = tty.log.log_output(self.test_log_file)
|
||||
|
||||
return self._logger
|
||||
|
||||
@@ -306,7 +297,7 @@ def test_logger(self, verbose: bool = False, externals: bool = False):
|
||||
fs.touch(self.test_log_file) # Otherwise log_parse complains
|
||||
fs.set_install_permissions(self.test_log_file)
|
||||
|
||||
with llnl.util.tty.log.log_output(self.test_log_file, verbose) as self._logger:
|
||||
with tty.log.log_output(self.test_log_file, verbose) as self._logger:
|
||||
with self.logger.force_echo(): # type: ignore[union-attr]
|
||||
tty.msg("Testing package " + colorize(r"@*g{" + self.pkg_id + r"}"))
|
||||
|
||||
|
@@ -48,6 +48,7 @@
|
||||
|
||||
import spack.binary_distribution as binary_distribution
|
||||
import spack.build_environment
|
||||
import spack.compilers
|
||||
import spack.config
|
||||
import spack.database
|
||||
import spack.deptypes as dt
|
||||
@@ -889,7 +890,7 @@ def __init__(
|
||||
# ensure priority queue invariants when tasks are "removed" from the
|
||||
# queue.
|
||||
if status == STATUS_REMOVED:
|
||||
raise spack.error.InstallError(
|
||||
raise InstallError(
|
||||
f"Cannot create a build task for {self.pkg_id} with status '{status}'", pkg=pkg
|
||||
)
|
||||
|
||||
@@ -1160,7 +1161,7 @@ def _check_deps_status(self, request: BuildRequest) -> None:
|
||||
if spack.store.STORE.failure_tracker.has_failed(dep):
|
||||
action = "'spack install' the dependency"
|
||||
msg = f"{dep_id} is marked as an install failure: {action}"
|
||||
raise spack.error.InstallError(err.format(request.pkg_id, msg), pkg=dep_pkg)
|
||||
raise InstallError(err.format(request.pkg_id, msg), pkg=dep_pkg)
|
||||
|
||||
# Attempt to get a read lock to ensure another process does not
|
||||
# uninstall the dependency while the requested spec is being
|
||||
@@ -1168,7 +1169,7 @@ def _check_deps_status(self, request: BuildRequest) -> None:
|
||||
ltype, lock = self._ensure_locked("read", dep_pkg)
|
||||
if lock is None:
|
||||
msg = f"{dep_id} is write locked by another process"
|
||||
raise spack.error.InstallError(err.format(request.pkg_id, msg), pkg=request.pkg)
|
||||
raise InstallError(err.format(request.pkg_id, msg), pkg=request.pkg)
|
||||
|
||||
# Flag external and upstream packages as being installed
|
||||
if dep_pkg.spec.external or dep_pkg.spec.installed_upstream:
|
||||
@@ -1220,7 +1221,7 @@ def _prepare_for_install(self, task: BuildTask) -> None:
|
||||
if not installed_in_db:
|
||||
# Ensure there is no other installed spec with the same prefix dir
|
||||
if spack.store.STORE.db.is_occupied_install_prefix(task.pkg.spec.prefix):
|
||||
raise spack.error.InstallError(
|
||||
raise InstallError(
|
||||
f"Install prefix collision for {task.pkg_id}",
|
||||
long_msg=f"Prefix directory {task.pkg.spec.prefix} already "
|
||||
"used by another installed spec.",
|
||||
@@ -1488,9 +1489,7 @@ def _install_task(self, task: BuildTask, install_status: InstallStatus) -> None:
|
||||
self._update_installed(task)
|
||||
return
|
||||
elif cache_only:
|
||||
raise spack.error.InstallError(
|
||||
"No binary found when cache-only was specified", pkg=pkg
|
||||
)
|
||||
raise InstallError("No binary found when cache-only was specified", pkg=pkg)
|
||||
else:
|
||||
tty.msg(f"No binary for {pkg_id} found: installing from source")
|
||||
|
||||
@@ -1517,7 +1516,7 @@ def _install_task(self, task: BuildTask, install_status: InstallStatus) -> None:
|
||||
# the database, so that we don't need to re-read from file.
|
||||
spack.store.STORE.db.add(pkg.spec, explicit=explicit)
|
||||
|
||||
except spack.error.StopPhase as e:
|
||||
except spack.build_environment.StopPhase as e:
|
||||
# A StopPhase exception means that do_install was asked to
|
||||
# stop early from clients, and is not an error at this point
|
||||
pid = f"{self.pid}: " if tty.show_pid() else ""
|
||||
@@ -1850,7 +1849,7 @@ def install(self) -> None:
|
||||
tty.warn(f"{pkg_id} does NOT actually have any uninstalled deps left")
|
||||
dep_str = "dependencies" if task.priority > 1 else "dependency"
|
||||
|
||||
raise spack.error.InstallError(
|
||||
raise InstallError(
|
||||
f"Cannot proceed with {pkg_id}: {task.priority} uninstalled "
|
||||
f"{dep_str}: {','.join(task.uninstalled_deps)}",
|
||||
pkg=pkg,
|
||||
@@ -1872,7 +1871,7 @@ def install(self) -> None:
|
||||
self._update_failed(task)
|
||||
|
||||
if self.fail_fast:
|
||||
raise spack.error.InstallError(fail_fast_err, pkg=pkg)
|
||||
raise InstallError(fail_fast_err, pkg=pkg)
|
||||
|
||||
continue
|
||||
|
||||
@@ -2001,7 +2000,7 @@ def install(self) -> None:
|
||||
)
|
||||
# Terminate if requested to do so on the first failure.
|
||||
if self.fail_fast:
|
||||
raise spack.error.InstallError(f"{fail_fast_err}: {str(exc)}", pkg=pkg)
|
||||
raise InstallError(f"{fail_fast_err}: {str(exc)}", pkg=pkg)
|
||||
|
||||
# Terminate when a single build request has failed, or summarize errors later.
|
||||
if task.is_build_request:
|
||||
@@ -2053,7 +2052,7 @@ def install(self) -> None:
|
||||
f"missing package ({ids[0]}) from {', '.join(ids)}"
|
||||
)
|
||||
|
||||
raise spack.error.InstallError(
|
||||
raise InstallError(
|
||||
"Installation request failed. Refer to reported errors for failing package(s).",
|
||||
pkg=pkg,
|
||||
)
|
||||
@@ -2319,21 +2318,33 @@ def install(self):
|
||||
raise e.inner_exception
|
||||
|
||||
|
||||
class BadInstallPhase(spack.error.InstallError):
|
||||
class InstallError(spack.error.SpackError):
|
||||
"""Raised when something goes wrong during install or uninstall.
|
||||
|
||||
The error can be annotated with a ``pkg`` attribute to allow the
|
||||
caller to get the package for which the exception was raised.
|
||||
"""
|
||||
|
||||
def __init__(self, message, long_msg=None, pkg=None):
|
||||
super().__init__(message, long_msg)
|
||||
self.pkg = pkg
|
||||
|
||||
|
||||
class BadInstallPhase(InstallError):
|
||||
"""Raised for an install phase option is not allowed for a package."""
|
||||
|
||||
def __init__(self, pkg_name, phase):
|
||||
super().__init__(f"'{phase}' is not a valid phase for package {pkg_name}")
|
||||
|
||||
|
||||
class ExternalPackageError(spack.error.InstallError):
|
||||
class ExternalPackageError(InstallError):
|
||||
"""Raised by install() when a package is only for external use."""
|
||||
|
||||
|
||||
class InstallLockError(spack.error.InstallError):
|
||||
class InstallLockError(InstallError):
|
||||
"""Raised during install when something goes wrong with package locking."""
|
||||
|
||||
|
||||
class UpstreamPackageError(spack.error.InstallError):
|
||||
class UpstreamPackageError(InstallError):
|
||||
"""Raised during install when something goes wrong with an upstream
|
||||
package."""
|
||||
|
@@ -9,8 +9,6 @@
|
||||
after the system path is set up.
|
||||
"""
|
||||
import argparse
|
||||
|
||||
# import spack.modules.common
|
||||
import inspect
|
||||
import io
|
||||
import operator
|
||||
@@ -34,20 +32,20 @@
|
||||
import llnl.util.tty.color as color
|
||||
from llnl.util.tty.log import log_output
|
||||
|
||||
import spack
|
||||
import spack.cmd
|
||||
import spack.config
|
||||
import spack.environment as ev
|
||||
import spack.error
|
||||
import spack.modules
|
||||
import spack.paths
|
||||
import spack.platforms
|
||||
import spack.repo
|
||||
import spack.solver.asp
|
||||
import spack.spec
|
||||
import spack.store
|
||||
import spack.util.debug
|
||||
import spack.util.environment
|
||||
import spack.util.lock
|
||||
import spack.util.git
|
||||
import spack.util.path
|
||||
from spack.error import SpackError
|
||||
|
||||
#: names of profile statistics
|
||||
@@ -100,18 +98,75 @@
|
||||
#: Properties that commands are required to set.
|
||||
required_command_properties = ["level", "section", "description"]
|
||||
|
||||
#: Recorded directory where spack command was originally invoked
|
||||
spack_working_dir = None
|
||||
spack_ld_library_path = os.environ.get("LD_LIBRARY_PATH", "")
|
||||
|
||||
#: Whether to print backtraces on error
|
||||
SHOW_BACKTRACE = False
|
||||
|
||||
|
||||
def set_working_dir():
|
||||
"""Change the working directory to getcwd, or spack prefix if no cwd."""
|
||||
global spack_working_dir
|
||||
try:
|
||||
spack_working_dir = os.getcwd()
|
||||
except OSError:
|
||||
os.chdir(spack.paths.prefix)
|
||||
spack_working_dir = spack.paths.prefix
|
||||
|
||||
|
||||
def add_all_commands(parser):
|
||||
"""Add all spack subcommands to the parser."""
|
||||
for cmd in spack.cmd.all_commands():
|
||||
parser.add_command(cmd)
|
||||
|
||||
|
||||
def get_spack_commit():
|
||||
"""Get the Spack git commit sha.
|
||||
|
||||
Returns:
|
||||
(str or None) the commit sha if available, otherwise None
|
||||
"""
|
||||
git_path = os.path.join(spack.paths.prefix, ".git")
|
||||
if not os.path.exists(git_path):
|
||||
return None
|
||||
|
||||
git = spack.util.git.git()
|
||||
if not git:
|
||||
return None
|
||||
|
||||
rev = git(
|
||||
"-C",
|
||||
spack.paths.prefix,
|
||||
"rev-parse",
|
||||
"HEAD",
|
||||
output=str,
|
||||
error=os.devnull,
|
||||
fail_on_error=False,
|
||||
)
|
||||
if git.returncode != 0:
|
||||
return None
|
||||
|
||||
match = re.match(r"[a-f\d]{7,}$", rev)
|
||||
return match.group(0) if match else None
|
||||
|
||||
|
||||
def get_version():
|
||||
"""Get a descriptive version of this instance of Spack.
|
||||
|
||||
Outputs '<PEP440 version> (<git commit sha>)'.
|
||||
|
||||
The commit sha is only added when available.
|
||||
"""
|
||||
version = spack.spack_version
|
||||
commit = get_spack_commit()
|
||||
if commit:
|
||||
version += " ({0})".format(commit)
|
||||
|
||||
return version
|
||||
|
||||
|
||||
def index_commands():
|
||||
"""create an index of commands by section for this help level"""
|
||||
index = {}
|
||||
@@ -755,8 +810,6 @@ def print_setup_info(*info):
|
||||
This is in ``main.py`` to make it fast; the setup scripts need to
|
||||
invoke spack in login scripts, and it needs to be quick.
|
||||
"""
|
||||
import spack.modules.common
|
||||
|
||||
shell = "csh" if "csh" in info else "sh"
|
||||
|
||||
def shell_set(var, value):
|
||||
@@ -901,7 +954,7 @@ def _main(argv=None):
|
||||
|
||||
# version is special as it does not require a command or loading and additional infrastructure
|
||||
if args.version:
|
||||
print(spack.get_version())
|
||||
print(get_version())
|
||||
return 0
|
||||
|
||||
# ------------------------------------------------------------------------
|
||||
@@ -986,7 +1039,7 @@ def finish_parse_and_run(parser, cmd_name, main_args, env_format_error):
|
||||
raise env_format_error
|
||||
|
||||
# many operations will fail without a working directory.
|
||||
spack.paths.set_working_dir()
|
||||
set_working_dir()
|
||||
|
||||
# now we can actually execute the command.
|
||||
if main_args.spack_profile or main_args.sorted_profile:
|
||||
|
@@ -29,7 +29,6 @@
|
||||
import spack.config
|
||||
import spack.error
|
||||
import spack.fetch_strategy
|
||||
import spack.mirror
|
||||
import spack.oci.image
|
||||
import spack.repo
|
||||
import spack.spec
|
||||
|
@@ -46,7 +46,6 @@
|
||||
import spack.deptypes as dt
|
||||
import spack.environment
|
||||
import spack.error
|
||||
import spack.modules
|
||||
import spack.paths
|
||||
import spack.projections as proj
|
||||
import spack.repo
|
||||
|
@@ -15,10 +15,17 @@
|
||||
|
||||
import llnl.util.tty as tty
|
||||
|
||||
import spack.binary_distribution
|
||||
import spack.config
|
||||
import spack.error
|
||||
import spack.fetch_strategy
|
||||
import spack.mirror
|
||||
import spack.oci.opener
|
||||
import spack.repo
|
||||
import spack.spec
|
||||
import spack.stage
|
||||
import spack.traverse
|
||||
import spack.util.crypto
|
||||
import spack.util.url
|
||||
|
||||
from .image import Digest, ImageReference
|
||||
@@ -30,6 +37,11 @@ class Blob(NamedTuple):
|
||||
size: int
|
||||
|
||||
|
||||
def create_tarball(spec: spack.spec.Spec, tarfile_path):
|
||||
buildinfo = spack.binary_distribution.get_buildinfo_dict(spec)
|
||||
return spack.binary_distribution._do_create_tarball(tarfile_path, spec.prefix, buildinfo)
|
||||
|
||||
|
||||
def with_query_param(url: str, param: str, value: str) -> str:
|
||||
"""Add a query parameter to a URL
|
||||
|
||||
|
@@ -22,6 +22,7 @@
|
||||
import spack.config
|
||||
import spack.mirror
|
||||
import spack.parser
|
||||
import spack.repo
|
||||
import spack.util.web
|
||||
|
||||
from .image import ImageReference
|
||||
|
@@ -11,8 +11,6 @@
|
||||
from os import chdir, environ, getcwd, makedirs, mkdir, remove, removedirs
|
||||
from shutil import move, rmtree
|
||||
|
||||
from spack.error import InstallError
|
||||
|
||||
# Emulate some shell commands for convenience
|
||||
env = environ
|
||||
cd = chdir
|
||||
@@ -75,7 +73,6 @@
|
||||
from spack.build_systems.waf import WafPackage
|
||||
from spack.build_systems.xorg import XorgPackage
|
||||
from spack.builder import run_after, run_before
|
||||
from spack.config import determine_number_of_jobs
|
||||
from spack.deptypes import ALL_TYPES as all_deptypes
|
||||
from spack.directives import *
|
||||
from spack.install_test import (
|
||||
@@ -87,7 +84,12 @@
|
||||
install_test_root,
|
||||
test_part,
|
||||
)
|
||||
from spack.installer import ExternalPackageError, InstallLockError, UpstreamPackageError
|
||||
from spack.installer import (
|
||||
ExternalPackageError,
|
||||
InstallError,
|
||||
InstallLockError,
|
||||
UpstreamPackageError,
|
||||
)
|
||||
from spack.mixins import filter_compiler_wrappers
|
||||
from spack.multimethod import default_args, when
|
||||
from spack.package_base import (
|
||||
@@ -100,6 +102,7 @@
|
||||
on_package_attributes,
|
||||
)
|
||||
from spack.spec import InvalidSpecDetected, Spec
|
||||
from spack.util.cpus import determine_number_of_jobs
|
||||
from spack.util.executable import *
|
||||
from spack.util.filesystem import file_command, fix_darwin_install_name, mime_type
|
||||
from spack.variant import (
|
||||
|
@@ -33,28 +33,28 @@
|
||||
from llnl.util.lang import classproperty, memoized
|
||||
from llnl.util.link_tree import LinkTree
|
||||
|
||||
import spack.build_environment
|
||||
import spack.builder
|
||||
import spack.compilers
|
||||
import spack.config
|
||||
import spack.dependency
|
||||
import spack.deptypes as dt
|
||||
import spack.directives
|
||||
import spack.directory_layout
|
||||
import spack.environment
|
||||
import spack.error
|
||||
import spack.fetch_strategy as fs
|
||||
import spack.hooks
|
||||
import spack.mirror
|
||||
import spack.mixins
|
||||
import spack.multimethod
|
||||
import spack.patch
|
||||
import spack.paths
|
||||
import spack.repo
|
||||
import spack.spec
|
||||
import spack.store
|
||||
import spack.url
|
||||
import spack.util.environment
|
||||
import spack.util.executable
|
||||
import spack.util.path
|
||||
import spack.util.web
|
||||
from spack.error import InstallError, NoURLError, PackageError
|
||||
from spack.filesystem_view import YamlFilesystemView
|
||||
from spack.install_test import (
|
||||
PackageTest,
|
||||
@@ -64,8 +64,7 @@
|
||||
cache_extra_test_sources,
|
||||
install_test_root,
|
||||
)
|
||||
from spack.installer import PackageInstaller
|
||||
from spack.solver.version_order import concretization_version_order
|
||||
from spack.installer import InstallError, PackageInstaller
|
||||
from spack.stage import DevelopStage, ResourceStage, Stage, StageComposite, compute_stage_name
|
||||
from spack.util.executable import ProcessError, which
|
||||
from spack.util.package_hash import package_hash
|
||||
@@ -117,6 +116,7 @@ def preferred_version(pkg: "PackageBase"):
|
||||
Arguments:
|
||||
pkg: The package whose versions are to be assessed.
|
||||
"""
|
||||
from spack.solver.asp import concretization_version_order
|
||||
|
||||
version, _ = max(pkg.versions.items(), key=concretization_version_order)
|
||||
return version
|
||||
@@ -451,11 +451,10 @@ def _by_name(
|
||||
else:
|
||||
all_by_name.setdefault(name, []).append(value)
|
||||
|
||||
# this needs to preserve the insertion order of whens
|
||||
return dict(sorted(all_by_name.items()))
|
||||
|
||||
|
||||
def _names(when_indexed_dictionary: WhenDict) -> List[str]:
|
||||
def _names(when_indexed_dictionary):
|
||||
"""Get sorted names from dicts keyed by when/name."""
|
||||
all_names = set()
|
||||
for when, by_name in when_indexed_dictionary.items():
|
||||
@@ -465,45 +464,6 @@ def _names(when_indexed_dictionary: WhenDict) -> List[str]:
|
||||
return sorted(all_names)
|
||||
|
||||
|
||||
WhenVariantList = List[Tuple["spack.spec.Spec", "spack.variant.Variant"]]
|
||||
|
||||
|
||||
def _remove_overridden_vdefs(variant_defs: WhenVariantList) -> None:
|
||||
"""Remove variant defs from the list if their when specs are satisfied by later ones.
|
||||
|
||||
Any such variant definitions are *always* overridden by their successor, as it will
|
||||
match everything the predecessor matches, and the solver will prefer it because of
|
||||
its higher precedence.
|
||||
|
||||
We can just remove these defs from variant definitions and avoid putting them in the
|
||||
solver. This is also useful for, e.g., `spack info`, where we don't want to show a
|
||||
variant from a superclass if it is always overridden by a variant defined in a
|
||||
subclass.
|
||||
|
||||
Example::
|
||||
|
||||
class ROCmPackage:
|
||||
variant("amdgpu_target", ..., when="+rocm")
|
||||
|
||||
class Hipblas:
|
||||
variant("amdgpu_target", ...)
|
||||
|
||||
The subclass definition *always* overrides the superclass definition here, but they
|
||||
have different when specs and the subclass def won't just replace the one in the
|
||||
superclass. In this situation, the subclass should *probably* also have
|
||||
``when="+rocm"``, but we can't guarantee that will always happen when a vdef is
|
||||
overridden. So we use this method to remove any overrides we can know statically.
|
||||
|
||||
"""
|
||||
i = 0
|
||||
while i < len(variant_defs):
|
||||
when, vdef = variant_defs[i]
|
||||
if any(when.satisfies(successor) for successor, _ in variant_defs[i + 1 :]):
|
||||
del variant_defs[i]
|
||||
else:
|
||||
i += 1
|
||||
|
||||
|
||||
class RedistributionMixin:
|
||||
"""Logic for determining whether a Package is source/binary
|
||||
redistributable.
|
||||
@@ -636,7 +596,7 @@ class PackageBase(WindowsRPath, PackageViewMixin, RedistributionMixin, metaclass
|
||||
provided: Dict["spack.spec.Spec", Set["spack.spec.Spec"]]
|
||||
provided_together: Dict["spack.spec.Spec", List[Set[str]]]
|
||||
patches: Dict["spack.spec.Spec", List["spack.patch.Patch"]]
|
||||
variants: Dict["spack.spec.Spec", Dict[str, "spack.variant.Variant"]]
|
||||
variants: Dict[str, Tuple["spack.variant.Variant", "spack.spec.Spec"]]
|
||||
languages: Dict["spack.spec.Spec", Set[str]]
|
||||
|
||||
#: By default, packages are not virtual
|
||||
@@ -790,72 +750,6 @@ def dependency_names(cls):
|
||||
def dependencies_by_name(cls, when: bool = False):
|
||||
return _by_name(cls.dependencies, when=when)
|
||||
|
||||
# Accessors for variants
|
||||
# External code workingw with Variants should go through the methods below
|
||||
|
||||
@classmethod
|
||||
def variant_names(cls) -> List[str]:
|
||||
return _names(cls.variants)
|
||||
|
||||
@classmethod
|
||||
def has_variant(cls, name) -> bool:
|
||||
return any(name in dictionary for dictionary in cls.variants.values())
|
||||
|
||||
@classmethod
|
||||
def num_variant_definitions(cls) -> int:
|
||||
"""Total number of variant definitions in this class so far."""
|
||||
return sum(len(variants_by_name) for variants_by_name in cls.variants.values())
|
||||
|
||||
@classmethod
|
||||
def variant_definitions(cls, name: str) -> WhenVariantList:
|
||||
"""Iterator over (when_spec, Variant) for all variant definitions for a particular name."""
|
||||
# construct a list of defs sorted by precedence
|
||||
defs: WhenVariantList = []
|
||||
for when, variants_by_name in cls.variants.items():
|
||||
variant_def = variants_by_name.get(name)
|
||||
if variant_def:
|
||||
defs.append((when, variant_def))
|
||||
|
||||
# With multiple definitions, ensure precedence order and simplify overrides
|
||||
if len(defs) > 1:
|
||||
defs.sort(key=lambda v: v[1].precedence)
|
||||
_remove_overridden_vdefs(defs)
|
||||
|
||||
return defs
|
||||
|
||||
@classmethod
|
||||
def variant_items(
|
||||
cls,
|
||||
) -> Iterable[Tuple["spack.spec.Spec", Dict[str, "spack.variant.Variant"]]]:
|
||||
"""Iterate over ``cls.variants.items()`` with overridden definitions removed."""
|
||||
# Note: This is quadratic in the average number of variant definitions per name.
|
||||
# That is likely close to linear in practice, as there are few variants with
|
||||
# multiple definitions (but it matters when they are there).
|
||||
exclude = {
|
||||
name: [id(vdef) for _, vdef in cls.variant_definitions(name)]
|
||||
for name in cls.variant_names()
|
||||
}
|
||||
|
||||
for when, variants_by_name in cls.variants.items():
|
||||
filtered_variants_by_name = {
|
||||
name: vdef for name, vdef in variants_by_name.items() if id(vdef) in exclude[name]
|
||||
}
|
||||
|
||||
if filtered_variants_by_name:
|
||||
yield when, filtered_variants_by_name
|
||||
|
||||
def get_variant(self, name: str) -> "spack.variant.Variant":
|
||||
"""Get the highest precedence variant definition matching this package's spec.
|
||||
|
||||
Arguments:
|
||||
name: name of the variant definition to get
|
||||
"""
|
||||
try:
|
||||
highest_to_lowest = reversed(self.variant_definitions(name))
|
||||
return next(vdef for when, vdef in highest_to_lowest if self.spec.satisfies(when))
|
||||
except StopIteration:
|
||||
raise ValueError(f"No variant '{name}' on spec: {self.spec}")
|
||||
|
||||
@classmethod
|
||||
def possible_dependencies(
|
||||
cls,
|
||||
@@ -1805,7 +1699,8 @@ def content_hash(self, content=None):
|
||||
# should this attempt to download the source and set one? This
|
||||
# probably only happens for source repositories which are
|
||||
# referenced by branch name rather than tag or commit ID.
|
||||
from_local_sources = "dev_path" in self.spec.variants
|
||||
env = spack.environment.active_environment()
|
||||
from_local_sources = env and env.is_develop(self.spec)
|
||||
if self.has_code and not self.spec.external and not from_local_sources:
|
||||
message = "Missing a source id for {s.name}@{s.version}"
|
||||
tty.debug(message.format(s=self))
|
||||
@@ -2689,6 +2584,20 @@ def __init__(self, spec, dependents):
|
||||
self.dependents = dependents
|
||||
|
||||
|
||||
class PackageError(spack.error.SpackError):
|
||||
"""Raised when something is wrong with a package definition."""
|
||||
|
||||
def __init__(self, message, long_msg=None):
|
||||
super().__init__(message, long_msg)
|
||||
|
||||
|
||||
class NoURLError(PackageError):
|
||||
"""Raised when someone tries to build a URL for a package with no URLs."""
|
||||
|
||||
def __init__(self, cls):
|
||||
super().__init__("Package %s has no version with a URL." % cls.__name__)
|
||||
|
||||
|
||||
class InvalidPackageOpError(PackageError):
|
||||
"""Raised when someone tries perform an invalid operation on a package."""
|
||||
|
||||
|
@@ -9,7 +9,7 @@
|
||||
import spack.error
|
||||
import spack.repo
|
||||
import spack.spec
|
||||
from spack.error import ConfigError
|
||||
from spack.config import ConfigError
|
||||
from spack.version import Version
|
||||
|
||||
_lesser_spec_types = {"compiler": spack.spec.CompilerSpec, "version": Version}
|
||||
@@ -149,12 +149,10 @@ def preferred_variants(cls, pkg_name):
|
||||
|
||||
# Only return variants that are actually supported by the package
|
||||
pkg_cls = spack.repo.PATH.get_pkg_class(pkg_name)
|
||||
spec = spack.spec.Spec(f"{pkg_name} {variants}")
|
||||
return {
|
||||
name: variant
|
||||
for name, variant in spec.variants.items()
|
||||
if name in pkg_cls.variant_names()
|
||||
}
|
||||
spec = spack.spec.Spec("%s %s" % (pkg_name, variants))
|
||||
return dict(
|
||||
(name, variant) for name, variant in spec.variants.items() if name in pkg_cls.variants
|
||||
)
|
||||
|
||||
|
||||
def is_spec_buildable(spec):
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user