From 8393d534d2163934f328589af6216e66f98637e1 Mon Sep 17 00:00:00 2001 From: "M. Sonntag" Date: Fri, 29 Jul 2022 14:43:29 +0200 Subject: [PATCH 01/12] [validate] Simplify validate funcs --- internal/web/validate.go | 30 +++++++++++------------------- 1 file changed, 11 insertions(+), 19 deletions(-) diff --git a/internal/web/validate.go b/internal/web/validate.go index ba39471..cc536b3 100644 --- a/internal/web/validate.go +++ b/internal/web/validate.go @@ -25,7 +25,6 @@ import ( "github.com/G-Node/gin-valid/internal/resources/templates" gogs "github.com/gogits/go-gogs-client" - "github.com/google/uuid" "github.com/gorilla/mux" ) @@ -342,10 +341,12 @@ func validateODML(valroot, resdir string) error { return nil } -func runValidatorBoth(validator, repopath, commit, commitname string, gcl *ginclient.Client, automatic bool) string { +func runValidator(validator, repopath, commit string, gcl *ginclient.Client) string { + checkoutCommit := commit == "HEAD" + respath := filepath.Join(validator, repopath, commit) go func() { - log.ShowWrite("[Info] running %s validation on repository %q (%s)", validator, repopath, commitname) + log.ShowWrite("[Info] running %s validation on repository %q (%s)", validator, repopath, commit) // TODO add check if a repo is currently being validated. Since the cloning // can potentially take quite some time prohibit running the same @@ -394,7 +395,7 @@ func runValidatorBoth(validator, repopath, commit, commitname string, gcl *gincl log.ShowWrite("[Error] writing results file for %q", valroot) } - if automatic { //TODO should be automatic or not? + if checkoutCommit { // Link 'latest' to new res dir to show processing latestdir := filepath.Join(filepath.Dir(resdir), "latest") err = os.Remove(latestdir) @@ -407,7 +408,7 @@ func runValidatorBoth(validator, repopath, commit, commitname string, gcl *gincl log.ShowWrite("[Error] failed to link %q to %q: %s", resdir, latestdir, err.Error()) } // create a session for the commit and the current validator; - // can lead to unpleasantness when multiple hooks trigger other wise + // can lead to unpleasantness when multiple hooks trigger otherwise keyname := fmt.Sprintf("%s-%s", commit, validator) log.ShowWrite("[Info] creating session key %q", keyname) err = makeSessionKey(gcl, keyname) @@ -435,7 +436,7 @@ func runValidatorBoth(validator, repopath, commit, commitname string, gcl *gincl log.ShowWrite("[Error] initializing log file: %s", err.Error()) } - err = cloneAndGet(gcl, tmpdir, commit, repopath, automatic) + err = cloneAndGet(gcl, tmpdir, commit, repopath, checkoutCommit) if err != nil { log.ShowWrite(err.Error()) writeValFailure(resdir) @@ -513,17 +514,6 @@ func cloneAndGet(gcl *ginclient.Client, tmpdir, commit, repopath string, checkou return nil } -func runValidator(validator, repopath, commit string, gcl *ginclient.Client) { - // change this automatic to a check for "HEAD" vs commit hash in the validator function - automatic := true - runValidatorBoth(validator, repopath, commit, commit, gcl, automatic) -} - -func runValidatorPub(validator, repopath string, gcl *ginclient.Client) string { - automatic := false - return runValidatorBoth(validator, repopath, uuid.New().String(), "HEAD", gcl, automatic) -} - // writeValFailure writes a badge and page content for when a hook payload is // valid, but the validator failed to run. This function does not return // anything, but logs all errors. @@ -599,6 +589,7 @@ func renderValidationForm(w http.ResponseWriter, r *http.Request, errMsg string) // PubValidatePost parses the POST data from the root form and calls the // validator using the built-in ServiceWaiter. func PubValidatePost(w http.ResponseWriter, r *http.Request) { + log.ShowWrite("[Info] starting public validation triggered manually") srvcfg := config.Read() ginuser := srvcfg.Settings.GINUser @@ -643,7 +634,8 @@ func PubValidatePost(w http.ResponseWriter, r *http.Request) { return } - respath := runValidatorPub(validator, repopath, gcl) + // Run public validation using the latest commit + respath := runValidator(validator, repopath, "HEAD", gcl) http.Redirect(w, r, filepath.Join("results", respath), http.StatusFound) } @@ -652,7 +644,7 @@ func PubValidatePost(w http.ResponseWriter, r *http.Request) { // repository is a valid BIDS dataset. // Any cloned files are cleaned up after the check is done. func Validate(w http.ResponseWriter, r *http.Request) { - log.ShowWrite("[Info] starting validation") + log.ShowWrite("[Info] starting validation triggered by hook") // TODO: Simplify/split this function secret := r.Header.Get("X-Gogs-Signature") From 2d6b9dd0282f8383fbf670f7e840cb94bba88420 Mon Sep 17 00:00:00 2001 From: "M. Sonntag" Date: Fri, 29 Jul 2022 14:44:20 +0200 Subject: [PATCH 02/12] [Dockerfile] Upgrade alpine run container version --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 610f2c7..2890a71 100644 --- a/Dockerfile +++ b/Dockerfile @@ -28,7 +28,7 @@ RUN go build ./cmd/ginvalid ### ============================ ### # RUNNER IMAGE -FROM alpine:3.14 +FROM alpine:3.16 # Runtime deps RUN echo http://dl-2.alpinelinux.org/alpine/edge/community/ >> /etc/apk/repositories From 473865750cfce83c5f6c990453c085483b77ecf8 Mon Sep 17 00:00:00 2001 From: "M. Sonntag" Date: Fri, 29 Jul 2022 14:44:46 +0200 Subject: [PATCH 03/12] [Dockerfile] Simplify nixio build --- Dockerfile | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/Dockerfile b/Dockerfile index 2890a71..8ded1c3 100644 --- a/Dockerfile +++ b/Dockerfile @@ -43,9 +43,8 @@ RUN apk --no-cache --no-progress add \ py3-tomli \ py3-pip \ python3-dev \ - py3-lxml \ - py3-h5py \ - py3-numpy + py3-numpy \ + py3-h5py # Install the BIDS validator RUN npm install -g bids-validator @@ -63,8 +62,7 @@ COPY ./scripts/odml-validate /bin COPY ./resources /resources # Install NIXPy for NIX validation -# Use master branch until new beta is released -RUN pip3 install --no-cache-dir -U git+https://github.com/G-Node/nixpy@master +RUN pip3 install --no-cache-dir nixio # Copy git-annex from builder image COPY --from=binbuilder /git-annex /git-annex From c05031b543bbde065e8779a498c394da0b0aae89 Mon Sep 17 00:00:00 2001 From: "M. Sonntag" Date: Fri, 29 Jul 2022 14:46:10 +0200 Subject: [PATCH 04/12] [Dockerfile] Remove nixio -h print --- Dockerfile | 1 - 1 file changed, 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 8ded1c3..1307ee8 100644 --- a/Dockerfile +++ b/Dockerfile @@ -84,7 +84,6 @@ COPY ./assets /assets # Test validation RUN odml-validate /resources/odmldata.odml -RUN nixio -h RUN nixio validate /resources/nixdata.nix RUN bids-validator --version From 829862605cd7a496c36be05b9dd2a1ccc00200d4 Mon Sep 17 00:00:00 2001 From: "M. Sonntag" Date: Fri, 29 Jul 2022 14:57:15 +0200 Subject: [PATCH 05/12] [validate] Refactor runValidate func Log any occured error from a validation run. --- internal/web/validate.go | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/internal/web/validate.go b/internal/web/validate.go index cc536b3..e79b1d6 100644 --- a/internal/web/validate.go +++ b/internal/web/validate.go @@ -379,7 +379,6 @@ func runValidator(validator, repopath, commit string, gcl *ginclient.Client) str _, repo := repopathparts[0], repopathparts[1] valroot := filepath.Join(tmpdir, repo) - // Enable cleanup once tried and tested defer os.RemoveAll(tmpdir) // Add the processing badge and message to display while the validator runs @@ -396,7 +395,7 @@ func runValidator(validator, repopath, commit string, gcl *ginclient.Client) str } if checkoutCommit { - // Link 'latest' to new res dir to show processing + // Link 'latest' to new results dir to show processing latestdir := filepath.Join(filepath.Dir(resdir), "latest") err = os.Remove(latestdir) if err != nil { @@ -407,7 +406,7 @@ func runValidator(validator, repopath, commit string, gcl *ginclient.Client) str // Don't return if processing badge write fails but log the issue log.ShowWrite("[Error] failed to link %q to %q: %s", resdir, latestdir, err.Error()) } - // create a session for the commit and the current validator; + // Create a session for the commit and the current validator; // can lead to unpleasantness when multiple hooks trigger otherwise keyname := fmt.Sprintf("%s-%s", commit, validator) log.ShowWrite("[Info] creating session key %q", keyname) @@ -419,6 +418,12 @@ func runValidator(validator, repopath, commit string, gcl *ginclient.Client) str } defer deleteSessionKey(gcl, keyname) } + + err = glog.Init() + if err != nil { + log.ShowWrite("[Error] initializing gin client log file: %s", err.Error()) + } + // TODO: if (annexed) content is not available yet, wait and retry. We // would have to set a max timeout for this. The issue is that when a user // does a 'gin upload' a push happens immediately and the hook is @@ -428,14 +433,6 @@ func runValidator(validator, repopath, commit string, gcl *ginclient.Client) str // until it's available, with a timeout. We could also make it more // efficient by only downloading the content in the directories which are // specified in the validator config (if it exists). - - err = glog.Init() - if err != nil { - // Weird to log after an error initializing the log file, - // but it should at least write to stdout. - log.ShowWrite("[Error] initializing log file: %s", err.Error()) - } - err = cloneAndGet(gcl, tmpdir, commit, repopath, checkoutCommit) if err != nil { log.ShowWrite(err.Error()) @@ -455,8 +452,7 @@ func runValidator(validator, repopath, commit string, gcl *ginclient.Client) str } if err != nil { - // this does not properly log the occurred error; do this here - // and refactor the function to include the type of validation that failed + log.ShowWrite(err.Error()) writeValFailure(resdir) } }() From 3e5e8f0eb5951133518c920c5b73fdf615718573 Mon Sep 17 00:00:00 2001 From: "M. Sonntag" Date: Fri, 29 Jul 2022 15:36:45 +0200 Subject: [PATCH 06/12] [validate] Add runNIXvalidation func --- internal/web/validate.go | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/internal/web/validate.go b/internal/web/validate.go index e79b1d6..3a113a2 100644 --- a/internal/web/validate.go +++ b/internal/web/validate.go @@ -165,6 +165,21 @@ func validateBIDS(valroot, resdir string) error { return nil } +// runNIXvalidation runs the nix validator on a specified file and +// returns the results of the validation. +func runNIXvalidation(nixexec, nixfile string) ([]byte, error) { + var out, serr bytes.Buffer + cmd := exec.Command(nixexec, "validate", nixfile) + out.Reset() + serr.Reset() + cmd.Stdout = &out + cmd.Stderr = &serr + if err := cmd.Run(); err != nil { + return nil, fmt.Errorf("[Error] running NIX validation %q, %q", err.Error(), serr.String()) + } + return out.Bytes(), nil +} + // validateNIX runs the NIX validator on the specified repository in 'path' // and saves the results to the appropriate document for later viewing. func validateNIX(valroot, resdir string) error { From 5c6b0753461e8bcdff2dbab36c67ca2fa6375283 Mon Sep 17 00:00:00 2001 From: "M. Sonntag" Date: Fri, 29 Jul 2022 15:37:12 +0200 Subject: [PATCH 07/12] [validate] Validate NIX files separately Closes #106 When a NIX file cannot be opened, the occurrence is logged as a validation error and the validation continues with the next NIX file. --- internal/web/validate.go | 43 ++++++++++++++++++++-------------------- 1 file changed, 21 insertions(+), 22 deletions(-) diff --git a/internal/web/validate.go b/internal/web/validate.go index 3a113a2..a588caa 100644 --- a/internal/web/validate.go +++ b/internal/web/validate.go @@ -183,12 +183,13 @@ func runNIXvalidation(nixexec, nixfile string) ([]byte, error) { // validateNIX runs the NIX validator on the specified repository in 'path' // and saves the results to the appropriate document for later viewing. func validateNIX(valroot, resdir string) error { + log.ShowWrite("[Info] starting NIX validation in %s", valroot) srvcfg := config.Read() // TODO: Allow validator config that specifies file paths to validate // For now we validate everything nixargs := make([]string, 0) - nixargs = append(nixargs, "validate") + // Find all NIX files (.nix) in the repository nixfinder := func(path string, info os.FileInfo, err error) error { if err != nil { @@ -215,35 +216,37 @@ func validateNIX(valroot, resdir string) error { err := filepath.Walk(valroot, nixfinder) if err != nil { - err = fmt.Errorf("[Error] while looking for NIX files in repository at %q: %s", valroot, err.Error()) - log.ShowWrite(err.Error()) - return err + return fmt.Errorf("[Error] while looking for NIX files in repository at %q: %s", valroot, err.Error()) } outBadge := filepath.Join(resdir, srvcfg.Label.ResultsBadge) // should walk through each file in the list individually; if there is a broken file, it breaks the whole process. - var out, serr bytes.Buffer - cmd := exec.Command(srvcfg.Exec.NIX, nixargs...) - out.Reset() - serr.Reset() - cmd.Stdout = &out - cmd.Stderr = &serr - // cmd.Dir = tmpdir - if err = cmd.Run(); err != nil { - err = fmt.Errorf("[Error] running NIX validation (%s): %q, %q", valroot, err.Error(), serr.String()) - log.ShowWrite(err.Error()) - return err + log.ShowWrite("[Info] found %d nix files: %v", len(nixargs), nixargs) + var output []byte + var invalidFile bool + for _, nixfile := range nixargs { + outbytes, err := runNIXvalidation(srvcfg.Exec.NIX, nixfile) + if err != nil { + log.ShowWrite("[Error] running validation on %s: %s", nixfile, err.Error()) + errout := fmt.Sprintf("Results for %q\n\tError: could not open file\n\n", nixfile) + output = append(output, errout...) + invalidFile = true + } else { + output = append(output, outbytes...) + } } // We need this for both the writing of the result and the badge errtag := []byte("with errors") warntag := []byte("with warnings") var badge []byte - output := out.Bytes() + // output := out.Bytes() switch { case bytes.Contains(output, errtag): badge = []byte(resources.ErrorBadge) + case invalidFile: + badge = []byte(resources.ErrorBadge) case bytes.Contains(output, warntag): badge = []byte(resources.WarningBadge) default: @@ -254,16 +257,12 @@ func validateNIX(valroot, resdir string) error { outFile := filepath.Join(resdir, srvcfg.Label.ResultsFile) err = ioutil.WriteFile(outFile, output, os.ModePerm) if err != nil { - err = fmt.Errorf("[Error] writing results file for %q", valroot) - log.ShowWrite(err.Error()) - return err + return fmt.Errorf("[Error] writing results file for %q", valroot) } err = ioutil.WriteFile(outBadge, badge, os.ModePerm) if err != nil { - err = fmt.Errorf("[Error] writing results badge for %q", valroot) - log.ShowWrite(err.Error()) - return err + return fmt.Errorf("[Error] writing results badge for %q", valroot) } log.ShowWrite("[Info] finished validating repo at %q", valroot) From 517fedde042eb41bee59e7dd4535323d009b4d9e Mon Sep 17 00:00:00 2001 From: "M. Sonntag" Date: Fri, 29 Jul 2022 15:50:24 +0200 Subject: [PATCH 08/12] [validate] Fix commit checkout --- internal/web/validate.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/web/validate.go b/internal/web/validate.go index a588caa..73f4e12 100644 --- a/internal/web/validate.go +++ b/internal/web/validate.go @@ -356,7 +356,7 @@ func validateODML(valroot, resdir string) error { } func runValidator(validator, repopath, commit string, gcl *ginclient.Client) string { - checkoutCommit := commit == "HEAD" + checkoutCommit := commit != "HEAD" respath := filepath.Join(validator, repopath, commit) go func() { From 0e368cc8801419feac4d44519264bc04e846c618 Mon Sep 17 00:00:00 2001 From: "M. Sonntag" Date: Fri, 29 Jul 2022 16:14:53 +0200 Subject: [PATCH 09/12] [ginutils] Add getRepoCommit func --- internal/web/ginutils.go | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/internal/web/ginutils.go b/internal/web/ginutils.go index e16a19f..300ce76 100644 --- a/internal/web/ginutils.go +++ b/internal/web/ginutils.go @@ -4,6 +4,7 @@ import ( "bytes" "encoding/json" "fmt" + "io/ioutil" "os" "os/user" "path/filepath" @@ -494,3 +495,19 @@ func remoteCommitCheckout(gitdir, hash string) error { } return nil } + +// getRepoCommit uses a gin client connection to query the latest commit +// of a provided gin repository and returns either an error or +// the commit hash as a string. +func getRepoCommit(client *ginclient.Client, repo string) (string, error) { + reqpath := fmt.Sprintf("api/v1/repos/%s/commits/refs/heads/master", repo) + resp, err := client.Get(reqpath) + if err != nil { + return "", fmt.Errorf("failed to get latest commit hash for %q: %s", repo, err.Error()) + } + data, err := ioutil.ReadAll(resp.Body) + if err != nil { + return "", fmt.Errorf("failed to read latest commit hash from response for %q: %s", repo, err.Error()) + } + return string(data), nil +} From 9e7fe25d0fda1719cc68da681f9558dd88a3b1e8 Mon Sep 17 00:00:00 2001 From: "M. Sonntag" Date: Fri, 29 Jul 2022 16:16:11 +0200 Subject: [PATCH 10/12] [validate] Fetch commit hash on pub validation Using the latest commit hash of a repository to create the results badge for a public validation. --- internal/web/validate.go | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/internal/web/validate.go b/internal/web/validate.go index 73f4e12..dd9fb49 100644 --- a/internal/web/validate.go +++ b/internal/web/validate.go @@ -355,10 +355,26 @@ func validateODML(valroot, resdir string) error { return nil } +// handleHeadCommit returns the latest commit hash of a repository, if HEAD is being used +// as commit string; otherwise return the commit string unchanged. +func handleHeadCommit(repopath, checkCommit string, gcl *ginclient.Client) string { + if checkCommit != "HEAD" { + return checkCommit + } + useCommitName, err := getRepoCommit(gcl, repopath) + if err != nil { + log.ShowWrite("[Error] could not fetch latest commit for repo %s: %s", repopath, err.Error()) + return checkCommit + } + log.ShowWrite("[Info] repo %s uses commit %s as HEAD commit", repopath, useCommitName) + return useCommitName +} + func runValidator(validator, repopath, commit string, gcl *ginclient.Client) string { checkoutCommit := commit != "HEAD" + useCommitName := handleHeadCommit(repopath, commit, gcl) + respath := filepath.Join(validator, repopath, useCommitName) - respath := filepath.Join(validator, repopath, commit) go func() { log.ShowWrite("[Info] running %s validation on repository %q (%s)", validator, repopath, commit) From 3c14ab0b7af16357ed916ac3bc17f64e68273255 Mon Sep 17 00:00:00 2001 From: "M. Sonntag" Date: Fri, 29 Jul 2022 16:31:44 +0200 Subject: [PATCH 11/12] [validate] Remove redundant error logging --- internal/web/validate.go | 33 ++++++++------------------------- 1 file changed, 8 insertions(+), 25 deletions(-) diff --git a/internal/web/validate.go b/internal/web/validate.go index dd9fb49..958bcd2 100644 --- a/internal/web/validate.go +++ b/internal/web/validate.go @@ -112,7 +112,6 @@ func validateBIDS(valroot, resdir string) error { args = append(args, "--json") args = append(args, valroot) - // cmd = exec.Command(srvcfg.Exec.BIDS, validateNifti, "--json", valroot) var out, serr bytes.Buffer cmd := exec.Command(srvcfg.Exec.BIDS, args...) out.Reset() @@ -121,9 +120,7 @@ func validateBIDS(valroot, resdir string) error { cmd.Stderr = &serr // cmd.Dir = tmpdir if err := cmd.Run(); err != nil { - err = fmt.Errorf("[Error] running bids validation (%s): %q, %q", valroot, err.Error(), serr.String()) - log.ShowWrite(err.Error()) - return err + return fmt.Errorf("[Error] running bids validation (%s): %q, %q", valroot, err.Error(), serr.String()) } // We need this for both the writing of the result and the badge @@ -133,9 +130,7 @@ func validateBIDS(valroot, resdir string) error { outFile := filepath.Join(resdir, srvcfg.Label.ResultsFile) err := ioutil.WriteFile(outFile, []byte(output), os.ModePerm) if err != nil { - err = fmt.Errorf("[Error] writing results file for %q", valroot) - log.ShowWrite(err.Error()) - return err + return fmt.Errorf("[Error] writing results file for %q", valroot) } // Write proper badge according to result @@ -143,9 +138,7 @@ func validateBIDS(valroot, resdir string) error { var parseBIDS BidsRoot err = json.Unmarshal(output, &parseBIDS) if err != nil { - err = fmt.Errorf("[Error] unmarshalling results json: %s", err.Error()) - log.ShowWrite(err.Error()) - return err + return fmt.Errorf("[Error] unmarshalling results json: %s", err.Error()) } if len(parseBIDS.Issues.Errors) > 0 { @@ -156,9 +149,7 @@ func validateBIDS(valroot, resdir string) error { err = ioutil.WriteFile(outBadge, []byte(content), os.ModePerm) if err != nil { - err = fmt.Errorf("[Error] writing results badge for %q", valroot) - log.ShowWrite(err.Error()) - return err + return fmt.Errorf("[Error] writing results badge for %q", valroot) } log.ShowWrite("[Info] finished validating repo at %q", valroot) @@ -301,9 +292,7 @@ func validateODML(valroot, resdir string) error { err := filepath.Walk(valroot, odmlfinder) if err != nil { - err = fmt.Errorf("[Error] while looking for odML files in repository at %q: %s", valroot, err.Error()) - log.ShowWrite(err.Error()) - return err + return fmt.Errorf("[Error] while looking for odML files in repository at %q: %s", valroot, err.Error()) } outBadge := filepath.Join(resdir, srvcfg.Label.ResultsBadge) @@ -315,9 +304,7 @@ func validateODML(valroot, resdir string) error { cmd.Stdout = &out cmd.Stderr = &serr if err = cmd.Run(); err != nil { - err = fmt.Errorf("[Error] running odML validation (%s): '%s', '%s'", valroot, err.Error(), serr.String()) - log.ShowWrite(err.Error()) - return err + return fmt.Errorf("[Error] running odML validation (%s): '%s', '%s'", valroot, err.Error(), serr.String()) } // We need this for both the writing of the result and the badge @@ -339,16 +326,12 @@ func validateODML(valroot, resdir string) error { outFile := filepath.Join(resdir, srvcfg.Label.ResultsFile) err = ioutil.WriteFile(outFile, output, os.ModePerm) if err != nil { - err = fmt.Errorf("[Error] writing results file for %q", valroot) - log.ShowWrite(err.Error()) - return err + return fmt.Errorf("[Error] writing results file for %q", valroot) } err = ioutil.WriteFile(outBadge, badge, os.ModePerm) if err != nil { - err = fmt.Errorf("[Error] writing results badge for %q", valroot) - log.ShowWrite(err.Error()) - return err + return fmt.Errorf("[Error] writing results badge for %q", valroot) } log.ShowWrite("[Info] finished validating repo at %q", valroot) From 01a7e6ba1c4e05ab60996cfacd6ca0dc2f086bc1 Mon Sep 17 00:00:00 2001 From: "M. Sonntag" Date: Fri, 29 Jul 2022 16:41:42 +0200 Subject: [PATCH 12/12] [validate] Provide invalid BIDS root error Closes #107 Provide the appropriate error when the BIDS validator is not run from the root BIDS folder structure. --- internal/web/validate.go | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/internal/web/validate.go b/internal/web/validate.go index 958bcd2..648a755 100644 --- a/internal/web/validate.go +++ b/internal/web/validate.go @@ -77,9 +77,9 @@ func handleValidationConfig(cfgpath string) (Validationcfg, error) { // and saves the results to the appropriate document for later viewing. func validateBIDS(valroot, resdir string) error { srvcfg := config.Read() - // Use validation config file if available var validateNifti bool + // Use validation config file if available cfgpath := filepath.Join(valroot, srvcfg.Label.ValidationConfigFile) log.ShowWrite("[Info] looking for config file at %q", cfgpath) if fi, err := os.Stat(cfgpath); err == nil && !fi.IsDir() { @@ -118,9 +118,11 @@ func validateBIDS(valroot, resdir string) error { serr.Reset() cmd.Stdout = &out cmd.Stderr = &serr - // cmd.Dir = tmpdir - if err := cmd.Run(); err != nil { - return fmt.Errorf("[Error] running bids validation (%s): %q, %q", valroot, err.Error(), serr.String()) + err := cmd.Run() + // Only return if the error is not related to the bids validation; if the out string contains information + // we can continue + if err != nil && !strings.Contains(out.String(), "QUICK_VALIDATION_FAILED") { + return fmt.Errorf("[Error] running bids validation (%s): %q, %q, %q", valroot, err.Error(), serr.String(), out.String()) } // We need this for both the writing of the result and the badge @@ -128,7 +130,7 @@ func validateBIDS(valroot, resdir string) error { // CHECK: can this lead to a race condition, if a job for the same user/repo combination is started twice in short succession? outFile := filepath.Join(resdir, srvcfg.Label.ResultsFile) - err := ioutil.WriteFile(outFile, []byte(output), os.ModePerm) + err = ioutil.WriteFile(outFile, []byte(output), os.ModePerm) if err != nil { return fmt.Errorf("[Error] writing results file for %q", valroot) }