sync: Replace []error by go.uber.org/multierr
This commit is contained in:
parent
9f49a689fd
commit
b6966d47ce
25 changed files with 380 additions and 348 deletions
|
|
@ -11,6 +11,7 @@ import (
|
|||
"unicode"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"go.uber.org/multierr"
|
||||
|
||||
"srs.epita.fr/fic-server/libfic"
|
||||
)
|
||||
|
|
@ -35,11 +36,11 @@ func validatorRegexp(vre string) (validator_regexp *string) {
|
|||
return
|
||||
}
|
||||
|
||||
func getRawKey(input interface{}, validatorRe string, ordered bool, showLines bool, separator string) (raw string, prep string, errs []error) {
|
||||
func getRawKey(input interface{}, validatorRe string, ordered bool, showLines bool, separator string) (raw string, prep string, errs error) {
|
||||
// Concatenate array
|
||||
if f, ok := input.([]interface{}); ok {
|
||||
if len(validatorRe) > 0 {
|
||||
errs = append(errs, fmt.Errorf("ValidatorRe cannot be defined for this kind of flag."))
|
||||
errs = multierr.Append(errs, fmt.Errorf("ValidatorRe cannot be defined for this kind of flag."))
|
||||
validatorRe = ""
|
||||
}
|
||||
|
||||
|
|
@ -47,20 +48,20 @@ func getRawKey(input interface{}, validatorRe string, ordered bool, showLines bo
|
|||
separator = ","
|
||||
} else if len(separator) > 1 {
|
||||
separator = string(separator[0])
|
||||
errs = append(errs, fmt.Errorf("separator truncated to %q", separator))
|
||||
errs = multierr.Append(errs, fmt.Errorf("separator truncated to %q", separator))
|
||||
}
|
||||
|
||||
var fitems []string
|
||||
for i, v := range f {
|
||||
if g, ok := v.(string); ok {
|
||||
if strings.Index(g, separator) != -1 {
|
||||
errs = append(errs, fmt.Errorf("flag items cannot contain %q character as it is used as separator. Change the separator attribute for this flag.", separator))
|
||||
errs = multierr.Append(errs, fmt.Errorf("flag items cannot contain %q character as it is used as separator. Change the separator attribute for this flag.", separator))
|
||||
return
|
||||
} else {
|
||||
fitems = append(fitems, g)
|
||||
}
|
||||
} else {
|
||||
errs = append(errs, fmt.Errorf("item %d has an invalid type: can only be string, is %T.", i, g))
|
||||
errs = multierr.Append(errs, fmt.Errorf("item %d has an invalid type: can only be string, is %T.", i, g))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
|
@ -77,7 +78,7 @@ func getRawKey(input interface{}, validatorRe string, ordered bool, showLines bo
|
|||
nbLines := 0
|
||||
if showLines {
|
||||
if len(fitems) > 9 {
|
||||
errs = append(errs, fmt.Errorf("too much items in vector to use ShowLines features, max 9."))
|
||||
errs = multierr.Append(errs, fmt.Errorf("too much items in vector to use ShowLines features, max 9."))
|
||||
} else {
|
||||
nbLines = len(fitems)
|
||||
}
|
||||
|
|
@ -91,7 +92,7 @@ func getRawKey(input interface{}, validatorRe string, ordered bool, showLines bo
|
|||
} else if f, ok := input.(float64); ok {
|
||||
raw = strconv.FormatFloat(f, 'f', -1, 64)
|
||||
} else if f, ok := input.(string); !ok {
|
||||
errs = append(errs, fmt.Errorf("has an invalid type: can only be []string or string, not %T", input))
|
||||
errs = multierr.Append(errs, fmt.Errorf("has an invalid type: can only be []string or string, not %T", input))
|
||||
return
|
||||
} else {
|
||||
raw = f
|
||||
|
|
@ -99,21 +100,21 @@ func getRawKey(input interface{}, validatorRe string, ordered bool, showLines bo
|
|||
return
|
||||
}
|
||||
|
||||
func buildLabelFlag(exercice *fic.Exercice, flag ExerciceFlag, flagline int, exceptions *CheckExceptions) (f *fic.FlagLabel, errs []error) {
|
||||
func buildLabelFlag(exercice *fic.Exercice, flag ExerciceFlag, flagline int, exceptions *CheckExceptions) (f *fic.FlagLabel, errs error) {
|
||||
if len(flag.Label) == 0 {
|
||||
errs = append(errs, NewFlagError(exercice, &flag, flagline, fmt.Errorf("Label cannot be empty.")))
|
||||
errs = multierr.Append(errs, NewFlagError(exercice, &flag, flagline, fmt.Errorf("Label cannot be empty.")))
|
||||
return
|
||||
}
|
||||
|
||||
// Call checks hooks
|
||||
for _, h := range hooks.mdTextHooks {
|
||||
for _, err := range h(flag.Label, exercice.Language, exceptions.Filter2ndCol(strconv.Itoa(flagline))) {
|
||||
errs = append(errs, NewFlagError(exercice, &flag, flagline, err))
|
||||
for _, err := range multierr.Errors(h(flag.Label, exercice.Language, exceptions.Filter2ndCol(strconv.Itoa(flagline)))) {
|
||||
errs = multierr.Append(errs, NewFlagError(exercice, &flag, flagline, err))
|
||||
}
|
||||
}
|
||||
|
||||
if mdlabel, err := ProcessMarkdown(GlobalImporter, flag.Label, exercice.Path); err != nil {
|
||||
errs = append(errs, NewFlagError(exercice, &flag, flagline, fmt.Errorf("unable to parse property label as Markdown: %w", err)))
|
||||
errs = multierr.Append(errs, NewFlagError(exercice, &flag, flagline, fmt.Errorf("unable to parse property label as Markdown: %w", err)))
|
||||
} else {
|
||||
if strings.Count(flag.Label, "\n\n") == 0 {
|
||||
flag.Label = mdlabel[3 : len(mdlabel)-4]
|
||||
|
|
@ -123,11 +124,11 @@ func buildLabelFlag(exercice *fic.Exercice, flag ExerciceFlag, flagline int, exc
|
|||
}
|
||||
|
||||
if flag.Raw != nil {
|
||||
errs = append(errs, NewFlagError(exercice, &flag, flagline, fmt.Errorf("raw cannot be defined.")))
|
||||
errs = multierr.Append(errs, NewFlagError(exercice, &flag, flagline, fmt.Errorf("raw cannot be defined.")))
|
||||
}
|
||||
|
||||
if len(flag.Choice) != 0 {
|
||||
errs = append(errs, NewFlagError(exercice, &flag, flagline, fmt.Errorf("choices cannot be defined.")))
|
||||
errs = multierr.Append(errs, NewFlagError(exercice, &flag, flagline, fmt.Errorf("choices cannot be defined.")))
|
||||
}
|
||||
|
||||
f = &fic.FlagLabel{
|
||||
|
|
@ -138,32 +139,33 @@ func buildLabelFlag(exercice *fic.Exercice, flag ExerciceFlag, flagline int, exc
|
|||
|
||||
// Call checks hooks
|
||||
for _, h := range hooks.flagLabelHooks {
|
||||
for _, e := range h(f, exercice, exceptions.Filter2ndCol(strconv.Itoa(flagline))) {
|
||||
errs = append(errs, NewFlagError(exercice, &flag, flagline, e))
|
||||
for _, e := range multierr.Errors(h(f, exercice, exceptions.Filter2ndCol(strconv.Itoa(flagline)))) {
|
||||
errs = multierr.Append(errs, NewFlagError(exercice, &flag, flagline, e))
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func buildKeyFlag(exercice *fic.Exercice, flag ExerciceFlag, flagline int, defaultLabel string, exceptions *CheckExceptions) (f *fic.Flag, choices []*fic.FlagChoice, errs []error) {
|
||||
func buildKeyFlag(exercice *fic.Exercice, flag ExerciceFlag, flagline int, defaultLabel string, exceptions *CheckExceptions) (f *fic.Flag, choices []*fic.FlagChoice, errs error) {
|
||||
if len(flag.Label) == 0 {
|
||||
flag.Label = defaultLabel
|
||||
}
|
||||
|
||||
if len(flag.Variant) != 0 {
|
||||
errs = append(errs, NewFlagError(exercice, &flag, flagline, fmt.Errorf("variant is not defined for this kind of flag.")))
|
||||
errs = multierr.Append(errs, NewFlagError(exercice, &flag, flagline, fmt.Errorf("variant is not defined for this kind of flag.")))
|
||||
}
|
||||
|
||||
if flag.Label[0] == '`' {
|
||||
errs = append(errs, NewFlagError(exercice, &flag, flagline, fmt.Errorf("Label should not begin with `.")))
|
||||
errs = multierr.Append(errs, NewFlagError(exercice, &flag, flagline, fmt.Errorf("Label should not begin with `.")))
|
||||
flag.Label = flag.Label[1:]
|
||||
}
|
||||
|
||||
raw, prep, terrs := getRawKey(flag.Raw, flag.CaptureRe, flag.Ordered, flag.ShowLines, flag.Separator)
|
||||
|
||||
if len(terrs) > 0 {
|
||||
for _, terr := range terrs {
|
||||
errs = append(errs, NewFlagError(exercice, &flag, flagline, terr))
|
||||
errors := multierr.Errors(terrs)
|
||||
if len(errors) > 0 {
|
||||
for _, terr := range errors {
|
||||
errs = multierr.Append(errs, NewFlagError(exercice, &flag, flagline, terr))
|
||||
}
|
||||
f = nil
|
||||
return
|
||||
|
|
@ -171,16 +173,16 @@ func buildKeyFlag(exercice *fic.Exercice, flag ExerciceFlag, flagline int, defau
|
|||
flag.Label = prep + flag.Label
|
||||
|
||||
if len(flag.Label) > 255 && flag.Type != "label" {
|
||||
errs = append(errs, NewFlagError(exercice, &flag, flagline, fmt.Errorf("label is too long (max 255 chars per label).")))
|
||||
errs = multierr.Append(errs, NewFlagError(exercice, &flag, flagline, fmt.Errorf("label is too long (max 255 chars per label).")))
|
||||
}
|
||||
|
||||
if (flag.Type == "text" && !isFullGraphic(strings.Replace(raw, "\n", "", -1))) || (flag.Type != "text" && !isFullGraphic(raw)) {
|
||||
errs = append(errs, NewFlagError(exercice, &flag, flagline, fmt.Errorf("WARNING non-printable characters in flag, is this really expected?")))
|
||||
errs = multierr.Append(errs, NewFlagError(exercice, &flag, flagline, fmt.Errorf("WARNING non-printable characters in flag, is this really expected?")))
|
||||
}
|
||||
|
||||
hashedFlag, err := fic.ComputeHashedFlag([]byte(raw), !flag.CaseSensitive, flag.NoTrim, validatorRegexp(flag.CaptureRe), flag.SortReGroups)
|
||||
if err != nil {
|
||||
errs = append(errs, NewFlagError(exercice, &flag, flagline, err))
|
||||
errs = multierr.Append(errs, NewFlagError(exercice, &flag, flagline, err))
|
||||
return
|
||||
}
|
||||
fk := &fic.FlagKey{
|
||||
|
|
@ -202,8 +204,8 @@ func buildKeyFlag(exercice *fic.Exercice, flag ExerciceFlag, flagline int, defau
|
|||
|
||||
// Call checks hooks
|
||||
for _, h := range hooks.flagKeyHooks {
|
||||
for _, e := range h(fk, raw, exercice, exceptions.Filter2ndCol(strconv.Itoa(flagline))) {
|
||||
errs = append(errs, NewFlagError(exercice, &flag, flagline, e))
|
||||
for _, e := range multierr.Errors(h(fk, raw, exercice, exceptions.Filter2ndCol(strconv.Itoa(flagline)))) {
|
||||
errs = multierr.Append(errs, NewFlagError(exercice, &flag, flagline, e))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -222,9 +224,10 @@ func buildKeyFlag(exercice *fic.Exercice, flag ExerciceFlag, flagline int, defau
|
|||
|
||||
for _, choice := range flag.Choice {
|
||||
val, prep, terrs := getRawKey(choice.Value, "", false, false, "")
|
||||
if len(terrs) > 0 {
|
||||
for _, terr := range terrs {
|
||||
errs = append(errs, NewFlagError(exercice, &flag, flagline, terr))
|
||||
errors := multierr.Errors(terrs)
|
||||
if len(errors) > 0 {
|
||||
for _, terr := range errors {
|
||||
errs = multierr.Append(errs, NewFlagError(exercice, &flag, flagline, terr))
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
|
@ -245,15 +248,15 @@ func buildKeyFlag(exercice *fic.Exercice, flag ExerciceFlag, flagline int, defau
|
|||
|
||||
// Call checks hooks
|
||||
for _, h := range hooks.flagChoiceHooks {
|
||||
for _, e := range h(fc, exercice, exceptions.Filter2ndCol(strconv.Itoa(flagline))) {
|
||||
errs = append(errs, NewFlagError(exercice, &flag, flagline, e))
|
||||
for _, e := range multierr.Errors(h(fc, exercice, exceptions.Filter2ndCol(strconv.Itoa(flagline)))) {
|
||||
errs = multierr.Append(errs, NewFlagError(exercice, &flag, flagline, e))
|
||||
}
|
||||
}
|
||||
|
||||
choices = append(choices, fc)
|
||||
|
||||
if val == "true" || val == "false" {
|
||||
errs = append(errs, NewFlagError(exercice, &flag, flagline, fmt.Errorf("value can't be %q, this is not a MCQ, the value has to be meaningful. The value is shown to players as response identifier.", val)))
|
||||
errs = multierr.Append(errs, NewFlagError(exercice, &flag, flagline, fmt.Errorf("value can't be %q, this is not a MCQ, the value has to be meaningful. The value is shown to players as response identifier.", val)))
|
||||
}
|
||||
|
||||
if val == raw || (!flag.CaseSensitive && val == strings.ToLower(raw)) {
|
||||
|
|
@ -261,13 +264,13 @@ func buildKeyFlag(exercice *fic.Exercice, flag ExerciceFlag, flagline int, defau
|
|||
}
|
||||
}
|
||||
if !hasOne {
|
||||
errs = append(errs, NewFlagError(exercice, &flag, flagline, fmt.Errorf("no valid answer defined.")))
|
||||
errs = multierr.Append(errs, NewFlagError(exercice, &flag, flagline, fmt.Errorf("no valid answer defined.")))
|
||||
}
|
||||
|
||||
// Call checks hooks
|
||||
for _, h := range hooks.flagKeyWithChoicesHooks {
|
||||
for _, e := range h(fk, raw, choices, exercice, exceptions.Filter2ndCol(strconv.Itoa(flagline))) {
|
||||
errs = append(errs, NewFlagError(exercice, &flag, flagline, e))
|
||||
for _, e := range multierr.Errors(h(fk, raw, choices, exercice, exceptions.Filter2ndCol(strconv.Itoa(flagline)))) {
|
||||
errs = multierr.Append(errs, NewFlagError(exercice, &flag, flagline, e))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -297,7 +300,7 @@ func iface2Number(input interface{}, output *string) error {
|
|||
}
|
||||
|
||||
// buildExerciceFlag read challenge.txt and extract all flags.
|
||||
func buildExerciceFlag(i Importer, exercice *fic.Exercice, flag ExerciceFlag, nline int, exceptions *CheckExceptions) (ret []importFlag, errs []error) {
|
||||
func buildExerciceFlag(i Importer, exercice *fic.Exercice, flag ExerciceFlag, nline int, exceptions *CheckExceptions) (ret []importFlag, errs error) {
|
||||
switch strings.ToLower(flag.Type) {
|
||||
case "":
|
||||
flag.Type = "key"
|
||||
|
|
@ -309,17 +312,17 @@ func buildExerciceFlag(i Importer, exercice *fic.Exercice, flag ExerciceFlag, nl
|
|||
var smin, smax, sstep string
|
||||
err := iface2Number(flag.NumberMin, &smin)
|
||||
if err != nil {
|
||||
errs = append(errs, NewFlagError(exercice, &flag, nline+1, fmt.Errorf("min %w", err)))
|
||||
errs = multierr.Append(errs, NewFlagError(exercice, &flag, nline+1, fmt.Errorf("min %w", err)))
|
||||
}
|
||||
|
||||
err = iface2Number(flag.NumberMax, &smax)
|
||||
if err != nil {
|
||||
errs = append(errs, NewFlagError(exercice, &flag, nline+1, fmt.Errorf("max %w", err)))
|
||||
errs = multierr.Append(errs, NewFlagError(exercice, &flag, nline+1, fmt.Errorf("max %w", err)))
|
||||
}
|
||||
|
||||
err = iface2Number(flag.NumberStep, &sstep)
|
||||
if err != nil {
|
||||
errs = append(errs, NewFlagError(exercice, &flag, nline+1, fmt.Errorf("step %w", err)))
|
||||
errs = multierr.Append(errs, NewFlagError(exercice, &flag, nline+1, fmt.Errorf("step %w", err)))
|
||||
}
|
||||
flag.Type = fmt.Sprintf("number,%s,%s,%s", smin, smax, sstep)
|
||||
case "text":
|
||||
|
|
@ -333,23 +336,23 @@ func buildExerciceFlag(i Importer, exercice *fic.Exercice, flag ExerciceFlag, nl
|
|||
case "mcq":
|
||||
flag.Type = "mcq"
|
||||
default:
|
||||
errs = append(errs, NewFlagError(exercice, &flag, nline+1, fmt.Errorf("invalid type of flag: should be 'key', 'number', 'text', 'mcq', 'ucq', 'radio' or 'vector'")))
|
||||
errs = multierr.Append(errs, NewFlagError(exercice, &flag, nline+1, fmt.Errorf("invalid type of flag: should be 'key', 'number', 'text', 'mcq', 'ucq', 'radio' or 'vector'")))
|
||||
return
|
||||
}
|
||||
|
||||
if !strings.HasPrefix(flag.Type, "number") {
|
||||
if flag.NumberMin != nil {
|
||||
errs = append(errs, NewFlagError(exercice, &flag, nline+1, fmt.Errorf("property min undefined for this kind of flag: should the type be 'number'")))
|
||||
errs = multierr.Append(errs, NewFlagError(exercice, &flag, nline+1, fmt.Errorf("property min undefined for this kind of flag: should the type be 'number'")))
|
||||
} else if flag.NumberMax != nil {
|
||||
errs = append(errs, NewFlagError(exercice, &flag, nline+1, fmt.Errorf("property max undefined for this kind of flag: should the type be 'number'")))
|
||||
errs = multierr.Append(errs, NewFlagError(exercice, &flag, nline+1, fmt.Errorf("property max undefined for this kind of flag: should the type be 'number'")))
|
||||
} else if flag.NumberStep != nil {
|
||||
errs = append(errs, NewFlagError(exercice, &flag, nline+1, fmt.Errorf("property step undefined for this kind of flag: should the type be 'number'")))
|
||||
errs = multierr.Append(errs, NewFlagError(exercice, &flag, nline+1, fmt.Errorf("property step undefined for this kind of flag: should the type be 'number'")))
|
||||
}
|
||||
}
|
||||
|
||||
if len(flag.Help) > 0 {
|
||||
if mdhelp, err := ProcessMarkdown(i, flag.Help, exercice.Path); err != nil {
|
||||
errs = append(errs, NewFlagError(exercice, &flag, nline+1, fmt.Errorf("unable to parse property help as Markdown: %w", err)))
|
||||
errs = multierr.Append(errs, NewFlagError(exercice, &flag, nline+1, fmt.Errorf("unable to parse property help as Markdown: %w", err)))
|
||||
} else {
|
||||
flag.Help = mdhelp[3 : len(mdhelp)-4]
|
||||
}
|
||||
|
|
@ -357,7 +360,7 @@ func buildExerciceFlag(i Importer, exercice *fic.Exercice, flag ExerciceFlag, nl
|
|||
|
||||
if flag.Type == "label" {
|
||||
addedFlag, berrs := buildLabelFlag(exercice, flag, nline+1, exceptions)
|
||||
errs = append(errs, berrs...)
|
||||
errs = multierr.Append(errs, berrs)
|
||||
if addedFlag != nil {
|
||||
ret = append(ret, importFlag{
|
||||
Line: nline + 1,
|
||||
|
|
@ -366,7 +369,7 @@ func buildExerciceFlag(i Importer, exercice *fic.Exercice, flag ExerciceFlag, nl
|
|||
}
|
||||
} else if flag.Type == "key" || strings.HasPrefix(flag.Type, "number") || flag.Type == "text" || flag.Type == "ucq" || flag.Type == "radio" || flag.Type == "vector" {
|
||||
addedFlag, choices, berrs := buildKeyFlag(exercice, flag, nline+1, "Flag", exceptions)
|
||||
errs = append(errs, berrs...)
|
||||
errs = multierr.Append(errs, berrs)
|
||||
if addedFlag != nil {
|
||||
ret = append(ret, importFlag{
|
||||
Line: nline + 1,
|
||||
|
|
@ -386,7 +389,7 @@ func buildExerciceFlag(i Importer, exercice *fic.Exercice, flag ExerciceFlag, nl
|
|||
isJustified := false
|
||||
|
||||
if len(flag.Variant) != 0 {
|
||||
errs = append(errs, NewFlagError(exercice, &flag, nline+1, fmt.Errorf("variant is not defined for this kind of flag")))
|
||||
errs = multierr.Append(errs, NewFlagError(exercice, &flag, nline+1, fmt.Errorf("variant is not defined for this kind of flag")))
|
||||
}
|
||||
|
||||
if !flag.NoShuffle {
|
||||
|
|
@ -400,7 +403,7 @@ func buildExerciceFlag(i Importer, exercice *fic.Exercice, flag ExerciceFlag, nl
|
|||
|
||||
if choice.Raw != nil {
|
||||
if hasOne && !isJustified {
|
||||
errs = append(errs, NewFlagError(exercice, &flag, nline+1, fmt.Errorf("all true items has to be justified in this MCQ")))
|
||||
errs = multierr.Append(errs, NewFlagError(exercice, &flag, nline+1, fmt.Errorf("all true items has to be justified in this MCQ")))
|
||||
continue
|
||||
}
|
||||
|
||||
|
|
@ -409,13 +412,13 @@ func buildExerciceFlag(i Importer, exercice *fic.Exercice, flag ExerciceFlag, nl
|
|||
} else if p, ok := choice.Value.(bool); ok {
|
||||
val = p
|
||||
if isJustified {
|
||||
errs = append(errs, NewFlagError(exercice, &flag, nline+1, fmt.Errorf("all true items has to be justified in this MCQ")))
|
||||
errs = multierr.Append(errs, NewFlagError(exercice, &flag, nline+1, fmt.Errorf("all true items has to be justified in this MCQ")))
|
||||
continue
|
||||
}
|
||||
} else if choice.Value == nil {
|
||||
val = false
|
||||
} else {
|
||||
errs = append(errs, NewFlagError(exercice, &flag, nline+1, fmt.Errorf("choice %d: incorrect type for value: %T is not boolean.", cid, choice.Value)))
|
||||
errs = multierr.Append(errs, NewFlagError(exercice, &flag, nline+1, fmt.Errorf("choice %d: incorrect type for value: %T is not boolean.", cid, choice.Value)))
|
||||
continue
|
||||
}
|
||||
|
||||
|
|
@ -427,9 +430,7 @@ func buildExerciceFlag(i Importer, exercice *fic.Exercice, flag ExerciceFlag, nl
|
|||
|
||||
if isJustified && choice.Raw != nil {
|
||||
addedFlag, choices, berrs := buildKeyFlag(exercice, choice.ExerciceFlag, nline+1, "Flag correspondant", exceptions)
|
||||
if len(berrs) > 0 {
|
||||
errs = append(errs, berrs...)
|
||||
}
|
||||
errs = multierr.Append(errs, berrs)
|
||||
if addedFlag != nil {
|
||||
ret = append(ret, importFlag{
|
||||
Line: nline + 1,
|
||||
|
|
@ -443,8 +444,8 @@ func buildExerciceFlag(i Importer, exercice *fic.Exercice, flag ExerciceFlag, nl
|
|||
|
||||
// Call checks hooks
|
||||
for _, h := range hooks.flagMCQHooks {
|
||||
for _, e := range h(&addedFlag, addedFlag.Entries, exercice, exceptions) {
|
||||
errs = append(errs, NewFlagError(exercice, &flag, nline+1, e))
|
||||
for _, e := range multierr.Errors(h(&addedFlag, addedFlag.Entries, exercice, exceptions)) {
|
||||
errs = multierr.Append(errs, NewFlagError(exercice, &flag, nline+1, e))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -457,9 +458,9 @@ func buildExerciceFlag(i Importer, exercice *fic.Exercice, flag ExerciceFlag, nl
|
|||
}
|
||||
|
||||
// buildExerciceFlags read challenge.txt and extract all flags.
|
||||
func buildExerciceFlags(i Importer, exercice *fic.Exercice, exceptions *CheckExceptions) (flags map[int64]importFlag, flagids []int64, errs []error) {
|
||||
func buildExerciceFlags(i Importer, exercice *fic.Exercice, exceptions *CheckExceptions) (flags map[int64]importFlag, flagids []int64, errs error) {
|
||||
params, gerrs := getExerciceParams(i, exercice)
|
||||
if len(gerrs) > 0 {
|
||||
if len(multierr.Errors(gerrs)) > 0 {
|
||||
return flags, flagids, gerrs
|
||||
}
|
||||
|
||||
|
|
@ -473,14 +474,12 @@ func buildExerciceFlags(i Importer, exercice *fic.Exercice, exceptions *CheckExc
|
|||
|
||||
// Ensure flag ID is unique
|
||||
for _, ok := flags[flag.Id]; ok; _, ok = flags[flag.Id] {
|
||||
errs = append(errs, NewFlagError(exercice, ¶ms.Flags[nline], nline+1, fmt.Errorf("identifier already used (%d), using a random one.", flag.Id)))
|
||||
errs = multierr.Append(errs, NewFlagError(exercice, ¶ms.Flags[nline], nline+1, fmt.Errorf("identifier already used (%d), using a random one.", flag.Id)))
|
||||
flag.Id = rand.Int63()
|
||||
}
|
||||
|
||||
newFlags, ferrs := buildExerciceFlag(i, exercice, flag, nline, exceptions)
|
||||
if len(ferrs) > 0 {
|
||||
errs = append(errs, ferrs...)
|
||||
}
|
||||
errs = multierr.Append(errs, ferrs)
|
||||
if len(newFlags) > 0 {
|
||||
for _, newFlag := range newFlags {
|
||||
fId := flag.Id
|
||||
|
|
@ -491,7 +490,7 @@ func buildExerciceFlags(i Importer, exercice *fic.Exercice, exceptions *CheckExc
|
|||
// Read dependency to flag
|
||||
for _, nf := range flag.NeedFlag {
|
||||
if len(nf.Theme) > 0 {
|
||||
errs = append(errs, NewFlagError(exercice, ¶ms.Flags[nline], nline+1, fmt.Errorf("dependancy on another scenario is not implemented yet.")))
|
||||
errs = multierr.Append(errs, NewFlagError(exercice, ¶ms.Flags[nline], nline+1, fmt.Errorf("dependancy on another scenario is not implemented yet.")))
|
||||
}
|
||||
newFlag.FlagsDeps = append(newFlag.FlagsDeps, nf.Id)
|
||||
}
|
||||
|
|
@ -514,18 +513,18 @@ func buildExerciceFlags(i Importer, exercice *fic.Exercice, exceptions *CheckExc
|
|||
}
|
||||
|
||||
// CheckExerciceFlags checks if all flags for the given challenge are correct.
|
||||
func CheckExerciceFlags(i Importer, exercice *fic.Exercice, files []string, exceptions *CheckExceptions) (rf []fic.Flag, errs []error) {
|
||||
func CheckExerciceFlags(i Importer, exercice *fic.Exercice, files []string, exceptions *CheckExceptions) (rf []fic.Flag, errs error) {
|
||||
exceptions = exceptions.GetFileExceptions("challenge.txt", "challenge.toml")
|
||||
|
||||
flags, flagsids, berrs := buildExerciceFlags(i, exercice, exceptions)
|
||||
errs = append(errs, berrs...)
|
||||
errs = multierr.Append(errs, berrs)
|
||||
|
||||
for _, flagid := range flagsids {
|
||||
if flag, ok := flags[flagid]; ok {
|
||||
// Check dependency to flag
|
||||
for _, nf := range flag.FlagsDeps {
|
||||
if _, ok := flags[nf]; !ok {
|
||||
errs = append(errs, NewFlagError(exercice, nil, flag.Line, fmt.Errorf("flag depend on flag id=%d: id not defined", nf)))
|
||||
errs = multierr.Append(errs, NewFlagError(exercice, nil, flag.Line, fmt.Errorf("flag depend on flag id=%d: id not defined", nf)))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -533,7 +532,7 @@ func CheckExerciceFlags(i Importer, exercice *fic.Exercice, files []string, exce
|
|||
deps := flag.FlagsDeps
|
||||
for i := 0; i < len(deps); i++ {
|
||||
if deps[i] == flagid {
|
||||
errs = append(errs, NewFlagError(exercice, nil, flag.Line, fmt.Errorf("flag dependency loop detected: flag id=%d: depends on itself", flagid)))
|
||||
errs = multierr.Append(errs, NewFlagError(exercice, nil, flag.Line, fmt.Errorf("flag dependency loop detected: flag id=%d: depends on itself", flagid)))
|
||||
break
|
||||
}
|
||||
|
||||
|
|
@ -558,7 +557,7 @@ func CheckExerciceFlags(i Importer, exercice *fic.Exercice, files []string, exce
|
|||
}
|
||||
}
|
||||
if !found {
|
||||
errs = append(errs, NewFlagError(exercice, nil, flag.Line, fmt.Errorf("flag depend on %s: No such file", lf)))
|
||||
errs = multierr.Append(errs, NewFlagError(exercice, nil, flag.Line, fmt.Errorf("flag depend on %s: No such file", lf)))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -587,16 +586,16 @@ func ExerciceFlagsMap(i Importer, exercice *fic.Exercice) (kmap map[int64]fic.Fl
|
|||
}
|
||||
|
||||
// SyncExerciceFlags imports all kind of flags for the given challenge.
|
||||
func SyncExerciceFlags(i Importer, exercice *fic.Exercice, exceptions *CheckExceptions) (kmap map[int64]fic.Flag, errs []error) {
|
||||
func SyncExerciceFlags(i Importer, exercice *fic.Exercice, exceptions *CheckExceptions) (kmap map[int64]fic.Flag, errs error) {
|
||||
if _, err := exercice.WipeFlags(); err != nil {
|
||||
errs = append(errs, err)
|
||||
errs = multierr.Append(errs, err)
|
||||
} else if _, err := exercice.WipeMCQs(); err != nil {
|
||||
errs = append(errs, err)
|
||||
errs = multierr.Append(errs, err)
|
||||
} else {
|
||||
exceptions = exceptions.GetFileExceptions("challenge.txt", "challenge.toml")
|
||||
|
||||
flags, flagids, berrs := buildExerciceFlags(i, exercice, exceptions)
|
||||
errs = append(errs, berrs...)
|
||||
errs = multierr.Append(errs, berrs)
|
||||
|
||||
kmap = map[int64]fic.Flag{}
|
||||
|
||||
|
|
@ -610,12 +609,12 @@ func SyncExerciceFlags(i Importer, exercice *fic.Exercice, exceptions *CheckExce
|
|||
}
|
||||
|
||||
if addedFlag, err := exercice.AddFlag(flag.Flag); err != nil {
|
||||
errs = append(errs, NewFlagError(exercice, nil, flag.Line, err))
|
||||
errs = multierr.Append(errs, NewFlagError(exercice, nil, flag.Line, err))
|
||||
} else {
|
||||
if f, ok := addedFlag.(*fic.FlagKey); ok {
|
||||
for _, choice := range flag.Choices {
|
||||
if _, err := f.AddChoice(choice); err != nil {
|
||||
errs = append(errs, NewFlagError(exercice, nil, flag.Line, fmt.Errorf("choice #FIXME: %w", err)))
|
||||
errs = multierr.Append(errs, NewFlagError(exercice, nil, flag.Line, fmt.Errorf("choice #FIXME: %w", err)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -625,18 +624,18 @@ func SyncExerciceFlags(i Importer, exercice *fic.Exercice, exceptions *CheckExce
|
|||
// Import dependency to flag
|
||||
for _, nf := range flag.FlagsDeps {
|
||||
if rf, ok := kmap[nf]; !ok {
|
||||
errs = append(errs, NewFlagError(exercice, nil, flag.Line, fmt.Errorf("dependency to flag id=%d: id not defined, perhaps not available at time of processing", nf)))
|
||||
errs = multierr.Append(errs, NewFlagError(exercice, nil, flag.Line, fmt.Errorf("dependency to flag id=%d: id not defined, perhaps not available at time of processing", nf)))
|
||||
} else if err := addedFlag.AddDepend(rf); err != nil {
|
||||
errs = append(errs, NewFlagError(exercice, nil, flag.Line, fmt.Errorf("dependency to id=%d: %w", nf, err)))
|
||||
errs = multierr.Append(errs, NewFlagError(exercice, nil, flag.Line, fmt.Errorf("dependency to id=%d: %w", nf, err)))
|
||||
}
|
||||
}
|
||||
|
||||
// Import dependency to file
|
||||
for _, lf := range flag.FilesDeps {
|
||||
if rf, err := exercice.GetFileByFilename(lf); err != nil {
|
||||
errs = append(errs, NewFlagError(exercice, nil, flag.Line, fmt.Errorf("dependency to %s: %w", lf, err)))
|
||||
errs = multierr.Append(errs, NewFlagError(exercice, nil, flag.Line, fmt.Errorf("dependency to %s: %w", lf, err)))
|
||||
} else if err := rf.AddDepend(addedFlag); err != nil {
|
||||
errs = append(errs, NewFlagError(exercice, nil, flag.Line, fmt.Errorf("dependency to %s: %w", lf, err)))
|
||||
errs = multierr.Append(errs, NewFlagError(exercice, nil, flag.Line, fmt.Errorf("dependency to %s: %w", lf, err)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Reference in a new issue