apply go formatting (#41)

pull/42/head
Marcus Kok 1 year ago committed by GitHub
parent 8ebfc35ccc
commit a135494bbc
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -14,94 +14,93 @@ import (
)
func init() {
RootCmd.AddCommand(addCommand)
RootCmd.AddCommand(addCommand)
}
var addCommand = &cobra.Command {
Use: "add",
Short: "Adds config to be tracked by dotctl",
Long: "TODO: add longer description", // TODO add more description
Run: runAddCommand,
var addCommand = &cobra.Command{
Use: "add",
Short: "Adds config to be tracked by dotctl",
Long: "TODO: add longer description", // TODO add more description
Run: runAddCommand,
}
func runAddCommand(cmd *cobra.Command, args []string) {
fs := FileSystem
testing := viper.GetBool("testing")
if len(args) <= 0 {
fmt.Println("ERROR: requires config path")
return
}
configSrc := args[0]
dirs := strings.Split(configSrc, "/")
name := dirs[len(dirs) - 1] // take the last section of the path, this should be the name
if name[0] == '.' {
name = name[1:]
}
links := viper.GetStringMap("links")
links[name] = configSrc
viper.Set("links", links)
dotfilePath := viper.Get("dotfile-path").(string)
dotfileDest := filepath.Join(dotfilePath, name)
if DryRun {
fmt.Printf("Will copy %s -> %s \n", configSrc, dotfileDest)
return
}
_, err := fs.Stat(dotfileDest)
if err == nil {
fmt.Printf("Looks like %s exists in current dotfile directory\n", dotfileDest)
fmt.Println("Do you want to overwrite it?")
confirm := promptui.Prompt{
Label: "overwrite config",
IsConfirm: true,
}
overwrite, _ := confirm.Run()
if strings.ToUpper(overwrite) == "Y" {
addConfigToDir(fs, configSrc, dotfileDest)
}
fmt.Printf("Just set up %s to link to %s\n", configSrc, dotfileDest)
} else {
addConfigToDir(fs, configSrc, dotfileDest)
}
if !testing {
err := viper.WriteConfig()
if err != nil {
fmt.Printf("Problem updating dotctl config %s", err)
}
}
fs := FileSystem
testing := viper.GetBool("testing")
if len(args) <= 0 {
fmt.Println("ERROR: requires config path")
return
}
configSrc := args[0]
dirs := strings.Split(configSrc, "/")
name := dirs[len(dirs)-1] // take the last section of the path, this should be the name
if name[0] == '.' {
name = name[1:]
}
links := viper.GetStringMap("links")
links[name] = configSrc
viper.Set("links", links)
dotfilePath := viper.Get("dotfile-path").(string)
dotfileDest := filepath.Join(dotfilePath, name)
if DryRun {
fmt.Printf("Will copy %s -> %s \n", configSrc, dotfileDest)
return
}
_, err := fs.Stat(dotfileDest)
if err == nil {
fmt.Printf("Looks like %s exists in current dotfile directory\n", dotfileDest)
fmt.Println("Do you want to overwrite it?")
confirm := promptui.Prompt{
Label: "overwrite config",
IsConfirm: true,
}
overwrite, _ := confirm.Run()
if strings.ToUpper(overwrite) == "Y" {
addConfigToDir(fs, configSrc, dotfileDest)
}
fmt.Printf("Just set up %s to link to %s\n", configSrc, dotfileDest)
} else {
addConfigToDir(fs, configSrc, dotfileDest)
}
if !testing {
err := viper.WriteConfig()
if err != nil {
fmt.Printf("Problem updating dotctl config %s", err)
}
}
}
func addConfigToDir(fs afero.Fs, configSrc, dotfileDest string) {
configFile, err := fs.Open(configSrc)
if err != nil {
log.Fatal(err)
}
configFile, err := fs.Open(configSrc)
if err != nil {
log.Fatal(err)
}
defer configFile.Close()
defer configFile.Close()
fileInfo, err := configFile.Stat()
if err != nil {
log.Fatal(err)
}
fileInfo, err := configFile.Stat()
if err != nil {
log.Fatal(err)
}
if fileInfo.IsDir() {
err = tools.CopyDir(fs, configSrc, dotfileDest)
} else {
err = tools.CopyFile(fs, configSrc, dotfileDest)
}
if fileInfo.IsDir() {
err = tools.CopyDir(fs, configSrc, dotfileDest)
} else {
err = tools.CopyFile(fs, configSrc, dotfileDest)
}
if err != nil {
log.Fatal(err)
}
if err != nil {
log.Fatal(err)
}
fmt.Printf("Copied %s -> %s\n", configSrc, dotfileDest)
fmt.Printf("Copied %s -> %s\n", configSrc, dotfileDest)
}

@ -14,76 +14,75 @@ import (
"github.com/spf13/viper"
)
func init() {
RootCmd.AddCommand(initCommand)
RootCmd.AddCommand(initCommand)
}
func copyExistingConfigs(programs []string, fs afero.Fs) {
// takes list of programs and backs up configs for them
destRoot := DotfilePath
configRoot := ConfigPath
for _, program := range(programs) {
// TODO: do something here
err := tools.CopyDir(fs, filepath.Join(configRoot, program), filepath.Join(destRoot, program))
if err != nil {
log.Fatalf("Problem copying %s", err.Error())
}
}
// takes list of programs and backs up configs for them
destRoot := DotfilePath
configRoot := ConfigPath
for _, program := range programs {
// TODO: do something here
err := tools.CopyDir(fs, filepath.Join(configRoot, program), filepath.Join(destRoot, program))
if err != nil {
log.Fatalf("Problem copying %s", err.Error())
}
}
}
func createDotfileStructure(programs []string, fs afero.Fs) {
// takes list of programs and creates dotfiles for them
dotfileRoot := DotfilePath
fmt.Printf("creating dotfile directory structure at %s\n", dotfileRoot)
for _, program := range(programs) {
if err := fs.MkdirAll(path.Join(dotfileRoot, program), os.ModePerm); err != nil {
log.Fatal(err)
}
}
// takes list of programs and creates dotfiles for them
dotfileRoot := DotfilePath
fmt.Printf("creating dotfile directory structure at %s\n", dotfileRoot)
for _, program := range programs {
if err := fs.MkdirAll(path.Join(dotfileRoot, program), os.ModePerm); err != nil {
log.Fatal(err)
}
}
}
var initCommand = &cobra.Command {
Use: "init",
Short: "Copy configs to dotfile directory",
Long: "Searches existing config directory for configs and then copies them to dotfile directory",
Run: runInitCommand,
var initCommand = &cobra.Command{
Use: "init",
Short: "Copy configs to dotfile directory",
Long: "Searches existing config directory for configs and then copies them to dotfile directory",
Run: runInitCommand,
}
func runInitCommand(cmd *cobra.Command, args []string) {
fs := FileSystem
// if user has passed a dotfile path flag need to add it to
// viper's search path for a config file
testing := viper.GetBool("testing")
viper.AddConfigPath(filepath.Join(DotfilePath, "dotctl"))
if(viper.Get("testing") == true && fs.Name() != "MemMapFS") {
log.Fatalf("wrong filesystem, got %s", fs.Name())
}
err := fs.MkdirAll(path.Join(DotfilePath, "dotctl"), 0755)
if err != nil {
log.Fatalf("Unable to create dotfile structure: %s", error.Error(err))
}
_, err = fs.Create(path.Join(DotfilePath, "dotctl/config.yml"))
if err != nil {
panic(fmt.Errorf("Unable to create config file %w", err))
}
if !testing {
err = viper.WriteConfig()
if err != nil && viper.Get("testing") != true {
log.Fatalf("Unable to write config on init: %s\n", err)
}
_, err = git.PlainInit(DotfilePath, false)
if err != nil {
log.Fatal(err)
}
gitignoreContent := []byte (`
fs := FileSystem
// if user has passed a dotfile path flag need to add it to
// viper's search path for a config file
testing := viper.GetBool("testing")
viper.AddConfigPath(filepath.Join(DotfilePath, "dotctl"))
if viper.Get("testing") == true && fs.Name() != "MemMapFS" {
log.Fatalf("wrong filesystem, got %s", fs.Name())
}
err := fs.MkdirAll(path.Join(DotfilePath, "dotctl"), 0755)
if err != nil {
log.Fatalf("Unable to create dotfile structure: %s", error.Error(err))
}
_, err = fs.Create(path.Join(DotfilePath, "dotctl/config.yml"))
if err != nil {
panic(fmt.Errorf("Unable to create config file %w", err))
}
if !testing {
err = viper.WriteConfig()
if err != nil && viper.Get("testing") != true {
log.Fatalf("Unable to write config on init: %s\n", err)
}
_, err = git.PlainInit(DotfilePath, false)
if err != nil {
log.Fatal(err)
}
gitignoreContent := []byte(`
# ignore dotctl config for individual installations
dotctl/
@ -93,13 +92,13 @@ func runInitCommand(cmd *cobra.Command, args []string) {
*.tmp
`)
err := afero.WriteFile(fs, filepath.Join(DotfilePath, ".gitignore"), gitignoreContent, 0644)
err := afero.WriteFile(fs, filepath.Join(DotfilePath, ".gitignore"), gitignoreContent, 0644)
if err != nil {
log.Fatal(err)
}
if err != nil {
log.Fatal(err)
}
}
}
fmt.Fprintf(cmd.OutOrStdout(), "Successfully created dotfiles repository at %s\n", DotfilePath)
fmt.Fprintf(cmd.OutOrStdout(), "Successfully created dotfiles repository at %s\n", DotfilePath)
}

@ -11,76 +11,72 @@ import (
)
func init() {
RootCmd.AddCommand(linkCommand)
linkCommand.AddCommand(listCommand)
RootCmd.AddCommand(linkCommand)
linkCommand.AddCommand(listCommand)
}
var linkCommand = &cobra.Command {
Use: "link",
Run: runLinkCommand,
Short: "generate symlinks according to config",
Long: "add longer description", // TODO add longer description here
var linkCommand = &cobra.Command{
Use: "link",
Run: runLinkCommand,
Short: "generate symlinks according to config",
Long: "add longer description", // TODO add longer description here
}
func runLinkCommand(cmd *cobra.Command, args []string) {
fs := FileSystem
fmt.Println("Symlinking dotfiles...")
dotfileRoot := viper.Get("dotfile-path").(string)
links := viper.GetStringMapString("links")
for configName, configPath := range links {
if configName == ".git" || configName == "dotctl" {
continue
}
dotPath := filepath.Join(dotfileRoot, configName)
if configPath == ""{
fmt.Fprintf(cmd.OutOrStdout(), "Warning: could not find config for %s\n", configName)
}
// destination needs to be removed before symlink
if(DryRun) {
log.Printf("Existing directory %s will be removed\n", configPath)
} else {
fs.RemoveAll(configPath)
}
testing := viper.Get("testing")
if(DryRun) {
log.Printf("Will link %s -> %s\n", configPath, dotPath)
} else {
if(testing == true) {
fmt.Fprintf(cmd.OutOrStdout(), "%s,%s", configPath, dotPath)
} else {
err := afero.OsFs.SymlinkIfPossible(afero.OsFs{}, dotPath, configPath)
if err != nil {
log.Fatalf("Cannot symlink %s: %s\n", configName, err.Error())
} else {
fmt.Printf("%s linked\n", configName)
}
}
}
}
fs := FileSystem
fmt.Println("Symlinking dotfiles...")
dotfileRoot := viper.Get("dotfile-path").(string)
links := viper.GetStringMapString("links")
for configName, configPath := range links {
if configName == ".git" || configName == "dotctl" {
continue
}
dotPath := filepath.Join(dotfileRoot, configName)
if configPath == "" {
fmt.Fprintf(cmd.OutOrStdout(), "Warning: could not find config for %s\n", configName)
}
// destination needs to be removed before symlink
if DryRun {
log.Printf("Existing directory %s will be removed\n", configPath)
} else {
fs.RemoveAll(configPath)
}
testing := viper.Get("testing")
if DryRun {
log.Printf("Will link %s -> %s\n", configPath, dotPath)
} else {
if testing == true {
fmt.Fprintf(cmd.OutOrStdout(), "%s,%s", configPath, dotPath)
} else {
err := afero.OsFs.SymlinkIfPossible(afero.OsFs{}, dotPath, configPath)
if err != nil {
log.Fatalf("Cannot symlink %s: %s\n", configName, err.Error())
} else {
fmt.Printf("%s linked\n", configName)
}
}
}
}
}
var listCommand = &cobra.Command {
Use: "list",
Run: runListCommand,
Short: "list configs that should be symlinked",
Long: "add longer description", // TODO add longer description here
var listCommand = &cobra.Command{
Use: "list",
Run: runListCommand,
Short: "list configs that should be symlinked",
Long: "add longer description", // TODO add longer description here
}
func runListCommand(cmd *cobra.Command, args []string) {
links := viper.GetStringMapString("links")
fmt.Println("Configs added:")
for configName, configPath := range links {
fmt.Printf("%s: %s\n", configName, configPath)
}
links := viper.GetStringMapString("links")
fmt.Println("Configs added:")
for configName, configPath := range links {
fmt.Printf("%s: %s\n", configName, configPath)
}
}

@ -10,65 +10,64 @@ import (
)
func init() {
RootCmd.AddCommand(removeCommand)
RootCmd.AddCommand(removeCommand)
}
var removeCommand = &cobra.Command {
Use: "rm",
Short: "remove dotfile link",
Long: "TODO: add longer description",
Run: runRemoveCommand,
var removeCommand = &cobra.Command{
Use: "rm",
Short: "remove dotfile link",
Long: "TODO: add longer description",
Run: runRemoveCommand,
}
func runRemoveCommand(cmd *cobra.Command, args []string) {
fs := FileSystem
fs := FileSystem
if len(args) <= 0 {
fmt.Println("ERROR: missing specified config")
return
}
if len(args) <= 0 {
fmt.Println("ERROR: missing specified config")
return
}
dotfile := args[0]
links := viper.GetStringMapString("links")
dotfileConfigPath := links[dotfile]
dotfile := args[0]
links := viper.GetStringMapString("links")
dotfileConfigPath := links[dotfile]
err := fs.Remove(dotfileConfigPath)
if err != nil {
fmt.Printf("ERROR: problem removing symlink %s: %s\n", dotfileConfigPath, err)
return
}
err := fs.Remove(dotfileConfigPath)
if err != nil {
fmt.Printf("ERROR: problem removing symlink %s: %s\n", dotfileConfigPath, err)
return
}
dotfileSavedPath := filepath.Join(DotfilePath, dotfile)
savedFile, err := fs.Open(dotfileSavedPath)
if err != nil {
fmt.Printf("ERROR: problem viewing saved dotfile(s): %s\n", err)
return
}
dotfileSavedPath := filepath.Join(DotfilePath, dotfile)
savedFile, err := fs.Open(dotfileSavedPath)
if err != nil {
fmt.Printf("ERROR: problem viewing saved dotfile(s): %s\n", err)
return
}
fileInfo, err := savedFile.Stat()
if err != nil {
fmt.Printf("ERROR: problem getting file info: %s\n", err)
return
}
if fileInfo.IsDir() {
err = tools.CopyDir(fs, dotfileSavedPath, dotfileConfigPath)
} else {
err = tools.CopyFile(fs, dotfileSavedPath, dotfileConfigPath)
}
fileInfo, err := savedFile.Stat()
if err != nil {
fmt.Printf("ERROR: problem getting file info: %s\n", err)
return
}
if fileInfo.IsDir() {
err = tools.CopyDir(fs, dotfileSavedPath, dotfileConfigPath)
} else {
err = tools.CopyFile(fs, dotfileSavedPath, dotfileConfigPath)
}
if err != nil {
fmt.Printf("ERROR: problem copying over dotfile(s) %s\n", err)
return
}
if err != nil {
fmt.Printf("ERROR: problem copying over dotfile(s) %s\n", err)
return
}
delete(links, dotfile)
viper.Set("links", links)
err = viper.WriteConfig()
if err != nil {
fmt.Printf("ERROR: problem saving config: %s\n", err)
return
}
delete(links, dotfile)
viper.Set("links", links)
err = viper.WriteConfig()
if err != nil {
fmt.Printf("ERROR: problem saving config: %s\n", err)
return
}
fmt.Printf("%s symlink removed, copied files over to %s\n", dotfile, dotfileConfigPath)
fmt.Printf("%s symlink removed, copied files over to %s\n", dotfile, dotfileConfigPath)
}

@ -13,7 +13,6 @@ import (
"github.com/spf13/viper"
)
var RootCmd = &cobra.Command{
Use: "dotctl",
Short: "dotfile management",
@ -38,63 +37,60 @@ var DryRun bool
var FileSystem afero.Fs
func init() {
// define flags and config sections
// define flags and config sections
// Cobra also supports local flags, which will only run
// when this action is called directly.
defaultDotPath := os.Getenv("HOME") + "/dotfiles/"
defaultConfPath := os.Getenv("HOME") + "/.config/"
RootCmd.PersistentFlags().StringVar(
&DotfilePath,
"dotfile-path",
defaultDotPath,
"Path pointing to dotfiles directory",
)
RootCmd.PersistentFlags().StringVar(
&ConfigPath,
"config-path",
defaultConfPath,
"Path pointing to config directory",
)
RootCmd.PersistentFlags().BoolVarP(&DryRun, "dry-run", "d", false, "Only output which symlinks will be created")
viper.BindPFlag("dotfile-path", RootCmd.PersistentFlags().Lookup("dotfile-path"))
viper.BindPFlag("config-path", RootCmd.PersistentFlags().Lookup("config-path"))
viper.BindEnv("testing")
viper.SetDefault("testing", false)
viper.SetConfigName("config.yml")
viper.SetConfigType("yaml")
viper.AddConfigPath("./tmp/dotfiles/dotctl")
viper.AddConfigPath(filepath.Join(DotfilePath, "dotctl"))
viper.SetDefault("links", map[string]string{})
err := viper.ReadInConfig()
if err != nil {
fmt.Println("No config detected. You can generate one by using 'dotctl init'")
}
FileSystem = UseFilesystem()
defaultDotPath := os.Getenv("HOME") + "/dotfiles/"
defaultConfPath := os.Getenv("HOME") + "/.config/"
RootCmd.PersistentFlags().StringVar(
&DotfilePath,
"dotfile-path",
defaultDotPath,
"Path pointing to dotfiles directory",
)
RootCmd.PersistentFlags().StringVar(
&ConfigPath,
"config-path",
defaultConfPath,
"Path pointing to config directory",
)
RootCmd.PersistentFlags().BoolVarP(&DryRun, "dry-run", "d", false, "Only output which symlinks will be created")
viper.BindPFlag("dotfile-path", RootCmd.PersistentFlags().Lookup("dotfile-path"))
viper.BindPFlag("config-path", RootCmd.PersistentFlags().Lookup("config-path"))
viper.BindEnv("testing")
viper.SetDefault("testing", false)
viper.SetConfigName("config.yml")
viper.SetConfigType("yaml")
viper.AddConfigPath("./tmp/dotfiles/dotctl")
viper.AddConfigPath(filepath.Join(DotfilePath, "dotctl"))
viper.SetDefault("links", map[string]string{})
err := viper.ReadInConfig()
if err != nil {
fmt.Println("No config detected. You can generate one by using 'dotctl init'")
}
FileSystem = UseFilesystem()
}
func UseFilesystem() afero.Fs {
testing := viper.Get("testing")
if(testing == "true") {
return afero.NewMemMapFs()
} else {
return afero.NewOsFs()
}
testing := viper.Get("testing")
if testing == "true" {
return afero.NewMemMapFs()
} else {
return afero.NewOsFs()
}
}
func CheckIfError(err error) {
if err != nil {
panic(err)
}
return
if err != nil {
panic(err)
}
return
}

@ -11,57 +11,52 @@ import (
)
func init() {
RootCmd.AddCommand(statusCommand)
RootCmd.AddCommand(statusCommand)
}
var statusCommand = &cobra.Command {
Use: "status",
Short: "View status of dotctl",
Long: "TODO: add longer description",
Run: runStatusCommand,
var statusCommand = &cobra.Command{
Use: "status",
Short: "View status of dotctl",
Long: "TODO: add longer description",
Run: runStatusCommand,
}
func runStatusCommand(cmd *cobra.Command, args[]string) {
fs := FileSystem
links := viper.GetStringMapString("links")
func runStatusCommand(cmd *cobra.Command, args []string) {
fs := FileSystem
links := viper.GetStringMapString("links")
var ignoredDirs = []string{".git", "dotctl", ".gitignore"}
var ignoredDirs = []string{".git", "dotctl", ".gitignore"}
dotfiles, err := afero.ReadDir(fs, viper.GetString("dotfile-path"))
if err != nil {
log.Fatalf("Cannot read dotfile dir: %s\n", err)
}
dotfiles, err := afero.ReadDir(fs, viper.GetString("dotfile-path"))
if err != nil {
log.Fatalf("Cannot read dotfile dir: %s\n", err)
}
var linkedConfigs []string
var orphanedConfigs []string
var linkedConfigs []string
var orphanedConfigs []string
fmt.Fprintln(cmd.OutOrStdout(), "Config directories currently in dotfile path:\n")
for _, dotfileDir := range(dotfiles) {
dirName := dotfileDir.Name()
if !slices.Contains(ignoredDirs, dirName) {
if links[dirName] != "" {
// fmt.Fprintf(cmd.OutOrStdout(), "%s -> %s\n", dirName, links[dirName])
linkedConfigs = append(linkedConfigs, dirName, links[dirName])
} else {
// fmt.Fprintln(cmd.OutOrStdout(), dirName)
orphanedConfigs = append(orphanedConfigs, dirName)
}
}
}
fmt.Fprintln(cmd.OutOrStdout(), "Config directories currently in dotfile path:")
for i := 0; i < len(linkedConfigs); i += 2 {
fmt.Fprintf(cmd.OutOrStdout(), "%s (links to %s)\n", linkedConfigs[i], linkedConfigs[i+1])
}
fmt.Fprintln(cmd.OutOrStdout(), "================")
for _, dotfileDir := range dotfiles {
dirName := dotfileDir.Name()
if !slices.Contains(ignoredDirs, dirName) {
if links[dirName] != "" {
linkedConfigs = append(linkedConfigs, dirName, links[dirName])
} else {
orphanedConfigs = append(orphanedConfigs, dirName)
}
}
}
fmt.Fprintln(cmd.OutOrStdout(), "Orphaned configs")
for _, conf := range(orphanedConfigs) {
fmt.Fprintln(cmd.OutOrStdout(), conf)
}
for i := 0; i < len(linkedConfigs); i += 2 {
fmt.Fprintf(cmd.OutOrStdout(), "%s (links to %s)\n", linkedConfigs[i], linkedConfigs[i+1])
}
fmt.Fprintln(cmd.OutOrStdout(), "================")
fmt.Fprintln(cmd.OutOrStdout(), "Orphaned configs")
for _, conf := range orphanedConfigs {
fmt.Fprintln(cmd.OutOrStdout(), conf)
}
}

@ -21,15 +21,15 @@ var remoteRepository string
func init() {
RootCmd.AddCommand(syncCommand)
syncCommand.Flags().StringVarP(
&remoteRepository,
"remote",
"r",
"",
"URL of remote repository",
)
viper.BindPFlag("dotctl-origin", syncCommand.Flags().Lookup("remote"))
syncCommand.Flags().StringVarP(
&remoteRepository,
"remote",
"r",
"",
"URL of remote repository",
)
viper.BindPFlag("dotctl-origin", syncCommand.Flags().Lookup("remote"))
}
var syncCommand = &cobra.Command{
@ -40,29 +40,29 @@ var syncCommand = &cobra.Command{
}
func validateInput(input string) error {
if input == "" {
return errors.New("Missing input")
}
if input == "" {
return errors.New("Missing input")
}
return nil
return nil
}
func gitAddFiles(worktree *git.Worktree, fs afero.Fs) error {
dotfilepath := viper.GetString("dotfile-path")
entries, err := afero.ReadDir(fs, dotfilepath)
if err != nil {
return err
}
for _, entry := range(entries) {
if(entry.Name() == "dotctl") {
continue
}
_, err = worktree.Add(entry.Name())
if err != nil {
return err
}
}
return nil
dotfilepath := viper.GetString("dotfile-path")
entries, err := afero.ReadDir(fs, dotfilepath)
if err != nil {
return err
}
for _, entry := range entries {
if entry.Name() == "dotctl" {
continue
}
_, err = worktree.Add(entry.Name())
if err != nil {
return err
}
}
return nil
}
func runSyncCommand(cmd *cobra.Command, args []string) {
@ -91,117 +91,116 @@ func runSyncCommand(cmd *cobra.Command, args []string) {
w, err := r.Worktree()
CheckIfError(err)
username := promptui.Prompt{
Label: "username",
Validate: validateInput,
}
password := promptui.Prompt{
Label: "password",
Validate: validateInput,
HideEntered: true,
Mask: '*',
}
username := promptui.Prompt{
Label: "username",
Validate: validateInput,
}
usernameVal, err := username.Run()
CheckIfError(err)
password := promptui.Prompt{
Label: "password",
Validate: validateInput,
HideEntered: true,
Mask: '*',
}
passwordVal, err := password.Run()
CheckIfError(err)
usernameVal, err := username.Run()
CheckIfError(err)
passwordVal, err := password.Run()
CheckIfError(err)
fmt.Println("Pulling from remote")
fmt.Println("Pulling from remote")
err = w.Pull(&git.PullOptions{
RemoteName: "origin",
Auth: &http.BasicAuth {
Username: usernameVal,
Password: passwordVal,
},
Auth: &http.BasicAuth{
Username: usernameVal,
Password: passwordVal,
},
})
if err != nil{
fmt.Println(err)
} else {
fmt.Fprintf(cmd.OutOrStdout(), "successfully pulled from %s", origin)
}
status, err := w.Status()
if err != nil {
log.Fatalln("Error getting status", err)
}
if !status.IsClean() {
fmt.Println("Changes detected, do you want to push them?")
confirm := promptui.Prompt {
Label: "commit and push changes",
IsConfirm: true,
}
_, err := confirm.Run()
if err != nil {
fmt.Println("Will not push changes")
return
}
fmt.Println("Pushing changes...")
err = gitAddFiles(w, FileSystem)
if err != nil {
log.Fatalf("Could not add files: %s\n", err)
return
}
commitMessage := "backup " + time.Now().String()
commit, err := w.Commit(commitMessage, &git.CommitOptions{
Author: &object.Signature{
Name: "dotctl CLI",
Email: "example@example.com",
When: time.Now(),
},
})
if err != nil {
log.Fatal(err.Error())
}
obj, err := r.CommitObject(commit)
if err != nil {
log.Fatalf("Cannot commit: %s",err)
}
fmt.Println(obj)
err = r.Push(&git.PushOptions{
RemoteName: "origin",
Auth: &http.BasicAuth {
Username: usernameVal,
Password: passwordVal,
},
})
CheckIfError(err)
}
// a pull deletes the dotctl config from the filesystem, need to recreate it
rewriteConfig()
if err != nil {
fmt.Println(err)
} else {
fmt.Fprintf(cmd.OutOrStdout(), "successfully pulled from %s", origin)
}
status, err := w.Status()
if err != nil {
log.Fatalln("Error getting status", err)
}
if !status.IsClean() {
fmt.Println("Changes detected, do you want to push them?")
confirm := promptui.Prompt{
Label: "commit and push changes",
IsConfirm: true,
}
_, err := confirm.Run()
if err != nil {
fmt.Println("Will not push changes")
return
}
fmt.Println("Pushing changes...")
err = gitAddFiles(w, FileSystem)
if err != nil {
log.Fatalf("Could not add files: %s\n", err)
return
}
commitMessage := "backup " + time.Now().String()
commit, err := w.Commit(commitMessage, &git.CommitOptions{
Author: &object.Signature{
Name: "dotctl CLI",
Email: "example@example.com",
When: time.Now(),
},
})
if err != nil {
log.Fatal(err.Error())
}
obj, err := r.CommitObject(commit)
if err != nil {
log.Fatalf("Cannot commit: %s", err)
}
fmt.Println(obj)
err = r.Push(&git.PushOptions{
RemoteName: "origin",
Auth: &http.BasicAuth{
Username: usernameVal,
Password: passwordVal,
},
})
CheckIfError(err)
}
// a pull deletes the dotctl config from the filesystem, need to recreate it
rewriteConfig()
}
func rewriteConfig() {
fs := UseFilesystem()
err := fs.MkdirAll(path.Join(DotfilePath, "dotctl"), 0755)
if err != nil {
log.Fatalf("Unable to create dotfile structure: %s", error.Error(err))
}
_, err = fs.Create(path.Join(DotfilePath, "dotctl/config"))
if err != nil {
panic(fmt.Errorf("Unable to create config file %w", err))
}
err = viper.WriteConfig()
if err != nil {
fmt.Println("Error: could not write config: ", err)
}
fs := UseFilesystem()
err := fs.MkdirAll(path.Join(DotfilePath, "dotctl"), 0755)
if err != nil {
log.Fatalf("Unable to create dotfile structure: %s", error.Error(err))
}
_, err = fs.Create(path.Join(DotfilePath, "dotctl/config"))
if err != nil {
panic(fmt.Errorf("Unable to create config file %w", err))
}
err = viper.WriteConfig()
if err != nil {
fmt.Println("Error: could not write config: ", err)
}
}

@ -12,16 +12,16 @@ import (
)
var (
version = "dev"
commit = "none"
date = "unknown"
version = "dev"
commit = "none"
date = "unknown"
)
func SetVersionInfo(version, commit, date string) {
cmd.RootCmd.Version = fmt.Sprintf("%s [Built on %s from Git Sha %s]", version, date, commit)
cmd.RootCmd.Version = fmt.Sprintf("%s [Built on %s from Git Sha %s]", version, date, commit)
}
func main() {
SetVersionInfo(versioninfo.Version, versioninfo.Revision, versioninfo.LastCommit.Format(time.RFC3339))
SetVersionInfo(versioninfo.Version, versioninfo.Revision, versioninfo.LastCommit.Format(time.RFC3339))
cmd.Execute()
}

@ -9,78 +9,76 @@ import (
)
func init() {
tools.SetTestFs()
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))
}
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))
}
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))
}
}

@ -12,24 +12,24 @@ import (
)
func TestInitCommand(t *testing.T) {
viper.Set("testing", true)
viper.Set("testing", true)
fs := cmd.FileSystem
fs := cmd.FileSystem
dotctl := cmd.RootCmd
actual := new(bytes.Buffer)
dotctl := cmd.RootCmd
actual := new(bytes.Buffer)
dotctl.SetOut(actual)
dotctl.SetErr(actual)
dotctl.SetArgs([]string{"init"})
dotctl.SetOut(actual)
dotctl.SetErr(actual)
dotctl.SetArgs([]string{"init"})
dotctl.Execute()
dotctl.Execute()
homedir := os.Getenv("HOME")
homedir := os.Getenv("HOME")
_, err := afero.ReadFile(fs, filepath.Join(homedir, "dotfiles/dotctl/config.yml"))
if err != nil {
t.Error(err.Error())
}
_, err := afero.ReadFile(fs, filepath.Join(homedir, "dotfiles/dotctl/config.yml"))
if err != nil {
t.Error(err.Error())
}
}

@ -13,33 +13,31 @@ import (
"github.com/stretchr/testify/assert"
)
func TestLinkCommand(t *testing.T) {
viper.Set("testing", true)
cmd.FileSystem = afero.NewMemMapFs()
fs := cmd.FileSystem
homedir := os.Getenv("HOME")
viper.Set("testing", true)
cmd.FileSystem = afero.NewMemMapFs()
fs := cmd.FileSystem
homedir := os.Getenv("HOME")
fs.MkdirAll(filepath.Join(homedir, "dotfiles/dotctl"), 0755)
links := map[string]string {
"someconfig": filepath.Join(homedir, ".config/someconfig"),
}
viper.Set("links", links)
fs.MkdirAll(filepath.Join(homedir, "dotfiles/dotctl"), 0755)
links := map[string]string{
"someconfig": filepath.Join(homedir, ".config/someconfig"),
}
viper.Set("links", links)
dotctl := cmd.RootCmd
actual := new(bytes.Buffer)
dotctl := cmd.RootCmd
actual := new(bytes.Buffer)
dotctl.SetOut(actual)
dotctl.SetErr(actual)
dotctl.SetArgs([]string{"link"})
dotctl.SetOut(actual)
dotctl.SetErr(actual)
dotctl.SetArgs([]string{"link"})
dotctl.Execute()
dotctl.Execute()
someconfig := filepath.Join(homedir, ".config/someconfig/")
somedot := filepath.Join(homedir, "dotfiles/someconfig/")
someconfig := filepath.Join(homedir, ".config/someconfig/")
somedot := filepath.Join(homedir, "dotfiles/someconfig/")
expected := fmt.Sprintf("%s,%s", someconfig, somedot)
expected := fmt.Sprintf("%s,%s", someconfig, somedot)
assert.Equal(t, expected, actual.String(), "actual differs from expected")
assert.Equal(t, expected, actual.String(), "actual differs from expected")
}

@ -12,34 +12,34 @@ import (
)
func TestStatusCommand(t *testing.T) {
cmd.FileSystem = afero.NewMemMapFs()
viper.Set("testing", true)
cmd.FileSystem = afero.NewMemMapFs()
viper.Set("testing", true)
fs := cmd.FileSystem
fs := cmd.FileSystem
homedir := os.Getenv("HOME")
fs.MkdirAll(filepath.Join(homedir, "dotfiles/dotctl"), 0755)
fs.MkdirAll(filepath.Join(homedir, "dotfiles/someconfig"), 0755)
fs.MkdirAll(filepath.Join(homedir, "dotfiles/somelinkedconfig"), 0755)
homedir := os.Getenv("HOME")
fs.MkdirAll(filepath.Join(homedir, "dotfiles/dotctl"), 0755)
fs.MkdirAll(filepath.Join(homedir, "dotfiles/someconfig"), 0755)
fs.MkdirAll(filepath.Join(homedir, "dotfiles/somelinkedconfig"), 0755)
var links = map[string]string {
"somelinkedconfig": "configpath",
}
var links = map[string]string{
"somelinkedconfig": "configpath",
}
viper.Set("links", links)
viper.Set("links", links)
dotctl := cmd.RootCmd
dotctl := cmd.RootCmd
actual := new(bytes.Buffer)
actual := new(bytes.Buffer)
dotctl.SetOut(actual)
dotctl.SetErr(actual)
dotctl.SetArgs([]string{"status"})
dotctl.SetOut(actual)
dotctl.SetErr(actual)
dotctl.SetArgs([]string{"status"})
dotctl.Execute()
dotctl.Execute()
// expected := "Config directories currently in dotfile path:\n" +
// "someconfig\nsomelinkedconfig - configpath\n"
// expected := "Config directories currently in dotfile path:\n" +
// "someconfig\nsomelinkedconfig - configpath\n"
// assert.Equal(t, expected, actual.String(), "actual differs from expected")
// assert.Equal(t, expected, actual.String(), "actual differs from expected")
}

@ -9,70 +9,69 @@ import (
"github.com/spf13/afero"
)
func CopyFile(os afero.Fs, srcFile, destFile string) error{
// helper function to copy files over
// ignore pre-existing git files
if strings.Contains(srcFile, ".git") {
return nil
}
func CopyFile(os afero.Fs, srcFile, destFile string) error {
// helper function to copy files over
// ignore pre-existing git files
if strings.Contains(srcFile, ".git") {
return nil
}
sourceFileStat, err := os.Stat(srcFile)
if err != nil {
return err
}
sourceFileStat, err := os.Stat(srcFile)
if err != nil {
return err
}
if !sourceFileStat.Mode().IsRegular() {
return fmt.Errorf("%s is not a regular file", srcFile)
}
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()
source, err := os.Open(srcFile)
if err != nil {
return err
}
defer source.Close()
destination, err := os.Create(destFile)
if err != nil {
fmt.Printf("Error creating destination file %s\n", destFile)
return err
}
defer destination.Close()
destination, err := os.Create(destFile)
if err != nil {
fmt.Printf("Error creating destination file %s\n", destFile)
return err
}
defer destination.Close()
_, err = io.Copy(destination, source)
_, err = io.Copy(destination, source)
return err
return err
}
func CopyDir(os afero.Fs, srcDir, destDir string) error {
os.Mkdir(destDir, 0755)
entries, err := afero.ReadDir(os, srcDir)
if err != nil {
return err
}
os.Mkdir(destDir, 0755)
entries, err := afero.ReadDir(os, srcDir)
if err != nil {
return err
}
for _, entry := range(entries) {
if entry.IsDir() {
if entry.Name() == ".git" {
continue
}
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())
for _, entry := range entries {
if entry.IsDir() {
if entry.Name() == ".git" {
continue
}
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
}
}
err := CopyFile(os, sourcePath, destPath)
if err != nil {
return err
}
}
return nil
return nil
}

@ -8,9 +8,8 @@ import (
var AppFs afero.Fs = afero.NewOsFs()
func SetTestFs() {
log.Println("setting test fs")
testFs := afero.NewMemMapFs()
AppFs = testFs
log.Println("setting test fs")
testFs := afero.NewMemMapFs()
AppFs = testFs
}

Loading…
Cancel
Save