2018-11-13 13:21:36 +00:00
|
|
|
package instruction
|
|
|
|
|
|
|
|
import (
|
|
|
|
"os"
|
|
|
|
"strings"
|
|
|
|
)
|
|
|
|
|
|
|
|
type copy struct {
|
|
|
|
raw string
|
|
|
|
Src string
|
|
|
|
Dst string
|
|
|
|
}
|
|
|
|
|
|
|
|
func (d *copy) Raw() string { return strings.Join([]string{"copy", d.raw}, " ") }
|
|
|
|
|
|
|
|
func (d *copy) Build(_args string) error {
|
|
|
|
|
|
|
|
// 1. extract action (sub command)
|
2018-11-14 21:10:31 +00:00
|
|
|
split := strings.Fields(_args)
|
2018-11-13 13:21:36 +00:00
|
|
|
|
|
|
|
// 2. check syntax
|
|
|
|
if len(split) != 2 {
|
|
|
|
return ErrInvalidSyntax
|
|
|
|
}
|
|
|
|
|
|
|
|
d.Src = strings.Trim(split[0], " \t")
|
|
|
|
d.Dst = strings.Trim(split[1], " \t")
|
|
|
|
d.raw = _args
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (d copy) Exec(ctx ExecutionContext) ([]byte, error) {
|
|
|
|
|
|
|
|
// 1. fail if source file not found
|
|
|
|
if _, err := os.Stat(d.Src); os.IsNotExist(err) {
|
2018-11-14 21:10:31 +00:00
|
|
|
return nil, &FileError{"cannot find file", d.Src, err}
|
2018-11-13 13:21:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// 2. execute script
|
2018-11-14 21:10:31 +00:00
|
|
|
if err := ctx.Executor.Command("cp", "-r", d.Src, d.Dst).Run(); err != nil {
|
|
|
|
return nil, &FileError{"cannot copy to", d.Dst, err}
|
2018-11-13 13:21:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return nil, nil
|
|
|
|
|
|
|
|
}
|
2018-11-14 19:11:07 +00:00
|
|
|
|
|
|
|
func (d copy) DryRun(ctx ExecutionContext) ([]byte, error) {
|
|
|
|
|
|
|
|
// 1. fail if source file not found
|
|
|
|
if _, err := os.Stat(d.Src); os.IsNotExist(err) {
|
2018-11-14 21:10:31 +00:00
|
|
|
return nil, &FileError{"cannot find file", d.Src, err}
|
2018-11-14 19:11:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// 2. if destination to create : try to create (then remove)
|
2018-11-14 21:10:31 +00:00
|
|
|
fi, err := os.Stat(d.Dst)
|
|
|
|
if os.IsNotExist(err) {
|
2018-11-14 19:11:07 +00:00
|
|
|
|
2018-11-14 19:21:34 +00:00
|
|
|
file, err2 := os.OpenFile(d.Dst, os.O_APPEND|os.O_WRONLY|os.O_CREATE, os.FileMode(0777))
|
|
|
|
if err2 != nil {
|
2018-11-14 21:10:31 +00:00
|
|
|
return nil, &FileError{"cannot copy to", d.Dst, err2}
|
2018-11-14 19:11:07 +00:00
|
|
|
}
|
|
|
|
file.Close()
|
|
|
|
|
2018-11-14 19:21:34 +00:00
|
|
|
if err2 := os.Remove(d.Dst); err2 != nil {
|
2018-11-14 21:10:31 +00:00
|
|
|
return nil, &FileError{"cannot remove dry-run file", d.Dst, err2}
|
2018-11-14 19:11:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return nil, nil
|
|
|
|
|
2018-11-14 21:10:31 +00:00
|
|
|
} else if fi != nil && fi.IsDir() {
|
|
|
|
return nil, nil // no error if dir
|
2018-11-14 19:11:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// 3. if destination exists : check write permission
|
|
|
|
file, err := os.OpenFile(d.Dst, os.O_APPEND|os.O_WRONLY, 0600)
|
|
|
|
if err != nil {
|
2018-11-14 21:10:31 +00:00
|
|
|
return nil, &FileError{"cannot copy to", d.Dst, err}
|
2018-11-14 19:11:07 +00:00
|
|
|
}
|
|
|
|
file.Close()
|
|
|
|
|
|
|
|
return nil, nil
|
|
|
|
|
|
|
|
}
|