8000 Support gazelle plugin when using bzlmod by aignas · Pull Request #961 · bazel-contrib/rules_python · GitHub
[go: up one dir, main page]

Skip to content

Support gazelle plugin when using bzlmod #961

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 8 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .bazelrc
Original file line number Diff line number Diff line change
Expand Up @@ -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/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/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/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/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,examples/bzlmod_build_file_generation,examples/bzlmod_build_file_generation/get_url,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/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_build_file_generation,examples/bzlmod_build_file_generation/get_url,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/relative_requirements,tests/compile_pip_requirements,tests/pip_repository_entry_points,tests/pip_deps

test --test_output=errors

Expand Down
19 changes: 19 additions & 0 deletions MODULE.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,22 @@ use_repo(
"pypi__wheel",
"pypi__zipp",
)

bazel_dep(name = "rules_go", repo_name = "io_bazel_rules_go", version = "0.35.0")
bazel_dep(name = "gazelle", repo_name = "bazel_gazelle", version = "0.28.0")

go_deps = use_extension("@bazel_gazelle//:extensions.bzl", "go_deps")

go_deps.from_file(go_mod = "//:go.mod")

use_repo(
go_deps,
"com_github_bazelbuild_bazel_gazelle",
"com_github_bazelbuild_buildtools",
"com_github_bazelbuild_rules_go",
"com_github_bmatcuk_doublestar",
"com_github_emirpasic_gods",
"com_github_ghodss_yaml",
"com_github_google_uuid",
"in_gopkg_yaml_v2",
)
6 changes: 6 additions & 0 deletions examples/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -53,3 +53,9 @@ bazel_integration_test(
bzlmod = True,
override_bazel_version = "6.0.0",
)

bazel_integration_test(
name = "bzlmod_build_file_generation_example",
bzlmod = True,
override_bazel_version = "6.0.0",
)
7 changes: 7 additions & 0 deletions examples/bzlmod_build_file_generation/.bazelrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
common --experimental_enable_bzlmod

test --test_output=errors

# Windows requires these for multi-python support:
build --enable_runfiles
startup --windows_enable_symlinks
1 change: 1 addition & 0 deletions examples/bzlmod_build_file_generation/.bazelversion
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
6.0.0
1 change: 1 addition & 0 deletions examples/bzlmod_build_file_generation/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
bazel-*
106 changes: 106 additions & 0 deletions examples/bzlmod_build_file_generation/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
# 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.
load("@gazelle//:def.bzl", "gazelle")
load("@pip//:requirements.bzl", "all_whl_requirements")
load("@rules_python//gazelle:def.bzl", "GAZELLE_PYTHON_RUNTIME_DEPS")
load("@rules_python//gazelle/manifest:defs.bzl", "gazelle_python_manifest")
load("@rules_python//gazelle/modules_mapping:def.bzl", "modules_mapping")
load("@rules_python//python:defs.bzl", "py_binary", "py_library", "py_test")
load("@rules_python//python:pip.bzl", "compile_pip_requirements")

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.
# To see what this rule does, try `bazel run @modules_map//:print`
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
gazelle_python_manifest(
name = "gazelle_python_manifest",
modules_mapping = ":modules_map",
pip_repository_name = "pip",
requirements = "//:requirements_lock.txt",
)

# 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
gazelle(
name = "gazelle",
data = GAZELLE_PYTHON_RUNTIME_DEPS,
gazelle = "@rules_python//gazelle:gazelle_python_binary",
)

# Using bzlmod we also need to set a different pip repository naming convention:
#
# gazelle:python_pip_repo_naming_convention $repo_name$
# gazelle:python_pip_target_naming_convention $distribution_name$_pkg

# This rule is auto-generated and managed by Gazelle,
# because it found the __init__.py file in this folder.
# See: https://bazel.build/reference/be/python#py_library
py_library(
name = "bzlmod_build_file_generation",
srcs = ["__init__.py"],
visibility = ["//:__subpackages__"],
deps = [
"//random_number_generator",
"@pip//:flask_pkg",
],
)

