Skip to content

Instantly share code, notes, and snippets.

@mmstick
Last active August 29, 2015 14:06
Show Gist options
  • Save mmstick/95f1c91b1cf9c43294fb to your computer and use it in GitHub Desktop.
Save mmstick/95f1c91b1cf9c43294fb to your computer and use it in GitHub Desktop.
// gorsync opens a file containing a tab-delimited list of backup entries.
// Spaces are allowed, and any number of tabs can be used when formatting the
// file. The first entry is the name of the entry, the second is the source
// directory, and the third entry is the target directory. After all jobs have
// been queued, the program will run them in serial and print to the terminal
// when it has completed each entry.
//
// Ex: Anime Archive /home/mmstick/Videos/Archive /home/mmstick/Backup/
package main
import "fmt"
import "io/ioutil"
import "os"
import "os/exec"
import "strings"
import "time"
type command struct {
name string
job *exec.Cmd
output []byte
err error
time time.Duration
}
// run performs the file synchronization.
func (backup *command) run() {
startTime := time.Now()
backup.output, backup.err = backup.job.CombinedOutput()
backup.time = time.Since(startTime)
}
// status prints the status of the job after synchronizing.
func (job *command) status() {
if job.err != nil {
fmt.Println(fmt.Sprint(job.err) + ": " + string(job.output))
os.Exit(0)
} else {
fmt.Printf("Synchronized %s in %s\n", job.name, job.time)
}
}
// getName returns the name of the current job.
func getName(entry *string) string {
return strings.Split(*entry, "\t")[0]
}
// trimEmptyVars trims empty variables from the slice.
func trimEmptyVars(entry []string) []string {
var trimmedSlice []string
for _, element := range entry {
if element != "" {
trimmedSlice = append(trimmedSlice, element)
}
}
return trimmedSlice
}
// getEntry returns the value of the indicated entry.
func getEntry(entry *string, index uint) string {
return trimEmptyVars(strings.Split(*entry, "\t"))[index]
}
// appendJob appends the current job to the jobs list.
func appendJob(jobs *[]command, entry *string) {
source, target := getEntry(entry, 1), getEntry(entry, 2)
job := exec.Command("rsync", "-av", "--delete", source, target)
appendJob := command{
name: getName(entry),
job: job,
}
*jobs = append(*jobs, appendJob)
}
// backupFile reads and returns a newline-delimited string slice of the
// backup file.
func backupFile() []string {
backupFile, err := ioutil.ReadFile("/home/mmstick/backup-dirs.txt")
if err != nil {
fmt.Println(err)
os.Exit(0)
}
return strings.Split(string(backupFile), "\n")
}
// backupJobs creates and returns a list of jobs to perform.
func backupJobs() *[]command {
jobs := &[]command{}
for _, entry := range backupFile() {
if len(entry) != 0 {
appendJob(jobs, &entry)
}
}
return jobs
}
func main() {
for _, job := range *backupJobs() {
job.run()
job.status()
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment