From ede703104c0891e64f9e50f66cd3d1b0a3c420f0 Mon Sep 17 00:00:00 2001 From: Jochen Issing Date: Sat, 4 Apr 2026 23:22:02 +0200 Subject: [PATCH] Remove Windows support Drop all Windows-specific workarounds and CI testing: - Remove windows-latest from CI matrices (test, failure-tests, integration-test) - Remove platform-specific C++ flags and Windows tag filters from .bazelrc - Remove requires-rust and requires-shell tags from all BUILD files - Remove MSYS2 path conversion workaround from integration test runner - Remove embedded _DEFAULT_CONFIG_YAML constant, read YAML file directly - Remove explicit encoding="utf-8" from all Python open() calls - Remove Windows Support section from README - Restore data = ["default_fire_config.yaml"] in config_models BUILD target Co-Authored-By: Claude Opus 4.6 --- .bazelrc | 18 +--- .github/workflows/ci.yaml | 19 ++-- README.md | 60 ------------ examples/BUILD.bazel | 4 - fire/starlark/BUILD.bazel | 1 + fire/starlark/config_models.py | 93 ++----------------- fire/starlark/config_models_test.py | 2 +- .../parameter_version/BUILD.bazel | 3 - fire/starlark/file_io_common.py | 6 +- fire/starlark/generate_format_spec.py | 2 +- fire/starlark/release_report.py | 10 +- fire/starlark/validate_release_readiness.py | 2 +- .../validate_release_readiness_test.py | 12 +-- integration_test/.bazelrc | 8 -- integration_test/BUILD.bazel | 2 - integration_test/consumer/BUILD.bazel | 1 - integration_test/run.sh | 14 --- 17 files changed, 31 insertions(+), 226 deletions(-) diff --git a/.bazelrc b/.bazelrc index fde94ee..23f38f7 100644 --- a/.bazelrc +++ b/.bazelrc @@ -3,27 +3,15 @@ # Use Bzlmod for dependency management common --enable_bzlmod -# Auto-select platform config (linux/macos/windows) -common --enable_platform_specific_config - # Python configuration build --incompatible_default_to_explicit_init_py # Test output test --test_output=errors -# C++ configuration (platform-specific) -build:linux --cxxopt=-std=c++17 -build:linux --host_cxxopt=-std=c++17 -build:macos --cxxopt=-std=c++17 -build:macos --host_cxxopt=-std=c++17 -build:windows --cxxopt=/std:c++20 -build:windows --host_cxxopt=/std:c++20 - -# Windows: exclude Rust targets and shell-based tests -# (rules_rust toolchain cannot build, sh_test scripts cannot execute on Windows) -build:windows --build_tag_filters=-requires-rust,-requires-shell -test:windows --test_tag_filters=-requires-rust,-requires-shell +# C++ configuration +build --cxxopt=-std=c++17 +build --host_cxxopt=-std=c++17 # Java configuration - use Java 17 for records support build --java_language_version=17 diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index a91eb64..4c34327 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -39,7 +39,7 @@ jobs: runs-on: ${{ matrix.os }} strategy: matrix: - os: [ubuntu-latest, macos-latest, windows-latest] + os: [ubuntu-latest, macos-latest] bazel-version: ["7.x", "8.x", "9.x"] steps: - name: Checkout code @@ -57,14 +57,12 @@ jobs: bazel-${{ matrix.os }}- - name: Run Bazel tests - shell: bash env: USE_BAZEL_VERSION: ${{ matrix.bazel-version }} run: | bazel test --config=ci --repository_cache="$HOME/.cache/bazel-repo" //... --test_output=errors - name: Build all targets - shell: bash env: USE_BAZEL_VERSION: ${{ matrix.bazel-version }} run: | @@ -91,11 +89,8 @@ jobs: run: bazel build --config=ci --config=typecheck --repository_cache="$HOME/.cache/bazel-repo" //... failure-tests: - name: Failure Tests (${{ matrix.os }}) - runs-on: ${{ matrix.os }} - strategy: - matrix: - os: [ubuntu-latest, windows-latest] + name: Failure Tests + runs-on: ubuntu-latest steps: - name: Checkout code uses: actions/checkout@v4 @@ -106,12 +101,11 @@ jobs: path: | ~/.cache/bazel-repo-failure ~/.cache/bazelisk - key: bazel-failure-tests-${{ matrix.os }}-${{ hashFiles('MODULE.bazel.lock') }} + key: bazel-failure-tests-ubuntu-latest-${{ hashFiles('MODULE.bazel.lock') }} restore-keys: | - bazel-failure-tests-${{ matrix.os }}- + bazel-failure-tests-ubuntu-latest- - name: Run failure tests - shell: bash run: | export BAZEL_EXTRA_OPTS="--config=ci --repository_cache=$HOME/.cache/bazel-repo-failure" ./fire/starlark/failure_test/run_failure_tests.sh @@ -121,7 +115,7 @@ jobs: runs-on: ${{ matrix.os }} strategy: matrix: - os: [ubuntu-latest, windows-latest] + os: [ubuntu-latest] python-version: ["3.10", "3.11", "3.12", "3.13"] steps: - name: Checkout code @@ -139,7 +133,6 @@ jobs: bazel-integration-${{ matrix.os }}- - name: Run integration test - shell: bash run: | export BAZEL_EXTRA_OPTS="--config=ci --repository_cache=$HOME/.cache/bazel-repo" cd integration_test diff --git a/README.md b/README.md index 47ba4f4..f60b2e4 100644 --- a/README.md +++ b/README.md @@ -360,63 +360,3 @@ generate_format_specification( out = "FORMAT_SPECIFICATION.md", ) ``` - -## Windows Support - -FIRE supports Windows with the following limitations: - -### Rust code generation - -The `rules_rust` toolchain cannot build on Windows due to an upstream linker -issue with the process_wrapper. All Rust targets must be tagged with -`requires-rust` so they are automatically excluded on Windows via `.bazelrc`: - -```starlark -rust_library( - name = "my_params_rs", - srcs = [":my_params_rs_src"], - tags = ["requires-rust"], -) -``` - -### Shell-based test rules - -`release_readiness_test` generates a shell script as its test executable, which -Windows cannot run via `CreateProcessW`. Tag these targets with `requires-shell` -to exclude them on Windows: - -```starlark -release_readiness_test( - name = "release_readiness", - report = ":release_report", - tags = ["requires-shell"], -) -``` - -### Platform configuration - -Windows exclusions are handled automatically via `.bazelrc` platform config. -Projects consuming FIRE should include these lines in their `.bazelrc`: - -```text -common --enable_platform_specific_config - -build:windows --build_tag_filters=-requires-rust,-requires-shell -test:windows --test_tag_filters=-requires-rust,-requires-shell -``` - -### C++ standard - -Windows (MSVC) requires C++20 for designated initializer support. Configure -in `.bazelrc`: - -```text -build:windows --cxxopt=/std:c++20 -build:windows --host_cxxopt=/std:c++20 -``` - -### File encoding - -Python scripts that read or write files containing Unicode characters (e.g., -`✓`, `⚠️`) must specify `encoding="utf-8"` explicitly, as Windows defaults to -`cp1252`. diff --git a/examples/BUILD.bazel b/examples/BUILD.bazel index dbb54ba..92bfe3f 100644 --- a/examples/BUILD.bazel +++ b/examples/BUILD.bazel @@ -109,7 +109,6 @@ generate_rust_parameters( rust_library( name = "vehicle_params_rs", srcs = [":vehicle_params_rs_src"], - tags = ["requires-rust"], ) # Second Rust library @@ -121,7 +120,6 @@ generate_rust_parameters( rust_library( name = "vehicle_params_rs_alt", srcs = [":vehicle_params_rs_alt_src"], - tags = ["requires-rust"], ) # C++ tests @@ -178,7 +176,6 @@ rust_test( name = "vehicle_params_rust_test", srcs = ["vehicle_params_test.rs"], crate_root = "vehicle_params_test.rs", - tags = ["requires-rust"], deps = [":vehicle_params_rs"], ) @@ -186,7 +183,6 @@ rust_test( name = "vehicle_params_rust_alt_test", srcs = ["vehicle_params_alt_test.rs"], crate_root = "vehicle_params_alt_test.rs", - tags = ["requires-rust"], deps = [":vehicle_params_rs_alt"], ) diff --git a/fire/starlark/BUILD.bazel b/fire/starlark/BUILD.bazel index 0be2188..9cec192 100644 --- a/fire/starlark/BUILD.bazel +++ b/fire/starlark/BUILD.bazel @@ -166,6 +166,7 @@ py_test( py_library( name = "config_models", srcs = ["config_models.py"], + data = ["default_fire_config.yaml"], visibility = ["//visibility:public"], deps = [ "@pip//pydantic", diff --git a/fire/starlark/config_models.py b/fire/starlark/config_models.py index 01dd56a..e703468 100644 --- a/fire/starlark/config_models.py +++ b/fire/starlark/config_models.py @@ -92,89 +92,9 @@ def known_fields(self) -> list[str]: return [fd.display_name.lower() for fd in self.field_definitions.values()] -_DEFAULT_CONFIG_YAML = """\ -fire_config_version: 1 - -field_definitions: - sil: - display_name: "SIL" - type: enum - values: - - "ASIL-A" - - "ASIL-B" - - "ASIL-C" - - "ASIL-D" - - "SIL-1" - - "SIL-2" - - "SIL-3" - - "SIL-4" - - "DAL-A" - - "DAL-B" - - "DAL-C" - - "DAL-D" - - "DAL-E" - - "PL-a" - - "PL-b" - - "PL-c" - - "PL-d" - - "QM" - allow_todo: true - description: "Safety Integrity Level (ISO 26262, IEC 61508, DO-178C/DO-254, ISO 13849, QM)" - - sec: - display_name: "Sec" - type: bool - allow_todo: true - description: "Security relevance flag" - - version: - display_name: "Version" - type: int - min_value: 1 - allow_todo: false - description: "Requirement version, positive integer >= 1" - - parent: - display_name: "Parent" - type: parent_link - allow_todo: true - allow_multiple: true - description: "Markdown link(s) to parent requirement(s)" - -document_types: - sysreq: - suffix: ".sysreq.md" - display_name: "System Requirement" - description: "High-level system requirements" - required_fields: - - sil - - sec - - version - optional_fields: - - parent - - swreq: - suffix: ".swreq.md" - display_name: "Software Requirement" - description: "Implementation-level software requirements" - required_fields: - - sil - - sec - - version - optional_fields: - - parent - - regreq: - suffix: ".regreq.md" - display_name: "Regulatory Requirement" - description: "Regulatory obligations (SIL/Sec optional)" - required_fields: - - version - optional_fields: - - sil - - sec - - parent -""" +def _default_config_path() -> Path: + """Return the path to the built-in default_fire_config.yaml.""" + return Path(__file__).parent / "default_fire_config.yaml" def load_config(config_path: str | Path | None = None) -> FireConfig: @@ -183,10 +103,11 @@ def load_config(config_path: str | Path | None = None) -> FireConfig: When *config_path* is ``None``, the built-in default is used. """ if config_path is None: - raw = yaml.safe_load(_DEFAULT_CONFIG_YAML) + config_path = _default_config_path() else: config_path = Path(config_path) - with open(config_path, encoding="utf-8") as f: - raw = yaml.safe_load(f) + + with open(config_path) as f: + raw = yaml.safe_load(f) return FireConfig.model_validate(raw) diff --git a/fire/starlark/config_models_test.py b/fire/starlark/config_models_test.py index b741a7c..f223833 100644 --- a/fire/starlark/config_models_test.py +++ b/fire/starlark/config_models_test.py @@ -169,7 +169,7 @@ def test_load_custom_config(self, tmp_path): }, } config_file = tmp_path / "fire_config.yaml" - config_file.write_text(yaml.dump(config_data), encoding="utf-8") + config_file.write_text(yaml.dump(config_data)) cfg = load_config(config_file) assert "handbook" in cfg.document_types assert cfg.document_types["handbook"].suffix == ".handbook.md" diff --git a/fire/starlark/failure_test/parameter_version/BUILD.bazel b/fire/starlark/failure_test/parameter_version/BUILD.bazel index 69e9847..a716a6f 100644 --- a/fire/starlark/failure_test/parameter_version/BUILD.bazel +++ b/fire/starlark/failure_test/parameter_version/BUILD.bazel @@ -68,7 +68,6 @@ generate_rust_parameters( rust_library( name = "test_params_rs", srcs = [":test_params_rust_src"], - tags = ["requires-rust"], ) # Generate Java code (directory of per-param-version .java files) @@ -131,7 +130,6 @@ rust_binary( tags = [ "failure_test", "manual", - "requires-rust", "version_too_old", ], deps = [":test_params_rs"], @@ -174,7 +172,6 @@ rust_binary( tags = [ "failure_test", "manual", - "requires-rust", "version_upgraded", ], deps = [":test_params_rs"], diff --git a/fire/starlark/file_io_common.py b/fire/starlark/file_io_common.py index 6b5d83e..296d39e 100644 --- a/fire/starlark/file_io_common.py +++ b/fire/starlark/file_io_common.py @@ -28,7 +28,7 @@ def read_file_safe(file_path: str) -> tuple[str | None, str | None]: ... process(content) """ try: - with open(file_path, "r", encoding="utf-8") as f: + with open(file_path) as f: return f.read(), None except FileNotFoundError: return None, f"File not found: {file_path}" @@ -57,7 +57,7 @@ def load_yaml_safe(file_path: str) -> tuple[Any | None, str | None]: ... process(data) """ try: - with open(file_path, "r", encoding="utf-8") as f: + with open(file_path) as f: data = yaml.safe_load(f) return data, None except FileNotFoundError: @@ -86,7 +86,7 @@ def write_yaml_safe(file_path: str, data: Any) -> str | None: ... print(f"Failed: {error}") """ try: - with open(file_path, "w", encoding="utf-8") as f: + with open(file_path, "w") as f: yaml.safe_dump(data, f, default_flow_style=False, sort_keys=False) return None except PermissionError: diff --git a/fire/starlark/generate_format_spec.py b/fire/starlark/generate_format_spec.py index 49a83d0..6ededaf 100644 --- a/fire/starlark/generate_format_spec.py +++ b/fire/starlark/generate_format_spec.py @@ -306,7 +306,7 @@ def main() -> int: config = load_config(args.config) content = generate_format_spec(config) - with open(args.out, "w", encoding="utf-8") as f: + with open(args.out, "w") as f: f.write(content) f.write("\n") diff --git a/fire/starlark/release_report.py b/fire/starlark/release_report.py index cbb49b9..4b967ce 100644 --- a/fire/starlark/release_report.py +++ b/fire/starlark/release_report.py @@ -17,7 +17,7 @@ def load_yaml_file(path: str) -> object: """Load YAML from disk and normalize empty files to an empty list.""" - with open(path, "r", encoding="utf-8") as handle: + with open(path) as handle: data = yaml.safe_load(handle) return data if data is not None else [] @@ -26,7 +26,7 @@ def load_json_file(path: str) -> object: """Load JSON from disk.""" import json - with open(path, "r", encoding="utf-8") as handle: + with open(path) as handle: return json.load(handle) @@ -332,7 +332,7 @@ def generate_release_report( for path in requirement_paths: if not path.endswith(".md"): continue - content = open(path, "r", encoding="utf-8").read() + content = open(path).read() sections.extend(parse_requirement_sections(content, path, known_fields)) for todo in extract_todos(content): todos.append((path, todo)) @@ -348,7 +348,7 @@ def generate_release_report( continue data = load_yaml_file(path) param_maps.append(build_param_version_map(data, path)) - content = open(path, "r", encoding="utf-8").read() + content = open(path).read() for todo in extract_todos(content): todos.append((path, todo)) bare_todos.extend( @@ -566,7 +566,7 @@ def main() -> int: product_name=args.product, config=config, ) - with open(args.out, "w", encoding="utf-8") as handle: + with open(args.out, "w") as handle: handle.write(report) handle.write("\n") diff --git a/fire/starlark/validate_release_readiness.py b/fire/starlark/validate_release_readiness.py index aed254b..c7a4b6d 100644 --- a/fire/starlark/validate_release_readiness.py +++ b/fire/starlark/validate_release_readiness.py @@ -16,7 +16,7 @@ def validate_release_readiness(report_path: str) -> int: Returns: 0 if ready for release, 1 if not ready """ - with open(report_path, "r", encoding="utf-8") as f: + with open(report_path) as f: content = f.read() # Check if the report indicates readiness diff --git a/fire/starlark/validate_release_readiness_test.py b/fire/starlark/validate_release_readiness_test.py index 9843fbc..3c33419 100644 --- a/fire/starlark/validate_release_readiness_test.py +++ b/fire/starlark/validate_release_readiness_test.py @@ -18,9 +18,7 @@ def test_validate_ready_for_release(): ✓ No issues found - all checks passed """ - with tempfile.NamedTemporaryFile( - mode="w", suffix=".md", delete=False, encoding="utf-8" - ) as f: + with tempfile.NamedTemporaryFile(mode="w", suffix=".md", delete=False) as f: f.write(content) f.flush() result = validate_release_readiness.validate_release_readiness(f.name) @@ -41,9 +39,7 @@ def test_validate_not_ready_for_release(): - ⚠️ Missing implementation traces: **2** ([details](#missing-implementation-traces)) - ⚠️ Open TODOs: **1** ([details](#todo-inventory)) """ - with tempfile.NamedTemporaryFile( - mode="w", suffix=".md", delete=False, encoding="utf-8" - ) as f: + with tempfile.NamedTemporaryFile(mode="w", suffix=".md", delete=False) as f: f.write(content) f.flush() result = validate_release_readiness.validate_release_readiness(f.name) @@ -57,9 +53,7 @@ def test_validate_malformed_report(): This is not a release report. """ - with tempfile.NamedTemporaryFile( - mode="w", suffix=".md", delete=False, encoding="utf-8" - ) as f: + with tempfile.NamedTemporaryFile(mode="w", suffix=".md", delete=False) as f: f.write(content) f.flush() result = validate_release_readiness.validate_release_readiness(f.name) diff --git a/integration_test/.bazelrc b/integration_test/.bazelrc index f5004b1..85f4bf0 100644 --- a/integration_test/.bazelrc +++ b/integration_test/.bazelrc @@ -3,14 +3,6 @@ # Use Bzlmod for dependency management common --enable_bzlmod -# Auto-select platform config (linux/macos/windows) -common --enable_platform_specific_config - -# Windows: exclude Rust targets and shell-based tests -# (rules_rust toolchain cannot build, sh_test scripts cannot execute on Windows) -build:windows --build_tag_filters=-requires-rust,-requires-shell -test:windows --test_tag_filters=-requires-rust,-requires-shell - # CI configuration - enables caching for GitHub Actions # Note: repository_cache path must be passed as a flag for proper $HOME expansion build:ci --announce_rc diff --git a/integration_test/BUILD.bazel b/integration_test/BUILD.bazel index 1b72580..80e3a6f 100644 --- a/integration_test/BUILD.bazel +++ b/integration_test/BUILD.bazel @@ -40,7 +40,6 @@ generate_rust_parameters( rust_library( name = "test_params_rs", srcs = [":test_params_rs_src"], - tags = ["requires-rust"], visibility = ["//visibility:public"], ) @@ -102,5 +101,4 @@ release_report( release_readiness_test( name = "integration_release_readiness", report = ":integration_release_report", - tags = ["requires-shell"], ) diff --git a/integration_test/consumer/BUILD.bazel b/integration_test/consumer/BUILD.bazel index 824be26..5f86708 100644 --- a/integration_test/consumer/BUILD.bazel +++ b/integration_test/consumer/BUILD.bazel @@ -23,7 +23,6 @@ rust_test( name = "test_rust_test", srcs = ["test_rust.rs"], crate_root = "test_rust.rs", - tags = ["requires-rust"], deps = ["//:test_params_rs"], ) diff --git a/integration_test/run.sh b/integration_test/run.sh index 8c300bf..e07628a 100755 --- a/integration_test/run.sh +++ b/integration_test/run.sh @@ -9,11 +9,6 @@ set -euo pipefail -# Prevent MSYS2 (Git Bash on Windows) from converting //foo to /foo in -# Bazel target labels. The exclusion pattern matches arguments starting -# with // so that real file paths are still converted normally. -export MSYS2_ARG_CONV_EXCL="//" - cd "$(dirname "$0")" # Parse command line arguments @@ -104,16 +99,7 @@ fi echo "" echo "Running release readiness test..." -set +e bazel test $BAZEL_OPTS //:integration_release_readiness --test_output=all -rc=$? -set -e -if [ $rc -eq 4 ]; then - # Exit code 4 means no test targets matched (e.g., filtered out on Windows) - echo "Release readiness test skipped (filtered by platform tag)" -elif [ $rc -ne 0 ]; then - exit $rc -fi echo "" echo "Integration tests completed successfully!"