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

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion hatch_custom_hook.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
import os
import shutil
from typing import Any

from hatchling.builders.hooks.plugin.interface import BuildHookInterface
from typing import Any


class HatchCustomBuildHook(BuildHookInterface):
Expand Down
3 changes: 2 additions & 1 deletion pipeline/setup-runner.py
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
def run(cmd, check=True, shell=False):
"""Run a command and optionally check for errors."""
print(f"Running: {cmd if shell else ' '.join(cmd)}")
result = subprocess.run(cmd, shell=shell)
result = subprocess.run(cmd, shell=shell, check=False)
if check and result.returncode != 0:
print(f"Command failed with return code {result.returncode}")
sys.exit(result.returncode)
Expand Down Expand Up @@ -74,6 +74,7 @@ def run_installer(setup_exe):
[str(setup_exe), "-q", "-i", "install"],
capture_output=True,
text=True,
check=False,
)
print(f"Installer exit code: {result.returncode}")
if result.stdout:
Expand Down
21 changes: 21 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -90,12 +90,33 @@ line-length = 100
[tool.ruff.lint]
ignore = ["E501"]

[tool.ruff.lint.per-file-ignores]

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These new suppressions appear to be no-ops: [tool.ruff.lint] only sets ignore = ["E501"] and never sets select / extend-select, so ruff runs with its default rule set (E4, E7, E9, F). None of N999, TRY002, BLE001, or B008 are in that set, so:

  • every entry in this per-file-ignores block ignores a rule that is never emitted,
  • [tool.ruff.lint.flake8-bugbear] extend-immutable-calls has nothing to affect (B008 is off),
  • the two new # noqa: BLE001 comments added in this PR (VRED_RenderScript_DeadlineCloud.py:531, ui/components/scene_settings_callbacks.py:131) suppress a rule that is not enabled.

The risk is that this reads as "these rules are enforced with documented exceptions," when in fact none of them are checked. Either add the corresponding rules to select (and then these suppressions become load-bearing), or drop the config block and the noqa markers so the file reflects what actually runs.

# This filename is a required pipeline component referenced by the job bundle
# scripts directory; it cannot be renamed to satisfy the module-name convention.
"src/deadline/vred_submitter/VRED_RenderScript_DeadlineCloud.py" = ["N999"]
# Build scripts use plain `raise Exception(...)` for simple guard clauses;
# defining custom exception classes there adds little value.
"scripts/**/*.py" = ["TRY002", "BLE001"]
# Build/CI scripts use top-level `except Exception` to log and continue/exit cleanly.
"pipeline/**/*.py" = ["BLE001"]
# Test harnesses and capability probes intentionally catch broadly to log and
# return a pass/fail rather than aborting the run.
"test/**/*.py" = ["BLE001"]
# The VRED plugin must never crash VRED's startup, so its load/init boundaries
# catch broadly, log, and degrade gracefully.
"vred_submitter_plugin/**/*.py" = ["BLE001"]

[tool.ruff.lint.isort]
known-first-party = [
"deadline",
"openjd"
]

[tool.ruff.lint.flake8-bugbear]
# Qt.WindowFlags() returns an immutable flag value that is only stored, never
# mutated, so using it as a default argument is safe (B008 false positive).
extend-immutable-calls = ["PySide6.QtCore.Qt.WindowFlags"]

[tool.black]
line-length = 100

Expand Down
4 changes: 2 additions & 2 deletions requirements-testing.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@ mypy == 2.*
pytest == 9.*
pytest-cov == 7.*
pytest-xdist == 3.*
ruff == 0.15.*
ruff == 0.16.*
twine == 7.*
types-pyyaml == 6.*
types-pyyaml == 6.*
32 changes: 15 additions & 17 deletions scripts/build_installer.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,14 @@
"""Script to create platform-specific Deadline Client installers using InstallBuilder."""

import os
import sys
import shutil
import sys
import tempfile
from typing import Optional
from pathlib import Path

from common import EvaluationBuildError, run, get_version_string
from find_installbuilder import InstallBuilderSelection, get_builder_exe_name

from common import EvaluationBuildError, get_version_string, run
from deps_bundle import build_deps_bundle
from find_installbuilder import InstallBuilderSelection, get_builder_exe_name

# This is derived from <installerFilename> in installer/DeadlineCloudClient.xml
# See "Supported Platforms" table in https://releases.installbuilder.com/installbuilder/docs/installbuilder-userguide.html
Expand All @@ -25,10 +23,10 @@

