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
|
|
@ -5,29 +5,31 @@ import (
|
|||
"path"
|
||||
"strings"
|
||||
|
||||
"go.uber.org/multierr"
|
||||
|
||||
"srs.epita.fr/fic-server/admin/sync"
|
||||
"srs.epita.fr/fic-server/libfic"
|
||||
)
|
||||
|
||||
func EPITACheckFile(file *fic.EFile, _ *fic.Exercice, exceptions *sync.CheckExceptions) (errs []error) {
|
||||
func EPITACheckFile(file *fic.EFile, _ *fic.Exercice, exceptions *sync.CheckExceptions) (errs error) {
|
||||
// Enforce file format
|
||||
if path.Ext(file.Name) == ".rar" || path.Ext(file.Name) == ".7z" {
|
||||
errs = append(errs, fmt.Errorf("this file use a forbidden archive type."))
|
||||
errs = multierr.Append(errs, fmt.Errorf("this file use a forbidden archive type."))
|
||||
}
|
||||
|
||||
// Check for stange file extension
|
||||
if strings.HasSuffix(file.Name, ".tar.zip") {
|
||||
errs = append(errs, fmt.Errorf(".tar.zip is not a valid tar format"))
|
||||
errs = multierr.Append(errs, fmt.Errorf(".tar.zip is not a valid tar format"))
|
||||
}
|
||||
|
||||
// Check .gz files have a dedicated hash
|
||||
if path.Ext(file.Name) == ".gz" && !strings.HasSuffix(file.Name, ".tar.gz") && len(file.ChecksumShown) == 0 {
|
||||
errs = append(errs, fmt.Errorf("digest of original, uncompressed, file missing in DIGESTS.txt"))
|
||||
errs = multierr.Append(errs, fmt.Errorf("digest of original, uncompressed, file missing in DIGESTS.txt"))
|
||||
}
|
||||
|
||||
// Check for huge file to compress
|
||||
if file.Size > 4000000 && path.Ext(file.Name) == ".tar" {
|
||||
errs = append(errs, fmt.Errorf("archive to compress with bzip2"))
|
||||
errs = multierr.Append(errs, fmt.Errorf("archive to compress with bzip2"))
|
||||
} else if file.Size > 40000000 && (path.Ext(file.Name) == "" ||
|
||||
path.Ext(file.Name) == ".csv" ||
|
||||
path.Ext(file.Name) == ".dump" ||
|
||||
|
|
@ -38,7 +40,7 @@ func EPITACheckFile(file *fic.EFile, _ *fic.Exercice, exceptions *sync.CheckExce
|
|||
path.Ext(file.Name) == ".pcap" ||
|
||||
path.Ext(file.Name) == ".pcapng" ||
|
||||
path.Ext(file.Name) == ".txt") {
|
||||
errs = append(errs, fmt.Errorf("huge file to compress with gzip"))
|
||||
errs = multierr.Append(errs, fmt.Errorf("huge file to compress with gzip"))
|
||||
}
|
||||
|
||||
return
|
||||
|
|
|
|||
|
|
@ -6,53 +6,55 @@ import (
|
|||
"strings"
|
||||
"unicode"
|
||||
|
||||
"go.uber.org/multierr"
|
||||
|
||||
"srs.epita.fr/fic-server/admin/sync"
|
||||
"srs.epita.fr/fic-server/libfic"
|
||||
)
|
||||
|
||||
func EPITACheckKeyFlag(flag *fic.FlagKey, raw string, _ *fic.Exercice, exceptions *sync.CheckExceptions) (errs []error) {
|
||||
func EPITACheckKeyFlag(flag *fic.FlagKey, raw string, _ *fic.Exercice, exceptions *sync.CheckExceptions) (errs error) {
|
||||
if (flag.Label[0] == 'Q' || flag.Label[0] == 'q') && (flag.Label[1] == 'U' || flag.Label[1] == 'u') ||
|
||||
(flag.Label[0] == 'W' || flag.Label[0] == 'w') && (flag.Label[1] == 'H' || flag.Label[1] == 'h') {
|
||||
errs = append(errs, fmt.Errorf("Label should not begin with %s. This seem to be a question. Reword your label as a description of the expected flag, `:` are automatically appended.", flag.Label[0:2]))
|
||||
errs = multierr.Append(errs, fmt.Errorf("Label should not begin with %s. This seem to be a question. Reword your label as a description of the expected flag, `:` are automatically appended.", flag.Label[0:2]))
|
||||
flag.Label = flag.Label[1:]
|
||||
}
|
||||
|
||||
if flag.Label[len(flag.Label)-1] != ')' && flag.Label[len(flag.Label)-1] != '©' && !unicode.IsLetter(rune(flag.Label[len(flag.Label)-1])) && !unicode.IsDigit(rune(flag.Label[len(flag.Label)-1])) {
|
||||
errs = append(errs, fmt.Errorf("Label should not end with punct (%q). Reword your label as a description of the expected flag, `:` are automatically appended.", flag.Label[len(flag.Label)-1]))
|
||||
errs = multierr.Append(errs, fmt.Errorf("Label should not end with punct (%q). Reword your label as a description of the expected flag, `:` are automatically appended.", flag.Label[len(flag.Label)-1]))
|
||||
}
|
||||
|
||||
if strings.HasPrefix(strings.ToLower(raw), "cve-") && flag.Type != "ucq" {
|
||||
errs = append(errs, fmt.Errorf("CVE numbers are required to be UCQ with choice_cost"))
|
||||
errs = multierr.Append(errs, fmt.Errorf("CVE numbers are required to be UCQ with choice_cost"))
|
||||
}
|
||||
|
||||
if _, err := strconv.ParseInt(raw, 10, 64); flag.Type == "key" && err == nil && !exceptions.HasException(":not-number-flag") {
|
||||
errs = append(errs, fmt.Errorf("shouldn't be this flag a number type? (:not-number-flag)"))
|
||||
errs = multierr.Append(errs, fmt.Errorf("shouldn't be this flag a number type? (:not-number-flag)"))
|
||||
}
|
||||
|
||||
if flag.Placeholder == "" && (strings.HasPrefix(flag.Type, "number") || flag.Type == "key" || flag.Type == "text" || (flag.Type == "ucq" && flag.ChoicesCost > 0)) {
|
||||
errs = append(errs, fmt.Errorf("no placeholder defined"))
|
||||
errs = multierr.Append(errs, fmt.Errorf("no placeholder defined"))
|
||||
}
|
||||
|
||||
if strings.HasPrefix(flag.Type, "number") {
|
||||
min, max, step, err := fic.AnalyzeNumberFlag(flag.Type)
|
||||
if err != nil {
|
||||
errs = append(errs, err)
|
||||
errs = multierr.Append(errs, err)
|
||||
} else if min == nil || max == nil || step == nil {
|
||||
errs = append(errs, fmt.Errorf("please define min and max for your number flag"))
|
||||
errs = multierr.Append(errs, fmt.Errorf("please define min and max for your number flag"))
|
||||
} else if (*max-*min) / *step <= 10 {
|
||||
errs = append(errs, fmt.Errorf("to avoid bruteforce, define more than 10 possibilities"))
|
||||
errs = multierr.Append(errs, fmt.Errorf("to avoid bruteforce, define more than 10 possibilities"))
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func EPITACheckKeyFlagWithChoices(flag *fic.FlagKey, raw string, choices []*fic.FlagChoice, _ *fic.Exercice, exceptions *sync.CheckExceptions) (errs []error) {
|
||||
func EPITACheckKeyFlagWithChoices(flag *fic.FlagKey, raw string, choices []*fic.FlagChoice, _ *fic.Exercice, exceptions *sync.CheckExceptions) (errs error) {
|
||||
if !exceptions.HasException(":bruteforcable-choices") {
|
||||
if len(choices) < 10 && flag.ChoicesCost == 0 {
|
||||
errs = append(errs, fmt.Errorf("requires at least 10 choices to avoid brute-force"))
|
||||
errs = multierr.Append(errs, fmt.Errorf("requires at least 10 choices to avoid brute-force"))
|
||||
} else if len(choices) < 6 && flag.ChoicesCost > 0 {
|
||||
errs = append(errs, fmt.Errorf("requires at least 10 choices to avoid brute-force"))
|
||||
errs = multierr.Append(errs, fmt.Errorf("requires at least 10 choices to avoid brute-force"))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -4,17 +4,19 @@ import (
|
|||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"go.uber.org/multierr"
|
||||
|
||||
"srs.epita.fr/fic-server/admin/sync"
|
||||
"srs.epita.fr/fic-server/libfic"
|
||||
)
|
||||
|
||||
func InspectFile(file *fic.EFile, _ *fic.Exercice, exceptions *sync.CheckExceptions) (errs []error) {
|
||||
func InspectFile(file *fic.EFile, _ *fic.Exercice, exceptions *sync.CheckExceptions) (errs error) {
|
||||
if filepath.Ext(file.Name) == ".tar" || strings.HasSuffix(file.Name, ".tar.gz") || strings.HasSuffix(file.Name, ".tar.bz2") {
|
||||
// Check there is more than 1 file in tarball
|
||||
errs = append(errs, checkTarball(file, exceptions)...)
|
||||
errs = multierr.Append(errs, checkTarball(file, exceptions))
|
||||
} else if filepath.Ext(file.Name) == ".zip" {
|
||||
// Check there is more than 1 file in zip
|
||||
errs = append(errs, checkZip(file, exceptions)...)
|
||||
errs = multierr.Append(errs, checkZip(file, exceptions))
|
||||
}
|
||||
|
||||
return
|
||||
|
|
|
|||
|
|
@ -9,11 +9,13 @@ import (
|
|||
"log"
|
||||
"strings"
|
||||
|
||||
"go.uber.org/multierr"
|
||||
|
||||
"srs.epita.fr/fic-server/admin/sync"
|
||||
"srs.epita.fr/fic-server/libfic"
|
||||
)
|
||||
|
||||
func checkTarball(file *fic.EFile, exceptions *sync.CheckExceptions) (errs []error) {
|
||||
func checkTarball(file *fic.EFile, exceptions *sync.CheckExceptions) (errs error) {
|
||||
fd, closer, err := sync.GetFile(sync.GlobalImporter, file.GetOrigin())
|
||||
if err != nil {
|
||||
log.Printf("Unable to open %q: %s", file.GetOrigin(), err.Error())
|
||||
|
|
@ -56,11 +58,11 @@ func checkTarball(file *fic.EFile, exceptions *sync.CheckExceptions) (errs []err
|
|||
|
||||
if nbFile < 2 {
|
||||
if !exceptions.HasException(":one-file-tarball") {
|
||||
errs = append(errs, fmt.Errorf("don't make a tarball for one file"))
|
||||
errs = multierr.Append(errs, fmt.Errorf("don't make a tarball for one file"))
|
||||
}
|
||||
} else if nbFile < 5 && false {
|
||||
if !exceptions.HasException(":few-files-tarball") {
|
||||
errs = append(errs, fmt.Errorf("don't make a tarball for so little files (:few-files-tarball)"))
|
||||
errs = multierr.Append(errs, fmt.Errorf("don't make a tarball for so little files (:few-files-tarball)"))
|
||||
}
|
||||
} else {
|
||||
log.Printf("%d files found in %q", nbFile, file.Name)
|
||||
|
|
|
|||
|
|
@ -7,11 +7,13 @@ import (
|
|||
"log"
|
||||
"strings"
|
||||
|
||||
"go.uber.org/multierr"
|
||||
|
||||
"srs.epita.fr/fic-server/admin/sync"
|
||||
"srs.epita.fr/fic-server/libfic"
|
||||
)
|
||||
|
||||
func checkZip(file *fic.EFile, exceptions *sync.CheckExceptions) (errs []error) {
|
||||
func checkZip(file *fic.EFile, exceptions *sync.CheckExceptions) (errs error) {
|
||||
fd, closer, err := sync.GetFile(sync.GlobalImporter, file.GetOrigin())
|
||||
if err != nil {
|
||||
log.Printf("Unable to open %q: %s", file.GetOrigin(), err.Error())
|
||||
|
|
@ -39,11 +41,11 @@ func checkZip(file *fic.EFile, exceptions *sync.CheckExceptions) (errs []error)
|
|||
|
||||
if len(r.File) < 2 {
|
||||
if !exceptions.HasException(":one-file-tarball") {
|
||||
errs = append(errs, fmt.Errorf("don't make a ZIP archive for one file, use gzip instead"))
|
||||
errs = multierr.Append(errs, fmt.Errorf("don't make a ZIP archive for one file, use gzip instead"))
|
||||
}
|
||||
} else if len(r.File) < 5 && false {
|
||||
if !exceptions.HasException(":few-files-tarball") {
|
||||
errs = append(errs, fmt.Errorf("don't make a ZIP archive for so little files (:few-files-tarball)"))
|
||||
errs = multierr.Append(errs, fmt.Errorf("don't make a ZIP archive for so little files (:few-files-tarball)"))
|
||||
}
|
||||
} else {
|
||||
log.Printf("%d files found in %q", len(r.File), file.Name)
|
||||
|
|
@ -83,7 +85,7 @@ func checkZip(file *fic.EFile, exceptions *sync.CheckExceptions) (errs []error)
|
|||
}
|
||||
|
||||
if nbLinuxDirFound > 2 && !exceptions.HasException(":not-a-linux-rootfs") {
|
||||
errs = append(errs, fmt.Errorf("don't use a ZIP archive to store an Unix file system, prefer a tarball (:not-a-linux-rootfs)"))
|
||||
errs = multierr.Append(errs, fmt.Errorf("don't use a ZIP archive to store an Unix file system, prefer a tarball (:not-a-linux-rootfs)"))
|
||||
}
|
||||
|
||||
return
|
||||
|
|
|
|||
|
|
@ -6,51 +6,53 @@ import (
|
|||
"log"
|
||||
"unicode"
|
||||
|
||||
"go.uber.org/multierr"
|
||||
|
||||
"srs.epita.fr/fic-server/admin/sync"
|
||||
"srs.epita.fr/fic-server/libfic"
|
||||
lib "srs.epita.fr/fic-server/repochecker/grammalecte/lib"
|
||||
)
|
||||
|
||||
func GrammalecteCheckKeyFlag(flag *fic.FlagKey, raw string, exercice *fic.Exercice, exceptions *sync.CheckExceptions) (errs []error) {
|
||||
func GrammalecteCheckKeyFlag(flag *fic.FlagKey, raw string, exercice *fic.Exercice, exceptions *sync.CheckExceptions) (errs error) {
|
||||
if !isRecognizedLanguage(exercice.Language) {
|
||||
return
|
||||
}
|
||||
|
||||
label, _, _, _ := flag.AnalyzeFlagLabel()
|
||||
for _, err := range grammalecte("label ", label, -1, exceptions, &CommonOpts) {
|
||||
for _, err := range multierr.Errors(grammalecte("label ", label, -1, exceptions, &CommonOpts)) {
|
||||
if e, ok := err.(lib.GrammarError); ok && e.RuleId == "poncfin_règle1" {
|
||||
continue
|
||||
}
|
||||
|
||||
errs = append(errs, err)
|
||||
errs = multierr.Append(errs, err)
|
||||
}
|
||||
|
||||
if len(flag.Help) > 0 {
|
||||
errs = append(errs, grammalecte("help ", flag.Help, -1, exceptions, &CommonOpts)...)
|
||||
errs = multierr.Append(errs, grammalecte("help ", flag.Help, -1, exceptions, &CommonOpts))
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func GrammalecteCheckFlagChoice(choice *fic.FlagChoice, exercice *fic.Exercice, exceptions *sync.CheckExceptions) (errs []error) {
|
||||
func GrammalecteCheckFlagChoice(choice *fic.FlagChoice, exercice *fic.Exercice, exceptions *sync.CheckExceptions) (errs error) {
|
||||
if isRecognizedLanguage(exercice.Language) {
|
||||
errs = append(errs, grammalecte("label ", choice.Label, -1, exceptions, &CommonOpts)...)
|
||||
errs = multierr.Append(errs, grammalecte("label ", choice.Label, -1, exceptions, &CommonOpts))
|
||||
}
|
||||
|
||||
if len(errs) == 0 && !unicode.IsUpper(bytes.Runes([]byte(choice.Label))[0]) && !exceptions.HasException(":label_majuscule") {
|
||||
errs = append(errs, fmt.Errorf("%q nécessite une majuscule (:label_majuscule)", choice.Label))
|
||||
if len(multierr.Errors(errs)) == 0 && !unicode.IsUpper(bytes.Runes([]byte(choice.Label))[0]) && !exceptions.HasException(":label_majuscule") {
|
||||
errs = multierr.Append(errs, fmt.Errorf("%q nécessite une majuscule (:label_majuscule)", choice.Label))
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func GrammalecteCheckHint(hint *fic.EHint, exercice *fic.Exercice, exceptions *sync.CheckExceptions) (errs []error) {
|
||||
func GrammalecteCheckHint(hint *fic.EHint, exercice *fic.Exercice, exceptions *sync.CheckExceptions) (errs error) {
|
||||
if len(hint.Title) > 0 {
|
||||
if isRecognizedLanguage(exercice.Language) {
|
||||
errs = append(errs, grammalecte("title ", hint.Title, -1, exceptions, &CommonOpts)...)
|
||||
errs = multierr.Append(errs, grammalecte("title ", hint.Title, -1, exceptions, &CommonOpts))
|
||||
}
|
||||
if len(errs) == 0 && !unicode.IsUpper(bytes.Runes([]byte(hint.Title))[0]) && !exceptions.HasException(":title_majuscule") {
|
||||
errs = append(errs, fmt.Errorf("%q nécessite une majuscule (:title_majuscule)", hint.Title))
|
||||
if len(multierr.Errors(errs)) == 0 && !unicode.IsUpper(bytes.Runes([]byte(hint.Title))[0]) && !exceptions.HasException(":title_majuscule") {
|
||||
errs = multierr.Append(errs, fmt.Errorf("%q nécessite une majuscule (:title_majuscule)", hint.Title))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -59,7 +61,7 @@ func GrammalecteCheckHint(hint *fic.EHint, exercice *fic.Exercice, exceptions *s
|
|||
return
|
||||
}
|
||||
|
||||
func GrammalecteCheckGrammar(data interface{}, exceptions *sync.CheckExceptions) []error {
|
||||
func GrammalecteCheckGrammar(data interface{}, exceptions *sync.CheckExceptions) error {
|
||||
if s, ok := data.(struct {
|
||||
Str string
|
||||
Language string
|
||||
|
|
|
|||
|
|
@ -9,6 +9,8 @@ import (
|
|||
"regexp"
|
||||
"strings"
|
||||
|
||||
"go.uber.org/multierr"
|
||||
|
||||
"srs.epita.fr/fic-server/admin/sync"
|
||||
lib "srs.epita.fr/fic-server/repochecker/grammalecte/lib"
|
||||
)
|
||||
|
|
@ -119,7 +121,7 @@ var (
|
|||
mdimg = regexp.MustCompile(`!\[([^\]]+)\]\([^)]+\)`)
|
||||
)
|
||||
|
||||
func grammalecte(name string, text string, paragraph int, exceptions *sync.CheckExceptions, options *GrammalecteOptions) (errs []error) {
|
||||
func grammalecte(name string, text string, paragraph int, exceptions *sync.CheckExceptions, options *GrammalecteOptions) (errs error) {
|
||||
// Remove Markdown elements
|
||||
text = mdimg.ReplaceAllString(text, "Image : ${1}")
|
||||
|
||||
|
|
@ -173,7 +175,7 @@ func grammalecte(name string, text string, paragraph int, exceptions *sync.Check
|
|||
}
|
||||
|
||||
suggestions, _ := suggest(serror.Value)
|
||||
errs = append(errs, lib.SpellingError{
|
||||
errs = multierr.Append(errs, lib.SpellingError{
|
||||
Prefix: name,
|
||||
Source: data.Text,
|
||||
NSource: data.Paragraph,
|
||||
|
|
@ -207,7 +209,7 @@ func grammalecte(name string, text string, paragraph int, exceptions *sync.Check
|
|||
continue
|
||||
}
|
||||
|
||||
errs = append(errs, err)
|
||||
errs = multierr.Append(errs, err)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -15,9 +15,10 @@ import (
|
|||
"github.com/yuin/goldmark/renderer"
|
||||
"github.com/yuin/goldmark/text"
|
||||
"github.com/yuin/goldmark/util"
|
||||
"go.uber.org/multierr"
|
||||
)
|
||||
|
||||
func GrammalecteCheckMDText(str string, lang string, exceptions *sync.CheckExceptions, forbiddenStrings ...string) (errs []error) {
|
||||
func GrammalecteCheckMDText(str string, lang string, exceptions *sync.CheckExceptions, forbiddenStrings ...string) (errs error) {
|
||||
if !isRecognizedLanguage(lang) {
|
||||
return
|
||||
}
|
||||
|
|
@ -34,7 +35,7 @@ func GrammalecteCheckMDText(str string, lang string, exceptions *sync.CheckExcep
|
|||
for _, s := range forbiddenStrings {
|
||||
if strings.Contains(str, s) {
|
||||
if !exceptions.HasException(":not-forbidden-string:" + s) {
|
||||
errs = append(errs, fmt.Errorf("Forbidden raw string %q included in file content, don't write it (:not-forbidden-string:%s)", s, s))
|
||||
errs = multierr.Append(errs, fmt.Errorf("Forbidden raw string %q included in file content, don't write it (:not-forbidden-string:%s)", s, s))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -62,13 +63,13 @@ func GrammalecteCheckMDText(str string, lang string, exceptions *sync.CheckExcep
|
|||
|
||||
var buf bytes.Buffer
|
||||
if err := markdown.Convert([]byte(str), &buf); err != nil {
|
||||
errs = append(errs, err)
|
||||
errs = multierr.Append(errs, err)
|
||||
}
|
||||
|
||||
errs = append(errs, checker.errs...)
|
||||
errs = append(errs, voidRenderer.Errors()...)
|
||||
errs = multierr.Append(errs, checker.errs)
|
||||
errs = multierr.Append(errs, voidRenderer.Errors())
|
||||
|
||||
for _, err := range grammalecte("", buf.String(), 0, exceptions, &CommonOpts) {
|
||||
for _, err := range multierr.Errors(grammalecte("", buf.String(), 0, exceptions, &CommonOpts)) {
|
||||
if gerror, ok := err.(lib.GrammarError); ok {
|
||||
if (gerror.RuleId == "redondances_paragraphe" || gerror.RuleId == "redondances_phrase") && gerror.GetPassage() == "SubstitutDeCode" {
|
||||
continue
|
||||
|
|
@ -79,7 +80,7 @@ func GrammalecteCheckMDText(str string, lang string, exceptions *sync.CheckExcep
|
|||
}
|
||||
}
|
||||
|
||||
errs = append(errs, err)
|
||||
errs = multierr.Append(errs, err)
|
||||
}
|
||||
|
||||
return
|
||||
|
|
@ -87,7 +88,7 @@ func GrammalecteCheckMDText(str string, lang string, exceptions *sync.CheckExcep
|
|||
|
||||
type grammarChecker struct {
|
||||
exceptions *sync.CheckExceptions
|
||||
errs []error
|
||||
errs error
|
||||
}
|
||||
|
||||
func (t *grammarChecker) Transform(doc *ast.Document, reader text.Reader, pc parser.Context) {
|
||||
|
|
@ -99,11 +100,11 @@ func (t *grammarChecker) Transform(doc *ast.Document, reader text.Reader, pc par
|
|||
switch child := node.(type) {
|
||||
case *ast.Image:
|
||||
if len(child.Title) > 0 {
|
||||
t.errs = append(t.errs, grammalecte("", string(child.Title), 0, t.exceptions, &CommonOpts)...)
|
||||
t.errs = multierr.Append(t.errs, grammalecte("", string(child.Title), 0, t.exceptions, &CommonOpts))
|
||||
}
|
||||
case *ast.Link:
|
||||
if len(child.Title) > 0 {
|
||||
t.errs = append(t.errs, grammalecte("", string(child.Title), 0, t.exceptions, &CommonOpts)...)
|
||||
t.errs = multierr.Append(t.errs, grammalecte("", string(child.Title), 0, t.exceptions, &CommonOpts))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -7,10 +7,11 @@ import (
|
|||
"github.com/yuin/goldmark/ast"
|
||||
goldrender "github.com/yuin/goldmark/renderer"
|
||||
"github.com/yuin/goldmark/util"
|
||||
"go.uber.org/multierr"
|
||||
)
|
||||
|
||||
type VoidRenderer struct {
|
||||
errs []error
|
||||
errs error
|
||||
}
|
||||
|
||||
func NewVoidRenderer() *VoidRenderer {
|
||||
|
|
@ -28,7 +29,7 @@ func (r *VoidRenderer) RegisterFuncs(reg goldrender.NodeRendererFuncRegisterer)
|
|||
reg.Register(ast.KindString, r.renderString)
|
||||
}
|
||||
|
||||
func (r *VoidRenderer) Errors() []error {
|
||||
func (r *VoidRenderer) Errors() error {
|
||||
return r.errs
|
||||
}
|
||||
|
||||
|
|
@ -77,7 +78,7 @@ func (r *VoidRenderer) renderImage(w util.BufWriter, source []byte, node ast.Nod
|
|||
// Check there is a correct image alt
|
||||
alt := nodeToText(n, source)
|
||||
if len(bytes.Fields(alt)) <= 1 {
|
||||
r.errs = append(r.errs, fmt.Errorf("No valid image alternative defined for %q", n.Destination))
|
||||
r.errs = multierr.Append(r.errs, fmt.Errorf("No valid image alternative defined for %q", n.Destination))
|
||||
return ast.WalkContinue, nil
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -15,6 +15,8 @@ import (
|
|||
"strconv"
|
||||
"strings"
|
||||
|
||||
"go.uber.org/multierr"
|
||||
|
||||
"srs.epita.fr/fic-server/admin/sync"
|
||||
"srs.epita.fr/fic-server/libfic"
|
||||
)
|
||||
|
|
@ -108,14 +110,14 @@ func searchBinaryInGit(edir string) (ret []string) {
|
|||
return
|
||||
}
|
||||
|
||||
func checkExercice(theme *fic.Theme, edir string, dmap *map[int64]*fic.Exercice, exceptions *sync.CheckExceptions) (errs []error) {
|
||||
func checkExercice(theme *fic.Theme, edir string, dmap *map[int64]*fic.Exercice, exceptions *sync.CheckExceptions) (errs error) {
|
||||
e, _, eid, exceptions, _, berrs := sync.BuildExercice(sync.GlobalImporter, theme, path.Join(theme.Path, edir), dmap, nil)
|
||||
errs = append(errs, berrs...)
|
||||
errs = multierr.Append(errs, berrs)
|
||||
|
||||
if e != nil {
|
||||
// Files
|
||||
var files []string
|
||||
var cerrs []error
|
||||
var cerrs error
|
||||
if !skipFileChecks {
|
||||
files, cerrs = sync.CheckExerciceFiles(sync.GlobalImporter, e, exceptions)
|
||||
log.Printf("%d files checked.\n", len(files))
|
||||
|
|
@ -123,16 +125,16 @@ func checkExercice(theme *fic.Theme, edir string, dmap *map[int64]*fic.Exercice,
|
|||
files, cerrs = sync.CheckExerciceFilesPresence(sync.GlobalImporter, e)
|
||||
log.Printf("%d files presents but not checked (please check digest yourself).\n", len(files))
|
||||
}
|
||||
errs = append(errs, cerrs...)
|
||||
errs = multierr.Append(errs, cerrs)
|
||||
|
||||
// Flags
|
||||
flags, cerrs := sync.CheckExerciceFlags(sync.GlobalImporter, e, files, exceptions)
|
||||
errs = append(errs, cerrs...)
|
||||
errs = multierr.Append(errs, cerrs)
|
||||
log.Printf("%d flags checked.\n", len(flags))
|
||||
|
||||
// Hints
|
||||
hints, cerrs := sync.CheckExerciceHints(sync.GlobalImporter, e, exceptions)
|
||||
errs = append(errs, cerrs...)
|
||||
errs = multierr.Append(errs, cerrs)
|
||||
log.Printf("%d hints checked.\n", len(hints))
|
||||
|
||||
if dmap != nil {
|
||||
|
|
@ -247,8 +249,9 @@ func main() {
|
|||
theme, exceptions, errs := sync.BuildTheme(sync.GlobalImporter, p)
|
||||
|
||||
if theme != nil && !sync.GlobalImporter.Exists(path.Join(p, "challenge.txt")) && !sync.GlobalImporter.Exists(path.Join(p, "challenge.toml")) {
|
||||
nberr += len(errs)
|
||||
for _, err := range errs {
|
||||
thiserrors := multierr.Errors(errs)
|
||||
nberr += len(thiserrors)
|
||||
for _, err := range thiserrors {
|
||||
log.Println(err)
|
||||
}
|
||||
|
||||
|
|
@ -264,7 +267,7 @@ func main() {
|
|||
for _, edir := range exercices {
|
||||
ex_exceptions := exceptions.GetFileExceptions(edir)
|
||||
|
||||
for _, err := range checkExercice(theme, edir, &dmap, ex_exceptions) {
|
||||
for _, err := range multierr.Errors(checkExercice(theme, edir, &dmap, ex_exceptions)) {
|
||||
log.Println(err.Error())
|
||||
|
||||
if logMissingResolution {
|
||||
|
|
@ -294,7 +297,7 @@ func main() {
|
|||
} else {
|
||||
log.Printf("This is not a theme directory, run checks for exercice.\n\n")
|
||||
|
||||
for _, err := range checkExercice(&fic.Theme{}, p, &map[int64]*fic.Exercice{}, nil) {
|
||||
for _, err := range multierr.Errors(checkExercice(&fic.Theme{}, p, &map[int64]*fic.Exercice{}, nil)) {
|
||||
nberr += 1
|
||||
log.Println(err)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ func (pcapNGReader *PcapNgReader) ReadPacketData() (data []byte, ci gopacket.Cap
|
|||
|
||||
// Iterate thought each packet to find potentialy unwanted packets
|
||||
// TODO: Allow custom rules to specify what is a unwanted packet
|
||||
func CheckPcap(pcapReader PcapPacketDataReader, pcapName string) (errs []error) {
|
||||
func CheckPcap(pcapReader PcapPacketDataReader, pcapName string) (errs error) {
|
||||
warningFlows := make(map[gopacket.Flow]([]time.Time))
|
||||
|
||||
//
|
||||
|
|
@ -105,11 +105,11 @@ func CheckPcap(pcapReader PcapPacketDataReader, pcapName string) (errs []error)
|
|||
return
|
||||
}
|
||||
|
||||
func CheckTextFile(fd *os.File) (errs []error) {
|
||||
func CheckTextFile(fd *os.File) (errs error) {
|
||||
return
|
||||
}
|
||||
|
||||
func InspectFileForIPAddr(file *fic.EFile, _ *fic.Exercice, exceptions *sync.CheckExceptions) (errs []error) {
|
||||
func InspectFileForIPAddr(file *fic.EFile, _ *fic.Exercice, exceptions *sync.CheckExceptions) (errs error) {
|
||||
fd, closer, err := sync.GetFile(sync.GlobalImporter, file.GetOrigin())
|
||||
if err != nil {
|
||||
log.Printf("Unable to open %q: %s", file.GetOrigin(), err.Error())
|
||||
|
|
|
|||
|
|
@ -3,6 +3,8 @@ package main
|
|||
import (
|
||||
"fmt"
|
||||
|
||||
"go.uber.org/multierr"
|
||||
|
||||
"srs.epita.fr/fic-server/admin/sync"
|
||||
"srs.epita.fr/fic-server/libfic"
|
||||
)
|
||||
|
|
@ -15,9 +17,9 @@ func RegisterChecksHooks(h *sync.CheckHooks) {
|
|||
h.RegisterExerciceHook(CheckResolutionVideo)
|
||||
}
|
||||
|
||||
func CheckResolutionVideo(e *fic.Exercice, exceptions *sync.CheckExceptions) (errs []error) {
|
||||
for _, err := range checkResolutionVideo(e, exceptions) {
|
||||
errs = append(errs, fmt.Errorf("resolution.mp4: %w", err))
|
||||
func CheckResolutionVideo(e *fic.Exercice, exceptions *sync.CheckExceptions) (errs error) {
|
||||
for _, err := range multierr.Errors(checkResolutionVideo(e, exceptions)) {
|
||||
errs = multierr.Append(errs, fmt.Errorf("resolution.mp4: %w", err))
|
||||
}
|
||||
|
||||
return
|
||||
|
|
|
|||
|
|
@ -9,14 +9,15 @@ import (
|
|||
|
||||
"github.com/asticode/go-astisub"
|
||||
ffmpeg "github.com/u2takey/ffmpeg-go"
|
||||
"go.uber.org/multierr"
|
||||
|
||||
"srs.epita.fr/fic-server/admin/sync"
|
||||
)
|
||||
|
||||
func CheckGrammarSubtitleTrack(path string, index uint, lang string, exceptions *sync.CheckExceptions) (errs []error) {
|
||||
func CheckGrammarSubtitleTrack(path string, index uint, lang string, exceptions *sync.CheckExceptions) (errs error) {
|
||||
tmpfile, err := ioutil.TempFile("", "resolution-*.srt")
|
||||
if err != nil {
|
||||
errs = append(errs, fmt.Errorf("unable to create a temporary file: %w", err))
|
||||
errs = multierr.Append(errs, fmt.Errorf("unable to create a temporary file: %w", err))
|
||||
return
|
||||
}
|
||||
defer os.Remove(tmpfile.Name())
|
||||
|
|
@ -26,7 +27,7 @@ func CheckGrammarSubtitleTrack(path string, index uint, lang string, exceptions
|
|||
Output(tmpfile.Name(), ffmpeg.KwArgs{"map": fmt.Sprintf("0:%d", index)}).
|
||||
OverWriteOutput().Run()
|
||||
if err != nil {
|
||||
errs = append(errs, fmt.Errorf("ffmpeg returns an error when extracting subtitles track: %w", err))
|
||||
errs = multierr.Append(errs, fmt.Errorf("ffmpeg returns an error when extracting subtitles track: %w", err))
|
||||
}
|
||||
|
||||
subtitles, err := astisub.OpenFile(tmpfile.Name())
|
||||
|
|
@ -39,11 +40,11 @@ func CheckGrammarSubtitleTrack(path string, index uint, lang string, exceptions
|
|||
for _, item := range subtitles.Items {
|
||||
lines = append(lines, item.String())
|
||||
}
|
||||
for _, e := range hooks.CallCustomHook("CheckGrammar", struct {
|
||||
for _, e := range multierr.Errors(hooks.CallCustomHook("CheckGrammar", struct {
|
||||
Str string
|
||||
Language string
|
||||
}{Str: strings.Join(lines, "\n"), Language: lang[:2]}, exceptions) {
|
||||
errs = append(errs, fmt.Errorf("subtitle-track: %w", e))
|
||||
}{Str: strings.Join(lines, "\n"), Language: lang[:2]}, exceptions)) {
|
||||
errs = multierr.Append(errs, fmt.Errorf("subtitle-track: %w", e))
|
||||
}
|
||||
|
||||
return
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import (
|
|||
"strconv"
|
||||
|
||||
ffmpeg "github.com/u2takey/ffmpeg-go"
|
||||
"go.uber.org/multierr"
|
||||
|
||||
"srs.epita.fr/fic-server/admin/sync"
|
||||
"srs.epita.fr/fic-server/libfic"
|
||||
|
|
@ -49,7 +50,7 @@ func gcd(a, b int) int {
|
|||
return bgcd(a, b, 1)
|
||||
}
|
||||
|
||||
func checkResolutionVideo(e *fic.Exercice, exceptions *sync.CheckExceptions) (errs []error) {
|
||||
func checkResolutionVideo(e *fic.Exercice, exceptions *sync.CheckExceptions) (errs error) {
|
||||
i, ok := sync.GlobalImporter.(sync.LocalImporter)
|
||||
if !ok {
|
||||
log.Printf("Unable to load `videos-rules.so` as the current Importer is not a LocalImporter (%T).", sync.GlobalImporter)
|
||||
|
|
@ -71,7 +72,7 @@ func checkResolutionVideo(e *fic.Exercice, exceptions *sync.CheckExceptions) (er
|
|||
|
||||
data, err := ffmpeg.Probe(path)
|
||||
if err != nil {
|
||||
errs = append(errs, fmt.Errorf("unable to open %q: %w", path, err))
|
||||
errs = multierr.Append(errs, fmt.Errorf("unable to open %q: %w", path, err))
|
||||
return
|
||||
}
|
||||
|
||||
|
|
@ -87,79 +88,79 @@ func checkResolutionVideo(e *fic.Exercice, exceptions *sync.CheckExceptions) (er
|
|||
if s.CodecType == "video" {
|
||||
video_seen = append(video_seen, idx)
|
||||
if (s.Width > 1920 || s.Height > 1080) && !exceptions.HasException(":size:above_maximum") {
|
||||
errs = append(errs, fmt.Errorf("video track is too wide: %dx%d (maximum allowed: 1920x1080)", s.Width, s.Height))
|
||||
errs = multierr.Append(errs, fmt.Errorf("video track is too wide: %dx%d (maximum allowed: 1920x1080)", s.Width, s.Height))
|
||||
}
|
||||
|
||||
ratio := s.Width * 10 / s.Height
|
||||
if ratio < 13 || ratio > 19 && !exceptions.HasException(":size:strange_ratio") {
|
||||
m := gcd(s.Width, s.Height)
|
||||
errs = append(errs, fmt.Errorf("video track has a strange ratio: %d:%d. Is this really expected?", s.Width/m, s.Height/m))
|
||||
errs = multierr.Append(errs, fmt.Errorf("video track has a strange ratio: %d:%d. Is this really expected?", s.Width/m, s.Height/m))
|
||||
}
|
||||
|
||||
if s.CodecName != "h264" {
|
||||
errs = append(errs, fmt.Errorf("video codec has to be H264 (currently: %s)", s.CodecLongName))
|
||||
errs = multierr.Append(errs, fmt.Errorf("video codec has to be H264 (currently: %s)", s.CodecLongName))
|
||||
}
|
||||
|
||||
duration, err := strconv.ParseFloat(s.Duration, 64)
|
||||
if err == nil {
|
||||
if duration < 45 && !exceptions.HasException(":duration:too_short") {
|
||||
errs = append(errs, fmt.Errorf("video is too short"))
|
||||
errs = multierr.Append(errs, fmt.Errorf("video is too short"))
|
||||
}
|
||||
if duration > 450 && !exceptions.HasException(":duration:too_long") {
|
||||
errs = append(errs, fmt.Errorf("video is too long"))
|
||||
errs = multierr.Append(errs, fmt.Errorf("video is too long"))
|
||||
}
|
||||
} else {
|
||||
errs = append(errs, fmt.Errorf("invalid track duration: %q", s.Duration))
|
||||
errs = multierr.Append(errs, fmt.Errorf("invalid track duration: %q", s.Duration))
|
||||
}
|
||||
} else if s.CodecType == "subtitle" {
|
||||
subtitles_seen = append(subtitles_seen, idx)
|
||||
|
||||
if s.CodecName != "mov_text" {
|
||||
errs = append(errs, fmt.Errorf("subtitle format has to be MOV text/3GPP Timed Text (currently: %s)", s.CodecLongName))
|
||||
errs = multierr.Append(errs, fmt.Errorf("subtitle format has to be MOV text/3GPP Timed Text (currently: %s)", s.CodecLongName))
|
||||
}
|
||||
|
||||
nbframes, err := strconv.ParseInt(s.NbFrames, 10, 64)
|
||||
if err == nil {
|
||||
if nbframes < 5 && !exceptions.HasException(":subtitle:tiny") {
|
||||
errs = append(errs, fmt.Errorf("too few subtitles"))
|
||||
errs = multierr.Append(errs, fmt.Errorf("too few subtitles"))
|
||||
}
|
||||
} else {
|
||||
errs = append(errs, fmt.Errorf("invalid number of frame: %q", s.NbFrames))
|
||||
errs = multierr.Append(errs, fmt.Errorf("invalid number of frame: %q", s.NbFrames))
|
||||
}
|
||||
} else if s.CodecType == "audio" {
|
||||
if !exceptions.HasException(":audio:allowed") {
|
||||
errs = append(errs, fmt.Errorf("an audio track is present, use subtitle for explainations"))
|
||||
errs = multierr.Append(errs, fmt.Errorf("an audio track is present, use subtitle for explainations"))
|
||||
}
|
||||
|
||||
if s.CodecName != "aac" {
|
||||
errs = append(errs, fmt.Errorf("audio codec has to be AAC (Advanced Audio Coding) (currently: %s)", s.CodecLongName))
|
||||
errs = multierr.Append(errs, fmt.Errorf("audio codec has to be AAC (Advanced Audio Coding) (currently: %s)", s.CodecLongName))
|
||||
}
|
||||
} else {
|
||||
errs = append(errs, fmt.Errorf("unknown track found of type %q", s.CodecType))
|
||||
errs = multierr.Append(errs, fmt.Errorf("unknown track found of type %q", s.CodecType))
|
||||
}
|
||||
}
|
||||
|
||||
if len(video_seen) == 0 {
|
||||
errs = append(errs, fmt.Errorf("no video track found"))
|
||||
errs = multierr.Append(errs, fmt.Errorf("no video track found"))
|
||||
} else if len(video_seen) > 1 {
|
||||
errs = append(errs, fmt.Errorf("%d video tracks found, is it expected?", len(video_seen)))
|
||||
errs = multierr.Append(errs, fmt.Errorf("%d video tracks found, is it expected?", len(video_seen)))
|
||||
}
|
||||
if len(subtitles_seen) == 0 && !exceptions.HasException(":subtitle:no_track") {
|
||||
errs = append(errs, fmt.Errorf("no subtitles track found"))
|
||||
errs = multierr.Append(errs, fmt.Errorf("no subtitles track found"))
|
||||
} else if len(subtitles_seen) > 0 {
|
||||
for _, idx := range subtitles_seen {
|
||||
language := e.Language
|
||||
if lang, ok := vInfo.Streams[idx].Tags["language"]; e.Language != "" && (!ok || lang == "" || lang == "und") {
|
||||
errs = append(errs, fmt.Errorf("subtitles track %d with no language defined", vInfo.Streams[idx].Index))
|
||||
errs = multierr.Append(errs, fmt.Errorf("subtitles track %d with no language defined", vInfo.Streams[idx].Index))
|
||||
} else {
|
||||
language = lang
|
||||
}
|
||||
|
||||
errs = append(errs, CheckGrammarSubtitleTrack(path, vInfo.Streams[idx].Index, language, exceptions)...)
|
||||
errs = multierr.Append(errs, CheckGrammarSubtitleTrack(path, vInfo.Streams[idx].Index, language, exceptions))
|
||||
}
|
||||
|
||||
if e.Language != "" && len(subtitles_seen) < 2 {
|
||||
errs = append(errs, fmt.Errorf("subtitle tracks must exist in original language and translated, only one subtitle track found"))
|
||||
errs = multierr.Append(errs, fmt.Errorf("subtitle tracks must exist in original language and translated, only one subtitle track found"))
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
Reference in a new issue