src

Go monorepo.
git clone git://code.dwrz.net/src
Log | Files | Refs

config.go (2014B)


      1 package lintcmd
      2 
      3 import (
      4 	"bufio"
      5 	"errors"
      6 	"fmt"
      7 	"io"
      8 	"strings"
      9 	"unicode"
     10 )
     11 
     12 type parseBuildConfigError struct {
     13 	line int
     14 	err  error
     15 }
     16 
     17 func (err parseBuildConfigError) Error() string { return err.err.Error() }
     18 
     19 func parseBuildConfigs(r io.Reader) ([]buildConfig, error) {
     20 	var builds []buildConfig
     21 	br := bufio.NewReader(r)
     22 	i := 0
     23 	for {
     24 		line, err := br.ReadString('\n')
     25 		if err != nil {
     26 			if err == io.EOF {
     27 				break
     28 			} else {
     29 				return nil, err
     30 			}
     31 		}
     32 		line = strings.TrimSpace(line)
     33 		if line == "" {
     34 			continue
     35 		}
     36 		name, envs, flags, err := parseBuildConfig(line)
     37 		if err != nil {
     38 			return nil, parseBuildConfigError{line: i + 1, err: err}
     39 		}
     40 
     41 		bc := buildConfig{
     42 			Name:  name,
     43 			Envs:  envs,
     44 			Flags: flags,
     45 		}
     46 		builds = append(builds, bc)
     47 
     48 		i++
     49 	}
     50 	return builds, nil
     51 }
     52 
     53 func parseBuildConfig(line string) (name string, envs []string, flags []string, err error) {
     54 	if line == "" {
     55 		return "", nil, nil, errors.New("couldn't parse empty build config")
     56 	}
     57 	if strings.Index(line, ":") == len(line)-1 {
     58 		name = line[:len(line)-1]
     59 	} else {
     60 		before, after, ok := strings.Cut(line, ": ")
     61 		if !ok {
     62 			return name, envs, flags, errors.New("missing build name")
     63 		}
     64 		name = before
     65 
     66 		var buf []rune
     67 		var inQuote bool
     68 		args := &envs
     69 		for _, r := range strings.TrimSpace(after) {
     70 			switch r {
     71 			case ' ':
     72 				if inQuote {
     73 					buf = append(buf, r)
     74 				} else if len(buf) != 0 {
     75 					if buf[0] == '-' {
     76 						args = &flags
     77 					}
     78 					*args = append(*args, string(buf))
     79 					buf = buf[:0]
     80 				}
     81 			case '"':
     82 				inQuote = !inQuote
     83 			default:
     84 				buf = append(buf, r)
     85 			}
     86 		}
     87 
     88 		if len(buf) > 0 {
     89 			if inQuote {
     90 				return "", nil, nil, errors.New("unterminated quoted string")
     91 			}
     92 			if buf[0] == '-' {
     93 				args = &flags
     94 			}
     95 			*args = append(*args, string(buf))
     96 		}
     97 	}
     98 
     99 	for _, r := range name {
    100 		if !(r == '_' || unicode.IsLetter(r) || unicode.IsNumber(r)) {
    101 			return "", nil, nil, fmt.Errorf("invalid build name %q", name)
    102 		}
    103 	}
    104 	return name, envs, flags, nil
    105 }