sync: import MCQ justification as Flag
This commit is contained in:
parent
07ec6cb613
commit
4f98536f91
2 changed files with 55 additions and 52 deletions
|
@ -25,20 +25,26 @@ type ExerciceUnlockFile struct {
|
||||||
Filename string `toml:",omitempty"`
|
Filename string `toml:",omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ExerciceFlagChoice holds informations about a choice (for MCQ and UCQ).
|
||||||
|
type ExerciceFlagChoice struct {
|
||||||
|
Label string `toml:",omitempty"`
|
||||||
|
Value interface{} `toml:",omitempty"`
|
||||||
|
Justification *ExerciceFlag `toml:",omitempty""`
|
||||||
|
}
|
||||||
|
|
||||||
// ExerciceFlag holds informations about one flag.
|
// ExerciceFlag holds informations about one flag.
|
||||||
type ExerciceFlag struct {
|
type ExerciceFlag struct {
|
||||||
Id int64
|
Id int64
|
||||||
Label string `toml:",omitempty"`
|
Label string `toml:",omitempty"`
|
||||||
Type string `toml:",omitempty"`
|
Type string `toml:",omitempty"`
|
||||||
Raw interface{}
|
Raw interface{}
|
||||||
Value interface{} `toml:",omitempty"`
|
|
||||||
Separator string `toml:",omitempty"`
|
Separator string `toml:",omitempty"`
|
||||||
Ordered bool `toml:",omitempty"`
|
Ordered bool `toml:",omitempty"`
|
||||||
IgnoreCase bool `toml:",omitempty"`
|
IgnoreCase bool `toml:",omitempty"`
|
||||||
ValidatorRe string `toml:"validator_regexp,omitempty"`
|
ValidatorRe string `toml:"validator_regexp,omitempty"`
|
||||||
Help string `toml:",omitempty"`
|
Help string `toml:",omitempty"`
|
||||||
ChoicesCost int64 `toml:"choices_cost,omitempty"`
|
ChoicesCost int64 `toml:"choices_cost,omitempty"`
|
||||||
Choice []ExerciceFlag
|
Choice []ExerciceFlagChoice
|
||||||
LockedFile []ExerciceUnlockFile `toml:"unlock_file,omitempty"`
|
LockedFile []ExerciceUnlockFile `toml:"unlock_file,omitempty"`
|
||||||
NeedFlag []ExerciceDependency `toml:"need_flag,omitempty"`
|
NeedFlag []ExerciceDependency `toml:"need_flag,omitempty"`
|
||||||
NoShuffle bool
|
NoShuffle bool
|
||||||
|
|
|
@ -31,25 +31,27 @@ func validatorRegexp(vre string) (validator_regexp *string) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func getRawKey(flag ExerciceFlag) (raw string, prep string, errs []string) {
|
func getRawKey(input interface{}, validatorRe string, ordered bool) (raw string, prep string, errs []string) {
|
||||||
|
separator := ","
|
||||||
|
|
||||||
// Concatenate array
|
// Concatenate array
|
||||||
if f, ok := flag.Raw.([]interface{}); ok {
|
if f, ok := input.([]interface{}); ok {
|
||||||
if len(flag.ValidatorRe) > 0 {
|
if len(validatorRe) > 0 {
|
||||||
errs = append(errs, "ValidatorRe cannot be defined for this kind of flag.")
|
errs = append(errs, "ValidatorRe cannot be defined for this kind of flag.")
|
||||||
flag.ValidatorRe = ""
|
validatorRe = ""
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(flag.Separator) == 0 {
|
if len(separator) == 0 {
|
||||||
flag.Separator = ","
|
separator = ","
|
||||||
} else if len(flag.Separator) > 1 {
|
} else if len(separator) > 1 {
|
||||||
flag.Separator = string(flag.Separator[0])
|
separator = string(separator[0])
|
||||||
errs = append(errs, "separator truncated to %q")
|
errs = append(errs, "separator truncated to %q")
|
||||||
}
|
}
|
||||||
|
|
||||||
var fitems []string
|
var fitems []string
|
||||||
for _, v := range f {
|
for _, v := range f {
|
||||||
if g, ok := v.(string); ok {
|
if g, ok := v.(string); ok {
|
||||||
if strings.Index(g, flag.Separator) != -1 {
|
if strings.Index(g, separator) != -1 {
|
||||||
errs = append(errs, "flag items cannot contain %q character as it is used as separator. Change the separator attribute for this flag.")
|
errs = append(errs, "flag items cannot contain %q character as it is used as separator. Change the separator attribute for this flag.")
|
||||||
return
|
return
|
||||||
} else {
|
} else {
|
||||||
|
@ -62,19 +64,17 @@ func getRawKey(flag ExerciceFlag) (raw string, prep string, errs []string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
ignord := "f"
|
ignord := "f"
|
||||||
if !flag.Ordered {
|
if !ordered {
|
||||||
sort.Strings(fitems)
|
sort.Strings(fitems)
|
||||||
ignord = "t"
|
ignord = "t"
|
||||||
}
|
}
|
||||||
raw = strings.Join(fitems, flag.Separator) + flag.Separator
|
raw = strings.Join(fitems, separator) + separator
|
||||||
|
|
||||||
prep = "`" + flag.Separator + ignord
|
prep = "`" + separator + ignord
|
||||||
} else if f, ok := flag.Raw.(int64); ok {
|
} else if f, ok := input.(int64); ok {
|
||||||
raw = fmt.Sprintf("%d", f)
|
raw = fmt.Sprintf("%d", f)
|
||||||
} else if f, ok := flag.Value.(string); ok && len(f) > 0 {
|
} else if f, ok := input.(string); !ok {
|
||||||
raw = f
|
errs = append(errs, fmt.Sprintf("has an invalid type: can only be []string or string, not %T", input))
|
||||||
} else if f, ok := flag.Raw.(string); !ok {
|
|
||||||
errs = append(errs, fmt.Sprintf("has an invalid type: can only be []string or string, not %T", flag.Raw))
|
|
||||||
return
|
return
|
||||||
} else {
|
} else {
|
||||||
raw = f
|
raw = f
|
||||||
|
@ -152,7 +152,7 @@ func SyncExerciceFlags(i Importer, exercice fic.Exercice) (errs []string) {
|
||||||
var addedFlag fic.Flag
|
var addedFlag fic.Flag
|
||||||
|
|
||||||
if flag.Type == "key" || flag.Type == "ucq" {
|
if flag.Type == "key" || flag.Type == "ucq" {
|
||||||
raw, prep, terrs := getRawKey(flag)
|
raw, prep, terrs := getRawKey(flag.Raw, flag.ValidatorRe, flag.Ordered)
|
||||||
|
|
||||||
if len(terrs) > 0 {
|
if len(terrs) > 0 {
|
||||||
for _, err := range terrs {
|
for _, err := range terrs {
|
||||||
|
@ -182,18 +182,18 @@ func SyncExerciceFlags(i Importer, exercice fic.Exercice) (errs []string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for cid, choice := range flag.Choice {
|
for cid, choice := range flag.Choice {
|
||||||
val, prep, terrs := getRawKey(choice)
|
val, prep, terrs := getRawKey(choice.Value, "", false)
|
||||||
if len(terrs) > 0 {
|
if len(terrs) > 0 {
|
||||||
for _, err := range terrs {
|
for _, err := range terrs {
|
||||||
errs = append(errs, fmt.Sprintf("%q: flag UCQ #%d: %s", path.Base(exercice.Path), nline + 1, err))
|
errs = append(errs, fmt.Sprintf("%q: flag UCQ #%d: %s", path.Base(exercice.Path), nline + 1, err))
|
||||||
}
|
}
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
choice.Label = prep + choice.Label
|
|
||||||
|
|
||||||
if len(choice.Label) == 0 {
|
if len(choice.Label) == 0 {
|
||||||
choice.Label = val
|
choice.Label = val
|
||||||
}
|
}
|
||||||
|
choice.Label = prep + choice.Label
|
||||||
|
|
||||||
if _, err := k.AddChoice(choice.Label, val); err != nil {
|
if _, err := k.AddChoice(choice.Label, val); err != nil {
|
||||||
errs = append(errs, fmt.Sprintf("%q: error in UCQ %d choice %d: %s", path.Base(exercice.Path), nline + 1, cid, err))
|
errs = append(errs, fmt.Sprintf("%q: error in UCQ %d choice %d: %s", path.Base(exercice.Path), nline + 1, cid, err))
|
||||||
|
@ -228,50 +228,47 @@ func SyncExerciceFlags(i Importer, exercice fic.Exercice) (errs []string) {
|
||||||
var val bool
|
var val bool
|
||||||
var justify string
|
var justify string
|
||||||
|
|
||||||
if choice.Value == nil {
|
if choice.Justification != nil {
|
||||||
val = false
|
|
||||||
} else if p, ok := choice.Value.(bool); ok {
|
|
||||||
val = p
|
|
||||||
if len(choice.Help) > 0 {
|
|
||||||
errs = append(errs, fmt.Sprintf("%q: error MCQ #%d: help field has to be used only with justified mcq.", path.Base(exercice.Path), nline + 1))
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if isJustified {
|
|
||||||
errs = append(errs, fmt.Sprintf("%q: error MCQ #%d: all true items has to be justified in this MCQ.", path.Base(exercice.Path), nline + 1))
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if choice.Raw == nil && choice.Value != nil {
|
|
||||||
choice.Raw = choice.Value
|
|
||||||
choice.Value = nil
|
|
||||||
}
|
|
||||||
if len(choice.Help) == 0 {
|
|
||||||
choice.Help = "Flag correspondant"
|
|
||||||
}
|
|
||||||
if hasOne && !isJustified {
|
if hasOne && !isJustified {
|
||||||
errs = append(errs, fmt.Sprintf("%q: error MCQ #%d: all true items has to be justified in this MCQ.", path.Base(exercice.Path), nline + 1))
|
errs = append(errs, fmt.Sprintf("%q: error MCQ #%d: all true items has to be justified in this MCQ.", path.Base(exercice.Path), nline + 1))
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
var prep string
|
|
||||||
var terrs []string
|
|
||||||
val = true
|
val = true
|
||||||
isJustified = true
|
isJustified = true
|
||||||
justify, prep, terrs = getRawKey(choice)
|
} else if p, ok := choice.Value.(bool); ok {
|
||||||
|
val = p
|
||||||
|
if isJustified {
|
||||||
|
errs = append(errs, fmt.Sprintf("%q: error MCQ #%d: all true items has to be justified in this MCQ.", path.Base(exercice.Path), nline + 1))
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
} else if choice.Value == nil {
|
||||||
|
val = false
|
||||||
|
} else {
|
||||||
|
errs = append(errs, fmt.Sprintf("%q: error in MCQ %d choice %d: incorrect type for value: %T is not boolean.", path.Base(exercice.Path), nline + 1, cid, choice.Value))
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if e, err := f.AddEntry(choice.Label, val); err != nil {
|
||||||
|
errs = append(errs, fmt.Sprintf("%q: error in MCQ %d choice %d: %s", path.Base(exercice.Path), nline + 1, cid, err))
|
||||||
|
continue
|
||||||
|
} else if isJustified && choice.Justification != nil {
|
||||||
|
var prep string
|
||||||
|
var terrs []string
|
||||||
|
justify, prep, terrs = getRawKey(choice.Justification.Raw, choice.Justification.ValidatorRe, choice.Justification.Ordered)
|
||||||
if len(terrs) > 0 {
|
if len(terrs) > 0 {
|
||||||
for _, err := range terrs {
|
for _, err := range terrs {
|
||||||
errs = append(errs, fmt.Sprintf("%q: flag MCQ #%d, choice #%d: %s", path.Base(exercice.Path), nline + 1, cid, err))
|
errs = append(errs, fmt.Sprintf("%q: flag MCQ #%d, choice #%d: %s", path.Base(exercice.Path), nline + 1, cid, err))
|
||||||
}
|
}
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
choice.Help = prep + choice.Help
|
|
||||||
}
|
|
||||||
|
|
||||||
if e, err := f.AddEntry(choice.Label, val); err != nil {
|
if len(choice.Justification.Label) == 0 {
|
||||||
errs = append(errs, fmt.Sprintf("%q: error in MCQ %d choice %d: %s", path.Base(exercice.Path), nline + 1, cid, err))
|
choice.Justification.Label = "Flag correspondant"
|
||||||
continue
|
}
|
||||||
} else if len(justify) > 0 {
|
choice.Justification.Label = prep + choice.Justification.Label
|
||||||
if _, err := exercice.AddRawFlagKey(fmt.Sprintf("%%%d%%%s", e.Id, choice.Help), "", false, nil, []byte(justify), 0); err != nil {
|
|
||||||
|
if _, err := exercice.AddRawFlagKey(fmt.Sprintf("%%%d%%%s", e.Id, choice.Justification.Label), choice.Justification.Help, choice.Justification.IgnoreCase, validatorRegexp(choice.Justification.ValidatorRe), []byte(justify), flag.ChoicesCost); err != nil {
|
||||||
errs = append(errs, fmt.Sprintf("%q: error MCQ #%d: %s", path.Base(exercice.Path), nline + 1, err))
|
errs = append(errs, fmt.Sprintf("%q: error MCQ #%d: %s", path.Base(exercice.Path), nline + 1, err))
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
Reference in a new issue