diff --git a/.bazelci/presubmit.yml b/.bazelci/presubmit.yml
index 8ad04894d9..b468970fbb 100644
--- a/.bazelci/presubmit.yml
+++ b/.bazelci/presubmit.yml
@@ -48,6 +48,8 @@ buildifier:
test_targets: ["..."]
.coverage_targets_example_bzlmod: &coverage_targets_example_bzlmod
coverage_targets: ["//:test"]
+.coverage_targets_example_bzlmod_build_file_generation: &coverage_targets_example_bzlmod_build_file_generation
+ coverage_targets: ["//:bzlmod_build_file_generation_test"]
.coverage_targets_example_multi_python: &coverage_targets_example_multi_python
coverage_targets:
- //tests:my_lib_3_10_test
@@ -179,6 +181,46 @@ tasks:
working_directory: examples/bzlmod
platform: windows
+ integration_test_bzlmod_generate_build_file_generation_ubuntu_min:
+ <<: *minimum_supported_bzlmod_version
+ <<: *reusable_build_test_all
+ <<: *coverage_targets_example_bzlmod_build_file_generation
+ name: example bzlmod build file min bazel version integration test
+ working_directory: examples/bzlmod_build_file_generation
+ platform: ubuntu2004
+ integration_test_bzlmod_generation_build_files_ubuntu:
+ <<: *reusable_build_test_all
+ <<: *coverage_targets_example_bzlmod_build_file_generation
+ name: example bzlmod build file integration test
+ working_directory: examples/bzlmod_build_file_generation
+ platform: ubuntu2004
+ integration_test_bzlmod_generation_build_files_ubuntu_run:
+ <<: *reusable_build_test_all
+ name: example bzlmod build file running gazelle and pip integration test
+ working_directory: examples/bzlmod_build_file_generation
+ platform: ubuntu2004
+ shell_commands:
+ - "bazel run //:gazelle_python_manifest.update"
+ - "bazel run //:gazelle -- update"
+ integration_test_bzlmod_build_file_generation_debian:
+ <<: *reusable_build_test_all
+ <<: *coverage_targets_example_bzlmod_build_file_generation
+ name: example bzlmod build file integration test
+ working_directory: examples/bzlmod_build_file_generation
+ platform: debian11
+ integration_test_bzlmod_build_file_generation_macos:
+ <<: *reusable_build_test_all
+ <<: *coverage_targets_example_bzlmod_build_file_generation
+ name: example bzlmod build file integration test
+ working_directory: examples/bzlmod_build_file_generation
+ platform: macos
+ integration_test_bzlmod_build_file_generation_windows:
+ <<: *reusable_build_test_all
+ # coverage is not supported on Windows
+ name: example bzlmod build file integration test
+ working_directory: examples/bzlmod_build_file_generation
+ platform: windows
+
integration_test_multi_python_versions_ubuntu_min:
<<: *minimum_supported_version
<<: *reusable_build_test_all
diff --git a/.bazelrc b/.bazelrc
index d607cdd9b7..e7e4af7bbd 100644
--- a/.bazelrc
+++ b/.bazelrc
@@ -3,8 +3,8 @@
# This lets us glob() up all the files inside the examples to make them inputs to tests
# (Note, we cannot use `common --deleted_packages` because the bazel version command doesn't support it)
# To update these lines, run tools/bazel_integration_test/update_deleted_packages.sh
-build --deleted_packages=examples/build_file_generation,examples/build_file_generation/get_url,examples/bzlmod,examples/bzlmod/other_module/other_module/pkg,examples/bzlmod/runfiles,examples/multi_python_versions,examples/multi_python_versions/libs/my_lib,examples/multi_python_versions/requirements,examples/multi_python_versions/tests,examples/pip_install,examples/pip_parse,examples/pip_parse_vendored,examples/pip_repository_annotations,examples/py_import,examples/py_proto_library,examples/relative_requirements,tests/compile_pip_requirements,tests/pip_repository_entry_points,tests/pip_deps
-query --deleted_packages=examples/build_file_generation,examples/build_file_generation/get_url,examples/bzlmod,examples/bzlmod/other_module/other_module/pkg,examples/bzlmod/runfiles,examples/multi_python_versions,examples/multi_python_versions/libs/my_lib,examples/multi_python_versions/requirements,examples/multi_python_versions/tests,examples/pip_install,examples/pip_parse,examples/pip_parse_vendored,examples/pip_repository_annotations,examples/py_import,examples/py_proto_library,examples/relative_requirements,tests/compile_pip_requirements,tests/pip_repository_entry_points,tests/pip_deps
+build --deleted_packages=examples/build_file_generation,examples/build_file_generation/get_url,examples/bzlmod_build_file_generation,examples/bzlmod_build_file_generation/other_module/other_module/pkg,examples/bzlmod_build_file_generation/runfiles,examples/bzlmod,examples/bzlmod/other_module/other_module/pkg,examples/bzlmod/runfiles,examples/multi_python_versions,examples/multi_python_versions/libs/my_lib,examples/multi_python_versions/requirements,examples/multi_python_versions/tests,examples/pip_install,examples/pip_parse,examples/pip_parse_vendored,examples/pip_repository_annotations,examples/py_import,examples/py_proto_library,examples/relative_requirements,tests/compile_pip_requirements,tests/pip_repository_entry_points,tests/pip_deps
+query --deleted_packages=examples/build_file_generation,examples/build_file_generation/get_url,examples/bzlmod_build_file_generation,examples/bzlmod_build_file_generation/other_module/other_module/pkg,examples/bzlmod_build_file_generation/runfiles,examples/bzlmod,examples/bzlmod/other_module/other_module/pkg,examples/bzlmod/runfiles,examples/multi_python_versions,examples/multi_python_versions/libs/my_lib,examples/multi_python_versions/requirements,examples/multi_python_versions/tests,examples/pip_install,examples/pip_parse,examples/pip_parse_vendored,examples/pip_repository_annotations,examples/py_import,examples/py_proto_library,examples/relative_requirements,tests/compile_pip_requirements,tests/pip_repository_entry_points,tests/pip_deps
test --test_output=errors
diff --git a/docs/pip_repository.md b/docs/pip_repository.md
index 99af4bac81..29cb3d9c32 100644
--- a/docs/pip_repository.md
+++ b/docs/pip_repository.md
@@ -69,7 +69,7 @@ py_binary(
| isolated | Whether or not to pass the [--isolated](https://pip.pypa.io/en/stable/cli/pip/#cmdoption-isolated) flag to the underlying pip command. Alternatively, the RULES_PYTHON_PIP_ISOLATED environment variable can be used to control this flag. | Boolean | optional | True |
| pip_data_exclude | Additional data exclusion parameters to add to the pip packages BUILD file. | List of strings | optional | [] |
| python_interpreter | The python interpreter to use. This can either be an absolute path or the name of a binary found on the host's PATH environment variable. If no value is set python3 is defaulted for Unix systems and python.exe for Windows. | String | optional | "" |
-| python_interpreter_target | If you are using a custom python interpreter built by another repository rule, use this attribute to specify its BUILD target. This allows pip_repository to invoke pip using the same interpreter as your toolchain. If set, takes precedence over python_interpreter. | Label | optional | None |
+| python_interpreter_target | If you are using a custom python interpreter built by another repository rule, use this attribute to specify its BUILD target. This allows pip_repository to invoke pip using the same interpreter as your toolchain. If set, takes precedence over python_interpreter. An example value: "@python3_x86_64-unknown-linux-gnu//:python". | Label | optional | None |
| quiet | If True, suppress printing stdout and stderr output to the terminal. | Boolean | optional | True |
| repo_mapping | A dictionary from local repository name to global repository name. This allows controls over workspace dependency resolution for dependencies of this repository.<p>For example, an entry "@foo": "@bar" declares that, for any time this repository depends on @foo (such as a dependency on @foo//some:target, it should actually resolve that dependency within globally-declared @bar (@bar//some:target). | Dictionary: String -> String | required | |
| repo_prefix | Prefix for the generated packages will be of the form @<prefix><sanitized-package-name>//... | String | optional | "" |
@@ -133,7 +133,7 @@ Instantiated from pip_repository and inherits config options from there.
| isolated | Whether or not to pass the [--isolated](https://pip.pypa.io/en/stable/cli/pip/#cmdoption-isolated) flag to the underlying pip command. Alternatively, the RULES_PYTHON_PIP_ISOLATED environment variable can be used to control this flag. | Boolean | optional | True |
| pip_data_exclude | Additional data exclusion parameters to add to the pip packages BUILD file. | List of strings | optional | [] |
| python_interpreter | The python interpreter to use. This can either be an absolute path or the name of a binary found on the host's PATH environment variable. If no value is set python3 is defaulted for Unix systems and python.exe for Windows. | String | optional | "" |
-| python_interpreter_target | If you are using a custom python interpreter built by another repository rule, use this attribute to specify its BUILD target. This allows pip_repository to invoke pip using the same interpreter as your toolchain. If set, takes precedence over python_interpreter. | Label | optional | None |
+| python_interpreter_target | If you are using a custom python interpreter built by another repository rule, use this attribute to specify its BUILD target. This allows pip_repository to invoke pip using the same interpreter as your toolchain. If set, takes precedence over python_interpreter. An example value: "@python3_x86_64-unknown-linux-gnu//:python". | Label | optional | None |
| quiet | If True, suppress printing stdout and stderr output to the terminal. | Boolean | optional | True |
| repo | Pointer to parent repo name. Used to make these rules rerun if the parent repo changes. | String | required | |
| repo_mapping | A dictionary from local repository name to global repository name. This allows controls over workspace dependency resolution for dependencies of this repository.<p>For example, an entry "@foo": "@bar" declares that, for any time this repository depends on @foo (such as a dependency on @foo//some:target, it should actually resolve that dependency within globally-declared @bar (@bar//some:target). | Dictionary: String -> String | required | |
diff --git a/examples/BUILD.bazel b/examples/BUILD.bazel
index 3ef89054c9..feb1cfbd4e 100644
--- a/examples/BUILD.bazel
+++ b/examples/BUILD.bazel
@@ -22,6 +22,11 @@ bazel_integration_test(
timeout = "long",
)
+bazel_integration_test(
+ name = "bzlmod_build_file_generation_example",
+ timeout = "long",
+)
+
bazel_integration_test(
name = "pip_install_example",
timeout = "long",
diff --git a/examples/build_file_generation/.bazelrc b/examples/build_file_generation/.bazelrc
index f23315a7a1..28f634bef6 100644
--- a/examples/build_file_generation/.bazelrc
+++ b/examples/build_file_generation/.bazelrc
@@ -1,4 +1,4 @@
-test --test_output=errors
+test --test_output=errors --enable_runfiles
# Windows requires these for multi-python support:
build --enable_runfiles
diff --git a/examples/bzlmod/gazelle_python.yaml b/examples/bzlmod/gazelle_python.yaml
new file mode 100644
index 0000000000..12096e5837
--- /dev/null
+++ b/examples/bzlmod/gazelle_python.yaml
@@ -0,0 +1,590 @@
+# GENERATED FILE - DO NOT EDIT!
+#
+# To update this file, run:
+# bazel run //:gazelle_python_manifest.update
+
+manifest:
+ modules_mapping:
+ S3: s3cmd
+ S3.ACL: s3cmd
+ S3.AccessLog: s3cmd
+ S3.BidirMap: s3cmd
+ S3.CloudFront: s3cmd
+ S3.Config: s3cmd
+ S3.ConnMan: s3cmd
+ S3.Crypto: s3cmd
+ S3.Custom_httplib27: s3cmd
+ S3.Custom_httplib3x: s3cmd
+ S3.Exceptions: s3cmd
+ S3.ExitCodes: s3cmd
+ S3.FileDict: s3cmd
+ S3.FileLists: s3cmd
+ S3.HashCache: s3cmd
+ S3.MultiPart: s3cmd
+ S3.PkgInfo: s3cmd
+ S3.Progress: s3cmd
+ S3.S3: s3cmd
+ S3.S3Uri: s3cmd
+ S3.SortedDict: s3cmd
+ S3.Utils: s3cmd
+ astroid: astroid
+ astroid.arguments: astroid
+ astroid.astroid_manager: astroid
+ astroid.bases: astroid
+ astroid.brain: astroid
+ astroid.brain.brain_argparse: astroid
+ astroid.brain.brain_attrs: astroid
+ astroid.brain.brain_boto3: astroid
+ astroid.brain.brain_builtin_inference: astroid
+ astroid.brain.brain_collections: astroid
+ astroid.brain.brain_crypt: astroid
+ astroid.brain.brain_ctypes: astroid
+ astroid.brain.brain_curses: astroid
+ astroid.brain.brain_dataclasses: astroid
+ astroid.brain.brain_dateutil: astroid
+ astroid.brain.brain_fstrings: astroid
+ astroid.brain.brain_functools: astroid
+ astroid.brain.brain_gi: astroid
+ astroid.brain.brain_hashlib: astroid
+ astroid.brain.brain_http: astroid
+ astroid.brain.brain_hypothesis: astroid
+ astroid.brain.brain_io: astroid
+ astroid.brain.brain_mechanize: astroid
+ astroid.brain.brain_multiprocessing: astroid
+ astroid.brain.brain_namedtuple_enum: astroid
+ astroid.brain.brain_nose: astroid
+ astroid.brain.brain_numpy_core_einsumfunc: astroid
+ astroid.brain.brain_numpy_core_fromnumeric: astroid
+ astroid.brain.brain_numpy_core_function_base: astroid
+ astroid.brain.brain_numpy_core_multiarray: astroid
+ astroid.brain.brain_numpy_core_numeric: astroid
+ astroid.brain.brain_numpy_core_numerictypes: astroid
+ astroid.brain.brain_numpy_core_umath: astroid
+ astroid.brain.brain_numpy_ma: astroid
+ astroid.brain.brain_numpy_ndarray: astroid
+ astroid.brain.brain_numpy_random_mtrand: astroid
+ astroid.brain.brain_numpy_utils: astroid
+ astroid.brain.brain_pathlib: astroid
+ astroid.brain.brain_pkg_resources: astroid
+ astroid.brain.brain_pytest: astroid
+ astroid.brain.brain_qt: astroid
+ astroid.brain.brain_random: astroid
+ astroid.brain.brain_re: astroid
+ astroid.brain.brain_responses: astroid
+ astroid.brain.brain_scipy_signal: astroid
+ astroid.brain.brain_signal: astroid
+ astroid.brain.brain_six: astroid
+ astroid.brain.brain_sqlalchemy: astroid
+ astroid.brain.brain_ssl: astroid
+ astroid.brain.brain_subprocess: astroid
+ astroid.brain.brain_threading: astroid
+ astroid.brain.brain_type: astroid
+ astroid.brain.brain_typing: astroid
+ astroid.brain.brain_unittest: astroid
+ astroid.brain.brain_uuid: astroid
+ astroid.brain.helpers: astroid
+ astroid.builder: astroid
+ astroid.const: astroid
+ astroid.context: astroid
+ astroid.decorators: astroid
+ astroid.exceptions: astroid
+ astroid.filter_statements: astroid
+ astroid.helpers: astroid
+ astroid.inference: astroid
+ astroid.inference_tip: astroid
+ astroid.interpreter: astroid
+ astroid.interpreter.dunder_lookup: astroid
+ astroid.interpreter.objectmodel: astroid
+ astroid.manager: astroid
+ astroid.mixins: astroid
+ astroid.modutils: astroid
+ astroid.node_classes: astroid
+ astroid.nodes: astroid
+ astroid.nodes.as_string: astroid
+ astroid.nodes.const: astroid
+ astroid.nodes.node_classes: astroid
+ astroid.nodes.node_ng: astroid
+ astroid.nodes.scoped_nodes: astroid
+ astroid.nodes.scoped_nodes.mixin: astroid
+ astroid.nodes.scoped_nodes.scoped_nodes: astroid
+ astroid.nodes.scoped_nodes.utils: astroid
+ astroid.nodes.utils: astroid
+ astroid.objects: astroid
+ astroid.protocols: astroid
+ astroid.raw_building: astroid
+ astroid.rebuilder: astroid
+ astroid.scoped_nodes: astroid
+ astroid.test_utils: astroid
+ astroid.transforms: astroid
+ astroid.typing: astroid
+ astroid.util: astroid
+ certifi: certifi
+ certifi.core: certifi
+ chardet: chardet
+ chardet.big5freq: chardet
+ chardet.big5prober: chardet
+ chardet.chardistribution: chardet
+ chardet.charsetgroupprober: chardet
+ chardet.charsetprober: chardet
+ chardet.cli: chardet
+ chardet.cli.chardetect: chardet
+ chardet.codingstatemachine: chardet
+ chardet.compat: chardet
+ chardet.cp949prober: chardet
+ chardet.enums: chardet
+ chardet.escprober: chardet
+ chardet.escsm: chardet
+ chardet.eucjpprober: chardet
+ chardet.euckrfreq: chardet
+ chardet.euckrprober: chardet
+ chardet.euctwfreq: chardet
+ chardet.euctwprober: chardet
+ chardet.gb2312freq: chardet
+ chardet.gb2312prober: chardet
+ chardet.hebrewprober: chardet
+ chardet.jisfreq: chardet
+ chardet.jpcntx: chardet
+ chardet.langbulgarianmodel: chardet
+ chardet.langgreekmodel: chardet
+ chardet.langhebrewmodel: chardet
+ chardet.langhungarianmodel: chardet
+ chardet.langrussianmodel: chardet
+ chardet.langthaimodel: chardet
+ chardet.langturkishmodel: chardet
+ chardet.latin1prober: chardet
+ chardet.mbcharsetprober: chardet
+ chardet.mbcsgroupprober: chardet
+ chardet.mbcssm: chardet
+ chardet.metadata: chardet
+ chardet.metadata.languages: chardet
+ chardet.sbcharsetprober: chardet
+ chardet.sbcsgroupprober: chardet
+ chardet.sjisprober: chardet
+ chardet.universaldetector: chardet
+ chardet.utf8prober: chardet
+ chardet.version: chardet
+ dateutil: python_dateutil
+ dateutil.easter: python_dateutil
+ dateutil.parser: python_dateutil
+ dateutil.parser.isoparser: python_dateutil
+ dateutil.relativedelta: python_dateutil
+ dateutil.rrule: python_dateutil
+ dateutil.tz: python_dateutil
+ dateutil.tz.tz: python_dateutil
+ dateutil.tz.win: python_dateutil
+ dateutil.tzwin: python_dateutil
+ dateutil.utils: python_dateutil
+ dateutil.zoneinfo: python_dateutil
+ dateutil.zoneinfo.rebuild: python_dateutil
+ dill: dill
+ dill.detect: dill
+ dill.logger: dill
+ dill.objtypes: dill
+ dill.pointers: dill
+ dill.session: dill
+ dill.settings: dill
+ dill.source: dill
+ dill.temp: dill
+ idna: idna
+ idna.codec: idna
+ idna.compat: idna
+ idna.core: idna
+ idna.idnadata: idna
+ idna.intranges: idna
+ idna.package_data: idna
+ idna.uts46data: idna
+ isort: isort
+ isort.api: isort
+ isort.comments: isort
+ isort.core: isort
+ isort.deprecated: isort
+ isort.deprecated.finders: isort
+ isort.exceptions: isort
+ isort.files: isort
+ isort.format: isort
+ isort.hooks: isort
+ isort.identify: isort
+ isort.io: isort
+ isort.literal: isort
+ isort.logo: isort
+ isort.main: isort
+ isort.output: isort
+ isort.parse: isort
+ isort.place: isort
+ isort.profiles: isort
+ isort.pylama_isort: isort
+ isort.sections: isort
+ isort.settings: isort
+ isort.setuptools_commands: isort
+ isort.sorting: isort
+ isort.stdlibs: isort
+ isort.stdlibs.all: isort
+ isort.stdlibs.py2: isort
+ isort.stdlibs.py27: isort
+ isort.stdlibs.py3: isort
+ isort.stdlibs.py310: isort
+ isort.stdlibs.py311: isort
+ isort.stdlibs.py36: isort
+ isort.stdlibs.py37: isort
+ isort.stdlibs.py38: isort
+ isort.stdlibs.py39: isort
+ isort.utils: isort
+ isort.wrap: isort
+ isort.wrap_modes: isort
+ lazy_object_proxy: lazy_object_proxy
+ lazy_object_proxy.compat: lazy_object_proxy
+ lazy_object_proxy.simple: lazy_object_proxy
+ lazy_object_proxy.slots: lazy_object_proxy
+ lazy_object_proxy.utils: lazy_object_proxy
+ magic: python_magic
+ magic.compat: python_magic
+ magic.loader: python_magic
+ mccabe: mccabe
+ pathspec: pathspec
+ pathspec.gitignore: pathspec
+ pathspec.pathspec: pathspec
+ pathspec.pattern: pathspec
+ pathspec.patterns: pathspec
+ pathspec.patterns.gitwildmatch: pathspec
+ pathspec.util: pathspec
+ pkg_resources: setuptools
+ pkg_resources.extern: setuptools
+ platformdirs: platformdirs
+ platformdirs.android: platformdirs
+ platformdirs.api: platformdirs
+ platformdirs.macos: platformdirs
+ platformdirs.unix: platformdirs
+ platformdirs.version: platformdirs
+ platformdirs.windows: platformdirs
+ pylint: pylint
+ pylint.checkers: pylint
+ pylint.checkers.async: pylint
+ pylint.checkers.base: pylint
+ pylint.checkers.base.basic_checker: pylint
+ pylint.checkers.base.basic_error_checker: pylint
+ pylint.checkers.base.comparison_checker: pylint
+ pylint.checkers.base.docstring_checker: pylint
+ pylint.checkers.base.name_checker: pylint
+ pylint.checkers.base.name_checker.checker: pylint
+ pylint.checkers.base.name_checker.naming_style: pylint
+ pylint.checkers.base.pass_checker: pylint
+ pylint.checkers.base_checker: pylint
+ pylint.checkers.classes: pylint
+ pylint.checkers.classes.class_checker: pylint
+ pylint.checkers.classes.special_methods_checker: pylint
+ pylint.checkers.deprecated: pylint
+ pylint.checkers.design_analysis: pylint
+ pylint.checkers.dunder_methods: pylint
+ pylint.checkers.ellipsis_checker: pylint
+ pylint.checkers.exceptions: pylint
+ pylint.checkers.format: pylint
+ pylint.checkers.imports: pylint
+ pylint.checkers.lambda_expressions: pylint
+ pylint.checkers.logging: pylint
+ pylint.checkers.mapreduce_checker: pylint
+ pylint.checkers.method_args: pylint
+ pylint.checkers.misc: pylint
+ pylint.checkers.modified_iterating_checker: pylint
+ pylint.checkers.newstyle: pylint
+ pylint.checkers.non_ascii_names: pylint
+ pylint.checkers.raw_metrics: pylint
+ pylint.checkers.refactoring: pylint
+ pylint.checkers.refactoring.implicit_booleaness_checker: pylint
+ pylint.checkers.refactoring.not_checker: pylint
+ pylint.checkers.refactoring.recommendation_checker: pylint
+ pylint.checkers.refactoring.refactoring_checker: pylint
+ pylint.checkers.similar: pylint
+ pylint.checkers.spelling: pylint
+ pylint.checkers.stdlib: pylint
+ pylint.checkers.strings: pylint
+ pylint.checkers.threading_checker: pylint
+ pylint.checkers.typecheck: pylint
+ pylint.checkers.unicode: pylint
+ pylint.checkers.unsupported_version: pylint
+ pylint.checkers.utils: pylint
+ pylint.checkers.variables: pylint
+ pylint.config: pylint
+ pylint.config.argument: pylint
+ pylint.config.arguments_manager: pylint
+ pylint.config.arguments_provider: pylint
+ pylint.config.callback_actions: pylint
+ pylint.config.config_file_parser: pylint
+ pylint.config.config_initialization: pylint
+ pylint.config.configuration_mixin: pylint
+ pylint.config.deprecation_actions: pylint
+ pylint.config.environment_variable: pylint
+ pylint.config.exceptions: pylint
+ pylint.config.find_default_config_files: pylint
+ pylint.config.help_formatter: pylint
+ pylint.config.option: pylint
+ pylint.config.option_manager_mixin: pylint
+ pylint.config.option_parser: pylint
+ pylint.config.options_provider_mixin: pylint
+ pylint.config.utils: pylint
+ pylint.constants: pylint
+ pylint.epylint: pylint
+ pylint.exceptions: pylint
+ pylint.extensions: pylint
+ pylint.extensions.bad_builtin: pylint
+ pylint.extensions.broad_try_clause: pylint
+ pylint.extensions.check_elif: pylint
+ pylint.extensions.code_style: pylint
+ pylint.extensions.comparetozero: pylint
+ pylint.extensions.comparison_placement: pylint
+ pylint.extensions.confusing_elif: pylint
+ pylint.extensions.consider_ternary_expression: pylint
+ pylint.extensions.docparams: pylint
+ pylint.extensions.docstyle: pylint
+ pylint.extensions.empty_comment: pylint
+ pylint.extensions.emptystring: pylint
+ pylint.extensions.eq_without_hash: pylint
+ pylint.extensions.for_any_all: pylint
+ pylint.extensions.mccabe: pylint
+ pylint.extensions.no_self_use: pylint
+ pylint.extensions.overlapping_exceptions: pylint
+ pylint.extensions.private_import: pylint
+ pylint.extensions.redefined_loop_name: pylint
+ pylint.extensions.redefined_variable_type: pylint
+ pylint.extensions.set_membership: pylint
+ pylint.extensions.typing: pylint
+ pylint.extensions.while_used: pylint
+ pylint.graph: pylint
+ pylint.interfaces: pylint
+ pylint.lint: pylint
+ pylint.lint.base_options: pylint
+ pylint.lint.caching: pylint
+ pylint.lint.expand_modules: pylint
+ pylint.lint.message_state_handler: pylint
+ pylint.lint.parallel: pylint
+ pylint.lint.pylinter: pylint
+ pylint.lint.report_functions: pylint
+ pylint.lint.run: pylint
+ pylint.lint.utils: pylint
+ pylint.message: pylint
+ pylint.message.message: pylint
+ pylint.message.message_definition: pylint
+ pylint.message.message_definition_store: pylint
+ pylint.message.message_id_store: pylint
+ pylint.pyreverse: pylint
+ pylint.pyreverse.diadefslib: pylint
+ pylint.pyreverse.diagrams: pylint
+ pylint.pyreverse.dot_printer: pylint
+ pylint.pyreverse.inspector: pylint
+ pylint.pyreverse.main: pylint
+ pylint.pyreverse.mermaidjs_printer: pylint
+ pylint.pyreverse.plantuml_printer: pylint
+ pylint.pyreverse.printer: pylint
+ pylint.pyreverse.printer_factory: pylint
+ pylint.pyreverse.utils: pylint
+ pylint.pyreverse.vcg_printer: pylint
+ pylint.pyreverse.writer: pylint
+ pylint.reporters: pylint
+ pylint.reporters.base_reporter: pylint
+ pylint.reporters.collecting_reporter: pylint
+ pylint.reporters.json_reporter: pylint
+ pylint.reporters.multi_reporter: pylint
+ pylint.reporters.reports_handler_mix_in: pylint
+ pylint.reporters.text: pylint
+ pylint.reporters.ureports: pylint
+ pylint.reporters.ureports.base_writer: pylint
+ pylint.reporters.ureports.nodes: pylint
+ pylint.reporters.ureports.text_writer: pylint
+ pylint.testutils: pylint
+ pylint.testutils.checker_test_case: pylint
+ pylint.testutils.configuration_test: pylint
+ pylint.testutils.constants: pylint
+ pylint.testutils.decorator: pylint
+ pylint.testutils.functional: pylint
+ pylint.testutils.functional.find_functional_tests: pylint
+ pylint.testutils.functional.lint_module_output_update: pylint
+ pylint.testutils.functional.test_file: pylint
+ pylint.testutils.functional_test_file: pylint
+ pylint.testutils.get_test_info: pylint
+ pylint.testutils.global_test_linter: pylint
+ pylint.testutils.lint_module_test: pylint
+ pylint.testutils.output_line: pylint
+ pylint.testutils.pyreverse: pylint
+ pylint.testutils.reporter_for_tests: pylint
+ pylint.testutils.tokenize_str: pylint
+ pylint.testutils.unittest_linter: pylint
+ pylint.testutils.utils: pylint
+ pylint.typing: pylint
+ pylint.utils: pylint
+ pylint.utils.ast_walker: pylint
+ pylint.utils.docs: pylint
+ pylint.utils.file_state: pylint
+ pylint.utils.linterstats: pylint
+ pylint.utils.pragma_parser: pylint
+ pylint.utils.utils: pylint
+ requests: requests
+ requests.adapters: requests
+ requests.api: requests
+ requests.auth: requests
+ requests.certs: requests
+ requests.compat: requests
+ requests.cookies: requests
+ requests.exceptions: requests
+ requests.help: requests
+ requests.hooks: requests
+ requests.models: requests
+ requests.packages: requests
+ requests.sessions: requests
+ requests.status_codes: requests
+ requests.structures: requests
+ requests.utils: requests
+ setuptools: setuptools
+ setuptools.archive_util: setuptools
+ setuptools.build_meta: setuptools
+ setuptools.command: setuptools
+ setuptools.command.alias: setuptools
+ setuptools.command.bdist_egg: setuptools
+ setuptools.command.bdist_rpm: setuptools
+ setuptools.command.build: setuptools
+ setuptools.command.build_clib: setuptools
+ setuptools.command.build_ext: setuptools
+ setuptools.command.build_py: setuptools
+ setuptools.command.develop: setuptools
+ setuptools.command.dist_info: setuptools
+ setuptools.command.easy_install: setuptools
+ setuptools.command.editable_wheel: setuptools
+ setuptools.command.egg_info: setuptools
+ setuptools.command.install: setuptools
+ setuptools.command.install_egg_info: setuptools
+ setuptools.command.install_lib: setuptools
+ setuptools.command.install_scripts: setuptools
+ setuptools.command.py36compat: setuptools
+ setuptools.command.register: setuptools
+ setuptools.command.rotate: setuptools
+ setuptools.command.saveopts: setuptools
+ setuptools.command.sdist: setuptools
+ setuptools.command.setopt: setuptools
+ setuptools.command.test: setuptools
+ setuptools.command.upload: setuptools
+ setuptools.command.upload_docs: setuptools
+ setuptools.config: setuptools
+ setuptools.config.expand: setuptools
+ setuptools.config.pyprojecttoml: setuptools
+ setuptools.config.setupcfg: setuptools
+ setuptools.dep_util: setuptools
+ setuptools.depends: setuptools
+ setuptools.discovery: setuptools
+ setuptools.dist: setuptools
+ setuptools.errors: setuptools
+ setuptools.extension: setuptools
+ setuptools.extern: setuptools
+ setuptools.glob: setuptools
+ setuptools.installer: setuptools
+ setuptools.launch: setuptools
+ setuptools.logging: setuptools
+ setuptools.monkey: setuptools
+ setuptools.msvc: setuptools
+ setuptools.namespaces: setuptools
+ setuptools.package_index: setuptools
+ setuptools.py34compat: setuptools
+ setuptools.sandbox: setuptools
+ setuptools.unicode_utils: setuptools
+ setuptools.version: setuptools
+ setuptools.wheel: setuptools
+ setuptools.windows_support: setuptools
+ six: six
+ tabulate: tabulate
+ tabulate.version: tabulate
+ tomli: tomli
+ tomlkit: tomlkit
+ tomlkit.api: tomlkit
+ tomlkit.container: tomlkit
+ tomlkit.exceptions: tomlkit
+ tomlkit.items: tomlkit
+ tomlkit.parser: tomlkit
+ tomlkit.source: tomlkit
+ tomlkit.toml_char: tomlkit
+ tomlkit.toml_document: tomlkit
+ tomlkit.toml_file: tomlkit
+ typing_extensions: typing_extensions
+ urllib3: urllib3
+ urllib3.connection: urllib3
+ urllib3.connectionpool: urllib3
+ urllib3.contrib: urllib3
+ urllib3.contrib.appengine: urllib3
+ urllib3.contrib.ntlmpool: urllib3
+ urllib3.contrib.pyopenssl: urllib3
+ urllib3.contrib.securetransport: urllib3
+ urllib3.contrib.socks: urllib3
+ urllib3.exceptions: urllib3
+ urllib3.fields: urllib3
+ urllib3.filepost: urllib3
+ urllib3.packages: urllib3
+ urllib3.packages.backports: urllib3
+ urllib3.packages.backports.makefile: urllib3
+ urllib3.packages.six: urllib3
+ urllib3.poolmanager: urllib3
+ urllib3.request: urllib3
+ urllib3.response: urllib3
+ urllib3.util: urllib3
+ urllib3.util.connection: urllib3
+ urllib3.util.proxy: urllib3
+ urllib3.util.queue: urllib3
+ urllib3.util.request: urllib3
+ urllib3.util.response: urllib3
+ urllib3.util.retry: urllib3
+ urllib3.util.ssl_: urllib3
+ urllib3.util.ssl_match_hostname: urllib3
+ urllib3.util.ssltransport: urllib3
+ urllib3.util.timeout: urllib3
+ urllib3.util.url: urllib3
+ urllib3.util.wait: urllib3
+ wrapt: wrapt
+ wrapt.arguments: wrapt
+ wrapt.decorators: wrapt
+ wrapt.importer: wrapt
+ wrapt.wrappers: wrapt
+ yaml: PyYAML
+ yaml.composer: PyYAML
+ yaml.constructor: PyYAML
+ yaml.cyaml: PyYAML
+ yaml.dumper: PyYAML
+ yaml.emitter: PyYAML
+ yaml.error: PyYAML
+ yaml.events: PyYAML
+ yaml.loader: PyYAML
+ yaml.nodes: PyYAML
+ yaml.parser: PyYAML
+ yaml.reader: PyYAML
+ yaml.representer: PyYAML
+ yaml.resolver: PyYAML
+ yaml.scanner: PyYAML
+ yaml.serializer: PyYAML
+ yaml.tokens: PyYAML
+ yamllint: yamllint
+ yamllint.cli: yamllint
+ yamllint.config: yamllint
+ yamllint.linter: yamllint
+ yamllint.parser: yamllint
+ yamllint.rules: yamllint
+ yamllint.rules.braces: yamllint
+ yamllint.rules.brackets: yamllint
+ yamllint.rules.colons: yamllint
+ yamllint.rules.commas: yamllint
+ yamllint.rules.comments: yamllint
+ yamllint.rules.comments_indentation: yamllint
+ yamllint.rules.common: yamllint
+ yamllint.rules.document_end: yamllint
+ yamllint.rules.document_start: yamllint
+ yamllint.rules.empty_lines: yamllint
+ yamllint.rules.empty_values: yamllint
+ yamllint.rules.float_values: yamllint
+ yamllint.rules.hyphens: yamllint
+ yamllint.rules.indentation: yamllint
+ yamllint.rules.key_duplicates: yamllint
+ yamllint.rules.key_ordering: yamllint
+ yamllint.rules.line_length: yamllint
+ yamllint.rules.new_line_at_end_of_file: yamllint
+ yamllint.rules.new_lines: yamllint
+ yamllint.rules.octal_values: yamllint
+ yamllint.rules.quoted_strings: yamllint
+ yamllint.rules.trailing_spaces: yamllint
+ yamllint.rules.truthy: yamllint
+ pip_repository:
+ name: pip
+ use_pip_repository_aliases: true
+integrity: d979738b10adbbaff0884837e4414688990491c6c40f6a25d58b9bb564411477
diff --git a/examples/bzlmod/runfiles/BUILD.bazel b/examples/bzlmod/runfiles/BUILD.bazel
index add56b3bd0..3503ac3017 100644
--- a/examples/bzlmod/runfiles/BUILD.bazel
+++ b/examples/bzlmod/runfiles/BUILD.bazel
@@ -1,5 +1,6 @@
load("@rules_python//python:defs.bzl", "py_test")
+# gazelle:ignore
py_test(
name = "runfiles_test",
srcs = ["runfiles_test.py"],
diff --git a/examples/bzlmod_build_file_generation/.bazelignore b/examples/bzlmod_build_file_generation/.bazelignore
new file mode 100644
index 0000000000..ab3eb1635c
--- /dev/null
+++ b/examples/bzlmod_build_file_generation/.bazelignore
@@ -0,0 +1 @@
+other_module
diff --git a/examples/bzlmod_build_file_generation/.bazelrc b/examples/bzlmod_build_file_generation/.bazelrc
new file mode 100644
index 0000000000..1fbada7ec4
--- /dev/null
+++ b/examples/bzlmod_build_file_generation/.bazelrc
@@ -0,0 +1,9 @@
+test --test_output=errors --enable_runfiles
+
+# Windows requires these for multi-python support:
+build --enable_runfiles
+startup --windows_enable_symlinks
+
+common --experimental_enable_bzlmod
+
+coverage --java_runtime_version=remotejdk_11
diff --git a/examples/bzlmod_build_file_generation/.bazelversion b/examples/bzlmod_build_file_generation/.bazelversion
new file mode 100644
index 0000000000..09b254e90c
--- /dev/null
+++ b/examples/bzlmod_build_file_generation/.bazelversion
@@ -0,0 +1 @@
+6.0.0
diff --git a/examples/bzlmod_build_file_generation/.gitignore b/examples/bzlmod_build_file_generation/.gitignore
new file mode 100644
index 0000000000..ac51a054d2
--- /dev/null
+++ b/examples/bzlmod_build_file_generation/.gitignore
@@ -0,0 +1 @@
+bazel-*
diff --git a/examples/bzlmod_build_file_generation/BUILD.bazel b/examples/bzlmod_build_file_generation/BUILD.bazel
new file mode 100644
index 0000000000..c667f1e49b
--- /dev/null
+++ b/examples/bzlmod_build_file_generation/BUILD.bazel
@@ -0,0 +1,103 @@
+# Load various rules so that we can have bazel download
+# various rulesets and dependencies.
+# The `load` statement imports the symbol for the rule, in the defined
+# ruleset. When the symbol is loaded you can use the rule.
+
+# The following code loads the base python requirements and gazelle
+# requirements.
+load("@bazel_gazelle//:def.bzl", "gazelle")
+load("@pip//:requirements.bzl", "all_whl_requirements")
+load("@python3//:defs.bzl", py_test_with_transition = "py_test")
+load("@rules_python//python:defs.bzl", "py_binary", "py_library", "py_test")
+load("@rules_python//python:pip.bzl", "compile_pip_requirements")
+load("@rules_python_gazelle_plugin//:def.bzl", "GAZELLE_PYTHON_RUNTIME_DEPS")
+load("@rules_python_gazelle_plugin//manifest:defs.bzl", "gazelle_python_manifest")
+load("@rules_python_gazelle_plugin//modules_mapping:def.bzl", "modules_mapping")
+
+# This stanza calls a rule that generates targets for managing pip dependencies
+# with pip-compile.
+compile_pip_requirements(
+ name = "requirements",
+ extra_args = ["--allow-unsafe"],
+ requirements_in = "requirements.in",
+ requirements_txt = "requirements_lock.txt",
+ requirements_windows = "requirements_windows.txt",
+)
+
+# This repository rule fetches the metadata for python packages we
+# depend on. That data is required for the gazelle_python_manifest
+# rule to update our manifest file.
+modules_mapping(
+ name = "modules_map",
+ exclude_patterns = [
+ "^_|(\\._)+", # This is the default.
+ "(\\.tests)+", # Add a custom one to get rid of the psutil tests.
+ ],
+ wheels = all_whl_requirements,
+)
+
+# Gazelle python extension needs a manifest file mapping from
+# an import to the installed package that provides it.
+# This macro produces two targets:
+# - //:gazelle_python_manifest.update can be used with `bazel run`
+# to recalculate the manifest
+# - //:gazelle_python_manifest.test is a test target ensuring that
+# the manifest doesn't need to be updated
+# This target updates a file called gazelle_python.yaml, and
+# requires that file exist before the target is run.
+# When you are using gazelle you need to run this target first.
+gazelle_python_manifest(
+ name = "gazelle_python_manifest",
+ modules_mapping = ":modules_map",
+ pip_repository_name = "pip",
+ requirements = "//:requirements_lock.txt",
+ # NOTE: we can use this flag in order to make our setup compatible with
+ # bzlmod.
+ use_pip_repository_aliases = True,
+)
+
+# Our gazelle target points to the python gazelle binary.
+# This is the simple case where we only need one language supported.
+# If you also had proto, go, or other gazelle-supported languages,
+# you would also need a gazelle_binary rule.
+# See https://github.com/bazelbuild/bazel-gazelle/blob/master/extend.rst#example
+# This is the primary gazelle target to run, so that you can update BUILD.bazel files.
+# You can execute:
+# - bazel run //:gazelle update
+# - bazel run //:gazelle fix
+# See: https://github.com/bazelbuild/bazel-gazelle#fix-and-update
+gazelle(
+ name = "gazelle",
+ data = GAZELLE_PYTHON_RUNTIME_DEPS,
+ gazelle = "@rules_python_gazelle_plugin//python:gazelle_binary",
+)
+
+py_test_with_transition(
+ name = "test_with_transition",
+ srcs = ["__test__.py"],
+ main = "__test__.py",
+ deps = [":bzlmod_build_file_generation"],
+)
+
+# The following targets are created and maintained by gazelle
+py_library(
+ name = "bzlmod_build_file_generation",
+ srcs = ["lib.py"],
+ visibility = ["//:__subpackages__"],
+ deps = ["@pip//tabulate"],
+)
+
+py_binary(
+ name = "bzlmod_build_file_generation_bin",
+ srcs = ["__main__.py"],
+ main = "__main__.py",
+ visibility = ["//:__subpackages__"],
+ deps = [":bzlmod_build_file_generation"],
+)
+
+py_test(
+ name = "bzlmod_build_file_generation_test",
+ srcs = ["__test__.py"],
+ main = "__test__.py",
+ deps = [":bzlmod_build_file_generation"],
+)
diff --git a/examples/bzlmod_build_file_generation/MODULE.bazel b/examples/bzlmod_build_file_generation/MODULE.bazel
new file mode 100644
index 0000000000..781b0cba39
--- /dev/null
+++ b/examples/bzlmod_build_file_generation/MODULE.bazel
@@ -0,0 +1,113 @@
+# This file replaces the WORKSPACE file when using bzlmod.
+
+# module declares certain properties of the Bazel module represented by the current Bazel repo.
+# These properties are either essential metadata of the module (such as the name and version),
+# or affect behavior of the current module and its dependents.
+module(
+ name = "example_bzlmod_build_file_generation",
+ version = "0.0.0",
+ compatibility_level = 1,
+)
+
+# The following stanza defines the dependency rules_python.
+# For typical setups you set the version.
+# See the releases page for available versions.
+# https://github.com/bazelbuild/rules_python/releases
+bazel_dep(name = "rules_python", version = "0.0.0")
+
+# The following loads rules_python from the file system.
+# For usual setups you should remove this local_path_override block.
+local_path_override(
+ module_name = "rules_python",
+ path = "../..",
+)
+
+# The following stanza defines the dependency rules_python_gazelle_plugin.
+# For typical setups you set the version.
+# See the releases page for available versions.
+# https://github.com/bazelbuild/rules_python/releases
+bazel_dep(name = "rules_python_gazelle_plugin", version = "0.0.0")
+
+# The following starlark loads the gazelle plugin from the file system.
+# For usual setups you should remove this local_path_override block.
+local_path_override(
+ module_name = "rules_python_gazelle_plugin",
+ path = "../../gazelle",
+)
+
+# The following stanza defines the dependency for gazelle
+# See here https://github.com/bazelbuild/bazel-gazelle/releases/ for the
+# latest version.
+bazel_dep(name = "gazelle", version = "0.30.0", repo_name = "bazel_gazelle")
+
+# The following stanze returns a proxy object representing a module extension;
+# its methods can be invoked to create module extension tags.
+python = use_extension("@rules_python//python:extensions.bzl", "python")
+
+# This name is passed into python.toolchain and it's use_repo statement.
+# We also use the same name for python.host_python_interpreter.
+PYTHON_NAME = "python3"
+
+# This is the name that is used for the host interpreter
+PYTHON_INTERPRETER = PYTHON_NAME + "_host_interpreter"
+
+# We next initialize the python toolchain using the extension.
+# You can set different Python versions in this block.
+python.toolchain(
+ # This name is used in the various use_repo statements
+ # below, and in the local extension that is in this
+ # example.
+ name = PYTHON_NAME,
+ configure_coverage_tool = True,
+ python_version = "3.9",
+)
+
+# Import the python repositories generated by the given module extension
+# into the scope of the current module.
+# All of the python3 repositories use the PYTHON_NAME as there prefix. They
+# are not catenated for ease of reading.
+use_repo(python, PYTHON_NAME)
+use_repo(python, "python3_toolchains")
+use_repo(python, PYTHON_INTERPRETER)
+
+# Register an already-defined toolchain so that Bazel can use it during toolchain resolution.
+register_toolchains(
+ "@python3_toolchains//:all",
+)
+
+# Use the pip extension
+pip = use_extension("@rules_python//python:extensions.bzl", "pip")
+
+# Use the extension to call the `pip_repository` rule that invokes `pip`, with `incremental` set.
+# Accepts a locked/compiled requirements file and installs the dependencies listed within.
+# Those dependencies become available in a generated `requirements.bzl` file.
+# You can instead check this `requirements.bzl` file into your repo.
+# Because this project has different requirements for windows vs other
+# operating systems, we have requirements for each.
+pip.parse(
+ name = "pip",
+ # When using gazelle you must use set the following flag
+ # in order for the generation of gazelle dependency resolution.
+ incompatible_generate_aliases = True,
+ # The interpreter attribute points to the interpreter to use for running
+ # pip commands to download the packages in the requirements file.
+ # As a best practice, we use the same interpreter as the toolchain
+ # that was configured above; this ensures the same Python version
+ # is used for both resolving dependencies and running tests/binaries.
+ # If this isn't specified, then you'll get whatever is locally installed
+ # on your system.
+ python_interpreter_target = "@" + PYTHON_INTERPRETER + "//:python",
+ requirements_lock = "//:requirements_lock.txt",
+ requirements_windows = "//:requirements_windows.txt",
+)
+
+# Imports the pip toolchain generated by the given module extension into the scope of the current module.
+use_repo(pip, "pip")
+
+# This project includes a different module that is on the local file system.
+# Add the module to this parent project.
+bazel_dep(name = "other_module", version = "", repo_name = "our_other_module")
+local_path_override(
+ module_name = "other_module",
+ path = "other_module",
+)
diff --git a/examples/bzlmod_build_file_generation/README.md b/examples/bzlmod_build_file_generation/README.md
new file mode 100644
index 0000000000..703fd38ebe
--- /dev/null
+++ b/examples/bzlmod_build_file_generation/README.md
@@ -0,0 +1,28 @@
+# Bzlmod build file generation example
+
+This example demostrates how to use `rules_python` and gazelle with `bzlmod` enabled.
+[Bzlmod](https://bazel.build/external/overview#bzlmod), the new external dependency
+subsystem, does not directly work with repo definitions. Instead, it builds a dependency
+graph from modules, runs extensions on top of the graph, and defines repos accordingly.
+
+Gazelle is setup with the `rules_python`
+extension, so that targets like `py_library` and `py_binary` can be
+automatically created just by running:
+
+```sh
+$ bazel run //:gazelle update
+```
+
+The are other targets that allow you to update the gazelle dependency management
+when you update the requirements.in file. See:
+
+```bash
+bazel run //:gazelle_python_manifest.update
+```
+
+For more information on the behavior of the `rules_python` gazelle extension,
+see the [README.md](../../gazelle/README.md) file in the /gazelle folder.
+
+This example uses a `MODULE.bazel` file that configures the bzlmod dependency
+management. See comments in the `MODULE.bazel` and `BUILD.bazel` files for more
+information.
diff --git a/examples/bzlmod_build_file_generation/WORKSPACE b/examples/bzlmod_build_file_generation/WORKSPACE
new file mode 100644
index 0000000000..78cc252e57
--- /dev/null
+++ b/examples/bzlmod_build_file_generation/WORKSPACE
@@ -0,0 +1,2 @@
+# Empty file indicating the root of a Bazel workspace.
+# Dependencies and setup are in MODULE.bazel.
diff --git a/examples/bzlmod_build_file_generation/__main__.py b/examples/bzlmod_build_file_generation/__main__.py
new file mode 100644
index 0000000000..099493b3c8
--- /dev/null
+++ b/examples/bzlmod_build_file_generation/__main__.py
@@ -0,0 +1,18 @@
+# Copyright 2023 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+from lib import main
+
+if __name__ == "__main__":
+ print(main([["A", 1], ["B", 2]]))
diff --git a/examples/bzlmod_build_file_generation/__test__.py b/examples/bzlmod_build_file_generation/__test__.py
new file mode 100644
index 0000000000..cdc1c89680
--- /dev/null
+++ b/examples/bzlmod_build_file_generation/__test__.py
@@ -0,0 +1,33 @@
+# Copyright 2023 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import unittest
+
+from lib import main
+
+
+class ExampleTest(unittest.TestCase):
+ def test_main(self):
+ self.assertEquals(
+ """\
+- -
+A 1
+B 2
+- -""",
+ main([["A", 1], ["B", 2]]),
+ )
+
+
+if __name__ == "__main__":
+ unittest.main()
diff --git a/examples/bzlmod_build_file_generation/gazelle_python.yaml b/examples/bzlmod_build_file_generation/gazelle_python.yaml
new file mode 100644
index 0000000000..12096e5837
--- /dev/null
+++ b/examples/bzlmod_build_file_generation/gazelle_python.yaml
@@ -0,0 +1,590 @@
+# GENERATED FILE - DO NOT EDIT!
+#
+# To update this file, run:
+# bazel run //:gazelle_python_manifest.update
+
+manifest:
+ modules_mapping:
+ S3: s3cmd
+ S3.ACL: s3cmd
+ S3.AccessLog: s3cmd
+ S3.BidirMap: s3cmd
+ S3.CloudFront: s3cmd
+ S3.Config: s3cmd
+ S3.ConnMan: s3cmd
+ S3.Crypto: s3cmd
+ S3.Custom_httplib27: s3cmd
+ S3.Custom_httplib3x: s3cmd
+ S3.Exceptions: s3cmd
+ S3.ExitCodes: s3cmd
+ S3.FileDict: s3cmd
+ S3.FileLists: s3cmd
+ S3.HashCache: s3cmd
+ S3.MultiPart: s3cmd
+ S3.PkgInfo: s3cmd
+ S3.Progress: s3cmd
+ S3.S3: s3cmd
+ S3.S3Uri: s3cmd
+ S3.SortedDict: s3cmd
+ S3.Utils: s3cmd
+ astroid: astroid
+ astroid.arguments: astroid
+ astroid.astroid_manager: astroid
+ astroid.bases: astroid
+ astroid.brain: astroid
+ astroid.brain.brain_argparse: astroid
+ astroid.brain.brain_attrs: astroid
+ astroid.brain.brain_boto3: astroid
+ astroid.brain.brain_builtin_inference: astroid
+ astroid.brain.brain_collections: astroid
+ astroid.brain.brain_crypt: astroid
+ astroid.brain.brain_ctypes: astroid
+ astroid.brain.brain_curses: astroid
+ astroid.brain.brain_dataclasses: astroid
+ astroid.brain.brain_dateutil: astroid
+ astroid.brain.brain_fstrings: astroid
+ astroid.brain.brain_functools: astroid
+ astroid.brain.brain_gi: astroid
+ astroid.brain.brain_hashlib: astroid
+ astroid.brain.brain_http: astroid
+ astroid.brain.brain_hypothesis: astroid
+ astroid.brain.brain_io: astroid
+ astroid.brain.brain_mechanize: astroid
+ astroid.brain.brain_multiprocessing: astroid
+ astroid.brain.brain_namedtuple_enum: astroid
+ astroid.brain.brain_nose: astroid
+ astroid.brain.brain_numpy_core_einsumfunc: astroid
+ astroid.brain.brain_numpy_core_fromnumeric: astroid
+ astroid.brain.brain_numpy_core_function_base: astroid
+ astroid.brain.brain_numpy_core_multiarray: astroid
+ astroid.brain.brain_numpy_core_numeric: astroid
+ astroid.brain.brain_numpy_core_numerictypes: astroid
+ astroid.brain.brain_numpy_core_umath: astroid
+ astroid.brain.brain_numpy_ma: astroid
+ astroid.brain.brain_numpy_ndarray: astroid
+ astroid.brain.brain_numpy_random_mtrand: astroid
+ astroid.brain.brain_numpy_utils: astroid
+ astroid.brain.brain_pathlib: astroid
+ astroid.brain.brain_pkg_resources: astroid
+ astroid.brain.brain_pytest: astroid
+ astroid.brain.brain_qt: astroid
+ astroid.brain.brain_random: astroid
+ astroid.brain.brain_re: astroid
+ astroid.brain.brain_responses: astroid
+ astroid.brain.brain_scipy_signal: astroid
+ astroid.brain.brain_signal: astroid
+ astroid.brain.brain_six: astroid
+ astroid.brain.brain_sqlalchemy: astroid
+ astroid.brain.brain_ssl: astroid
+ astroid.brain.brain_subprocess: astroid
+ astroid.brain.brain_threading: astroid
+ astroid.brain.brain_type: astroid
+ astroid.brain.brain_typing: astroid
+ astroid.brain.brain_unittest: astroid
+ astroid.brain.brain_uuid: astroid
+ astroid.brain.helpers: astroid
+ astroid.builder: astroid
+ astroid.const: astroid
+ astroid.context: astroid
+ astroid.decorators: astroid
+ astroid.exceptions: astroid
+ astroid.filter_statements: astroid
+ astroid.helpers: astroid
+ astroid.inference: astroid
+ astroid.inference_tip: astroid
+ astroid.interpreter: astroid
+ astroid.interpreter.dunder_lookup: astroid
+ astroid.interpreter.objectmodel: astroid
+ astroid.manager: astroid
+ astroid.mixins: astroid
+ astroid.modutils: astroid
+ astroid.node_classes: astroid
+ astroid.nodes: astroid
+ astroid.nodes.as_string: astroid
+ astroid.nodes.const: astroid
+ astroid.nodes.node_classes: astroid
+ astroid.nodes.node_ng: astroid
+ astroid.nodes.scoped_nodes: astroid
+ astroid.nodes.scoped_nodes.mixin: astroid
+ astroid.nodes.scoped_nodes.scoped_nodes: astroid
+ astroid.nodes.scoped_nodes.utils: astroid
+ astroid.nodes.utils: astroid
+ astroid.objects: astroid
+ astroid.protocols: astroid
+ astroid.raw_building: astroid
+ astroid.rebuilder: astroid
+ astroid.scoped_nodes: astroid
+ astroid.test_utils: astroid
+ astroid.transforms: astroid
+ astroid.typing: astroid
+ astroid.util: astroid
+ certifi: certifi
+ certifi.core: certifi
+ chardet: chardet
+ chardet.big5freq: chardet
+ chardet.big5prober: chardet
+ chardet.chardistribution: chardet
+ chardet.charsetgroupprober: chardet
+ chardet.charsetprober: chardet
+ chardet.cli: chardet
+ chardet.cli.chardetect: chardet
+ chardet.codingstatemachine: chardet
+ chardet.compat: chardet
+ chardet.cp949prober: chardet
+ chardet.enums: chardet
+ chardet.escprober: chardet
+ chardet.escsm: chardet
+ chardet.eucjpprober: chardet
+ chardet.euckrfreq: chardet
+ chardet.euckrprober: chardet
+ chardet.euctwfreq: chardet
+ chardet.euctwprober: chardet
+ chardet.gb2312freq: chardet
+ chardet.gb2312prober: chardet
+ chardet.hebrewprober: chardet
+ chardet.jisfreq: chardet
+ chardet.jpcntx: chardet
+ chardet.langbulgarianmodel: chardet
+ chardet.langgreekmodel: chardet
+ chardet.langhebrewmodel: chardet
+ chardet.langhungarianmodel: chardet
+ chardet.langrussianmodel: chardet
+ chardet.langthaimodel: chardet
+ chardet.langturkishmodel: chardet
+ chardet.latin1prober: chardet
+ chardet.mbcharsetprober: chardet
+ chardet.mbcsgroupprober: chardet
+ chardet.mbcssm: chardet
+ chardet.metadata: chardet
+ chardet.metadata.languages: chardet
+ chardet.sbcharsetprober: chardet
+ chardet.sbcsgroupprober: chardet
+ chardet.sjisprober: chardet
+ chardet.universaldetector: chardet
+ chardet.utf8prober: chardet
+ chardet.version: chardet
+ dateutil: python_dateutil
+ dateutil.easter: python_dateutil
+ dateutil.parser: python_dateutil
+ dateutil.parser.isoparser: python_dateutil
+ dateutil.relativedelta: python_dateutil
+ dateutil.rrule: python_dateutil
+ dateutil.tz: python_dateutil
+ dateutil.tz.tz: python_dateutil
+ dateutil.tz.win: python_dateutil
+ dateutil.tzwin: python_dateutil
+ dateutil.utils: python_dateutil
+ dateutil.zoneinfo: python_dateutil
+ dateutil.zoneinfo.rebuild: python_dateutil
+ dill: dill
+ dill.detect: dill
+ dill.logger: dill
+ dill.objtypes: dill
+ dill.pointers: dill
+ dill.session: dill
+ dill.settings: dill
+ dill.source: dill
+ dill.temp: dill
+ idna: idna
+ idna.codec: idna
+ idna.compat: idna
+ idna.core: idna
+ idna.idnadata: idna
+ idna.intranges: idna
+ idna.package_data: idna
+ idna.uts46data: idna
+ isort: isort
+ isort.api: isort
+ isort.comments: isort
+ isort.core: isort
+ isort.deprecated: isort
+ isort.deprecated.finders: isort
+ isort.exceptions: isort
+ isort.files: isort
+ isort.format: isort
+ isort.hooks: isort
+ isort.identify: isort
+ isort.io: isort
+ isort.literal: isort
+ isort.logo: isort
+ isort.main: isort
+ isort.output: isort
+ isort.parse: isort
+ isort.place: isort
+ isort.profiles: isort
+ isort.pylama_isort: isort
+ isort.sections: isort
+ isort.settings: isort
+ isort.setuptools_commands: isort
+ isort.sorting: isort
+ isort.stdlibs: isort
+ isort.stdlibs.all: isort
+ isort.stdlibs.py2: isort
+ isort.stdlibs.py27: isort
+ isort.stdlibs.py3: isort
+ isort.stdlibs.py310: isort
+ isort.stdlibs.py311: isort
+ isort.stdlibs.py36: isort
+ isort.stdlibs.py37: isort
+ isort.stdlibs.py38: isort
+ isort.stdlibs.py39: isort
+ isort.utils: isort
+ isort.wrap: isort
+ isort.wrap_modes: isort
+ lazy_object_proxy: lazy_object_proxy
+ lazy_object_proxy.compat: lazy_object_proxy
+ lazy_object_proxy.simple: lazy_object_proxy
+ lazy_object_proxy.slots: lazy_object_proxy
+ lazy_object_proxy.utils: lazy_object_proxy
+ magic: python_magic
+ magic.compat: python_magic
+ magic.loader: python_magic
+ mccabe: mccabe
+ pathspec: pathspec
+ pathspec.gitignore: pathspec
+ pathspec.pathspec: pathspec
+ pathspec.pattern: pathspec
+ pathspec.patterns: pathspec
+ pathspec.patterns.gitwildmatch: pathspec
+ pathspec.util: pathspec
+ pkg_resources: setuptools
+ pkg_resources.extern: setuptools
+ platformdirs: platformdirs
+ platformdirs.android: platformdirs
+ platformdirs.api: platformdirs
+ platformdirs.macos: platformdirs
+ platformdirs.unix: platformdirs
+ platformdirs.version: platformdirs
+ platformdirs.windows: platformdirs
+ pylint: pylint
+ pylint.checkers: pylint
+ pylint.checkers.async: pylint
+ pylint.checkers.base: pylint
+ pylint.checkers.base.basic_checker: pylint
+ pylint.checkers.base.basic_error_checker: pylint
+ pylint.checkers.base.comparison_checker: pylint
+ pylint.checkers.base.docstring_checker: pylint
+ pylint.checkers.base.name_checker: pylint
+ pylint.checkers.base.name_checker.checker: pylint
+ pylint.checkers.base.name_checker.naming_style: pylint
+ pylint.checkers.base.pass_checker: pylint
+ pylint.checkers.base_checker: pylint
+ pylint.checkers.classes: pylint
+ pylint.checkers.classes.class_checker: pylint
+ pylint.checkers.classes.special_methods_checker: pylint
+ pylint.checkers.deprecated: pylint
+ pylint.checkers.design_analysis: pylint
+ pylint.checkers.dunder_methods: pylint
+ pylint.checkers.ellipsis_checker: pylint
+ pylint.checkers.exceptions: pylint
+ pylint.checkers.format: pylint
+ pylint.checkers.imports: pylint
+ pylint.checkers.lambda_expressions: pylint
+ pylint.checkers.logging: pylint
+ pylint.checkers.mapreduce_checker: pylint
+ pylint.checkers.method_args: pylint
+ pylint.checkers.misc: pylint
+ pylint.checkers.modified_iterating_checker: pylint
+ pylint.checkers.newstyle: pylint
+ pylint.checkers.non_ascii_names: pylint
+ pylint.checkers.raw_metrics: pylint
+ pylint.checkers.refactoring: pylint
+ pylint.checkers.refactoring.implicit_booleaness_checker: pylint
+ pylint.checkers.refactoring.not_checker: pylint
+ pylint.checkers.refactoring.recommendation_checker: pylint
+ pylint.checkers.refactoring.refactoring_checker: pylint
+ pylint.checkers.similar: pylint
+ pylint.checkers.spelling: pylint
+ pylint.checkers.stdlib: pylint
+ pylint.checkers.strings: pylint
+ pylint.checkers.threading_checker: pylint
+ pylint.checkers.typecheck: pylint
+ pylint.checkers.unicode: pylint
+ pylint.checkers.unsupported_version: pylint
+ pylint.checkers.utils: pylint
+ pylint.checkers.variables: pylint
+ pylint.config: pylint
+ pylint.config.argument: pylint
+ pylint.config.arguments_manager: pylint
+ pylint.config.arguments_provider: pylint
+ pylint.config.callback_actions: pylint
+ pylint.config.config_file_parser: pylint
+ pylint.config.config_initialization: pylint
+ pylint.config.configuration_mixin: pylint
+ pylint.config.deprecation_actions: pylint
+ pylint.config.environment_variable: pylint
+ pylint.config.exceptions: pylint
+ pylint.config.find_default_config_files: pylint
+ pylint.config.help_formatter: pylint
+ pylint.config.option: pylint
+ pylint.config.option_manager_mixin: pylint
+ pylint.config.option_parser: pylint
+ pylint.config.options_provider_mixin: pylint
+ pylint.config.utils: pylint
+ pylint.constants: pylint
+ pylint.epylint: pylint
+ pylint.exceptions: pylint
+ pylint.extensions: pylint
+ pylint.extensions.bad_builtin: pylint
+ pylint.extensions.broad_try_clause: pylint
+ pylint.extensions.check_elif: pylint
+ pylint.extensions.code_style: pylint
+ pylint.extensions.comparetozero: pylint
+ pylint.extensions.comparison_placement: pylint
+ pylint.extensions.confusing_elif: pylint
+ pylint.extensions.consider_ternary_expression: pylint
+ pylint.extensions.docparams: pylint
+ pylint.extensions.docstyle: pylint
+ pylint.extensions.empty_comment: pylint
+ pylint.extensions.emptystring: pylint
+ pylint.extensions.eq_without_hash: pylint
+ pylint.extensions.for_any_all: pylint
+ pylint.extensions.mccabe: pylint
+ pylint.extensions.no_self_use: pylint
+ pylint.extensions.overlapping_exceptions: pylint
+ pylint.extensions.private_import: pylint
+ pylint.extensions.redefined_loop_name: pylint
+ pylint.extensions.redefined_variable_type: pylint
+ pylint.extensions.set_membership: pylint
+ pylint.extensions.typing: pylint
+ pylint.extensions.while_used: pylint
+ pylint.graph: pylint
+ pylint.interfaces: pylint
+ pylint.lint: pylint
+ pylint.lint.base_options: pylint
+ pylint.lint.caching: pylint
+ pylint.lint.expand_modules: pylint
+ pylint.lint.message_state_handler: pylint
+ pylint.lint.parallel: pylint
+ pylint.lint.pylinter: pylint
+ pylint.lint.report_functions: pylint
+ pylint.lint.run: pylint
+ pylint.lint.utils: pylint
+ pylint.message: pylint
+ pylint.message.message: pylint
+ pylint.message.message_definition: pylint
+ pylint.message.message_definition_store: pylint
+ pylint.message.message_id_store: pylint
+ pylint.pyreverse: pylint
+ pylint.pyreverse.diadefslib: pylint
+ pylint.pyreverse.diagrams: pylint
+ pylint.pyreverse.dot_printer: pylint
+ pylint.pyreverse.inspector: pylint
+ pylint.pyreverse.main: pylint
+ pylint.pyreverse.mermaidjs_printer: pylint
+ pylint.pyreverse.plantuml_printer: pylint
+ pylint.pyreverse.printer: pylint
+ pylint.pyreverse.printer_factory: pylint
+ pylint.pyreverse.utils: pylint
+ pylint.pyreverse.vcg_printer: pylint
+ pylint.pyreverse.writer: pylint
+ pylint.reporters: pylint
+ pylint.reporters.base_reporter: pylint
+ pylint.reporters.collecting_reporter: pylint
+ pylint.reporters.json_reporter: pylint
+ pylint.reporters.multi_reporter: pylint
+ pylint.reporters.reports_handler_mix_in: pylint
+ pylint.reporters.text: pylint
+ pylint.reporters.ureports: pylint
+ pylint.reporters.ureports.base_writer: pylint
+ pylint.reporters.ureports.nodes: pylint
+ pylint.reporters.ureports.text_writer: pylint
+ pylint.testutils: pylint
+ pylint.testutils.checker_test_case: pylint
+ pylint.testutils.configuration_test: pylint
+ pylint.testutils.constants: pylint
+ pylint.testutils.decorator: pylint
+ pylint.testutils.functional: pylint
+ pylint.testutils.functional.find_functional_tests: pylint
+ pylint.testutils.functional.lint_module_output_update: pylint
+ pylint.testutils.functional.test_file: pylint
+ pylint.testutils.functional_test_file: pylint
+ pylint.testutils.get_test_info: pylint
+ pylint.testutils.global_test_linter: pylint
+ pylint.testutils.lint_module_test: pylint
+ pylint.testutils.output_line: pylint
+ pylint.testutils.pyreverse: pylint
+ pylint.testutils.reporter_for_tests: pylint
+ pylint.testutils.tokenize_str: pylint
+ pylint.testutils.unittest_linter: pylint
+ pylint.testutils.utils: pylint
+ pylint.typing: pylint
+ pylint.utils: pylint
+ pylint.utils.ast_walker: pylint
+ pylint.utils.docs: pylint
+ pylint.utils.file_state: pylint
+ pylint.utils.linterstats: pylint
+ pylint.utils.pragma_parser: pylint
+ pylint.utils.utils: pylint
+ requests: requests
+ requests.adapters: requests
+ requests.api: requests
+ requests.auth: requests
+ requests.certs: requests
+ requests.compat: requests
+ requests.cookies: requests
+ requests.exceptions: requests
+ requests.help: requests
+ requests.hooks: requests
+ requests.models: requests
+ requests.packages: requests
+ requests.sessions: requests
+ requests.status_codes: requests
+ requests.structures: requests
+ requests.utils: requests
+ setuptools: setuptools
+ setuptools.archive_util: setuptools
+ setuptools.build_meta: setuptools
+ setuptools.command: setuptools
+ setuptools.command.alias: setuptools
+ setuptools.command.bdist_egg: setuptools
+ setuptools.command.bdist_rpm: setuptools
+ setuptools.command.build: setuptools
+ setuptools.command.build_clib: setuptools
+ setuptools.command.build_ext: setuptools
+ setuptools.command.build_py: setuptools
+ setuptools.command.develop: setuptools
+ setuptools.command.dist_info: setuptools
+ setuptools.command.easy_install: setuptools
+ setuptools.command.editable_wheel: setuptools
+ setuptools.command.egg_info: setuptools
+ setuptools.command.install: setuptools
+ setuptools.command.install_egg_info: setuptools
+ setuptools.command.install_lib: setuptools
+ setuptools.command.install_scripts: setuptools
+ setuptools.command.py36compat: setuptools
+ setuptools.command.register: setuptools
+ setuptools.command.rotate: setuptools
+ setuptools.command.saveopts: setuptools
+ setuptools.command.sdist: setuptools
+ setuptools.command.setopt: setuptools
+ setuptools.command.test: setuptools
+ setuptools.command.upload: setuptools
+ setuptools.command.upload_docs: setuptools
+ setuptools.config: setuptools
+ setuptools.config.expand: setuptools
+ setuptools.config.pyprojecttoml: setuptools
+ setuptools.config.setupcfg: setuptools
+ setuptools.dep_util: setuptools
+ setuptools.depends: setuptools
+ setuptools.discovery: setuptools
+ setuptools.dist: setuptools
+ setuptools.errors: setuptools
+ setuptools.extension: setuptools
+ setuptools.extern: setuptools
+ setuptools.glob: setuptools
+ setuptools.installer: setuptools
+ setuptools.launch: setuptools
+ setuptools.logging: setuptools
+ setuptools.monkey: setuptools
+ setuptools.msvc: setuptools
+ setuptools.namespaces: setuptools
+ setuptools.package_index: setuptools
+ setuptools.py34compat: setuptools
+ setuptools.sandbox: setuptools
+ setuptools.unicode_utils: setuptools
+ setuptools.version: setuptools
+ setuptools.wheel: setuptools
+ setuptools.windows_support: setuptools
+ six: six
+ tabulate: tabulate
+ tabulate.version: tabulate
+ tomli: tomli
+ tomlkit: tomlkit
+ tomlkit.api: tomlkit
+ tomlkit.container: tomlkit
+ tomlkit.exceptions: tomlkit
+ tomlkit.items: tomlkit
+ tomlkit.parser: tomlkit
+ tomlkit.source: tomlkit
+ tomlkit.toml_char: tomlkit
+ tomlkit.toml_document: tomlkit
+ tomlkit.toml_file: tomlkit
+ typing_extensions: typing_extensions
+ urllib3: urllib3
+ urllib3.connection: urllib3
+ urllib3.connectionpool: urllib3
+ urllib3.contrib: urllib3
+ urllib3.contrib.appengine: urllib3
+ urllib3.contrib.ntlmpool: urllib3
+ urllib3.contrib.pyopenssl: urllib3
+ urllib3.contrib.securetransport: urllib3
+ urllib3.contrib.socks: urllib3
+ urllib3.exceptions: urllib3
+ urllib3.fields: urllib3
+ urllib3.filepost: urllib3
+ urllib3.packages: urllib3
+ urllib3.packages.backports: urllib3
+ urllib3.packages.backports.makefile: urllib3
+ urllib3.packages.six: urllib3
+ urllib3.poolmanager: urllib3
+ urllib3.request: urllib3
+ urllib3.response: urllib3
+ urllib3.util: urllib3
+ urllib3.util.connection: urllib3
+ urllib3.util.proxy: urllib3
+ urllib3.util.queue: urllib3
+ urllib3.util.request: urllib3
+ urllib3.util.response: urllib3
+ urllib3.util.retry: urllib3
+ urllib3.util.ssl_: urllib3
+ urllib3.util.ssl_match_hostname: urllib3
+ urllib3.util.ssltransport: urllib3
+ urllib3.util.timeout: urllib3
+ urllib3.util.url: urllib3
+ urllib3.util.wait: urllib3
+ wrapt: wrapt
+ wrapt.arguments: wrapt
+ wrapt.decorators: wrapt
+ wrapt.importer: wrapt
+ wrapt.wrappers: wrapt
+ yaml: PyYAML
+ yaml.composer: PyYAML
+ yaml.constructor: PyYAML
+ yaml.cyaml: PyYAML
+ yaml.dumper: PyYAML
+ yaml.emitter: PyYAML
+ yaml.error: PyYAML
+ yaml.events: PyYAML
+ yaml.loader: PyYAML
+ yaml.nodes: PyYAML
+ yaml.parser: PyYAML
+ yaml.reader: PyYAML
+ yaml.representer: PyYAML
+ yaml.resolver: PyYAML
+ yaml.scanner: PyYAML
+ yaml.serializer: PyYAML
+ yaml.tokens: PyYAML
+ yamllint: yamllint
+ yamllint.cli: yamllint
+ yamllint.config: yamllint
+ yamllint.linter: yamllint
+ yamllint.parser: yamllint
+ yamllint.rules: yamllint
+ yamllint.rules.braces: yamllint
+ yamllint.rules.brackets: yamllint
+ yamllint.rules.colons: yamllint
+ yamllint.rules.commas: yamllint
+ yamllint.rules.comments: yamllint
+ yamllint.rules.comments_indentation: yamllint
+ yamllint.rules.common: yamllint
+ yamllint.rules.document_end: yamllint
+ yamllint.rules.document_start: yamllint
+ yamllint.rules.empty_lines: yamllint
+ yamllint.rules.empty_values: yamllint
+ yamllint.rules.float_values: yamllint
+ yamllint.rules.hyphens: yamllint
+ yamllint.rules.indentation: yamllint
+ yamllint.rules.key_duplicates: yamllint
+ yamllint.rules.key_ordering: yamllint
+ yamllint.rules.line_length: yamllint
+ yamllint.rules.new_line_at_end_of_file: yamllint
+ yamllint.rules.new_lines: yamllint
+ yamllint.rules.octal_values: yamllint
+ yamllint.rules.quoted_strings: yamllint
+ yamllint.rules.trailing_spaces: yamllint
+ yamllint.rules.truthy: yamllint
+ pip_repository:
+ name: pip
+ use_pip_repository_aliases: true
+integrity: d979738b10adbbaff0884837e4414688990491c6c40f6a25d58b9bb564411477
diff --git a/examples/bzlmod_build_file_generation/lib.py b/examples/bzlmod_build_file_generation/lib.py
new file mode 100644
index 0000000000..646c6e890f
--- /dev/null
+++ b/examples/bzlmod_build_file_generation/lib.py
@@ -0,0 +1,19 @@
+# Copyright 2023 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+from tabulate import tabulate
+
+
+def main(table):
+ return tabulate(table)
diff --git a/examples/bzlmod_build_file_generation/other_module/MODULE.bazel b/examples/bzlmod_build_file_generation/other_module/MODULE.bazel
new file mode 100644
index 0000000000..992e120760
--- /dev/null
+++ b/examples/bzlmod_build_file_generation/other_module/MODULE.bazel
@@ -0,0 +1,5 @@
+module(
+ name = "other_module",
+)
+
+bazel_dep(name = "rules_python", version = "")
diff --git a/examples/bzlmod_build_file_generation/other_module/WORKSPACE b/examples/bzlmod_build_file_generation/other_module/WORKSPACE
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/examples/bzlmod_build_file_generation/other_module/other_module/pkg/BUILD.bazel b/examples/bzlmod_build_file_generation/other_module/other_module/pkg/BUILD.bazel
new file mode 100644
index 0000000000..9a130e3554
--- /dev/null
+++ b/examples/bzlmod_build_file_generation/other_module/other_module/pkg/BUILD.bazel
@@ -0,0 +1,11 @@
+load("@rules_python//python:defs.bzl", "py_library")
+
+py_library(
+ name = "lib",
+ srcs = ["lib.py"],
+ data = ["data/data.txt"],
+ visibility = ["//visibility:public"],
+ deps = ["@rules_python//python/runfiles"],
+)
+
+exports_files(["data/data.txt"])
diff --git a/examples/bzlmod_build_file_generation/other_module/other_module/pkg/data/data.txt b/examples/bzlmod_build_file_generation/other_module/other_module/pkg/data/data.txt
new file mode 100644
index 0000000000..e975eaf640
--- /dev/null
+++ b/examples/bzlmod_build_file_generation/other_module/other_module/pkg/data/data.txt
@@ -0,0 +1 @@
+Hello, other_module!
diff --git a/examples/bzlmod_build_file_generation/other_module/other_module/pkg/lib.py b/examples/bzlmod_build_file_generation/other_module/other_module/pkg/lib.py
new file mode 100644
index 0000000000..eaf65fb46a
--- /dev/null
+++ b/examples/bzlmod_build_file_generation/other_module/other_module/pkg/lib.py
@@ -0,0 +1,27 @@
+# Copyright 2023 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+from python.runfiles import runfiles
+
+
+def GetRunfilePathWithCurrentRepository():
+ r = runfiles.Create()
+ own_repo = r.CurrentRepository()
+ # For a non-main repository, the name of the runfiles directory is equal to
+ # the canonical repository name.
+ return r.Rlocation(own_repo + "/other_module/pkg/data/data.txt")
+
+
+def GetRunfilePathWithRepoMapping():
+ return runfiles.Create().Rlocation("other_module/other_module/pkg/data/data.txt")
diff --git a/examples/bzlmod_build_file_generation/requirements.in b/examples/bzlmod_build_file_generation/requirements.in
new file mode 100644
index 0000000000..a709195442
--- /dev/null
+++ b/examples/bzlmod_build_file_generation/requirements.in
@@ -0,0 +1,6 @@
+requests~=2.25.1
+s3cmd~=2.1.0
+yamllint>=1.28.0
+tabulate~=0.9.0
+pylint~=2.15.5
+python-dateutil>=2.8.2
diff --git a/examples/bzlmod_build_file_generation/requirements_lock.txt b/examples/bzlmod_build_file_generation/requirements_lock.txt
new file mode 100644
index 0000000000..2160fe1163
--- /dev/null
+++ b/examples/bzlmod_build_file_generation/requirements_lock.txt
@@ -0,0 +1,227 @@
+#
+# This file is autogenerated by pip-compile with Python 3.9
+# by the following command:
+#
+# bazel run //:requirements.update
+#
+astroid==2.12.13 \
+ --hash=sha256:10e0ad5f7b79c435179d0d0f0df69998c4eef4597534aae44910db060baeb907 \
+ --hash=sha256:1493fe8bd3dfd73dc35bd53c9d5b6e49ead98497c47b2307662556a5692d29d7
+ # via pylint
+certifi==2022.12.7 \
+ --hash=sha256:35824b4c3a97115964b408844d64aa14db1cc518f6562e8d7261699d1350a9e3 \
+ --hash=sha256:4ad3232f5e926d6718ec31cfc1fcadfde020920e278684144551c91769c7bc18
+ # via requests
+chardet==4.0.0 \
+ --hash=sha256:0d6f53a15db4120f2b08c94f11e7d93d2c911ee118b6b30a04ec3ee8310179fa \
+ --hash=sha256:f864054d66fd9118f2e67044ac8981a54775ec5b67aed0441892edb553d21da5
+ # via requests
+dill==0.3.6 \
+ --hash=sha256:a07ffd2351b8c678dfc4a856a3005f8067aea51d6ba6c700796a4d9e280f39f0 \
+ --hash=sha256:e5db55f3687856d8fbdab002ed78544e1c4559a130302693d839dfe8f93f2373
+ # via pylint
+idna==2.10 \
+ --hash=sha256:b307872f855b18632ce0c21c5e45be78c0ea7ae4c15c828c20788b26921eb3f6 \
+ --hash=sha256:b97d804b1e9b523befed77c48dacec60e6dcb0b5391d57af6a65a312a90648c0
+ # via requests
+isort==5.11.4 \
+ --hash=sha256:6db30c5ded9815d813932c04c2f85a360bcdd35fed496f4d8f35495ef0a261b6 \
+ --hash=sha256:c033fd0edb91000a7f09527fe5c75321878f98322a77ddcc81adbd83724afb7b
+ # via pylint
+lazy-object-proxy==1.8.0 \
+ --hash=sha256:0c1c7c0433154bb7c54185714c6929acc0ba04ee1b167314a779b9025517eada \
+ --hash=sha256:14010b49a2f56ec4943b6cf925f597b534ee2fe1f0738c84b3bce0c1a11ff10d \
+ --hash=sha256:4e2d9f764f1befd8bdc97673261b8bb888764dfdbd7a4d8f55e4fbcabb8c3fb7 \
+ --hash=sha256:4fd031589121ad46e293629b39604031d354043bb5cdf83da4e93c2d7f3389fe \
+ --hash=sha256:5b51d6f3bfeb289dfd4e95de2ecd464cd51982fe6f00e2be1d0bf94864d58acd \
+ --hash=sha256:6850e4aeca6d0df35bb06e05c8b934ff7c533734eb51d0ceb2d63696f1e6030c \
+ --hash=sha256:6f593f26c470a379cf7f5bc6db6b5f1722353e7bf937b8d0d0b3fba911998858 \
+ --hash=sha256:71d9ae8a82203511a6f60ca5a1b9f8ad201cac0fc75038b2dc5fa519589c9288 \
+ --hash=sha256:7e1561626c49cb394268edd00501b289053a652ed762c58e1081224c8d881cec \
+ --hash=sha256:8f6ce2118a90efa7f62dd38c7dbfffd42f468b180287b748626293bf12ed468f \
+ --hash=sha256:ae032743794fba4d171b5b67310d69176287b5bf82a21f588282406a79498891 \
+ --hash=sha256:afcaa24e48bb23b3be31e329deb3f1858f1f1df86aea3d70cb5c8578bfe5261c \
+ --hash=sha256:b70d6e7a332eb0217e7872a73926ad4fdc14f846e85ad6749ad111084e76df25 \
+ --hash=sha256:c219a00245af0f6fa4e95901ed28044544f50152840c5b6a3e7b2568db34d156 \
+ --hash=sha256:ce58b2b3734c73e68f0e30e4e725264d4d6be95818ec0a0be4bb6bf9a7e79aa8 \
+ --hash=sha256:d176f392dbbdaacccf15919c77f526edf11a34aece58b55ab58539807b85436f \
+ --hash=sha256:e20bfa6db17a39c706d24f82df8352488d2943a3b7ce7d4c22579cb89ca8896e \
+ --hash=sha256:eac3a9a5ef13b332c059772fd40b4b1c3d45a3a2b05e33a361dee48e54a4dad0 \
+ --hash=sha256:eb329f8d8145379bf5dbe722182410fe8863d186e51bf034d2075eb8d85ee25b
+ # via astroid
+mccabe==0.7.0 \
+ --hash=sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325 \
+ --hash=sha256:6c2d30ab6be0e4a46919781807b4f0d834ebdd6c6e3dca0bda5a15f863427b6e
+ # via pylint
+pathspec==0.10.3 \
+ --hash=sha256:3c95343af8b756205e2aba76e843ba9520a24dd84f68c22b9f93251507509dd6 \
+ --hash=sha256:56200de4077d9d0791465aa9095a01d421861e405b5096955051deefd697d6f6
+ # via yamllint
+platformdirs==2.6.0 \
+ --hash=sha256:1a89a12377800c81983db6be069ec068eee989748799b946cce2a6e80dcc54ca \
+ --hash=sha256:b46ffafa316e6b83b47489d240ce17173f123a9b9c83282141c3daf26ad9ac2e
+ # via pylint
+pylint==2.15.9 \
+ --hash=sha256:18783cca3cfee5b83c6c5d10b3cdb66c6594520ffae61890858fe8d932e1c6b4 \
+ --hash=sha256:349c8cd36aede4d50a0754a8c0218b43323d13d5d88f4b2952ddfe3e169681eb
+ # via -r requirements.in
+python-dateutil==2.8.2 \
+ --hash=sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86 \
+ --hash=sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9
+ # via
+ # -r requirements.in
+ # s3cmd
+python-magic==0.4.27 \
+ --hash=sha256:c1ba14b08e4a5f5c31a302b7721239695b2f0f058d125bd5ce1ee36b9d9d3c3b \
+ --hash=sha256:c212960ad306f700aa0d01e5d7a325d20548ff97eb9920dcd29513174f0294d3
+ # via s3cmd
+pyyaml==6.0 \
+ --hash=sha256:01b45c0191e6d66c470b6cf1b9531a771a83c1c4208272ead47a3ae4f2f603bf \
+ --hash=sha256:0283c35a6a9fbf047493e3a0ce8d79ef5030852c51e9d911a27badfde0605293 \
+ --hash=sha256:055d937d65826939cb044fc8c9b08889e8c743fdc6a32b33e2390f66013e449b \
+ --hash=sha256:07751360502caac1c067a8132d150cf3d61339af5691fe9e87803040dbc5db57 \
+ --hash=sha256:0b4624f379dab24d3725ffde76559cff63d9ec94e1736b556dacdfebe5ab6d4b \
+ --hash=sha256:0ce82d761c532fe4ec3f87fc45688bdd3a4c1dc5e0b4a19814b9009a29baefd4 \
+ --hash=sha256:1e4747bc279b4f613a09eb64bba2ba602d8a6664c6ce6396a4d0cd413a50ce07 \
+ --hash=sha256:213c60cd50106436cc818accf5baa1aba61c0189ff610f64f4a3e8c6726218ba \
+ --hash=sha256:231710d57adfd809ef5d34183b8ed1eeae3f76459c18fb4a0b373ad56bedcdd9 \
+ --hash=sha256:277a0ef2981ca40581a47093e9e2d13b3f1fbbeffae064c1d21bfceba2030287 \
+ --hash=sha256:2cd5df3de48857ed0544b34e2d40e9fac445930039f3cfe4bcc592a1f836d513 \
+ --hash=sha256:40527857252b61eacd1d9af500c3337ba8deb8fc298940291486c465c8b46ec0 \
+ --hash=sha256:432557aa2c09802be39460360ddffd48156e30721f5e8d917f01d31694216782 \
+ --hash=sha256:473f9edb243cb1935ab5a084eb238d842fb8f404ed2193a915d1784b5a6b5fc0 \
+ --hash=sha256:48c346915c114f5fdb3ead70312bd042a953a8ce5c7106d5bfb1a5254e47da92 \
+ --hash=sha256:50602afada6d6cbfad699b0c7bb50d5ccffa7e46a3d738092afddc1f9758427f \
+ --hash=sha256:68fb519c14306fec9720a2a5b45bc9f0c8d1b9c72adf45c37baedfcd949c35a2 \
+ --hash=sha256:77f396e6ef4c73fdc33a9157446466f1cff553d979bd00ecb64385760c6babdc \
+ --hash=sha256:81957921f441d50af23654aa6c5e5eaf9b06aba7f0a19c18a538dc7ef291c5a1 \
+ --hash=sha256:819b3830a1543db06c4d4b865e70ded25be52a2e0631ccd2f6a47a2822f2fd7c \
+ --hash=sha256:897b80890765f037df3403d22bab41627ca8811ae55e9a722fd0392850ec4d86 \
+ --hash=sha256:98c4d36e99714e55cfbaaee6dd5badbc9a1ec339ebfc3b1f52e293aee6bb71a4 \
+ --hash=sha256:9df7ed3b3d2e0ecfe09e14741b857df43adb5a3ddadc919a2d94fbdf78fea53c \
+ --hash=sha256:9fa600030013c4de8165339db93d182b9431076eb98eb40ee068700c9c813e34 \
+ --hash=sha256:a80a78046a72361de73f8f395f1f1e49f956c6be882eed58505a15f3e430962b \
+ --hash=sha256:afa17f5bc4d1b10afd4466fd3a44dc0e245382deca5b3c353d8b757f9e3ecb8d \
+ --hash=sha256:b3d267842bf12586ba6c734f89d1f5b871df0273157918b0ccefa29deb05c21c \
+ --hash=sha256:b5b9eccad747aabaaffbc6064800670f0c297e52c12754eb1d976c57e4f74dcb \
+ --hash=sha256:bfaef573a63ba8923503d27530362590ff4f576c626d86a9fed95822a8255fd7 \
+ --hash=sha256:c5687b8d43cf58545ade1fe3e055f70eac7a5a1a0bf42824308d868289a95737 \
+ --hash=sha256:cba8c411ef271aa037d7357a2bc8f9ee8b58b9965831d9e51baf703280dc73d3 \
+ --hash=sha256:d15a181d1ecd0d4270dc32edb46f7cb7733c7c508857278d3d378d14d606db2d \
+ --hash=sha256:d4b0ba9512519522b118090257be113b9468d804b19d63c71dbcf4a48fa32358 \
+ --hash=sha256:d4db7c7aef085872ef65a8fd7d6d09a14ae91f691dec3e87ee5ee0539d516f53 \
+ --hash=sha256:d4eccecf9adf6fbcc6861a38015c2a64f38b9d94838ac1810a9023a0609e1b78 \
+ --hash=sha256:d67d839ede4ed1b28a4e8909735fc992a923cdb84e618544973d7dfc71540803 \
+ --hash=sha256:daf496c58a8c52083df09b80c860005194014c3698698d1a57cbcfa182142a3a \
+ --hash=sha256:dbad0e9d368bb989f4515da330b88a057617d16b6a8245084f1b05400f24609f \
+ --hash=sha256:e61ceaab6f49fb8bdfaa0f92c4b57bcfbea54c09277b1b4f7ac376bfb7a7c174 \
+ --hash=sha256:f84fbc98b019fef2ee9a1cb3ce93e3187a6df0b2538a651bfb890254ba9f90b5
+ # via yamllint
+requests==2.25.1 \
+ --hash=sha256:27973dd4a904a4f13b263a19c866c13b92a39ed1c964655f025f3f8d3d75b804 \
+ --hash=sha256:c210084e36a42ae6b9219e00e48287def368a26d03a048ddad7bfee44f75871e
+ # via -r requirements.in
+s3cmd==2.1.0 \
+ --hash=sha256:49cd23d516b17974b22b611a95ce4d93fe326feaa07320bd1d234fed68cbccfa \
+ --hash=sha256:966b0a494a916fc3b4324de38f089c86c70ee90e8e1cae6d59102103a4c0cc03
+ # via -r requirements.in
+setuptools==65.6.3 \
+ --hash=sha256:57f6f22bde4e042978bcd50176fdb381d7c21a9efa4041202288d3737a0c6a54 \
+ --hash=sha256:a7620757bf984b58deaf32fc8a4577a9bbc0850cf92c20e1ce41c38c19e5fb75
+ # via yamllint
+six==1.16.0 \
+ --hash=sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926 \
+ --hash=sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254
+ # via python-dateutil
+tabulate==0.9.0 \
+ --hash=sha256:0095b12bf5966de529c0feb1fa08671671b3368eec77d7ef7ab114be2c068b3c \
+ --hash=sha256:024ca478df22e9340661486f85298cff5f6dcdba14f3813e8830015b9ed1948f
+ # via -r requirements.in
+tomli==2.0.1 \
+ --hash=sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc \
+ --hash=sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f
+ # via pylint
+tomlkit==0.11.6 \
+ --hash=sha256:07de26b0d8cfc18f871aec595fda24d95b08fef89d147caa861939f37230bf4b \
+ --hash=sha256:71b952e5721688937fb02cf9d354dbcf0785066149d2855e44531ebdd2b65d73
+ # via pylint
+typing-extensions==4.4.0 \
+ --hash=sha256:1511434bb92bf8dd198c12b1cc812e800d4181cfcb867674e0f8279cc93087aa \
+ --hash=sha256:16fa4864408f655d35ec496218b85f79b3437c829e93320c7c9215ccfd92489e
+ # via
+ # astroid
+ # pylint
+urllib3==1.26.13 \
+ --hash=sha256:47cc05d99aaa09c9e72ed5809b60e7ba354e64b59c9c173ac3018642d8bb41fc \
+ --hash=sha256:c083dd0dce68dbfbe1129d5271cb90f9447dea7d52097c6e0126120c521ddea8
+ # via requests
+wrapt==1.14.1 \
+ --hash=sha256:00b6d4ea20a906c0ca56d84f93065b398ab74b927a7a3dbd470f6fc503f95dc3 \
+ --hash=sha256:01c205616a89d09827986bc4e859bcabd64f5a0662a7fe95e0d359424e0e071b \
+ --hash=sha256:02b41b633c6261feff8ddd8d11c711df6842aba629fdd3da10249a53211a72c4 \
+ --hash=sha256:07f7a7d0f388028b2df1d916e94bbb40624c59b48ecc6cbc232546706fac74c2 \
+ --hash=sha256:11871514607b15cfeb87c547a49bca19fde402f32e2b1c24a632506c0a756656 \
+ --hash=sha256:1b376b3f4896e7930f1f772ac4b064ac12598d1c38d04907e696cc4d794b43d3 \
+ --hash=sha256:21ac0156c4b089b330b7666db40feee30a5d52634cc4560e1905d6529a3897ff \
+ --hash=sha256:257fd78c513e0fb5cdbe058c27a0624c9884e735bbd131935fd49e9fe719d310 \
+ --hash=sha256:2b39d38039a1fdad98c87279b48bc5dce2c0ca0d73483b12cb72aa9609278e8a \
+ --hash=sha256:2cf71233a0ed05ccdabe209c606fe0bac7379fdcf687f39b944420d2a09fdb57 \
+ --hash=sha256:2fe803deacd09a233e4762a1adcea5db5d31e6be577a43352936179d14d90069 \
+ --hash=sha256:3232822c7d98d23895ccc443bbdf57c7412c5a65996c30442ebe6ed3df335383 \
+ --hash=sha256:34aa51c45f28ba7f12accd624225e2b1e5a3a45206aa191f6f9aac931d9d56fe \
+ --hash=sha256:36f582d0c6bc99d5f39cd3ac2a9062e57f3cf606ade29a0a0d6b323462f4dd87 \
+ --hash=sha256:380a85cf89e0e69b7cfbe2ea9f765f004ff419f34194018a6827ac0e3edfed4d \
+ --hash=sha256:40e7bc81c9e2b2734ea4bc1aceb8a8f0ceaac7c5299bc5d69e37c44d9081d43b \
+ --hash=sha256:43ca3bbbe97af00f49efb06e352eae40434ca9d915906f77def219b88e85d907 \
+ --hash=sha256:4fcc4649dc762cddacd193e6b55bc02edca674067f5f98166d7713b193932b7f \
+ --hash=sha256:5a0f54ce2c092aaf439813735584b9537cad479575a09892b8352fea5e988dc0 \
+ --hash=sha256:5a9a0d155deafd9448baff28c08e150d9b24ff010e899311ddd63c45c2445e28 \
+ --hash=sha256:5b02d65b9ccf0ef6c34cba6cf5bf2aab1bb2f49c6090bafeecc9cd81ad4ea1c1 \
+ --hash=sha256:60db23fa423575eeb65ea430cee741acb7c26a1365d103f7b0f6ec412b893853 \
+ --hash=sha256:642c2e7a804fcf18c222e1060df25fc210b9c58db7c91416fb055897fc27e8cc \
+ --hash=sha256:6a9a25751acb379b466ff6be78a315e2b439d4c94c1e99cb7266d40a537995d3 \
+ --hash=sha256:6b1a564e6cb69922c7fe3a678b9f9a3c54e72b469875aa8018f18b4d1dd1adf3 \
+ --hash=sha256:6d323e1554b3d22cfc03cd3243b5bb815a51f5249fdcbb86fda4bf62bab9e164 \
+ --hash=sha256:6e743de5e9c3d1b7185870f480587b75b1cb604832e380d64f9504a0535912d1 \
+ --hash=sha256:709fe01086a55cf79d20f741f39325018f4df051ef39fe921b1ebe780a66184c \
+ --hash=sha256:7b7c050ae976e286906dd3f26009e117eb000fb2cf3533398c5ad9ccc86867b1 \
+ --hash=sha256:7d2872609603cb35ca513d7404a94d6d608fc13211563571117046c9d2bcc3d7 \
+ --hash=sha256:7ef58fb89674095bfc57c4069e95d7a31cfdc0939e2a579882ac7d55aadfd2a1 \
+ --hash=sha256:80bb5c256f1415f747011dc3604b59bc1f91c6e7150bd7db03b19170ee06b320 \
+ --hash=sha256:81b19725065dcb43df02b37e03278c011a09e49757287dca60c5aecdd5a0b8ed \
+ --hash=sha256:833b58d5d0b7e5b9832869f039203389ac7cbf01765639c7309fd50ef619e0b1 \
+ --hash=sha256:88bd7b6bd70a5b6803c1abf6bca012f7ed963e58c68d76ee20b9d751c74a3248 \
+ --hash=sha256:8ad85f7f4e20964db4daadcab70b47ab05c7c1cf2a7c1e51087bfaa83831854c \
+ --hash=sha256:8c0ce1e99116d5ab21355d8ebe53d9460366704ea38ae4d9f6933188f327b456 \
+ --hash=sha256:8d649d616e5c6a678b26d15ece345354f7c2286acd6db868e65fcc5ff7c24a77 \
+ --hash=sha256:903500616422a40a98a5a3c4ff4ed9d0066f3b4c951fa286018ecdf0750194ef \
+ --hash=sha256:9736af4641846491aedb3c3f56b9bc5568d92b0692303b5a305301a95dfd38b1 \
+ --hash=sha256:988635d122aaf2bdcef9e795435662bcd65b02f4f4c1ae37fbee7401c440b3a7 \
+ --hash=sha256:9cca3c2cdadb362116235fdbd411735de4328c61425b0aa9f872fd76d02c4e86 \
+ --hash=sha256:9e0fd32e0148dd5dea6af5fee42beb949098564cc23211a88d799e434255a1f4 \
+ --hash=sha256:9f3e6f9e05148ff90002b884fbc2a86bd303ae847e472f44ecc06c2cd2fcdb2d \
+ --hash=sha256:a85d2b46be66a71bedde836d9e41859879cc54a2a04fad1191eb50c2066f6e9d \
+ --hash=sha256:a9a52172be0b5aae932bef82a79ec0a0ce87288c7d132946d645eba03f0ad8a8 \
+ --hash=sha256:aa31fdcc33fef9eb2552cbcbfee7773d5a6792c137b359e82879c101e98584c5 \
+ --hash=sha256:b014c23646a467558be7da3d6b9fa409b2c567d2110599b7cf9a0c5992b3b471 \
+ --hash=sha256:b21bb4c09ffabfa0e85e3a6b623e19b80e7acd709b9f91452b8297ace2a8ab00 \
+ --hash=sha256:b5901a312f4d14c59918c221323068fad0540e34324925c8475263841dbdfe68 \
+ --hash=sha256:b9b7a708dd92306328117d8c4b62e2194d00c365f18eff11a9b53c6f923b01e3 \
+ --hash=sha256:d1967f46ea8f2db647c786e78d8cc7e4313dbd1b0aca360592d8027b8508e24d \
+ --hash=sha256:d52a25136894c63de15a35bc0bdc5adb4b0e173b9c0d07a2be9d3ca64a332735 \
+ --hash=sha256:d77c85fedff92cf788face9bfa3ebaa364448ebb1d765302e9af11bf449ca36d \
+ --hash=sha256:d79d7d5dc8a32b7093e81e97dad755127ff77bcc899e845f41bf71747af0c569 \
+ --hash=sha256:dbcda74c67263139358f4d188ae5faae95c30929281bc6866d00573783c422b7 \
+ --hash=sha256:ddaea91abf8b0d13443f6dac52e89051a5063c7d014710dcb4d4abb2ff811a59 \
+ --hash=sha256:dee0ce50c6a2dd9056c20db781e9c1cfd33e77d2d569f5d1d9321c641bb903d5 \
+ --hash=sha256:dee60e1de1898bde3b238f18340eec6148986da0455d8ba7848d50470a7a32fb \
+ --hash=sha256:e2f83e18fe2f4c9e7db597e988f72712c0c3676d337d8b101f6758107c42425b \
+ --hash=sha256:e3fb1677c720409d5f671e39bac6c9e0e422584e5f518bfd50aa4cbbea02433f \
+ --hash=sha256:ee2b1b1769f6707a8a445162ea16dddf74285c3964f605877a20e38545c3c462 \
+ --hash=sha256:ee6acae74a2b91865910eef5e7de37dc6895ad96fa23603d1d27ea69df545015 \
+ --hash=sha256:ef3f72c9666bba2bab70d2a8b79f2c6d2c1a42a7f7e2b0ec83bb2f9e383950af
+ # via astroid
+yamllint==1.28.0 \
+ --hash=sha256:89bb5b5ac33b1ade059743cf227de73daa34d5e5a474b06a5e17fc16583b0cf2 \
+ --hash=sha256:9e3d8ddd16d0583214c5fdffe806c9344086721f107435f68bad990e5a88826b
+ # via -r requirements.in
diff --git a/examples/bzlmod_build_file_generation/requirements_windows.txt b/examples/bzlmod_build_file_generation/requirements_windows.txt
new file mode 100644
index 0000000000..06cfdc332c
--- /dev/null
+++ b/examples/bzlmod_build_file_generation/requirements_windows.txt
@@ -0,0 +1,231 @@
+#
+# This file is autogenerated by pip-compile with Python 3.9
+# by the following command:
+#
+# bazel run //:requirements.update
+#
+astroid==2.12.13 \
+ --hash=sha256:10e0ad5f7b79c435179d0d0f0df69998c4eef4597534aae44910db060baeb907 \
+ --hash=sha256:1493fe8bd3dfd73dc35bd53c9d5b6e49ead98497c47b2307662556a5692d29d7
+ # via pylint
+certifi==2022.12.7 \
+ --hash=sha256:35824b4c3a97115964b408844d64aa14db1cc518f6562e8d7261699d1350a9e3 \
+ --hash=sha256:4ad3232f5e926d6718ec31cfc1fcadfde020920e278684144551c91769c7bc18
+ # via requests
+chardet==4.0.0 \
+ --hash=sha256:0d6f53a15db4120f2b08c94f11e7d93d2c911ee118b6b30a04ec3ee8310179fa \
+ --hash=sha256:f864054d66fd9118f2e67044ac8981a54775ec5b67aed0441892edb553d21da5
+ # via requests
+colorama==0.4.6 \
+ --hash=sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44 \
+ --hash=sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6
+ # via pylint
+dill==0.3.6 \
+ --hash=sha256:a07ffd2351b8c678dfc4a856a3005f8067aea51d6ba6c700796a4d9e280f39f0 \
+ --hash=sha256:e5db55f3687856d8fbdab002ed78544e1c4559a130302693d839dfe8f93f2373
+ # via pylint
+idna==2.10 \
+ --hash=sha256:b307872f855b18632ce0c21c5e45be78c0ea7ae4c15c828c20788b26921eb3f6 \
+ --hash=sha256:b97d804b1e9b523befed77c48dacec60e6dcb0b5391d57af6a65a312a90648c0
+ # via requests
+isort==5.11.4 \
+ --hash=sha256:6db30c5ded9815d813932c04c2f85a360bcdd35fed496f4d8f35495ef0a261b6 \
+ --hash=sha256:c033fd0edb91000a7f09527fe5c75321878f98322a77ddcc81adbd83724afb7b
+ # via pylint
+lazy-object-proxy==1.8.0 \
+ --hash=sha256:0c1c7c0433154bb7c54185714c6929acc0ba04ee1b167314a779b9025517eada \
+ --hash=sha256:14010b49a2f56ec4943b6cf925f597b534ee2fe1f0738c84b3bce0c1a11ff10d \
+ --hash=sha256:4e2d9f764f1befd8bdc97673261b8bb888764dfdbd7a4d8f55e4fbcabb8c3fb7 \
+ --hash=sha256:4fd031589121ad46e293629b39604031d354043bb5cdf83da4e93c2d7f3389fe \
+ --hash=sha256:5b51d6f3bfeb289dfd4e95de2ecd464cd51982fe6f00e2be1d0bf94864d58acd \
+ --hash=sha256:6850e4aeca6d0df35bb06e05c8b934ff7c533734eb51d0ceb2d63696f1e6030c \
+ --hash=sha256:6f593f26c470a379cf7f5bc6db6b5f1722353e7bf937b8d0d0b3fba911998858 \
+ --hash=sha256:71d9ae8a82203511a6f60ca5a1b9f8ad201cac0fc75038b2dc5fa519589c9288 \
+ --hash=sha256:7e1561626c49cb394268edd00501b289053a652ed762c58e1081224c8d881cec \
+ --hash=sha256:8f6ce2118a90efa7f62dd38c7dbfffd42f468b180287b748626293bf12ed468f \
+ --hash=sha256:ae032743794fba4d171b5b67310d69176287b5bf82a21f588282406a79498891 \
+ --hash=sha256:afcaa24e48bb23b3be31e329deb3f1858f1f1df86aea3d70cb5c8578bfe5261c \
+ --hash=sha256:b70d6e7a332eb0217e7872a73926ad4fdc14f846e85ad6749ad111084e76df25 \
+ --hash=sha256:c219a00245af0f6fa4e95901ed28044544f50152840c5b6a3e7b2568db34d156 \
+ --hash=sha256:ce58b2b3734c73e68f0e30e4e725264d4d6be95818ec0a0be4bb6bf9a7e79aa8 \
+ --hash=sha256:d176f392dbbdaacccf15919c77f526edf11a34aece58b55ab58539807b85436f \
+ --hash=sha256:e20bfa6db17a39c706d24f82df8352488d2943a3b7ce7d4c22579cb89ca8896e \
+ --hash=sha256:eac3a9a5ef13b332c059772fd40b4b1c3d45a3a2b05e33a361dee48e54a4dad0 \
+ --hash=sha256:eb329f8d8145379bf5dbe722182410fe8863d186e51bf034d2075eb8d85ee25b
+ # via astroid
+mccabe==0.7.0 \
+ --hash=sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325 \
+ --hash=sha256:6c2d30ab6be0e4a46919781807b4f0d834ebdd6c6e3dca0bda5a15f863427b6e
+ # via pylint
+pathspec==0.10.3 \
+ --hash=sha256:3c95343af8b756205e2aba76e843ba9520a24dd84f68c22b9f93251507509dd6 \
+ --hash=sha256:56200de4077d9d0791465aa9095a01d421861e405b5096955051deefd697d6f6
+ # via yamllint
+platformdirs==2.6.0 \
+ --hash=sha256:1a89a12377800c81983db6be069ec068eee989748799b946cce2a6e80dcc54ca \
+ --hash=sha256:b46ffafa316e6b83b47489d240ce17173f123a9b9c83282141c3daf26ad9ac2e
+ # via pylint
+pylint==2.15.9 \
+ --hash=sha256:18783cca3cfee5b83c6c5d10b3cdb66c6594520ffae61890858fe8d932e1c6b4 \
+ --hash=sha256:349c8cd36aede4d50a0754a8c0218b43323d13d5d88f4b2952ddfe3e169681eb
+ # via -r requirements.in
+python-dateutil==2.8.2 \
+ --hash=sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86 \
+ --hash=sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9
+ # via
+ # -r requirements.in
+ # s3cmd
+python-magic==0.4.27 \
+ --hash=sha256:c1ba14b08e4a5f5c31a302b7721239695b2f0f058d125bd5ce1ee36b9d9d3c3b \
+ --hash=sha256:c212960ad306f700aa0d01e5d7a325d20548ff97eb9920dcd29513174f0294d3
+ # via s3cmd
+pyyaml==6.0 \
+ --hash=sha256:01b45c0191e6d66c470b6cf1b9531a771a83c1c4208272ead47a3ae4f2f603bf \
+ --hash=sha256:0283c35a6a9fbf047493e3a0ce8d79ef5030852c51e9d911a27badfde0605293 \
+ --hash=sha256:055d937d65826939cb044fc8c9b08889e8c743fdc6a32b33e2390f66013e449b \
+ --hash=sha256:07751360502caac1c067a8132d150cf3d61339af5691fe9e87803040dbc5db57 \
+ --hash=sha256:0b4624f379dab24d3725ffde76559cff63d9ec94e1736b556dacdfebe5ab6d4b \
+ --hash=sha256:0ce82d761c532fe4ec3f87fc45688bdd3a4c1dc5e0b4a19814b9009a29baefd4 \
+ --hash=sha256:1e4747bc279b4f613a09eb64bba2ba602d8a6664c6ce6396a4d0cd413a50ce07 \
+ --hash=sha256:213c60cd50106436cc818accf5baa1aba61c0189ff610f64f4a3e8c6726218ba \
+ --hash=sha256:231710d57adfd809ef5d34183b8ed1eeae3f76459c18fb4a0b373ad56bedcdd9 \
+ --hash=sha256:277a0ef2981ca40581a47093e9e2d13b3f1fbbeffae064c1d21bfceba2030287 \
+ --hash=sha256:2cd5df3de48857ed0544b34e2d40e9fac445930039f3cfe4bcc592a1f836d513 \
+ --hash=sha256:40527857252b61eacd1d9af500c3337ba8deb8fc298940291486c465c8b46ec0 \
+ --hash=sha256:432557aa2c09802be39460360ddffd48156e30721f5e8d917f01d31694216782 \
+ --hash=sha256:473f9edb243cb1935ab5a084eb238d842fb8f404ed2193a915d1784b5a6b5fc0 \
+ --hash=sha256:48c346915c114f5fdb3ead70312bd042a953a8ce5c7106d5bfb1a5254e47da92 \
+ --hash=sha256:50602afada6d6cbfad699b0c7bb50d5ccffa7e46a3d738092afddc1f9758427f \
+ --hash=sha256:68fb519c14306fec9720a2a5b45bc9f0c8d1b9c72adf45c37baedfcd949c35a2 \
+ --hash=sha256:77f396e6ef4c73fdc33a9157446466f1cff553d979bd00ecb64385760c6babdc \
+ --hash=sha256:81957921f441d50af23654aa6c5e5eaf9b06aba7f0a19c18a538dc7ef291c5a1 \
+ --hash=sha256:819b3830a1543db06c4d4b865e70ded25be52a2e0631ccd2f6a47a2822f2fd7c \
+ --hash=sha256:897b80890765f037df3403d22bab41627ca8811ae55e9a722fd0392850ec4d86 \
+ --hash=sha256:98c4d36e99714e55cfbaaee6dd5badbc9a1ec339ebfc3b1f52e293aee6bb71a4 \
+ --hash=sha256:9df7ed3b3d2e0ecfe09e14741b857df43adb5a3ddadc919a2d94fbdf78fea53c \
+ --hash=sha256:9fa600030013c4de8165339db93d182b9431076eb98eb40ee068700c9c813e34 \
+ --hash=sha256:a80a78046a72361de73f8f395f1f1e49f956c6be882eed58505a15f3e430962b \
+ --hash=sha256:afa17f5bc4d1b10afd4466fd3a44dc0e245382deca5b3c353d8b757f9e3ecb8d \
+ --hash=sha256:b3d267842bf12586ba6c734f89d1f5b871df0273157918b0ccefa29deb05c21c \
+ --hash=sha256:b5b9eccad747aabaaffbc6064800670f0c297e52c12754eb1d976c57e4f74dcb \
+ --hash=sha256:bfaef573a63ba8923503d27530362590ff4f576c626d86a9fed95822a8255fd7 \
+ --hash=sha256:c5687b8d43cf58545ade1fe3e055f70eac7a5a1a0bf42824308d868289a95737 \
+ --hash=sha256:cba8c411ef271aa037d7357a2bc8f9ee8b58b9965831d9e51baf703280dc73d3 \
+ --hash=sha256:d15a181d1ecd0d4270dc32edb46f7cb7733c7c508857278d3d378d14d606db2d \
+ --hash=sha256:d4b0ba9512519522b118090257be113b9468d804b19d63c71dbcf4a48fa32358 \
+ --hash=sha256:d4db7c7aef085872ef65a8fd7d6d09a14ae91f691dec3e87ee5ee0539d516f53 \
+ --hash=sha256:d4eccecf9adf6fbcc6861a38015c2a64f38b9d94838ac1810a9023a0609e1b78 \
+ --hash=sha256:d67d839ede4ed1b28a4e8909735fc992a923cdb84e618544973d7dfc71540803 \
+ --hash=sha256:daf496c58a8c52083df09b80c860005194014c3698698d1a57cbcfa182142a3a \
+ --hash=sha256:dbad0e9d368bb989f4515da330b88a057617d16b6a8245084f1b05400f24609f \
+ --hash=sha256:e61ceaab6f49fb8bdfaa0f92c4b57bcfbea54c09277b1b4f7ac376bfb7a7c174 \
+ --hash=sha256:f84fbc98b019fef2ee9a1cb3ce93e3187a6df0b2538a651bfb890254ba9f90b5
+ # via yamllint
+requests==2.25.1 \
+ --hash=sha256:27973dd4a904a4f13b263a19c866c13b92a39ed1c964655f025f3f8d3d75b804 \
+ --hash=sha256:c210084e36a42ae6b9219e00e48287def368a26d03a048ddad7bfee44f75871e
+ # via -r requirements.in
+s3cmd==2.1.0 \
+ --hash=sha256:49cd23d516b17974b22b611a95ce4d93fe326feaa07320bd1d234fed68cbccfa \
+ --hash=sha256:966b0a494a916fc3b4324de38f089c86c70ee90e8e1cae6d59102103a4c0cc03
+ # via -r requirements.in
+setuptools==65.6.3 \
+ --hash=sha256:57f6f22bde4e042978bcd50176fdb381d7c21a9efa4041202288d3737a0c6a54 \
+ --hash=sha256:a7620757bf984b58deaf32fc8a4577a9bbc0850cf92c20e1ce41c38c19e5fb75
+ # via yamllint
+six==1.16.0 \
+ --hash=sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926 \
+ --hash=sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254
+ # via python-dateutil
+tabulate==0.9.0 \
+ --hash=sha256:0095b12bf5966de529c0feb1fa08671671b3368eec77d7ef7ab114be2c068b3c \
+ --hash=sha256:024ca478df22e9340661486f85298cff5f6dcdba14f3813e8830015b9ed1948f
+ # via -r requirements.in
+tomli==2.0.1 \
+ --hash=sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc \
+ --hash=sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f
+ # via pylint
+tomlkit==0.11.6 \
+ --hash=sha256:07de26b0d8cfc18f871aec595fda24d95b08fef89d147caa861939f37230bf4b \
+ --hash=sha256:71b952e5721688937fb02cf9d354dbcf0785066149d2855e44531ebdd2b65d73
+ # via pylint
+typing-extensions==4.4.0 \
+ --hash=sha256:1511434bb92bf8dd198c12b1cc812e800d4181cfcb867674e0f8279cc93087aa \
+ --hash=sha256:16fa4864408f655d35ec496218b85f79b3437c829e93320c7c9215ccfd92489e
+ # via
+ # astroid
+ # pylint
+urllib3==1.26.13 \
+ --hash=sha256:47cc05d99aaa09c9e72ed5809b60e7ba354e64b59c9c173ac3018642d8bb41fc \
+ --hash=sha256:c083dd0dce68dbfbe1129d5271cb90f9447dea7d52097c6e0126120c521ddea8
+ # via requests
+wrapt==1.14.1 \
+ --hash=sha256:00b6d4ea20a906c0ca56d84f93065b398ab74b927a7a3dbd470f6fc503f95dc3 \
+ --hash=sha256:01c205616a89d09827986bc4e859bcabd64f5a0662a7fe95e0d359424e0e071b \
+ --hash=sha256:02b41b633c6261feff8ddd8d11c711df6842aba629fdd3da10249a53211a72c4 \
+ --hash=sha256:07f7a7d0f388028b2df1d916e94bbb40624c59b48ecc6cbc232546706fac74c2 \
+ --hash=sha256:11871514607b15cfeb87c547a49bca19fde402f32e2b1c24a632506c0a756656 \
+ --hash=sha256:1b376b3f4896e7930f1f772ac4b064ac12598d1c38d04907e696cc4d794b43d3 \
+ --hash=sha256:21ac0156c4b089b330b7666db40feee30a5d52634cc4560e1905d6529a3897ff \
+ --hash=sha256:257fd78c513e0fb5cdbe058c27a0624c9884e735bbd131935fd49e9fe719d310 \
+ --hash=sha256:2b39d38039a1fdad98c87279b48bc5dce2c0ca0d73483b12cb72aa9609278e8a \
+ --hash=sha256:2cf71233a0ed05ccdabe209c606fe0bac7379fdcf687f39b944420d2a09fdb57 \
+ --hash=sha256:2fe803deacd09a233e4762a1adcea5db5d31e6be577a43352936179d14d90069 \
+ --hash=sha256:3232822c7d98d23895ccc443bbdf57c7412c5a65996c30442ebe6ed3df335383 \
+ --hash=sha256:34aa51c45f28ba7f12accd624225e2b1e5a3a45206aa191f6f9aac931d9d56fe \
+ --hash=sha256:36f582d0c6bc99d5f39cd3ac2a9062e57f3cf606ade29a0a0d6b323462f4dd87 \
+ --hash=sha256:380a85cf89e0e69b7cfbe2ea9f765f004ff419f34194018a6827ac0e3edfed4d \
+ --hash=sha256:40e7bc81c9e2b2734ea4bc1aceb8a8f0ceaac7c5299bc5d69e37c44d9081d43b \
+ --hash=sha256:43ca3bbbe97af00f49efb06e352eae40434ca9d915906f77def219b88e85d907 \
+ --hash=sha256:4fcc4649dc762cddacd193e6b55bc02edca674067f5f98166d7713b193932b7f \
+ --hash=sha256:5a0f54ce2c092aaf439813735584b9537cad479575a09892b8352fea5e988dc0 \
+ --hash=sha256:5a9a0d155deafd9448baff28c08e150d9b24ff010e899311ddd63c45c2445e28 \
+ --hash=sha256:5b02d65b9ccf0ef6c34cba6cf5bf2aab1bb2f49c6090bafeecc9cd81ad4ea1c1 \
+ --hash=sha256:60db23fa423575eeb65ea430cee741acb7c26a1365d103f7b0f6ec412b893853 \
+ --hash=sha256:642c2e7a804fcf18c222e1060df25fc210b9c58db7c91416fb055897fc27e8cc \
+ --hash=sha256:6a9a25751acb379b466ff6be78a315e2b439d4c94c1e99cb7266d40a537995d3 \
+ --hash=sha256:6b1a564e6cb69922c7fe3a678b9f9a3c54e72b469875aa8018f18b4d1dd1adf3 \
+ --hash=sha256:6d323e1554b3d22cfc03cd3243b5bb815a51f5249fdcbb86fda4bf62bab9e164 \
+ --hash=sha256:6e743de5e9c3d1b7185870f480587b75b1cb604832e380d64f9504a0535912d1 \
+ --hash=sha256:709fe01086a55cf79d20f741f39325018f4df051ef39fe921b1ebe780a66184c \
+ --hash=sha256:7b7c050ae976e286906dd3f26009e117eb000fb2cf3533398c5ad9ccc86867b1 \
+ --hash=sha256:7d2872609603cb35ca513d7404a94d6d608fc13211563571117046c9d2bcc3d7 \
+ --hash=sha256:7ef58fb89674095bfc57c4069e95d7a31cfdc0939e2a579882ac7d55aadfd2a1 \
+ --hash=sha256:80bb5c256f1415f747011dc3604b59bc1f91c6e7150bd7db03b19170ee06b320 \
+ --hash=sha256:81b19725065dcb43df02b37e03278c011a09e49757287dca60c5aecdd5a0b8ed \
+ --hash=sha256:833b58d5d0b7e5b9832869f039203389ac7cbf01765639c7309fd50ef619e0b1 \
+ --hash=sha256:88bd7b6bd70a5b6803c1abf6bca012f7ed963e58c68d76ee20b9d751c74a3248 \
+ --hash=sha256:8ad85f7f4e20964db4daadcab70b47ab05c7c1cf2a7c1e51087bfaa83831854c \
+ --hash=sha256:8c0ce1e99116d5ab21355d8ebe53d9460366704ea38ae4d9f6933188f327b456 \
+ --hash=sha256:8d649d616e5c6a678b26d15ece345354f7c2286acd6db868e65fcc5ff7c24a77 \
+ --hash=sha256:903500616422a40a98a5a3c4ff4ed9d0066f3b4c951fa286018ecdf0750194ef \
+ --hash=sha256:9736af4641846491aedb3c3f56b9bc5568d92b0692303b5a305301a95dfd38b1 \
+ --hash=sha256:988635d122aaf2bdcef9e795435662bcd65b02f4f4c1ae37fbee7401c440b3a7 \
+ --hash=sha256:9cca3c2cdadb362116235fdbd411735de4328c61425b0aa9f872fd76d02c4e86 \
+ --hash=sha256:9e0fd32e0148dd5dea6af5fee42beb949098564cc23211a88d799e434255a1f4 \
+ --hash=sha256:9f3e6f9e05148ff90002b884fbc2a86bd303ae847e472f44ecc06c2cd2fcdb2d \
+ --hash=sha256:a85d2b46be66a71bedde836d9e41859879cc54a2a04fad1191eb50c2066f6e9d \
+ --hash=sha256:a9a52172be0b5aae932bef82a79ec0a0ce87288c7d132946d645eba03f0ad8a8 \
+ --hash=sha256:aa31fdcc33fef9eb2552cbcbfee7773d5a6792c137b359e82879c101e98584c5 \
+ --hash=sha256:b014c23646a467558be7da3d6b9fa409b2c567d2110599b7cf9a0c5992b3b471 \
+ --hash=sha256:b21bb4c09ffabfa0e85e3a6b623e19b80e7acd709b9f91452b8297ace2a8ab00 \
+ --hash=sha256:b5901a312f4d14c59918c221323068fad0540e34324925c8475263841dbdfe68 \
+ --hash=sha256:b9b7a708dd92306328117d8c4b62e2194d00c365f18eff11a9b53c6f923b01e3 \
+ --hash=sha256:d1967f46ea8f2db647c786e78d8cc7e4313dbd1b0aca360592d8027b8508e24d \
+ --hash=sha256:d52a25136894c63de15a35bc0bdc5adb4b0e173b9c0d07a2be9d3ca64a332735 \
+ --hash=sha256:d77c85fedff92cf788face9bfa3ebaa364448ebb1d765302e9af11bf449ca36d \
+ --hash=sha256:d79d7d5dc8a32b7093e81e97dad755127ff77bcc899e845f41bf71747af0c569 \
+ --hash=sha256:dbcda74c67263139358f4d188ae5faae95c30929281bc6866d00573783c422b7 \
+ --hash=sha256:ddaea91abf8b0d13443f6dac52e89051a5063c7d014710dcb4d4abb2ff811a59 \
+ --hash=sha256:dee0ce50c6a2dd9056c20db781e9c1cfd33e77d2d569f5d1d9321c641bb903d5 \
+ --hash=sha256:dee60e1de1898bde3b238f18340eec6148986da0455d8ba7848d50470a7a32fb \
+ --hash=sha256:e2f83e18fe2f4c9e7db597e988f72712c0c3676d337d8b101f6758107c42425b \
+ --hash=sha256:e3fb1677c720409d5f671e39bac6c9e0e422584e5f518bfd50aa4cbbea02433f \
+ --hash=sha256:ee2b1b1769f6707a8a445162ea16dddf74285c3964f605877a20e38545c3c462 \
+ --hash=sha256:ee6acae74a2b91865910eef5e7de37dc6895ad96fa23603d1d27ea69df545015 \
+ --hash=sha256:ef3f72c9666bba2bab70d2a8b79f2c6d2c1a42a7f7e2b0ec83bb2f9e383950af
+ # via astroid
+yamllint==1.28.0 \
+ --hash=sha256:89bb5b5ac33b1ade059743cf227de73daa34d5e5a474b06a5e17fc16583b0cf2 \
+ --hash=sha256:9e3d8ddd16d0583214c5fdffe806c9344086721f107435f68bad990e5a88826b
+ # via -r requirements.in
diff --git a/examples/bzlmod_build_file_generation/runfiles/BUILD.bazel b/examples/bzlmod_build_file_generation/runfiles/BUILD.bazel
new file mode 100644
index 0000000000..3503ac3017
--- /dev/null
+++ b/examples/bzlmod_build_file_generation/runfiles/BUILD.bazel
@@ -0,0 +1,19 @@
+load("@rules_python//python:defs.bzl", "py_test")
+
+# gazelle:ignore
+py_test(
+ name = "runfiles_test",
+ srcs = ["runfiles_test.py"],
+ data = [
+ "data/data.txt",
+ "@our_other_module//other_module/pkg:data/data.txt",
+ ],
+ env = {
+ "DATA_RLOCATIONPATH": "$(rlocationpath data/data.txt)",
+ "OTHER_MODULE_DATA_RLOCATIONPATH": "$(rlocationpath @our_other_module//other_module/pkg:data/data.txt)",
+ },
+ deps = [
+ "@our_other_module//other_module/pkg:lib",
+ "@rules_python//python/runfiles",
+ ],
+)
diff --git a/examples/bzlmod_build_file_generation/runfiles/data/data.txt b/examples/bzlmod_build_file_generation/runfiles/data/data.txt
new file mode 100644
index 0000000000..fb17e0df66
--- /dev/null
+++ b/examples/bzlmod_build_file_generation/runfiles/data/data.txt
@@ -0,0 +1 @@
+Hello, example_bzlmod!
diff --git a/examples/bzlmod_build_file_generation/runfiles/runfiles_test.py b/examples/bzlmod_build_file_generation/runfiles/runfiles_test.py
new file mode 100644
index 0000000000..a588040cfd
--- /dev/null
+++ b/examples/bzlmod_build_file_generation/runfiles/runfiles_test.py
@@ -0,0 +1,64 @@
+# Copyright 2023 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import os
+import unittest
+
+from other_module.pkg import lib
+
+from python.runfiles import runfiles
+
+
+class RunfilesTest(unittest.TestCase):
+ # """Unit tests for `runfiles.Runfiles`."""
+ def testCurrentRepository(self):
+ self.assertEqual(runfiles.Create().CurrentRepository(), "")
+
+ def testRunfilesWithRepoMapping(self):
+ data_path = runfiles.Create().Rlocation("example_bzlmod_build_file_generation/runfiles/data/data.txt")
+ with open(data_path) as f:
+ self.assertEqual(f.read().strip(), "Hello, example_bzlmod!")
+
+ def testRunfileWithRlocationpath(self):
+ data_rlocationpath = os.getenv("DATA_RLOCATIONPATH")
+ data_path = runfiles.Create().Rlocation(data_rlocationpath)
+ with open(data_path) as f:
+ self.assertEqual(f.read().strip(), "Hello, example_bzlmod!")
+
+ def testRunfileInOtherModuleWithOurRepoMapping(self):
+ data_path = runfiles.Create().Rlocation(
+ "our_other_module/other_module/pkg/data/data.txt"
+ )
+ with open(data_path) as f:
+ self.assertEqual(f.read().strip(), "Hello, other_module!")
+
+ def testRunfileInOtherModuleWithItsRepoMapping(self):
+ data_path = lib.GetRunfilePathWithRepoMapping()
+ with open(data_path) as f:
+ self.assertEqual(f.read().strip(), "Hello, other_module!")
+
+ def testRunfileInOtherModuleWithCurrentRepository(self):
+ data_path = lib.GetRunfilePathWithCurrentRepository()
+ with open(data_path) as f:
+ self.assertEqual(f.read().strip(), "Hello, other_module!")
+
+ def testRunfileInOtherModuleWithRlocationpath(self):
+ data_rlocationpath = os.getenv("OTHER_MODULE_DATA_RLOCATIONPATH")
+ data_path = runfiles.Create().Rlocation(data_rlocationpath)
+ with open(data_path) as f:
+ self.assertEqual(f.read().strip(), "Hello, other_module!")
+
+
+if __name__ == "__main__":
+ unittest.main()
diff --git a/gazelle/README.md b/gazelle/README.md
index 2cd38764fc..e36f3a303a 100644
--- a/gazelle/README.md
+++ b/gazelle/README.md
@@ -15,7 +15,10 @@ without using bzlmod as your dependency manager.
## Example
-We have an example of using Gazelle with Python located [here](https://github.com/bazelbuild/rules_python/tree/main/examples/build_file_generation).
+We have an example of using Gazelle with Python located [here](https://github.com/bazelbuild/rules_python/tree/main/examples/bzlmod).
+A fully-working example without using bzlmod is in [`examples/build_file_generation`](../examples/build_file_generation).
+
+The following documentation covers using bzlmod.
## Adding Gazelle to your project
@@ -40,10 +43,37 @@ bazel_dep(name = "rules_python_gazelle_plugin", version = "0.20.0")
# The following stanza defines the dependency rules_python.
bazel_dep(name = "gazelle", version = "0.30.0", repo_name = "bazel_gazelle")
-```
-You will also need to do the other usual configuration for `rules_python` in your
-`MODULE.bazel` file.
+# Import the python repositories generated by the given module extension into the scope of the current module.
+use_repo(python, "python3_9")
+use_repo(python, "python3_9_toolchains")
+
+# Register an already-defined toolchain so that Bazel can use it during toolchain resolution.
+register_toolchains(
+ "@python3_9_toolchains//:all",
+)
+
+# Use the pip extension
+pip = use_extension("@rules_python//python:extensions.bzl", "pip")
+
+# Use the extension to call the `pip_repository` rule that invokes `pip`, with `incremental` set.
+# Accepts a locked/compiled requirements file and installs the dependencies listed within.
+# Those dependencies become available in a generated `requirements.bzl` file.
+# You can instead check this `requirements.bzl` file into your repo.
+# Because this project has different requirements for windows vs other
+# operating systems, we have requirements for each.
+pip.parse(
+ name = "pip",
+ # When using gazelle you must use set the following flag
+ # in order for the generation of gazelle dependency resolution.
+ incompatible_generate_aliases = True,
+ requirements_lock = "//:requirements_lock.txt",
+ requirements_windows = "//:requirements_windows.txt",
+)
+
+# Imports the pip toolchain generated by the given module extension into the scope of the current module.
+use_repo(pip, "pip")
+```
Next, we'll fetch metadata about your Python dependencies, so that gazelle can
determine which package a given import statement comes from. This is provided
by the `modules_mapping` rule. We'll make a target for consuming this
@@ -86,6 +116,9 @@ gazelle_python_manifest(
# This should point to wherever we declare our python dependencies
# (the same as what we passed to the modules_mapping rule in WORKSPACE)
requirements = "//:requirements_lock.txt",
+ # NOTE: we can use this flag in order to make our setup compatible with
+ # bzlmod.
+ use_pip_repository_aliases = True,
)
```
@@ -112,8 +145,6 @@ gazelle(
That's it, now you can finally run `bazel run //:gazelle` anytime
you edit Python code, and it should update your `BUILD` files correctly.
-A fully-working example is in [`examples/build_file_generation`](../examples/build_file_generation).
-
## Usage
Gazelle is non-destructive.
diff --git a/python/extensions.bzl b/python/extensions.bzl
index 2b0c188554..3bcbb5023d 100644
--- a/python/extensions.bzl
+++ b/python/extensions.bzl
@@ -19,18 +19,24 @@ load("@rules_python//python/pip_install:pip_repository.bzl", "locked_requirement
load("@rules_python//python/pip_install:repositories.bzl", "pip_install_dependencies")
load("@rules_python//python/pip_install:requirements_parser.bzl", parse_requirements = "parse")
load("@rules_python//python/private:coverage_deps.bzl", "install_coverage_deps")
+load("@rules_python//python/private:toolchains_repo.bzl", "get_host_os_arch", "get_host_platform")
def _python_impl(module_ctx):
for mod in module_ctx.modules:
- for attr in mod.tags.toolchain:
+ for toolchain_attr in mod.tags.toolchain:
python_register_toolchains(
- name = attr.name,
- python_version = attr.python_version,
+ name = toolchain_attr.name,
+ python_version = toolchain_attr.python_version,
bzlmod = True,
# Toolchain registration in bzlmod is done in MODULE file
register_toolchains = False,
- register_coverage_tool = attr.configure_coverage_tool,
- ignore_root_user_error = attr.ignore_root_user_error,
+ register_coverage_tool = toolchain_attr.configure_coverage_tool,
+ ignore_root_user_error = toolchain_attr.ignore_root_user_error,
+ )
+ host_hub_name = toolchain_attr.name + "_host_interpreter"
+ _host_hub(
+ name = host_hub_name,
+ user_repo_prefix = toolchain_attr.name,
)
python = module_extension(
@@ -127,3 +133,89 @@ pip = module_extension(
"parse": tag_class(attrs = _pip_parse_ext_attrs()),
},
)
+
+# This function allows us to build the label name of a label
+# that is not passed into the current context.
+# The module_label is the key element that is passed in.
+# This value provides the root location of the labels
+# See https://bazel.build/external/extension#repository_names_and_visibility
+def _repo_mapped_label(module_label, extension_name, apparent):
+ """Construct a canonical repo label accounting for repo mapping.
+
+ Args:
+ module_label: Label object of the module hosting the extension; see
+ "_module" implicit attribute.
+ extension_name: str, name of the extension that created the repo in `apparent`.
+ apparent: str, a repo-qualified target string, but without the "@". e.g.
+ "python38_x86_linux//:python". The repo name should use the apparent
+ name used by the extension named by `ext_name` (i.e. the value of the
+ `name` arg the extension passes to repository rules)
+ """
+ return Label("@@{module}~{extension_name}~{apparent}".format(
+ module = module_label.workspace_name,
+ extension_name = extension_name,
+ apparent = apparent,
+ ))
+
+# We are doing some bazel stuff here that could use an explanation.
+# The basis of this function is that we need to create a symlink to
+# the python binary that exists in a different repo that we know is
+# setup by rules_python.
+#
+# We are building a Label like
+# @@rules_python~override~python~python3_x86_64-unknown-linux-gnu//:python
+# and then the function creates a symlink named python to that Label.
+# The tricky part is the "~override~" part can't be known in advance
+# and will change depending on how and what version of rules_python
+# is used. To figure that part out, an implicit attribute is used to
+# resolve the module's current name (see "_module" attribute)
+#
+# We are building the Label name dynamically, and can do this even
+# though the Label is not passed into this function. If we choose
+# not do this a user would have to write another 16 lines
+# of configuration code, but we are able to save them that work
+# because we know how rules_python works internally. We are using
+# functions from private:toolchains_repo.bzl which is where the repo
+# is being built. The repo name differs between host OS and platforms
+# and the functions from toolchains_repo gives us this functions that
+# information.
+def _host_hub_impl(repo_ctx):
+ # Intentionally empty; this is only intended to be used by repository
+ # rules, which don't process build file contents.
+ repo_ctx.file("BUILD.bazel", "")
+
+ # The two get_ functions we use are also utilized when building
+ # the repositories for the different interpreters.
+ (os, arch) = get_host_os_arch(repo_ctx)
+ host_platform = "{}_{}//:python".format(
+ repo_ctx.attr.user_repo_prefix,
+ get_host_platform(os, arch),
+ )
+
+ # the attribute is set to attr.label(default = "//:_"), which
+ # provides us the resolved, canonical, prefix for the module's repos.
+ # The extension_name "python" is determined by the
+ # name bound to the module_extension() call.
+ # We then have the OS and platform specific name of the python
+ # interpreter.
+ label = _repo_mapped_label(repo_ctx.attr._module, "python", host_platform)
+
+ # create the symlink in order to set the interpreter for pip.
+ repo_ctx.symlink(label, "python")
+
+# We use this rule to set the pip interpreter target when using different operating
+# systems with the same project
+_host_hub = repository_rule(
+ implementation = _host_hub_impl,
+ local = True,
+ attrs = {
+ "user_repo_prefix": attr.string(
+ mandatory = True,
+ doc = """\
+The prefix to create the repository name. Usually the name you used when you created the
+Python toolchain.
+""",
+ ),
+ "_module": attr.label(default = "//:_"),
+ },
+)
diff --git a/python/pip_install/pip_repository.bzl b/python/pip_install/pip_repository.bzl
index f58c2afddb..032f23f47a 100644
--- a/python/pip_install/pip_repository.bzl
+++ b/python/pip_install/pip_repository.bzl
@@ -559,7 +559,7 @@ of a binary found on the host's `PATH` environment variable. If no value is set
If you are using a custom python interpreter built by another repository rule,
use this attribute to specify its BUILD target. This allows pip_repository to invoke
pip using the same interpreter as your toolchain. If set, takes precedence over
-python_interpreter.
+python_interpreter. An example value: "@python3_x86_64-unknown-linux-gnu//:python".
""",
),
"quiet": attr.bool(