//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 }