From 4fa12066d02ab7b124796bd14fb05da8c23e942b Mon Sep 17 00:00:00 2001 From: Nguyen Tran Hau Date: Thu, 22 Apr 2021 16:36:11 +0700 Subject: [PATCH] feat: add --dry-run flag (#6) * feat: add --dry-run flag to all commands * feat: update copy-go with single copy.Replace * refactor: make Config interface * chore(config): cleanup unused * feat: add config demo (1/?) * chore: better naming for cfg * refactor: move to pkg config * refactor: use data for store configs * refactor: split real and demo config * feat: make use of dry run flag Co-authored-by: Tran Hau --- config/alacritty/alacritty.yml | 13 --- config/alacritty/one-dark.yml | 21 ---- config/bat/config | 3 - config/config.json | 88 ---------------- config/i3/config | 139 ------------------------- config/i3status/config | 39 ------- config/redshift/redshift.conf | 7 -- config/rofi/config.rasi | 4 - config/tmux/tmux.conf | 19 ---- config/vim/vimrc | 52 --------- config/xinit/xinitrc | 7 -- data/data.json | 12 +++ {config => data}/nvim/init.vim | 0 file.go | 62 ----------- go.mod | 2 +- go.sum | 4 +- main.go | 61 +++++++++-- pkg/config/config.go | 7 ++ pkg/config/config_demo.go | 19 ++++ config.go => pkg/config/config_real.go | 58 +++++++---- 20 files changed, 127 insertions(+), 490 deletions(-) delete mode 100644 config/alacritty/alacritty.yml delete mode 100644 config/alacritty/one-dark.yml delete mode 100644 config/bat/config delete mode 100644 config/config.json delete mode 100644 config/i3/config delete mode 100644 config/i3status/config delete mode 100644 config/redshift/redshift.conf delete mode 100644 config/rofi/config.rasi delete mode 100644 config/tmux/tmux.conf delete mode 100644 config/vim/vimrc delete mode 100644 config/xinit/xinitrc create mode 100644 data/data.json rename {config => data}/nvim/init.vim (100%) delete mode 100644 file.go create mode 100644 pkg/config/config.go create mode 100644 pkg/config/config_demo.go rename config.go => pkg/config/config_real.go (63%) diff --git a/config/alacritty/alacritty.yml b/config/alacritty/alacritty.yml deleted file mode 100644 index 70f7fe0..0000000 --- a/config/alacritty/alacritty.yml +++ /dev/null @@ -1,13 +0,0 @@ -import: - - ~/.config/alacritty/one-dark.yml - -font: - normal: - family: Cascadia Code - style: Regular - - bold: - family: Cascadia Code - style: Bold - - size: 12 diff --git a/config/alacritty/one-dark.yml b/config/alacritty/one-dark.yml deleted file mode 100644 index eea7f1f..0000000 --- a/config/alacritty/one-dark.yml +++ /dev/null @@ -1,21 +0,0 @@ -# https://github.com/alacritty/alacritty/wiki/Color-schemes -# Colors (One Dark) -colors: - primary: - background: "#282c34" - foreground: "#abb2bf" - cursor: - text: CellBackground - cursor: "#528bff" - selection: - text: CellForeground - background: "#3e4451" - normal: - black: "#5c6370" - red: "#e06c75" - green: "#98c379" - yellow: "#e5c07b" - blue: "#61afef" - magenta: "#c678dd" - cyan: "#56b6c2" - white: "#828997" diff --git a/config/bat/config b/config/bat/config deleted file mode 100644 index e143a2e..0000000 --- a/config/bat/config +++ /dev/null @@ -1,3 +0,0 @@ ---theme="TwoDark" - ---style="plain" diff --git a/config/config.json b/config/config.json deleted file mode 100644 index 0759952..0000000 --- a/config/config.json +++ /dev/null @@ -1,88 +0,0 @@ -{ - "apps": { - "nvim": { - "files": [ - { - "internal": "config/nvim/init.vim", - "external": "~/.config/nvim/init.vim" - } - ] - }, - "vim": { - "files": [ - { - "internal": "config/vim/vimrc", - "external": "~/.vimrc" - } - ] - }, - "bat": { - "dirs": [ - { - "internal": "config/bat", - "external": "~/.config/bat" - } - ] - }, - "tmux": { - "files": [ - { - "internal": "config/tmux/tmux.conf", - "external": "~/.tmux.conf" - } - ] - }, - "alacritty": { - "files": [ - { - "internal": "config/alacritty/alacritty.yml", - "external": "~/.config/alacritty/alacritty.yml" - }, - { - "internal": "config/alacritty/one-dark.yml", - "external": "~/.config/alacritty/one-dark.yml" - } - ] - }, - "i3": { - "files": [ - { - "internal": "config/i3/config", - "external": "~/.config/i3/config" - } - ] - }, - "i3status": { - "files": [ - { - "internal": "config/i3status/config", - "external": "~/.config/i3status/config" - } - ] - }, - "rofi": { - "files": [ - { - "internal": "config/rofi/config.rasi", - "external": "~/.config/rofi/config.rasi" - } - ] - }, - "xinit": { - "files": [ - { - "internal": "config/xinit/xinitrc", - "external": "~/.xinitrc" - } - ] - }, - "redshift": { - "files": [ - { - "internal": "config/redshift/redshift.conf", - "external": "~/.config/redshift/redshift.conf" - } - ] - } - } -} diff --git a/config/i3/config b/config/i3/config deleted file mode 100644 index 094239a..0000000 --- a/config/i3/config +++ /dev/null @@ -1,139 +0,0 @@ -# https://i3wm.org/docs/userguide.html - -set $mod Mod4 - -font pango:Cascadia Code 12 - -# feh -# https://wiki.archlinux.org/index.php/Feh -exec --no-startup-id feh --no-fehbg --bg-fill --randomize /usr/share/backgrounds/archlinux/* - -# redshift -# https://wiki.archlinux.org/index.php/Redshift -exec --no-startup-id redshift-gtk - -# fcitx -# https://wiki.archlinux.org/index.php/fcitx -exec --no-startup-id fcitx - -# i3lock -bindsym $mod+l exec --no-startup-id i3lock -e -c 000000 - -# adjust volume -set $refresh_i3status killall -SIGUSR1 i3status -bindsym XF86AudioRaiseVolume exec --no-startup-id pactl set-sink-volume @DEFAULT_SINK@ +5% && $refresh_i3status -bindsym XF86AudioLowerVolume exec --no-startup-id pactl set-sink-volume @DEFAULT_SINK@ -5% && $refresh_i3status -bindsym XF86AudioMute exec --no-startup-id pactl set-sink-mute @DEFAULT_SINK@ toggle && $refresh_i3status -bindsym XF86AudioMicMute exec --no-startup-id pactl set-source-mute @DEFAULT_SOURCE@ toggle && $refresh_i3status - -# adjust brightness -bindsym XF86MonBrightnessUp exec --no-startup-id xbacklight -inc 10 -bindsym XF86MonBrightnessDown exec --no-startup-id xbacklight -dec 10 - -# use Mouse+$mod to move floating windows -floating_modifier $mod - -# start a terminal -bindsym $mod+Return exec i3-sensible-terminal - -# kill focused window -bindsym $mod+Shift+q kill - -# rofi (a program launcher) -# https://wiki.archlinux.org/index.php/Rofi -bindsym $mod+d exec "rofi -combi-modi window,drun -show combi" - -# change focus -bindsym $mod+Left focus left -bindsym $mod+Down focus down -bindsym $mod+Up focus up -bindsym $mod+Right focus right - -# move focused window -bindsym $mod+Shift+Left move left -bindsym $mod+Shift+Down move down -bindsym $mod+Shift+Up move up -bindsym $mod+Shift+Right move right - -# split in horizontal orientation -bindsym $mod+h split h - -# split in vertical orientation -bindsym $mod+v split v - -# enter fullscreen mode -bindsym $mod+f fullscreen toggle - -# change container layout (stacked, tabbed, toggle split) -bindsym $mod+s layout stacking -bindsym $mod+w layout tabbed -bindsym $mod+e layout toggle split - -# toggle tiling / floating -bindsym $mod+Shift+space floating toggle - -# change focus between tiling / floating windows -bindsym $mod+space focus mode_toggle - -# focus the parent container -bindsym $mod+a focus parent - -# workspace -set $ws1 "1" -set $ws2 "2" -set $ws3 "3" -set $ws4 "4" -set $ws5 "5" -set $ws6 "6" -set $ws7 "7" -set $ws8 "8" -set $ws9 "9" -set $ws10 "10" - -# switch to workspace -bindsym $mod+1 workspace number $ws1 -bindsym $mod+2 workspace number $ws2 -bindsym $mod+3 workspace number $ws3 -bindsym $mod+4 workspace number $ws4 -bindsym $mod+5 workspace number $ws5 -bindsym $mod+6 workspace number $ws6 -bindsym $mod+7 workspace number $ws7 -bindsym $mod+8 workspace number $ws8 -bindsym $mod+9 workspace number $ws9 -bindsym $mod+0 workspace number $ws10 - -# move focused container to workspace -bindsym $mod+Shift+1 move container to workspace number $ws1 -bindsym $mod+Shift+2 move container to workspace number $ws2 -bindsym $mod+Shift+3 move container to workspace number $ws3 -bindsym $mod+Shift+4 move container to workspace number $ws4 -bindsym $mod+Shift+5 move container to workspace number $ws5 -bindsym $mod+Shift+6 move container to workspace number $ws6 -bindsym $mod+Shift+7 move container to workspace number $ws7 -bindsym $mod+Shift+8 move container to workspace number $ws8 -bindsym $mod+Shift+9 move container to workspace number $ws9 -bindsym $mod+Shift+0 move container to workspace number $ws10 - -bindsym $mod+Shift+c reload -bindsym $mod+Shift+r restart -bindsym $mod+Shift+e exec "i3-nagbar -t warning -f 'pango:Cascadia Code 12' -m 'Do you want to exit i3?' -B 'Yes, exit i3' 'i3-msg exit'" - -# resize window -mode "resize" { - bindsym Left resize shrink width 10 px or 10 ppt - bindsym Down resize grow height 10 px or 10 ppt - bindsym Up resize shrink height 10 px or 10 ppt - bindsym Right resize grow width 10 px or 10 ppt - - bindsym Return mode "default" - bindsym Escape mode "default" - bindsym $mod+r mode "default" -} - -bindsym $mod+r mode "resize" - -# use i3status -bar { - position top - status_command i3status -} diff --git a/config/i3status/config b/config/i3status/config deleted file mode 100644 index d528fce..0000000 --- a/config/i3status/config +++ /dev/null @@ -1,39 +0,0 @@ -general { - interval = 5 - - # https://github.com/joshdick/onedark.vim - colors = true - color_good = "#98C379" - color_degraded = "#E5C07B" - color_bad = "#E06C75" -} - -order += "wireless _first_" -order += "ethernet _first_" -order += "battery all" -order += "volume master" -order += "tztime local" - -wireless _first_ { - format_up = "Wifi: %essid" - format_down = "Wifi: down" -} - -ethernet _first_ { - format_up = "Ethernet: %ip (%speed)" - format_down = "Ethernet: down" -} - -battery all { - format = "%status %percentage %remaining" -} - -volume master { - format = "Sound: %volume" - format_muted = "Sound: muted (%volume)" - device = "pulse" -} - -tztime local { - format = "%Y-%m-%d %H:%M:%S" -} diff --git a/config/redshift/redshift.conf b/config/redshift/redshift.conf deleted file mode 100644 index 4cdf6ec..0000000 --- a/config/redshift/redshift.conf +++ /dev/null @@ -1,7 +0,0 @@ -[redshift] -location-provider=manual - -[manual] -; Ho Chi Minh, Vietnam -lat=10.8188 -lon=106.65186 diff --git a/config/rofi/config.rasi b/config/rofi/config.rasi deleted file mode 100644 index 78c773e..0000000 --- a/config/rofi/config.rasi +++ /dev/null @@ -1,4 +0,0 @@ -configuration { - modi: "window,drun,combi"; - font: "Cascadia Code 12"; -} diff --git a/config/tmux/tmux.conf b/config/tmux/tmux.conf deleted file mode 100644 index e6d252d..0000000 --- a/config/tmux/tmux.conf +++ /dev/null @@ -1,19 +0,0 @@ -# https://github.com/tmux/tmux/wiki/FAQ - -# Switch panes using Alt without prefix -bind -n M-Left select-pane -L -bind -n M-Right select-pane -R -bind -n M-Up select-pane -U -bind -n M-Down select-pane -D - -# Color -set -g default-terminal "tmux-256color" - -# https://github.com/tmux-plugins/tpm -# List of plugins -set -g @plugin 'tmux-plugins/tpm' -set -g @plugin 'tmux-plugins/tmux-sensible' -set -g @plugin 'tmux-plugins/tmux-pain-control' - -# Initialize TMUX plugin manager -run '~/.tmux/plugins/tpm/tpm' diff --git a/config/vim/vimrc b/config/vim/vimrc deleted file mode 100644 index 6379941..0000000 --- a/config/vim/vimrc +++ /dev/null @@ -1,52 +0,0 @@ -set breakindent -set completeopt=menuone,noinsert,noselect -set noswapfile -set number -set relativenumber -set scrolloff=4 -set virtualedit=block -set whichwrap=<,>,[,] - -" True color -" https://gist.github.com/XVilka/8346728 -if (empty($TMUX)) - if (has('termguicolors')) - set termguicolors - endif -endif - -" Disable cursor styling -set guicursor= - -" Install xclip or xsel -set clipboard+=unnamedplus - -" FZF -set rtp+=~/.fzf - -" Plugins config -let g:go_fmt_command='gopls' -let g:go_gopls_gofumpt=1 -let g:go_version_warning=0 -let g:lightline={'colorscheme':'onedark'} - -" vim-plug -" https://github.com/junegunn/vim-plug -call plug#begin() - -" Should use -Plug 'sheerun/vim-polyglot' -Plug 'preservim/nerdtree' -Plug 'machakann/vim-sandwich' -Plug 'itchyny/lightline.vim' - -" Colorschemes -Plug 'joshdick/onedark.vim' - -" Languages -Plug 'fatih/vim-go', {'tag': '*'} - -call plug#end() - -set background=dark -colorscheme onedark diff --git a/config/xinit/xinitrc b/config/xinit/xinitrc deleted file mode 100644 index 67d09bd..0000000 --- a/config/xinit/xinitrc +++ /dev/null @@ -1,7 +0,0 @@ -# https://wiki.archlinux.org/index.php/fcitx -export GTK_IM_MODULE=fcitx -export QT_IM_MODULE=fcitx -export XMODIFIERS=@im=fcitx - -# https://wiki.archlinux.org/index.php/i3 -exec i3 diff --git a/data/data.json b/data/data.json new file mode 100644 index 0000000..0702d58 --- /dev/null +++ b/data/data.json @@ -0,0 +1,12 @@ +{ + "apps": { + "nvim": { + "files": [ + { + "internal": "config/nvim/init.vim", + "external": "~/.config/nvim/init.vim" + } + ] + } + } +} diff --git a/config/nvim/init.vim b/data/nvim/init.vim similarity index 100% rename from config/nvim/init.vim rename to data/nvim/init.vim diff --git a/file.go b/file.go deleted file mode 100644 index 7ed0d59..0000000 --- a/file.go +++ /dev/null @@ -1,62 +0,0 @@ -package main - -import ( - "fmt" - "os" - "os/user" - "path/filepath" - - copier "github.com/haunt98/copy-go" -) - -const ( - homeSymbol = '~' -) - -type copyFn func(from, to string) error - -func replaceFile(from, to string) error { - return replace(from, to, copier.CopyFile) -} - -func replaceDir(from, to string) error { - return replace(from, to, copier.CopyDir) -} - -func replace(from, to string, fn copyFn) error { - newFrom, err := replaceHomeSymbol(from) - if err != nil { - return fmt.Errorf("failed to replace home symbol %s: %w", from, err) - } - - newTo, err := replaceHomeSymbol(to) - if err != nil { - return fmt.Errorf("failed to replace home symbol %s: %w", to, err) - } - - if err := os.RemoveAll(newTo); err != nil { - return fmt.Errorf("failed to remove %s: %w", newTo, err) - } - - if err := fn(newFrom, newTo); err != nil { - return fmt.Errorf("failed to copy from %s to %s: %w", newFrom, newTo, err) - } - - return nil -} - -// replace ~ -// https://stackoverflow.com/a/17609894 -func replaceHomeSymbol(path string) (string, error) { - if path == "" || path[0] != homeSymbol { - return path, nil - } - - currentUser, err := user.Current() - if err != nil { - return "", err - } - - newPath := filepath.Join(currentUser.HomeDir, path[1:]) - return newPath, nil -} diff --git a/go.mod b/go.mod index 8128926..70be108 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,7 @@ go 1.16 require ( github.com/cpuguy83/go-md2man/v2 v2.0.0 // indirect github.com/haunt98/color v0.1.0 - github.com/haunt98/copy-go v0.4.0 + github.com/haunt98/copy-go v0.5.0 github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/urfave/cli/v2 v2.3.0 golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57 // indirect diff --git a/go.sum b/go.sum index 26bb898..2795f68 100644 --- a/go.sum +++ b/go.sum @@ -6,8 +6,8 @@ github.com/fatih/color v1.10.0 h1:s36xzo75JdqLaaWoiEHk767eHiwo0598uUxyfiPkDsg= github.com/fatih/color v1.10.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM= github.com/haunt98/color v0.1.0 h1:qfP5oNI3aoUC8T+bH/JNVAg79ljyhTGpgfqSKWhkiQQ= github.com/haunt98/color v0.1.0/go.mod h1:V4BPVUSuiOItuVZHRHUTkpxO7OYQiP0DSgIWMpC/2qs= -github.com/haunt98/copy-go v0.4.0 h1:ts47dExLyIWWrnLQmVc475Af3/LO111zeB58waSe02A= -github.com/haunt98/copy-go v0.4.0/go.mod h1:cK1mRlW7QXPHhe5YI1VtL/U4OjUbRLAtZnO/oucrwRI= +github.com/haunt98/copy-go v0.5.0 h1:8yy7Dx47BBtlHIFIXxcCIECZRoQB/JSgLN9yunqtLAQ= +github.com/haunt98/copy-go v0.5.0/go.mod h1:cK1mRlW7QXPHhe5YI1VtL/U4OjUbRLAtZnO/oucrwRI= github.com/mattn/go-colorable v0.1.8 h1:c1ghPdyEDarC70ftn0y+A/Ee++9zz8ljHG1b13eJ0s8= github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY= diff --git a/main.go b/main.go index 0e2cbda..0139d5c 100644 --- a/main.go +++ b/main.go @@ -7,6 +7,7 @@ import ( "runtime" "github.com/haunt98/color" + "github.com/haunt98/dotfiles/pkg/config" "github.com/urfave/cli/v2" ) @@ -16,6 +17,7 @@ const ( // flags verboseFlag = "verbose" + dryRunFlag = "dry-run" // commands installCommand = "install" @@ -24,6 +26,7 @@ const ( // usages verboseUsage = "show what is going on" + dryRunUsage = "demo mode without actually changing anything" installUsage = "install user configs from dotfiles" updateUsage = "update dotfiles from user configs" cleanUsage = "clean unused dotfiles" @@ -66,6 +69,10 @@ func main() { Name: verboseFlag, Usage: verboseUsage, }, + &cli.BoolFlag{ + Name: dryRunFlag, + Usage: dryRunUsage, + }, }, Action: a.RunInstall, }, @@ -73,13 +80,33 @@ func main() { Name: updateCommand, Aliases: updateAliases, Usage: updateUsage, - Action: a.RunUpdate, + Flags: []cli.Flag{ + &cli.BoolFlag{ + Name: verboseFlag, + Usage: verboseUsage, + }, + &cli.BoolFlag{ + Name: dryRunFlag, + Usage: dryRunUsage, + }, + }, + Action: a.RunUpdate, }, { Name: cleanCommand, Aliases: cleanAliases, Usage: cleanUsage, - Action: a.RunClean, + Flags: []cli.Flag{ + &cli.BoolFlag{ + Name: verboseFlag, + Usage: verboseUsage, + }, + &cli.BoolFlag{ + Name: dryRunFlag, + Usage: dryRunUsage, + }, + }, + Action: a.RunClean, }, }, Action: a.RunHelp, @@ -93,6 +120,7 @@ func main() { type action struct { flags struct { verbose bool + dryRun bool } } @@ -105,11 +133,10 @@ func (a *action) RunInstall(c *cli.Context) error { a.getFlags(c) a.log("start %s\n", installCommand) - cfg, err := LoadConfig(currentDir) + cfg, err := a.loadConfig() if err != nil { - return fmt.Errorf("failed to load config: %w", err) + return err } - a.log("config %+v\n", cfg) if err := cfg.Install(); err != nil { return fmt.Errorf("failed to install config: %w", err) @@ -122,11 +149,10 @@ func (a *action) RunUpdate(c *cli.Context) error { a.getFlags(c) a.log("start %s\n", updateCommand) - cfg, err := LoadConfig(currentDir) + cfg, err := a.loadConfig() if err != nil { - return fmt.Errorf("failed to load config: %w", err) + return err } - a.log("config %+v\n", cfg) if err := cfg.Update(); err != nil { return fmt.Errorf("failed to update config: %w", err) @@ -139,11 +165,10 @@ func (a *action) RunClean(c *cli.Context) error { a.getFlags(c) a.log("start %s\n", cleanCommand) - cfg, err := LoadConfig(currentDir) + cfg, err := a.loadConfig() if err != nil { - return fmt.Errorf("failed to load config: %w", err) + return err } - a.log("config %+v\n", cfg) if err := cfg.Clean(); err != nil { return fmt.Errorf("failed to clean config: %w", err) @@ -152,8 +177,22 @@ func (a *action) RunClean(c *cli.Context) error { return nil } +func (a *action) loadConfig() (config.Config, error) { + cfgReal, cfgDemo, err := config.LoadConfig(currentDir) + if err != nil { + return nil, fmt.Errorf("failed to load config: %w", err) + } + + if a.flags.dryRun { + return cfgDemo, nil + } + + return cfgReal, nil +} + func (a *action) getFlags(c *cli.Context) { a.flags.verbose = c.Bool(verboseFlag) + a.flags.dryRun = c.Bool(dryRunFlag) } func (a *action) log(format string, v ...interface{}) { diff --git a/pkg/config/config.go b/pkg/config/config.go new file mode 100644 index 0000000..4412123 --- /dev/null +++ b/pkg/config/config.go @@ -0,0 +1,7 @@ +package config + +type Config interface { + Install() error + Update() error + Clean() error +} diff --git a/pkg/config/config_demo.go b/pkg/config/config_demo.go new file mode 100644 index 0000000..b288aa8 --- /dev/null +++ b/pkg/config/config_demo.go @@ -0,0 +1,19 @@ +package config + +type configDemo struct { + configApps +} + +var _ Config = (*configDemo)(nil) + +func (cd *configDemo) Install() error { + return nil +} + +func (cd *configDemo) Update() error { + return nil +} + +func (cd *configDemo) Clean() error { + return nil +} diff --git a/config.go b/pkg/config/config_real.go similarity index 63% rename from config.go rename to pkg/config/config_real.go index 26bc2f8..16a6793 100644 --- a/config.go +++ b/pkg/config/config_real.go @@ -1,4 +1,4 @@ -package main +package config import ( "encoding/json" @@ -6,18 +6,26 @@ import ( "fmt" "os" "path/filepath" + + "github.com/haunt98/copy-go" ) const ( - configDirPath = "config" - configFile = "config.json" + configDirPath = "data" + configFile = "data.json" ) -type Config struct { - // Read from file +type config struct { + configApps +} + +var _ Config = (*config)(nil) + +type configApps struct { Apps map[string]App `json:"apps"` } +// Read from file type App struct { Files []Path `json:"files"` Dirs []Path `json:"dirs"` @@ -28,39 +36,45 @@ type Path struct { External string `json:"external"` } -// Load config from file -func LoadConfig(path string) (result Config, err error) { +// LoadConfig return config, configDemo +func LoadConfig(path string) (*config, *configDemo, error) { configPath := getConfigPath(path) bytes, err := os.ReadFile(configPath) if err != nil { if errors.Is(err, os.ErrNotExist) { - err = fmt.Errorf("file not exist %s: %w", configPath, err) - return + return nil, nil, fmt.Errorf("file not exist %s: %w", configPath, err) } - err = fmt.Errorf("failed to read file%s: %w", configPath, err) - return + return nil, nil, fmt.Errorf("failed to read file%s: %w", configPath, err) } - if err = json.Unmarshal(bytes, &result); err != nil { - err = fmt.Errorf("failed to unmarshal: %w", err) - return + var cfgApps configApps + if err = json.Unmarshal(bytes, &cfgApps); err != nil { + return nil, nil, fmt.Errorf("failed to unmarshal: %w", err) } - return + cfg := config{ + configApps: cfgApps, + } + + cfgDemo := configDemo{ + configApps: cfgApps, + } + + return &cfg, &cfgDemo, nil } // internal -> external -func (c *Config) Install() error { +func (c *config) Install() error { for _, app := range c.Apps { for _, file := range app.Files { - if err := replaceFile(file.Internal, file.External); err != nil { + if err := copy.Replace(file.Internal, file.External); err != nil { return fmt.Errorf("failed to remove and copy from %s to %s: %w", file.Internal, file.External, err) } } for _, dir := range app.Dirs { - if err := replaceDir(dir.Internal, dir.External); err != nil { + if err := copy.Replace(dir.Internal, dir.External); err != nil { return fmt.Errorf("failed to remove and copy from %s to %s: %w", dir.Internal, dir.External, err) } } @@ -70,16 +84,16 @@ func (c *Config) Install() error { } // external -> internal -func (c *Config) Update() error { +func (c *config) Update() error { for _, app := range c.Apps { for _, file := range app.Files { - if err := replaceFile(file.External, file.Internal); err != nil { + if err := copy.Replace(file.External, file.Internal); err != nil { return fmt.Errorf("failed to remove and copy from %s to %s: %w", file.External, file.Internal, err) } } for _, dir := range app.Dirs { - if err := replaceDir(dir.External, dir.Internal); err != nil { + if err := copy.Replace(dir.External, dir.Internal); err != nil { return fmt.Errorf("failed to remove and copy from %s to %s: %w", dir.External, dir.Internal, err) } } @@ -88,7 +102,7 @@ func (c *Config) Update() error { return nil } -func (c *Config) Clean() error { +func (c *config) Clean() error { files, err := os.ReadDir(configDirPath) if err != nil { return fmt.Errorf("failed to read dir %s: %w", configDirPath, err)