| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105 |
- package lintcmd
- import (
- "bufio"
- "errors"
- "fmt"
- "io"
- "strings"
- "unicode"
- )
- type parseBuildConfigError struct {
- line int
- err error
- }
- func (err parseBuildConfigError) Error() string { return err.err.Error() }
- func parseBuildConfigs(r io.Reader) ([]BuildConfig, error) {
- var builds []BuildConfig
- br := bufio.NewReader(r)
- i := 0
- for {
- line, err := br.ReadString('\n')
- if err != nil {
- if err == io.EOF {
- break
- } else {
- return nil, err
- }
- }
- line = strings.TrimSpace(line)
- if line == "" {
- continue
- }
- name, envs, flags, err := parseBuildConfig(line)
- if err != nil {
- return nil, parseBuildConfigError{line: i + 1, err: err}
- }
- bc := BuildConfig{
- Name: name,
- Envs: envs,
- Flags: flags,
- }
- builds = append(builds, bc)
- i++
- }
- return builds, nil
- }
- func parseBuildConfig(line string) (name string, envs []string, flags []string, err error) {
- if line == "" {
- return "", nil, nil, errors.New("couldn't parse empty build config")
- }
- if strings.Index(line, ":") == len(line)-1 {
- name = line[:len(line)-1]
- } else {
- idx := strings.Index(line, ": ")
- if idx == -1 {
- return name, envs, flags, errors.New("missing build name")
- }
- name = line[:idx]
- var buf []rune
- var inQuote bool
- args := &envs
- for _, r := range strings.TrimSpace(line[idx+2:]) {
- switch r {
- case ' ':
- if inQuote {
- buf = append(buf, r)
- } else if len(buf) != 0 {
- if buf[0] == '-' {
- args = &flags
- }
- *args = append(*args, string(buf))
- buf = buf[:0]
- }
- case '"':
- inQuote = !inQuote
- default:
- buf = append(buf, r)
- }
- }
- if len(buf) > 0 {
- if inQuote {
- return "", nil, nil, errors.New("unterminated quoted string")
- }
- if buf[0] == '-' {
- args = &flags
- }
- *args = append(*args, string(buf))
- }
- }
- for _, r := range name {
- if !(r == '_' || unicode.IsLetter(r) || unicode.IsNumber(r)) {
- return "", nil, nil, fmt.Errorf("invalid build name %q", name)
- }
- }
- return name, envs, flags, nil
- }
|