load("@rules_proto//proto:defs.bzl", "proto_library") load("@rules_rust//rust:defs.bzl", "rust_binary", "rust_library", "rust_test") # Prost generator binary for converting proto files to Rust code rust_binary( name = "prost_generator", srcs = ["prost_generator.rs"], edition = "2021", visibility = ["//visibility:public"], deps = [ "@crates//:prost", "@crates//:prost-build", "@crates//:schemars", "@crates//:serde", "@crates//:tempfile", ], ) # DataBuild library using generated prost code rust_library( name = "databuild", srcs = [ "event_log/delta.rs", "event_log/mock.rs", "event_log/mod.rs", "event_log/postgres.rs", "event_log/sqlite.rs", "event_log/stdout.rs", "event_log/writer.rs", "format_consistency_test.rs", "lib.rs", "log_access.rs", "log_collector.rs", "mermaid_utils.rs", "metric_templates.rs", "metrics_aggregator.rs", "orchestration/error.rs", "orchestration/events.rs", "orchestration/mod.rs", "repositories/builds/mod.rs", "repositories/jobs/mod.rs", "repositories/mod.rs", "repositories/partitions/mod.rs", "repositories/tasks/mod.rs", "service/handlers.rs", "service/mod.rs", "status_utils.rs", ":generate_databuild_rust", ], edition = "2021", proc_macro_deps = [ "@crates//:async-trait", ], visibility = ["//visibility:public"], deps = [ "@crates//:aide", "@crates//:axum", "@crates//:axum-jsonschema", "@crates//:chrono", "@crates//:deltalake", "@crates//:log", "@crates//:parquet", "@crates//:prost", "@crates//:prost-types", "@crates//:rusqlite", "@crates//:schemars", "@crates//:serde", "@crates//:serde_json", "@crates//:thiserror", "@crates//:tokio", "@crates//:uuid", ], ) # OpenAPI Spec Generator binary (no dashboard dependency) # No need to run this manually - it will automatically generate source and it will be used in # the related targets (e.g. //databuild/client:extract_openapi_spec) rust_binary( name = "openapi_spec_generator", srcs = ["service/openapi_spec_generator.rs"], edition = "2021", visibility = ["//visibility:public"], deps = [ ":databuild", "@crates//:log", "@crates//:serde_json", "@crates//:tokio", ], ) # Build Graph Service binary rust_binary( name = "build_graph_service", srcs = ["service/main.rs"], data = ["//databuild/dashboard:dist"], edition = "2021", visibility = ["//visibility:public"], deps = [ ":databuild", "@crates//:aide", "@crates//:axum", "@crates//:axum-jsonschema", "@crates//:clap", "@crates//:hyper", "@crates//:log", "@crates//:schemars", "@crates//:serde", "@crates//:serde_json", "@crates//:simple_logger", "@crates//:tokio", "@crates//:tower", "@crates//:tower-http", "@crates//:uuid", ], ) # Test for orchestration module rust_test( name = "orchestration_test", crate = ":databuild", edition = "2021", deps = [ "@crates//:tempfile", "@crates//:tokio", ], ) # Legacy filegroup for backwards compatibility filegroup( name = "proto", srcs = ["databuild.proto"], visibility = ["//visibility:public"], ) # Generate Rust code for databuild proto genrule( name = "generate_databuild_rust", srcs = [ "databuild.proto", ], outs = ["databuild.rs"], cmd = "PROTOC=$(location @com_google_protobuf//:protoc) $(location :prost_generator) $(location databuild.proto) /dev/null $@", tools = [ "//databuild:prost_generator", "@com_google_protobuf//:protoc", ], visibility = ["//visibility:public"], ) # Python proto dataclass codegen py_binary( name = "protoc-gen-python_betterproto2", srcs = ["proto_wrapper.py"], main = "proto_wrapper.py", deps = [ "@databuild_pypi//betterproto2_compiler", ], ) genrule( name = "py_protobuf_dataclasses", srcs = [ "databuild.proto", ], outs = [ "py_proto_out/__init__.py", "py_proto_out/databuild/__init__.py", "py_proto_out/databuild/v1/__init__.py", "py_proto_out/message_pool.py", ], cmd = """ mkdir -p $(@D) export PATH=$$PATH:$$(dirname $(location :protoc-gen-python_betterproto2)) export PATH=$$PATH:$$(dirname $(location //:ruff_binary)) $(location @com_google_protobuf//:protoc) --python_betterproto2_out=$(@D) $(location databuild.proto) mkdir -p $(@D)/py_proto_out/databuild/v1 # Make grpc import conditional to avoid binary compatibility issues during DSL generation cat > /tmp/fix_grpc_import.py << 'EOF' import sys with open(sys.argv[1], 'r') as f: content = f.read() # Replace the grpc import with conditional import content = content.replace( 'import grpc', '''try: import grpc _GRPC_AVAILABLE = True except ImportError: grpc = None _GRPC_AVAILABLE = False''' ) # Replace service constructors to check grpc availability content = content.replace( 'def __init__(self, channel: grpc.Channel):', '''def __init__(self, channel): if not _GRPC_AVAILABLE: raise RuntimeError("grpc not available - required for service classes")''' ) with open(sys.argv[1], 'w') as f: f.write(content) EOF python3 /tmp/fix_grpc_import.py $(@D)/databuild/v1/__init__.py cp $(@D)/databuild/__init__.py $(@D)/py_proto_out/__init__.py cp $(@D)/databuild/__init__.py $(@D)/py_proto_out/databuild/__init__.py cp $(@D)/databuild/v1/__init__.py $(@D)/py_proto_out/databuild/v1/__init__.py cp $(@D)/message_pool.py $(@D)/py_proto_out/message_pool.py """, tools = [ ":protoc-gen-python_betterproto2", "//:ruff_binary", "@com_google_protobuf//:protoc", "@databuild_pypi//betterproto2_compiler", ], ) py_library( name = "py_proto", srcs = [ "proto.py", ":py_protobuf_dataclasses", ], visibility = ["//visibility:public"], deps = [ "@databuild_pypi//betterproto2_compiler", "@databuild_pypi//grpcio", "@databuild_pypi//pytest", ], )