def setup_install_builder(
workdir: Path,
install_builder_location: Optional[Path],
license_file_path: Optional[Path],
install_builder_s3_bucket: Optional[str] = None,
install_builder_s3_key: Optional[str] = None,
install_builder_location: Path | None,
license_file_path: Path | None,
install_builder_s3_bucket: str | None = None,
install_builder_s3_key: str | None = None,
) -> Path:
"""
Ensure installbuilder is installed in some way and return the path
Expand Down Expand Up @@ -69,7 +67,7 @@ def build_installer(
install_builder_location: Path,
installer_platform: str,
dev: bool,
override_installer_version: Optional[str],
override_installer_version: str | None,
) -> Path:
"""
Actually build the installer
Expand Down Expand Up @@ -133,19 +131,19 @@ def build_installer(

def main(
dev: bool,
install_builder_location: Optional[Path],
install_builder_license_path: Optional[Path],
install_builder_s3_bucket: Optional[str],
install_builder_s3_key: Optional[str],
output_dir: Optional[Path],
install_builder_location: Path | None,
install_builder_license_path: Path | None,
install_builder_s3_bucket: str | None,
install_builder_s3_key: str | None,
output_dir: Path | None,
installer_platform: str,
installer_source_path: Path,
override_installer_version: Optional[str],
override_installer_version: str | None,
) -> None:
with tempfile.TemporaryDirectory() as wd:
workdir = Path(wd)
print(f"cwd: {os.getcwd()}")
print(f"working directory: {str(workdir)}")
print(f"working directory: {workdir!s}")

installbuilder_path = setup_install_builder(
workdir=workdir,
Expand Down
50 changes: 24 additions & 26 deletions scripts/build_installer_cli.py
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
import os
import platform
from collections.abc import Callable, Iterable
from pathlib import Path
from typing import Any

import click

from pathlib import Path
from typing import Any, Callable, Iterable, Optional
from build_installer import main


Expand Down Expand Up @@ -52,11 +52,10 @@ def _dependency(dependency: str) -> Callable[[click.Context, click.Option, Any],
"""

def _callback(ctx: click.Context, param: click.Option, value: Any) -> Any:
if value:
if not ctx.params.get(dependency):
raise click.BadParameter(
f"Must specify --{_snake_to_kebab(dependency)} when specifying --{param.name}"
)
if value and not ctx.params.get(dependency):
raise click.BadParameter(
f"Must specify --{_snake_to_kebab(dependency)} when specifying --{param.name}"
)
return value

return _callback
Expand All @@ -70,11 +69,10 @@ def _require_if_false_or_unspecified(
"""

def _callback(ctx: click.Context, param: click.Option, value: Any) -> Any:
if not ctx.params.get(other):
if not value:
raise click.BadParameter(
f"Must specify --{param.name} when --{_snake_to_kebab(other)} is not specified"
)
if not ctx.params.get(other) and not value:
raise click.BadParameter(
f"Must specify --{param.name} when --{_snake_to_kebab(other)} is not specified"
)
return value

return _callback
Expand Down Expand Up @@ -103,7 +101,7 @@ def _callback(ctx: click.Context, param: click.Option, value: Any) -> Any:


def _current_platform_as_default(
_ctx: click.Context, _param: click.Option, value: Optional[str]
_ctx: click.Context, _param: click.Option, value: str | None
) -> str:
"""
A callback that dynamically sets the default to the current platform
Expand Down Expand Up @@ -192,16 +190,16 @@ def _callback(_ctx: click.Context, param: click.Option, value: Any) -> Any:
)
@click.option("--override-installer-version", type=str, help="Use this as the installer version.")
def cli(
install_builder_path: Optional[Path],
install_builder_s3_bucket: Optional[str],
install_builder_s3_key: Optional[str],
install_builder_license_path: Optional[Path],
install_builder_path: Path | None,
install_builder_s3_bucket: str | None,
install_builder_s3_key: str | None,
install_builder_license_path: Path | None,
dev: bool,
local_dev: bool,
platform: str,
output_dir: Optional[Path],
output_dir: Path | None,
installer_source_path: Path,
override_installer_version: Optional[str],
override_installer_version: str | None,
) -> None:
cli_body(
install_builder_path,
Expand All @@ -218,16 +216,16 @@ def cli(


def cli_body(
install_builder_path: Optional[Path],
install_builder_s3_bucket: Optional[str],
install_builder_s3_key: Optional[str],
install_builder_license_path: Optional[Path],
install_builder_path: Path | None,
install_builder_s3_bucket: str | None,
install_builder_s3_key: str | None,
install_builder_license_path: Path | None,
dev: bool,
local_dev: bool,
platform: str,
output_dir: Optional[Path],
output_dir: Path | None,
installer_source_path: Path,
override_installer_version: Optional[str],
override_installer_version: str | None,
) -> None:
"""
Separate from the command function so we can mock the body out
Expand Down
20 changes: 9 additions & 11 deletions scripts/common.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
import subprocess
import sys

from os import PathLike
from typing import Union, Dict, Optional, List


class BadExitCodeError(Exception):
Expand All @@ -19,9 +17,9 @@ class UnsupportedOSError(Exception):


def run(
cmd: Union[PathLike, str, List[Union[str, PathLike]]],
cwd: Optional[Union[str, PathLike]] = None,
env: Optional[Dict[str, str]] = None,
cmd: PathLike | str | list[str | PathLike],
cwd: str | PathLike | None = None,
env: dict[str, str] | None = None,
echo: bool = True,
) -> str:
if echo:
Expand All @@ -35,34 +33,34 @@ def run(

if p.returncode != 0:
raise BadExitCodeError(
f"Process '{str(cmd)}' failed with exit code {p.returncode} and output: {output}"
f"Process '{cmd!s}' failed with exit code {p.returncode} and output: {output}"
)

return output


def get_latest_git_tag(cwd: Optional[Union[PathLike, str]] = None) -> str:
def get_latest_git_tag(cwd: PathLike | str | None = None) -> str:
result = run(["git", "describe", "--tags", "--abbrev=0"], cwd=cwd, echo=False).strip()
return result


def get_latest_commit_hash(cwd: Optional[Union[PathLike, str]] = None) -> str:
def get_latest_commit_hash(cwd: PathLike | str | None = None) -> str:
result = run(["git", "rev-parse", "HEAD"], cwd=cwd, echo=False).strip()
return result


def get_latest_git_tag_hash(cwd: Optional[Union[PathLike, str]] = None) -> str:
def get_latest_git_tag_hash(cwd: PathLike | str | None = None) -> str:
tag = get_latest_git_tag(cwd)
result = run(["git", "rev-list", "-n", "1", tag], cwd=cwd, echo=False).strip()
return result


def get_latest_commit_short_hash(cwd: Optional[Union[PathLike, str]] = None) -> str:
def get_latest_commit_short_hash(cwd: PathLike | str | None = None) -> str:
result = run(["git", "rev-parse", "--short", "HEAD"], cwd=cwd, echo=False).strip()
return result


def get_version_string(cwd: Optional[Union[PathLike, str]] = None) -> str:
def get_version_string(cwd: PathLike | str | None = None) -> str:
latest_tag = get_latest_git_tag(cwd)
latest_commit_hash = get_latest_commit_hash(cwd)
latest_tag_hash = get_latest_git_tag_hash(cwd)
Expand Down
20 changes: 4 additions & 16 deletions scripts/deps_bundle.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@
import re
import shutil
import subprocess
import sys

from pathlib import Path
from tempfile import TemporaryDirectory
from typing import Any
Expand All @@ -16,19 +14,9 @@


def _get_project_dict() -> dict[str, Any]:
if sys.version_info < (3, 11):
with TemporaryDirectory() as toml_env:
toml_install_pip_args = ["pip", "install", "--target", toml_env, "toml"]
subprocess.run(toml_install_pip_args, check=True)
sys.path.insert(0, toml_env)
import toml # type: ignore
mode = "r"
else:
import tomllib as toml

mode = "rb"

with open("pyproject.toml", mode) as pyproject_toml:
import tomllib as toml

with open("pyproject.toml", "rb") as pyproject_toml:
return toml.load(pyproject_toml)


Expand All @@ -40,7 +28,7 @@ def _get_dependencies(pyproject_dict: dict[str, Any]) -> list[str]:

dependencies = pyproject_dict["project"]["dependencies"]
deps_noopenjd = filter(lambda dep: not dep.startswith("openjd"), dependencies)
return list(map(lambda dep: dep.replace(" ", ""), deps_noopenjd))
return [dep.replace(" ", "") for dep in deps_noopenjd]


def _get_package_version_regex(package: str) -> re.Pattern:
Expand Down
6 changes: 2 additions & 4 deletions scripts/find_installbuilder.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,8 @@
from dataclasses import dataclass
from enum import Enum
from pathlib import Path
from typing import Optional, Union

import boto3

from common import UnsupportedOSError

_INSTALL_BUILDER_ARCHIVE_FILENAME = {
Expand All @@ -33,7 +31,7 @@ class _InstallBuilderS3Selection:

@dataclass
class InstallBuilderSelection:
selection: Optional[Union[_InstallBuilderPathSelection, _InstallBuilderS3Selection]]
selection: _InstallBuilderPathSelection | _InstallBuilderS3Selection | None

def resolve_install_builder_installation(self, workdir: Path) -> Path:
if self.selection is None:
Expand Down Expand Up @@ -65,7 +63,7 @@ def resolve_install_builder_installation(self, workdir: Path) -> Path:
raise ValueError(f"Unknown selection type: {type(self.selection)}")

@staticmethod
def from_s3(bucket_name: str, dest_path: Path, key: Optional[str] = None):
def from_s3(bucket_name: str, dest_path: Path, key: str | None = None):
if key is None:
if platform.system() in _INSTALL_BUILDER_ARCHIVE_FILENAME:
resolved_key = (
Expand Down
Loading
Loading