From d5c3f35a3869c7122110b87c64cbc3155d71c695 Mon Sep 17 00:00:00 2001 From: Pete Gadomski Date: Thu, 6 Apr 2023 13:31:06 -0600 Subject: [PATCH] ci: rework minimum requirements check --- .github/setup/action.yml | 6 +-- .github/workflows/continuous-integration.yml | 11 ++--- requirements-min.txt | 13 ------ scripts/check_minimum_requirements | 43 -------------------- scripts/install-min-requirements | 36 ++++++++++++++++ 5 files changed, 41 insertions(+), 68 deletions(-) delete mode 100644 requirements-min.txt delete mode 100755 scripts/check_minimum_requirements create mode 100755 scripts/install-min-requirements diff --git a/.github/setup/action.yml b/.github/setup/action.yml index d0ae7817..d8032ddd 100644 --- a/.github/setup/action.yml +++ b/.github/setup/action.yml @@ -4,10 +4,6 @@ inputs: python-version: description: Python version to set up w/ conda required: True - pip-cache-hash: - description: The hash used for the pip cache - required: False - default: ${{ hashFiles('setup.cfg', 'requirements-dev.txt') }} runs: using: composite steps: @@ -21,7 +17,7 @@ runs: uses: actions/cache@v2 with: path: ~/.cache/pip - key: ${{ runner.os }}-pip-${{ inputs.pip-cache-hash }} + key: ${{ runner.os }}-pip-${{ hashFiles('setup.cfg', 'requirements-dev.txt') }} restore-keys: ${{ runner.os }}-pip- - name: Set up pre-commit cache uses: actions/cache@v2 diff --git a/.github/workflows/continuous-integration.yml b/.github/workflows/continuous-integration.yml index f669d039..b885f72f 100644 --- a/.github/workflows/continuous-integration.yml +++ b/.github/workflows/continuous-integration.yml @@ -63,15 +63,12 @@ jobs: - uses: ./.github/setup with: python-version: ${{ matrix.python-version }} - pip-cache-hash: ${{ hashFiles('requirements-min.txt', 'requirements-dev.txt') }} - - name: Install minimum requirements - run: pip install -r requirements-min.txt - - name: Install the package - run: pip install . - name: Install development dependencies run: pip install -r requirements-dev.txt - - name: Check minimum requirements - run: scripts/check_minimum_requirements + - name: Install the minimum requirements + run: scripts/install-min-requirements + - name: Install the package + run: pip install . - name: Test run: scripts/test pre-release-versions: diff --git a/requirements-min.txt b/requirements-min.txt deleted file mode 100644 index eabe0f91..00000000 --- a/requirements-min.txt +++ /dev/null @@ -1,13 +0,0 @@ -Shapely == 1.8.5.post1 -aiohttp == 3.8.3 -click == 8.1.3 -fsspec == 2021.7 -lxml == 4.9.2 -jsonschema == 4.0.1 -numpy == 1.22.0 -pyproj == 3.3 -pystac[validation] == 1.6.1 -rasterio == 1.3.2 -requests == 2.27.1 -stac-check == 1.3.2 -stac-validator == 3.1.0 diff --git a/scripts/check_minimum_requirements b/scripts/check_minimum_requirements deleted file mode 100755 index 74dc92f6..00000000 --- a/scripts/check_minimum_requirements +++ /dev/null @@ -1,43 +0,0 @@ -#!/usr/bin/env python3 -# type: ignore - -import os.path -import sys - -from importlib_metadata import requires -from packaging.requirements import Requirement - -package_requirements = [ - Requirement(requirement) for requirement in requires("stactools") -] -requirements_min = os.path.join( - os.path.dirname(os.path.dirname(__file__)), "requirements-min.txt" -) -with open(requirements_min) as file: - min_requirements = [Requirement(line) for line in file] -min_requirements = dict( - (requirement.name, requirement) for requirement in min_requirements -) - -incorrect_requirements = list() -for package_requirement in package_requirements: - if package_requirement.marker is not None: - continue - min_requirement = min_requirements[package_requirement.name] - for package_specifier, min_specifier in zip( - package_requirement.specifier, min_requirement.specifier - ): - if ( - package_specifier.operator == ">=" - and package_specifier.version != min_specifier.version - ): - incorrect_requirements.append((package_requirement, min_requirement)) - -if incorrect_requirements: - print("ERROR: Incorrect min-requirements.txt!") - for package_requirement, min_requirement in incorrect_requirements: - print(f"- package: {package_requirement}, min: {min_requirement}") - sys.exit(1) -else: - print("OK") - sys.exit(0) diff --git a/scripts/install-min-requirements b/scripts/install-min-requirements new file mode 100755 index 00000000..06f522da --- /dev/null +++ b/scripts/install-min-requirements @@ -0,0 +1,36 @@ +#!/usr/bin/env python3 + +"""Installs the minimum version of all stactools dependencies, with pip. + +Assumptions: +- You've installed the development dependencies: `pip install -r requirements-dev.txt` +- All of the dependencies in setup.cfg are specified with `>=` + +For more context on the approach and rationale behind testing against minimum +requirements, see +https://www.gadom.ski/2022/02/18/dependency-protection-with-python-and-github-actions.html. + +""" + +import subprocess +from configparser import ConfigParser +from pathlib import Path + +from packaging.requirements import Requirement + +root = Path(__file__).parents[1] +setup_cfg = ConfigParser() +setup_cfg.read(root / "setup.cfg") +requirements = [] +for install_requires in filter( + bool, + (i.strip() for i in setup_cfg["options"]["install_requires"].splitlines()), +): + requirement = Requirement(install_requires) + assert len(requirement.specifier) == 1 + specifier = list(requirement.specifier)[0] + assert specifier.operator == ">=" + install_requires = install_requires.replace(">=", "==") + requirements.append(install_requires) + +subprocess.run(["pip", "install", *requirements])