qcs-api-client-common 0.19.1

Common code for QCS API clients
Documentation
[tasks.check-venv]
description = "Check if a virtual environment is activated"
script = [
    '''
    if [ -z "$VIRTUAL_ENV" ]; then
        echo "No virtual environment activated. Please activate one."
        exit 1
    else
        echo "Virtual environment is active."
    fi
    '''
]

[tasks.upgrade-pip]
dependencies = ["check-venv"]
description = "Upgrade pip to ensure it supports depency groups"
command = "pip"
args = ["install", "--upgrade", "pip"]

[tasks.install-uv]
dependencies = ["check-venv", "upgrade-pip"]
description = "Install dependencies using uv"
command = "pip"
args = ["install", "uv"]

[tasks.install-deps]
dependencies = ["install-uv"]
description = "Install dependencies using uv"
command = "uv"
args = ["pip", "install", "--group", "dev", "."]

[tasks.install-python-package]
dependencies = ["install-deps", "generate-stubs"]
description = "Build the qcs-api-client-common python package and install it in the current virtual environment."
command = "maturin"
args = ["develop"]

[tasks.generate-stubs]
description = "Generate Python stub files."
command = "cargo"
args = ["run", "-p", "qcs-api-client-common", "--features", "stubs", "--bin", "stub_gen"]
install_crate = false

[tasks.check-generated-python-files]
# The generated `__init__.py` files are what expose the compiled
# `qcs_api_client_common._qcs_api_client_common` modules under their public names, and release
# wheels are built from the committed tree. So if they go stale, a release can silently omit a
# class with nothing else to catch it.
description = "Check that the committed stubs and `__init__.py` files are up to date."
dependencies = ["generate-stubs"]
cwd = "python"
script = '''
if [ -n "$(git status --porcelain .)" ]; then
    echo "error: the generated Python files are out of date." >&2
    echo "Run 'cargo make --cwd qcs-api-client-common generate-stubs' and commit the result:" >&2
    git status --porcelain . >&2
    git --no-pager diff . >&2
    exit 1
fi
echo "Generated Python files are up to date."
'''

[tasks.stubtest]
dependencies = ["install-python-package"]
description = "Validate type stubs using stubtest"
cwd = "python"
command = "uv"
args = [
    "run", "--group", "dev",
    "stubtest",
    "--allowlist", "stubtest-allowlist",
    "--ignore-unused-allowlist",
    "--ignore-disjoint-bases",
    "qcs_api_client_common",
]

[tasks.pytest]
dependencies = ["install-python-package"]
description = "Run the Python unit test suite."
command = "uv"
args = [
    "run", "--group", "dev",
    "pytest",
    "tests_py", "-vv"
]

[tasks.pytest-integration]
dependencies = ["install-python-package"]
description = "Run the integration tests in the Python test suite. Requires a valid QCS configuration."
command = "uv"
args = [
    "run", "--group", "dev",
    "pytest",
    "tests_py", "--integration"
]

[tasks.build-python-docs]
dependencies = ["install-python-package"]
description = "Build the Sphinx documentation."
cwd = "docs"
script = [
    '''
    make html
    '''
]

[tasks.ruff-check]
dependencies = ["install-uv"]
command = "uv"
args = ["run", "--group", "dev", "ruff", "check"]

[tasks.check-python-api]
description = "Check if Python API has breaking changes."
dependencies = ["install-python-package"]
script = { file = "./scripts/check-py-api.sh" }

[tasks.check-python-bindings]
description = "Find errors in the Python-related Rust code."
command = "uv"
args = [
    "run",
    "--group", "dev",
    "python",
    "./scripts/lint-bindings.py",
    "--base", "src",
    "--show-mistakes",
]

[tasks.show-python-layout]
description = "Print the Python package layout as defined within the Rust code."
command = "uv"
args = [
    "run",
    "--group", "dev",
    "python",
    "./scripts/lint-bindings.py",
    "--base", "src",
    "--show-package",
]

[tasks.check-python]
dependencies = [
    "check-python-bindings",
    "check-generated-python-files",
    "check-python-api",
    "stubtest",
    "ruff-check",
]

[tasks.dev-flow]
dependencies = ["dev-test-flow", "check-python", "pytest"]

[tasks.test]
dependencies = ["test-in-ci"]

[tasks.test-in-ci]
description = "Tasks that only run when the CI environment variable is set."
condition = { env_set = ["CI"] }
run_task = [
  { name = "test-credentials" },
]

[tasks.test-credentials]
command = "cargo"
args = ["test", "test_client_credentials", "--", "--ignored"]

[tasks.default]
alias = "dev-flow"