Takes the D-Bus Introspection Data Format and generates Go code.
The project depends only on github.com/godbus/dbus module and cannot be used separately because it operates its data types.
API may change until 1.0.0, so please vendor the source code if you want to use this tool.
XML like this:
<node>
<interface name="my.awesome.interface">
<method name="IToA">
<arg name="In" type="x" direction="in" />
<arg name="Out" type="s" direction="out" />
</method>
<property name="Powered" type="b" access="readwrite" />
<signal name="SomethingHappened">
<arg name="object_path" type="o" />
<arg name="what" type="s" />
</signal>
</interface>
</node>
The tool will generate the following data structures:
-
Structure
My_Awesome_Interface
, that can be created withNewMy_Awesome_Interface(object)
or viaInterfaceLookup(object, "my.awesome.interface").(*My_Awesome_Interface)
in case you have more than one interface. -
IToA
method attached to the structure:(*My_Awesome_Interface) IToA(int64) (string, error)
. -
Powered
property getter and setter:(*My_Awesome_Interface) GetPowered() (bool, error)
and(*My_Awesome_Interface) SetPowered(bool) error
. -
My_Awesome_Interface_SomethingHappenedSignal
for typed access to signal body attributes,LookupSignal(*dbus.Signal) Signal
andAddMatchRule(*dbus.Signal) string
helper functions, see usage in the examples section. -
Annotations added to interfaces, methods, properties and signals as comments.
You can install it with go get
withing $GOPATH
or a module (go1.11 has issues with binaries installation outside of a module):
go get -u github.com/tq-systems/go-dbus-codegen/cmd/dbus-codegen-go
Or clone the repo and build it manually:
git clone [email protected]:tq-systems/go-dbus-codegen.git
cd dbus-codegen-go
go build ./cmd/dbus-codegen-go
The program treats command-line arguments as paths to XML files or reads out stdin if none given:
dbus-send --system \
--type=method_call \
--print-reply=literal \
--dest=org.freedesktop.systemd1 \
/org/freedesktop/systemd1 \
org.freedesktop.DBus.Introspectable.Introspect \
> org.freedesktop.systemd1.xml
dbus-codegen-go org.freedesktop.systemd1.xml
dbus-codegen-go < org.freedesktop.systemd1.xml
Apart of reading existing files it can introspect real D-Bus destinations recursively:
dbus-codegen-go -dest=org.freedesktop.systemd1
You may also want to safe the introspection file that combines all interfaces in the tree on some system for further reuse. For that simply add -xml
flag:
dbus-codegen-go -xml -dest=org.freedesktop.systemd1
Here's an example of a bit more advanced usage, where we're changing the generated code's package name and narrow down the introspected interfaces to just two we need, plus we're trimming org.freedesktop
prefix to shorten generated structure names:
dbus-codegen-go \
-dest=org.freedesktop.systemd1 \
-package=systemd \
-only=org.freedesktop.systemd1.Manager \
-only=org.freedesktop.systemd1.Service \
-prefix=org.freedesktop.systemd1
The following example subscribes to all PropertyChanged
signals from org.freedesktop.systemd1
destination.
The generated code is generated with:
dbus-codegen-go \
-package=main \
-dest=org.freedesktop.DBus \
-dest=org.freedesktop.systemd1
package main
import (
"fmt"
"os"
"github.com/godbus/dbus"
)
func main() {
if err := run(); err != nil {
fmt.Fprintf(os.Stderr, "error: %s\n", err)
os.Exit(1)
}
}
func run() error {
conn, err := dbus.SystemBus()
if err != nil {
return err
}
defer conn.Close()
sigc := make(chan *dbus.Signal, 1)
conn.Signal(sigc)
defer conn.RemoveSignal(sigc)
bus := NewOrg_Freedesktop_DBus(conn.BusObject())
if err := bus.AddMatch(
AddMatchRule((*Org_Freedesktop_DBus_Properties_PropertiesChangedSignal)(nil)) +
",sender='org.freedesktop.systemd1'",
); err != nil {
return err
}
for sig := range sigc {
switch v := LookupSignal(sig).(type) {
case *Org_Freedesktop_DBus_Properties_PropertiesChangedSignal:
fmt.Printf("%s %s: %v\n", v.Path(), v.Body.Interface, v.Body.ChangedProperties)
}
}
return nil
}
To test the package simply run:
go test ./...
tests
directory contains integration tests that technically compile the package's binary and use it for code generation and further compilation with test file scenarios, so make sure that go
is in your $PATH
.
The generated output by printer
package cannot be parsed by gofmt and that is the package issue, disable it with -gofmt=false
and inspect the result or create an issue with input xml files and the generated code.
- name conflicts resolver
- server side code generation
- add coding examples
- sophisticated tests
- more printer options, like using Ugly_Case and CamelCase in interface names
All contributions are welcome, just create an issue or issue a pull request.