misc: Improve go bindings gen 17/35617/3
authorNathan Skrzypczak <nathan.skrzypczak@gmail.com>
Thu, 10 Mar 2022 11:38:31 +0000 (12:38 +0100)
committerBeno�t Ganne <bganne@cisco.com>
Thu, 17 Mar 2022 13:05:48 +0000 (13:05 +0000)
Type: improvement

Change-Id: Id705dab895602a60b053296b560ca3db5b0cd344
Signed-off-by: Nathan Skrzypczak <nathan.skrzypczak@gmail.com>
Makefile
src/tools/vppapigen/generate_go.py

index 6583a29..4ac4c9a 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -639,7 +639,7 @@ json-api-files-debug:
 
 .PHONY: go-api-files
 go-api-files: json-api-files
-       $(WS_ROOT)/src/tools/vppapigen/generate_go.py
+       $(WS_ROOT)/src/tools/vppapigen/generate_go.py $(ARGS)
 
 .PHONY: ctags
 ctags: ctags.files
index 1e072ef..1fb53c7 100755 (executable)
@@ -5,6 +5,7 @@ import os
 import pathlib
 import subprocess
 import tarfile
+import shutil
 
 import requests
 import sys
@@ -13,38 +14,9 @@ import sys
 # GoVPP API generator generates Go bindings compatible with the local VPP
 #
 
-parser = argparse.ArgumentParser()
-parser.add_argument("-govpp-commit", help="GoVPP commit or branch (defaults to v0.3.5-45-g671f16c)",
-                    default="671f16c",  # fixed GoVPP version
-                    type=str)
-parser.add_argument("-output-dir", help="output target directory for generated bindings", type=str)
-parser.add_argument("-api-files", help="api files to generate (without commas)", nargs="+", type=str)
-parser.add_argument("-import-prefix", help="prefix imports in the generated go code", type=str)
-parser.add_argument("-no-source-path-info", help="disable source path info in generated files", nargs='?', const=True,
-                    default=False)
-args = parser.parse_args()
-
-
-# Check input arguments
-def validate_args(vpp_dir, o, f, c, i):
-    if o is not None:
-        if not os.path.exists(o) or os.path.isfile(o):
-            print(o + " is not a valid output path")
-            sys.exit(1)
-    else:
-        o = vpp_dir
-    if f is None:
-        f = []
-    if c is None:
-        c = "671f16c"
-    if i is None:
-        i = ""
-
-    return str(o), f, c, i
 
-
-# Returns version of the installed Go
 def get_go_version(go_root):