# A py_binary is an executable Python program consisting of a collection of .py source files.
# See: https://bazel.build/reference/be/python#py_binary
#
# This rule is auto-generated and managed by Gazelle,
# because it found the __main__.py file in this folder.
# This rule creates a target named //:bzlmod_build_file_generation_bin and you can use
# bazel to run the target:
# `bazel run //:bzlmod_build_file_generation_bin`
py_binary(
name = "bzlmod_build_file_generation_bin",
srcs = ["__main__.py"],
main = "__main__.py",
visibility = ["//:__subpackages__"],
deps = [":bzlmod_build_file_generation"],
)

# A py_test is a Python unit test.
# See: https://bazel.build/reference/be/python#py_test
#
< F438 /td> # This rule is auto-generated and managed by Gazelle,
# because it found the __test__.py file in this folder.
# This rule creates a target named //:bzlmod_build_file_generation_test and you can use
# bazel to run the target:
# `bazel test //:bzlmod_build_file_generation_test`
py_test(
name = "bzlmod_build_file_generation_test",
srcs = ["__test__.py"],
main = "__test__.py",
deps = [":bzlmod_build_file_generation"],
)
37 changes: 37 additions & 0 deletions examples/bzlmod_build_file_generation/MODULE.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
module(
name = "example_bzlmod",
compatibility_level = 1,
version = "0.0.0",
)

bazel_dep(name = "rules_python", version = "0.0.0")

local_path_override(
module_name = "rules_python",
path = "../..",
)

python = use_extension("@rules_python//python:extensions.bzl", "python")

python.toolchain(
name = "python3_9",
python_version = "3.9",
)

use_repo(python, "python3_9_toolchains")

register_toolchains(
"@python3_9_toolchains//:all",
)

pip = use_extension("@rules_python//python:extensions.bzl", "pip")

pip.parse(
name = "pip",
requirements_lock = "//:requirements_lock.txt",
requirements_windows = "//:requirements_windows.txt",
)

use_repo(pip, "pip")

bazel_dep(name = "gazelle", version = "0.28.0")
20 changes: 20 additions & 0 deletions examples/bzlmod_build_file_generation/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Build file generation with Gazelle

This example shows a project that has Gazelle 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
```

As a demo, try creating a `__main__.py` file in this directory, then
re-run that gazelle command. You'll see that a `py_binary` target
is created in the `BUILD` file.

Or, try importing the `requests` library in `__init__.py`.
You'll see that `deps = ["@pip//pypi__requests"]` is automatically
added to the `py_library` target in the `BUILD` file.

For more information on the behavior of the rules_python gazelle extension,
see the README.md file in the /gazelle folder.
2 changes: 2 additions & 0 deletions examples/bzlmod_build_file_generation/WORKSPACE
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Empty file indicating the root of a Bazel workspace.
# Dependencies and setup are in MODULE.bazel.
30 changes: 30 additions & 0 deletions examples/bzlmod_build_file_generation/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Copyright 2022 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 flask import Flask, jsonify
from random_number_generator import generate_random_number

app = Flask(__name__)


@app.route("/random-number", methods=["GET"])
def get_random_number():
return jsonify({"number": generate_random_number.generate_random_number()})


"""Start the python web server"""


def main():
app.run()
18 changes: 18 additions & 0 deletions examples/bzlmod_build_file_generation/__main__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Copyright 2022 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 __init__ import main

if __name__ == "__main__":
main()
31 changes: 31 additions & 0 deletions examples/bzlmod_build_file_generation/__test__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# Copyright 2022 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 __init__ import app


class TestServer(unittest.TestCase):
def setUp(self):
self.app = app.test_client()

def test_get_random_number(self):
response = self.app.get("/random-number")
self.assertEqual(response.status_code, 200)
self.assertIn("number", response.json)


if __name__ == "__main__":
unittest.main()
Loading
0