Open AndrewGuenther opened 3 years ago
This seems to be similar to issue #6 I think it has something to do the implementation returning all the files:
return DefaultInfo(files = depset([
declared_dir,
]))
Any updates on this? I'm trying to use go_library
openapi_generator(
name="sample-go-src",
generator="go",
spec="sample.yaml",
api_package = "com.swagger.api",
model_package = "com.swagger.model",
)
go_library(
name = "sample-go",
# srcs = glob(["**/*.go"]),
# deps = [":sample-go-src"],
srcs = [":sample-go-src"],
importpath = <omitted>,
)
Building sample-go
fails with Error in fail: Unknown source type sample-go-src
I can't depend on the generated code either in typescript. @wing328 Can you post an example of how to depend on the outputs of this?
Hi,
I tried to solve this issue but unfortunately I couldn't find a way around a major obstacle.
The generator-cli's output is not transparent, which is the reason why the output files can't be defined in advance, which is required for bazel.
In other words, I couldn't find a way to define the output files based on the yaml, since the way bazel is built, you would have to parse the yaml in advance and additionally know the implementation of the generator-cli, which defines the naming convention (eg. InlineResponse500.ts)
The workaround for me is to just generate the client manually and compiling the resulting typescript files as usual with bazel. (Which is not a solution one is looking for in this repo)
I don't really see any benefit in using this "bazel" tool. Which is a pity if you try to use open-api in a bigger project, where you need to automate these steps.
I think the only way to do this is have this be a appropriate provider and create a switch statement for every language to filter for the "library" files. I was going to write something specific for the few languages that we needed support for, but we went a completely different route.
Hi, this question was raised on stackoverflow, and some workarounds, at least for python, are discussed there: https://stackoverflow.com/a/73411230/6327445
Also, the java rules can take a source jar in srcs, so one workaround for the generated java code is to zip up the java files from the generated directory. Something like this:
WORKSPACE
:
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
http_archive(
name = "openapi_tools_generator_bazel",
sha256 = "c6e4c253f1ae0fbe4d4ded8a719f6647273141d0dc3c0cd8bb074aa7fc3c8d1c",
urls = ["https://github.com/OpenAPITools/openapi-generator-bazel/releases/download/0.1.5/openapi-tools-generator-bazel-0.1.5.tar.gz"],
)
load("@openapi_tools_generator_bazel//:defs.bzl", "openapi_tools_generator_bazel_repositories")
# You can provide any version of the CLI that has been uploaded to Maven
openapi_tools_generator_bazel_repositories(
openapi_generator_cli_version = "5.1.0",
sha256 = "62f9842f0fcd91e4afeafc33f19a7af41f2927c7472c601310cedfc72ff1bb19"
)
RULES_JVM_EXTERNAL_TAG = "4.2"
RULES_JVM_EXTERNAL_SHA = "cd1a77b7b02e8e008439ca76fd34f5b07aecb8c752961f9640dea15e9e5ba1ca"
http_archive(
name = "rules_jvm_external",
strip_prefix = "rules_jvm_external-%s" % RULES_JVM_EXTERNAL_TAG,
sha256 = RULES_JVM_EXTERNAL_SHA,
url = "https://github.com/bazelbuild/rules_jvm_external/archive/%s.zip" % RULES_JVM_EXTERNAL_TAG,
)
load("@rules_jvm_external//:repositories.bzl", "rules_jvm_external_deps")
rules_jvm_external_deps()
load("@rules_jvm_external//:setup.bzl", "rules_jvm_external_setup")
rules_jvm_external_setup()
load("@rules_jvm_external//:defs.bzl", "maven_install")
maven_install(
artifacts = [
"io.swagger:swagger-annotations:1.5.24",
"com.google.code.findbugs:jsr305:3.0.2",
"com.squareup.okhttp3:okhttp:3.14.7",
"com.squareup.okhttp3:logging-interceptor:3.14.7",
"com.google.code.gson:gson:2.8.6",
"io.gsonfire:gson-fire:1.8.4",
"org.apache.commons:commons-lang3:3.10",
"org.threeten:threetenbp:1.4.3",
"javax.annotation:javax.annotation-api:1.3.2",
],
repositories = [
"https://repo1.maven.org/maven2",
],
)
BUILD
:
load("@openapi_tools_generator_bazel//:defs.bzl", "openapi_generator")
openapi_generator(
name = "gen_petstore_java",
generator = "java",
spec = "petstore.yaml",
)
genrule(
name = "get_petstore_java_srcs",
srcs = [":gen_petstore_java"],
outs = ["petstore.srcjar"],
exec_tools = ["@bazel_tools//tools/zip:zipper"],
cmd = """
files=$$(find -L $(location :gen_petstore_java)/src/main/java -type f)
zipper_args=()
for f in $${files[@]}; do
path_in_zip="$${f/bazel-out\\/k8-fastbuild\\/bin\\/gen_petstore_java\\/src\\/main\\/java\\//}"
zipper_args+=("$$path_in_zip=$$f")
done
$(location @bazel_tools//tools/zip:zipper) c $@ $${zipper_args[@]}
""",
)
java_library(
name = "petstore_java",
srcs = [":petstore.srcjar"],
deps = [
"@maven//:io_swagger_swagger_annotations",
"@maven//:com_google_code_findbugs_jsr305",
"@maven//:com_squareup_okhttp3_okhttp",
"@maven//:com_squareup_okhttp3_logging_interceptor",
"@maven//:com_google_code_gson_gson",
"@maven//:io_gsonfire_gson_fire",
"@maven//:org_apache_commons_commons_lang3",
"@maven//:org_threeten_threetenbp",
"@maven//:javax_annotation_javax_annotation_api",
],
)
java_binary(
name = "petstore_java_main",
srcs = ["java/petstore/Main.java"],
deps = [":petstore_java"],
main_class = "petstore.Main",
)
The maven deps I got from the generated build.gradle file, but I got compilation errors like this
org/openapitools/client/ApiClient.java:818: error: no suitable method found for create(byte[],MediaType)
so something's not lined up between the generated code and the deps, but the main idea is the get_petstore_java_srcs
genrule.
+1
this makes it "impossible" to work with in a multi language repository
Hi guys,
I implemented a simple workaround. Bazel requires to know exact list of input and output files. Also Bazel does not offer anything that could be useful during an analysis (parse swagger/openapi YAML, etc.). So I forked the repo and specified additional attributes which takes generated models list. Now generation works well and I'm able to import models/invokers to java_library
target and so on.
There is possible solution from my perspective: add something like gazelle
functionality and generate bazel code manually but using a convenient tool. WDYT ?
Hi all, A simple Golang example - keeping only relevant *.go files:
load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library")
load("@openapi_tools_generator_bazel//:defs.bzl", "openapi_generator")
load("@aspect_bazel_lib//lib:copy_to_directory.bzl", "copy_to_directory")
openapi_generator(
name = "petstore",
generator = "go-gin-server",
spec = "petstore.yml",
)
copy_to_directory(
name = "petstore.go",
srcs = [":petstore"],
exclude_srcs_patterns = ["**/main.go"],
include_srcs_patterns = ["**/*.go"],
)
go_library(
name = "server_lib",
srcs = [":petstore.go"],
importpath = "petstore",
visibility = ["//visibility:private"],
deps = ["@com_github_gin_gonic_gin//:go_default_library"],
)
go_binary(
name = "server",
srcs = ["main.go"],
visibility = ["//visibility:public"],
deps = [":server_lib"],
)
The trick is the petstore.go
folder name to fool rules_go that this is valid input.
NOTE: you need your own main.go file:
package main
import (
"log"
sw "petstore"
)
func main() {
log.Printf("Server started")
router := sw.NewRouter()
log.Fatal(router.Run(":8080"))
}
Inspired from C++ example here: https://stackoverflow.com/questions/48417712/how-to-build-static-library-from-the-generated-source-files-using-bazel-build
Using copy_to_directory and including the result as data
instead of srcs
seems to have worked for us:
openapi_generator(
name = "xcover_client_codegen",
additional_properties = {
"packageName": "xcover_python_client",
},
generator = "python",
spec = "swagger.json",
)
copy_to_directory(
name = "xcover_python_client",
srcs = [":xcover_client_codegen"],
include_srcs_patterns = ["xcover_client_codegen/xcover_python_client/**"],
replace_prefixes = {
"xcover_client_codegen/xcover_python_client": "",
},
)
py_library(
name = "xcover_python_client_lib",
# Output from openapi_generator is a directory and not a list of files, so we
# include it as data instead of as srcs, in order to prevent Bazel from emitting
# a warning that no .py files were found.
data = [
":xcover_python_client",
],
imports = ["."],
visibility = ["//visibility:public"],
deps = [
requirement("python_dateutil"),
requirement("urllib3"),
],
)
But really the OpenAPI generator rules should probably be rewritten as repository rules... (https://bazel.build/extending/repo)
Here's a solution to the problem that doesn't use copy_to_directory
. It's similar to @guillaumep's solution, but uses the imports
attribute of py_library
.
openapi_generator(
name = "my_client",
additional_properties = {
"packageName": "my_client",
},
generator = "python",
spec = "swagger.json",
)
py_library(
name = "my_client_py",
data = [":my_client"],
imports = ["./my_client"],
visibility = ["//visibility:public"],
deps = [
requirement("python_dateutil"),
requirement("urllib3"),
],
)
I have seen some issues while running the go-gin-server generator, has anyone been able to use the go-server generator for go successfully?
If we try to use the copy_to_directory(), the go_library() panics with unused dep statements.
I have seen some issues while running the go-gin-server generator, has anyone been able to use the go-server generator for go successfully?
If we try to use the copy_to_directory(), the go_library() panics with unused dep statements.
This would be a bug in the code generation and should be fixed as part of the main project. I am able to generate code with the go-server generator in my project.
Make sure you also use the latest version of the cli.
Hopefully I'm missing something simple, but so far as I can tell, when using
openapi_generator
it doesn't appear to declare and outputs. So in my use case, I am generating a Python client which will then be depended on by apy_library
. This doesn't appear to work.I'd appreciate if someone could provide an example where they depend on a generated client and how that gets wired up. Thanks!
Some additional context on what I've tried:
The above will claim that the
my_api_client_src
target doesn't contain any python files, so I've tried depending on it as data instead and making a dedicatedpy_library
target for it, but that doesn't appear to work either.