2018-11-08 12:41:07 +00:00
|
|
|
package instruction
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
2018-11-13 12:10:55 +00:00
|
|
|
"github.com/xdrm-brackets/nix-amer/internal/cnf"
|
2018-11-10 18:04:16 +00:00
|
|
|
"os"
|
2018-11-08 12:41:07 +00:00
|
|
|
"strings"
|
|
|
|
)
|
|
|
|
|
2018-11-11 18:01:00 +00:00
|
|
|
// ErrCannotSet is raised when there is an error trying to update
|
|
|
|
// a field
|
|
|
|
var ErrCannotSet = fmt.Errorf("cannot set the field")
|
2018-11-10 18:04:16 +00:00
|
|
|
|
2018-11-12 21:54:37 +00:00
|
|
|
type set struct {
|
2018-11-10 12:20:10 +00:00
|
|
|
raw string
|
2018-11-08 12:41:07 +00:00
|
|
|
// File is the path to the file
|
|
|
|
File string
|
|
|
|
// Path is the configuration field path
|
2018-11-10 18:04:16 +00:00
|
|
|
Path string
|
2018-11-08 12:41:07 +00:00
|
|
|
// Value if the value to add or update
|
|
|
|
Value string
|
2018-11-10 11:37:31 +00:00
|
|
|
// Format is the configuration format in use
|
|
|
|
Format *cnf.ConfigurationFormat
|
2018-11-08 12:41:07 +00:00
|
|
|
}
|
|
|
|
|
2018-11-12 22:38:37 +00:00
|
|
|
func (d *set) Raw() string { return strings.Join([]string{"set", d.raw}, " ") }
|
2018-11-10 12:20:10 +00:00
|
|
|
|
2018-11-12 21:54:37 +00:00
|
|
|
func (d *set) Build(_args string) error {
|
2018-11-08 12:41:07 +00:00
|
|
|
|
|
|
|
// 1. extract action (sub command)
|
2018-11-10 11:37:31 +00:00
|
|
|
split := strings.Fields(_args)
|
2018-11-08 12:41:07 +00:00
|
|
|
|
|
|
|
// 2. check path
|
|
|
|
if len(split) < 2 {
|
|
|
|
return fmt.Errorf("missing configuration path")
|
|
|
|
}
|
2018-11-10 11:37:31 +00:00
|
|
|
path := split[0]
|
|
|
|
value := strings.Join(split[1:], "")
|
2018-11-08 12:41:07 +00:00
|
|
|
|
|
|
|
// 3. check path separator
|
2018-11-10 11:37:31 +00:00
|
|
|
splitPath := strings.Split(path, "@")
|
2018-11-08 12:41:07 +00:00
|
|
|
if len(splitPath) > 2 {
|
|
|
|
return fmt.Errorf("invalid path (additional '@'?)")
|
|
|
|
}
|
|
|
|
|
|
|
|
d.File = splitPath[0]
|
|
|
|
if len(splitPath) > 1 { // add field path only if set
|
2018-11-10 18:04:16 +00:00
|
|
|
d.Path = splitPath[1]
|
2018-11-08 12:41:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// add value
|
2018-11-10 11:37:31 +00:00
|
|
|
d.Value = value
|
2018-11-10 12:20:10 +00:00
|
|
|
d.raw = _args
|
2018-11-08 12:41:07 +00:00
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2018-11-12 21:54:37 +00:00
|
|
|
func (d set) Exec(ctx ExecutionContext) ([]byte, error) {
|
2018-11-08 12:41:07 +00:00
|
|
|
|
2018-11-12 23:41:42 +00:00
|
|
|
// 1. get file / alias
|
|
|
|
path := d.File
|
|
|
|
if !strings.Contains(path, "/") {
|
|
|
|
if p, exists := ctx.Alias[path]; exists {
|
|
|
|
path = p
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// 2. fail if file not found
|
|
|
|
if _, err := os.Stat(path); os.IsNotExist(err) {
|
|
|
|
return nil, fmt.Errorf("cannot find file '%s'", path)
|
|
|
|
}
|
|
|
|
|
|
|
|
// 3. try to load format
|
|
|
|
format, err := cnf.Load(path)
|
2018-11-10 18:04:16 +00:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2018-11-12 23:41:42 +00:00
|
|
|
// 4. try to update value
|
2018-11-10 18:04:16 +00:00
|
|
|
if !format.Set(d.Path, d.Value) {
|
2018-11-11 18:01:00 +00:00
|
|
|
return nil, ErrCannotSet
|
2018-11-10 18:04:16 +00:00
|
|
|
}
|
|
|
|
|
2018-11-12 23:41:42 +00:00
|
|
|
// 5. Update file
|
|
|
|
file, err := os.OpenFile(path, os.O_WRONLY, 0)
|
2018-11-10 18:04:16 +00:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
defer file.Close()
|
2018-11-11 00:05:14 +00:00
|
|
|
if _, err = format.WriteTo(file); err != nil {
|
2018-11-10 18:04:16 +00:00
|
|
|
return nil, err
|
|
|
|
}
|
2018-11-10 16:33:27 +00:00
|
|
|
|
2018-11-08 12:41:07 +00:00
|
|
|
return nil, nil
|
|
|
|
|
|
|
|
}
|