From 640b60c47f0366fc1f85ce9e27c0836e806d5210 Mon Sep 17 00:00:00 2001 From: cupcakearmy Date: Mon, 12 Apr 2021 10:55:57 +0200 Subject: [PATCH] current state --- ROADMAP.md | 4 +--- cmd/backup.go | 3 --- cmd/check.go | 5 ---- cmd/root.go | 3 ++- cmd/uninstall.go | 36 +++++++++++++++++++++++++++++ go.mod | 1 + go.sum | 8 +++++++ internal/bins/bins.go | 12 ++++++++++ internal/colors/colors.go | 12 ++++++++++ internal/config.go | 3 +++ internal/location.go | 48 +++++++++++++++++++++++++++++++-------- 11 files changed, 113 insertions(+), 22 deletions(-) create mode 100644 cmd/uninstall.go create mode 100644 internal/colors/colors.go diff --git a/ROADMAP.md b/ROADMAP.md index 652a636..13ce6e7 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -2,9 +2,7 @@ ## Todo -- cron -- check & enforce config -- auto create key +- output formatting ## Packages diff --git a/cmd/backup.go b/cmd/backup.go index ac3a515..81f728d 100644 --- a/cmd/backup.go +++ b/cmd/backup.go @@ -16,8 +16,6 @@ limitations under the License. package cmd import ( - "fmt" - "github.com/cupcakearmy/autorestic/internal" "github.com/cupcakearmy/autorestic/internal/lock" "github.com/spf13/cobra" @@ -40,7 +38,6 @@ var backupCmd = &cobra.Command{ CheckErr(err) for _, name := range selected { location, _ := internal.GetLocation(name) - fmt.Printf("Backing up: `%s`", name) location.Backup() } }, diff --git a/cmd/check.go b/cmd/check.go index f081913..02ed6e1 100644 --- a/cmd/check.go +++ b/cmd/check.go @@ -16,7 +16,6 @@ limitations under the License. package cmd import ( - "errors" "fmt" "github.com/cupcakearmy/autorestic/internal" @@ -29,10 +28,6 @@ var checkCmd = &cobra.Command{ Use: "check", Short: "Check if everything is setup", Run: func(cmd *cobra.Command, args []string) { - if !internal.CheckIfResticIsCallable() { - CheckErr(errors.New("restic is not callable. Install: https://restic.readthedocs.io/en/stable/020_installation.html")) - } - err := lock.Lock() CheckErr(err) defer lock.Unlock() diff --git a/cmd/root.go b/cmd/root.go index 70d1538..8e2a987 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -20,6 +20,7 @@ import ( "os" "github.com/cupcakearmy/autorestic/internal" + "github.com/cupcakearmy/autorestic/internal/colors" "github.com/cupcakearmy/autorestic/internal/lock" "github.com/spf13/cobra" @@ -83,7 +84,7 @@ func initConfig() { // If a config file is found, read it in. if err := viper.ReadInConfig(); err == nil { - fmt.Fprintln(os.Stderr, "Using config file:", viper.ConfigFileUsed()) + colors.Faint.Println("Using config file:", viper.ConfigFileUsed()) } internal.GetConfig() diff --git a/cmd/uninstall.go b/cmd/uninstall.go new file mode 100644 index 0000000..b794e3d --- /dev/null +++ b/cmd/uninstall.go @@ -0,0 +1,36 @@ +/* +Copyright © 2021 NAME HERE + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +package cmd + +import ( + "github.com/cupcakearmy/autorestic/internal/bins" + "github.com/spf13/cobra" +) + +// uninstallCmd represents the uninstall command +var uninstallCmd = &cobra.Command{ + Use: "uninstall", + Short: "Uninstall restic and autorestic", + Run: func(cmd *cobra.Command, args []string) { + noRestic, _ := cmd.Flags().GetBool("no-restic") + bins.Uninstall(!noRestic) + }, +} + +func init() { + rootCmd.AddCommand(uninstallCmd) + uninstallCmd.Flags().Bool("no-restic", false, "Do not uninstall restic.") +} diff --git a/go.mod b/go.mod index 6befd16..9354fba 100644 --- a/go.mod +++ b/go.mod @@ -5,6 +5,7 @@ go 1.16 require ( github.com/blang/semver/v4 v4.0.0 github.com/buger/goterm v1.0.0 + github.com/fatih/color v1.10.0 github.com/mitchellh/go-homedir v1.1.0 github.com/robfig/cron v1.2.0 github.com/spf13/cobra v1.1.3 diff --git a/go.sum b/go.sum index e27c519..86b9403 100644 --- a/go.sum +++ b/go.sum @@ -42,6 +42,8 @@ github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= +github.com/fatih/color v1.10.0 h1:s36xzo75JdqLaaWoiEHk767eHiwo0598uUxyfiPkDsg= +github.com/fatih/color v1.10.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM= github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= @@ -117,7 +119,11 @@ github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/magiconair/properties v1.8.1 h1:ZC2Vc7/ZFkGmsVC9KvOjumD+G5lXy2RtTKyzRKO2BQ4= github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= +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.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= +github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY= +github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= @@ -253,6 +259,8 @@ golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210331175145-43e1dd70ce54 h1:rF3Ohx8DRyl8h2zw9qojyLHLhrJpEMgyPOImREEryf0= golang.org/x/sys v0.0.0-20210331175145-43e1dd70ce54/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= diff --git a/internal/bins/bins.go b/internal/bins/bins.go index 276e2a5..64ac1f6 100644 --- a/internal/bins/bins.go +++ b/internal/bins/bins.go @@ -44,6 +44,18 @@ func dlJSON(url string) (GithubRelease, error) { return parsed, nil } +func Uninstall(restic bool) error { + if err := os.Remove(path.Join(INSTALL_PATH, "autorestic")); err != nil { + fmt.Println(err) + } + if restic { + if err := os.Remove(path.Join(INSTALL_PATH, "restic")); err != nil { + fmt.Println(err) + } + } + return nil +} + func InstallRestic() error { installed := internal.CheckIfCommandIsCallable("restic") if installed { diff --git a/internal/colors/colors.go b/internal/colors/colors.go new file mode 100644 index 0000000..c67e8fb --- /dev/null +++ b/internal/colors/colors.go @@ -0,0 +1,12 @@ +package colors + +import ( + "github.com/fatih/color" +) + +var Body = color.New() +var Primary = color.New(color.Underline, color.Bold, color.BgBlue) +var Secondary = color.New(color.Bold, color.FgCyan) +var Success = color.New(color.FgGreen) +var Error = color.New(color.FgRed, color.Bold) +var Faint = color.New(color.Faint) diff --git a/internal/config.go b/internal/config.go index 97f5b47..ea7cce4 100644 --- a/internal/config.go +++ b/internal/config.go @@ -45,6 +45,9 @@ func GetPathRelativeToConfig(p string) (string, error) { } func (c *Config) CheckConfig() error { + if !CheckIfResticIsCallable() { + return fmt.Errorf(`restic was not found. Install either with "autorestic install" or manually`) + } found := map[string]bool{} for _, backend := range c.Backends { if err := backend.validate(); err != nil { diff --git a/internal/location.go b/internal/location.go index 95ba1c1..76db271 100644 --- a/internal/location.go +++ b/internal/location.go @@ -7,6 +7,7 @@ import ( "path/filepath" "time" + "github.com/cupcakearmy/autorestic/internal/colors" "github.com/cupcakearmy/autorestic/internal/lock" "github.com/robfig/cron" ) @@ -71,11 +72,17 @@ func (l Location) getOptions(key string) []string { } func ExecuteHooks(commands []string, options ExecuteOptions) error { + if len(commands) == 0 { + return nil + } + colors.Secondary.Println("🪝 Running hooks") for _, command := range commands { + colors.Body.Println(command) out, err := ExecuteCommand(options, "-c", command) - fmt.Println(out) + colors.Faint.Print(out) return err } + fmt.Println("") return nil } @@ -103,26 +110,47 @@ func (l Location) forEachBackend(fn func(ExecuteOptions) error) error { } func (l Location) Backup() error { - return l.forEachBackend(func(options ExecuteOptions) error { - if err := ExecuteHooks(l.Hooks.Before, options); err != nil { + fmt.Printf("\n\n") + colors.Primary.Printf("💽 Backing up location \"%s\"", l.Name) + fmt.Printf("\n") + from, err := GetPathRelativeToConfig(l.From) + if err != nil { + return err + } + options := ExecuteOptions{ + Command: "bash", + Dir: from, + } + if err := ExecuteHooks(l.Hooks.Before, options); err != nil { + return nil + } + for _, to := range l.To { + backend, _ := GetBackend(to) + colors.Secondary.Printf("Backend: %s\n", backend.Name) + env, err := backend.getEnv() + if err != nil { return nil } - + options := ExecuteOptions{ + Command: "restic", + Dir: from, + Envs: env, + } flags := l.getOptions("backup") cmd := []string{"backup"} cmd = append(cmd, flags...) cmd = append(cmd, ".") out, err := ExecuteResticCommand(options, cmd...) - fmt.Println(out) + colors.Faint.Print(out) if err != nil { return err } - - if err := ExecuteHooks(l.Hooks.After, options); err != nil { - return nil - } + } + if err := ExecuteHooks(l.Hooks.After, options); err != nil { return nil - }) + } + colors.Success.Println("✅ Done") + return err } func (l Location) Forget(prune bool, dry bool) error {