checkpoint: implemented managing external config
This commit is contained in:
parent
823252fe4d
commit
c5c643197f
5 changed files with 147 additions and 125 deletions
|
@ -193,11 +193,5 @@
|
||||||
"user-dirs.dirs",
|
"user-dirs.dirs",
|
||||||
"user-dirs.locale",
|
"user-dirs.locale",
|
||||||
"zk"
|
"zk"
|
||||||
],
|
]
|
||||||
"neovim": {
|
|
||||||
"manage": true,
|
|
||||||
"gitRepoURL": "https://codeflow.dananglin.me.uk/linux-home/nvim.d.git",
|
|
||||||
"gitRef": "746f07efdb203a46a7a02ada987cd97b68fa92d6",
|
|
||||||
"gitRepoPath": "nvim"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,6 +43,14 @@
|
||||||
"Projects"
|
"Projects"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"externalConfigurations": [
|
||||||
|
{
|
||||||
|
"label": "Neovim",
|
||||||
|
"gitRepoURL": "https://codeflow.dananglin.me.uk/linux-home/nvim.d.git",
|
||||||
|
"gitRef": "746f07efdb203a46a7a02ada987cd97b68fa92d6",
|
||||||
|
"gitRepoPath": "nvim"
|
||||||
|
}
|
||||||
|
],
|
||||||
"git": {
|
"git": {
|
||||||
"gpgSign": false,
|
"gpgSign": false,
|
||||||
"user": {
|
"user": {
|
||||||
|
|
100
magefiles/external.go
Normal file
100
magefiles/external.go
Normal file
|
@ -0,0 +1,100 @@
|
||||||
|
//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 := cloneNvimConfigRepo(cfg.GitRepoURL, cfg.GitRef)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("unable to clone the git repository: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
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 cloneNvimConfigRepo(repoURL, repoRef string) (string, error) {
|
||||||
|
cloneDir, err := os.MkdirTemp("/tmp", "neovim-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
|
||||||
|
}
|
|
@ -1,6 +1,4 @@
|
||||||
//go:build mage
|
package config
|
||||||
|
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
@ -10,74 +8,76 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
type config struct {
|
const dir string = "hosts"
|
||||||
ManagedConfigurations []string `json:"managedConfigurations"`
|
|
||||||
BashProfile configBashProfile `json:"bashProfile"`
|
type Config struct {
|
||||||
Directories configDirectories `json:"directories"`
|
ManagedConfigurations []string `json:"managedConfigurations"`
|
||||||
Git configGit `json:"git"`
|
BashProfile BashProfile `json:"bashProfile"`
|
||||||
Neovim configNeovim `json:"neovim"`
|
Directories Directories `json:"directories"`
|
||||||
|
Git Git `json:"git"`
|
||||||
|
ExternalConfigurations []ExternalConfig `json:"externalConfigurations"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type configDirectories struct {
|
type Directories struct {
|
||||||
UseDefaultDirectories bool `json:"useDefaultDirectories"`
|
UseDefaultDirectories bool `json:"useDefaultDirectories"`
|
||||||
IncludeXDGDirectories bool `json:"includeXDGDirectories"`
|
IncludeXDGDirectories bool `json:"includeXDGDirectories"`
|
||||||
AdditionalDirectories []string `json:"additionalDirectories"`
|
AdditionalDirectories []string `json:"additionalDirectories"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type configGit struct {
|
type Git struct {
|
||||||
GpgSign bool `json:"gpgSign"`
|
GpgSign bool `json:"gpgSign"`
|
||||||
User configGitUser `json:"user"`
|
User GitUser `json:"user"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type configGitUser struct {
|
type GitUser struct {
|
||||||
Email string `json:"email"`
|
Email string `json:"email"`
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
SigningKey string `json:"signingKey"`
|
SigningKey string `json:"signingKey"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type configBashProfile struct {
|
type BashProfile struct {
|
||||||
Manage bool `json:"manage"`
|
Manage bool `json:"manage"`
|
||||||
Filename string `json:"filename"`
|
Filename string `json:"filename"`
|
||||||
SessionPaths []configBashProfileSessionPath `json:"sessionPaths"`
|
SessionPaths []BashProfileSessionPath `json:"sessionPaths"`
|
||||||
XdgDirectories map[string]string `json:"xdgDirectories"`
|
XdgDirectories map[string]string `json:"xdgDirectories"`
|
||||||
EnvironmentVariables map[string]string `json:"environmentVariables"`
|
EnvironmentVariables map[string]string `json:"environmentVariables"`
|
||||||
Aliases map[string]string `json:"aliases"`
|
Aliases map[string]string `json:"aliases"`
|
||||||
Commands []configBashProfileCommand `json:"commands"`
|
Commands []BashProfileCommand `json:"commands"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type configBashProfileSessionPath struct {
|
type BashProfileSessionPath struct {
|
||||||
Path string `json:"path"`
|
Path string `json:"path"`
|
||||||
Description string `json:"description"`
|
Description string `json:"description"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type configBashProfileCommand struct {
|
type BashProfileCommand struct {
|
||||||
Command string `json:"command"`
|
Command string `json:"command"`
|
||||||
Description string `json:"description"`
|
Description string `json:"description"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type configNeovim struct {
|
type ExternalConfig struct {
|
||||||
Manage bool `json:"manage"`
|
Label string `json:"label"`
|
||||||
GitRepoURL string `json:"gitRepoURL"`
|
GitRepoURL string `json:"gitRepoURL"`
|
||||||
GitRef string `json:"gitRef"`
|
GitRef string `json:"gitRef"`
|
||||||
GitRepoPath string `json:"gitRepoPath"`
|
GitRepoPath string `json:"gitRepoPath"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func newConfig() (config, error) {
|
func NewConfig() (Config, error) {
|
||||||
cfg := defaultConfig()
|
cfg := defaultConfig()
|
||||||
|
|
||||||
path, err := configFilePath()
|
path, err := configFilePath()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return config{}, fmt.Errorf("unable to calculate the config file path: %w", err)
|
return Config{}, fmt.Errorf("unable to calculate the config file path: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
file, err := os.Open(path)
|
file, err := os.Open(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return config{}, fmt.Errorf("unable to open the file: %w", err)
|
return Config{}, fmt.Errorf("unable to open the file: %w", err)
|
||||||
}
|
}
|
||||||
defer file.Close()
|
defer file.Close()
|
||||||
|
|
||||||
if err = json.NewDecoder(file).Decode(&cfg); err != nil {
|
if err = json.NewDecoder(file).Decode(&cfg); err != nil {
|
||||||
return config{}, fmt.Errorf("unable to decode the JSON file: %w", err)
|
return Config{}, fmt.Errorf("unable to decode the JSON file: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return cfg, nil
|
return cfg, nil
|
||||||
|
@ -97,24 +97,25 @@ func configFilePath() (string, error) {
|
||||||
|
|
||||||
identifier := hostnameParts[1]
|
identifier := hostnameParts[1]
|
||||||
|
|
||||||
return filepath.Join(configDir, identifier+".json"), nil
|
return filepath.Join(dir, identifier+".json"), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func defaultConfig() config {
|
func defaultConfig() Config {
|
||||||
return config{
|
return Config{
|
||||||
Directories: configDirectories{
|
Directories: Directories{
|
||||||
UseDefaultDirectories: true,
|
UseDefaultDirectories: true,
|
||||||
IncludeXDGDirectories: true,
|
IncludeXDGDirectories: true,
|
||||||
AdditionalDirectories: []string{},
|
AdditionalDirectories: []string{},
|
||||||
},
|
},
|
||||||
Git: configGit{
|
Git: Git{
|
||||||
GpgSign: false,
|
GpgSign: false,
|
||||||
User: configGitUser{
|
User: GitUser{
|
||||||
Email: "",
|
Email: "",
|
||||||
Name: "",
|
Name: "",
|
||||||
SigningKey: "",
|
SigningKey: "",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
ManagedConfigurations: []string{},
|
ManagedConfigurations: []string{},
|
||||||
|
ExternalConfigurations: []ExternalConfig{},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,81 +0,0 @@
|
||||||
//go:build mage
|
|
||||||
|
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"os"
|
|
||||||
"slices"
|
|
||||||
|
|
||||||
"github.com/magefile/mage/sh"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Neovim downloads and manages neovim configuration from a remote git repository.
|
|
||||||
func Neovim() error {
|
|
||||||
config, err := newConfig()
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf(
|
|
||||||
"unable to load the configuration: %w",
|
|
||||||
err,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
if !config.Neovim.Manage {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
//homeConfigDirectory, err := os.UserConfigDir()
|
|
||||||
//if err != nil {
|
|
||||||
// return fmt.Errorf(
|
|
||||||
// "unable to get the user's home configuration directory: %w",
|
|
||||||
// err,
|
|
||||||
// )
|
|
||||||
//}
|
|
||||||
|
|
||||||
var (
|
|
||||||
// neovimManagedDir = filepath.Join(rootManagedDir, "nvim")
|
|
||||||
// versionLabelFile = filepath.Join(neovimManagedDir, ".managed.version")
|
|
||||||
// neovimConfigDir = filepath.Join(homeConfigDirectory, "nvim")
|
|
||||||
)
|
|
||||||
|
|
||||||
tempLocalRepo, err := cloneNvimConfigRepo(config.Neovim.GitRepoURL, config.Neovim.GitRef)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("unable to clone the git repository: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
fmt.Println("Git repository cloned to:", tempLocalRepo)
|
|
||||||
|
|
||||||
// defer os.Remove(tempLocalRepo)
|
|
||||||
|
|
||||||
// TODO: copy the files from temp folder to managed folder
|
|
||||||
|
|
||||||
// TODO: add commit/tag ref to .managed.version
|
|
||||||
|
|
||||||
// TODO: symlink all inside managed neovim folder
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func cloneNvimConfigRepo(repoURL, repoRef string) (string, error) {
|
|
||||||
cloneDir, err := os.MkdirTemp("/tmp", "neovim-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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return cloneDir, nil
|
|
||||||
}
|
|
Loading…
Reference in a new issue