diff --git a/homemaker.go b/homemaker.go index 8d9168c..8e74839 100644 --- a/homemaker.go +++ b/homemaker.go @@ -35,9 +35,10 @@ const ( flagClobber = 1 << iota flagForce flagVerbose - flagNoCmd - flagNoLink + flagNoCmds + flagNoLinks flagNoMacro + flagUnlink = flagNoCmds | (1 << iota) ) func usage() { @@ -58,9 +59,10 @@ func main() { force := flag.Bool("force", true, "create parent directories to target") clobber := flag.Bool("clobber", false, "delete files and directories at target") verbose := flag.Bool("verbose", false, "verbose output") - nocmd := flag.Bool("nocmd", false, "don't execute commands") - nolink := flag.Bool("nolink", false, "don't create links") - variant := flag.String("variant", "", "execution variant") + nocmds := flag.Bool("nocmds", false, "don't execute commands") + nolinks := flag.Bool("nolinks", false, "don't create links") + variant := flag.String("variant", "", "execution variant for tasks and macros") + unlink := flag.Bool("unlink", false, "remove existing links instead of creating them") flag.Usage = usage flag.Parse() @@ -75,11 +77,14 @@ func main() { if *verbose { flags |= flagVerbose } - if *nocmd { - flags |= flagNoCmd + if *nocmds { + flags |= flagNoCmds } - if *nolink { - flags |= flagNoLink + if *nolinks { + flags |= flagNoLinks + } + if *unlink { + flags |= flagUnlink } if flag.NArg() == 2 { diff --git a/link.go b/link.go index 2ac7bd8..b465d02 100644 --- a/link.go +++ b/link.go @@ -115,23 +115,32 @@ func processLink(params []string, conf *config) error { dstPathAbs = path.Join(conf.dstDir, dstPath) } - if _, err := os.Stat(srcPathAbs); os.IsNotExist(err) { - return fmt.Errorf("source path %s does not exist in filesystem", srcPathAbs) - } + if conf.flags&flagUnlink == 0 { + if _, err := os.Stat(srcPathAbs); os.IsNotExist(err) { + return fmt.Errorf("source path %s does not exist in filesystem", srcPathAbs) + } - if err := try(func() error { return createPath(dstPathAbs, conf.flags, mode) }); err != nil { - return err - } + if err := try(func() error { return createPath(dstPathAbs, conf.flags, mode) }); err != nil { + return err + } - if err := try(func() error { return cleanPath(dstPathAbs, conf.flags) }); err != nil { - return err - } + if err := try(func() error { return cleanPath(dstPathAbs, conf.flags) }); err != nil { + return err + } - if conf.flags&flagVerbose != 0 { - log.Printf("linking %s to %s", srcPathAbs, dstPathAbs) - } + if conf.flags&flagVerbose != 0 { + log.Printf("linking %s to %s", srcPathAbs, dstPathAbs) + } - return try(func() error { - return os.Symlink(srcPathAbs, dstPathAbs) - }) + return try(func() error { + return os.Symlink(srcPathAbs, dstPathAbs) + }) + } else { + stat, err := os.Lstat(dstPathAbs) + if os.IsNotExist(err) || stat.Mode()&os.ModeSymlink == 0 { + return nil + } + + return try(func() error { return cleanPath(dstPathAbs, conf.flags) }) + } } diff --git a/task.go b/task.go index b920cd6..0a5a776 100644 --- a/task.go +++ b/task.go @@ -47,7 +47,7 @@ func (t *task) process(conf *config) error { } } - if conf.flags&flagNoCmd == 0 { + if conf.flags&flagNoCmds == 0 { for _, currCmd := range t.Cmds { if err := processCmd(currCmd, conf); err != nil { return err @@ -55,7 +55,7 @@ func (t *task) process(conf *config) error { } } - if conf.flags&flagNoLink == 0 { + if conf.flags&flagNoLinks == 0 { for _, currLink := range t.Links { if err := processLink(currLink, conf); err != nil { return err