{"id":13414141,"url":"https://github.com/wendigo/go-bind-plugin","last_synced_at":"2025-05-01T16:33:31.642Z","repository":{"id":57497031,"uuid":"73194860","full_name":"wendigo/go-bind-plugin","owner":"wendigo","description":"go-bind-plugin generates API for exported plugin symbols (-buildmode=plugin) - go1.8+ only (http://golang.org/pkg/plugin)","archived":false,"fork":false,"pushed_at":"2019-08-29T11:59:32.000Z","size":2326,"stargazers_count":184,"open_issues_count":0,"forks_count":11,"subscribers_count":6,"default_branch":"master","last_synced_at":"2024-10-25T05:25:33.224Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/wendigo.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2016-11-08T14:40:26.000Z","updated_at":"2024-07-09T09:49:44.000Z","dependencies_parsed_at":"2022-09-03T23:50:30.877Z","dependency_job_id":null,"html_url":"https://github.com/wendigo/go-bind-plugin","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wendigo%2Fgo-bind-plugin","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wendigo%2Fgo-bind-plugin/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wendigo%2Fgo-bind-plugin/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wendigo%2Fgo-bind-plugin/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/wendigo","download_url":"https://codeload.github.com/wendigo/go-bind-plugin/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":224268354,"owners_count":17283473,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-07-30T20:01:58.987Z","updated_at":"2024-11-12T11:37:36.788Z","avatar_url":"https://github.com/wendigo.png","language":"Go","readme":"# go-bind-plugin [![Build Status](https://travis-ci.org/wendigo/go-bind-plugin.svg?branch=master)](https://travis-ci.org/wendigo/go-bind-plugin)\u0026nbsp;[![Coverage Status](https://coveralls.io/repos/github/wendigo/go-bind-plugin/badge.svg?branch=master)](https://coveralls.io/github/wendigo/go-bind-plugin?branch=master)\u0026nbsp;[![GoDoc](https://godoc.org/github.com/wendigo/go-bind-plugin/cli?status.svg)](https://godoc.org/github.com/wendigo/go-bind-plugin/cli)\u0026nbsp;[![Go Report Card](https://goreportcard.com/badge/github.com/wendigo/go-bind-plugin)](https://goreportcard.com/report/github.com/wendigo/go-bind-plugin)\u0026nbsp;[![Say thanks!](https://img.shields.io/badge/SayThanks.io-%E2%98%BC-1EAEDB.svg)](https://saythanks.io/to/wendigo)\n\n\u003e TL;DR: See end-to-end example in [go-bind-plugin-example](https://github.com/wendigo/go-bind-plugin-example).\n\n**go-bind-plugin** is `go:generate` tool for building [golang 1.8 plugins](https://tip.golang.org/pkg/plugin) and generating wrappers around exported symbols (functions and variables).\n\n## What is it?\n\n**go-bind-plugin** generates neat API around symbols exported by a `*.so` plugin built with `go build -buildmode=plugin` in upcoming go 1.8. [plugin.Plugin](https://tip.golang.org/pkg/plugin/#Plugin) holds information about exported symbols as `map[string]interface{}`.\n\n**go-bind-plugins** uses reflection to find out actual types of symbols and generates typed API wrapping plugin with additional functionalities (like dereferencing exported variables and checking SHA256 sum).\n\n*Note: Basic usage does not require plugin sources as wrapper can be generated using only* `*.so` *file.*\n\n## Why should I use it?\n\nIn example if plugin exports `func AddTwoInts(a, b int) int` and `var BuildVersion string` instead of using [Plugin.Lookup](https://tip.golang.org/pkg/plugin/#Plugin.Lookup) directly:\n\n```go\nplug, err := plugin.Open(\"plugin.so\")\n\nif err != nil {\n  panic(err)\n}\n\nsymbol, err := plug.Lookup(\"AddTwoInts\")\nif err != nil {\n  panic(\"AddTwoInts was not found in a plugin\")\n}\n\nif typed, ok := symbol.(func(int, int) int); ok {\n  result := typed(10, 20)\n} else {\n  panic(\"AddTwoInts has different type than exported by plugin\")\n}\n\nsymbol, err := plug.Lookup(\"BuildVersion\")\nif err != nil {\n  panic(\"BuildVersion was not found in a plugin\")\n}\n\nif typed, ok := symbol.(*string); ok {\n  fmt.Println(*typed)\n} else {\n  panic(\"BuildVersion is not a string reference\")\n}\n```\n\nyou can just simply do:\n\n```go\nplug, err := pluginapi.BindPluginAPI(\"plugin.so\") // plug is *plugin_api.PluginAPI\n\nif err != nil {\n  panic(err)\n}\n\nresult := plug.AddTwoInts(10, 20)\nfmt.Println(plug.BuildVersion) // or fmt.Println(*plug.BuildVersion) if -dereference-vars is not used\n```\n\n`pluginapi.BindPluginAPI()` ensures that plugin exports required symbols and their types are correct.\n\n## Usage\n\n```go\ngo get -u github.com/wendigo/go-bind-plugin\ngo-bind-plugin -help\n\nUsage of go-bind-plugin:\n  -dereference-vars\n    \tDereference plugin variables\n  -format\n    \tFormat generated output file with gofmt (default true)\n  -hide-vars\n    \tDo not export plugin variables\n  -interface\n    \tGenerate and return interface instead of struct (turns on -hide-vars)\n  -output-name string\n    \tOutput struct name (default \"PluginAPI\")\n  -output-package string\n    \tOutput package (can be derived from output-path) (default \"main\")\n  -output-path string\n    \tOutput file path (default \"plugin_api.go\")\n  -plugin-package string\n    \tPlugin package url (as accepted by go get)\n  -plugin-path string\n    \tPath to plugin (.so file)\n  -rebuild\n    \tRebuild plugin on every run\n  -sha256\n    \tWrite plugin's sha256 checksum to wrapper and validate it when loading it\n```\n\n### Example\n`\n//go:generate go-bind-plugin -format -plugin-package github.com/plugin_test/plug -rebuild -sha256 -dereference-vars -output-name TestPlugin -output-path tmp/plugin.go -plugin-path tmp/plugin.so -output-package pluginapi\n`\n\n**go-bind-plugin** will do following things on invocation:\n\n- build plugin to `tmp/plugin.so` (even if plugin exists it will be rebuilded) from `github.com/plugin_test/plug` source (must exist in $GOPATH or vendor/)\n- generate wrapper struct `wrapper.TestPlugin` in `tmp/plugin.go`\n- dereference variables in the generated wrapper\n- format generated wrapper with `gofmt -s -w`\n- write sha256 checksum to `tmp/plugin.go` that will be checked when loading plugin with `pluginapi.BindTestPlugin(path string) (*TestPlugin, error)`\n\n### Wrapper API example (for -output-name \"PluginAPI\")\n\n`BindPluginAPI(path string) (*PluginAPI, error)` - loads plugin from `path` and wraps it with `type PluginAPI struct`:\n  - all functions exported by the plugin are exposed as methods on struct `PluginAPI`\n  - all variables exported by the plugin are exposed as fields on struct `PluginAPI` (if `-dereference-vars` is used fields are not references to plugin's variables)\n\n`func (*PluginAPI) String() string` - provides nice textual representation of the wrapper\n\n### Wrapper as interface\n\nWhen `-interface` is used instead of generating and returning `struct` interface containing all exported symbols is generated. This eases mocking and working with multiple plugins exporting the same API. \n\n**Note** that `-interface` effectively enables `-hide-vars` so variables won't be exported from the plugin.\n\n### Generated code quality\n\nGenerated code passes both `go vet` and `golint` and can be formatted using `gofmt -s -w`. Exported symbols names are not changed in any way so names not following [go naming convention](https://golang.org/doc/effective_go.html) will still be reported by `golint` as invalid.\n\n### Example generated wrapper information\n\n```go\nWrapper info:\n\t- Generated on: 2016-11-08 16:15:07.513150982 +0100 CET\n\t- Command: go-bind-plugin -plugin-path ./internal/test_fixtures/generated/basic_plugin/plugin.so -plugin-package ./internal/test_fixtures/basic_plugin -output-name TestWrapper -output-path ./internal/test_fixtures/generated/basic_plugin/plugin.go -output-package main -sha256 true -format true -rebuild true\n\nPlugin info:\n\t- package: github.com/wendigo/go-bind-plugin/internal/test_fixtures/basic_plugin\n\t- sha256 sum: 55aa13402686f3200f5067604c04ce8d365e7cf2095d8278b2ff52ae26df7e6d\n\t- size: 1232572 bytes\n\nExported functions (3):\n\t- ReturningInt32 func() (int32)\n\t- ReturningStringSlice func() ([]string)\n\t- ReturningIntArray func() ([3]int32)\n```\n\n## Plugin call overhead\n\nUsing `-buildmode=plugin` with generated wrapper seems not to add overhead when calling methods on a wrapper (creating plugin instance and loading `*.so` file is constant cost).\n\n```go\nBenchmarkCallOverhead/plugin-8         \t30000000\t        58.0 ns/op\t       0 B/op\t       0 allocs/op\nBenchmarkCallOverhead/plugin-8         \t30000000\t        59.3 ns/op\t       0 B/op\t       0 allocs/op\nBenchmarkCallOverhead/plugin-8         \t30000000\t        54.8 ns/op\t       0 B/op\t       0 allocs/op\nBenchmarkCallOverhead/native-8         \t20000000\t        59.3 ns/op\t       0 B/op\t       0 allocs/op\nBenchmarkCallOverhead/native-8         \t20000000\t        59.8 ns/op\t       0 B/op\t       0 allocs/op\nBenchmarkCallOverhead/native-8         \t20000000\t        59.7 ns/op\t       0 B/op\t       0 allocs/op\n```\n","funding_links":[],"categories":["Utilities","工具库","公用事业公司","工具库`可以提升效率的通用代码库和工具`","Utility","实用工具"],"sub_categories":["Utility/Miscellaneous","交流","Advanced Console UIs","HTTP Clients","实用程序/Miscellaneous","查询语","\u003cspan id=\"高级控制台用户界面-advanced-console-uis\"\u003e高级控制台用户界面 Advanced Console UIs\u003c/span\u003e","Fail injection"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwendigo%2Fgo-bind-plugin","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fwendigo%2Fgo-bind-plugin","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwendigo%2Fgo-bind-plugin/lists"}