Add copy (#3)

Adds helper functions to copy a file and recursively copy a directory
pull/6/head
Marcus Kok 2 years ago committed by GitHub
parent e2b88f11d9
commit 0a06a6ad0c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -2,7 +2,6 @@ name: CI
on:
pull_request:
branches:
- main
jobs:
ci:
@ -16,4 +15,4 @@ jobs:
- name: Install dependencies
run: go get .
- name: Test with Go CLI
run: go test ./test
run: go test -v ./test

@ -7,12 +7,44 @@ import (
"path/filepath"
"github.com/spf13/cobra"
"github.com/Marcusk19/bender/tools"
)
var fs = tools.AppFs
func init() {
RootCmd.AddCommand(initCommand)
}
func copyExistingConfigs(programs []string, destRootOpt ...string) {
// takes list of programs and backs up configs for them
destRoot := os.Getenv("HOME") + "/.dotfiles/"
if len(destRootOpt) > 0 {
destRoot = destRootOpt[0]
}
configRoot := os.Getenv("HOME") + "/.config/"
for _, program := range(programs) {
// TODO: do something here
print(configRoot + program)
err := tools.CopyDir(fs, filepath.Join(configRoot, program), filepath.Join(destRoot, program))
if err != nil {
log.Fatal(err)
}
}
}
func createDotfileStructure(programs []string) {
// takes list of programs and creates dotfiles for them
dotfileRoot := os.Getenv("HOME") + "/.dotfiles/"
for _, program := range(programs) {
fmt.Printf("attempting to create directory %s%s\n", dotfileRoot, program)
if err := fs.MkdirAll(dotfileRoot + program, os.ModePerm); err != nil {
log.Fatal(err)
}
}
}
var initCommand = &cobra.Command {
Use: "init",
Run: func(cmd *cobra.Command, args []string) {
@ -28,11 +60,11 @@ var initCommand = &cobra.Command {
log.Fatal("path needs trailing slash")
}
var files []string
var acceptedfiles [3] string
acceptedfiles[0] = "nvim"
acceptedfiles[1] = "tmux"
acceptedfiles[2] = "alacritty"
var programs []string
var acceptedprograms [3] string
acceptedprograms[0] = "nvim"
acceptedprograms[1] = "tmux"
acceptedprograms[2] = "alacritty"
err := filepath.Walk(rootpath, func(path string, info os.FileInfo, err error) error {
if err != nil {
@ -40,9 +72,9 @@ var initCommand = &cobra.Command {
return nil
}
for _, acceptedfile := range(acceptedfiles) {
if path == rootpath + acceptedfile {
files = append(files, path)
for _, acceptedprogram := range(acceptedprograms) {
if path == rootpath + acceptedprogram {
programs = append(programs, path[len(rootpath):])
}
}
return nil
@ -53,9 +85,12 @@ var initCommand = &cobra.Command {
}
fmt.Fprintf(cmd.OutOrStdout(), "binaries installed: \n =======================\n")
for _, file := range(files) {
fmt.Fprintf(cmd.OutOrStdout(), file[len(rootpath):] + "\n" )
for _, program := range(programs) {
fmt.Fprintf(cmd.OutOrStdout(), program + "\n" )
}
createDotfileStructure(programs)
copyExistingConfigs(programs)
},
}

@ -6,8 +6,10 @@ require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/spf13/afero v1.11.0 // indirect
github.com/spf13/cobra v1.8.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/stretchr/testify v1.9.0 // indirect
golang.org/x/text v0.14.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)

@ -6,12 +6,16 @@ github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLf
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/spf13/afero v1.11.0 h1:WJQKhtpdm3v2IzqG8VMqrr6Rf3UYpEF239Jy9wNepM8=
github.com/spf13/afero v1.11.0/go.mod h1:GH9Y3pIexgf1MTIWtNGyogA5MwRIDXGUr+hbWNoBjkY=
github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0=
github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

@ -0,0 +1,86 @@
package test
import (
"os"
"testing"
"github.com/Marcusk19/bender/tools"
"github.com/spf13/afero"
)
func init() {
tools.SetTestFs()
}
func TestCopyFile(t *testing.T) {
fs := afero.NewMemMapFs()
fs.MkdirAll("test/src", 0755)
fs.MkdirAll("test/dest", 0755)
err := afero.WriteFile(fs, "test/src/a.txt", []byte("file a"), 0644)
if err != nil {
t.Errorf("problem creating source file: %s", err.Error())
}
err = tools.CopyFile(fs, "test/src/a.txt", "test/dest/a.txt")
if err != nil {
t.Error(err.Error())
}
_, err = fs.Stat("test/dest/a.txt")
if os.IsNotExist(err) {
t.Errorf("expected destination file does not exist")
}
result, err := afero.ReadFile(fs, "test/dest/a.txt")
if err != nil {
t.Error(err.Error())
}
if string(result) != "file a" {
t.Errorf("expected 'file a' got '%s'", string(result))
}
}
func TestCopyDir(t *testing.T) {
fs := afero.NewMemMapFs()
fs.MkdirAll("test/src/dirA", 0755)
fs.MkdirAll("test/dest/", 0755)
fs.Mkdir("test/src/dirA/dirB", 0755)
err := afero.WriteFile(fs, "test/src/dirA/a.txt", []byte("file a"), 0644)
if err != nil {
t.Error(err.Error())
}
err = afero.WriteFile(fs, "test/src/dirA/dirB/b.txt", []byte("file b"), 0644)
if err != nil {
t.Error(err.Error())
}
err = tools.CopyDir(fs, "test/src", "test/dest")
if err != nil {
t.Error(err.Error())
}
result, err := afero.ReadFile(fs, "test/dest/dirA/a.txt")
if err != nil {
t.Error(err.Error())
}
if string(result) != "file a" {
t.Errorf("expected 'file a' got '%s'", string(result))
}
result, err = afero.ReadFile(fs, "test/dest/dirA/dirB/b.txt")
if err != nil {
t.Error(err.Error())
}
if string(result) != "file b" {
t.Errorf("expected 'file b' got '%s'", string(result))
}
}

@ -0,0 +1,66 @@
package tools
import (
"fmt"
"io"
"path/filepath"
"github.com/spf13/afero"
)
func CopyFile(os afero.Fs, srcFile, destFile string) error{
// helper function to copy files over
sourceFileStat, err := os.Stat(srcFile)
if err != nil {
return err
}
if !sourceFileStat.Mode().IsRegular() {
return fmt.Errorf("%s is not a regular file", srcFile)
}
source, err := os.Open(srcFile)
if err != nil {
return err
}
defer source.Close()
destination, err := os.Create(destFile)
if err != nil {
return err
}
defer destination.Close()
_, err = io.Copy(destination, source)
return err
}
func CopyDir(os afero.Fs, srcDir, destDir string) error {
entries, err := afero.ReadDir(os, srcDir)
if err != nil {
return err
}
for _, entry := range(entries) {
if entry.IsDir() {
subDir := filepath.Join(srcDir, entry.Name())
destSubDir := filepath.Join(destDir, entry.Name())
err := os.MkdirAll(destSubDir, entry.Mode().Perm())
if err != nil {
return err
}
CopyDir(os, subDir, destSubDir)
continue
}
sourcePath := filepath.Join(srcDir, entry.Name())
destPath := filepath.Join(destDir, entry.Name())
err := CopyFile(os, sourcePath, destPath)
if err != nil {
return err
}
}
return nil
}

@ -0,0 +1,16 @@
package tools
import (
"log"
"github.com/spf13/afero"
)
var AppFs afero.Fs = afero.NewOsFs()
func SetTestFs() {
log.Print("setting test fs")
testFs := afero.NewMemMapFs()
AppFs = testFs
}
Loading…
Cancel
Save