nix-amer/internal/buildfile/reader.go

108 lines
2.5 KiB
Go

package buildfile
import (
"bufio"
"errors"
"fmt"
"git.xdrm.io/go/nix-amer/internal/clifmt"
"git.xdrm.io/go/nix-amer/internal/instruction"
"io"
"strings"
"time"
)
// ErrNullContext is raised when the given context is nil
var ErrNullContext = errors.New("null context")
// Reader is the buildfile reader
type Reader struct {
// Context is the linux distribution-specified execution context (package manager, service manager, etc)
Context *instruction.ExecutionContext
// Content is the instruction list
Content []instruction.T
}
// NewReader creates a new reader for the specified build file and linux distribution
func NewReader(ctx *instruction.ExecutionContext, buildfile io.Reader) (*Reader, error) {
// fail on null context
if ctx == nil {
return nil, ErrNullContext
}
r := &Reader{
Context: ctx,
Content: make([]instruction.T, 0),
}
// add each line as instruction
l, reader := 0, bufio.NewReader(buildfile)
for {
l++
// read line until end
line, err := reader.ReadString('\n')
if err == io.EOF {
break
} else if err != nil {
return nil, LineError{l, err}
}
line = strings.Trim(line, " \t\r\n")
// ignore newline & comments
if len(line) < 1 || strings.ContainsAny(line[0:1], "[#;") {
continue
}
// turn into instruction
inst, err := instruction.Parse(line)
if err != nil {
return nil, LineError{l, err}
}
// add to list
r.Content = append(r.Content, inst)
}
return r, nil
}
// Execute the current buildfile instruction by instruction
func (r *Reader) Execute() error {
// 1. update package list
// err := r.Context.PackageManager.Fetch()
// if err != nil {
// return fmt.Errorf("cannot fetch packages | %s", err)
// }
// // 2. upgrade packages
// err = r.Context.PackageManager.Upgrade()
// if err != nil {
// return fmt.Errorf("cannot upgrade | %s", err)
// }
// 3. exec each instruction
for i, inst := range r.Content {
clifmt.Align(fmt.Sprintf("(%d) %s", i, clifmt.Color(0, inst.Raw())))
fmt.Printf("%s", clifmt.Color(33, "processing"))
start := time.Now()
_, err := inst.Exec(*r.Context)
if err != nil {
fmt.Printf("\r")
clifmt.Align(fmt.Sprintf("(%d) %s", i, clifmt.Color(0, inst.Raw())))
fmt.Printf("%s \n", clifmt.Color(31, err.Error()))
continue
} else {
fmt.Printf("\r")
clifmt.Align(fmt.Sprintf("(%d) %s", i, clifmt.Color(34, inst.Raw())))
fmt.Printf("%ss \n", clifmt.Color(32, fmt.Sprintf("%.2f", time.Now().Sub(start).Seconds())))
}
}
return nil
}