package instruction import ( "fmt" "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) split := strings.Split(_args, " ") // 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) { return nil, fmt.Errorf("cannot find script '%s'", d.Src) } // 2. execute script if err := ctx.Executor.Command("cp", d.Src, d.Dst).Run(); err != nil { return nil, fmt.Errorf("cannot copy '%s' to '%s' | %s", d.Src, d.Dst, err) } return nil, nil } func (d copy) DryRun(ctx ExecutionContext) ([]byte, error) { // 1. fail if source file not found if _, err := os.Stat(d.Src); os.IsNotExist(err) { return nil, fmt.Errorf("cannot find file '%s'", d.Src) } // 2. if destination to create : try to create (then remove) if _, err := os.Stat(d.Dst); os.IsNotExist(err) { file, err2 := os.OpenFile(d.Dst, os.O_APPEND|os.O_WRONLY|os.O_CREATE, os.FileMode(0777)) if err2 != nil { return nil, fmt.Errorf("cannot copy to '%s' | %s", d.Dst, err2) } file.Close() if err2 := os.Remove(d.Dst); err2 != nil { return nil, fmt.Errorf("cannot remove dry-run file '%s' | %s", d.Dst, err2) } return nil, nil } // 3. if destination exists : check write permission file, err := os.OpenFile(d.Dst, os.O_APPEND|os.O_WRONLY, 0600) if err != nil { return nil, fmt.Errorf("cannot copy to '%s' | %s", d.Dst, err) } file.Close() return nil, nil }