Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactoring #317

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ import (
"path/filepath"
"strings"

"github.com/cupcakearmy/autorestic/internal"
"github.com/cupcakearmy/autorestic/internal/colors"
"github.com/cupcakearmy/autorestic/internal/flags"
"github.com/cupcakearmy/autorestic/internal/lock"
"github.com/cupcakearmy/autorestic/internal/version"
"github.com/spf13/cobra"

homedir "github.com/mitchellh/go-homedir"
Expand All @@ -26,7 +26,7 @@ func CheckErr(err error) {
var cfgFile string

var rootCmd = &cobra.Command{
Version: internal.VERSION,
Version: version.VERSION,
Use: "autorestic",
Short: "CLI Wrapper for restic",
Long: "Documentation:\thttps://autorestic.vercel.app\nSupport:\thttps://discord.gg/wS7RpYTYd2",
Expand All @@ -41,7 +41,7 @@ func init() {
rootCmd.PersistentFlags().BoolVar(&flags.CI, "ci", false, "CI mode disabled interactive mode and colors and enables verbosity")
rootCmd.PersistentFlags().BoolVarP(&flags.VERBOSE, "verbose", "v", false, "verbose mode")
rootCmd.PersistentFlags().StringVar(&flags.RESTIC_BIN, "restic-bin", "restic", "specify custom restic binary")
rootCmd.PersistentFlags().StringVar(&flags.DOCKER_IMAGE, "docker-image", "cupcakearmy/autorestic:"+internal.VERSION, "specify a custom docker image")
rootCmd.PersistentFlags().StringVar(&flags.DOCKER_IMAGE, "docker-image", "cupcakearmy/autorestic:"+version.VERSION, "specify a custom docker image")
cobra.OnInitialize(initConfig)
}

Expand Down
27 changes: 18 additions & 9 deletions internal/backend.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import (

"github.com/cupcakearmy/autorestic/internal/colors"
"github.com/cupcakearmy/autorestic/internal/flags"
"github.com/cupcakearmy/autorestic/internal/options"
"github.com/cupcakearmy/autorestic/internal/utils"
)

type BackendRest struct {
Expand All @@ -24,7 +26,7 @@ type Backend struct {
Key string `mapstructure:"key,omitempty"`
Env map[string]string `mapstructure:"env,omitempty"`
Rest BackendRest `mapstructure:"rest,omitempty"`
Options Options `mapstructure:"options,omitempty"`
Options options.Options `mapstructure:"options,omitempty"`
}

func GetBackend(name string) (Backend, bool) {
Expand Down Expand Up @@ -120,19 +122,23 @@ func (b Backend) validate() error {
if err != nil {
return err
}
options := ExecuteOptions{Envs: env, Silent: true}
options := utils.ExecuteOptions{
Envs: env,
Silent: true,
Global: GetConfig().Global,
}
// Check if already initialized
cmd := []string{"check"}
cmd = append(cmd, combineBackendOptions("check", b)...)
_, _, err = ExecuteResticCommand(options, cmd...)
_, _, err = utils.ExecuteResticCommand(options, cmd...)
if err == nil {
return nil
} else {
// If not initialize
colors.Body.Printf("Initializing backend \"%s\"...\n", b.name)
cmd := []string{"init"}
cmd = append(cmd, combineBackendOptions("init", b)...)
_, _, err := ExecuteResticCommand(options, cmd...)
_, _, err := utils.ExecuteResticCommand(options, cmd...)
return err
}
}
Expand All @@ -142,8 +148,11 @@ func (b Backend) Exec(args []string) error {
if err != nil {
return err
}
options := ExecuteOptions{Envs: env}
_, out, err := ExecuteResticCommand(options, args...)
options := utils.ExecuteOptions{
Envs: env,
Global: GetConfig().Global,
}
_, out, err := utils.ExecuteResticCommand(options, args...)
if err != nil {
colors.Error.Println(out)
return err
Expand All @@ -157,7 +166,7 @@ func (b Backend) ExecDocker(l Location, args []string) (int, string, error) {
return -1, "", err
}
volume := l.From[0]
options := ExecuteOptions{
options := utils.ExecuteOptions{
Command: "docker",
Envs: env,
}
Expand Down Expand Up @@ -185,7 +194,7 @@ func (b Backend) ExecDocker(l Location, args []string) (int, string, error) {
// No additional setup needed
case "rclone":
// Read host rclone config and mount it into the container
code, configFile, err := ExecuteCommand(ExecuteOptions{Command: "rclone"}, "config", "file")
code, configFile, err := utils.ExecuteCommand(utils.ExecuteOptions{Command: "rclone"}, "config", "file")
if err != nil {
return code, "", err
}
Expand All @@ -200,5 +209,5 @@ func (b Backend) ExecDocker(l Location, args []string) (int, string, error) {
}

docker = append(docker, flags.DOCKER_IMAGE, "-c", strings.Join(args, " "))
return ExecuteCommand(options, docker...)
return utils.ExecuteCommand(options, docker...)
}
9 changes: 5 additions & 4 deletions internal/bins/bins.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,10 @@ import (
"strings"

"github.com/blang/semver/v4"
"github.com/cupcakearmy/autorestic/internal"
"github.com/cupcakearmy/autorestic/internal/colors"
"github.com/cupcakearmy/autorestic/internal/flags"
"github.com/cupcakearmy/autorestic/internal/utils"
"github.com/cupcakearmy/autorestic/internal/version"
)

const INSTALL_PATH = "/usr/local/bin"
Expand Down Expand Up @@ -115,7 +116,7 @@ func downloadAndInstallAsset(body GithubRelease, name string) error {
}

func InstallRestic() error {
installed := internal.CheckIfCommandIsCallable("restic")
installed := utils.CheckIfCommandIsCallable("restic")
if installed {
colors.Body.Println("restic already installed")
return nil
Expand All @@ -129,7 +130,7 @@ func InstallRestic() error {
}

func upgradeRestic() error {
_, _, err := internal.ExecuteCommand(internal.ExecuteOptions{
_, _, err := utils.ExecuteCommand(utils.ExecuteOptions{
Command: flags.RESTIC_BIN,
}, "self-update")
return err
Expand All @@ -147,7 +148,7 @@ func Upgrade(restic bool) error {
}

// Upgrade self
current, err := semver.ParseTolerant(internal.VERSION)
current, err := semver.ParseTolerant(version.VERSION)
if err != nil {
return err
}
Expand Down
52 changes: 10 additions & 42 deletions internal/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,23 +11,20 @@ import (
"github.com/cupcakearmy/autorestic/internal/colors"
"github.com/cupcakearmy/autorestic/internal/flags"
"github.com/cupcakearmy/autorestic/internal/lock"
"github.com/cupcakearmy/autorestic/internal/options"
"github.com/cupcakearmy/autorestic/internal/utils"
"github.com/joho/godotenv"
"github.com/mitchellh/go-homedir"
"github.com/spf13/cobra"
"github.com/spf13/viper"
)

const VERSION = "1.7.7"

type OptionMap map[string][]interface{}
type Options map[string]OptionMap

type Config struct {
Version string `mapstructure:"version"`
Extras interface{} `mapstructure:"extras"`
Locations map[string]Location `mapstructure:"locations"`
Backends map[string]Backend `mapstructure:"backends"`
Global Options `mapstructure:"global"`
Global options.Options `mapstructure:"global"`
}

var once sync.Once
Expand Down Expand Up @@ -184,7 +181,7 @@ func CheckConfig() error {
if c == nil {
return fmt.Errorf("config could not be loaded/found")
}
if !CheckIfResticIsCallable() {
if !utils.CheckIfResticIsCallable() {
return fmt.Errorf(`%s was not found. Install either with "autorestic install" or manually`, flags.RESTIC_BIN)
}
for name, backend := range c.Backends {
Expand Down Expand Up @@ -263,7 +260,7 @@ func AddFlagsToCommand(cmd *cobra.Command, backend bool) {

func (c *Config) SaveConfig() error {
file := viper.ConfigFileUsed()
if err := CopyFile(file, file+".old"); err != nil {
if err := utils.CopyFile(file, file+".old"); err != nil {
return err
}
colors.Secondary.Println("Saved a backup copy of your file next to the original.")
Expand All @@ -274,40 +271,11 @@ func (c *Config) SaveConfig() error {
return viper.WriteConfig()
}

func optionToString(option string) string {
if !strings.HasPrefix(option, "-") {
return "--" + option
}
return option
}

func appendOptionsToSlice(str *[]string, options OptionMap) {
for key, values := range options {
for _, value := range values {
// Bool
asBool, ok := value.(bool)
if ok && asBool {
*str = append(*str, optionToString(key))
continue
}
*str = append(*str, optionToString(key), fmt.Sprint(value))
}
}
}

func getOptions(options Options, keys []string) []string {
var selected []string
for _, key := range keys {
appendOptionsToSlice(&selected, options[key])
}
return selected
}

func combineBackendOptions(key string, b Backend) []string {
// Priority: backend > global
var options []string
gFlags := getOptions(GetConfig().Global, []string{key})
bFlags := getOptions(b.Options, []string{"all", key})
gFlags := GetConfig().Global.GetOptions([]string{key})
bFlags := b.Options.GetOptions([]string{"all", key})
options = append(options, gFlags...)
options = append(options, bFlags...)
return options
Expand All @@ -316,9 +284,9 @@ func combineBackendOptions(key string, b Backend) []string {
func combineAllOptions(key string, l Location, b Backend) []string {
// Priority: location > backend > global
var options []string
gFlags := getOptions(GetConfig().Global, []string{key})
bFlags := getOptions(b.Options, []string{"all", key})
lFlags := getOptions(l.Options, []string{"all", key})
gFlags := GetConfig().Global.GetOptions([]string{key})
bFlags := b.Options.GetOptions([]string{"all", key})
lFlags := l.Options.GetOptions([]string{"all", key})
options = append(options, gFlags...)
options = append(options, bFlags...)
options = append(options, lFlags...)
Expand Down
29 changes: 17 additions & 12 deletions internal/location.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ import (
"github.com/cupcakearmy/autorestic/internal/flags"
"github.com/cupcakearmy/autorestic/internal/lock"
"github.com/cupcakearmy/autorestic/internal/metadata"
"github.com/cupcakearmy/autorestic/internal/utils"
"github.com/cupcakearmy/autorestic/internal/options"
"github.com/robfig/cron"
)

Expand Down Expand Up @@ -49,7 +51,7 @@ type Location struct {
To []string `mapstructure:"to,omitempty"`
Hooks Hooks `mapstructure:"hooks,omitempty"`
Cron string `mapstructure:"cron,omitempty"`
Options Options `mapstructure:"options,omitempty"`
Options options.Options `mapstructure:"options,omitempty"`
ForgetOption LocationForgetOption `mapstructure:"forget,omitempty"`
CopyOption LocationCopy `mapstructure:"copy,omitempty"`
}
Expand Down Expand Up @@ -101,14 +103,14 @@ func (l Location) validate() error {
if _, ok := GetBackend(copyFrom); !ok {
return fmt.Errorf(`location "%s" has an invalid backend "%s" in copy option`, l.name, copyFrom)
}
if !ArrayContains(l.To, copyFrom) {
if !utils.ArrayContains(l.To, copyFrom) {
return fmt.Errorf(`location "%s" has an invalid copy from "%s"`, l.name, copyFrom)
}
for _, copyToTarget := range copyTo {
if _, ok := GetBackend(copyToTarget); !ok {
return fmt.Errorf(`location "%s" has an invalid backend "%s" in copy option`, l.name, copyToTarget)
}
if ArrayContains(l.To, copyToTarget) {
if utils.ArrayContains(l.To, copyToTarget) {
return fmt.Errorf(`location "%s" cannot copy to "%s" as it's already a target`, l.name, copyToTarget)
}
}
Expand All @@ -123,7 +125,7 @@ func (l Location) validate() error {
return nil
}

func (l Location) ExecuteHooks(commands []string, options ExecuteOptions) error {
func (l Location) ExecuteHooks(commands []string, options utils.ExecuteOptions) error {
if len(commands) == 0 {
return nil
}
Expand All @@ -137,7 +139,7 @@ func (l Location) ExecuteHooks(commands []string, options ExecuteOptions) error
colors.Secondary.Println("\nRunning hooks")
for _, command := range commands {
colors.Body.Println("> " + command)
_, out, err := ExecuteCommand(options, "-c", command)
_, out, err := utils.ExecuteCommand(options, "-c", command)
if err != nil {
colors.Error.Println(out)
return err
Expand Down Expand Up @@ -176,7 +178,7 @@ func (l Location) Backup(cron bool, specificBackend string) []error {
return errors
}
cwd, _ := GetPathRelativeToConfig(".")
options := ExecuteOptions{
options := utils.ExecuteOptions{
Command: "bash",
Dir: cwd,
Envs: map[string]string{
Expand Down Expand Up @@ -221,8 +223,9 @@ func (l Location) Backup(cron bool, specificBackend string) []error {
cmd = append(cmd, "--tag", buildTag("cron"))
}
cmd = append(cmd, "--tag", l.getLocationTags())
backupOptions := ExecuteOptions{
backupOptions := utils.ExecuteOptions{
Envs: env,
Global: GetConfig().Global,
}

var code int = 0
Expand All @@ -237,9 +240,9 @@ func (l Location) Backup(cron bool, specificBackend string) []error {
}
cmd = append(cmd, path)
}
code, out, err = ExecuteResticCommand(backupOptions, cmd...)
code, out, err = utils.ExecuteResticCommand(backupOptions, cmd...)
case TypeVolume:
ok := CheckIfVolumeExists(l.From[0])
ok := utils.CheckIfVolumeExists(l.From[0])
if !ok {
errors = append(errors, fmt.Errorf("volume \"%s\" does not exist", l.From[0]))
continue
Expand Down Expand Up @@ -277,8 +280,9 @@ func (l Location) Backup(cron bool, specificBackend string) []error {
for k, v := range env2 {
env[k+"2"] = v
}
_, _, err := ExecuteResticCommand(ExecuteOptions{
_, _, err := utils.ExecuteResticCommand(utils.ExecuteOptions{
Envs: env,
Global: GetConfig().Global,
}, "copy", md.SnapshotID)

if err != nil {
Expand Down Expand Up @@ -335,8 +339,9 @@ func (l Location) Forget(prune bool, dry bool) error {
if err != nil {
return nil
}
options := ExecuteOptions{
options := utils.ExecuteOptions{
Envs: env,
Global: GetConfig().Global,
}
cmd := []string{"forget", "--tag", l.getLocationTags()}
if prune {
Expand All @@ -346,7 +351,7 @@ func (l Location) Forget(prune bool, dry bool) error {
cmd = append(cmd, "--dry-run")
}
cmd = append(cmd, combineAllOptions("forget", l, backend)...)
_, _, err = ExecuteResticCommand(options, cmd...)
_, _, err = utils.ExecuteResticCommand(options, cmd...)
if err != nil {
return err
}
Expand Down
Loading