manager/magefiles/external.go
Dan Anglin 59a6969c25
feat: download configs from external sources
Download and install configurations from external sources. At the moment
downloading from external git repositories is only supported.

Download and install the Neovim configuration for sparrow.

Add an external script to install lazy.nvim.
2024-09-14 11:41:58 +01:00

102 lines
2.3 KiB
Go

//go:build mage
package main
import (
"fmt"
"os"
"path/filepath"
"slices"
"strings"
"codeflow.dananglin.me.uk/linux-home/manager/magefiles/internal/config"
"codeflow.dananglin.me.uk/linux-home/manager/magefiles/internal/walk"
"github.com/magefile/mage/sh"
)
// Externalconfigs downloads and manages neovim configuration from a remote git repository.
func Externalconfigs() error {
cfg, err := config.NewConfig()
if err != nil {
return fmt.Errorf(
"unable to load the configuration: %w",
err,
)
}
homeConfigDir, err := os.UserConfigDir()
if err != nil {
return fmt.Errorf(
"unable to get the user's home configuration directory: %w",
err,
)
}
for _, externalConfig := range slices.All(cfg.ExternalConfigurations) {
if err := manageExternalConfig(externalConfig, homeConfigDir); err != nil {
return fmt.Errorf("received an error while processing %s: %w", externalConfig.Label, err)
}
}
return nil
}
func manageExternalConfig(cfg config.ExternalConfig, homeConfigDir string) error {
clonedRepo, err := downloadRepo(cfg.GitRepoURL, cfg.GitRef)
if err != nil {
return fmt.Errorf("unable to clone the git repository: %w", err)
}
defer os.RemoveAll(clonedRepo)
fmt.Println("Git repository cloned to:", clonedRepo)
validationFunc := func(relativePath string) bool {
split := strings.SplitN(relativePath, "/", 2)
if len(split) < 1 {
return false
}
rootPath := split[0]
return rootPath == cfg.GitRepoPath
}
if err = filepath.WalkDir(
clonedRepo,
walk.CopyFiles(homeConfigDir, clonedRepo, rootManagedDir, validationFunc),
); err != nil {
return fmt.Errorf("received an error while copying the files: %w", err)
}
return nil
}
func downloadRepo(repoURL, repoRef string) (string, error) {
cloneDir, err := os.MkdirTemp("/tmp", "config-")
if err != nil {
return "", fmt.Errorf("unable to create the temporary directory: %w", err)
}
git := sh.RunCmd("git", "-C", cloneDir)
commands := [][]string{
{"init"},
{"remote", "add", "origin", repoURL},
{"fetch", "origin", repoRef},
{"checkout", "FETCH_HEAD"},
}
for _, command := range slices.All(commands) {
if err := git(command...); err != nil {
return "", err
}
}
if err := os.RemoveAll(filepath.Join(cloneDir, ".git")); err != nil {
return "", fmt.Errorf("unable to remove the .git folder: %w", err)
}
return cloneDir, nil
}