package main import ( "flag" "fmt" "io/ioutil" "log" "os" "path" "path/filepath" "srs.epita.fr/fic-server/admin/sync" "srs.epita.fr/fic-server/libfic" ) var skipFileChecks = false func checkExercice(theme fic.Theme, edir string, dmap *map[int64]fic.Exercice) (errs []string) { e, _, eid, _, berrs := sync.BuildExercice(sync.GlobalImporter, theme, path.Join(theme.Path, edir), dmap) errs = append(errs, berrs...) if e != nil { // Files var files []string var cerrs []string if !skipFileChecks { files, cerrs = sync.CheckExerciceFiles(sync.GlobalImporter, *e) log.Printf("%d files checked.\n", len(files)) } else { 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...) // Flags flags, cerrs := sync.CheckExerciceFlags(sync.GlobalImporter, *e, files) errs = append(errs, cerrs...) log.Printf("%d flags checked.\n", len(flags)) // Hints hints, cerrs := sync.CheckExerciceHints(sync.GlobalImporter, *e) errs = append(errs, cerrs...) log.Printf("%d hints checked.\n", len(hints)) if dmap != nil { (*dmap)[int64(eid)] = *e } } return } func main() { cloudDAVBase := "" cloudUsername := "fic" cloudPassword := "" localImporterDirectory := "" // Read paremeters from environment if v, exists := os.LookupEnv("FICCLOUD_URL"); exists { cloudDAVBase = v } if v, exists := os.LookupEnv("FICCLOUD_USER"); exists { cloudUsername = v } if v, exists := os.LookupEnv("FICCLOUD_PASS"); exists { cloudPassword = v } // Read parameters from command line flag.StringVar(&localImporterDirectory, "localimport", localImporterDirectory, "Base directory where to find challenges files to import, local part") flag.StringVar(&cloudDAVBase, "clouddav", cloudDAVBase, "Base directory where to find challenges files to import, cloud part") flag.StringVar(&cloudUsername, "clouduser", cloudUsername, "Username used to sync") flag.StringVar(&cloudPassword, "cloudpass", cloudPassword, "Password used to sync") flag.BoolVar(&fic.OptionalDigest, "optionaldigest", fic.OptionalDigest, "Is the digest required when importing files?") flag.BoolVar(&fic.StrongDigest, "strongdigest", fic.StrongDigest, "Are BLAKE2b digests required or is SHA-1 good enough?") flag.BoolVar(&skipFileChecks, "skipfiledigests", skipFileChecks, "Don't perform DIGESTS checks on file to speed up the checks") flag.BoolVar(&sync.LogMissingResolution, "skipresolution", sync.LogMissingResolution, "Don't fail if resolution.mp4 is absent") flag.Parse() log.SetPrefix("[repochecker] ") // Instantiate importer regenImporter := false if localImporterDirectory != "" { sync.GlobalImporter = sync.LocalImporter{Base: localImporterDirectory, Symlink: true} } else if cloudDAVBase != "" { sync.GlobalImporter, _ = sync.NewCloudImporter(cloudDAVBase, cloudUsername, cloudPassword) } else { // In this case, we want to treat the entier path given regenImporter = true } var err error // Create temporary directory for storing FILES/ content fic.FilesDir, err = ioutil.TempDir("", "fic-repochecker.") if err != nil { } defer os.RemoveAll(fic.FilesDir) if sync.GlobalImporter != nil { log.Println("Using", sync.GlobalImporter.Kind()) if themes, err := sync.GetThemes(sync.GlobalImporter); err != nil { log.Fatal(err) } else if len(flag.Args()) == 0 { log.Println("Existing themes:") for _, th := range themes { log.Println("-", th) } os.Exit(1) } } else if len(flag.Args()) == 0 { log.Fatal("No importer nor path given!") } // Variable that handles the exit status hasError := false for _, p := range flag.Args() { if regenImporter { var err error p, err = filepath.Abs(p) if err != nil { p = path.Clean(p) } sync.GlobalImporter = sync.LocalImporter{ Base: path.Dir(p), Symlink: true, } p = path.Base(p) } nberr := 0 theme, errs := sync.BuildTheme(sync.GlobalImporter, p) if theme != nil { nberr += len(errs) for _, err := range errs { log.Println(err) } exercices, err := sync.GetExercices(sync.GlobalImporter, *theme) if err != nil { nberr += 1 log.Println(err) continue } dmap := map[int64]fic.Exercice{} for _, edir := range exercices { for _, err := range checkExercice(*theme, edir, &dmap) { nberr += 1 log.Println(err) } log.Printf("================================== Exercice %q treated\n", edir) } fmt.Printf("\n") log.Printf("Theme %q treated. %d error(s) reported.\n\n", p, nberr) } 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{}) { nberr += 1 log.Println(err) } fmt.Printf("\n") log.Printf("Exercice %q treated. %d error(s) reported.\n", p, nberr) } if nberr > 0 { hasError = true } } if hasError { os.Exit(1) } }