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.
This commit is contained in:
parent
d29b6894e5
commit
59a6969c25
5 changed files with 163 additions and 25 deletions
|
@ -43,6 +43,14 @@
|
|||
"Projects"
|
||||
]
|
||||
},
|
||||
"externalConfigurations": [
|
||||
{
|
||||
"label": "Neovim",
|
||||
"gitRepoURL": "https://codeflow.dananglin.me.uk/linux-home/nvim.d.git",
|
||||
"gitRef": "746f07efdb203a46a7a02ada987cd97b68fa92d6",
|
||||
"gitRepoPath": "nvim"
|
||||
}
|
||||
],
|
||||
"git": {
|
||||
"gpgSign": false,
|
||||
"user": {
|
||||
|
|
102
magefiles/external.go
Normal file
102
magefiles/external.go
Normal file
|
@ -0,0 +1,102 @@
|
|||
//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
|
||||
}
|
|
@ -8,52 +8,60 @@ import (
|
|||
"strings"
|
||||
)
|
||||
|
||||
const configDir string = "hosts"
|
||||
const dir string = "hosts"
|
||||
|
||||
type Config struct {
|
||||
ManagedConfigurations []string `json:"managedConfigurations"`
|
||||
BashProfile ConfigBashProfile `json:"bashProfile"`
|
||||
Directories ConfigDirectories `json:"directories"`
|
||||
Git ConfigGit `json:"git"`
|
||||
BashProfile BashProfile `json:"bashProfile"`
|
||||
Directories Directories `json:"directories"`
|
||||
Git Git `json:"git"`
|
||||
ExternalConfigurations []ExternalConfig `json:"externalConfigurations"`
|
||||
}
|
||||
|
||||
type ConfigDirectories struct {
|
||||
type Directories struct {
|
||||
UseDefaultDirectories bool `json:"useDefaultDirectories"`
|
||||
IncludeXDGDirectories bool `json:"includeXDGDirectories"`
|
||||
AdditionalDirectories []string `json:"additionalDirectories"`
|
||||
}
|
||||
|
||||
type ConfigGit struct {
|
||||
type Git struct {
|
||||
GpgSign bool `json:"gpgSign"`
|
||||
User ConfigGitUser `json:"user"`
|
||||
User GitUser `json:"user"`
|
||||
}
|
||||
|
||||
type ConfigGitUser struct {
|
||||
type GitUser struct {
|
||||
Email string `json:"email"`
|
||||
Name string `json:"name"`
|
||||
SigningKey string `json:"signingKey"`
|
||||
}
|
||||
|
||||
type ConfigBashProfile struct {
|
||||
type BashProfile struct {
|
||||
Manage bool `json:"manage"`
|
||||
Filename string `json:"filename"`
|
||||
SessionPaths []ConfigBashProfileSessionPath `json:"sessionPaths"`
|
||||
SessionPaths []BashProfileSessionPath `json:"sessionPaths"`
|
||||
XdgDirectories map[string]string `json:"xdgDirectories"`
|
||||
EnvironmentVariables map[string]string `json:"environmentVariables"`
|
||||
Aliases map[string]string `json:"aliases"`
|
||||
Commands []ConfigBashProfileCommand `json:"commands"`
|
||||
Commands []BashProfileCommand `json:"commands"`
|
||||
}
|
||||
|
||||
type ConfigBashProfileSessionPath struct {
|
||||
type BashProfileSessionPath struct {
|
||||
Path string `json:"path"`
|
||||
Description string `json:"description"`
|
||||
}
|
||||
|
||||
type ConfigBashProfileCommand struct {
|
||||
type BashProfileCommand struct {
|
||||
Command string `json:"command"`
|
||||
Description string `json:"description"`
|
||||
}
|
||||
|
||||
type ExternalConfig struct {
|
||||
Label string `json:"label"`
|
||||
GitRepoURL string `json:"gitRepoURL"`
|
||||
GitRef string `json:"gitRef"`
|
||||
GitRepoPath string `json:"gitRepoPath"`
|
||||
}
|
||||
|
||||
func NewConfig() (Config, error) {
|
||||
cfg := defaultConfig()
|
||||
|
||||
|
@ -89,24 +97,25 @@ func configFilePath() (string, error) {
|
|||
|
||||
identifier := hostnameParts[1]
|
||||
|
||||
return filepath.Join(configDir, identifier+".json"), nil
|
||||
return filepath.Join(dir, identifier+".json"), nil
|
||||
}
|
||||
|
||||
func defaultConfig() Config {
|
||||
return Config{
|
||||
Directories: ConfigDirectories{
|
||||
Directories: Directories{
|
||||
UseDefaultDirectories: true,
|
||||
IncludeXDGDirectories: true,
|
||||
AdditionalDirectories: []string{},
|
||||
},
|
||||
Git: ConfigGit{
|
||||
Git: Git{
|
||||
GpgSign: false,
|
||||
User: ConfigGitUser{
|
||||
User: GitUser{
|
||||
Email: "",
|
||||
Name: "",
|
||||
SigningKey: "",
|
||||
},
|
||||
},
|
||||
ManagedConfigurations: []string{},
|
||||
ExternalConfigurations: []ExternalConfig{},
|
||||
}
|
||||
}
|
||||
|
|
19
scripts/install_lazy.nvim
Executable file
19
scripts/install_lazy.nvim
Executable file
|
@ -0,0 +1,19 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
set -o errexit
|
||||
set -o nounset
|
||||
set -o pipefail
|
||||
|
||||
LAZY_NVIM_SOURCE="https://github.com/folke/lazy.nvim.git"
|
||||
LAZY_NVIM_DESTINATION="${XDG_DATA_HOME}/nvim/lazy/lazy.nvim"
|
||||
LAZY_STATE_DIR="${XDG_STATE_HOME}/nvim/lazy"
|
||||
|
||||
mkdir -p "${LAZY_STATE_DIR}"
|
||||
|
||||
if [ -d "${LAZY_NVIM_DESTINATION}/.git" ]; then
|
||||
echo "INFO: ${LAZY_NVIM_DESTINATION} is already present"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo "INFO: Cloning ${LAZY_NVIM_SOURCE} to ${LAZY_NVIM_DESTINATION}..."
|
||||
git clone --filter=blob:none --single-branch "${LAZY_NVIM_SOURCE}" "${LAZY_NVIM_DESTINATION}"
|
Loading…
Reference in a new issue