Skip to content

Commit

Permalink
feat: add api for analysis-phase code
Browse files Browse the repository at this point in the history
  • Loading branch information
rickeylev committed Sep 25, 2024
1 parent b326848 commit 8722be3
Show file tree
Hide file tree
Showing 8 changed files with 168 additions and 0 deletions.
1 change: 1 addition & 0 deletions docs/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ sphinx_stardocs(
"//python:py_runtime_info_bzl",
"//python:py_test_bzl",
"//python:repositories_bzl",
"//python/api:api_bzl",
"//python/cc:py_cc_toolchain_bzl",
"//python/cc:py_cc_toolchain_info_bzl",
"//python/entry_points:py_console_script_binary_bzl",
Expand Down
1 change: 1 addition & 0 deletions python/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ licenses(["notice"])
filegroup(
name = "distribution",
srcs = glob(["**"]) + [
"//python/api:distribution",
"//python/cc:distribution",
"//python/config_settings:distribution",
"//python/constraints:distribution",
Expand Down
27 changes: 27 additions & 0 deletions python/api/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Copyright 2024 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.

load("@bazel_skylib//:bzl_library.bzl", "bzl_library")

bzl_library(
name = "api_bzl",
srcs = ["api.bzl"],
visibility = ["//visibility:public"],
deps = ["//python/private/api:api_bzl"],
)

filegroup(
name = "distribution",
srcs = glob(["**"]),
)
5 changes: 5 additions & 0 deletions python/api/api.bzl
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
"""Public, analysis phase APIs for Python rules."""

load("//python/private/api:api.bzl", _py_common = "py_common")

py_common = _py_common
Empty file added python/private/api.bzl
Empty file.
43 changes: 43 additions & 0 deletions python/private/api/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# Copyright 2024 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.

load("@bazel_skylib//:bzl_library.bzl", "bzl_library")
load(":py_common_api.bzl", "py_common_api")

package(
default_visibility = ["//:__subpackages__"],
)

py_common_api(
name = "py_common_api",
# NOTE: Not actually public. Implicit dependency of public rules.
visibility = ["//visibility:public"],
)

bzl_library(
name = "api_bzl",
srcs = ["api.bzl"],
deps = [
"//python/private:py_info_bzl",
],
)

bzl_library(
name = "py_common_api_bzl",
srcs = ["py_common_api.bzl"],
deps = [
":api_bzl",
"//python/private:py_info_bzl",
],
)
41 changes: 41 additions & 0 deletions python/private/api/api.bzl
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# Copyright 2024 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.
"""Implementation of py_api."""

_PY_COMMON_API_LABEL = Label("//python/private/api:py_common_api")

ApiImplInfo = provider(
fields = {
"impl": """
:type: struct
The implementation of the API being provided.
""",
},
)

def _py_common_get(ctx):
# A generic provider is used to decouple the API implementations from
# the loading phase of the rules using an implementation.
return ctx.attr._py_common_api[ApiImplInfo].impl

py_common = struct(
get = _py_common_get,
API_ATTRS = {
"_py_common_api": attr.label(
default = _PY_COMMON_API_LABEL,
providers = [ApiImplInfo],
),
},
)
50 changes: 50 additions & 0 deletions python/private/api/py_common_api.bzl
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# Copyright 2024 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.
"""Implementation of py_api."""

load("//python/private:py_info.bzl", "PyInfoBuilder")
load("//python/private/api:api.bzl", "ApiImplInfo")

PyCommonApiInfo = provider(
doc = """
Analysis-time APIs for rule implementations.
""",
fields = {
"merge_py_infos": """
:type: callable
""",
"PyInfoBuilder": """
:type: callable
""",
},
)

def _py_common_api_impl(ctx):
_ = ctx # @unused
return [ApiImplInfo(impl = PyCommonApiInfo(
merge_py_infos = _merge_py_infos,
PyInfoBuilder = PyInfoBuilder,
))]

py_common_api = rule(
implementation = _py_common_api_impl,
)

def _merge_py_infos(transitive, *, direct = None):
builder = PyInfoBuilder()
if direct:
builder.direct_pyc_files.add(direct.direct_pyc_files)
builder.merge(direct)
builder.merge_all(transitive)
return builder.build()

0 comments on commit 8722be3

Please sign in to comment.