@@ -329,11 +329,11 @@ func validateODML(valroot, resdir string) error {
329
329
return nil
330
330
}
331
331
332
- func runValidator (validator , repopath , commit string , gcl * ginclient.Client ) {
332
+ func runValidatorBoth (validator , repopath , commit , commitname string , gcl * ginclient.Client , automatic bool ) string {
333
+ respath := filepath .Join (validator , repopath , commit )
333
334
go func () {
334
- log .ShowWrite ("[Info] Running %s validation on repository %q (%s)" , validator , repopath , commit )
335
+ log .ShowWrite ("[Info] Running %s validation on repository %q (%s)" , validator , repopath , commitname )
335
336
336
- srvcfg := config .Read ()
337
337
// TODO add check if a repo is currently being validated. Since the cloning
338
338
// can potentially take quite some time prohibit running the same
339
339
// validation at the same time. Could also move this to a mapped go
@@ -343,8 +343,9 @@ func runValidator(validator, repopath, commit string, gcl *ginclient.Client) {
343
343
344
344
// TODO: Use the payload data to check if the specific commit has already
345
345
// been validated
346
+ srvcfg := config .Read ()
347
+ resdir := filepath .Join (srvcfg .Dir .Result , respath )
346
348
347
- resdir := filepath .Join (srvcfg .Dir .Result , validator , repopath , commit )
348
349
// Create results folder if necessary
349
350
// CHECK: can this lead to a race condition, if a job for the same user/repo combination is started twice in short succession?
350
351
err := os .MkdirAll (resdir , os .ModePerm )
@@ -380,146 +381,23 @@ func runValidator(validator, repopath, commit string, gcl *ginclient.Client) {
380
381
log .ShowWrite ("[Error] writing results file for %q" , valroot )
381
382
}
382
383
383
- // Link 'latest' to new res dir to show processing
384
- latestdir := filepath .Join (filepath .Dir (resdir ), "latest" )
385
- os .Remove (latestdir ) // ignore error
386
- err = os .Symlink (resdir , latestdir )
387
- if err != nil {
388
- log .ShowWrite ("[Error] failed to link %q to %q: %s" , resdir , latestdir , err .Error ())
389
- // Don't return if processing badge write fails
390
- }
391
-
392
- err = makeSessionKey (gcl , commit )
393
- if err != nil {
394
- log .ShowWrite ("[error] failed to create session key: %s" , err .Error ())
395
- writeValFailure (resdir )
396
- return
397
- }
398
- defer deleteSessionKey (gcl , commit )
399
-
400
- // TODO: if (annexed) content is not available yet, wait and retry. We
401
- // would have to set a max timeout for this. The issue is that when a user
402
- // does a 'gin upload' a push happens immediately and the hook is
403
- // triggered, but annexed content is only transferred after the push and
404
- // could take a while (hours?). The validation service should try to
405
- // download content after the transfer is complete, or should keep retrying
406
- // until it's available, with a timeout. We could also make it more
407
- // efficient by only downloading the content in the directories which are
408
- // specified in the validator config (if it exists).
409
-
410
- glog .Init ()
411
- clonechan := make (chan git.RepoFileStatus )
412
- os .Chdir (tmpdir )
413
- go gcl .CloneRepo (repopath , clonechan )
414
- for stat := range clonechan {
415
- if stat .Err != nil {
416
- log .ShowWrite ("[Error] Failed to fetch repository data for %q: %s" , repopath , stat .Err .Error ())
417
- writeValFailure (resdir )
418
- return
384
+ if automatic { //TODO should be automatic or not?
385
+ // Link 'latest' to new res dir to show processing
386
+ latestdir := filepath .Join (filepath .Dir (resdir ), "latest" )
387
+ os .Remove (latestdir ) // ignore error
388
+ err = os .Symlink (resdir , latestdir )
389
+ if err != nil {
390
+ log .ShowWrite ("[Error] failed to link %q to %q: %s" , resdir , latestdir , err .Error ())
391
+ // Don't return if processing badge write fails
419
392
}
420
- log .ShowWrite ("[Info] %s %s" , stat .State , stat .Progress )
421
- }
422
- log .ShowWrite ("[Info] clone complete for '%s'" , repopath )
423
-
424
- // checkout specific commit then download all content
425
- log .ShowWrite ("[Info] git checkout %s" , commit )
426
- err = git .Checkout (commit , nil )
427
- if err != nil {
428
- log .ShowWrite ("[Error] failed to checkout commit %q: %s" , commit , err .Error ())
429
- writeValFailure (resdir )
430
- return
431
- }
432
-
433
- log .ShowWrite ("[Info] Downloading content" )
434
- getcontentchan := make (chan git.RepoFileStatus )
435
- // TODO: Get only the content for the files that will be validated
436
- go gcl .GetContent ([]string {"." }, getcontentchan )
437
- for stat := range getcontentchan {
438
- if stat .Err != nil {
439
- log .ShowWrite ("[Error] failed to get content for %q: %s" , repopath , stat .Err .Error ())
393
+ err = makeSessionKey (gcl , commit )
394
+ if err != nil {
395
+ log .ShowWrite ("[error] failed to create session key: %s" , err .Error ())
440
396
writeValFailure (resdir )
441
397
return
442
398
}
443
- log . ShowWrite ( "[Info] %s %s %s" , stat . State , stat . FileName , stat . Progress )
399
+ defer deleteSessionKey ( gcl , commit )
444
400
}
445
- log .ShowWrite ("[Info] get-content complete" )
446
-
447
- switch validator {
448
- case "bids" :
449
- err = validateBIDS (valroot , resdir )
450
- case "nix" :
451
- err = validateNIX (valroot , resdir )
452
- case "odml" :
453
- err = validateODML (valroot , resdir )
454
- default :
455
- err = fmt .Errorf ("[Error] invalid validator name: %s" , validator )
456
- }
457
-
458
- if err != nil {
459
- writeValFailure (resdir )
460
- }
461
- }()
462
- }
463
-
464
- func runValidatorPub (validator , repopath string , gcl * ginclient.Client ) string {
465
- uuid := uuid .New ()
466
- respath := filepath .Join (validator , repopath , uuid .String ())
467
- go func () {
468
- log .ShowWrite ("[Info] Running %s validation on repository %q (HEAD)" , validator , repopath )
469
-
470
- // TODO add check if a repo is currently being validated. Since the cloning
471
- // can potentially take quite some time prohibit running the same
472
- // validation at the same time. Could also move this to a mapped go
473
- // routine and if the same repo is validated twice, the first occurrence is
474
- // stopped and cleaned up while the second starts anew - to make sure its
475
- // always the latest state of the repository that is being validated.
476
-
477
- srvcfg := config .Read ()
478
- resdir := filepath .Join (srvcfg .Dir .Result , respath )
479
-
480
- // Create results folder if necessary
481
- // CHECK: can this lead to a race condition, if a job for the same user/repo combination is started twice in short succession?
482
- err := os .MkdirAll (resdir , os .ModePerm )
483
- if err != nil {
484
- log .ShowWrite ("[Error] creating %q results folder: %s" , resdir , err .Error ())
485
- return
486
- }
487
-
488
- tmpdir , err := ioutil .TempDir (srvcfg .Dir .Temp , validator )
489
- if err != nil {
490
- log .ShowWrite ("[Error] Internal error: Couldn't create temporary gin directory: %s" , err .Error ())
491
- writeValFailure (resdir )
492
- return
493
- }
494
-
495
- repopathparts := strings .SplitN (repopath , "/" , 2 )
496
- _ , repo := repopathparts [0 ], repopathparts [1 ]
497
- valroot := filepath .Join (tmpdir , repo )
498
-
499
- // Enable cleanup once tried and tested
500
- defer os .RemoveAll (tmpdir )
501
-
502
- // Add the processing badge and message to display while the validator runs
503
- procBadge := filepath .Join (resdir , srvcfg .Label .ResultsBadge )
504
- err = ioutil .WriteFile (procBadge , []byte (resources .ProcessingBadge ), os .ModePerm )
505
- if err != nil {
506
- log .ShowWrite ("[Error] writing results badge for %q" , valroot )
507
- }
508
-
509
- outFile := filepath .Join (resdir , srvcfg .Label .ResultsFile )
510
- err = ioutil .WriteFile (outFile , []byte (progressmsg ), os .ModePerm )
511
- if err != nil {
512
- log .ShowWrite ("[Error] writing results file for %q" , valroot )
513
- }
514
-
515
- // err = makeSessionKey(gcl, commit)
516
- // if err != nil {
517
- // log.ShowWrite("[error] failed to create session key: %s", err.Error())
518
- // writeValFailure(resdir)
519
- // return
520
- // }
521
- // defer deleteSessionKey(gcl, commit)
522
-
523
401
// TODO: if (annexed) content is not available yet, wait and retry. We
524
402
// would have to set a max timeout for this. The issue is that when a user
525
403
// does a 'gin upload' a push happens immediately and the hook is
@@ -544,6 +422,16 @@ func runValidatorPub(validator, repopath string, gcl *ginclient.Client) string {
544
422
}
545
423
log .ShowWrite ("[Info] clone complete for '%s'" , repopath )
546
424
425
+ if automatic {
426
+ // checkout specific commit then download all content
427
+ log .ShowWrite ("[Info] git checkout %s" , commit )
428
+ err = git .Checkout (commit , nil )
429
+ if err != nil {
430
+ log .ShowWrite ("[Error] failed to checkout commit %q: %s" , commit , err .Error ())
431
+ writeValFailure (resdir )
432
+ return
433
+ }
434
+ }
547
435
log .ShowWrite ("[Info] Downloading content" )
548
436
getcontentchan := make (chan git.RepoFileStatus )
549
437
// TODO: Get only the content for the files that will be validated
@@ -575,6 +463,15 @@ func runValidatorPub(validator, repopath string, gcl *ginclient.Client) string {
575
463
}()
576
464
return respath
577
465
}
466
+ func runValidator (validator , repopath , commit string , gcl * ginclient.Client ) {
467
+ automatic := true
468
+ runValidatorBoth (validator , repopath , commit , commit , gcl , automatic )
469
+ }
470
+
471
+ func runValidatorPub (validator , repopath string , gcl * ginclient.Client ) string {
472
+ automatic := false
473
+ return runValidatorBoth (validator , repopath , uuid .New ().String (), "HEAD" , gcl , automatic )
474
+ }
578
475
579
476
// writeValFailure writes a badge and page content for when a hook payload is
580
477
// valid, but the validator failed to run. This function does not return
@@ -683,6 +580,7 @@ func PubValidatePost(w http.ResponseWriter, r *http.Request) {
683
580
// repository is a valid BIDS dataset.
684
581
// Any cloned files are cleaned up after the check is done.
685
582
func Validate (w http.ResponseWriter , r * http.Request ) {
583
+ log .ShowWrite ("[Info] Entering validation" )
686
584
// TODO: Simplify/split this function
687
585
secret := r .Header .Get ("X-Gogs-Signature" )
688
586
@@ -714,6 +612,7 @@ func Validate(w http.ResponseWriter, r *http.Request) {
714
612
vars := mux .Vars (r )
715
613
validator := vars ["validator" ]
716
614
if ! helpers .SupportedValidator (validator ) {
615
+ log .ShowWrite ("[Error] unspuported validator (%v)" , validator )
717
616
fail (w , http .StatusNotFound , "unsupported validator" )
718
617
return
719
618
}
@@ -736,6 +635,7 @@ func Validate(w http.ResponseWriter, r *http.Request) {
736
635
ut , err := getTokenByRepo (repopath )
737
636
if err != nil {
738
637
// We don't have a valid token for this repository: can't clone
638
+ log .ShowWrite ("[Error] Bad Token: %v" , err )
739
639
msg := fmt .Sprintf ("accessing '%s': no access token found" , repopath )
740
640
fail (w , http .StatusUnauthorized , msg )
741
641
return
0 commit comments