Skip to content

fix: better bootstrap manifest handling#3611

Draft
rickeylev wants to merge 4 commits intobazel-contrib:mainfrom
rickeylev:fix.bootstrap.manifest
Draft

fix: better bootstrap manifest handling#3611
rickeylev wants to merge 4 commits intobazel-contrib:mainfrom
rickeylev:fix.bootstrap.manifest

Conversation

@rickeylev
Copy link
Collaborator

Changes to the bootstrap to better handle RUNFILES_MANIFEST_FILE mode

DO NOT MERGE: await #3610

@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @rickeylev, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request refines the bootstrap process for Python executables within Bazel, focusing on robust handling of runfiles manifests and improving cross-platform compatibility, especially for Windows environments. It introduces a structured way to manage Bazel's command-line options through dedicated aliases and streamlines the configuration of Python binaries and tests.

Highlights

  • Enhanced RUNFILES_MANIFEST_FILE Handling: Improved the bootstrap mechanism to better support the RUNFILES_MANIFEST_FILE mode, particularly for locating Python binaries and main files within the runfiles manifest.
  • Bazel command_line_option Aliases: Introduced a new command_line_option package to define aliases for Bazel's built-in //command_line_option:XXX pseudo-targets, allowing py_binary.config_settings to correctly transition these settings.
  • Windows Compatibility Improvements: Addressed several Windows-specific issues, including refactoring the PowerShell build_data_writer to prevent encoding/locking problems, and enhancing runfiles path resolution and build data reading to handle Windows paths and BOMs.
  • Refactored Python Executable Macros: Consolidated common setup logic for py_binary and py_test rules into a new common_executable_macro_kwargs_setup function, which now includes default config_settings for runfiles behavior, especially on Windows.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Changelog
  • BUILD.bazel
    • Added //command_line_option:distribution to the distribution filegroup.
  • command_line_option/BUILD.bazel
    • Added new Bazel BUILD file to define aliases for //command_line_option pseudo-targets like build_runfile_links and enable_runfiles, and a distribution filegroup.
  • docs/api/rules_python/command_line_option/index.md
    • Added new documentation file for the //command_line_option package.
  • python/private/attributes.bzl
    • Added an important note explaining the special handling of command_line_option labels in config_settings.
    • Modified apply_config_settings_attr to correctly map command_line_option package labels to their Bazel-builtin pseudo-target format.
  • python/private/build_data_writer.ps1
    • Refactored PowerShell script to collect output lines into an array and write them using .NET's System.IO.File::WriteAllLines with UTF8 No BOM encoding to avoid PowerShell encoding/locking quirks.
    • Added logic to set file access control list (ACL) for the output path, granting read access to 'Everyone'.
  • python/private/common_labels.bzl
    • Added BUILD_RUNFILE_LINKS and ENABLE_RUNFILES labels, referencing the new //command_line_option aliases.
    • Added PLATFORMS_OS_WINDOWS label for platform-specific configuration.
  • python/private/py_binary_macro.bzl
    • Replaced the direct call to convert_legacy_create_init_to_int with a call to the new common_executable_macro_kwargs_setup function.
  • python/private/py_executable.bzl
    • Modified _create_stage1_bootstrap to use runfiles_root_path for stage2_bootstrap path construction.
    • Introduced add_config_setting_defaults function to apply default config_settings, including ENABLE_RUNFILES for Windows.
    • Created common_executable_macro_kwargs_setup to encapsulate convert_legacy_create_init_to_int and add_config_setting_defaults.
    • Updated create_executable_rule_builder to include //command_line_option:build_runfile_links and //command_line_option:enable_runfiles in the transition inputs and outputs.
  • python/private/py_test_macro.bzl
    • Replaced the direct call to convert_legacy_create_init_to_int with a call to the new common_executable_macro_kwargs_setup function.
  • python/private/python_bootstrap_template.txt
    • Updated comment for _STAGE2_BOOTSTRAP_SENTINEL to clarify its purpose.
    • Added a new maybe_find_in_manifest function to search for files within the RUNFILES_MANIFEST_FILE.
    • Modified FindBinary to check RUNFILES_MANIFEST_FILE if the binary is not found directly.
    • Introduced find_main_file to locate the main script, incorporating manifest lookup.
    • Added verbose logging for various bootstrap variables and paths.
    • Enhanced the error message when the Python binary cannot be found.
  • python/private/stage2_bootstrap_template.py
    • Added a comment to BUILD_DATA_FILE regarding Windows path conversion.
    • Modified get_build_data to handle Windows path separators, use utf-8-sig encoding for BOM compatibility, and provide more detailed error information on failure.
    • Added a comment to find_runfiles_root about the implications of --enable_runfiles=false.
  • tests/bootstrap_impls/BUILD.bazel
    • Imported py_binary and py_test rules.
    • Added a new py_test target named system_python_nodeps_test.
  • tests/bootstrap_impls/system_python_nodeps_test.py
    • Added a simple Python test file.
  • tests/pypi/whl_installer/wheel_installer_test.py
    • Modified tearDown method to ignore errors when removing the wheel directory, addressing Windows-specific file locking issues.
  • tests/support/py_reconfig.bzl
    • Removed the explicit loop for attr.config_settings from _perform_transition_impl as this is now handled by apply_config_settings_attr.
    • Added //command_line_option:build_runfile_links, //command_line_option:extra_toolchains, and //command_line_option:stamp to _RECONFIG_INPUTS for reconfigurable transitions.
Activity
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request introduces significant improvements to the bootstrap manifest handling, particularly for RUNFILES_MANIFEST_FILE mode. It adds a new command_line_option package to better handle Bazel pseudo-targets and includes several refactorings to enhance robustness, especially on Windows. The changes are well-structured and include necessary test updates. I have a couple of minor suggestions to improve documentation and logging.

Comment on lines 10 to 22
# todo: add docs, xref with config_settings
# rules_python target, config_setting processing code converts it to the
# Bazel-builtin //command_line_label:build_runfile_links psuedo-target
alias(
name = "build_runfile_links",
actual = "//python:none",
)

# todo: add docs
alias(
name = "enable_runfiles",
actual = "//python:none",
)
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

The todo comments indicate that documentation for these new aliases is pending. It would be beneficial to add this documentation to docs/api/rules_python/command_line_option/index.md within this pull request. This will help users understand and adopt this new feature.

full_path = os.path.join(module_space, bin_name)
if os.path.exists(full_path):
return full_path
full_path = maybe_find_in_manifest(bin_name, True)
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

The show_lines argument to maybe_find_in_manifest is hardcoded to True. When verbose logging is enabled, this will print every line of the runfiles manifest, which could be excessively noisy for large projects. It would be better to set this to False to keep the verbose output focused. Note that the call to this function in find_main_file already uses the default of False.

    full_path = maybe_find_in_manifest(bin_name, False)

@rickeylev rickeylev marked this pull request as draft February 18, 2026 01:57
@rickeylev rickeylev force-pushed the fix.bootstrap.manifest branch from 7fa5fa3 to 43706c4 Compare February 18, 2026 02:31
@rickeylev rickeylev force-pushed the fix.bootstrap.manifest branch from 43706c4 to 0cd1479 Compare February 18, 2026 03:11
print("bootstrap: stage 1:", *args, file=sys.stderr, flush=True)

def maybe_find_in_manifest(rf_root_path, show_lines=False):
if not os.environ.get("RUNFILES_MANIFEST_FILE"):
Copy link
Collaborator

Choose a reason for hiding this comment

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

Nit: mixing 4-space indent and 2-space indent, here and a couple other places.

It looks like most of the file is 2-space.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

Comments