diff --git a/CHANGELOG.md b/CHANGELOG.md index 55c0243..5b3cee6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # nextflow-io/nf-schema: Changelog +# Version 2.6.0 + +## Bug fixes + +1. Fixed a bug where Azure blob storage paths were incorrectly validated as directories. + # Version 2.5.1 ## Bug fixes diff --git a/src/main/groovy/nextflow/validation/validators/evaluators/FormatDirectoryPathEvaluator.groovy b/src/main/groovy/nextflow/validation/validators/evaluators/FormatDirectoryPathEvaluator.groovy index 5b610c1..2b3bbb7 100644 --- a/src/main/groovy/nextflow/validation/validators/evaluators/FormatDirectoryPathEvaluator.groovy +++ b/src/main/groovy/nextflow/validation/validators/evaluators/FormatDirectoryPathEvaluator.groovy @@ -24,22 +24,27 @@ class FormatDirectoryPathEvaluator implements Evaluator { } def String value = node.asString() + def Path file - try { file = Nextflow.file(value) as Path if (!(file instanceof List)) { file.exists() // Do an exists check to see if the file can be correctly accessed } } catch (Exception e) { - return Evaluator.Result.failure("could not validate file format of '${value}': ${e.message}" as String) + return Evaluator.Result.failure("could not validate directory format of '${value}': ${e.message}" as String) } // Actual validation logic if (file instanceof List) { return Evaluator.Result.failure("'${value}' is not a directory, but a file path pattern" as String) } + if (file.exists() && !file.isDirectory()) { + // If it's an Azure storage path, skip directory validation + if (value.startsWith('az://')) { + return Evaluator.Result.success() + } return Evaluator.Result.failure("'${value}' is not a directory, but a file" as String) } return Evaluator.Result.success() diff --git a/src/main/groovy/nextflow/validation/validators/evaluators/FormatFilePathEvaluator.groovy b/src/main/groovy/nextflow/validation/validators/evaluators/FormatFilePathEvaluator.groovy index ea43fb4..44eed11 100644 --- a/src/main/groovy/nextflow/validation/validators/evaluators/FormatFilePathEvaluator.groovy +++ b/src/main/groovy/nextflow/validation/validators/evaluators/FormatFilePathEvaluator.groovy @@ -25,7 +25,6 @@ class FormatFilePathEvaluator implements Evaluator { def String value = node.asString() def Path file - try { file = Nextflow.file(value) as Path if (!(file instanceof List)) { @@ -39,7 +38,12 @@ class FormatFilePathEvaluator implements Evaluator { if (file instanceof List) { return Evaluator.Result.failure("'${value}' is not a file, but a file path pattern" as String) } + if (file.exists() && file.isDirectory()) { + // If it's an Azure storage path, skip directoryvalidation + if(value.startsWith('az://')) { + return Evaluator.Result.success() + } return Evaluator.Result.failure("'${value}' is not a file, but a directory" as String) } return Evaluator.Result.success() diff --git a/src/main/groovy/nextflow/validation/validators/evaluators/FormatFilePathPatternEvaluator.groovy b/src/main/groovy/nextflow/validation/validators/evaluators/FormatFilePathPatternEvaluator.groovy index 74cde15..4e0c2fa 100644 --- a/src/main/groovy/nextflow/validation/validators/evaluators/FormatFilePathPatternEvaluator.groovy +++ b/src/main/groovy/nextflow/validation/validators/evaluators/FormatFilePathPatternEvaluator.groovy @@ -24,8 +24,8 @@ class FormatFilePathPatternEvaluator implements Evaluator { } def String value = node.asString() - def List files + def List files try { files = Nextflow.files(value) files.each { file -> @@ -41,7 +41,8 @@ class FormatFilePathPatternEvaluator implements Evaluator { return Evaluator.Result.failure("No files were found using the glob pattern '${value}'" as String) } files.each { file -> - if (file.isDirectory()) { + // If it's an Azure storage path, skip directory validation + if (file.isDirectory() && !file.toString().startsWith('az://')) { errors.add("'${file.toString()}' is not a file, but a directory" as String) } } diff --git a/src/main/groovy/nextflow/validation/validators/evaluators/SchemaEvaluator.groovy b/src/main/groovy/nextflow/validation/validators/evaluators/SchemaEvaluator.groovy index bb78d70..7b2458b 100644 --- a/src/main/groovy/nextflow/validation/validators/evaluators/SchemaEvaluator.groovy +++ b/src/main/groovy/nextflow/validation/validators/evaluators/SchemaEvaluator.groovy @@ -44,9 +44,16 @@ class SchemaEvaluator implements Evaluator { // Actual validation logic def Path file = Nextflow.file(value) - // Don't validate if the file does not exist or is a directory - if(!file.exists() || file.isDirectory()) { - log.debug("Could not validate the file ${file.toString()}") + + // Don't validate if the file does not exist + if(!file.exists()) { + log.debug("Could not validate the file ${file.toString()} - file does not exist") + return Evaluator.Result.success() + } + + // Skip validation if it's a directory + if(file.isDirectory() || value.startsWith('az://')) { + log.debug("Could not validate the file ${file.toString()} - path is a directory") return Evaluator.Result.success() } diff --git a/src/testResources/nextflow_schema_azure_path.json b/src/testResources/nextflow_schema_azure_path.json new file mode 100644 index 0000000..5549d7b --- /dev/null +++ b/src/testResources/nextflow_schema_azure_path.json @@ -0,0 +1,19 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://raw.githubusercontent.com/nf-core/nf-schema/master/examples/azurepath/nextflow_schema.json", + "title": "Azure path validation test", + "description": "Test schema for Azure path validation", + "type": "object", + "properties": { + "az_file": { + "type": "string", + "format": "file-path", + "description": "Azure storage file path" + }, + "az_directory": { + "type": "string", + "format": "directory-path", + "description": "Azure storage directory path" + } + } +}