(conf []byte)
| 915 | var trailerRegexp = regexp.MustCompile("# REPL Bindings:") |
| 916 | |
| 917 | func (e *Evaluator) parseYAMLConfig(conf []byte) (string, error) { |
| 918 | yamlSrc := conf |
| 919 | var replSrc []byte |
| 920 | |
| 921 | pos := trailerRegexp.FindIndex(conf) |
| 922 | if len(pos) == 2 { |
| 923 | yamlSrc = conf[0:pos[0]] |
| 924 | replSrc = conf[pos[1]:] |
| 925 | } |
| 926 | |
| 927 | var c env.Config |
| 928 | if err := yaml.Unmarshal(yamlSrc, &c); err != nil { |
| 929 | return "", fmt.Errorf("configure (yaml): %w", err) |
| 930 | } |
| 931 | |
| 932 | s := string(replSrc) |
| 933 | |
| 934 | lines := strings.Split(s, "\n") |
| 935 | |
| 936 | // A little unfortunate, but we need to apply option commands manually |
| 937 | // before the yaml environment. This is mainly because the yaml doesn't |
| 938 | // describe how to lookup extension types (e.g. load_descriptors). |
| 939 | updated, _ := NewEvaluator() |
| 940 | |
| 941 | var cmds []Cmder |
| 942 | var sb strings.Builder |
| 943 | for _, line := range lines { |
| 944 | if !strings.HasPrefix(line, "# ") { |
| 945 | continue |
| 946 | } |
| 947 | norm := strings.TrimPrefix(line, "# ") |
| 948 | if strings.HasSuffix(norm, "\\") { |
| 949 | norm = strings.TrimSuffix(norm, "\\") |
| 950 | sb.WriteString(norm) |
| 951 | sb.WriteString("\n") |
| 952 | continue |
| 953 | } |
| 954 | sb.WriteString(norm) |
| 955 | cmd := sb.String() |
| 956 | sb.Reset() |
| 957 | pCmd, err := Parse(cmd) |
| 958 | if err != nil { |
| 959 | return "", fmt.Errorf("configure: invalid REPL command: %w", err) |
| 960 | } |
| 961 | switch pCmd.(type) { |
| 962 | case *letFnCmd, *letVarCmd: |
| 963 | cmds = append(cmds, pCmd) |
| 964 | continue |
| 965 | } |
| 966 | _, exit, err := updated.Process(pCmd) |
| 967 | |
| 968 | if exit { |
| 969 | return "", errors.New("configure: config triggered an exit") |
| 970 | } |
| 971 | if err != nil { |
| 972 | return "", fmt.Errorf("configure: failed to process option %w", err) |
| 973 | } |
| 974 | } |
no test coverage detected