ob-go
ob-go copied to clipboard
Support importing external packages
It would be convenient if it were possible to also import packages not part of the standard library, e.g., via…
#+begin_src go :imports "golang.org/x/exp/constraints@latest"
…
#+end_src
I have a workaround, but it's kind of ugly.
Since Go 1.17, you can't install a package "globally" using go get example.org/foo.
- You can install such a package locally if you're in a directory that has (or whose ancestors have) a
go.modfile created withgo mod init, or - You can install a package globally with
go install example.org/foo@SOMEVERif and only if it is an executable command. But most Go packages are not stand-alone commands.
Unfortunately, ob-go creates a new temp directory for each of the source blocks it executes, so for most third-party imports, neither of the above points applies.
I got it to work by doing this:
- I created a known, static location for all
ob-gocode to run in:mkdir $GOPATH/src/babel - I turned this directory into a module:
cd $GOPATH/src/babel go mod init github.com/uakotaobi/babel - I installed third-party packages my
ob-goblocks needed by hand:go get example.org/foo - I forced any source blocks requiring third-party code to use that module directory:
Steps 1-3 only have to be done once, and step 4 is not needed if a source block is only using builtins.#+name: ob-go-sample-source-block #+begin_src go :dir (substitute-in-file-name "$GOPATH/src/babel") import ( "fmt" "example.org/foo" ) func main() { fmt.Printf("Hello, world\n") } #+end_src
This is pretty ugly, but I've tested it and it works. It would be better if ob-go automatically turned its temp folders into modules and imported the :imports dependencies with go get.