blob: 09c66f2c3508dff8dcb3a8f376e13a285ed0b3b6 [file] [log] [blame]
// Copyright 2017 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.
package com.google.devtools.build.lib.packages.util;
import static com.google.devtools.build.lib.rules.python.PythonTestUtils.getPyLoad;
import com.google.devtools.build.lib.rules.proto.ProtoConstants;
import com.google.devtools.build.lib.testutil.TestConstants;
import java.io.IOException;
/**
* Creates mock BUILD files required for the proto_library rule.
*/
public final class MockProtoSupport {
private MockProtoSupport() {
throw new UnsupportedOperationException();
}
/**
* Setup the support for building proto_library. You additionally need to setup support for each
* of the languages used in the specific test.
*
* <p>Cannot be used for integration tests that actually need to run protoc.
*/
public static void setup(MockToolsConfig config) throws IOException {
createNetProto2(config);
setupWorkspace(config);
registerProtoToolchain(config);
}
private static void registerProtoToolchain(MockToolsConfig config) throws IOException {
config.append("WORKSPACE", "register_toolchains('tools/proto/toolchains:all')");
config.create(
"tools/proto/toolchains/BUILD",
TestConstants.LOAD_PROTO_TOOLCHAIN,
TestConstants.LOAD_PROTO_LANG_TOOLCHAIN,
"proto_toolchain(name = 'protoc_sources',"
+ "proto_compiler = '"
+ ProtoConstants.DEFAULT_PROTOC_LABEL
+ "')");
}
/** Create a dummy "net/proto2 compiler and proto APIs for all languages and versions. */
private static void createNetProto2(MockToolsConfig config) throws IOException {
config.create(
"net/proto2/compiler/public/BUILD",
"""
package(default_visibility = ["//visibility:public"])
sh_binary(
name = "protocol_compiler",
srcs = ["protocol_compiler.sh"],
)
""");
if (config.isRealFileSystem()) {
// when using a "real" file system, import the jars and link to ensure compilation
config.create(
"java/com/google/io/protocol/BUILD",
"""
package(default_visibility = ["//visibility:public"])
java_import(
name = "protocol",
jars = ["protocol.jar"],
)
""");
config.create(
"java/com/google/io/protocol2/BUILD",
"""
package(default_visibility = ["//visibility:public"])
java_import(
name = "protocol2",
jars = ["protocol2.jar"],
)
""");
config.linkTool("javatests/com/google/devtools/build/lib/prepackaged_protocol_deploy.jar",
"java/com/google/io/protocol/protocol.jar");
config.linkTool("javatests/com/google/devtools/build/lib/prepackaged_protocol2_deploy.jar",
"java/com/google/io/protocol2/protocol2.jar");
} else {
// for "fake" file systems, provide stub rules. This is different from the "real" filesystem,
// as it produces the interface jars that the production environment has.
config.create(
"java/com/google/io/protocol/BUILD",
"""
package(default_visibility = ["//visibility:public"])
java_library(
name = "protocol",
srcs = ["Protocol.java"],
)
""");
config.create("java/com/google/io/protocol/Protocol.java");
config.create(
"java/com/google/io/protocol2/BUILD",
"""
package(default_visibility = ["//visibility:public"])
java_library(
name = "protocol2",
srcs = ["Protocol2.java"],
)
""");
config.create("java/com/google/io/protocol/Protocol2.java");
}
config.create(
"java/com/google/protobuf/BUILD",
"""
package(default_visibility = ["//visibility:public"])
proto_library(
name = "protobuf_proto_sources",
srcs = [],
)
""");
// RPC generator plugins.
config.create(
"net/rpc/compiler/BUILD",
"""
package(default_visibility = ["//visibility:public"])
cc_binary(
name = "proto2_py_plugin",
srcs = ["proto2_py_plugin.cc"],
)
cc_binary(
name = "proto2_java_plugin",
srcs = ["proto2_java_plugin.cc"],
)
""");
config.create(
"net/grpc/compiler/BUILD",
"""
package(default_visibility = ["//visibility:public"])
cc_binary(
name = "composite_cc_plugin",
srcs = ["composite_cc_plugin.cc"],
)
""");
// Fake targets for proto API libs of all languages and versions.
config.create(
"net/proto2/public/BUILD",
"""
package(default_visibility = ["//visibility:public"])
cc_library(
name = "cc_proto_library_blaze_internal_deps",
srcs = ["cc_proto_library_blaze_internal_deps.cc"],
)
""");
config.create(
"net/proto2/python/public/BUILD",
getPyLoad("py_library"),
"package(default_visibility=['//visibility:public'])",
"py_library(name = 'public',",
" srcs = [ 'pyproto2.py' ])");
config.create(
"net/proto2/bridge/public/BUILD",
"""
package(default_visibility = ["//visibility:public"])
cc_library(
name = "compatibility_mode_support",
srcs = ["compatibility.cc"],
)
""");
config.create(
"net/proto/BUILD",
getPyLoad("py_library"),
"package(default_visibility=['//visibility:public'])",
"cc_library(name = 'proto',",
" srcs = [ 'proto.cc' ])",
"py_library(name = 'pyproto',",
" srcs = [ 'pyproto.py' ])");
config.create(
"net/proto/python/BUILD",
getPyLoad("py_library"),
"package(default_visibility=['//visibility:public'])",
"py_library(name = 'proto1',",
" srcs = [ 'pyproto.py' ])");
config.create(
"net/rpc/BUILD",
"""
package(default_visibility = ["//visibility:public"])
cc_library(name = "stubby12_proto_rpc_libs")
""");
config.create(
"net/rpc4/public/core/BUILD",
"""
package(default_visibility = ["//visibility:public"])
cc_library(name = "stubby4_rpc_libs")
""");
config.create(
"net/grpc/BUILD",
"""
package(default_visibility = ["//visibility:public"])
cc_library(
name = "grpc++_codegen_lib",
srcs = ["grpc++_codegen_lib.cc"],
)
""");
config.create(
"net/rpc/python/BUILD",
getPyLoad("py_library"),
"py_library(name = 'proto_python_api_2_stub',",
" srcs = [ 'test_only_prefix_proto_python_api_2_stub.py' ],",
" visibility = ['//visibility:public'],",
")");
config.create(
"java/com/google/net/rpc/BUILD",
"""
package(default_visibility = ["//visibility:public"])
java_library(
name = "rpc",
srcs = ["Rpc.java"],
)
java_library(
name = "rpc_noloas_internal",
srcs = ["RpcNoloas.java"],
)
""");
config.create(
"java/com/google/net/rpc3/BUILD",
"""
package(default_visibility = ["//visibility:public"])
java_library(
name = "rpc3_proto_runtime",
srcs = ["Rpc3.java"],
deps = [":rpc3_noloas_internal"],
)
java_library(
name = "rpc3_noloas_internal",
srcs = ["Rpc3Noloas.java"],
deps = ["//java/com/google/net/rpc:rpc_noloas_internal"],
)
""");
config.create(
"net/proto2/proto/BUILD",
TestConstants.LOAD_PROTO_LIBRARY,
"package(default_visibility=['//visibility:public'])",
"genrule(name = 'go_internal_bootstrap_hack',",
" srcs = [ 'descriptor.pb.go-prebuilt' ],",
" outs = [ 'descriptor.pb.go' ],",
" cmd = '')",
"proto_library(name='descriptor',",
" srcs=['descriptor.proto'])");
config.create(
"net/proto2/go/BUILD",
"""
package(default_visibility = ["//visibility:public"])
go_library(
name = "protodeps",
srcs = ["protodeps.go"],
)
""");
config.create(
"net/proto2/compiler/go/BUILD",
"""
package(default_visibility = ["//visibility:public"])
go_binary(
name = "protoc-gen-go",
srcs = ["main.go"],
)
""");
config.create(
"net/rpc/go/BUILD",
"""
package(default_visibility = ["//visibility:public"])
go_library(
name = "rpc",
srcs = ["rpc.go"],
)
""");
config.create(
"go/context/BUILD",
"""
package(default_visibility = ["//visibility:public"])
go_library(
name = "context",
srcs = ["context.go"],
)
""");
// TODO(b/77901188): remove once j_p_l migration is complete
config.create(
"third_party/java/jsr250_annotations/BUILD",
"""
package(default_visibility = ["//visibility:public"])
licenses(["notice"])
java_library(
name = "jsr250_source_annotations",
srcs = ["Generated.java"],
)
""");
config.create(
"third_party/golang/grpc/metadata/BUILD",
"""
package(default_visibility = ["//visibility:public"])
licenses(["notice"])
go_library(
name = "metadata",
srcs = ["metadata.go"],
)
""");
}
public static void setupWorkspace(MockToolsConfig config) throws IOException {
if (TestConstants.PRODUCT_NAME.equals("bazel")) {
config.append(
"WORKSPACE",
"local_repository(",
" name = 'rules_proto',",
" path = 'third_party/bazel_rules/rules_proto',",
")");
}
config.create(
"third_party/bazel_rules/rules_proto/proto/BUILD",
"""
licenses(["notice"])
toolchain_type(
name = "toolchain_type",
visibility = ["//visibility:public"],
)
""");
config.create(
"third_party/bazel_rules/rules_proto/proto/defs.bzl",
"""
load(":proto_lang_toolchain.bzl", _proto_lang_toolchain = "proto_lang_toolchain")
def _add_tags(kargs):
if "tags" in kargs:
kargs["tags"] += ["__PROTO_RULES_MIGRATION_DO_NOT_USE_WILL_BREAK__"]
else:
kargs["tags"] = ["__PROTO_RULES_MIGRATION_DO_NOT_USE_WILL_BREAK__"]
return kargs
def proto_library(**kargs):
native.proto_library(**_add_tags(kargs))
def proto_lang_toolchain(**kargs):
_proto_lang_toolchain(**_add_tags(kargs))
""");
config.create(
"third_party/bazel_rules/rules_proto/proto/proto_toolchain.bzl",
"load(':proto_toolchain_rule.bzl', _proto_toolchain_rule = 'proto_toolchain')",
"def proto_toolchain(*, name, proto_compiler, exec_compatible_with = []):",
" _proto_toolchain_rule(name = name, proto_compiler = proto_compiler)",
" native.toolchain(",
" name = name + '_toolchain',",
" toolchain_type = '" + TestConstants.PROTO_TOOLCHAIN + "',",
" exec_compatible_with = exec_compatible_with,",
" target_compatible_with = [],",
" toolchain = name,",
" )");
config.create(
"third_party/bazel_rules/rules_proto/proto/proto_toolchain_rule.bzl",
"""
ProtoLangToolchainInfo = proto_common_do_not_use.ProtoLangToolchainInfo
def _impl(ctx):
return [
DefaultInfo(
files = depset(),
runfiles = ctx.runfiles(),
),
platform_common.ToolchainInfo(
proto = ProtoLangToolchainInfo(
out_replacement_format_flag = ctx.attr.command_line,
output_files = ctx.attr.output_files,
plugin = None,
runtime = None,
proto_compiler = ctx.attr.proto_compiler.files_to_run,
protoc_opts = ctx.fragments.proto.experimental_protoc_opts,
progress_message = ctx.attr.progress_message,
mnemonic = ctx.attr.mnemonic,
allowlist_different_package = None,
toolchain_type =
"//third_party/bazel_rules/rules_proto/proto:toolchain_type",
),
),
]
proto_toolchain = rule(
_impl,
attrs = {
"progress_message": attr.string(default =
"Generating Descriptor Set proto_library %{label}"),
"mnemonic": attr.string(default = "GenProtoDescriptorSet"),
"command_line": attr.string(default = "--descriptor_set_out=%s"),
"output_files": attr.string(
values = ["single", "multiple", "legacy"],
default = "single",
),
"proto_compiler": attr.label(
cfg = "exec",
executable = True,
allow_files = True,
),
},
provides = [platform_common.ToolchainInfo],
fragments = ["proto"],
)
""");
config.create(
"third_party/bazel_rules/rules_proto/proto/proto_lang_toolchain.bzl",
"""
def proto_lang_toolchain(
*,
name,
toolchain_type = None,
exec_compatible_with = [],
target_compatible_with = [],
**attrs):
native.proto_lang_toolchain(name = name, toolchain_type = toolchain_type, **attrs)
if toolchain_type:
native.toolchain(
name = name + "_toolchain",
toolchain_type = toolchain_type,
exec_compatible_with = exec_compatible_with,
target_compatible_with = target_compatible_with,
toolchain = name,
)
""");
}
}