Skip to content

Commit

Permalink
feat: magefiles (+adds to trunk.yaml)
Browse files Browse the repository at this point in the history
  • Loading branch information
scottames committed Apr 14, 2023
1 parent 6d97c11 commit 53bc6f4
Show file tree
Hide file tree
Showing 10 changed files with 577 additions and 0 deletions.
10 changes: 10 additions & 0 deletions .trunk/trunk.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,20 @@ plugins:
uri: https://github.com/trunk-io/plugins
actions:
enabled:
- go-mod-tidy
- trunk-announce
- trunk-check-pre-push
- trunk-fmt-pre-commit
- trunk-upgrade-available
- go-test
definitions:
- id: go-test
display_name: Go Test
description: Runs go tests
run: go test ./...
triggers:
- git_hooks: [pre-push, pre-commit]
- files: ["*.go"]
lint:
enabled:
- actionlint@1.6.24
Expand Down
8 changes: 8 additions & 0 deletions go.mod
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
)
8 changes: 8 additions & 0 deletions go.sum
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=
127 changes: 127 additions & 0 deletions magefiles/dconf.go
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),
"/", "-"),
"-"),
)
}
27 changes: 27 additions & 0 deletions magefiles/mage.go
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,
)
}
99 changes: 99 additions & 0 deletions pkg/helpers/file.go
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
}
Loading

0 comments on commit 53bc6f4

Please sign in to comment.