diff --git a/command.go b/command.go new file mode 100644 index 0000000..5d38d37 --- /dev/null +++ b/command.go @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2015 Alex Yatskov + * Author: Alex Yatskov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package main + +import ( + "fmt" + "log" + "os" + "os/exec" + "strings" +) + +type command []string + +func (this *command) valid() bool { + return len(*this) >= 1 +} + +func (this *command) process(dir string, flags int) error { + if !this.valid() { + return fmt.Errorf("command element is invalid") + } + + cmd := exec.Command((*this)[0], (*this)[1:]...) + cmd.Dir = dir + cmd.Stderr = os.Stderr + cmd.Stdout = os.Stdout + + if flags&optVerbose == optVerbose { + log.Printf("executing command %s", strings.Join(*this, " ")) + } + + return cmd.Run() +} diff --git a/config.go b/config.go index fb6ffcb..8de9bf7 100644 --- a/config.go +++ b/config.go @@ -28,11 +28,11 @@ type config struct { Tasks map[string]task } -func (this *config) install(srcDir, dstDir, taskName string, flags int) error { +func (this *config) process(srcDir, dstDir, taskName string, flags int) error { task, ok := this.Tasks[taskName] if !ok { - return fmt.Errorf("Task not found: '%s'", taskName) + return fmt.Errorf("task not found %s", taskName) } - return task.install(srcDir, dstDir, this, flags) + return task.process(srcDir, dstDir, this, flags) } diff --git a/homemaker.go b/homemaker.go index cd8268b..b671689 100644 --- a/homemaker.go +++ b/homemaker.go @@ -63,7 +63,7 @@ func parse(filename string) (*config, error) { return nil, err } default: - return nil, fmt.Errorf("Unsupported configuration file format") + return nil, fmt.Errorf("unsupported configuration file format") } return conf, nil @@ -116,7 +116,7 @@ func main() { log.Fatal(err) } - if err := conf.install(makeAbsPath(flag.Arg(1)), makeAbsPath(*dstDir), *taskName, flags); err != nil { + if err := conf.process(makeAbsPath(flag.Arg(1)), makeAbsPath(*dstDir), *taskName, flags); err != nil { log.Fatal(err) } } else { diff --git a/link.go b/link.go index 47aba12..5341a31 100644 --- a/link.go +++ b/link.go @@ -29,27 +29,25 @@ import ( "path" ) -func cleanPath(loc string, flags int) error { - verbose := flags&optVerbose == optVerbose +type link []string +func cleanPath(loc string, flags int) error { if info, _ := os.Lstat(loc); info != nil { if info.Mode()&os.ModeSymlink == os.ModeSymlink { - if verbose { - log.Printf("Removing symlink: '%s'", loc) + if flags&optVerbose == optVerbose { + log.Printf("removing symlink %s", loc) } if err := os.Remove(loc); err != nil { return err } } else { if flags&optClobber == optClobber { - if verbose { - log.Print("Clobbering path: '%s'", loc) + if flags&optVerbose == optVerbose { + log.Printf("clobbering path %s", loc) } if err := os.RemoveAll(loc); err != nil { return err } - } else { - return fmt.Errorf("Cannot create link; target already exists: '%s'", loc) } } } @@ -58,18 +56,15 @@ func cleanPath(loc string, flags int) error { } func createPath(loc string, flags int) error { - if flags&optForce == 0 { - return nil - } - - parentDir, _ := path.Split(loc) - - if _, err := os.Stat(parentDir); os.IsNotExist(err) { - if flags&optVerbose == optVerbose { - log.Printf("Force creating path: '%s'", parentDir) - } - if err := os.MkdirAll(parentDir, 0777); err != nil { - return err + if flags&optForce == optForce { + parentDir, _ := path.Split(loc) + if _, err := os.Stat(parentDir); os.IsNotExist(err) { + if flags&optVerbose == optVerbose { + log.Printf("force creating path %s", parentDir) + } + if err := os.MkdirAll(parentDir, 0777); err != nil { + return err + } } } @@ -97,16 +92,16 @@ func (this *link) valid() bool { return length >= 1 && length <= 2 } -func (this *link) install(srcDir, dstDir string, flags int) error { +func (this *link) process(srcDir, dstDir string, flags int) error { if !this.valid() { - return fmt.Errorf("Link element is invalid") + return fmt.Errorf("link element is invalid") } srcPath := path.Join(srcDir, this.source()) dstPath := path.Join(dstDir, this.destination()) if _, err := os.Stat(srcPath); os.IsNotExist(err) { - return fmt.Errorf("Source path does not exist in filesystem: '%s'", srcPath) + return fmt.Errorf("source path %s does not exist in filesystem", srcPath) } if err := createPath(dstPath, flags); err != nil { @@ -118,7 +113,7 @@ func (this *link) install(srcDir, dstDir string, flags int) error { } if flags&optVerbose == optVerbose { - log.Printf("Linking: '%s' to '%s'", srcPath, dstPath) + log.Printf("linking %s to %s", srcPath, dstPath) } return os.Symlink(srcPath, dstPath) diff --git a/task.go b/task.go index aef78ce..bf03b13 100644 --- a/task.go +++ b/task.go @@ -24,27 +24,33 @@ package main import "fmt" -type link []string - type task struct { - Deps []string - Links []link + Deps []string + Links []link + Commands []command } -func (this *task) install(srcDir, dstDir string, conf *config, flags int) error { +func (this *task) process(srcDir, dstDir string, conf *config, flags int) error { for _, depName := range this.Deps { depTask, ok := conf.Tasks[depName] if !ok { - return fmt.Errorf("Task dependency not found: '%s'", depName) + return fmt.Errorf("task dependency not found %s", depName) } - if err := depTask.install(srcDir, dstDir, conf, flags); err != nil { + if err := depTask.process(srcDir, dstDir, conf, flags); err != nil { return err } } for _, currLink := range this.Links { - if err := currLink.install(srcDir, dstDir, flags); err != nil { + if err := currLink.process(srcDir, dstDir, flags); err != nil { + return err + } + } + + fmt.Print(this.Commands) + for _, currCmd := range this.Commands { + if err := currCmd.process(dstDir, flags); err != nil { return err } }