Skip to content
This repository has been archived by the owner on Aug 20, 2024. It is now read-only.

Commit

Permalink
Merge pull request #40 from mirpedrol/new-entry-exists
Browse files Browse the repository at this point in the history
New entry exists
  • Loading branch information
mirpedrol authored Jun 5, 2023
2 parents a7f8358 + 6858bc4 commit 99a2826
Show file tree
Hide file tree
Showing 10 changed files with 98 additions and 90 deletions.
33 changes: 21 additions & 12 deletions docs/nextflow_schema/nextflow_schema_specification.md
Original file line number Diff line number Diff line change
Expand Up @@ -328,7 +328,7 @@ Formats can be used to give additional validation checks against `string` values
!!! note

In addition to _validating_ the strings as the provided format type, nf-validation also _coerces_ the parameter variable type.
That is: if the schema defines `params.input` as a `file-path-exists`, nf-validation will convert the parameter from a `String` into a `Nextflow.File`.
That is: if the schema defines `params.input` as a `file-path`, nf-validation will convert the parameter from a `String` into a `Nextflow.File`.

Example usage is as follows:

Expand All @@ -344,26 +344,35 @@ The available `format` types are below:
`file-path`
: States if the provided value is a file. Does not check its existence, but it does check that the path is not a directory.

`file-path-exists`
: Automatically checks if the provided value is a file (and not a directory), if it exists and transforms the `String` type to a `Nextflow.File` type, which is usable in Nextflow processes as a `path` input.

`directory-path`
: States if the provided value is a directory. Does not check its existence, but it does check that the path is not a file.

`directory-path-exists`
: Automatically checks if the provided value is a directory (and not a file), if it exists and transforms the `String` type to a `Nextflow.File` type, which is usable in Nextflow processes as a `path` input.
: States if the provided value is a directory. Does not check its existence, but if it exists, it does check that the path is not a file.

`path`
: States if the provided value is a path (file or directory). Does not check its existence.

`path-exists`
: Automatically checks if the path (file or directory) exists and transforms the `String` type to a `Nextflow.File` type, which is usable in Nextflow processes as a `path` input.
### `exists`

When a format is specified for a value, you can provide the key `exists` set to true in order to validate that the provided path exists.

Example usage is as follows:

```json
{
"type": "string",
"format": "file-path",
"exists": true
}
```

!!! note

If `exists` is set to `false`, this validation is ignored. Does not check if the path exists.

### `mimetype`

MIME type for a file path. Setting this value informs downstream tools about what _kind_ of file is expected.

Should only be set when `format` is `file-path` or `file-path-exists`.
Should only be set when `format` is `file-path`.

- See a [list of common MIME types](https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Common_types)

Expand All @@ -379,7 +388,7 @@ Should only be set when `format` is `file-path` or `file-path-exists`.

Path to a JSON schema file used to validate _the supplied file_.

Should only be set when `format` is `file-path` or `file-path-exists`.
Should only be set when `format` is `file-path`.

!!! tip

Expand Down
5 changes: 4 additions & 1 deletion docs/parameters/summary_log.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,10 @@ This function returns a string that can be logged to the terminal, summarizing t

!!! note

The summary prioritizes displaying only the parameters that are **different** the default schema values. This is to streamline the extensive parameter lists often associated with pipelines, and highlight the customized elements. This feature is essential for users to verify their configurations, like checking for typos or confirming proper resolution, without wading through an array of default settings.
The summary prioritizes displaying only the parameters that are **different** the default schema values.
This is to streamline the extensive parameter lists often associated with pipelines, and highlight the customized elements.
This feature is essential for users to verify their configurations, like checking for typos or confirming proper resolution,
without wading through an array of default settings.

The function takes two arguments:

