Browse Source

Detect correct go protobuf import path

Andy Hochhaus 3 years ago
parent
commit
23723868d1
4 changed files with 67 additions and 22 deletions
  1. 2 0
      README.md
  2. 38 12
      defs.bzl
  3. 14 6
      generator/generator.go
  4. 13 4
      generator/gowriter.go

+ 2 - 0
README.md

@@ -70,6 +70,8 @@ TODO(hochhaus)
 - Convert go generation to use go/ast and go/printer
 - Convert js generation to use otto/ast and printer?
 - Ensure works with standard go tools (without bazel)
+- Document soyotto usage with bazel (rules_closure, rules_go) vs standard go
+  tooling
 
 ### Beta
 

+ 38 - 12
defs.bzl

@@ -20,13 +20,47 @@ load(
 )
 load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_prefix")
 
+def _impl(ctx):
+  args = [
+      "--js_out=%s" % ctx.outputs.genjs.path,
+      "--go_out=%s" % ctx.outputs.gengo.path,
+  ]
+  imports = []
+  for dep in ctx.attr.go_deps:
+    for val in dep.transitive_go_importmap.values():
+      imports.append(val)
+  if len(imports) > 0:
+    args += ["--imports=%s" % ",".join(imports)]
+  args += [src.path for src in ctx.files.srcs]
+  ctx.action(
+      inputs = ctx.files.srcs,
+      outputs = [ctx.outputs.genjs, ctx.outputs.gengo],
+      executable = ctx.executable._genbin,
+      arguments = args,
+  )
+
+soyotto_bindings = rule(
+    implementation = _impl,
+    output_to_genfiles = True,
+    attrs = {
+        "srcs": attr.label_list(allow_files=True),
+        "go_deps": attr.label_list(),
+
+        # internal only
+        "_genbin": attr.label(default=Label("//generator"), executable=True),
+    },
+    outputs = {
+        "genjs": "%{name}.js",
+        "gengo": "%{name}.go",
+    }
+)
+
 def soyotto_idom_template(
     name,
     srcs,
     css = None,
     js_deps = [],
-    go_deps = [],
-    genbin = str(Label("//generator"))):
+    go_deps = []):
   closure_js_template_library(
       name = name,
       srcs = srcs,
@@ -40,18 +74,10 @@ def soyotto_idom_template(
       deps = js_deps,
   )
 
-  cmd = [
-      "$(location %s)" % genbin,
-      "--js_out=$(location %s_noidom_gen.js)" % name,
-      "--go_out=$(location %s_noidom_gen.go)" % name,
-  ]
-  cmd += ["$(location " + src + ")" for src in srcs]
-  native.genrule(
+  soyotto_bindings(
       name = name + "_noidom_gen",
       srcs = srcs,
-      outs = [name + "_noidom_gen.js", name + "_noidom_gen.go"],
-      cmd = " ".join(cmd),
-      tools = [genbin],
+      go_deps = go_deps,
   )
 
   closure_js_library(

+ 14 - 6
generator/generator.go

@@ -20,14 +20,14 @@ import (
 	"strings"
 )
 
-func parseCommandLine() ([]string, string, string) {
+func parseCommandLine() ([]string, string, string, []string) {
 	if len(os.Args) == 1 {
 		fmt.Printf("exportgen [--js_out=<file>] [--go_out=<file>] soy_files...\n")
 		os.Exit(1)
 	}
-	srcs := []string{}
+	srcs, imports := []string{}, []string{}
 	jsOut, goOut := "", ""
-	nextArgJSOut, nextArgGoOut := false, false
+	nextArgJSOut, nextArgGoOut, nextArgImports := false, false, false
 	for _, arg := range os.Args[1:] {
 		switch {
 		case nextArgJSOut:
@@ -36,14 +36,22 @@ func parseCommandLine() ([]string, string, string) {
 		case nextArgGoOut:
 			nextArgGoOut = false
 			goOut = arg
+		case nextArgImports:
+			nextArgImports = false
+			imports = strings.Split(arg, ",")
 		case arg == "--js_out":
 			nextArgJSOut = true
 		case arg == "--go_out":
 			nextArgGoOut = true
+		case arg == "--imports":
+			nextArgImports = true
 		case strings.HasPrefix(arg, "--js_out="):
 			jsOut = strings.SplitN(arg, "=", 2)[1]
 		case strings.HasPrefix(arg, "--go_out="):
 			goOut = strings.SplitN(arg, "=", 2)[1]
+		case strings.HasPrefix(arg, "--imports="):
+			val := strings.SplitN(arg, "=", 2)[1]
+			imports = strings.Split(val, ",")
 		default:
 			srcs = append(srcs, arg)
 		}
@@ -64,16 +72,16 @@ func parseCommandLine() ([]string, string, string) {
 		fmt.Printf("At least one *.soy file required\n")
 		os.Exit(1)
 	}
-	return srcs, jsOut, goOut
+	return srcs, jsOut, goOut, imports
 }
 
 func main() {
-	srcs, jsOut, goOut := parseCommandLine()
+	srcs, jsOut, goOut, imports := parseCommandLine()
 	files := parseSoyFiles(srcs)
 	if jsOut != "" {
 		generateJSExportFile(files, jsOut)
 	}
 	if goOut != "" {
-		generateGoExportFile(files, goOut)
+		generateGoExportFile(files, goOut, imports)
 	}
 }

+ 13 - 4
generator/gowriter.go

@@ -89,7 +89,18 @@ func jsToGoType(jsType string) string {
 	}
 }
 
-func generateGoExportFile(files []*soyFile, goOut string) {
+func lookupImport(type_ string, imports []string) string {
+	for _, imp := range imports {
+		if strings.HasSuffix(imp, type_) {
+			return imp
+		}
+	}
+	fmt.Printf("Unable to find import for type: %s\n", type_)
+	os.Exit(1)
+	panic("not reached")
+}
+
+func generateGoExportFile(files []*soyFile, goOut string, imports []string) {
 	f, err := os.Create(goOut)
 	if err != nil {
 		fmt.Printf("Unable to create file %s: %v\n", goOut, err)
@@ -106,9 +117,7 @@ func generateGoExportFile(files []*soyFile, goOut string) {
 				}
 				parts := strings.Split(arg.datatype, ".")
 				suffix := strings.Join(parts[:len(parts)-1], "/")
-				// TODO(hochhaus): Fix prefix
-				imp := "github.com/socialworkout/soyotto/" + suffix
-				importMap[imp] = struct{}{}
+				importMap[lookupImport(suffix, imports)] = struct{}{}
 			}
 		}
 	}