I’m writing a derivation for the fly
CLI (for use with Concourse CI).
I wanted to include bash completions along with the fly
executable. Because buildGoPackage
produces a multiple-output package, I ended up using symlinkJoin
to wrap things up in a single derivation.
I’m not familiar with golang, and it was a bit of a journey figuring out how to package the bash completions alongside the binary. I’d like to post what I ended up with in case anyone has suggestions about possible improvements.
At the moment, I’m accessing the derivation through an overlay:
self: super: {
fly = super.callPackage pkgs/fly { };
}
The pkgs/fly/default.nix
:
{ pkgs ? import ./nixpkgs.nix { } }:
let
pinned = builtins.fromJSON (builtins.readFile ./pinned.json);
fly = with pkgs; buildGoPackage rec {
name = "fly-${version}";
version = pinned.fly.version;
src = fetchFromGitHub pinned.fly.src;
goPackagePath = "github.com/concourse/fly";
goDeps = ./deps.nix;
buildFlagsArray = ''
-ldflags=
-X ${goPackagePath}/version.Version=${version}
'';
postInstall = ''
install -D -m 444 ${
pkgs.writeText "fly.bash" (builtins.readFile ./fly.bash)
} $out/share/bash-completion/completions/fly
'';
};
in pkgs.symlinkJoin {
name = "fly";
paths = [
fly.bin
fly.out
];
}
The pkgs/fly/fly.bash
script:
#!/usr/bin/env bash
_fly() {
# All arguments except the first one
args=("${COMP_WORDS[@]:1:$COMP_CWORD}")
# Only split on newlines
local IFS=$'\n'
# Call completion (note that the first element of COMP_WORDS is
# the executable itself)
COMPREPLY=($(GO_FLAGS_COMPLETION=1 ${COMP_WORDS[0]} "${args[@]}"))
return 0
}
complete -F _fly fly
The pkgs/fly/deps.nix
was generated using go2nix
as follows:
git clone --jobs=8 --recursive --branch=v4.2.3 https://github.com/concourse/concourse
cd concourse
nix-shell -p go go2nix
export GOPATH=$PWD
cd src/github.com/concourse/fly
go build -ldflags "-X github.com/concourse/fly/version.Version=4.2.3"
go2nix save
As a side-note, I’m using buildGoPackage
rather than buildGoModule
because the version of fly
I need doesn’t use go modules. I’d like to eventually submit a derivation to nixpkgs, though I’ll probably try to package a more recent version of fly
for that, and would put something more idiomatic together (e.g. without pinned.json
, etc.).