diff --git a/bindings/go/Gopkg.lock b/bindings/go/Gopkg.lock new file mode 100644 index 0000000000..bef2d0092e --- /dev/null +++ b/bindings/go/Gopkg.lock @@ -0,0 +1,9 @@ +# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'. + + +[solve-meta] + analyzer-name = "dep" + analyzer-version = 1 + inputs-digest = "ab4fef131ee828e96ba67d31a7d690bd5f2f42040c6766b1b12fe856f87e0ff7" + solver-name = "gps-cdcl" + solver-version = 1 diff --git a/bindings/go/Gopkg.toml b/bindings/go/Gopkg.toml new file mode 100644 index 0000000000..525774ebad --- /dev/null +++ b/bindings/go/Gopkg.toml @@ -0,0 +1,2 @@ +# The FoundationDB go bindings currently have no external golang dependencies outside of +# the go standard library. diff --git a/bindings/go/include.mk b/bindings/go/include.mk index 4a5ea38433..4fceadb9d7 100644 --- a/bindings/go/include.mk +++ b/bindings/go/include.mk @@ -21,7 +21,7 @@ TARGETS += fdb_go fdb_go_tester CLEAN_TARGETS += fdb_go_clean fdb_go_tester_clean -GOPATH := $(CURDIR)/bindings/go +GOPATH := $(shell go env GOPATH) # We only override if the environment didn't set it (this is used by # the fdbwebsite documentation build process) @@ -47,6 +47,15 @@ GO_SRC := $(shell find $(GOPATH)/src -name '*.go') fdb_go: $(GO_PACKAGE_OBJECTS) $(GO_SRC) +fdb_go_path: + @echo "Creating fdb_go_path" + @mkdir -p $(GOPATH)/src/github.com/cie 2> /dev/null +ifeq ($(PLATFORM),linux) + @ln -sF $(CURDIR) $(GOPATH)/src/github.com/apple/foundationdb +else ifeq ($(PLATFORM),osx) + @ln -sf $(CURDIR) $(GOPATH)/src/github.com/apple/foundationdb +endif + fdb_go_clean: @echo "Cleaning fdb_go" @rm -rf $(GO_PACKAGE_OUTDIR) @@ -57,27 +66,27 @@ fdb_go_tester_clean: @echo "Cleaning fdb_go_tester" @rm -rf $(GOPATH)/bin -$(GOPATH)/bin/_stacktester: $(GO_SRC) $(GO_PACKAGE_OBJECTS) bindings/go/src/fdb/generated.go +$(GOPATH)/bin/_stacktester: fdb_go_path $(GO_SRC) $(GO_PACKAGE_OBJECTS) bindings/go/src/fdb/generated.go @echo "Compiling $(basename $(notdir $@))" - @go install _stacktester + @go install github.com/apple/foundationdb/bindings/go/src/_stacktester -$(GO_PACKAGE_OUTDIR)/fdb/tuple.a: $(GO_SRC) $(GO_PACKAGE_OUTDIR)/fdb.a bindings/go/src/fdb/generated.go +$(GO_PACKAGE_OUTDIR)/fdb/tuple.a: fdb_go_path $(GO_SRC) $(GO_PACKAGE_OUTDIR)/fdb.a bindings/go/src/fdb/generated.go @echo "Compiling fdb/tuple" - @go install fdb/tuple + @go install github.com/apple/foundationdb/bindings/go/src/fdb/tuple -$(GO_PACKAGE_OUTDIR)/fdb/subspace.a: $(GO_SRC) $(GO_PACKAGE_OUTDIR)/fdb.a $(GO_PACKAGE_OUTDIR)/fdb/tuple.a bindings/go/src/fdb/generated.go +$(GO_PACKAGE_OUTDIR)/fdb/subspace.a: fdb_go_path $(GO_SRC) $(GO_PACKAGE_OUTDIR)/fdb.a $(GO_PACKAGE_OUTDIR)/fdb/tuple.a bindings/go/src/fdb/generated.go @echo "Compiling fdb/subspace" - @go install fdb/subspace + @go install github.com/apple/foundationdb/bindings/go/src/fdb/subspace -$(GO_PACKAGE_OUTDIR)/fdb/directory.a: $(GO_SRC) $(GO_PACKAGE_OUTDIR)/fdb.a $(GO_PACKAGE_OUTDIR)/fdb/tuple.a $(GO_PACKAGE_OUTDIR)/fdb/subspace.a bindings/go/src/fdb/generated.go +$(GO_PACKAGE_OUTDIR)/fdb/directory.a: fdb_go_path $(GO_SRC) $(GO_PACKAGE_OUTDIR)/fdb.a $(GO_PACKAGE_OUTDIR)/fdb/tuple.a $(GO_PACKAGE_OUTDIR)/fdb/subspace.a bindings/go/src/fdb/generated.go @echo "Compiling fdb/directory" - @go install fdb/directory + @go install github.com/apple/foundationdb/bindings/go/src/fdb/directory -$(GO_PACKAGE_OUTDIR)/fdb.a: $(GO_SRC) bindings/go/src/fdb/generated.go +$(GO_PACKAGE_OUTDIR)/fdb.a: fdb_go_path $(GO_SRC) bindings/go/src/fdb/generated.go @echo "Compiling fdb" - @go install fdb + @go install github.com/apple/foundationdb/bindings/go/src/fdb -bindings/go/src/fdb/generated.go: lib/libfdb_c.$(DLEXT) bindings/go/src/_util/translate_fdb_options.go fdbclient/vexillographer/fdb.options +bindings/go/src/fdb/generated.go: fdb_go_path lib/libfdb_c.$(DLEXT) bindings/go/src/_util/translate_fdb_options.go fdbclient/vexillographer/fdb.options @echo "Building $@" @go run bindings/go/src/_util/translate_fdb_options.go < fdbclient/vexillographer/fdb.options > $@ diff --git a/bindings/go/install.sh b/bindings/go/install.sh new file mode 100755 index 0000000000..e24577ae03 --- /dev/null +++ b/bindings/go/install.sh @@ -0,0 +1,288 @@ +#!/bin/bash -eu +# +# install.sh +# +# Installs the FoundationDB Go bindings for a client. This will download +# the repository from the remote repo either into the go directory +# with the appropriate semantic version. It will then build a few +# generated files that need to be present for the go build to work. +# At the end, it has some advice for flags to modify within your +# go environment so that other packages may successfully use this +# library. +# + +DESTDIR="${DESTDIR:-}" +FDBVER="${FDBVER:-5.0.1}" +REMOTE="${REMOTE:-github.geo.apple.com}" +FDBREPO="${FDBREPO:-cie/foundation}" + +status=0 + +platform=$(uname) +if [[ "${platform}" == "Darwin" ]] ; then + FDBLIBDIR="${FDBLIBDIR:-/usr/local/lib}" + libfdbc="libfdb_c.dylib" +elif [[ "${platform}" == "Linux" ]] ; then + FDBLIBDIR="${FDBLIBDIR:-/usr/lib}" + libfdbc="libfdb_c.so" +else + echo "Unsupported platform ${platform}". + echo "At the moment, only macOS and Linux are supported by this script." + let status="${status} + 1" +fi + +filedir=$(cd `dirname "${BASH_SOURCE[0]}"` && pwd) +destdir="" + +function printUsage() { + echo "Usage: install.sh " + echo + echo "cmd: One of the commands to run. The options are:" + echo " install Download the FDB go bindings and install them" + echo " localinstall Install a into the go path a local copy of the repo" + echo " download Download but do not prepare the FoundationDB bindings" + echo " help Print this help message and then quit" + echo + echo "Command Line Options:" + echo " --fdbver FoundationDB semantic version (default is ${FDBVER})" + echo " -d/--dest-dir Local location for the repo (default is to place in go path)" + echo + echo "Environment Variable Options:" + echo " REMOTE Remote repository to download from (currently ${REMOTE})" + echo " FDBREPO Repository of FoundationDB library to download (currently ${FDBREPO})" + echo " FDBLIBDIR Directory within which should be the FoundationDB c library (currently ${FDBLIBDIR})" +} + +function parseArgs() { + local status=0 + + if [[ "${#}" -lt 0 ]] ; then + printUsage + let status="${status} + 1" + else + operation="${1}" + shift + if [[ "${operation}" != "install" ]] && [[ "${operation}" != "localinstall" ]] && [[ "${operation}" != "download" ]] && [[ "${operation}" != "help" ]] ; then + echo "Unknown command: ${operation}" + printUsage + let status="${status} + 1" + fi + fi + + while [[ "${#}" -gt 0 ]] && [[ "${status}" -eq 0 ]] ; do + local key="${1}" + case "${key}" in + --fdbver) + if [[ "${#}" -lt 2 ]] ; then + echo "No version specified with --fdbver flag" + printUsage + let status="${status} + 1" + else + FDBVER="${2}" + fi + shift + ;; + + -d|--dest-dir) + if [[ "${#}" -lt 2 ]] ; then + echo "No destination specified with ${key} flag" + printUsage + let status="${status} + 1" + else + destdir="${2}" + fi + shift + ;; + + *) + echo "Unrecognized argument ${key}" + printUsage + let status="${status} + 1" + esac + shift + done + + return "${status}" +} + +function checkBin() { + if [[ "${#}" -lt 1 ]] ; then + echo "Usage: checkBin " + return 1 + else + if [[ -n $(which "${1}") ]] ; then + return 0 + else + return 1 + fi + fi +} + +if [[ "${status}" -gt 0 ]] ; then + # We have already failed. + : +elif [[ "${#}" -lt 1 ]] ; then + printUsage +else + required_bins=( 'go' 'git' 'make' 'mono' ) + + missing_bins=() + for bin in "${required_bins[@]}" ; do + if ! checkBin "${bin}" ; then + missing_bins+=("${bin}") + let status="${status} + 1" + fi + done + + if [[ "${status}" -gt 0 ]] ; then + echo "Missing binaries: ${missing_bins[*]}" + elif ! parseArgs ${@} ; then + let status="${status} + 1" + elif [[ "${operation}" == "help" ]] ; then + printUsage + else + # Add go-specific environment variables. + eval $(go env) + + golibdir=$(dirname "${GOPATH}/src/${REMOTE}/${FDBREPO}") + if [[ -z "${destdir}" ]] ; then + if [[ "${operation}" == "localinstall" ]] ; then + # Assume its the local directory. + destdir=$(cd "${filedir}/../../.." && pwd) + else + destdir="${golibdir}" + fi + fi + + if [[ ! -d "${destdir}" ]] ; then + cmd=( 'mkdir' '-p' "${destdir}" ) + echo "${cmd[*]}" + if ! "${cmd[@]}" ; then + let status="${status} + 1" + echo "Could not create destination directory ${destdir}." + fi + fi + + # Step 1: Make sure repository is present. + + if [[ "${status}" -eq 0 ]] ; then + destdir=$( cd "${destdir}" && pwd ) # Get absolute path of destination dir. + fdbdir="${destdir}/foundation" + + if [[ ! -d "${destdir}" ]] ; then + cmd=("mkdir" "-p" "${destdir}") + echo "${cmd[*]}" + if ! "${cmd[@]}" ; then + echo "Could not create destination directory ${destdir}." + let status="${status} + 1" + fi + fi + fi + + if [[ "${operation}" == "localinstall" ]] ; then + # No download occurs in this case. + : + else + if [[ -d "${fdbdir}" ]] ; then + echo "Directory ${fdbdir} already exists ; checking out appropriate tag" + cmd1=( 'git' '-C' "${fdbdir}" 'fetch' 'origin' ) + cmd2=( 'git' '-C' "${fdbdir}" 'checkout' "release-${FDBVER}" ) + + if ! echo "${cmd1[*]}" || ! "${cmd1[@]}" ; then + let status="${status} + 1" + echo "Could not pull latest changes from origin" + elif ! echo "${cmd2[*]}" || ! "${cmd2[@]}" ; then + let status="${status} + 1" + echo "Could not checkout tag release-${FDBVER}." + fi + else + echo "Downloading foundation repository into ${destdir}:" + cmd=( 'git' '-C' "${destdir}" 'clone' '--branch' "release-${FDBVER}" "git@${REMOTE}:${FDBREPO}.git" ) + + echo "${cmd[*]}" + if ! "${cmd[@]}" ; then + let status="${status} + 1" + echo "Could not download repository." + fi + fi + fi + + # Step 2: Build generated things. + + if [[ "${operation}" == "download" ]] ; then + # The generated files are not created under a strict download. + : + elif [[ "${status}" -eq 0 ]] ; then + echo "Building generated files." + cmd=( 'make' '-C' "${fdbdir}" 'bindings/c/foundationdb/fdb_c_options.g.h' ) + + echo "${cmd[*]}" + if ! "${cmd[@]}" ; then + let status="${status} + 1" + echo "Could not generate required c header" + else + infile="${fdbdir}/fdbclient/vexillographer/fdb.options" + outfile="${fdbdir}/bindings/go/src/fdb/generated.go" + cmd=( 'go' 'run' "${fdbdir}/bindings/go/src/_util/translate_fdb_options.go" ) + echo "${cmd[*]} < ${infile} > ${outfile}" + if ! "${cmd[@]}" < "${infile}" > "${outfile}" ; then + let status="${status} + 1" + echo "Could not generate generated go file." + fi + fi + fi + + # Step 3: Add to go path. + + if [[ "${operation}" == "download" ]] ; then + # The files are not moved under a strict download. + : + elif [[ "${status}" -eq 0 ]] ; then + linkpath="${GOPATH}/src/${REMOTE}/${FDBREPO}" + if [[ "${linkpath}" == "${fdbdir}" ]] ; then + # Downloaded directly into go path. Skip making the link. + : + elif [[ -e "${linkpath}" ]] ; then + echo "Warning: link path (${linkpath}) already exists. Leaving in place." + else + dirpath=$(dirname "${linkpath}") + if [[ ! -d "${dirpath}" ]] ; then + cmd=( 'mkdir' '-p' "${dirpath}" ) + echo "${cmd[*]}" + if ! "${cmd[@]}" ; then + let status="${status} + 1" + echo "Could not create directory for link." + fi + fi + + if [[ "${status}" -eq 0 ]] ; then + cmd=( 'ln' '-s' "${fdbdir}" "${linkpath}" ) + echo "${cmd[*]}" + if ! "${cmd[@]}" ; then + let status="${status} + 1" + echo "Could not create link within go path." + fi + fi + fi + fi + + # Step 4: Explain CGO flags. + + if [[ "${status}" -eq 0 && ("${operation}" == "localinstall" || "${operation}" == "install" ) ]] ; then + echo + echo "The FoundationDB go bindings were successfully installed." + echo "To build packages which use the go bindings, you will need to" + echo "set the following environment variables:" + echo " CGO_CFLAGS=\"-g -O2 -I${linkpath}/bindings/c\"" + echo " CGO_LDFLAGS=\"-g -O2 -L${FDBLIBDIR}\"" + + if [[ ! -e "${FDBLIBDIR}/${libfdbc}" ]] ; then + echo + echo "WARNING: The FoundationDB C library was not found within ${FDBLIBDIR}." + echo "Your installation may be incomplete." + fi + fi + fi +fi + +exit "${status}" diff --git a/bindings/go/src/_stacktester/directory.go b/bindings/go/src/_stacktester/directory.go index ac4ff1217b..fa66205fde 100644 --- a/bindings/go/src/_stacktester/directory.go +++ b/bindings/go/src/_stacktester/directory.go @@ -21,10 +21,10 @@ package main import ( - "fdb" - "fdb/tuple" - "fdb/subspace" - "fdb/directory" + "github.com/apple/foundationdb/bindings/go/src/fdb" + "github.com/apple/foundationdb/bindings/go/src/fdb/tuple" + "github.com/apple/foundationdb/bindings/go/src/fdb/subspace" + "github.com/apple/foundationdb/bindings/go/src/fdb/directory" "strings" "bytes" ) @@ -94,14 +94,14 @@ func (sm *StackMachine) maybePath() []string { } var createOps = map[string]bool { - "CREATE_SUBSPACE": true, - "CREATE_LAYER": true, - "CREATE_OR_OPEN": true, - "CREATE": true, - "OPEN": true, - "MOVE": true, - "MOVE_TO": true, - "OPEN_SUBSPACE": true, + "CREATE_SUBSPACE": true, + "CREATE_LAYER": true, + "CREATE_OR_OPEN": true, + "CREATE": true, + "OPEN": true, + "MOVE": true, + "MOVE_TO": true, + "OPEN_SUBSPACE": true, } func (de *DirectoryExtension) processOp(sm *StackMachine, op string, isDB bool, idx int, t fdb.Transactor, rt fdb.ReadTransactor) { diff --git a/bindings/go/src/_stacktester/stacktester.go b/bindings/go/src/_stacktester/stacktester.go index 81a1c9e18b..615e851f86 100644 --- a/bindings/go/src/_stacktester/stacktester.go +++ b/bindings/go/src/_stacktester/stacktester.go @@ -24,8 +24,8 @@ import ( "bytes" "encoding/binary" "encoding/hex" - "fdb" - "fdb/tuple" + "github.com/apple/foundationdb/bindings/go/src/fdb" + "github.com/apple/foundationdb/bindings/go/src/fdb/tuple" "log" "fmt" "os" diff --git a/bindings/go/src/fdb/directory/allocator.go b/bindings/go/src/fdb/directory/allocator.go index 69400fff8d..7303a45fee 100644 --- a/bindings/go/src/fdb/directory/allocator.go +++ b/bindings/go/src/fdb/directory/allocator.go @@ -23,8 +23,8 @@ package directory import ( - "fdb" - "fdb/subspace" + "github.com/apple/foundationdb/bindings/go/src/fdb" + "github.com/apple/foundationdb/bindings/go/src/fdb/subspace" "encoding/binary" "bytes" "math/rand" diff --git a/bindings/go/src/fdb/directory/directory.go b/bindings/go/src/fdb/directory/directory.go index 72e82230a1..7125dc45a5 100644 --- a/bindings/go/src/fdb/directory/directory.go +++ b/bindings/go/src/fdb/directory/directory.go @@ -40,8 +40,8 @@ package directory import ( - "fdb" - "fdb/subspace" + "github.com/apple/foundationdb/bindings/go/src/fdb" + "github.com/apple/foundationdb/bindings/go/src/fdb/subspace" "errors" ) @@ -140,15 +140,15 @@ type Directory interface { } func stringsEqual(a, b []string) bool { - if len(a) != len(b) { - return false - } - for i, v := range a { - if v != b[i] { - return false - } - } - return true + if len(a) != len(b) { + return false + } + for i, v := range a { + if v != b[i] { + return false + } + } + return true } func moveTo(t fdb.Transactor, dl directoryLayer, path, newAbsolutePath []string) (DirectorySubspace, error) { diff --git a/bindings/go/src/fdb/directory/directoryLayer.go b/bindings/go/src/fdb/directory/directoryLayer.go index a5bfd4f102..f27caac418 100644 --- a/bindings/go/src/fdb/directory/directoryLayer.go +++ b/bindings/go/src/fdb/directory/directoryLayer.go @@ -23,9 +23,9 @@ package directory import ( - "fdb" - "fdb/subspace" - "fdb/tuple" + "github.com/apple/foundationdb/bindings/go/src/fdb" + "github.com/apple/foundationdb/bindings/go/src/fdb/subspace" + "github.com/apple/foundationdb/bindings/go/src/fdb/tuple" "encoding/binary" "bytes" "fmt" diff --git a/bindings/go/src/fdb/directory/directoryPartition.go b/bindings/go/src/fdb/directory/directoryPartition.go index 253d9482db..cdacc1746e 100644 --- a/bindings/go/src/fdb/directory/directoryPartition.go +++ b/bindings/go/src/fdb/directory/directoryPartition.go @@ -23,9 +23,9 @@ package directory import ( - "fdb" - "fdb/subspace" - "fdb/tuple" + "github.com/apple/foundationdb/bindings/go/src/fdb" + "github.com/apple/foundationdb/bindings/go/src/fdb/subspace" + "github.com/apple/foundationdb/bindings/go/src/fdb/tuple" ) type directoryPartition struct { diff --git a/bindings/go/src/fdb/directory/directorySubspace.go b/bindings/go/src/fdb/directory/directorySubspace.go index 70641f4422..36437ea994 100644 --- a/bindings/go/src/fdb/directory/directorySubspace.go +++ b/bindings/go/src/fdb/directory/directorySubspace.go @@ -23,8 +23,8 @@ package directory import ( - "fdb" - "fdb/subspace" + "github.com/apple/foundationdb/bindings/go/src/fdb" + "github.com/apple/foundationdb/bindings/go/src/fdb/subspace" ) // DirectorySubspace represents a Directory that may also be used as a Subspace diff --git a/bindings/go/src/fdb/directory/node.go b/bindings/go/src/fdb/directory/node.go index a608abafcc..881a965880 100644 --- a/bindings/go/src/fdb/directory/node.go +++ b/bindings/go/src/fdb/directory/node.go @@ -23,8 +23,8 @@ package directory import ( - "fdb" - "fdb/subspace" + "github.com/apple/foundationdb/bindings/go/src/fdb" + "github.com/apple/foundationdb/bindings/go/src/fdb/subspace" "bytes" ) diff --git a/bindings/go/src/fdb/doc.go b/bindings/go/src/fdb/doc.go index aee3e85cfe..fc4cdc563b 100644 --- a/bindings/go/src/fdb/doc.go +++ b/bindings/go/src/fdb/doc.go @@ -39,7 +39,7 @@ A basic interaction with the FoundationDB API is demonstrated below: package main import ( - "github.com/apple/foundationdb/bindings/go/fdb" + "github.com/apple/foundationdb/bindings/go/src/fdb" "log" "fmt" ) diff --git a/bindings/go/src/fdb/fdb_test.go b/bindings/go/src/fdb/fdb_test.go index 4f07a5c6f9..709310a499 100644 --- a/bindings/go/src/fdb/fdb_test.go +++ b/bindings/go/src/fdb/fdb_test.go @@ -23,7 +23,7 @@ package fdb_test import ( - "fdb" + "github.com/apple/foundationdb/bindings/go/src/fdb" "fmt" "testing" ) diff --git a/bindings/go/src/fdb/subspace/subspace.go b/bindings/go/src/fdb/subspace/subspace.go index 3e48842a1f..a123ea1d31 100644 --- a/bindings/go/src/fdb/subspace/subspace.go +++ b/bindings/go/src/fdb/subspace/subspace.go @@ -33,8 +33,8 @@ package subspace import ( - "fdb" - "fdb/tuple" + "github.com/apple/foundationdb/bindings/go/src/fdb" + "github.com/apple/foundationdb/bindings/go/src/fdb/tuple" "bytes" "errors" ) diff --git a/bindings/go/src/fdb/tuple/tuple.go b/bindings/go/src/fdb/tuple/tuple.go index 1f1c5959da..444f2a8cff 100644 --- a/bindings/go/src/fdb/tuple/tuple.go +++ b/bindings/go/src/fdb/tuple/tuple.go @@ -38,7 +38,7 @@ import ( "fmt" "encoding/binary" "bytes" - "fdb" + "github.com/apple/foundationdb/bindings/go/src/fdb" ) // A TupleElement is one of the types that may be encoded in FoundationDB