Shoal
is a declarative tool that installs sets of GoFish foods.
- CLI
- Go library
Create a shoal.yaml
and run shoal [-f shoal.yaml] sync
:
rig: &rig https://github.com/fishworks/fish-food
dependencies:
- rig: *rig
food: helmfile
version: ">= 0.125.0"
- rig: *rig
food: helm
version: ">= 3.3.0"
- rig: *rig
food: kubectl
version: ">= 1.18.0"
- rig: *rig
food: eksctl
version: ">= 0.23.0"
# Additionally, you can declare whatever food found in
# https://github.com/fishworks/fish-food/tree/main/Food
helm:
plugins:
diff: ">= 3.1.3"
The installed binaries are linked under $PWD/.shoal/bin
.
Create a shoal.Config
and run shoal/App.Sync
on it.
The installation path can be obtained via shoal/App.BinPath
:
import "github.com/fishworks/gofish/shoal"
func example() {
rig := "https://github.com/fishworks/fish-food"
app, err := shoal.New()
if err != nil {
fmt.Fprintf(os.Stderr, "Error: %v\n", err)
os.Exit(1)
}
if err := app.Sync(shoal.Config{
Dependencies: []shoal.Dependency{
{
Rig: rig,
Food: "helmfile",
Version: ">= 0.125.0",
},
{
Rig: rig,
Food: "helm",
Version: ">= 3.3.0",
},
{
Rig: rig,
Food: "kubectl",
Version: ">= 1.18.0",
},
{
Rig: rig,
Food: "eksctl",
Version: ">= 0.23.0",
},
},
}); err != nil {
fmt.Fprintf(os.Stderr, "%v\n", err)
os.Exit(1)
}
binPath := app.BinPath()
cmd := exec.Command(filepath.Join(binPath, "helm"), "version", "-c")
out, err := cmd.CombinedOutput()
if err != nil {
fmt.Fprintf(os.Stderr, "Error: running helm: %v", err)
os.Exit(1)
}
}
shoal
has two implementations of the provider
:
native
(default)go-git
The go-git
provider uses go-git instead of the git
command installed on your system,
for whatever git operation it needs to run, like clone
, log
, etc.
To enable the go-git
provider, add the git
section to your config, and set provider
to go-git
in it:
git:
provider: go-git
My initial goal was to build a cross-platform package manager that can be embedded into my terraform-provider-eksctl and terraform-provider-helmfile,
so that those tf providers are able to install and upgrade extra binaries
like eksctl
and helmfile
on demand,
while allowing users to manage versions of those binaries declaratively.
At the time of writing the first version of shoal
, there was already a robust cross-platform package manager written in Go, called gofish, authored by @bacongobbler.
I've conducted some manual testing, code reading, made one change to gofish
, and successfully built the initial version of shoal
on top of gofish
.
shoal
was implemented by mostly reorganizing gofish init
and gofish install
code, then adding a feature to fetch historical revisions of rigs(repos) and foods(packages) from Git, and a declarative config syntax.
The reorganization and additions were needed because gofish init
doesn't support sudo-less mode and gofish install
was unable to specify the specific version of food(package) to install.
Although the original use-case was to embed it into terraform providers, I got to think that something like brew-bundle
for Homebrew can be easily built around it, so I built the command-line interface to it. That's shoal sync
.