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-gitMy 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.
