diff --git a/internal/buildfile/errors.go b/internal/buildfile/errors.go index d00ffdb..d09374a 100644 --- a/internal/buildfile/errors.go +++ b/internal/buildfile/errors.go @@ -1,9 +1,13 @@ package buildfile import ( + "errors" "fmt" ) +var ErrInvalidSyntax = errors.New("invalid instruction format") +var ErrUnknownInstruction = errors.New("unknown instruction") + type LineError struct { Line int Err error diff --git a/internal/buildfile/instruction.go b/internal/buildfile/instruction.go new file mode 100644 index 0000000..46b1d68 --- /dev/null +++ b/internal/buildfile/instruction.go @@ -0,0 +1,63 @@ +package buildfile + +import ( + "strings" +) + +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 +} + +// createInstruction from a raw line +func createInstruction(raw string) (*instruction, error) { + + // 1. fail if invalid base syntax 'cmd args...' + // where command is 3 letters + if len(raw) < 5 || len(strings.Trim(raw[0:3], " ")) < 3 || raw[1] == ' ' || raw[3] != ' ' { + return nil, ErrInvalidSyntax + } + + // 2. prepare instruction + inst := &instruction{ + Type: INSTALL, + Sub: make([]string, 0), + Args: raw[4:], + } + + // 3. Extract instruction type + switch raw[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, ErrUnknownInstruction + } + + return inst, nil +} diff --git a/internal/buildfile/reader.go b/internal/buildfile/reader.go index c6f4047..828bba5 100644 --- a/internal/buildfile/reader.go +++ b/internal/buildfile/reader.go @@ -2,37 +2,10 @@ 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 @@ -61,33 +34,11 @@ func NewReader(distro string, buildfile io.Reader) (*Reader, error) { } 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} + // get and add instruction to list + inst, err := createInstruction(line) + if err != nil { + return nil, LineError{l, err} } - - // 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) }