+    # Returns version of the installed Go
     p = subprocess.Popen(["./go", "version"],
                          cwd=go_root + "/bin",
                          stdout=subprocess.PIPE,
@@ -76,15 +48,24 @@ def install_golang(go_root):
         print('Go ' + get_go_version(go_root) + ' is already installed')
         return
 
+    filename = requests.get(
+        'https://golang.org/VERSION?m=text').text + ".linux-amd64.tar.gz"
+    url = "https://dl.google.com/go/" + filename
+
     print("Go binary not found, installing the latest version...")
+    print("Download url      = %s" % url)
+    print("Install directory = %s" % go_root)
+    text = input("[Y/n] ?")
+
+    if text.strip().lower() != "y" and text.strip().lower() != "yes":
+        print("Aborting...")
+        exit(1)
+
     go_folders = ['src', 'pkg', 'bin']
 
     for f in go_folders:
         if not os.path.exists(os.path.join(go_root, f)):
             os.makedirs(os.path.join(go_root, f))
-
-    filename = requests.get('https://golang.org/VERSION?m=text').text + ".linux-amd64.tar.gz"
-    url = "https://dl.google.com/go/" + filename
     r = requests.get(url)
     with open("/tmp/" + filename, 'wb') as f:
         f.write(r.content)
@@ -103,23 +84,26 @@ def install_golang(go_root):
 # Installs latest binary API generator
 def install_binapi_gen(c, go_root, go_path):
     os.environ['GO111MODULE'] = "on"
-    if os.path.exists(go_root + "/bin/go") & os.path.isfile(go_root + "/bin/go"):
-        p = subprocess.Popen(["./go", "get", "git.fd.io/govpp.git/cmd/binapi-generator@" + c],
+    if (os.path.exists(go_root + "/bin/go") and
+            os.path.isfile(go_root + "/bin/go")):
+        p = subprocess.Popen(["./go", "get",
+                              "git.fd.io/govpp.git/cmd/binapi-generator@" + c],
                              cwd=go_root + "/bin",
                              stdout=subprocess.PIPE,
                              stderr=subprocess.PIPE,
                              universal_newlines=True, )
         _, error = p.communicate()
         if p.returncode != 0:
-            print("binapi generator installation failed: %d %s" % (p.returncode, error))
+            print("binapi generator installation failed: %d %s" %
+                  (p.returncode, error))
             sys.exit(1)
     bg_ver = get_binapi_gen_version(go_path)
     print('Installed binary API generator ' + bg_ver)
 
 
 # Creates generated bindings using GoVPP binapigen to the target folder
-def generate_api(output_dir, vpp_dir, api_list, import_prefix, no_source, go_path):
-    output_binapi = output_dir + "binapi" if output_dir[-1] == "/" else output_dir + "/binapi"
+def generate_api(output_dir, vpp_dir, api_list, import_prefix,
+                 no_source, go_path):
     json_dir = vpp_dir + "/build-root/install-vpp-native/vpp/share/vpp/api"
 
     if not os.path.exists(json_dir):
@@ -127,12 +111,16 @@ def generate_api(output_dir, vpp_dir, api_list, import_prefix, no_source, go_pat
         sys.exit(1)
 
     print("Generating API")
-    cmd = ["./binapi-generator", "--output-dir=" + output_binapi, "--input-dir=" + json_dir]
+    cmd = ["./binapi-generator", "--input-dir=" + json_dir]
+    if output_dir:
+        cmd += ["--output-dir=" + output_dir]
     if len(api_list):
-        print("Following API files were requested by 'GO_API_FILES': " + str(api_list))
-        print("Note that dependency requirements may generate additional API files")
+        print("Following API files were requested by 'GO_API_FILES': " +
+              str(api_list))
+        print("Note that dependency requirements may generate "
+              "additional API files")
         cmd.append(api_list)
-    if not import_prefix == "":
+    if import_prefix:
         cmd.append("-import-prefix=" + import_prefix)
     if no_source:
         cmd.append("-no-source-path-info")
@@ -153,30 +141,59 @@ def generate_api(output_dir, vpp_dir, api_list, import_prefix, no_source, go_pat
         print(msg, end=" ")
 
     print("\n")
-    print("Go API bindings were generated to " + output_binapi)
+    print("Go API bindings were generated to " + output_dir)
 
 
 def main():
     # project root directory
     root = pathlib.Path(os.path.dirname(os.path.abspath(__file__)))
-    vpp_dir: str = root.parent.parent.parent
-
-    o, f, c, i = validate_args(vpp_dir, args.output_dir, args.api_files, args.govpp_commit,
-                               args.import_prefix)
+    vpp_dir = root.parent.parent.parent
+
+    parser = argparse.ArgumentParser()
+    parser.add_argument("-govpp-commit", "--govpp-commit",
+                        help="GoVPP commit or branch "
+                             "(defaults to v0.3.5-45-g671f16c)",
+                        default="671f16c",  # fixed GoVPP version
+                        type=str)
+    parser.add_argument("-output-dir", "--output-dir",
+                        help="output target directory for generated bindings",
+                        type=str,
+                        default=os.path.join(vpp_dir, "vppbinapi"))
+    parser.add_argument("-api-files", "--api-files",
+                        help="api files to generate (without commas)",
+                        nargs="+",
+                        type=str,
+                        default=[])
+    parser.add_argument("-import-prefix", "--import-prefix",
+                        help="prefix imports in the generated go code",
+                        default="",
+                        type=str)
+    parser.add_argument("-no-source-path-info", "--no-source-path-info",
+                        help="disable source path info in generated files",
+                        nargs='?',
+                        const=True,
+                        default=True)
+    args = parser.parse_args()
 
     # go specific environment variables
     if "GOROOT" in os.environ:
         go_root = os.environ['GOROOT']
     else:
-        go_root = os.environ['HOME'] + "/.go"
+        go_binary = shutil.which("go")
+        if go_binary != "":
+            go_binary_dir, _ = os.path.split(go_binary)
+            go_root = os.path.join(go_binary_dir, "..")
+        else:
+            go_root = os.environ['HOME'] + "/.go"
     if "GOPATH" in os.environ:
         go_path = os.environ['GOPATH']
     else:
         go_path = os.environ['HOME'] + "/go"
 
     install_golang(go_root)
-    install_binapi_gen(c, go_root, go_path)
-    generate_api(o, str(vpp_dir), f, i, args.no_source_path_info, go_path)
+    install_binapi_gen(args.govpp_commit, go_root, go_path)
+    generate_api(args.output_dir, str(vpp_dir), args.api_files,
+                 args.import_prefix, args.no_source_path_info, go_path)
 
 
 if __name__ == "__main__":