-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: magefiles (+adds to trunk.yaml)
- Loading branch information
Showing
10 changed files
with
577 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
module github.com/scottames/dots | ||
|
||
go 1.20 | ||
|
||
require ( | ||
github.com/magefile/mage v1.14.0 | ||
github.com/scottames/cmder v0.1.1 | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= | ||
github.com/magefile/mage v1.14.0 h1:6QDX3g6z1YvJ4olPhT1wksUcSa/V0a1B+pJb73fBjyo= | ||
github.com/magefile/mage v1.14.0/go.mod h1:z5UZb/iS3GoOSn0JgWuiw7dxlurVYTu+/jHXqQg881A= | ||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= | ||
github.com/scottames/cmder v0.1.1 h1:TAAekeeWw+uM1ZFQi+TmtqAPQxR/hvQAw3+iOutnYZ8= | ||
github.com/scottames/cmder v0.1.1/go.mod h1:mBPkznUdjre9Gf36KYauSbJw8p8Ocz2+xGZ7afg1cKw= | ||
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= | ||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,127 @@ | ||
package main | ||
|
||
import ( | ||
"fmt" | ||
"os" | ||
"path/filepath" | ||
"strings" | ||
|
||
"github.com/magefile/mage/mg" | ||
"github.com/scottames/cmder" | ||
|
||
"github.com/scottames/dots/pkg/helpers" | ||
) | ||
|
||
const ( | ||
dconf string = "dconf" | ||
backupDir string = "./dconf" | ||
root = "/" | ||
) | ||
|
||
var dirs = []string{ | ||
"/com/gexperts/Tilix/", // https://github.com/gnunn1/tilix/ | ||
"/org/gnome/shell/extensions/paperwm/", // https://github.com/paperwm/PaperWM | ||
"/org/gnome/settings-daemon/plugins/media-keys/", // custom key bindings + media keys | ||
"/org/gnome/desktop/wm/keybindings/", // keybindings | ||
} | ||
|
||
// Dconf - Gnome Dconf settings. | ||
type Dconf mg.Namespace | ||
|
||
// Backup - backup named dconf setting. | ||
func (Dconf) Backup(key string) error { | ||
mg.Deps(Dconf.installed) | ||
|
||
dump, err := cmder.New(dconf, "dump", key).Output() | ||
if err != nil { | ||
return err | ||
} | ||
|
||
var file string | ||
if key == root { | ||
file = "all.conf" | ||
} else { | ||
file = fileNameFromKey(key) | ||
} | ||
|
||
if _, statErr := os.Stat(backupDir); os.IsNotExist(statErr) { | ||
mkDirErr := os.MkdirAll(backupDir, 0700) | ||
if mkDirErr != nil { | ||
return fmt.Errorf("error creating backup dir (%s): %w", backupDir, err) | ||
} | ||
} | ||
|
||
backupPath := filepath.Join(backupDir, file) | ||
err = os.WriteFile(backupPath, dump, 0600) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
return nil | ||
} | ||
|
||
// Backupall - backup all tracked dconf settings. | ||
func (d Dconf) Backupall() error { | ||
for _, key := range dirs { | ||
err := d.Backup(key) | ||
if err != nil { | ||
return err | ||
} | ||
fmt.Println(key) | ||
} | ||
return nil | ||
} | ||
|
||
// Dump - dump named (or all, default) dconf setting(s). | ||
func (d Dconf) Dump(s string) error { | ||
if s == "" || s == "all" { | ||
s = root | ||
} | ||
return d.Backup(s) | ||
} | ||
|
||
// Load - load named dconf setting. | ||
func (Dconf) Load(key string) error { | ||
mg.Deps(Dconf.installed) | ||
|
||
_, err := os.ReadDir(backupDir) | ||
if err != nil { | ||
return fmt.Errorf("dconf backup dir '%s' not found", backupDir) | ||
} | ||
|
||
file := fileNameFromKey(key) | ||
backup := filepath.Join(backupDir, file) | ||
data, err := os.ReadFile(backup) | ||
if err != nil { | ||
return fmt.Errorf("unable to load '%s' from '%s': %w", key, backup, err) | ||
} | ||
|
||
return cmder.New(dconf, "load", key).In(data...).Run() | ||
} | ||
|
||
// Loadall - load all tracked dconf settings. | ||
func (d Dconf) Loadall() error { | ||
for _, key := range dirs { | ||
err := d.Load(key) | ||
if err != nil { | ||
return err | ||
} | ||
fmt.Println(key) | ||
} | ||
return nil | ||
} | ||
|
||
func (Dconf) installed() error { | ||
_, err := helpers.Which(dconf) | ||
return err | ||
} | ||
|
||
func fileNameFromKey(key string) string { | ||
return fmt.Sprintf("%s.conf", | ||
strings.Trim( | ||
strings.ReplaceAll( | ||
strings.Replace(key, "/", "", 1), | ||
"/", "-"), | ||
"-"), | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
package main | ||
|
||
import ( | ||
"github.com/magefile/mage/mg" | ||
) | ||
|
||
// Aliases - target aliases. | ||
var Aliases = map[string]interface{}{ | ||
"dconf:restore": Dconf.Loadall, | ||
} | ||
|
||
// All - wraps all commands into one. | ||
type All mg.Namespace | ||
|
||
// Backup - backup all. | ||
func (All) Backup() { | ||
mg.Deps( | ||
Dconf.Backupall, | ||
) | ||
} | ||
|
||
// Restore - restore all. | ||
func (All) Restore() { | ||
mg.Deps( | ||
Dconf.Loadall, | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
package helpers | ||
|
||
import ( | ||
"fmt" | ||
"os" | ||
"path" | ||
|
||
"github.com/scottames/cmder" | ||
) | ||
|
||
// IsDir - returns true if given directory exists or an error. | ||
func IsDir(path string) (bool, error) { | ||
fileInfo, err := os.Stat(path) | ||
if err != nil { | ||
return false, err | ||
} | ||
|
||
return fileInfo.IsDir(), err | ||
} | ||
|
||
// Exists - returns true if file or dir exists | ||
// - see SymlinkExists for symlinks | ||
func Exists(path string) bool { | ||
_, err := os.Stat(path) | ||
if err != nil { | ||
return os.IsExist(err) | ||
} | ||
return true | ||
} | ||
|
||
// SymlinkExists - returns true if symlink exists | ||
// - see Exists for files & dirs | ||
func SymlinkExists(symlink string) bool { | ||
target, err := os.Lstat(symlink) | ||
if err != nil { | ||
return false | ||
} | ||
/* | ||
target.Mode() returns a bitmask representing the file mode and permission bits for the file | ||
if the os.ModeSymlink bit is set in this bitmask, that indicates that the file is a symbolic link | ||
this checks if the os.ModeSymlink bit is set in the mode bits of the file at symlink | ||
indicating that it is a symbolic link | ||
*/ | ||
if target.Mode()&os.ModeSymlink != os.ModeSymlink { | ||
return false | ||
} | ||
|
||
return true | ||
} | ||
|
||
// CreateSymlinks creates a set of symlinks and returns an error if any issues are encountered | ||
// - forces replacement of existing links. | ||
func CreateSymlinks(sls map[string]string, ignoreErr bool) error { | ||
for file, symlink := range sls { | ||
// Check if symlink already exists | ||
if SymlinkExists(symlink) { | ||
fmt.Printf("Removing existing link: %s\n", symlink) | ||
if err := os.Remove(symlink); err != nil { | ||
return fmt.Errorf("unable to remove existing link %s: %w", symlink, err) | ||
} | ||
if SymlinkExists(symlink) { | ||
return fmt.Errorf("unable to remove existing link %s", symlink) | ||
} | ||
} | ||
|
||
// Create new symlink | ||
fmt.Printf("Linking: %s -> %s\n", symlink, file) | ||
err := os.Symlink(file, symlink) | ||
if err != nil { | ||
if ignoreErr { | ||
fmt.Printf("Ignoring error: %s\n", err.Error()) | ||
} else { | ||
return fmt.Errorf("unable to create symlink %s -> %s: %w", symlink, file, err) | ||
} | ||
} | ||
} | ||
|
||
return nil | ||
} | ||
|
||
// SetupEnvRCs - symlink & `direnv allow` .envrc files. | ||
func SetupEnvRCs(sls map[string]string, ignoreErr bool) error { | ||
const direnv = "direnv" | ||
if _, err := Which(direnv); err != nil { | ||
return fmt.Errorf("unable to find %s in path", direnv) | ||
} | ||
|
||
err := CreateSymlinks(sls, ignoreErr) | ||
if err != nil && !ignoreErr { | ||
return err | ||
} | ||
for _, v := range sls { | ||
err = cmder.New(direnv, "allow").Dir(path.Dir(v)).Run() | ||
if err != nil && !ignoreErr { | ||
return err | ||
} | ||
} | ||
return nil | ||
} |
Oops, something went wrong.