package buildfile import ( "bufio" "errors" "fmt" "github.com/xdrm-brackets/nix-amer/internal/clifmt" "github.com/xdrm-brackets/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 }