97 lines
1.9 KiB
Go
97 lines
1.9 KiB
Go
|
package buildfile
|
||
|
|
||
|
import (
|
||
|
"bufio"
|
||
|
"errors"
|
||
|
"io"
|
||
|
"strings"
|
||
|
)
|
||
|
|
||
|
var ErrInvalidSyntax = errors.New("invalid instruction format")
|
||
|
var ErrUnknownInstruction = errors.New("unknown instruction")
|
||
|
|
||
|
type instruction_type byte
|
||
|
|
||
|
const (
|
||
|
// INSTALL one or more package(s)
|
||
|
INSTALL instruction_type = iota
|
||
|
// UPDATE all installed packages candidates
|
||
|
UPDATE
|
||
|
// REMOVE one or more package(s)
|
||
|
REMOVE
|
||
|
// SERVICE management (enable, disable, start, stop, restart, reload)
|
||
|
SERVICE
|
||
|
// CONF edits configuration files
|
||
|
CONF
|
||
|
)
|
||
|
|
||
|
// instruction is self-explanatory
|
||
|
type instruction struct {
|
||
|
Type instruction_type
|
||
|
// Sub command instruction-type-specific
|
||
|
Sub []string
|
||
|
Args string
|
||
|
}
|
||
|
|
||
|
// Reader is the buildfile reader
|
||
|
type Reader struct {
|
||
|
// linux distribution to run on
|
||
|
distribution string
|
||
|
Content []*instruction
|
||
|
}
|
||
|
|
||
|
// NewReader creates a new reader for the specified build file and linux distribution
|
||
|
func NewReader(distro string, buildfile io.Reader) (*Reader, error) {
|
||
|
|
||
|
r := &Reader{
|
||
|
distribution: distro,
|
||
|
Content: make([]*instruction, 0),
|
||
|
}
|
||
|
|
||
|
// read each line
|
||
|
l, reader := 0, bufio.NewReader(buildfile)
|
||
|
for {
|
||
|
l++
|
||
|
|
||
|
line, err := reader.ReadString('\n')
|
||
|
if err == io.EOF {
|
||
|
break
|
||
|
} else if err != nil {
|
||
|
return nil, LineError{l, err}
|
||
|
}
|
||
|
line = strings.Trim(line, " \t\n")
|
||
|
|
||
|
// check line base syntax 'cmd args...'
|
||
|
if len(line) < 5 || len(strings.Trim(line[0:3], " ")) < 3 || line[1] == ' ' || line[3] != ' ' {
|
||
|
return nil, LineError{l, ErrInvalidSyntax}
|
||
|
}
|
||
|
|
||
|
// build instruction from line
|
||
|
inst := &instruction{
|
||
|
Type: INSTALL,
|
||
|
Sub: make([]string, 0),
|
||
|
Args: line[4:],
|
||
|
}
|
||
|
|
||
|
switch line[0:3] {
|
||
|
case "ins":
|
||
|
inst.Type = INSTALL
|
||
|
case "upd":
|
||
|
inst.Type = UPDATE
|
||
|
case "del":
|
||
|
inst.Type = REMOVE
|
||
|
case "ser":
|
||
|
inst.Type = SERVICE
|
||
|
case "cnf":
|
||
|
inst.Type = CONF
|
||
|
default:
|
||
|
return nil, LineError{l, ErrUnknownInstruction}
|
||
|
}
|
||
|
|
||
|
r.Content = append(r.Content, inst)
|
||
|
|
||
|
}
|
||
|
|
||
|
return r, nil
|
||
|
}
|