103 lines
2.3 KiB
Go
103 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
|
||
|
}
|