Expand Down
9 changes: 6 additions & 3 deletions docs/schema_input.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,16 +32,19 @@
},
"field_7": {
"type": "string",
"format": "file-path-exists",
"format": "file-path",
"exists": true,
"pattern": "^.*\\.txt$"
},
"field_8": {
"type": "string",
"format": "directory-path-exists"
"format": "directory-path",
"exists": true
},
"field_9": {
"type": "string",
"format": "path-exists"
"format": "path",
"exists": true
},
"field_10": {
"type": "string",
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ public class DirectoryPathValidator implements FormatValidator {
@Override
public Optional<String> validate(final String subject) {
Path file = Nextflow.file(subject) as Path
if (!file.isDirectory()) {
if (file.exists() && !file.isDirectory()) {
return Optional.of("'${subject}' is not a directory, but a file" as String)
}
return Optional.empty()
Expand Down

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,13 @@ class SchemaValidator extends PluginExtensionPoint {
def List expectedParams = (List) enumsTuple[0] + addExpectedParams()
def Map enums = (Map) enumsTuple[1]

//=====================================================================//
// Check if files or directories exist
def List<String> pathsToCheck = (List) collectExists(schemaParams)
pathsToCheck.each {
pathExists(params[it].toString())
}

def Boolean lenientMode = params.validationLenientMode ? params.validationLenientMode : false
def Boolean failUnrecognisedParams = params.validationFailUnrecognisedParams ? params.validationFailUnrecognisedParams : false

Expand Down Expand Up @@ -303,6 +310,7 @@ class SchemaValidator extends PluginExtensionPoint {
.schemaJson(rawSchema)
.addFormatValidator("file-path", new FilePathValidator())
.addFormatValidator("directory-path", new DirectoryPathValidator())
.addFormatValidator("path", new PathValidator())
.build()
final schema = schemaLoader.load().build()

Expand Down Expand Up @@ -463,11 +471,8 @@ class SchemaValidator extends PluginExtensionPoint {
final SchemaLoader schemaLoader = SchemaLoader.builder()
.schemaJson(rawSchema)
.addFormatValidator("file-path", new FilePathValidator())
.addFormatValidator("file-path-exists", new FilePathExistsValidator())
.addFormatValidator("directory-path", new DirectoryPathValidator())
.addFormatValidator("directory-path-exists", new DirectoryPathExistsValidator())
.addFormatValidator("path", new PathValidator())
.addFormatValidator("path-exists", new PathExistsValidator())
.build()
final schema = schemaLoader.load().build()

Expand All @@ -491,6 +496,19 @@ class SchemaValidator extends PluginExtensionPoint {
def List expectedParams = (List) enumsTuple[0] + addExpectedParams()
def Map enums = (Map) enumsTuple[1]

//=====================================================================//
// Check if files or directories exist
def List<String> pathsToCheck = (List) collectExists(schemaParams)
pathsToCheck.each { fieldName ->
def String filedName = fieldName
for (int i=0; i < arrayJSON.size(); i++) {
def JSONObject entry = arrayJSON.getJSONObject(i)
if ( entry.has(filedName) ) {
pathExists(entry[filedName].toString())
}
}
}

//=====================================================================//
// Validate
try {
Expand All @@ -514,6 +532,38 @@ class SchemaValidator extends PluginExtensionPoint {
}


//
// Function to check if a file or directory exists
//
List pathExists(String path) {
def Path file = Nextflow.file(path) as Path
if (!file.exists()) {
errors << "* The file or directory '${path}' does not exist.".toString()
}
}


//
// Function to collect parameters with an exists key in the schema.
//
List collectExists(Map schemaParams) {
def exists = []
for (group in schemaParams) {
def Map properties = (Map) group.value['properties']
for (p in properties) {
def String key = (String) p.key
def Map property = properties[key] as Map
if (property.containsKey('exists') && property.containsKey('format')) {
if (property['exists'] && (property['format'] == 'file-path' || property['format'] == 'directory-path' || property['format'] == 'path') ) {
exists.push(key)
}
}
}
}
return exists
}


//
// Function to collect enums (options) of a parameter and expected parameters (present in the schema)
//
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -352,12 +352,12 @@ class SamplesheetConverterTest extends Dsl2Spec{
def error = thrown(SchemaValidationException)
def errorMessages = error.message.readLines()
errorMessages[0] == "\033[0;31mThe following errors have been detected:"
errorMessages[2] == '* -- Entry 1 - field_7: string [non_existing_file.tsv] does not match pattern ^.*\\.txt$ (non_existing_file.tsv)'
errorMessages[3] == "* -- Entry 1 - field_7: the file 'non_existing_file.tsv' does not exist (non_existing_file.tsv)"
errorMessages[4] == "* -- Entry 1 - field_8: 'src/testResources/test.txt' is not a directory (src/testResources/test.txt)"
errorMessages[5] == "* -- Entry 1 - field_5: expected type: Number, found: String (string)"
errorMessages[6] == "* -- Entry 1 - field_6: expected type: Boolean, found: String (20)"
errorMessages[7] == "* -- Entry 1 - field_9: the file or directory 'non_existing_path' does not exist (non_existing_path)"
errorMessages[2] == "* The file or directory 'non_existing_path' does not exist."
errorMessages[3] == "* The file or directory 'non_existing_file.tsv' does not exist."
errorMessages[4] == '* -- Entry 1 - field_7: string [non_existing_file.tsv] does not match pattern ^.*\\.txt$ (non_existing_file.tsv)'
errorMessages[5] == "* -- Entry 1 - field_8: 'src/testResources/test.txt' is not a directory, but a file (src/testResources/test.txt)"
errorMessages[6] == "* -- Entry 1 - field_5: expected type: Number, found: String (string)"
errorMessages[7] == "* -- Entry 1 - field_6: expected type: Boolean, found: String (20)"
errorMessages[8] == "* -- Entry 2: Missing required value: field_4"
errorMessages[9] == "* -- Entry 2: Missing required value: field_5"
errorMessages[10] == "* -- Entry 2: Missing required value: field_6"
Expand Down
11 changes: 7 additions & 4 deletions plugins/nf-validation/src/testResources/schema_input.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,17 +34,20 @@
},
"field_7": {
"type": "string",
"format": "file-path-exists",
"format": "file-path",
"exists": true,
"pattern": "^.*\\.txt$"
},
"field_8": {
"type": "string",
"format": "directory-path-exists"
"format": "directory-path",
"exists": true
},
"field_9": {
"type": "string",
"format": "path-exists"
},
"format": "path",
"exists": true
},
"field_10": {
"type": "string",
"unique": true
Expand Down

0 comments on commit 99a2826

Please sign in to comment.