diff --git a/.github/workflows/golangci-lint.yml b/.github/workflows/golangci-lint.yml
index e42782c94..2d383450b 100644
--- a/.github/workflows/golangci-lint.yml
+++ b/.github/workflows/golangci-lint.yml
@@ -14,11 +14,6 @@ jobs:
fail-fast: false
matrix:
go-version: [
- # 1.19.x, # Ended 06 Sep 2023
- # 1.20.x, # Ended 06 Feb 2024
- # 1.21.x, # Ended 13 Aug 2024
- # 1.22.x, # Ended 11 Feb 2025
- 1.23.x,
1.24.x,
1.25.x,
]
@@ -41,8 +36,7 @@ jobs:
# working-directory: somedir
# Optional: golangci-lint command line arguments.
- # ignore the lib.go file as it only contains cgo annotations
- args: --exclude-files internal/native/lib.go --timeout 2m
+ args: --timeout 2m
# Optional: show only new issues if it's a pull request. The default value is `false`.
# only-new-issues: true
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index 208f06684..e7662e2cb 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -13,16 +13,24 @@ on:
description: 'Skip alpine provider tests'
required: false
default: 'false'
-
+ log_level:
+ description: 'Log level'
+ type: choice
+ required: true
+ default: 'INFO'
+ options:
+ - 'INFO'
+ - 'DEBUG'
+ - 'TRACE'
env:
PACT_BROKER_BASE_URL: https://testdemo.pactflow.io
PACT_BROKER_TOKEN: ${{ secrets.PACT_BROKER_TOKEN }}
REACT_APP_API_BASE_URL: http://localhost:8080
APP_SHA: ${{ github.sha }}
APP_REF: ${{ github.ref }}
- LD_LIBRARY_PATH: /tmp
- PACT_GO_LIB_DOWNLOAD_PATH: /tmp
- LOG_LEVEL: debug
+ # PACT_GO_LIB_DOWNLOAD_PATH: /tmp
+ # PACT_LD_LIBRARY_PATH: /tmp
+ LOG_LEVEL: ${{ github.event.inputs.log_level || 'INFO' }}
COVERALLS_TOKEN: ${{ secrets.GITHUB_TOKEN }}
jobs:
@@ -31,17 +39,11 @@ jobs:
fail-fast: false
matrix:
go-version: [ # https://endoflife.date/go
- # 1.17.x, # Ended 02 Aug 2022
- # 1.18.x, # Ended 01 Feb 2023
- # 1.19.x, # Ended 06 Sep 2023
- # 1.20.x, # Ended 06 Feb 2024
- # 1.21.x, # Ended 13 Aug 2024
- # 1.22.x, # Ended 11 Feb 2025
- 1.23.x,
1.24.x,
1.25.x,
]
- os: [ubuntu-latest, macos-13, macos-14, windows-latest]
+ os: [ubuntu-latest, macos-15, macos-15-intel, windows-latest]
+ cgo: [0,1]
runs-on: ${{ matrix.os }}
steps:
- name: Checkout code
@@ -54,16 +56,23 @@ jobs:
with:
distribution: 'zulu'
java-version: '17'
+ - name: "Set CGO_ENABLED: ${{ matrix.cgo }}"
+ if: matrix.os == 'windows-latest'
+ run: |
+ "CGO_ENABLED=${{ matrix.cgo }}" >> $env:GITHUB_ENV
+ - name: "Set CGO_ENABLED: ${{ matrix.cgo }}"
+ if: matrix.os != 'windows-latest'
+ run: |
+ echo "CGO_ENABLED=${{ matrix.cgo }}" >> $GITHUB_ENV
- if: matrix.os == 'macos-14'
run: brew install protobuf
- name: Test
if: matrix.os == 'ubuntu-latest'
run: APP_BRANCH=${APP_REF:11} DOCKER_GATEWAY_HOST=172.17.0.1 DOCKER_HOST_HTTP="http://172.17.0.1" make
- - name: Set CGO_LDFLAGS / pact_ffi lib on PATH
- if: matrix.os == 'windows-latest'
- run: |
- "CGO_LDFLAGS=-L$env:TMP" >> $env:GITHUB_ENV
- "$env:TMP" >> $env:GITHUB_PATH
+ # - name: Set PACT_LD_LIBRARY_PATH
+ # if: matrix.os == 'windows-latest'
+ # run: |
+ # "PACT_LD_LIBRARY_PATH=$env:TMP" >> $env:GITHUB_ENV
- name: Test (unit)
if: matrix.os != 'ubuntu-latest'
run: make test
@@ -78,26 +87,23 @@ jobs:
run: goveralls -coverprofile=coverage.txt -service=github -parallel
- uses: actions/upload-artifact@v5
with:
- name: logs-${{ github.job }}-${{ github.run_id }}-${{ github.run_attempt }}-${{ matrix.go-version }}-${{ matrix.os }}.zip
+ name: logs-${{ github.job }}-${{ github.run_id }}-${{ github.run_attempt }}-${{ matrix.go-version }}-${{ matrix.os }}-${{matrix.cgo}}.zip
path: ~/.pact/plugins/**/plugin.log
if: ${{ always() }}
test-containers:
continue-on-error: ${{ matrix.experimental }}
runs-on: ${{ matrix.os }}
- name: ${{ matrix.os }}-${{ matrix.variant }}-${{ matrix.go-version }}-test-container
+ name: ${{ matrix.os }}-${{ matrix.variant }}-${{ matrix.go-version }}-test-container-cgo-${{ matrix.cgo }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, ubuntu-24.04-arm]
- go-version: ["1.23", "1.24", "1.25"]
+ go-version: ["1.24", "1.25"]
variant: [debian]
experimental: [false]
+ cgo: [0,1]
include:
- - variant: alpine
- go-version: 1.23
- experimental: true
- os: ubuntu-latest
- variant: alpine
go-version: 1.24
experimental: true
@@ -106,10 +112,6 @@ jobs:
go-version: 1.25
experimental: true
os: ubuntu-latest
- - variant: alpine
- go-version: 1.23
- experimental: true
- os: ubuntu-24.04-arm
- variant: alpine
go-version: 1.24
experimental: true
@@ -133,6 +135,7 @@ jobs:
env:
GO_VERSION: ${{ matrix.go-version }}
IMAGE_VARIANT: ${{ matrix.variant }}
+ CGO_ENABLED: ${{ matrix.cgo }}
finish:
needs: [test,test-containers]
diff --git a/Dockerfile.alpine b/Dockerfile.alpine
index 2a332ce7e..b9291ac6e 100644
--- a/Dockerfile.alpine
+++ b/Dockerfile.alpine
@@ -1,5 +1,5 @@
-ARG VERSION=1.23
-FROM golang:${VERSION}-alpine
+ARG GO_VERSION=1.24
+FROM golang:${GO_VERSION}-alpine
RUN apk add --no-cache curl gcc musl-dev gzip openjdk17-jre bash protoc protobuf-dev make file
diff --git a/Dockerfile.debian b/Dockerfile.debian
index d8da299b3..a86f67aac 100644
--- a/Dockerfile.debian
+++ b/Dockerfile.debian
@@ -1,5 +1,5 @@
-ARG VERSION=latest
-FROM golang:${VERSION}
+ARG GO_VERSION=latest
+FROM golang:${GO_VERSION}
RUN apt-get update && apt-get install -y openjdk-21-jre file protobuf-compiler
COPY . /go/src/github.com/pact-foundation/pact-go
diff --git a/Makefile b/Makefile
index d52206c69..cf064c782 100755
--- a/Makefile
+++ b/Makefile
@@ -9,15 +9,21 @@ PLUGIN_PACT_CSV_VERSION=0.0.6
PLUGIN_PACT_MATT_VERSION=0.1.1
PLUGIN_PACT_AVRO_VERSION=0.0.6
-GO_VERSION?=1.23
+GO_VERSION?=1.24
IMAGE_VARIANT?=debian
ci:: docker deps clean bin test pact
-PACT_DOWNLOAD_DIR=/tmp
-ifeq ($(OS),Windows_NT)
- PACT_DOWNLOAD_DIR=$$TMP
+# PACT_DOWNLOAD_DIR=/tmp
+# ifeq ($(OS),Windows_NT)
+# PACT_DOWNLOAD_DIR=$$TMP
+# endif
+
+CGO_ENABLED?=1
+ifeq ($(CGO_ENABLED),0)
+ SKIP_RACE=true
endif
SKIP_RACE?=false
RACE?=-race
+SKIP_SIGNAL_HANDLERS?=false
ifeq ($(SKIP_RACE),true)
RACE=
endif
@@ -49,6 +55,7 @@ docker_test: docker_build
-e LOG_LEVEL=INFO \
-e SKIP_PROVIDER_TESTS=$(SKIP_PROVIDER_TESTS) \
-e SKIP_RACE=$(SKIP_RACE) \
+ -e CGO_ENABLED=$(CGO_ENABLED) \
--rm \
-it \
pactfoundation/pact-go-test-$(IMAGE_VARIANT) \
@@ -58,6 +65,7 @@ docker_pact: docker_build
-e LOG_LEVEL=INFO \
-e SKIP_PROVIDER_TESTS=$(SKIP_PROVIDER_TESTS) \
-e SKIP_RACE=$(SKIP_RACE) \
+ -e CGO_ENABLED=$(CGO_ENABLED) \
--rm \
pactfoundation/pact-go-test-$(IMAGE_VARIANT) \
/bin/sh -c "make pact_local"
@@ -66,6 +74,7 @@ docker_test_all: docker_build
-e LOG_LEVEL=INFO \
-e SKIP_PROVIDER_TESTS=$(SKIP_PROVIDER_TESTS) \
-e SKIP_RACE=$(SKIP_RACE) \
+ -e CGO_ENABLED=$(CGO_ENABLED) \
--rm \
pactfoundation/pact-go-test-$(IMAGE_VARIANT) \
/bin/sh -c "make test && make pact_local"
@@ -117,18 +126,18 @@ cli:
install: bin
echo "--- 🐿 Installing Pact FFI dependencies"
- ./build/pact-go -l DEBUG install --libDir $(PACT_DOWNLOAD_DIR)
+ ./build/pact-go -l DEBUG install
pact: clean install docker
@echo "--- 🔨 Running Pact examples"
- go test -v -tags=consumer -count=1 github.com/pact-foundation/pact-go/v2/examples/...
+ ./build/pact-go test -v -tags=consumer -count=1 github.com/pact-foundation/pact-go/v2/examples/...
make publish
- go test -v -timeout=30s -tags=provider -count=1 github.com/pact-foundation/pact-go/v2/examples/...
+ ./build/pact-go test -v -timeout=30s -tags=provider -count=1 github.com/pact-foundation/pact-go/v2/examples/...
pact_local: clean download_plugins install
@echo "--- 🔨 Running Pact examples"
- go test -v -tags=consumer -count=1 github.com/pact-foundation/pact-go/v2/examples/...
+ ./build/pact-go test -v -tags=consumer -count=1 github.com/pact-foundation/pact-go/v2/examples/...
if [ "$(SKIP_PROVIDER_TESTS)" != "true" ]; then \
- SKIP_PUBLISH=true go test -v -timeout=30s -tags=provider -count=1 github.com/pact-foundation/pact-go/v2/examples/...; \
+ SKIP_PUBLISH=true ./build/pact-go test -v -timeout=30s -tags=provider -count=1 github.com/pact-foundation/pact-go/v2/examples/...; \
fi
publish:
@@ -151,7 +160,7 @@ test: deps install
@echo "mode: count" > coverage.txt
@for d in $$(go list ./... | grep -v vendor | grep -v examples); \
do \
- go test -v $(RACE) -coverprofile=profile.out $(PROVIDER_TEST_TAGS) -covermode=atomic $$d; \
+ ./build/pact-go test -v $(RACE) -coverprofile=profile.out $(PROVIDER_TEST_TAGS) -covermode=atomic $$d; \
if [ $$? != 0 ]; then \
exit 1; \
fi; \
@@ -164,7 +173,7 @@ test: deps install
testrace:
- go test $(RACE) $(TEST) $(TESTARGS)
+ ./build/pact-go test $(RACE) $(TEST) $(TESTARGS)
updatedeps:
go get -d -v -p 2 ./...
@@ -182,5 +191,5 @@ protos:
.PHONY: grpc-test
grpc-test:
rm -rf ./examples/pacts
- go test -v -tags=consumer -count=1 github.com/pact-foundation/pact-go/v2/examples/grpc
- go test -v -timeout=30s -tags=provider -count=1 github.com/pact-foundation/pact-go/v2/examples/grpc
+ ./build/pact-go test -v -tags=consumer -count=1 github.com/pact-foundation/pact-go/v2/examples/grpc
+ ./build/pact-go test -v -timeout=30s -tags=provider -count=1 github.com/pact-foundation/pact-go/v2/examples/grpc
diff --git a/README.md b/README.md
index 3ab2ab1c3..84ab7e067 100644
--- a/README.md
+++ b/README.md
@@ -90,6 +90,8 @@ go install github.com/pact-foundation/pact-go/v2
pact-go -l DEBUG install
# 🚀 now write some tests!
+pact-go test
+# pact-go test is a wrapper around go test, and sets the PACT_LD_LIBRARY_PATH environment variable to the pact required libraries
```
If the `pact-go` command above is not found, make sure that `$GOPATH/bin` is in your path. I.e.,
@@ -100,56 +102,14 @@ export PATH=$PATH:$GOPATH/bin
You can also keep the library versions up to date by running the `version.CheckVersion()` function.
-Set `PACT_GO_LIB_DOWNLOAD_PATH` env var if you have installed the library in a non-standard location.
-
-Pre-Requisites
-
-### Pre-Requisites
-
-- `cgo`
- - Pact relies on C shared libraries compiled from Rust
- - `CGO_ENABLED=1` (check with `go env`)
-
-#### Linux
-
-- Install `gcc` package
-
-#### MacOS
-
-- Install the Xcode Command line tools
-
-By default, pact-go install will attempt to install in `/usr/local/lib`.
-
-Note this is not user-writable, so `pact-go install` must be run with `sudo`.
-
-An alternative is to install to `/tmp` via `pact-go -l DEBUG install --libDir /tmp`
-
-#### Windows
-
-- Install `gcc`
- - `choco install mingw`
- - `scoop install mingw`
-
-- Add location of the pact-go installed shared library to
- - `PATH`
- - `CGO_LDFLAGS`
-
-##### Powershell
-
-- `$env:Path += ";$env:TMP"`
-- `$env:CGO_LDFLAGS = "-L$env:TMP"`
-
-- Command Prompt
-- `set PATH="%PATH%;%TMP%"`
-- `set CGO_LDFLAGS="-L%TMP%"`
-
-
+- Set `PACT_GO_LIB_DOWNLOAD_PATH` env var if you have installed the library in a non-standard location.
+- Set `PACT_LD_LIBRARY_PATH` env var if you have installed the library in a non-standard location and are running `go test` directly without the `pact-go test` wrapper.
Manual Installation Instructions
### Manual
-Download the latest `Pact FFI Library` [library] for your OS, and install onto a standard library search path (we suggest: `/usr/local/lib` on MacOS/Linux):
+Download the latest `Pact FFI Library` [library] for your OS.
Ensure you have the correct extension for your OS:
@@ -160,13 +120,12 @@ Ensure you have the correct extension for your OS:
```sh
wget https://github.com/pact-foundation/pact-reference/releases/download/libpact_ffi-v0.4.21/libpact_ffi-macos-x86_64.dylib.gz
gunzip libpact_ffi-macos-x86_64.dylib.gz
-mv libpact_ffi-macos-x86_64.dylib /usr/local/lib/libpact_ffi.dylib
```
Test the installation:
```sh
-pact-go help
+PACT_LD_LIBRARY_PATH=${PATH_TO_LIB} pact-go check
```
diff --git a/command/check.go b/command/check.go
index 01eb52c06..cbc86161f 100644
--- a/command/check.go
+++ b/command/check.go
@@ -27,7 +27,7 @@ var checkCmd = &cobra.Command{
log.Println("[INFO] set lib dir target to", libDir)
i.SetLibDir(libDir)
}
-
+
if err = i.CheckPackageInstall(); err != nil {
log.Println("[DEBUG] error from CheckPackageInstall:", err)
log.Println("[ERROR] Your Pact library installation is out of date. Run `pact-go install` to correct")
diff --git a/command/install.go b/command/install.go
index 55436d039..5dfebbaef 100644
--- a/command/install.go
+++ b/command/install.go
@@ -37,6 +37,8 @@ var installCmd = &cobra.Command{
log.Println("[ERROR] Your Pact library installation is out of date and we were unable to download a newer one for you:", err)
os.Exit(1)
}
+
+ i.SetConfigLibDir(i.GetActualLibDir())
},
}
diff --git a/command/test.go b/command/test.go
new file mode 100644
index 000000000..7e5c7b80d
--- /dev/null
+++ b/command/test.go
@@ -0,0 +1,72 @@
+package command
+
+import (
+ "log"
+ "os"
+ "os/exec"
+ "syscall"
+
+ "github.com/pact-foundation/pact-go/v2/installer"
+ "github.com/spf13/cobra"
+)
+
+var testCmd = &cobra.Command{
+ Use: "test",
+ Short: "Run go test with Pact library path configured",
+ Long: "Wrapper for 'go test' that sets PACT_LD_LIBRARY_PATH to the configured library directory",
+ DisableFlagParsing: true,
+ Run: func(cmd *cobra.Command, args []string) {
+ setLogLevel(verbose, logLevel)
+
+ // Get the configured library directory
+ libDir := installer.GetConfigLibDir()
+ if libDir == "" {
+ log.Println("[WARN] No library directory configured. Run 'pact-go install -d ' to set one.")
+ // check PACT_LD_LIBRARY_PATH env var
+ if envLibDir := os.Getenv("PACT_LD_LIBRARY_PATH"); envLibDir != "" {
+ libDir = envLibDir
+ log.Printf("[INFO] Using PACT_LD_LIBRARY_PATH from environment: %s", libDir)
+ } else {
+ log.Println("[ERROR] No library directory configured and PACT_LD_LIBRARY_PATH is not set. Cannot run tests.")
+ os.Exit(1)
+ }
+ }
+
+ // Set the PACT_LD_LIBRARY_PATH environment variable
+ err := os.Setenv("PACT_LD_LIBRARY_PATH", libDir)
+ if err != nil {
+ log.Printf("[ERROR] Failed to set PACT_LD_LIBRARY_PATH: %v", err)
+ os.Exit(1)
+ }
+
+ log.Printf("[INFO] Running go test with PACT_LD_LIBRARY_PATH=%s", libDir)
+
+ // Prepare the go test command
+ goTestArgs := append([]string{"test"}, args...)
+ goCmd := exec.Command("go", goTestArgs...)
+
+ // Pass through environment variables
+ goCmd.Env = os.Environ()
+
+ // Set up stdout, stderr, and stdin
+ goCmd.Stdout = os.Stdout
+ goCmd.Stderr = os.Stderr
+ goCmd.Stdin = os.Stdin
+
+ // Execute the command and exit with the same exit code
+ if err := goCmd.Run(); err != nil {
+ if exitError, ok := err.(*exec.ExitError); ok {
+ // Exit with the same code as go test
+ if status, ok := exitError.Sys().(syscall.WaitStatus); ok {
+ os.Exit(status.ExitStatus())
+ }
+ }
+ log.Printf("[ERROR] Failed to run go test: %v", err)
+ os.Exit(1)
+ }
+ },
+}
+
+func init() {
+ RootCmd.AddCommand(testCmd)
+}
diff --git a/examples/avro/avro_provider_test.go b/examples/avro/avro_provider_test.go
index c7f957436..4b6d6e68a 100644
--- a/examples/avro/avro_provider_test.go
+++ b/examples/avro/avro_provider_test.go
@@ -62,7 +62,7 @@ func startHTTPProvider(port int) {
log.Println("ERROR: ", err)
w.WriteHeader(500)
} else {
- fmt.Fprintf(w, string(binary))
+ w.Write(binary)
w.WriteHeader(200)
}
})
diff --git a/examples/provider_test.go b/examples/provider_test.go
index bd3ca53f9..e02a031f9 100644
--- a/examples/provider_test.go
+++ b/examples/provider_test.go
@@ -27,7 +27,7 @@ var requestFilterCalled = false
var stateHandlerCalled = false
func TestV3HTTPProvider(t *testing.T) {
- log.SetLogLevel("TRACE")
+ log.SetLogLevel("INFO")
version.CheckVersion()
// Start provider API in the background
@@ -138,7 +138,7 @@ func TestV3HTTPProvider(t *testing.T) {
}
func TestV3MessageProvider(t *testing.T) {
- log.SetLogLevel("TRACE")
+ log.SetLogLevel("INFO")
var user *User
verifier := provider.NewVerifier()
diff --git a/go.mod b/go.mod
index 2911662e7..a5261f6b9 100644
--- a/go.mod
+++ b/go.mod
@@ -1,10 +1,11 @@
module github.com/pact-foundation/pact-go/v2
-go 1.23.0
+go 1.24.0
toolchain go1.24.5
require (
+ github.com/ebitengine/purego v0.9.0
github.com/golang/protobuf v1.5.4
github.com/hashicorp/go-version v1.7.0
github.com/hashicorp/logutils v1.0.0
@@ -12,6 +13,7 @@ require (
github.com/spf13/afero v1.15.0
github.com/spf13/cobra v1.10.1
github.com/stretchr/testify v1.11.1
+ golang.org/x/sys v0.37.0
google.golang.org/grpc v1.73.0
google.golang.org/protobuf v1.36.10
gopkg.in/yaml.v3 v3.0.1
@@ -26,7 +28,6 @@ require (
github.com/rogpeppe/go-internal v1.9.0 // indirect
github.com/spf13/pflag v1.0.9 // indirect
golang.org/x/net v0.38.0 // indirect
- golang.org/x/sys v0.31.0 // indirect
golang.org/x/text v0.28.0 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20250324211829-b45e905df463 // indirect
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
diff --git a/go.sum b/go.sum
index a013e203f..e2efd6d08 100644
--- a/go.sum
+++ b/go.sum
@@ -3,6 +3,8 @@ github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ3
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/ebitengine/purego v0.9.0 h1:mh0zpKBIXDceC63hpvPuGLiJ8ZAa3DfrFTudmfi8A4k=
+github.com/ebitengine/purego v0.9.0/go.mod h1:iIjxzd6CiRiOG0UyXP+V1+jWqUXVjPKLAI0mRfJZTmQ=
github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
@@ -12,8 +14,8 @@ github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6
github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM=
github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
-github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
-github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
+github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
+github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKeRZfjY=
@@ -30,10 +32,6 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
-github.com/linkedin/goavro/v2 v2.13.1 h1:4qZ5M0QzQFDRqccsroJlgOJznqAS/TpdvXg55h429+I=
-github.com/linkedin/goavro/v2 v2.13.1/go.mod h1:KXx+erlq+RPlGSPmLF7xGo6SAbh8sCQ53x064+ioxhk=
-github.com/linkedin/goavro/v2 v2.14.0 h1:aNO/js65U+Mwq4yB5f1h01c3wiM458qtRad1DN0CMUI=
-github.com/linkedin/goavro/v2 v2.14.0/go.mod h1:KXx+erlq+RPlGSPmLF7xGo6SAbh8sCQ53x064+ioxhk=
github.com/linkedin/goavro/v2 v2.14.1 h1:/8VjDpd38PRsy02JS0jflAu7JZPfJcGTwqWgMkFS2iI=
github.com/linkedin/goavro/v2 v2.14.1/go.mod h1:KXx+erlq+RPlGSPmLF7xGo6SAbh8sCQ53x064+ioxhk=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
@@ -42,70 +40,40 @@ github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTE
github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
-github.com/spf13/afero v1.12.0 h1:UcOPyRBYczmFn6yvphxkn9ZEOY65cpwGKb5mL36mrqs=
-github.com/spf13/afero v1.12.0/go.mod h1:ZTlWwG4/ahT8W7T0WQ5uYmjI9duaLQGy3Q2OAl4sk/4=
-github.com/spf13/afero v1.14.0 h1:9tH6MapGnn/j0eb0yIXiLjERO8RB6xIVZRDCX7PtqWA=
-github.com/spf13/afero v1.14.0/go.mod h1:acJQ8t0ohCGuMN3O+Pv0V0hgMxNYDlvdk+VTfyZmbYo=
github.com/spf13/afero v1.15.0 h1:b/YBCLWAJdFWJTN9cLhiXXcD7mzKn9Dm86dNnfyQw1I=
github.com/spf13/afero v1.15.0/go.mod h1:NC2ByUVxtQs4b3sIUphxK0NioZnmxgyCrfzeuq8lxMg=
-github.com/spf13/cobra v1.9.1 h1:CXSaggrXdbHK9CF+8ywj8Amf7PBRmPCOJugH954Nnlo=
-github.com/spf13/cobra v1.9.1/go.mod h1:nDyEzZ8ogv936Cinf6g1RU9MRY64Ir93oCnqb9wxYW0=
github.com/spf13/cobra v1.10.1 h1:lJeBwCfmrnXthfAupyUTzJ/J4Nc1RsHC/mSRU2dll/s=
github.com/spf13/cobra v1.10.1/go.mod h1:7SmJGaTHFVBY0jW4NXGluQoLvhqFQM+6XSKD+P4XaB0=
-github.com/spf13/pflag v1.0.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o=
-github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/spf13/pflag v1.0.9 h1:9exaQaMOCwffKiiiYk6/BndUBv+iRViNW+4lEMi0PvY=
github.com/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.5/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
-github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
-github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
-go.opentelemetry.io/otel v1.32.0 h1:WnBN+Xjcteh0zdk01SVqV55d/m62NJLJdIyb4y/WO5U=
-go.opentelemetry.io/otel v1.32.0/go.mod h1:00DCVSB0RQcnzlwyTfqtxSm+DRr9hpYrHjNGiBHVQIg=
-go.opentelemetry.io/otel/metric v1.32.0 h1:xV2umtmNcThh2/a/aCP+h64Xx5wsj8qqnkYZktzNa0M=
-go.opentelemetry.io/otel/metric v1.32.0/go.mod h1:jH7CIbbK6SH2V2wE16W05BHCtIDzauciCRLoc/SyMv8=
-go.opentelemetry.io/otel/sdk v1.32.0 h1:RNxepc9vK59A8XsgZQouW8ue8Gkb4jpWtJm9ge5lEG4=
-go.opentelemetry.io/otel/sdk v1.32.0/go.mod h1:LqgegDBjKMmb2GC6/PrTnteJG39I8/vJCAP9LlJXEjU=
-go.opentelemetry.io/otel/sdk/metric v1.32.0 h1:rZvFnvmvawYb0alrYkjraqJq0Z4ZUJAiyYCU9snn1CU=
-go.opentelemetry.io/otel/sdk/metric v1.32.0/go.mod h1:PWeZlq0zt9YkYAp3gjKZ0eicRYvOh1Gd+X99x6GHpCQ=
-go.opentelemetry.io/otel/trace v1.32.0 h1:WIC9mYrXf8TmY/EXuULKc8hR17vE+Hjv2cssQDe03fM=
-go.opentelemetry.io/otel/trace v1.32.0/go.mod h1:+i4rkvCraA+tG6AzwloGaCtkx53Fa+L+V8e9a7YvhT8=
-golang.org/x/net v0.33.0 h1:74SYHlV8BIgHIFC/LrYkOGIwL19eTYXQ5wc6TBuO36I=
-golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4=
-golang.org/x/net v0.34.0 h1:Mb7Mrk043xzHgnRM88suvJFwzVrRfHEHJEl5/71CKw0=
-golang.org/x/net v0.34.0/go.mod h1:di0qlW3YNM5oh6GqDGQr92MyTozJPmybPK4Ev/Gm31k=
+go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA=
+go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A=
+go.opentelemetry.io/otel v1.35.0 h1:xKWKPxrxB6OtMCbmMY021CqC45J+3Onta9MqjhnusiQ=
+go.opentelemetry.io/otel v1.35.0/go.mod h1:UEqy8Zp11hpkUrL73gSlELM0DupHoiq72dR+Zqel/+Y=
+go.opentelemetry.io/otel/metric v1.35.0 h1:0znxYu2SNyuMSQT4Y9WDWej0VpcsxkuklLa4/siN90M=
+go.opentelemetry.io/otel/metric v1.35.0/go.mod h1:nKVFgxBZ2fReX6IlyW28MgZojkoAkJGaE8CpgeAU3oE=
+go.opentelemetry.io/otel/sdk v1.35.0 h1:iPctf8iprVySXSKJffSS79eOjl9pvxV9ZqOWT0QejKY=
+go.opentelemetry.io/otel/sdk v1.35.0/go.mod h1:+ga1bZliga3DxJ3CQGg3updiaAJoNECOgJREo9KHGQg=
+go.opentelemetry.io/otel/sdk/metric v1.35.0 h1:1RriWBmCKgkeHEhM7a2uMjMUfP7MsOF5JpUCaEqEI9o=
+go.opentelemetry.io/otel/sdk/metric v1.35.0/go.mod h1:is6XYCUMpcKi+ZsOvfluY5YstFnhW0BidkR+gL+qN+w=
+go.opentelemetry.io/otel/trace v1.35.0 h1:dPpEfJu1sDIqruz7BHFG3c7528f6ddfSWfFDVt/xgMs=
+go.opentelemetry.io/otel/trace v1.35.0/go.mod h1:WUk7DtFp1Aw2MkvqGdwiXYDZZNvA/1J8o6xRXLrIkyc=
golang.org/x/net v0.38.0 h1:vRMAPTMaeGqVhG5QyLJHqNDwecKTomGeqbnfZyKlBI8=
golang.org/x/net v0.38.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8=
-golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU=
-golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
-golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik=
-golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
-golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo=
-golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
-golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY=
-golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4=
+golang.org/x/sys v0.37.0 h1:fdNQudmxPjkdUTPnLn5mdQv7Zwvbvpaxqs831goi9kQ=
+golang.org/x/sys v0.37.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
golang.org/x/text v0.28.0 h1:rhazDwis8INMIwQ4tpjLDzUhx6RlXqZNPEM0huQojng=
golang.org/x/text v0.28.0/go.mod h1:U8nCwOR8jO/marOQ0QbDiOngZVEBB7MAiitBuMjXiNU=
-google.golang.org/genproto/googleapis/rpc v0.0.0-20241223144023-3abc09e42ca8 h1:TqExAhdPaB60Ux47Cn0oLV07rGnxZzIsaRhQaqS666A=
-google.golang.org/genproto/googleapis/rpc v0.0.0-20241223144023-3abc09e42ca8/go.mod h1:lcTa1sDdWEIHMWlITnIczmw5w60CF9ffkb8Z+DVmmjA=
-google.golang.org/genproto/googleapis/rpc v0.0.0-20250115164207-1a7da9e5054f h1:OxYkA3wjPsZyBylwymxSHa7ViiW1Sml4ToBrncvFehI=
-google.golang.org/genproto/googleapis/rpc v0.0.0-20250115164207-1a7da9e5054f/go.mod h1:+2Yz8+CLJbIfL9z73EW45avw8Lmge3xVElCP9zEKi50=
google.golang.org/genproto/googleapis/rpc v0.0.0-20250324211829-b45e905df463 h1:e0AIkUUhxyBKh6ssZNrAMeqhA7RKUj42346d1y02i2g=
google.golang.org/genproto/googleapis/rpc v0.0.0-20250324211829-b45e905df463/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A=
-google.golang.org/grpc v1.70.0 h1:pWFv03aZoHzlRKHWicjsZytKAiYCtNS0dHbXnIdq7jQ=
-google.golang.org/grpc v1.70.0/go.mod h1:ofIJqVKDXx/JiXrwr2IG4/zwdH9txy3IlF40RmcJSQw=
-google.golang.org/grpc v1.71.0 h1:kF77BGdPTQ4/JZWMlb9VpJ5pa25aqvVqogsxNHHdeBg=
-google.golang.org/grpc v1.71.0/go.mod h1:H0GRtasmQOh9LkFoCPDu3ZrwUtD1YGE+b2vYBYd/8Ec=
google.golang.org/grpc v1.73.0 h1:VIWSmpI2MegBtTuFt5/JWy2oXxtjJ/e89Z70ImfD2ok=
google.golang.org/grpc v1.73.0/go.mod h1:50sbHOUqWoCQGI8V2HQLJM0B+LMlIUjNSZmow7EVBQc=
-google.golang.org/protobuf v1.36.5 h1:tPhr+woSbjfYvY6/GPufUoYizxw1cF/yFoxJ2fmpwlM=
-google.golang.org/protobuf v1.36.5/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
-google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY=
-google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY=
google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE=
google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
diff --git a/installer/installer.go b/installer/installer.go
index 30965e1fa..da91ae437 100644
--- a/installer/installer.go
+++ b/installer/installer.go
@@ -88,6 +88,29 @@ func (i *Installer) SetLibDir(dir string) {
i.libDir = dir
}
+// SetConfigLibDir stores the libDir in the config
+func (i *Installer) SetConfigLibDir(dir string) {
+ // print debug log
+ log.Printf("[DEBUG] setting config lib dir to %s", dir)
+ c := i.config.readConfig()
+ c.LibDir = dir
+ if err := i.config.writeConfig(c); err != nil {
+ log.Printf("[ERROR] failed to write config: %v", err)
+ }
+}
+
+// GetConfigLibDir retrieves the libDir from config
+func GetConfigLibDir() string {
+ c := &configuration{}
+ config := c.readConfig()
+ return config.LibDir
+}
+
+// GetActualLibDir returns the actual library directory being used
+func (i *Installer) GetActualLibDir() string {
+ return i.getLibDir()
+}
+
// Force installs over the top
func (i *Installer) Force(force bool) {
i.force = force
@@ -133,8 +156,13 @@ func (i *Installer) getLibDir() string {
if env != "" {
return env
}
+ homeDir, err := os.UserHomeDir()
+ if err != nil {
+ log.Printf("[WARN] Could not determine home directory: %v", err)
+ return ""
+ }
- return "/usr/local/lib"
+ return filepath.Join(homeDir, ".pact", "pact-go", "libs")
}
// CheckPackageInstall discovers any existing packages, and checks installation of a given binary using semver-compatible checks
@@ -446,6 +474,7 @@ type packageMetadata struct {
type pactConfig struct {
Libraries map[string]packageMetadata
+ LibDir string `yaml:"libDir,omitempty"`
}
type configReader interface {
diff --git a/installer/installer_test.go b/installer/installer_test.go
index dd6c85492..5729cda9e 100644
--- a/installer/installer_test.go
+++ b/installer/installer_test.go
@@ -18,7 +18,7 @@ func TestNativeLibPath(t *testing.T) {
libFilePath := filepath.Join(lib, "lib.go")
file, err := os.ReadFile(libFilePath)
assert.NoError(t, err)
- assert.Contains(t, string(file), "-lpact_ffi")
+ assert.Contains(t, string(file), "libpact_ffi")
}
// 1. Be able to specify the path of the binary in advance
diff --git a/internal/native/lib.go b/internal/native/lib.go
index d4324ff52..b7007ad1a 100644
--- a/internal/native/lib.go
+++ b/internal/native/lib.go
@@ -1,11 +1,600 @@
// Package native contains the c bindings into the Pact Reference types.
package native
-/*
-#cgo darwin,arm64 LDFLAGS: -L/tmp -L/usr/local/lib -Wl,-rpath -Wl,/tmp -Wl,-rpath -Wl,/usr/local/lib -lpact_ffi
-#cgo darwin,amd64 LDFLAGS: -L/tmp -L/usr/local/lib -Wl,-rpath -Wl,/tmp -Wl,-rpath -Wl,/usr/local/lib -lpact_ffi
-#cgo windows,amd64 LDFLAGS: -lpact_ffi
-#cgo linux,amd64 LDFLAGS: -L/tmp -L/opt/pact/lib -L/usr/local/lib -Wl,-rpath -Wl,/opt/pact/lib -Wl,-rpath -Wl,/tmp -Wl,-rpath -Wl,/usr/local/lib -lpact_ffi
-#cgo linux,arm64 LDFLAGS: -L/tmp -L/opt/pact/lib -L/usr/local/lib -Wl,-rpath -Wl,/opt/pact/lib -Wl,-rpath -Wl,/tmp -Wl,-rpath -Wl,/usr/local/lib -lpact_ffi
-*/
-import "C"
+import (
+ "fmt"
+ "os"
+ "path/filepath"
+ "runtime"
+ "unsafe"
+
+ "github.com/ebitengine/purego"
+)
+
+func getSystemLibrary() string {
+ switch runtime.GOOS {
+ case "darwin":
+ return "libpact_ffi.dylib"
+ case "linux":
+ return "libpact_ffi.so"
+ case "windows":
+ return "pact_ffi.dll"
+ default:
+ panic(fmt.Errorf("GOOS=%s is not supported", runtime.GOOS))
+ }
+}
+
+type (
+ size_t uintptr
+)
+
+var pactffi_version func() string
+var pactffi_init func(string)
+var pactffi_init_with_log_level func(string)
+var pactffi_enable_ansi_support func()
+var pactffi_log_message func(string, string, string)
+var pactffi_match_message func(uintptr, uintptr) uintptr
+var pactffi_mismatches_get_iter func(uintptr) uintptr
+var pactffi_mismatches_delete func(uintptr)
+var pactffi_mismatches_iter_next func(uintptr) uintptr
+var pactffi_mismatches_iter_delete func(uintptr)
+var pactffi_mismatch_to_json func(uintptr) string
+var pactffi_mismatch_type func(uintptr) string
+var pactffi_mismatch_summary func(uintptr) string
+var pactffi_mismatch_description func(uintptr) string
+var pactffi_mismatch_ansi_description func(uintptr) string
+var pactffi_get_error_message func(string, int32) int32
+var pactffi_log_to_stdout func(int32) int32
+var pactffi_log_to_stderr func(int32) int32
+var pactffi_log_to_file func(string, int32) int32
+var pactffi_log_to_buffer func(int32) int32
+var pactffi_logger_init func()
+var pactffi_logger_attach_sink func(string, int32) int32
+var pactffi_logger_apply func() int32
+var pactffi_fetch_log_buffer func(string) string
+var pactffi_parse_pact_json func(string) uintptr
+var pactffi_pact_model_delete func(uintptr)
+var pactffi_pact_model_interaction_iterator func(uintptr) uintptr
+var pactffi_pact_spec_version func(uintptr) int32
+var pactffi_pact_interaction_delete func(uintptr)
+var pactffi_async_message_new func() uintptr
+var pactffi_async_message_delete func(uintptr)
+var pactffi_async_message_get_contents func(uintptr) uintptr
+var pactffi_async_message_get_contents_str func(uintptr) string
+var pactffi_async_message_set_contents_str func(uintptr, string, string)
+var pactffi_async_message_get_contents_length func(uintptr) size_t
+var pactffi_async_message_get_contents_bin func(uintptr) uintptr
+var pactffi_async_message_set_contents_bin func(uintptr, uintptr, size_t, string)
+var pactffi_async_message_get_description func(uintptr) string
+var pactffi_async_message_set_description func(uintptr, string) int32
+var pactffi_async_message_get_provider_state func(uintptr, uint32) uintptr
+var pactffi_async_message_get_provider_state_iter func(uintptr) uintptr
+var pactffi_consumer_get_name func(uintptr) string
+var pactffi_pact_get_consumer func(uintptr) uintptr
+var pactffi_pact_consumer_delete func(uintptr)
+var pactffi_message_contents_get_contents_str func(uintptr) string
+var pactffi_message_contents_set_contents_str func(uintptr, string, string)
+var pactffi_message_contents_get_contents_length func(uintptr) size_t
+var pactffi_message_contents_get_contents_bin func(uintptr) uintptr
+var pactffi_message_contents_set_contents_bin func(uintptr, uintptr, size_t, string)
+var pactffi_message_contents_get_metadata_iter func(uintptr) uintptr
+var pactffi_message_contents_get_matching_rule_iter func(uintptr, int32) uintptr
+var pactffi_request_contents_get_matching_rule_iter func(uintptr, int32) uintptr
+var pactffi_response_contents_get_matching_rule_iter func(uintptr, int32) uintptr
+var pactffi_message_contents_get_generators_iter func(uintptr, int32) uintptr
+var pactffi_request_contents_get_generators_iter func(uintptr, int32) uintptr
+var pactffi_response_contents_get_generators_iter func(uintptr, int32) uintptr
+var pactffi_parse_matcher_definition func(string) uintptr
+var pactffi_matcher_definition_error func(uintptr) string
+var pactffi_matcher_definition_value func(uintptr) string
+var pactffi_matcher_definition_delete func(uintptr)
+var pactffi_matcher_definition_generator func(uintptr) uintptr
+var pactffi_matcher_definition_value_type func(uintptr) int32
+var pactffi_matching_rule_iter_delete func(uintptr)
+var pactffi_matcher_definition_iter func(uintptr) uintptr
+var pactffi_matching_rule_iter_next func(uintptr) uintptr
+var pactffi_matching_rule_id func(uintptr) uint16
+var pactffi_matching_rule_value func(uintptr) string
+var pactffi_matching_rule_pointer func(uintptr) uintptr
+var pactffi_matching_rule_reference_name func(uintptr) string
+var pactffi_validate_datetime func(string, string) int32
+var pactffi_generator_to_json func(uintptr) string
+var pactffi_generator_generate_string func(uintptr, string) string
+var pactffi_generator_generate_integer func(uintptr, string) uint16
+var pactffi_generators_iter_delete func(uintptr)
+var pactffi_generators_iter_next func(uintptr) uintptr
+var pactffi_generators_iter_pair_delete func(uintptr)
+var pactffi_sync_http_new func() uintptr
+var pactffi_sync_http_delete func(uintptr)
+var pactffi_sync_http_get_request func(uintptr) uintptr
+var pactffi_sync_http_get_request_contents func(uintptr) string
+var pactffi_sync_http_set_request_contents func(uintptr, string, string)
+var pactffi_sync_http_get_request_contents_length func(uintptr) size_t
+var pactffi_sync_http_get_request_contents_bin func(uintptr) uintptr
+var pactffi_sync_http_set_request_contents_bin func(uintptr, uintptr, size_t, string)
+var pactffi_sync_http_get_response func(uintptr) uintptr
+var pactffi_sync_http_get_response_contents func(uintptr) string
+var pactffi_sync_http_set_response_contents func(uintptr, string, string)
+var pactffi_sync_http_get_response_contents_length func(uintptr) size_t
+var pactffi_sync_http_get_response_contents_bin func(uintptr) uintptr
+var pactffi_sync_http_set_response_contents_bin func(uintptr, uintptr, size_t, string)
+var pactffi_sync_http_get_description func(uintptr) string
+var pactffi_sync_http_set_description func(uintptr, string) int32
+var pactffi_sync_http_get_provider_state func(uintptr, uint32) uintptr
+var pactffi_sync_http_get_provider_state_iter func(uintptr) uintptr
+var pactffi_pact_interaction_as_synchronous_http func(uintptr) uintptr
+var pactffi_pact_interaction_as_message func(uintptr) uintptr
+var pactffi_pact_interaction_as_asynchronous_message func(uintptr) uintptr
+var pactffi_pact_interaction_as_synchronous_message func(uintptr) uintptr
+var pactffi_pact_message_iter_delete func(uintptr)
+var pactffi_pact_message_iter_next func(uintptr) uintptr
+var pactffi_pact_sync_message_iter_next func(uintptr) uintptr
+var pactffi_pact_sync_message_iter_delete func(uintptr)
+var pactffi_pact_sync_http_iter_next func(uintptr) uintptr
+var pactffi_pact_sync_http_iter_delete func(uintptr)
+var pactffi_pact_interaction_iter_next func(uintptr) uintptr
+var pactffi_pact_interaction_iter_delete func(uintptr)
+var pactffi_matching_rule_to_json func(uintptr) string
+var pactffi_matching_rules_iter_delete func(uintptr)
+var pactffi_matching_rules_iter_next func(uintptr) uintptr
+var pactffi_matching_rules_iter_pair_delete func(uintptr)
+var pactffi_message_new func() uintptr
+var pactffi_message_new_from_json func(uint32, string, int32) uintptr
+var pactffi_message_new_from_body func(string, string) uintptr
+var pactffi_message_delete func(uintptr)
+var pactffi_message_get_contents func(uintptr) string
+var pactffi_message_set_contents func(uintptr, string, string)
+var pactffi_message_get_contents_length func(uintptr) size_t
+var pactffi_message_get_contents_bin func(uintptr) uintptr
+var pactffi_message_set_contents_bin func(uintptr, uintptr, size_t, string)
+var pactffi_message_get_description func(uintptr) string
+var pactffi_message_set_description func(uintptr, string) int32
+var pactffi_message_get_provider_state func(uintptr, uint32) uintptr
+var pactffi_message_get_provider_state_iter func(uintptr) uintptr
+var pactffi_provider_state_iter_next func(uintptr) uintptr
+var pactffi_provider_state_iter_delete func(uintptr)
+var pactffi_message_find_metadata func(uintptr, string) string
+var pactffi_message_insert_metadata func(uintptr, string, string) int32
+var pactffi_message_metadata_iter_next func(uintptr) uintptr
+var pactffi_message_get_metadata_iter func(uintptr) uintptr
+var pactffi_message_metadata_iter_delete func(uintptr)
+var pactffi_message_metadata_pair_delete func(uintptr)
+var pactffi_message_pact_new_from_json func(string, string) uintptr
+var pactffi_message_pact_delete func(uintptr)
+var pactffi_message_pact_get_consumer func(uintptr) uintptr
+var pactffi_message_pact_get_provider func(uintptr) uintptr
+var pactffi_message_pact_get_message_iter func(uintptr) uintptr
+var pactffi_message_pact_message_iter_next func(uintptr) uintptr
+var pactffi_message_pact_message_iter_delete func(uintptr)
+var pactffi_message_pact_find_metadata func(uintptr, string, string) string
+var pactffi_message_pact_get_metadata_iter func(uintptr) uintptr
+var pactffi_message_pact_metadata_iter_next func(uintptr) uintptr
+var pactffi_message_pact_metadata_iter_delete func(uintptr)
+var pactffi_message_pact_metadata_triple_delete func(uintptr)
+var pactffi_provider_get_name func(uintptr) string
+var pactffi_pact_get_provider func(uintptr) uintptr
+var pactffi_pact_provider_delete func(uintptr)
+var pactffi_provider_state_get_name func(uintptr) string
+var pactffi_provider_state_get_param_iter func(uintptr) uintptr
+var pactffi_provider_state_param_iter_next func(uintptr) uintptr
+var pactffi_provider_state_delete func(uintptr)
+var pactffi_provider_state_param_iter_delete func(uintptr)
+var pactffi_provider_state_param_pair_delete func(uintptr)
+var pactffi_sync_message_new func() uintptr
+var pactffi_sync_message_delete func(uintptr)
+var pactffi_sync_message_get_request_contents_str func(uintptr) string
+var pactffi_sync_message_set_request_contents_str func(uintptr, string, string)
+var pactffi_sync_message_get_request_contents_length func(uintptr) size_t
+var pactffi_sync_message_get_request_contents_bin func(uintptr) uintptr
+var pactffi_sync_message_set_request_contents_bin func(uintptr, uintptr, size_t, string)
+var pactffi_sync_message_get_request_contents func(uintptr) uintptr
+var pactffi_sync_message_get_number_responses func(uintptr) size_t
+var pactffi_sync_message_get_response_contents_str func(uintptr, size_t) string
+var pactffi_sync_message_set_response_contents_str func(uintptr, size_t, string, string)
+var pactffi_sync_message_get_response_contents_length func(uintptr, size_t) size_t
+var pactffi_sync_message_get_response_contents_bin func(uintptr, size_t) uintptr
+var pactffi_sync_message_set_response_contents_bin func(uintptr, size_t, uintptr, size_t, string)
+var pactffi_sync_message_get_response_contents func(uintptr, size_t) uintptr
+var pactffi_sync_message_get_description func(uintptr) string
+var pactffi_sync_message_set_description func(uintptr, string) int32
+var pactffi_sync_message_get_provider_state func(uintptr, uint32) uintptr
+var pactffi_sync_message_get_provider_state_iter func(uintptr) uintptr
+var pactffi_string_delete func(string)
+var pactffi_create_mock_server func(string, string, bool) int32
+var pactffi_get_tls_ca_certificate func() string
+var pactffi_create_mock_server_for_pact func(uintptr, string, bool) int32
+var pactffi_create_mock_server_for_transport func(uintptr, string, uint16, string, string) int32
+var pactffi_mock_server_matched func(int32) bool
+var pactffi_mock_server_mismatches func(int32) string
+var pactffi_cleanup_mock_server func(int32) bool
+var pactffi_write_pact_file func(int32, string, bool) int32
+var pactffi_mock_server_logs func(int32) string
+var pactffi_generate_datetime_string func(string) uintptr
+var pactffi_check_regex func(string, string) bool
+var pactffi_generate_regex_value func(string) uintptr
+var pactffi_free_string func(uintptr)
+var pactffi_new_pact func(string, string) uintptr
+var pactffi_pact_handle_to_pointer func(uint16) uintptr
+var pactffi_new_interaction func(uintptr, string) uintptr
+var pactffi_new_message_interaction func(uintptr, string) uintptr
+var pactffi_new_sync_message_interaction func(uintptr, string) uintptr
+var pactffi_upon_receiving func(uintptr, string) bool
+var pactffi_given func(uintptr, string) bool
+var pactffi_interaction_test_name func(uint32, string) uint32
+var pactffi_given_with_param func(uintptr, string, string, string) bool
+var pactffi_given_with_params func(uintptr, string, string) int32
+var pactffi_with_request func(uintptr, string, string) bool
+var pactffi_with_query_parameter func(uintptr, string, int, string) bool
+var pactffi_with_query_parameter_v2 func(uintptr, string, int, string) bool
+var pactffi_with_specification func(uintptr, int32) bool
+var pactffi_handle_get_pact_spec_version func(uint16) int32
+var pactffi_with_pact_metadata func(uintptr, string, string, string) bool
+var pactffi_with_header func(uintptr, int32, string, int, string) bool
+var pactffi_with_header_v2 func(uintptr, int32, string, int, string) bool
+var pactffi_set_header func(uint32, int32, string, string) bool
+var pactffi_response_status func(uintptr, uint16) bool
+var pactffi_response_status_v2 func(uintptr, string) bool
+var pactffi_with_body func(uintptr, int32, string, string) bool
+var pactffi_with_binary_body func(uint32, int32, string, string, size_t) bool
+var pactffi_with_binary_file func(uintptr, int32, string, string, size_t) bool
+var pactffi_with_matching_rules func(uint32, int32, string) bool
+var pactffi_with_multipart_file_v2 func(uint32, int32, string, string, string, string) uintptr
+var pactffi_with_multipart_file func(uintptr, int32, string, string, string) uintptr
+var pactffi_pact_handle_get_message_iter func(uintptr) uintptr
+var pactffi_pact_handle_get_sync_message_iter func(uintptr) uintptr
+var pactffi_pact_handle_get_sync_http_iter func(uint16) uintptr
+var pactffi_new_message_pact func(string, string) uintptr
+var pactffi_new_message func(uint16, string) uint32
+var pactffi_with_metadata func(uintptr, string, string, int) bool
+var pactffi_message_expects_to_receive func(uintptr, string)
+var pactffi_message_given func(uintptr, string)
+var pactffi_message_given_with_param func(uintptr, string, string, string)
+var pactffi_message_with_contents func(uintptr, string, uintptr, size_t)
+var pactffi_message_with_metadata func(uintptr, string, string)
+var pactffi_message_with_metadata_v2 func(uint32, string, string)
+var pactffi_message_reify func(uint32) string
+var pactffi_write_message_pact_file func(uintptr, string, bool) int32
+var pactffi_with_message_pact_metadata func(uintptr, string, string, string)
+var pactffi_pact_handle_write_file func(uint16, string, bool) int32
+var pactffi_new_async_message func(uint16, string) uint32
+var pactffi_free_pact_handle func(uint16) uint32
+var pactffi_free_message_pact_handle func(uint16) uint32
+var pactffi_verify func(string) int32
+var pactffi_verifier_new func() uintptr
+var pactffi_verifier_new_for_application func(string, string) uintptr
+var pactffi_verifier_shutdown func(uintptr)
+var pactffi_verifier_set_provider_info func(uintptr, string, string, string, uint16, string)
+var pactffi_verifier_add_provider_transport func(uintptr, string, uint16, string, string)
+var pactffi_verifier_set_filter_info func(uintptr, string, string, uint8)
+var pactffi_verifier_set_provider_state func(uintptr, string, uint8, uint8)
+var pactffi_verifier_set_verification_options func(uintptr, uint8, uint64) int32
+var pactffi_verifier_set_coloured_output func(uintptr, uint8) int32
+var pactffi_verifier_set_no_pacts_is_error func(uintptr, uint8) int32
+var pactffi_verifier_set_publish_options func(uintptr, string, string, []*byte, uint16, string) int32
+var pactffi_verifier_set_consumer_filters func(uintptr, []*byte, uint16)
+var pactffi_verifier_add_custom_header func(uintptr, string, string)
+var pactffi_verifier_add_file_source func(uintptr, string)
+var pactffi_verifier_add_directory_source func(uintptr, string)
+var pactffi_verifier_url_source func(uintptr, string, string, string, string)
+var pactffi_verifier_broker_source func(uintptr, string, string, string, string)
+var pactffi_verifier_broker_source_with_selectors func(uintptr, string, string, string, string, uint8, string, []*byte, uint16, string, []*byte, uint16, []*byte, uint16)
+var pactffi_verifier_execute func(uintptr) int32
+var pactffi_verifier_cli_args func() string
+var pactffi_verifier_logs func(uintptr) string
+var pactffi_verifier_logs_for_provider func(string) string
+var pactffi_verifier_output func(uintptr, uint8) string
+var pactffi_verifier_json func(uintptr) string
+var pactffi_using_plugin func(uintptr, string, string) uint32
+var pactffi_cleanup_plugins func(uintptr)
+var pactffi_interaction_contents func(uintptr, int32, string, string) uint32
+var pactffi_matches_string_value func(uintptr, string, string, uint8) string
+var pactffi_matches_u64_value func(uintptr, uint64, uint64, uint8) string
+var pactffi_matches_i64_value func(uintptr, int64, int64, uint8) string
+var pactffi_matches_f64_value func(uintptr, float64, float64, uint8) string
+var pactffi_matches_bool_value func(uintptr, uint8, uint8, uint8) string
+var pactffi_matches_binary_value func(uintptr, uintptr, uint64, uintptr, uint64, uint8) string
+var pactffi_matches_json_value func(uintptr, string, string, uint8) string
+
+func init() {
+ libpact_ffi, err := openLibrary(filepath.Join(os.Getenv("PACT_LD_LIBRARY_PATH"), getSystemLibrary()))
+ if err != nil {
+ panic(err)
+ }
+ purego.RegisterLibFunc(&pactffi_version, libpact_ffi, "pactffi_version")
+ purego.RegisterLibFunc(&pactffi_init, libpact_ffi, "pactffi_init")
+ purego.RegisterLibFunc(&pactffi_init_with_log_level, libpact_ffi, "pactffi_init_with_log_level")
+ purego.RegisterLibFunc(&pactffi_enable_ansi_support, libpact_ffi, "pactffi_enable_ansi_support")
+ purego.RegisterLibFunc(&pactffi_log_message, libpact_ffi, "pactffi_log_message")
+ purego.RegisterLibFunc(&pactffi_match_message, libpact_ffi, "pactffi_match_message")
+ purego.RegisterLibFunc(&pactffi_mismatches_get_iter, libpact_ffi, "pactffi_mismatches_get_iter")
+ purego.RegisterLibFunc(&pactffi_mismatches_delete, libpact_ffi, "pactffi_mismatches_delete")
+ purego.RegisterLibFunc(&pactffi_mismatches_iter_next, libpact_ffi, "pactffi_mismatches_iter_next")
+ purego.RegisterLibFunc(&pactffi_mismatches_iter_delete, libpact_ffi, "pactffi_mismatches_iter_delete")
+ purego.RegisterLibFunc(&pactffi_mismatch_to_json, libpact_ffi, "pactffi_mismatch_to_json")
+ purego.RegisterLibFunc(&pactffi_mismatch_type, libpact_ffi, "pactffi_mismatch_type")
+ purego.RegisterLibFunc(&pactffi_mismatch_summary, libpact_ffi, "pactffi_mismatch_summary")
+ purego.RegisterLibFunc(&pactffi_mismatch_description, libpact_ffi, "pactffi_mismatch_description")
+ purego.RegisterLibFunc(&pactffi_mismatch_ansi_description, libpact_ffi, "pactffi_mismatch_ansi_description")
+ purego.RegisterLibFunc(&pactffi_get_error_message, libpact_ffi, "pactffi_get_error_message")
+ purego.RegisterLibFunc(&pactffi_log_to_stdout, libpact_ffi, "pactffi_log_to_stdout")
+ purego.RegisterLibFunc(&pactffi_log_to_stderr, libpact_ffi, "pactffi_log_to_stderr")
+ purego.RegisterLibFunc(&pactffi_log_to_file, libpact_ffi, "pactffi_log_to_file")
+ purego.RegisterLibFunc(&pactffi_log_to_buffer, libpact_ffi, "pactffi_log_to_buffer")
+ purego.RegisterLibFunc(&pactffi_logger_init, libpact_ffi, "pactffi_logger_init")
+ purego.RegisterLibFunc(&pactffi_logger_attach_sink, libpact_ffi, "pactffi_logger_attach_sink")
+ purego.RegisterLibFunc(&pactffi_logger_apply, libpact_ffi, "pactffi_logger_apply")
+ purego.RegisterLibFunc(&pactffi_fetch_log_buffer, libpact_ffi, "pactffi_fetch_log_buffer")
+ purego.RegisterLibFunc(&pactffi_parse_pact_json, libpact_ffi, "pactffi_parse_pact_json")
+ purego.RegisterLibFunc(&pactffi_pact_model_delete, libpact_ffi, "pactffi_pact_model_delete")
+ purego.RegisterLibFunc(&pactffi_pact_model_interaction_iterator, libpact_ffi, "pactffi_pact_model_interaction_iterator")
+ purego.RegisterLibFunc(&pactffi_pact_spec_version, libpact_ffi, "pactffi_pact_spec_version")
+ purego.RegisterLibFunc(&pactffi_pact_interaction_delete, libpact_ffi, "pactffi_pact_interaction_delete")
+ purego.RegisterLibFunc(&pactffi_async_message_new, libpact_ffi, "pactffi_async_message_new")
+ purego.RegisterLibFunc(&pactffi_async_message_delete, libpact_ffi, "pactffi_async_message_delete")
+ purego.RegisterLibFunc(&pactffi_async_message_get_contents, libpact_ffi, "pactffi_async_message_get_contents")
+ purego.RegisterLibFunc(&pactffi_async_message_get_contents_str, libpact_ffi, "pactffi_async_message_get_contents_str")
+ purego.RegisterLibFunc(&pactffi_async_message_set_contents_str, libpact_ffi, "pactffi_async_message_set_contents_str")
+ purego.RegisterLibFunc(&pactffi_async_message_get_contents_length, libpact_ffi, "pactffi_async_message_get_contents_length")
+ purego.RegisterLibFunc(&pactffi_async_message_get_contents_bin, libpact_ffi, "pactffi_async_message_get_contents_bin")
+ purego.RegisterLibFunc(&pactffi_async_message_set_contents_bin, libpact_ffi, "pactffi_async_message_set_contents_bin")
+ purego.RegisterLibFunc(&pactffi_async_message_get_description, libpact_ffi, "pactffi_async_message_get_description")
+ purego.RegisterLibFunc(&pactffi_async_message_set_description, libpact_ffi, "pactffi_async_message_set_description")
+ purego.RegisterLibFunc(&pactffi_async_message_get_provider_state, libpact_ffi, "pactffi_async_message_get_provider_state")
+ purego.RegisterLibFunc(&pactffi_async_message_get_provider_state_iter, libpact_ffi, "pactffi_async_message_get_provider_state_iter")
+ purego.RegisterLibFunc(&pactffi_consumer_get_name, libpact_ffi, "pactffi_consumer_get_name")
+ purego.RegisterLibFunc(&pactffi_pact_get_consumer, libpact_ffi, "pactffi_pact_get_consumer")
+ purego.RegisterLibFunc(&pactffi_pact_consumer_delete, libpact_ffi, "pactffi_pact_consumer_delete")
+ purego.RegisterLibFunc(&pactffi_message_contents_get_contents_str, libpact_ffi, "pactffi_message_contents_get_contents_str")
+ purego.RegisterLibFunc(&pactffi_message_contents_set_contents_str, libpact_ffi, "pactffi_message_contents_set_contents_str")
+ purego.RegisterLibFunc(&pactffi_message_contents_get_contents_length, libpact_ffi, "pactffi_message_contents_get_contents_length")
+ purego.RegisterLibFunc(&pactffi_message_contents_get_contents_bin, libpact_ffi, "pactffi_message_contents_get_contents_bin")
+ purego.RegisterLibFunc(&pactffi_message_contents_set_contents_bin, libpact_ffi, "pactffi_message_contents_set_contents_bin")
+ purego.RegisterLibFunc(&pactffi_message_contents_get_metadata_iter, libpact_ffi, "pactffi_message_contents_get_metadata_iter")
+ purego.RegisterLibFunc(&pactffi_message_contents_get_matching_rule_iter, libpact_ffi, "pactffi_message_contents_get_matching_rule_iter")
+ purego.RegisterLibFunc(&pactffi_request_contents_get_matching_rule_iter, libpact_ffi, "pactffi_request_contents_get_matching_rule_iter")
+ purego.RegisterLibFunc(&pactffi_response_contents_get_matching_rule_iter, libpact_ffi, "pactffi_response_contents_get_matching_rule_iter")
+ purego.RegisterLibFunc(&pactffi_message_contents_get_generators_iter, libpact_ffi, "pactffi_message_contents_get_generators_iter")
+ purego.RegisterLibFunc(&pactffi_request_contents_get_generators_iter, libpact_ffi, "pactffi_request_contents_get_generators_iter")
+ purego.RegisterLibFunc(&pactffi_response_contents_get_generators_iter, libpact_ffi, "pactffi_response_contents_get_generators_iter")
+ purego.RegisterLibFunc(&pactffi_parse_matcher_definition, libpact_ffi, "pactffi_parse_matcher_definition")
+ purego.RegisterLibFunc(&pactffi_matcher_definition_error, libpact_ffi, "pactffi_matcher_definition_error")
+ purego.RegisterLibFunc(&pactffi_matcher_definition_value, libpact_ffi, "pactffi_matcher_definition_value")
+ purego.RegisterLibFunc(&pactffi_matcher_definition_delete, libpact_ffi, "pactffi_matcher_definition_delete")
+ purego.RegisterLibFunc(&pactffi_matcher_definition_generator, libpact_ffi, "pactffi_matcher_definition_generator")
+ purego.RegisterLibFunc(&pactffi_matcher_definition_value_type, libpact_ffi, "pactffi_matcher_definition_value_type")
+ purego.RegisterLibFunc(&pactffi_matching_rule_iter_delete, libpact_ffi, "pactffi_matching_rule_iter_delete")
+ purego.RegisterLibFunc(&pactffi_matcher_definition_iter, libpact_ffi, "pactffi_matcher_definition_iter")
+ purego.RegisterLibFunc(&pactffi_matching_rule_iter_next, libpact_ffi, "pactffi_matching_rule_iter_next")
+ purego.RegisterLibFunc(&pactffi_matching_rule_id, libpact_ffi, "pactffi_matching_rule_id")
+ purego.RegisterLibFunc(&pactffi_matching_rule_value, libpact_ffi, "pactffi_matching_rule_value")
+ purego.RegisterLibFunc(&pactffi_matching_rule_pointer, libpact_ffi, "pactffi_matching_rule_pointer")
+ purego.RegisterLibFunc(&pactffi_matching_rule_reference_name, libpact_ffi, "pactffi_matching_rule_reference_name")
+ purego.RegisterLibFunc(&pactffi_validate_datetime, libpact_ffi, "pactffi_validate_datetime")
+ purego.RegisterLibFunc(&pactffi_generator_to_json, libpact_ffi, "pactffi_generator_to_json")
+ purego.RegisterLibFunc(&pactffi_generator_generate_string, libpact_ffi, "pactffi_generator_generate_string")
+ purego.RegisterLibFunc(&pactffi_generator_generate_integer, libpact_ffi, "pactffi_generator_generate_integer")
+ purego.RegisterLibFunc(&pactffi_generators_iter_delete, libpact_ffi, "pactffi_generators_iter_delete")
+ purego.RegisterLibFunc(&pactffi_generators_iter_next, libpact_ffi, "pactffi_generators_iter_next")
+ purego.RegisterLibFunc(&pactffi_generators_iter_pair_delete, libpact_ffi, "pactffi_generators_iter_pair_delete")
+ purego.RegisterLibFunc(&pactffi_sync_http_new, libpact_ffi, "pactffi_sync_http_new")
+ purego.RegisterLibFunc(&pactffi_sync_http_delete, libpact_ffi, "pactffi_sync_http_delete")
+ purego.RegisterLibFunc(&pactffi_sync_http_get_request, libpact_ffi, "pactffi_sync_http_get_request")
+ purego.RegisterLibFunc(&pactffi_sync_http_get_request_contents, libpact_ffi, "pactffi_sync_http_get_request_contents")
+ purego.RegisterLibFunc(&pactffi_sync_http_set_request_contents, libpact_ffi, "pactffi_sync_http_set_request_contents")
+ purego.RegisterLibFunc(&pactffi_sync_http_get_request_contents_length, libpact_ffi, "pactffi_sync_http_get_request_contents_length")
+ purego.RegisterLibFunc(&pactffi_sync_http_get_request_contents_bin, libpact_ffi, "pactffi_sync_http_get_request_contents_bin")
+ purego.RegisterLibFunc(&pactffi_sync_http_set_request_contents_bin, libpact_ffi, "pactffi_sync_http_set_request_contents_bin")
+ purego.RegisterLibFunc(&pactffi_sync_http_get_response, libpact_ffi, "pactffi_sync_http_get_response")
+ purego.RegisterLibFunc(&pactffi_sync_http_get_response_contents, libpact_ffi, "pactffi_sync_http_get_response_contents")
+ purego.RegisterLibFunc(&pactffi_sync_http_set_response_contents, libpact_ffi, "pactffi_sync_http_set_response_contents")
+ purego.RegisterLibFunc(&pactffi_sync_http_get_response_contents_length, libpact_ffi, "pactffi_sync_http_get_response_contents_length")
+ purego.RegisterLibFunc(&pactffi_sync_http_get_response_contents_bin, libpact_ffi, "pactffi_sync_http_get_response_contents_bin")
+ purego.RegisterLibFunc(&pactffi_sync_http_set_response_contents_bin, libpact_ffi, "pactffi_sync_http_set_response_contents_bin")
+ purego.RegisterLibFunc(&pactffi_sync_http_get_description, libpact_ffi, "pactffi_sync_http_get_description")
+ purego.RegisterLibFunc(&pactffi_sync_http_set_description, libpact_ffi, "pactffi_sync_http_set_description")
+ purego.RegisterLibFunc(&pactffi_sync_http_get_provider_state, libpact_ffi, "pactffi_sync_http_get_provider_state")
+ purego.RegisterLibFunc(&pactffi_sync_http_get_provider_state_iter, libpact_ffi, "pactffi_sync_http_get_provider_state_iter")
+ purego.RegisterLibFunc(&pactffi_pact_interaction_as_synchronous_http, libpact_ffi, "pactffi_pact_interaction_as_synchronous_http")
+ purego.RegisterLibFunc(&pactffi_pact_interaction_as_message, libpact_ffi, "pactffi_pact_interaction_as_message")
+ purego.RegisterLibFunc(&pactffi_pact_interaction_as_asynchronous_message, libpact_ffi, "pactffi_pact_interaction_as_asynchronous_message")
+ purego.RegisterLibFunc(&pactffi_pact_interaction_as_synchronous_message, libpact_ffi, "pactffi_pact_interaction_as_synchronous_message")
+ purego.RegisterLibFunc(&pactffi_pact_message_iter_delete, libpact_ffi, "pactffi_pact_message_iter_delete")
+ purego.RegisterLibFunc(&pactffi_pact_message_iter_next, libpact_ffi, "pactffi_pact_message_iter_next")
+ purego.RegisterLibFunc(&pactffi_pact_sync_message_iter_next, libpact_ffi, "pactffi_pact_sync_message_iter_next")
+ purego.RegisterLibFunc(&pactffi_pact_sync_message_iter_delete, libpact_ffi, "pactffi_pact_sync_message_iter_delete")
+ purego.RegisterLibFunc(&pactffi_pact_sync_http_iter_next, libpact_ffi, "pactffi_pact_sync_http_iter_next")
+ purego.RegisterLibFunc(&pactffi_pact_sync_http_iter_delete, libpact_ffi, "pactffi_pact_sync_http_iter_delete")
+ purego.RegisterLibFunc(&pactffi_pact_interaction_iter_next, libpact_ffi, "pactffi_pact_interaction_iter_next")
+ purego.RegisterLibFunc(&pactffi_pact_interaction_iter_delete, libpact_ffi, "pactffi_pact_interaction_iter_delete")
+ purego.RegisterLibFunc(&pactffi_matching_rule_to_json, libpact_ffi, "pactffi_matching_rule_to_json")
+ purego.RegisterLibFunc(&pactffi_matching_rules_iter_delete, libpact_ffi, "pactffi_matching_rules_iter_delete")
+ purego.RegisterLibFunc(&pactffi_matching_rules_iter_next, libpact_ffi, "pactffi_matching_rules_iter_next")
+ purego.RegisterLibFunc(&pactffi_matching_rules_iter_pair_delete, libpact_ffi, "pactffi_matching_rules_iter_pair_delete")
+ purego.RegisterLibFunc(&pactffi_message_new, libpact_ffi, "pactffi_message_new")
+ purego.RegisterLibFunc(&pactffi_message_new_from_json, libpact_ffi, "pactffi_message_new_from_json")
+ purego.RegisterLibFunc(&pactffi_message_new_from_body, libpact_ffi, "pactffi_message_new_from_body")
+ purego.RegisterLibFunc(&pactffi_message_delete, libpact_ffi, "pactffi_message_delete")
+ purego.RegisterLibFunc(&pactffi_message_get_contents, libpact_ffi, "pactffi_message_get_contents")
+ purego.RegisterLibFunc(&pactffi_message_set_contents, libpact_ffi, "pactffi_message_set_contents")
+ purego.RegisterLibFunc(&pactffi_message_get_contents_length, libpact_ffi, "pactffi_message_get_contents_length")
+ purego.RegisterLibFunc(&pactffi_message_get_contents_bin, libpact_ffi, "pactffi_message_get_contents_bin")
+ purego.RegisterLibFunc(&pactffi_message_set_contents_bin, libpact_ffi, "pactffi_message_set_contents_bin")
+ purego.RegisterLibFunc(&pactffi_message_get_description, libpact_ffi, "pactffi_message_get_description")
+ purego.RegisterLibFunc(&pactffi_message_set_description, libpact_ffi, "pactffi_message_set_description")
+ purego.RegisterLibFunc(&pactffi_message_get_provider_state, libpact_ffi, "pactffi_message_get_provider_state")
+ purego.RegisterLibFunc(&pactffi_message_get_provider_state_iter, libpact_ffi, "pactffi_message_get_provider_state_iter")
+ purego.RegisterLibFunc(&pactffi_provider_state_iter_next, libpact_ffi, "pactffi_provider_state_iter_next")
+ purego.RegisterLibFunc(&pactffi_provider_state_iter_delete, libpact_ffi, "pactffi_provider_state_iter_delete")
+ purego.RegisterLibFunc(&pactffi_message_find_metadata, libpact_ffi, "pactffi_message_find_metadata")
+ purego.RegisterLibFunc(&pactffi_message_insert_metadata, libpact_ffi, "pactffi_message_insert_metadata")
+ purego.RegisterLibFunc(&pactffi_message_metadata_iter_next, libpact_ffi, "pactffi_message_metadata_iter_next")
+ purego.RegisterLibFunc(&pactffi_message_get_metadata_iter, libpact_ffi, "pactffi_message_get_metadata_iter")
+ purego.RegisterLibFunc(&pactffi_message_metadata_iter_delete, libpact_ffi, "pactffi_message_metadata_iter_delete")
+ purego.RegisterLibFunc(&pactffi_message_metadata_pair_delete, libpact_ffi, "pactffi_message_metadata_pair_delete")
+ purego.RegisterLibFunc(&pactffi_message_pact_new_from_json, libpact_ffi, "pactffi_message_pact_new_from_json")
+ purego.RegisterLibFunc(&pactffi_message_pact_delete, libpact_ffi, "pactffi_message_pact_delete")
+ purego.RegisterLibFunc(&pactffi_message_pact_get_consumer, libpact_ffi, "pactffi_message_pact_get_consumer")
+ purego.RegisterLibFunc(&pactffi_message_pact_get_provider, libpact_ffi, "pactffi_message_pact_get_provider")
+ purego.RegisterLibFunc(&pactffi_message_pact_get_message_iter, libpact_ffi, "pactffi_message_pact_get_message_iter")
+ purego.RegisterLibFunc(&pactffi_message_pact_message_iter_next, libpact_ffi, "pactffi_message_pact_message_iter_next")
+ purego.RegisterLibFunc(&pactffi_message_pact_message_iter_delete, libpact_ffi, "pactffi_message_pact_message_iter_delete")
+ purego.RegisterLibFunc(&pactffi_message_pact_find_metadata, libpact_ffi, "pactffi_message_pact_find_metadata")
+ purego.RegisterLibFunc(&pactffi_message_pact_get_metadata_iter, libpact_ffi, "pactffi_message_pact_get_metadata_iter")
+ purego.RegisterLibFunc(&pactffi_message_pact_metadata_iter_next, libpact_ffi, "pactffi_message_pact_metadata_iter_next")
+ purego.RegisterLibFunc(&pactffi_message_pact_metadata_iter_delete, libpact_ffi, "pactffi_message_pact_metadata_iter_delete")
+ purego.RegisterLibFunc(&pactffi_message_pact_metadata_triple_delete, libpact_ffi, "pactffi_message_pact_metadata_triple_delete")
+ purego.RegisterLibFunc(&pactffi_provider_get_name, libpact_ffi, "pactffi_provider_get_name")
+ purego.RegisterLibFunc(&pactffi_pact_get_provider, libpact_ffi, "pactffi_pact_get_provider")
+ purego.RegisterLibFunc(&pactffi_pact_provider_delete, libpact_ffi, "pactffi_pact_provider_delete")
+ purego.RegisterLibFunc(&pactffi_provider_state_get_name, libpact_ffi, "pactffi_provider_state_get_name")
+ purego.RegisterLibFunc(&pactffi_provider_state_get_param_iter, libpact_ffi, "pactffi_provider_state_get_param_iter")
+ purego.RegisterLibFunc(&pactffi_provider_state_param_iter_next, libpact_ffi, "pactffi_provider_state_param_iter_next")
+ purego.RegisterLibFunc(&pactffi_provider_state_delete, libpact_ffi, "pactffi_provider_state_delete")
+ purego.RegisterLibFunc(&pactffi_provider_state_param_iter_delete, libpact_ffi, "pactffi_provider_state_param_iter_delete")
+ purego.RegisterLibFunc(&pactffi_provider_state_param_pair_delete, libpact_ffi, "pactffi_provider_state_param_pair_delete")
+ purego.RegisterLibFunc(&pactffi_sync_message_new, libpact_ffi, "pactffi_sync_message_new")
+ purego.RegisterLibFunc(&pactffi_sync_message_delete, libpact_ffi, "pactffi_sync_message_delete")
+ purego.RegisterLibFunc(&pactffi_sync_message_get_request_contents_str, libpact_ffi, "pactffi_sync_message_get_request_contents_str")
+ purego.RegisterLibFunc(&pactffi_sync_message_set_request_contents_str, libpact_ffi, "pactffi_sync_message_set_request_contents_str")
+ purego.RegisterLibFunc(&pactffi_sync_message_get_request_contents_length, libpact_ffi, "pactffi_sync_message_get_request_contents_length")
+ purego.RegisterLibFunc(&pactffi_sync_message_get_request_contents_bin, libpact_ffi, "pactffi_sync_message_get_request_contents_bin")
+ purego.RegisterLibFunc(&pactffi_sync_message_set_request_contents_bin, libpact_ffi, "pactffi_sync_message_set_request_contents_bin")
+ purego.RegisterLibFunc(&pactffi_sync_message_get_request_contents, libpact_ffi, "pactffi_sync_message_get_request_contents")
+ purego.RegisterLibFunc(&pactffi_sync_message_get_number_responses, libpact_ffi, "pactffi_sync_message_get_number_responses")
+ purego.RegisterLibFunc(&pactffi_sync_message_get_response_contents_str, libpact_ffi, "pactffi_sync_message_get_response_contents_str")
+ purego.RegisterLibFunc(&pactffi_sync_message_set_response_contents_str, libpact_ffi, "pactffi_sync_message_set_response_contents_str")
+ purego.RegisterLibFunc(&pactffi_sync_message_get_response_contents_length, libpact_ffi, "pactffi_sync_message_get_response_contents_length")
+ purego.RegisterLibFunc(&pactffi_sync_message_get_response_contents_bin, libpact_ffi, "pactffi_sync_message_get_response_contents_bin")
+ purego.RegisterLibFunc(&pactffi_sync_message_set_response_contents_bin, libpact_ffi, "pactffi_sync_message_set_response_contents_bin")
+ purego.RegisterLibFunc(&pactffi_sync_message_get_response_contents, libpact_ffi, "pactffi_sync_message_get_response_contents")
+ purego.RegisterLibFunc(&pactffi_sync_message_get_description, libpact_ffi, "pactffi_sync_message_get_description")
+ purego.RegisterLibFunc(&pactffi_sync_message_set_description, libpact_ffi, "pactffi_sync_message_set_description")
+ purego.RegisterLibFunc(&pactffi_sync_message_get_provider_state, libpact_ffi, "pactffi_sync_message_get_provider_state")
+ purego.RegisterLibFunc(&pactffi_sync_message_get_provider_state_iter, libpact_ffi, "pactffi_sync_message_get_provider_state_iter")
+ purego.RegisterLibFunc(&pactffi_string_delete, libpact_ffi, "pactffi_string_delete")
+ purego.RegisterLibFunc(&pactffi_create_mock_server, libpact_ffi, "pactffi_create_mock_server")
+ purego.RegisterLibFunc(&pactffi_get_tls_ca_certificate, libpact_ffi, "pactffi_get_tls_ca_certificate")
+ purego.RegisterLibFunc(&pactffi_create_mock_server_for_pact, libpact_ffi, "pactffi_create_mock_server_for_pact")
+ purego.RegisterLibFunc(&pactffi_create_mock_server_for_transport, libpact_ffi, "pactffi_create_mock_server_for_transport")
+ purego.RegisterLibFunc(&pactffi_mock_server_matched, libpact_ffi, "pactffi_mock_server_matched")
+ purego.RegisterLibFunc(&pactffi_mock_server_mismatches, libpact_ffi, "pactffi_mock_server_mismatches")
+ purego.RegisterLibFunc(&pactffi_cleanup_mock_server, libpact_ffi, "pactffi_cleanup_mock_server")
+ purego.RegisterLibFunc(&pactffi_write_pact_file, libpact_ffi, "pactffi_write_pact_file")
+ purego.RegisterLibFunc(&pactffi_mock_server_logs, libpact_ffi, "pactffi_mock_server_logs")
+ purego.RegisterLibFunc(&pactffi_generate_datetime_string, libpact_ffi, "pactffi_generate_datetime_string")
+ purego.RegisterLibFunc(&pactffi_check_regex, libpact_ffi, "pactffi_check_regex")
+ purego.RegisterLibFunc(&pactffi_generate_regex_value, libpact_ffi, "pactffi_generate_regex_value")
+ purego.RegisterLibFunc(&pactffi_free_string, libpact_ffi, "pactffi_free_string")
+ purego.RegisterLibFunc(&pactffi_new_pact, libpact_ffi, "pactffi_new_pact")
+ purego.RegisterLibFunc(&pactffi_pact_handle_to_pointer, libpact_ffi, "pactffi_pact_handle_to_pointer")
+ purego.RegisterLibFunc(&pactffi_new_interaction, libpact_ffi, "pactffi_new_interaction")
+ purego.RegisterLibFunc(&pactffi_new_message_interaction, libpact_ffi, "pactffi_new_message_interaction")
+ purego.RegisterLibFunc(&pactffi_new_sync_message_interaction, libpact_ffi, "pactffi_new_sync_message_interaction")
+ purego.RegisterLibFunc(&pactffi_upon_receiving, libpact_ffi, "pactffi_upon_receiving")
+ purego.RegisterLibFunc(&pactffi_given, libpact_ffi, "pactffi_given")
+ purego.RegisterLibFunc(&pactffi_interaction_test_name, libpact_ffi, "pactffi_interaction_test_name")
+ purego.RegisterLibFunc(&pactffi_given_with_param, libpact_ffi, "pactffi_given_with_param")
+ purego.RegisterLibFunc(&pactffi_given_with_params, libpact_ffi, "pactffi_given_with_params")
+ purego.RegisterLibFunc(&pactffi_with_request, libpact_ffi, "pactffi_with_request")
+ purego.RegisterLibFunc(&pactffi_with_query_parameter, libpact_ffi, "pactffi_with_query_parameter")
+ purego.RegisterLibFunc(&pactffi_with_query_parameter_v2, libpact_ffi, "pactffi_with_query_parameter_v2")
+ purego.RegisterLibFunc(&pactffi_with_specification, libpact_ffi, "pactffi_with_specification")
+ purego.RegisterLibFunc(&pactffi_handle_get_pact_spec_version, libpact_ffi, "pactffi_handle_get_pact_spec_version")
+ purego.RegisterLibFunc(&pactffi_with_pact_metadata, libpact_ffi, "pactffi_with_pact_metadata")
+ purego.RegisterLibFunc(&pactffi_with_header, libpact_ffi, "pactffi_with_header")
+ purego.RegisterLibFunc(&pactffi_with_header_v2, libpact_ffi, "pactffi_with_header_v2")
+ purego.RegisterLibFunc(&pactffi_set_header, libpact_ffi, "pactffi_set_header")
+ purego.RegisterLibFunc(&pactffi_response_status, libpact_ffi, "pactffi_response_status")
+ purego.RegisterLibFunc(&pactffi_response_status_v2, libpact_ffi, "pactffi_response_status_v2")
+ purego.RegisterLibFunc(&pactffi_with_body, libpact_ffi, "pactffi_with_body")
+ purego.RegisterLibFunc(&pactffi_with_binary_body, libpact_ffi, "pactffi_with_binary_body")
+ purego.RegisterLibFunc(&pactffi_with_binary_file, libpact_ffi, "pactffi_with_binary_file")
+ purego.RegisterLibFunc(&pactffi_with_matching_rules, libpact_ffi, "pactffi_with_matching_rules")
+ purego.RegisterLibFunc(&pactffi_with_multipart_file_v2, libpact_ffi, "pactffi_with_multipart_file_v2")
+ purego.RegisterLibFunc(&pactffi_with_multipart_file, libpact_ffi, "pactffi_with_multipart_file")
+ purego.RegisterLibFunc(&pactffi_pact_handle_get_message_iter, libpact_ffi, "pactffi_pact_handle_get_message_iter")
+ purego.RegisterLibFunc(&pactffi_pact_handle_get_sync_message_iter, libpact_ffi, "pactffi_pact_handle_get_sync_message_iter")
+ purego.RegisterLibFunc(&pactffi_pact_handle_get_sync_http_iter, libpact_ffi, "pactffi_pact_handle_get_sync_http_iter")
+ purego.RegisterLibFunc(&pactffi_new_message_pact, libpact_ffi, "pactffi_new_message_pact")
+ purego.RegisterLibFunc(&pactffi_new_message, libpact_ffi, "pactffi_new_message")
+ purego.RegisterLibFunc(&pactffi_with_metadata, libpact_ffi, "pactffi_with_metadata")
+ purego.RegisterLibFunc(&pactffi_message_expects_to_receive, libpact_ffi, "pactffi_message_expects_to_receive")
+ purego.RegisterLibFunc(&pactffi_message_given, libpact_ffi, "pactffi_message_given")
+ purego.RegisterLibFunc(&pactffi_message_given_with_param, libpact_ffi, "pactffi_message_given_with_param")
+ purego.RegisterLibFunc(&pactffi_message_with_contents, libpact_ffi, "pactffi_message_with_contents")
+ purego.RegisterLibFunc(&pactffi_message_with_metadata, libpact_ffi, "pactffi_message_with_metadata")
+ purego.RegisterLibFunc(&pactffi_message_with_metadata_v2, libpact_ffi, "pactffi_message_with_metadata_v2")
+ purego.RegisterLibFunc(&pactffi_message_reify, libpact_ffi, "pactffi_message_reify")
+ purego.RegisterLibFunc(&pactffi_write_message_pact_file, libpact_ffi, "pactffi_write_message_pact_file")
+ purego.RegisterLibFunc(&pactffi_with_message_pact_metadata, libpact_ffi, "pactffi_with_message_pact_metadata")
+ purego.RegisterLibFunc(&pactffi_pact_handle_write_file, libpact_ffi, "pactffi_pact_handle_write_file")
+ purego.RegisterLibFunc(&pactffi_new_async_message, libpact_ffi, "pactffi_new_async_message")
+ purego.RegisterLibFunc(&pactffi_free_pact_handle, libpact_ffi, "pactffi_free_pact_handle")
+ purego.RegisterLibFunc(&pactffi_free_message_pact_handle, libpact_ffi, "pactffi_free_message_pact_handle")
+ purego.RegisterLibFunc(&pactffi_verify, libpact_ffi, "pactffi_verify")
+ purego.RegisterLibFunc(&pactffi_verifier_new, libpact_ffi, "pactffi_verifier_new")
+ purego.RegisterLibFunc(&pactffi_verifier_new_for_application, libpact_ffi, "pactffi_verifier_new_for_application")
+ purego.RegisterLibFunc(&pactffi_verifier_shutdown, libpact_ffi, "pactffi_verifier_shutdown")
+ purego.RegisterLibFunc(&pactffi_verifier_set_provider_info, libpact_ffi, "pactffi_verifier_set_provider_info")
+ purego.RegisterLibFunc(&pactffi_verifier_add_provider_transport, libpact_ffi, "pactffi_verifier_add_provider_transport")
+ purego.RegisterLibFunc(&pactffi_verifier_set_filter_info, libpact_ffi, "pactffi_verifier_set_filter_info")
+ purego.RegisterLibFunc(&pactffi_verifier_set_provider_state, libpact_ffi, "pactffi_verifier_set_provider_state")
+ purego.RegisterLibFunc(&pactffi_verifier_set_verification_options, libpact_ffi, "pactffi_verifier_set_verification_options")
+ purego.RegisterLibFunc(&pactffi_verifier_set_coloured_output, libpact_ffi, "pactffi_verifier_set_coloured_output")
+ purego.RegisterLibFunc(&pactffi_verifier_set_no_pacts_is_error, libpact_ffi, "pactffi_verifier_set_no_pacts_is_error")
+ purego.RegisterLibFunc(&pactffi_verifier_set_publish_options, libpact_ffi, "pactffi_verifier_set_publish_options")
+ purego.RegisterLibFunc(&pactffi_verifier_set_consumer_filters, libpact_ffi, "pactffi_verifier_set_consumer_filters")
+ purego.RegisterLibFunc(&pactffi_verifier_add_custom_header, libpact_ffi, "pactffi_verifier_add_custom_header")
+ purego.RegisterLibFunc(&pactffi_verifier_add_file_source, libpact_ffi, "pactffi_verifier_add_file_source")
+ purego.RegisterLibFunc(&pactffi_verifier_add_directory_source, libpact_ffi, "pactffi_verifier_add_directory_source")
+ purego.RegisterLibFunc(&pactffi_verifier_url_source, libpact_ffi, "pactffi_verifier_url_source")
+ purego.RegisterLibFunc(&pactffi_verifier_broker_source, libpact_ffi, "pactffi_verifier_broker_source")
+ purego.RegisterLibFunc(&pactffi_verifier_broker_source_with_selectors, libpact_ffi, "pactffi_verifier_broker_source_with_selectors")
+ purego.RegisterLibFunc(&pactffi_verifier_execute, libpact_ffi, "pactffi_verifier_execute")
+ purego.RegisterLibFunc(&pactffi_verifier_cli_args, libpact_ffi, "pactffi_verifier_cli_args")
+ purego.RegisterLibFunc(&pactffi_verifier_logs, libpact_ffi, "pactffi_verifier_logs")
+ purego.RegisterLibFunc(&pactffi_verifier_logs_for_provider, libpact_ffi, "pactffi_verifier_logs_for_provider")
+ purego.RegisterLibFunc(&pactffi_verifier_output, libpact_ffi, "pactffi_verifier_output")
+ purego.RegisterLibFunc(&pactffi_verifier_json, libpact_ffi, "pactffi_verifier_json")
+ purego.RegisterLibFunc(&pactffi_using_plugin, libpact_ffi, "pactffi_using_plugin")
+ purego.RegisterLibFunc(&pactffi_cleanup_plugins, libpact_ffi, "pactffi_cleanup_plugins")
+ purego.RegisterLibFunc(&pactffi_interaction_contents, libpact_ffi, "pactffi_interaction_contents")
+ purego.RegisterLibFunc(&pactffi_matches_string_value, libpact_ffi, "pactffi_matches_string_value")
+ purego.RegisterLibFunc(&pactffi_matches_u64_value, libpact_ffi, "pactffi_matches_u64_value")
+ purego.RegisterLibFunc(&pactffi_matches_i64_value, libpact_ffi, "pactffi_matches_i64_value")
+ purego.RegisterLibFunc(&pactffi_matches_f64_value, libpact_ffi, "pactffi_matches_f64_value")
+ purego.RegisterLibFunc(&pactffi_matches_bool_value, libpact_ffi, "pactffi_matches_bool_value")
+ purego.RegisterLibFunc(&pactffi_matches_binary_value, libpact_ffi, "pactffi_matches_binary_value")
+ purego.RegisterLibFunc(&pactffi_matches_json_value, libpact_ffi, "pactffi_matches_json_value")
+}
+
+// func main() {
+
+// print(pactffi_version())
+// pactffi_log_to_stdout(4)
+// // pactffi_log_to_file("pact.log", 5)
+
+// var verifier_handle = pactffi_verifier_new_for_application("pact-purego", "0.0.1")
+// pactffi_verifier_set_provider_info(verifier_handle, "grpc-provider", "http", "localhost", 1234, "/")
+// pactffi_verifier_add_file_source(verifier_handle, "no_pact.json")
+// // pactffi_verifier_add_file_source(verifier_handle, "pact.json")
+// // pactffi_verifier_add_file_source(verifier_handle, "../pacts/Consumer-Alice Service.json")
+// // pactffi_verifier_add_file_source(verifier_handle, "../pacts/grpc-consumer-perl-area-calculator-provider.json")
+// pactffi_verifier_execute(verifier_handle)
+// pactffi_verifier_shutdown(verifier_handle)
+// }
+
+// hasSuffix tests whether the string s ends with suffix.
+func hasSuffix(s, suffix string) bool {
+ return len(s) >= len(suffix) && s[len(s)-len(suffix):] == suffix
+}
+
+// CString converts a go string to *byte that can be passed to C code.
+func CString(name string) *byte {
+ if hasSuffix(name, "\x00") {
+ return &(*(*[]byte)(unsafe.Pointer(&name)))[0]
+ }
+ b := make([]byte, len(name)+1)
+ copy(b, name)
+ return &b[0]
+}
diff --git a/internal/native/lib_unix.go b/internal/native/lib_unix.go
new file mode 100644
index 000000000..c072731c6
--- /dev/null
+++ b/internal/native/lib_unix.go
@@ -0,0 +1,9 @@
+//go:build darwin || linux
+
+package native
+
+import "github.com/ebitengine/purego"
+
+func openLibrary(name string) (uintptr, error) {
+ return purego.Dlopen(name, purego.RTLD_NOW|purego.RTLD_GLOBAL)
+}
diff --git a/internal/native/lib_windows.go b/internal/native/lib_windows.go
new file mode 100644
index 000000000..d07ffa93f
--- /dev/null
+++ b/internal/native/lib_windows.go
@@ -0,0 +1,10 @@
+//go:build windows
+
+package native
+
+import "golang.org/x/sys/windows"
+
+func openLibrary(name string) (uintptr, error) {
+ handle, err := windows.LoadLibrary(name)
+ return uintptr(handle), err
+}
diff --git a/internal/native/message_server.go b/internal/native/message_server.go
index 4fb0dbb9e..f6cada891 100644
--- a/internal/native/message_server.go
+++ b/internal/native/message_server.go
@@ -1,20 +1,16 @@
package native
-/*
-#include "pact.h"
-*/
-import "C"
-
import (
"encoding/json"
"errors"
"fmt"
"log"
+
"unsafe"
)
type MessagePact struct {
- handle C.PactHandle
+ handle uintptr
}
type messageType int
@@ -25,7 +21,7 @@ const (
)
type Message struct {
- handle C.InteractionHandle
+ handle uintptr
messageType messageType
pact *MessagePact
index int
@@ -40,24 +36,24 @@ type MessageServer struct {
// NewMessage initialises a new message for the current contract
func NewMessageServer(consumer string, provider string) *MessageServer {
- cConsumer := C.CString(consumer)
- cProvider := C.CString(provider)
- defer free(cConsumer)
- defer free(cProvider)
+ // cConsumer := C.CString(consumer)
+ // cProvider := C.CString(provider)
+ // defer free(cConsumer)
+ // defer free(cProvider)
- return &MessageServer{messagePact: &MessagePact{handle: C.pactffi_new_message_pact(cConsumer, cProvider)}}
+ return &MessageServer{messagePact: &MessagePact{handle: pactffi_new_message_pact(consumer, provider)}}
}
// Sets the additional metadata on the Pact file. Common uses are to add the client library details such as the name and version
func (m *MessageServer) WithMetadata(namespace, k, v string) *MessageServer {
- cNamespace := C.CString(namespace)
- defer free(cNamespace)
- cName := C.CString(k)
- defer free(cName)
- cValue := C.CString(v)
- defer free(cValue)
+ // cNamespace := C.CString(namespace)
+ // defer free(cNamespace)
+ // cName := C.CString(k)
+ // defer free(cName)
+ // cValue := C.CString(v)
+ // defer free(cValue)
- C.pactffi_with_message_pact_metadata(m.messagePact.handle, cNamespace, cName, cValue)
+ pactffi_with_message_pact_metadata(m.messagePact.handle, namespace, k, v)
return m
}
@@ -71,11 +67,9 @@ func (m *MessageServer) NewMessage() *Message {
// NewSyncMessageInteraction initialises a new synchronous message interaction for the current contract
func (m *MessageServer) NewSyncMessageInteraction(description string) *Message {
- cDescription := C.CString(description)
- defer free(cDescription)
i := &Message{
- handle: C.pactffi_new_sync_message_interaction(m.messagePact.handle, cDescription),
+ handle: pactffi_new_sync_message_interaction(m.messagePact.handle, description),
messageType: MESSAGE_TYPE_SYNC,
pact: m.messagePact,
index: len(m.messages),
@@ -88,11 +82,9 @@ func (m *MessageServer) NewSyncMessageInteraction(description string) *Message {
// NewAsyncMessageInteraction initialises a new asynchronous message interaction for the current contract
func (m *MessageServer) NewAsyncMessageInteraction(description string) *Message {
- cDescription := C.CString(description)
- defer free(cDescription)
i := &Message{
- handle: C.pactffi_new_message_interaction(m.messagePact.handle, cDescription),
+ handle: pactffi_new_message_interaction(m.messagePact.handle, description),
messageType: MESSAGE_TYPE_ASYNC,
pact: m.messagePact,
index: len(m.messages),
@@ -104,35 +96,22 @@ func (m *MessageServer) NewAsyncMessageInteraction(description string) *Message
}
func (m *MessageServer) WithSpecificationVersion(version specificationVersion) {
- C.pactffi_with_specification(m.messagePact.handle, C.int(version))
+ pactffi_with_specification(m.messagePact.handle, int32(version))
}
func (m *Message) Given(state string) *Message {
- cState := C.CString(state)
- defer free(cState)
-
- C.pactffi_given(m.handle, cState)
+ pactffi_given(m.handle, state)
return m
}
func (m *Message) GivenWithParameter(state string, params map[string]interface{}) *Message {
- cState := C.CString(state)
- defer free(cState)
-
if len(params) == 0 {
- C.pactffi_given(m.handle, cState)
+ pactffi_given(m.handle, state)
} else {
for k, v := range params {
- cKey := C.CString(k)
-
param := stringFromInterface(v)
- cValue := C.CString(param)
-
- C.pactffi_given_with_param(m.handle, cState, cKey, cValue)
-
- free(cValue)
- free(cKey)
+ pactffi_given_with_param(m.handle, state, k, param)
}
}
@@ -140,76 +119,51 @@ func (m *Message) GivenWithParameter(state string, params map[string]interface{}
}
func (m *Message) ExpectsToReceive(description string) *Message {
- cDescription := C.CString(description)
- defer free(cDescription)
-
- C.pactffi_message_expects_to_receive(m.handle, cDescription)
+ pactffi_message_expects_to_receive(m.handle, description)
return m
}
func (m *Message) WithMetadata(valueOrMatcher map[string]string) *Message {
for k, v := range valueOrMatcher {
- cName := C.CString(k)
-
// TODO: check if matching rules allowed here
// value := stringFromInterface(v)
// fmt.Printf("withheaders, sending: %+v \n\n", value)
// cValue := C.CString(value)
- cValue := C.CString(v)
-
- C.pactffi_message_with_metadata(m.handle, cName, cValue)
- free(cValue)
- free(cName)
+ pactffi_message_with_metadata(m.handle, k, v)
}
return m
}
func (m *Message) WithRequestMetadata(valueOrMatcher map[string]string) *Message {
for k, v := range valueOrMatcher {
- cName := C.CString(k)
- cValue := C.CString(v)
-
- C.pactffi_with_metadata(m.handle, cName, cValue, 0)
-
- free(cValue)
- free(cName)
+ pactffi_with_metadata(m.handle, k, v, 0)
}
return m
}
func (m *Message) WithResponseMetadata(valueOrMatcher map[string]string) *Message {
for k, v := range valueOrMatcher {
- cName := C.CString(k)
- cValue := C.CString(v)
-
- C.pactffi_with_metadata(m.handle, cName, cValue, 1)
-
- free(cValue)
- free(cName)
+ pactffi_with_metadata(m.handle, k, v, 1)
}
return m
}
func (m *Message) WithRequestBinaryContents(body []byte) *Message {
- cHeader := C.CString("application/octet-stream")
- defer free(cHeader)
// TODO: handle response
- res := C.pactffi_with_binary_file(m.handle, C.int(INTERACTION_PART_REQUEST), cHeader, (*C.uchar)(unsafe.Pointer(&body[0])), CUlong(len(body)))
+ res := pactffi_with_binary_file(m.handle, int32(INTERACTION_PART_REQUEST), "application/octet-stream", string(body), size_t(len(body)))
- log.Println("[DEBUG] WithRequestBinaryContents - pactffi_with_binary_file returned", bool(res))
+ log.Println("[DEBUG] WithRequestBinaryContents - pactffi_with_binary_file returned", res)
return m
}
func (m *Message) WithRequestBinaryContentType(contentType string, body []byte) *Message {
- cHeader := C.CString(contentType)
- defer free(cHeader)
// TODO: handle response
- res := C.pactffi_with_binary_file(m.handle, C.int(INTERACTION_PART_REQUEST), cHeader, (*C.uchar)(unsafe.Pointer(&body[0])), CUlong(len(body)))
+ res := pactffi_with_binary_file(m.handle, int32(INTERACTION_PART_REQUEST), contentType, string(body), size_t(len(body)))
log.Println("[DEBUG] WithRequestBinaryContents - pactffi_with_binary_file returned", res)
@@ -225,11 +179,9 @@ func (m *Message) WithRequestJSONContents(body interface{}) *Message {
}
func (m *Message) WithResponseBinaryContents(body []byte) *Message {
- cHeader := C.CString("application/octet-stream")
- defer free(cHeader)
// TODO: handle response
- C.pactffi_with_binary_file(m.handle, C.int(INTERACTION_PART_RESPONSE), cHeader, (*C.uchar)(unsafe.Pointer(&body[0])), CUlong(len(body)))
+ pactffi_with_binary_file(m.handle, int32(INTERACTION_PART_RESPONSE), "application/octet-stream", string(body), size_t(len(body)))
return m
}
@@ -244,14 +196,9 @@ func (m *Message) WithResponseJSONContents(body interface{}) *Message {
// Note that string values here must be NUL terminated.
func (m *Message) WithContents(part interactionPart, contentType string, body []byte) *Message {
- cHeader := C.CString(contentType)
- defer free(cHeader)
-
- cBody := C.CString(string(body))
- defer free(cBody)
- res := C.pactffi_with_body(m.handle, C.int(part), cHeader, cBody)
- log.Println("[DEBUG] response from pactffi_interaction_contents", (bool(res)))
+ res := pactffi_with_body(m.handle, int32(part), contentType, string(body))
+ log.Println("[DEBUG] response from pactffi_interaction_contents", res)
return m
}
@@ -260,13 +207,8 @@ func (m *Message) WithContents(part interactionPart, contentType string, body []
// NewInteraction initialises a new interaction for the current contract
func (m *MessageServer) UsingPlugin(pluginName string, pluginVersion string) error {
- cPluginName := C.CString(pluginName)
- defer free(cPluginName)
- cPluginVersion := C.CString(pluginVersion)
- defer free(cPluginVersion)
-
- r := C.pactffi_using_plugin(m.messagePact.handle, cPluginName, cPluginVersion)
+ r := pactffi_using_plugin(m.messagePact.handle, pluginName, pluginVersion)
// 1 - A general panic was caught.
// 2 - Failed to load the plugin.
// 3 - Pact Handle is not valid.
@@ -289,12 +231,8 @@ func (m *MessageServer) UsingPlugin(pluginName string, pluginVersion string) err
// NewInteraction initialises a new interaction for the current contract
func (m *Message) WithPluginInteractionContents(part interactionPart, contentType string, contents string) error {
- cContentType := C.CString(contentType)
- defer free(cContentType)
- cContents := C.CString(contents)
- defer free(cContents)
- r := C.pactffi_interaction_contents(m.handle, C.int(part), cContentType, cContents)
+ r := pactffi_interaction_contents(m.handle, int32(part), contentType, contents)
// 1 - A general panic was caught.
// 2 - The mock server has already been started.
@@ -325,6 +263,18 @@ func (m *Message) WithPluginInteractionContents(part interactionPart, contentTyp
return nil
}
+func GoByteArrayFromC(ptr uintptr, length int) []byte {
+ if unsafe.Pointer(ptr) == nil || length == 0 {
+ return []byte{}
+ }
+ // Create a Go byte slice from the C string
+ b := make([]byte, length)
+ for i := 0; i < length; i++ {
+ b[i] = *(*byte)(unsafe.Pointer(uintptr(unsafe.Pointer(ptr)) + uintptr(i)))
+ }
+ return b
+}
+
// GetMessageContents retreives the binary contents of the request for a given message
// any matchers are stripped away if given
// if the contents is from a plugin, the byte[] representation of the parsed
@@ -332,9 +282,10 @@ func (m *Message) WithPluginInteractionContents(part interactionPart, contentTyp
func (m *Message) GetMessageRequestContents() ([]byte, error) {
log.Println("[DEBUG] GetMessageRequestContents")
if m.messageType == MESSAGE_TYPE_ASYNC {
- iter := C.pactffi_pact_handle_get_message_iter(m.pact.handle)
+ iter := pactffi_pact_handle_get_message_iter(m.pact.handle)
log.Println("[DEBUG] pactffi_pact_handle_get_message_iter")
- if iter == nil {
+ // TODO
+ if unsafe.Pointer(iter) == nil {
return nil, errors.New("unable to get a message iterator")
}
log.Println("[DEBUG] pactffi_pact_handle_get_message_iter - OK")
@@ -347,63 +298,59 @@ func (m *Message) GetMessageRequestContents() ([]byte, error) {
for i := 0; i < len(m.server.messages); i++ {
log.Println("[DEBUG] pactffi_pact_handle_get_message_iter - index", i)
- message := C.pactffi_pact_message_iter_next(iter)
+ message := pactffi_pact_message_iter_next(iter)
log.Println("[DEBUG] pactffi_pact_message_iter_next - message", message)
if i == m.index {
log.Println("[DEBUG] pactffi_pact_message_iter_next - index match", message)
- if message == nil {
+ if unsafe.Pointer(message) == nil {
return nil, errors.New("retrieved a null message pointer")
}
-
- len := C.pactffi_message_get_contents_length(message)
+ len := pactffi_message_get_contents_length(message)
log.Println("[DEBUG] pactffi_message_get_contents_length - len", len)
if len == 0 {
// You can have empty bodies
log.Println("[DEBUG] message body is empty")
- return nil, nil
+ return []byte{}, nil
}
- data := C.pactffi_message_get_contents_bin(message)
+ data := pactffi_message_get_contents_bin(message)
log.Println("[DEBUG] pactffi_message_get_contents_bin - data", data)
- if data == nil {
+ if unsafe.Pointer(data) == nil {
// You can have empty bodies
log.Println("[DEBUG] message binary contents are empty")
return nil, nil
}
- ptr := unsafe.Pointer(data)
- bytes := C.GoBytes(ptr, C.int(len))
-
+ bytes := GoByteArrayFromC(data, int(len))
return bytes, nil
}
}
} else {
- iter := C.pactffi_pact_handle_get_sync_message_iter(m.pact.handle)
- if iter == nil {
+ iter := pactffi_pact_handle_get_sync_message_iter(m.pact.handle)
+ if unsafe.Pointer(iter) == nil {
return nil, errors.New("unable to get a message iterator")
}
for i := 0; i < len(m.server.messages); i++ {
- message := C.pactffi_pact_sync_message_iter_next(iter)
+ message := pactffi_pact_sync_message_iter_next(iter)
if i == m.index {
- if message == nil {
+ if unsafe.Pointer(message) == nil {
return nil, errors.New("retrieved a null message pointer")
}
- len := C.pactffi_sync_message_get_request_contents_length(message)
+ len := pactffi_sync_message_get_request_contents_length(message)
if len == 0 {
log.Println("[DEBUG] message body is empty")
- return nil, nil
+ return []byte{}, nil
}
- data := C.pactffi_sync_message_get_request_contents_bin(message)
- if data == nil {
+ data := pactffi_sync_message_get_request_contents_bin(message)
+ if unsafe.Pointer(data) == nil {
log.Println("[DEBUG] message binary contents are empty")
return nil, nil
}
- ptr := unsafe.Pointer(data)
- bytes := C.GoBytes(ptr, C.int(len))
+ bytes := GoByteArrayFromC(data, int(len))
return bytes, nil
}
@@ -423,29 +370,35 @@ func (m *Message) GetMessageResponseContents() ([][]byte, error) {
if m.messageType == MESSAGE_TYPE_ASYNC {
return nil, errors.New("invalid request: asynchronous messages do not have response")
}
- iter := C.pactffi_pact_handle_get_sync_message_iter(m.pact.handle)
- if iter == nil {
+ iter := pactffi_pact_handle_get_sync_message_iter(m.pact.handle)
+ if unsafe.Pointer(iter) == nil {
return nil, errors.New("unable to get a message iterator")
}
for i := 0; i < len(m.server.messages); i++ {
- message := C.pactffi_pact_sync_message_iter_next(iter)
+ message := pactffi_pact_sync_message_iter_next(iter)
- if message == nil {
+ if unsafe.Pointer(message) == nil {
return nil, errors.New("retrieved a null message pointer")
}
// Get Response body
- len := C.pactffi_sync_message_get_response_contents_length(message, C.size_t(i))
- if len != 0 {
- data := C.pactffi_sync_message_get_response_contents_bin(message, C.size_t(i))
- if data == nil {
- return nil, errors.New("retrieved an empty pointer to the message contents")
- }
- ptr := unsafe.Pointer(data)
- bytes := C.GoBytes(ptr, C.int(len))
- responses[i] = bytes
+ len := pactffi_sync_message_get_response_contents_length(message, size_t(i))
+ // if len == 0 {
+ // return nil, errors.New("retrieved an empty message")
+ // }
+ if len == 0 {
+ // You can have empty bodies
+ log.Println("[DEBUG] message body is empty")
+ responses[i] = []byte{}
+ return responses, nil
}
+ data := pactffi_sync_message_get_response_contents_bin(message, size_t(i))
+ if unsafe.Pointer(data) == nil {
+ return nil, errors.New("retrieved an empty pointer to the message contents")
+ }
+ bytes := GoByteArrayFromC(data, int(len))
+ responses[i] = bytes
}
return responses, nil
@@ -459,17 +412,9 @@ func (m *MessageServer) StartTransport(transport string, address string, port in
}
log.Println("[DEBUG] mock server starting on address:", address, port)
- cAddress := C.CString(address)
- defer free(cAddress)
-
- cTransport := C.CString(transport)
- defer free(cTransport)
-
configJson := stringFromInterface(config)
- cConfig := C.CString(configJson)
- defer free(cConfig)
- p := C.pactffi_create_mock_server_for_transport(m.messagePact.handle, cAddress, C.ushort(port), cTransport, cConfig)
+ p := pactffi_create_mock_server_for_transport(m.messagePact.handle, address, uint16(port), transport, configJson)
// | Error | Description
// |-------|-------------
@@ -501,7 +446,7 @@ func (m *MessageServer) StartTransport(transport string, address string, port in
// NewInteraction initialises a new interaction for the current contract
func (m *MessageServer) CleanupPlugins() {
- C.pactffi_cleanup_plugins(m.messagePact.handle)
+ pactffi_cleanup_plugins(m.messagePact.handle)
}
// CleanupMockServer frees the memory from the previous mock server.
@@ -510,9 +455,9 @@ func (m *MessageServer) CleanupMockServer(port int) bool {
return true
}
log.Println("[DEBUG] mock server cleaning up port:", port)
- res := C.pactffi_cleanup_mock_server(C.int(port))
+ res := pactffi_cleanup_mock_server(int32(port))
- return bool(res)
+ return res
}
// MockServerMismatchedRequests returns a JSON object containing any mismatches from
@@ -521,16 +466,17 @@ func (m *MessageServer) MockServerMismatchedRequests(port int) []MismatchedReque
log.Println("[DEBUG] mock server determining mismatches:", port)
var res []MismatchedRequest
- mismatches := C.pactffi_mock_server_mismatches(C.int(port))
+ mismatches := pactffi_mock_server_mismatches(int32(port))
// This method can return a nil pointer, in which case, it
// should be considered a failure (or at least, an issue)
// converting it to a string might also do nasty things here!
- if mismatches == nil {
+ // TODO change return type to uintptr
+ if mismatches == "" {
log.Println("[WARN] received a null pointer from the native interface, returning empty list of mismatches")
return []MismatchedRequest{}
}
- err := json.Unmarshal([]byte(C.GoString(mismatches)), &res)
+ err := json.Unmarshal([]byte(mismatches), &res)
if err != nil {
log.Println("[ERROR] failed to unmarshal mismatches response, returning empty list of mismatches")
return []MismatchedRequest{}
@@ -544,27 +490,25 @@ func (m *MessageServer) MockServerMismatchedRequests(port int) []MismatchedReque
func (m *MessageServer) MockServerMatched(port int) bool {
log.Println("[DEBUG] mock server determining mismatches:", port)
- res := C.pactffi_mock_server_matched(C.int(port))
+ res := pactffi_mock_server_matched(int32(port))
// TODO: why this number is so big and not a bool? Type def wrong? Port value wrong?
// log.Println("MATCHED RES?")
// log.Println(int(res))
- return bool(res)
+ return res
}
// WritePactFile writes the Pact to file.
func (m *MessageServer) WritePactFile(dir string, overwrite bool) error {
log.Println("[DEBUG] writing pact file for message pact at dir:", dir)
- cDir := C.CString(dir)
- defer free(cDir)
overwritePact := false
if overwrite {
overwritePact = true
}
- res := int(C.pactffi_write_message_pact_file(m.messagePact.handle, cDir, C.bool(overwritePact)))
+ res := pactffi_write_message_pact_file(m.messagePact.handle, dir, overwritePact)
/// | Error | Description |
/// |-------|-------------|
@@ -585,15 +529,13 @@ func (m *MessageServer) WritePactFile(dir string, overwrite bool) error {
// WritePactFile writes the Pact to file.
func (m *MessageServer) WritePactFileForServer(port int, dir string, overwrite bool) error {
log.Println("[DEBUG] writing pact file for message pact at dir:", dir)
- cDir := C.CString(dir)
- defer free(cDir)
overwritePact := false
if overwrite {
overwritePact = true
}
- res := int(C.pactffi_write_pact_file(C.int(port), cDir, C.bool(overwritePact)))
+ res := pactffi_write_pact_file(int32(port), dir, overwritePact)
/// | Error | Description |
/// |-------|-------------|
diff --git a/internal/native/mock_server.go b/internal/native/mock_server.go
index 2429301c1..dcf179387 100644
--- a/internal/native/mock_server.go
+++ b/internal/native/mock_server.go
@@ -1,10 +1,5 @@
package native
-/*
-#include "pact.h"
-*/
-import "C"
-
import (
"crypto/tls"
"crypto/x509"
@@ -12,8 +7,8 @@ import (
"fmt"
"log"
"os"
+
"strings"
- "unsafe"
)
type interactionPart int
@@ -61,19 +56,19 @@ var logLevelStringToInt = map[string]logLevel{
// Pact is a Go representation of the PactHandle struct
type Pact struct {
- handle C.PactHandle
+ handle uintptr
}
// Interaction is a Go representation of the InteractionHandle struct
type Interaction struct {
- handle C.InteractionHandle
+ handle uintptr
}
// Version returns the current semver FFI interface version
func Version() string {
- v := C.pactffi_version()
+ v := pactffi_version()
- return C.GoString(v)
+ return v
}
var loggingInitialised string
@@ -111,18 +106,13 @@ func Init(logLevel string) {
// MockServer is the public interface for managing the HTTP mock server
type MockServer struct {
pact *Pact
- messagePact *MessagePact
+ // messagePact *MessagePact
interactions []*Interaction
}
// NewHTTPPact creates a new HTTP mock server for a given consumer/provider
func NewHTTPPact(consumer string, provider string) *MockServer {
- cConsumer := C.CString(consumer)
- cProvider := C.CString(provider)
- defer free(cConsumer)
- defer free(cProvider)
-
- return &MockServer{pact: &Pact{handle: C.pactffi_new_pact(cConsumer, cProvider)}}
+ return &MockServer{pact: &Pact{handle: pactffi_new_pact(consumer, provider)}}
}
// Version returns the current semver FFI interface version
@@ -131,23 +121,19 @@ func (m *MockServer) Version() string {
}
func (m *MockServer) WithSpecificationVersion(version specificationVersion) {
- C.pactffi_with_specification(m.pact.handle, C.int(version))
+ pactffi_with_specification(m.pact.handle, int32(version))
}
// CreateMockServer creates a new Mock Server from a given Pact file.
// Returns the port number it started on or an error if failed
func (m *MockServer) CreateMockServer(pact string, address string, tls bool) (int, error) {
log.Println("[DEBUG] mock server starting on address:", address)
- cPact := C.CString(pact)
- cAddress := C.CString(address)
- defer free(cPact)
- defer free(cAddress)
tlsEnabled := false
if tls {
tlsEnabled = true
}
- p := C.pactffi_create_mock_server(cPact, cAddress, C.bool(tlsEnabled))
+ p := pactffi_create_mock_server(pact, address, tlsEnabled)
// | Error | Description |
// |-------|-------------|
@@ -195,16 +181,16 @@ func (m *MockServer) MockServerMismatchedRequests(port int) []MismatchedRequest
log.Println("[DEBUG] mock server determining mismatches:", port)
var res []MismatchedRequest
- mismatches := C.pactffi_mock_server_mismatches(C.int(port))
+ mismatches := pactffi_mock_server_mismatches(int32(port))
// This method can return a nil pointer, in which case, it
// should be considered a failure (or at least, an issue)
// converting it to a string might also do nasty things here!
- if mismatches == nil {
+ if mismatches == "" {
log.Println("[WARN] received a null pointer from the native interface, returning empty list of mismatches")
return []MismatchedRequest{}
}
- err := json.Unmarshal([]byte(C.GoString(mismatches)), &res)
+ err := json.Unmarshal([]byte(mismatches), &res)
if err != nil {
log.Println("[ERROR] failed to unmarshal mismatches response, returning empty list of mismatches")
return []MismatchedRequest{}
@@ -218,25 +204,23 @@ func (m *MockServer) CleanupMockServer(port int) bool {
return true
}
log.Println("[DEBUG] mock server cleaning up port:", port)
- res := C.pactffi_cleanup_mock_server(C.int(port))
+ res := pactffi_cleanup_mock_server(int32(port))
- return bool(res)
+ return res
}
// WritePactFile writes the Pact to file.
// TODO: expose overwrite
func (m *MockServer) WritePactFile(port int, dir string) error {
log.Println("[DEBUG] writing pact file for mock server on port:", port, ", dir:", dir)
- cDir := C.CString(dir)
- defer free(cDir)
- // overwritePact := 0
+ overwritePact := false
// if overwrite {
// overwritePact = 1
// }
// res := int(C.pactffi_write_pact_file(C.int(port), cDir, C.int(overwritePact)))
- res := int(C.pactffi_write_pact_file(C.int(port), cDir, C.bool(false)))
+ res := int(pactffi_write_pact_file(int32(port), dir, overwritePact))
// | Error | Description |
// |-------|-------------|
@@ -260,25 +244,28 @@ func (m *MockServer) WritePactFile(port int, dir string) error {
// GetTLSConfig returns a tls.Config compatible with the TLS
// mock server
func GetTLSConfig() *tls.Config {
- cert := C.pactffi_get_tls_ca_certificate()
- defer libRustFree(cert)
+ cert := pactffi_get_tls_ca_certificate()
+ // defer libRustFree(cert)
- goCert := C.GoString(cert)
certPool := x509.NewCertPool()
- certPool.AppendCertsFromPEM([]byte(goCert))
+ certPool.AppendCertsFromPEM([]byte(cert))
return &tls.Config{
RootCAs: certPool,
}
}
-func free(str *C.char) {
- C.free(unsafe.Pointer(str))
-}
+// func free(str *C.char) {
+// C.free(unsafe.Pointer(str))
+// }
-func libRustFree(str *C.char) {
- C.pactffi_free_string(str)
-}
+// func libRustFree(str uintptr) {
+// pactffi_free_string(str)
+// }
+
+// func libRustFree(str string) {
+// pactffi_string_delete(str)
+// }
// Start starts up the mock HTTP server on the given address:port and TLS config
// https://docs.rs/pact_mock_server_ffi/0.0.7/pact_mock_server_ffi/fn.create_mock_server_for_pact.html
@@ -288,14 +275,14 @@ func (m *MockServer) Start(address string, tls bool) (int, error) {
}
log.Println("[DEBUG] mock server starting on address:", address)
- cAddress := C.CString(address)
- defer free(cAddress)
+ // cAddress := C.CString(address)
+ // defer free(cAddress)
tlsEnabled := false
if tls {
tlsEnabled = true
}
- p := C.pactffi_create_mock_server_for_pact(m.pact.handle, cAddress, C.bool(tlsEnabled))
+ p := pactffi_create_mock_server_for_pact(m.pact.handle, address, tlsEnabled)
// | Error | Description |
// |-------|-------------|
@@ -334,19 +321,10 @@ func (m *MockServer) StartTransport(transport string, address string, port int,
if len(m.interactions) == 0 {
return 0, ErrNoInteractions
}
-
- log.Println("[DEBUG] mock server starting on address:", address, port)
- cAddress := C.CString(address)
- defer free(cAddress)
-
- cTransport := C.CString(transport)
- defer free(cTransport)
-
configJson := stringFromInterface(config)
- cConfig := C.CString(configJson)
- defer free(cConfig)
- p := C.pactffi_create_mock_server_for_transport(m.pact.handle, cAddress, C.ushort(port), cTransport, cConfig)
+ log.Println("[DEBUG] mock server starting on address:", address, port)
+ p := pactffi_create_mock_server_for_transport(m.pact.handle, address, uint16(port), transport, configJson)
// | Error | Description
// |-------|-------------
@@ -378,27 +356,15 @@ func (m *MockServer) StartTransport(transport string, address string, port int,
// Sets the additional metadata on the Pact file. Common uses are to add the client library details such as the name and version
func (m *MockServer) WithMetadata(namespace, k, v string) *MockServer {
- cNamespace := C.CString(namespace)
- defer free(cNamespace)
- cName := C.CString(k)
- defer free(cName)
- cValue := C.CString(v)
- defer free(cValue)
-
- C.pactffi_with_pact_metadata(m.pact.handle, cNamespace, cName, cValue)
+ pactffi_with_pact_metadata(m.pact.handle, namespace, k, v)
return m
}
// NewInteraction initialises a new interaction for the current contract
func (m *MockServer) UsingPlugin(pluginName string, pluginVersion string) error {
- cPluginName := C.CString(pluginName)
- defer free(cPluginName)
- cPluginVersion := C.CString(pluginVersion)
- defer free(cPluginVersion)
-
- r := C.pactffi_using_plugin(m.pact.handle, cPluginName, cPluginVersion)
+ r := pactffi_using_plugin(m.pact.handle, pluginName, pluginVersion)
// 1 - A general panic was caught.
// 2 - Failed to load the plugin.
// 3 - Pact Handle is not valid.
@@ -421,16 +387,13 @@ func (m *MockServer) UsingPlugin(pluginName string, pluginVersion string) error
// NewInteraction initialises a new interaction for the current contract
func (m *MockServer) CleanupPlugins() {
- C.pactffi_cleanup_plugins(m.pact.handle)
+ pactffi_cleanup_plugins(m.pact.handle)
}
// NewInteraction initialises a new interaction for the current contract
func (m *MockServer) NewInteraction(description string) *Interaction {
- cDescription := C.CString(description)
- defer free(cDescription)
-
i := &Interaction{
- handle: C.pactffi_new_interaction(m.pact.handle, cDescription),
+ handle: pactffi_new_interaction(m.pact.handle, description),
}
m.interactions = append(m.interactions, i)
@@ -439,12 +402,8 @@ func (m *MockServer) NewInteraction(description string) *Interaction {
// NewInteraction initialises a new interaction for the current contract
func (i *Interaction) WithPluginInteractionContents(part interactionPart, contentType string, contents string) error {
- cContentType := C.CString(contentType)
- defer free(cContentType)
- cContents := C.CString(contents)
- defer free(cContents)
- r := C.pactffi_interaction_contents(i.handle, C.int(part), cContentType, cContents)
+ r := pactffi_interaction_contents(i.handle, int32(part), contentType, contents)
// 1 - A general panic was caught.
// 2 - The mock server has already been started.
@@ -476,50 +435,31 @@ func (i *Interaction) WithPluginInteractionContents(part interactionPart, conten
}
func (i *Interaction) UponReceiving(description string) *Interaction {
- cDescription := C.CString(description)
- defer free(cDescription)
-
- C.pactffi_upon_receiving(i.handle, cDescription)
+ pactffi_upon_receiving(i.handle, description)
return i
}
func (i *Interaction) Given(state string) *Interaction {
- cState := C.CString(state)
- defer free(cState)
-
- C.pactffi_given(i.handle, cState)
+ pactffi_given(i.handle, state)
return i
}
func (i *Interaction) GivenWithParameter(state string, params map[string]interface{}) *Interaction {
- cState := C.CString(state)
- defer free(cState)
for k, v := range params {
- cKey := C.CString(k)
param := stringFromInterface(v)
- cValue := C.CString(param)
-
- C.pactffi_given_with_param(i.handle, cState, cKey, cValue)
-
- free(cValue)
- free(cKey)
+ pactffi_given_with_param(i.handle, state, k, param)
}
return i
}
func (i *Interaction) WithRequest(method string, pathOrMatcher interface{}) *Interaction {
- cMethod := C.CString(method)
- defer free(cMethod)
-
path := stringFromInterface(pathOrMatcher)
- cPath := C.CString(path)
- defer free(cPath)
- C.pactffi_with_request(i.handle, cMethod, cPath)
+ pactffi_with_request(i.handle, method, path)
return i
}
@@ -534,18 +474,12 @@ func (i *Interaction) WithResponseHeaders(valueOrMatcher map[string][]interface{
func (i *Interaction) withHeaders(part interactionPart, valueOrMatcher map[string][]interface{}) *Interaction {
for k, v := range valueOrMatcher {
- cName := C.CString(k)
-
for _, header := range v {
value := stringFromInterface(header)
- cValue := C.CString(value)
-
- C.pactffi_with_header_v2(i.handle, C.int(part), cName, CUlong(0), cValue)
- free(cValue)
+ pactffi_with_header_v2(i.handle, int32(part), k, int(0), value)
}
- free(cName)
}
return i
@@ -553,18 +487,12 @@ func (i *Interaction) withHeaders(part interactionPart, valueOrMatcher map[strin
func (i *Interaction) WithQuery(valueOrMatcher map[string][]interface{}) *Interaction {
for k, values := range valueOrMatcher {
- cName := C.CString(k)
for idx, v := range values {
value := stringFromInterface(v)
- cValue := C.CString(value)
- C.pactffi_with_query_parameter_v2(i.handle, cName, CUlong(idx), cValue)
-
- free(cValue)
+ pactffi_with_query_parameter_v2(i.handle, k, int(idx), value)
}
-
- free(cName)
}
return i
@@ -579,14 +507,9 @@ func (i *Interaction) WithJSONResponseBody(body interface{}) *Interaction {
}
func (i *Interaction) withJSONBody(body interface{}, part interactionPart) *Interaction {
- cHeader := C.CString("application/json")
- defer free(cHeader)
-
jsonBody := stringFromInterface(body)
- cBody := C.CString(jsonBody)
- defer free(cBody)
- C.pactffi_with_body(i.handle, C.int(part), cHeader, cBody)
+ pactffi_with_body(i.handle, int32(part), "application/json", jsonBody)
return i
}
@@ -600,22 +523,15 @@ func (i *Interaction) WithResponseBody(contentType string, body []byte) *Interac
}
func (i *Interaction) withBody(contentType string, body []byte, part interactionPart) *Interaction {
- cHeader := C.CString(contentType)
- defer free(cHeader)
-
- cBody := C.CString(string(body))
- defer free(cBody)
- C.pactffi_with_body(i.handle, C.int(part), cHeader, cBody)
+ pactffi_with_body(i.handle, int32(part), contentType, string(body))
return i
}
func (i *Interaction) withBinaryBody(contentType string, body []byte, part interactionPart) *Interaction {
- cHeader := C.CString(contentType)
- defer free(cHeader)
- C.pactffi_with_binary_file(i.handle, C.int(part), cHeader, (*C.uchar)(unsafe.Pointer(&body[0])), CUlong(len(body)))
+ pactffi_with_binary_file(i.handle, int32(part), contentType, string(body), size_t(len(body)))
return i
}
@@ -637,30 +553,21 @@ func (i *Interaction) WithResponseMultipartFile(contentType string, filename str
}
func (i *Interaction) withMultipartFile(contentType string, filename string, mimePartName string, part interactionPart) *Interaction {
- cHeader := C.CString(contentType)
- defer free(cHeader)
-
- cPartName := C.CString(mimePartName)
- defer free(cPartName)
-
- cFilename := C.CString(filename)
- defer free(cFilename)
-
- C.pactffi_with_multipart_file(i.handle, C.int(part), cHeader, cFilename, cPartName)
+ pactffi_with_multipart_file(i.handle, int32(part), contentType, filename, mimePartName)
return i
}
// Set the expected HTTTP response status
func (i *Interaction) WithStatus(status int) *Interaction {
- C.pactffi_response_status(i.handle, C.ushort(status))
+ pactffi_response_status(i.handle, uint16(status))
return i
}
-type stringLike interface {
- String() string
-}
+// type stringLike interface {
+// String() string
+// }
func stringFromInterface(obj interface{}) string {
switch t := obj.(type) {
@@ -708,17 +615,14 @@ func quotedString(s string) string {
// }
func logToStdout(level logLevel) error {
- res := C.pactffi_log_to_stdout(C.int(level))
+ res := pactffi_log_to_stdout(int32(level))
log.Println("[DEBUG] log_to_stdout res", res)
return logResultToError(int(res))
}
func logToFile(file string, level logLevel) error {
- cFile := C.CString(file)
- defer free(cFile)
-
- res := C.pactffi_log_to_file(cFile, C.int(level))
+ res := pactffi_log_to_file(file, int32(level))
log.Println("[DEBUG] log_to_file res", res)
return logResultToError(int(res))
diff --git a/internal/native/verifier.go b/internal/native/verifier.go
index 3f03df269..ccc155777 100644
--- a/internal/native/verifier.go
+++ b/internal/native/verifier.go
@@ -1,27 +1,19 @@
package native
-/*
-#include "pact.h"
-*/
-import "C"
-
import (
"fmt"
"log"
+
"strings"
- "unsafe"
)
type Verifier struct {
- handle *C.VerifierHandle
+ handle uintptr
}
func (v *Verifier) Verify(args []string) error {
log.Println("[DEBUG] executing verifier FFI with args", args)
- cargs := C.CString(strings.Join(args, "\n"))
- defer free(cargs)
- result := C.pactffi_verify(cargs)
-
+ result := pactffi_verify(strings.Join(args, "\n"))
/// | Error | Description |
/// |-------|-------------|
/// | 1 | The verification process failed, see output for errors |
@@ -41,10 +33,10 @@ func (v *Verifier) Verify(args []string) error {
}
}
-// Version returns the current semver FFI interface version
-func (v *Verifier) Version() string {
- return Version()
-}
+// // Version returns the current semver FFI interface version
+// func (v *Verifier) Version() string {
+// return Version()
+// }
var (
// ErrVerifierPanic indicates a panic ocurred when invoking the verifier.
@@ -60,12 +52,7 @@ var (
)
func NewVerifier(name string, version string) *Verifier {
- cName := C.CString(name)
- cVersion := C.CString(version)
- defer free(cName)
- defer free(cVersion)
-
- h := C.pactffi_verifier_new_for_application(cName, cVersion)
+ h := pactffi_verifier_new_for_application(name, version)
return &Verifier{
handle: h,
@@ -73,130 +60,63 @@ func NewVerifier(name string, version string) *Verifier {
}
func (v *Verifier) Shutdown() {
- C.pactffi_verifier_shutdown(v.handle)
+ pactffi_verifier_shutdown(v.handle)
}
func (v *Verifier) SetProviderInfo(name string, scheme string, host string, port uint16, path string) {
- cName := C.CString(name)
- defer free(cName)
- cScheme := C.CString(scheme)
- defer free(cScheme)
- cHost := C.CString(host)
- defer free(cHost)
- cPort := C.ushort(port)
- cPath := C.CString(path)
- defer free(cPath)
-
- C.pactffi_verifier_set_provider_info(v.handle, cName, cScheme, cHost, cPort, cPath)
+ pactffi_verifier_set_provider_info(v.handle, name, scheme, host, port, path)
}
func (v *Verifier) AddTransport(protocol string, port uint16, path string, scheme string) {
log.Println("[DEBUG] Adding transport with protocol:", protocol, "port:", port, "path:", path, "scheme:", scheme)
- cProtocol := C.CString(protocol)
- defer free(cProtocol)
- cPort := C.ushort(port)
- cPath := C.CString(path)
- defer free(cPath)
- cScheme := C.CString(scheme)
- defer free(cScheme)
- C.pactffi_verifier_add_provider_transport(v.handle, cProtocol, cPort, cPath, cScheme)
+ pactffi_verifier_add_provider_transport(v.handle, protocol, port, path, scheme)
}
func (v *Verifier) SetFilterInfo(description string, state string, noState bool) {
- cFilterDescription := C.CString(description)
- defer free(cFilterDescription)
- cFilterState := C.CString(state)
- defer free(cFilterState)
-
- C.pactffi_verifier_set_filter_info(v.handle, cFilterDescription, cFilterState, boolToCUchar(noState))
+ pactffi_verifier_set_filter_info(v.handle, description, state, boolToCInt(noState))
}
func (v *Verifier) SetProviderState(url string, teardown bool, body bool) {
- cURL := C.CString(url)
- defer free(cURL)
-
- C.pactffi_verifier_set_provider_state(v.handle, cURL, boolToCUchar(teardown), boolToCUchar(body))
+ pactffi_verifier_set_provider_state(v.handle, url, boolToCInt(teardown), boolToCInt(body))
}
func (v *Verifier) SetVerificationOptions(disableSSLVerification bool, requestTimeout int64) {
// TODO: this returns an int and therefore can error. We should have all of these functions return values??
- C.pactffi_verifier_set_verification_options(v.handle, boolToCUchar(disableSSLVerification), C.ulong(requestTimeout))
+ pactffi_verifier_set_verification_options(v.handle, boolToCInt(disableSSLVerification), uint64(requestTimeout))
}
func (v *Verifier) SetConsumerFilters(consumers []string) {
- // TODO: check if this actually works!
- C.pactffi_verifier_set_consumer_filters(v.handle, stringArrayToCStringArray(consumers), C.ushort(len(consumers)))
+ pactffi_verifier_set_consumer_filters(v.handle, stringArrayToCByteArray(consumers), uint16(len(consumers)))
}
func (v *Verifier) AddCustomHeader(name string, value string) {
- cHeaderName := C.CString(name)
- defer free(cHeaderName)
- cHeaderValue := C.CString(value)
- defer free(cHeaderValue)
-
- C.pactffi_verifier_add_custom_header(v.handle, cHeaderName, cHeaderValue)
+ pactffi_verifier_add_custom_header(v.handle, name, value)
}
func (v *Verifier) AddFileSource(file string) {
- cFile := C.CString(file)
- defer free(cFile)
-
- C.pactffi_verifier_add_file_source(v.handle, cFile)
+ pactffi_verifier_add_file_source(v.handle, file)
}
func (v *Verifier) AddDirectorySource(directory string) {
- cDirectory := C.CString(directory)
- defer free(cDirectory)
-
- C.pactffi_verifier_add_directory_source(v.handle, cDirectory)
+ pactffi_verifier_add_directory_source(v.handle, directory)
}
func (v *Verifier) AddURLSource(url string, username string, password string, token string) {
- cUrl := C.CString(url)
- defer free(cUrl)
- cUsername := C.CString(username)
- defer free(cUsername)
- cPassword := C.CString(password)
- defer free(cPassword)
- cToken := C.CString(token)
- defer free(cToken)
-
- C.pactffi_verifier_url_source(v.handle, cUrl, cUsername, cPassword, cToken)
+ pactffi_verifier_url_source(v.handle, url, username, password, token)
}
func (v *Verifier) BrokerSourceWithSelectors(url string, username string, password string, token string, enablePending bool, includeWipPactsSince string, providerTags []string, providerBranch string, selectors []string, consumerVersionTags []string) {
- cUrl := C.CString(url)
- defer free(cUrl)
- cUsername := C.CString(username)
- defer free(cUsername)
- cPassword := C.CString(password)
- defer free(cPassword)
- cToken := C.CString(token)
- defer free(cToken)
- cIncludeWipPactsSince := C.CString(includeWipPactsSince)
- defer free(cIncludeWipPactsSince)
- cProviderBranch := C.CString(providerBranch)
- defer free(cProviderBranch)
-
- C.pactffi_verifier_broker_source_with_selectors(v.handle, cUrl, cUsername, cPassword, cToken, boolToCUchar(enablePending), cIncludeWipPactsSince, stringArrayToCStringArray(providerTags), C.ushort(len(providerTags)), cProviderBranch, stringArrayToCStringArray(selectors), C.ushort(len(selectors)), stringArrayToCStringArray(consumerVersionTags), C.ushort(len(consumerVersionTags)))
+ pactffi_verifier_broker_source_with_selectors(v.handle, url, username, password, token, boolToCInt(enablePending), includeWipPactsSince, stringArrayToCByteArray(providerTags), uint16(len(providerTags)), providerBranch, stringArrayToCByteArray(selectors), uint16(len(selectors)), stringArrayToCByteArray(consumerVersionTags), uint16(len(consumerVersionTags)))
}
func (v *Verifier) SetPublishOptions(providerVersion string, buildUrl string, providerTags []string, providerBranch string) {
- cProviderVersion := C.CString(providerVersion)
- defer free(cProviderVersion)
- cBuildUrl := C.CString(buildUrl)
- defer free(cBuildUrl)
- cProviderBranch := C.CString(providerBranch)
- defer free(cProviderBranch)
-
- C.pactffi_verifier_set_publish_options(v.handle, cProviderVersion, cBuildUrl, stringArrayToCStringArray(providerTags), C.ushort(len(providerTags)), cProviderBranch)
+ pactffi_verifier_set_publish_options(v.handle, providerVersion, buildUrl, stringArrayToCByteArray(providerTags), uint16(len(providerTags)), providerBranch)
}
func (v *Verifier) Execute() error {
// TODO: Validate
- result := C.pactffi_verifier_execute(v.handle)
-
+ result := pactffi_verifier_execute(v.handle)
/// | Error | Description |
/// |-------|-------------|
/// | 1 | The verification process failed, see output for errors |
@@ -213,30 +133,30 @@ func (v *Verifier) Execute() error {
}
func (v *Verifier) SetNoPactsIsError(isError bool) {
- C.pactffi_verifier_set_no_pacts_is_error(v.handle, boolToCUchar(isError))
+ pactffi_verifier_set_no_pacts_is_error(v.handle, boolToCInt(isError))
}
func (v *Verifier) SetColoredOutput(isColoredOutput bool) {
- C.pactffi_verifier_set_coloured_output(v.handle, boolToCUchar(isColoredOutput))
+ pactffi_verifier_set_coloured_output(v.handle, boolToCInt(isColoredOutput))
}
-func stringArrayToCStringArray(inputs []string) **C.char {
+func stringArrayToCByteArray(inputs []string) []*byte {
if len(inputs) == 0 {
return nil
}
- output := make([]*C.char, len(inputs))
+ output := make([]*byte, len(inputs))
for i, consumer := range inputs {
- output[i] = C.CString(consumer)
+ output[i] = CString(consumer)
}
- return (**C.char)(unsafe.Pointer(&output[0]))
+ return ([]*byte)(output)
}
-func boolToCUchar(val bool) C.uchar {
+func boolToCInt(val bool) uint8 {
if val {
- return C.uchar(1)
+ return uint8(1)
}
- return C.uchar(0)
+ return uint8(0)
}