Skip to content

Commit

Permalink
Re-organise Groovy lib/ classes
Browse files Browse the repository at this point in the history
  • Loading branch information
drpatelh committed May 4, 2021
1 parent fe9d707 commit 736dfad
Show file tree
Hide file tree
Showing 13 changed files with 899 additions and 672 deletions.
66 changes: 0 additions & 66 deletions lib/Checks.groovy

This file was deleted.

107 changes: 62 additions & 45 deletions lib/NfcoreSchema.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,24 @@ import groovy.json.JsonSlurper
import groovy.json.JsonBuilder

class NfcoreSchema {

/*
* Resolve Schema path relative to main workflow directory
*/
public static String getSchemaPath(workflow, schema_filename='nextflow_schema.json') {
return "${workflow.projectDir}/${schema_filename}"
}

/*
* Function to loop over all parameters defined in schema and check
* whether the given paremeters adhere to the specificiations
* whether the given parameters adhere to the specifications
*/
/* groovylint-disable-next-line UnusedPrivateMethodParameter */
public static void validateParameters(params, jsonSchema, log) {
public static void validateParameters(workflow, params, log, schema_filename='nextflow_schema.json') {
def has_error = false
//=====================================================================//
// Check for nextflow core params and unexpected params
def json = new File(jsonSchema).text
def json = new File(getSchemaPath(workflow, schema_filename=schema_filename)).text
def Map schemaParams = (Map) new JsonSlurper().parseText(json).get('definitions')
def nf_params = [
// Options for base `nextflow` command
Expand Down Expand Up @@ -119,36 +126,36 @@ class NfcoreSchema {

//=====================================================================//
// Validate parameters against the schema
InputStream inputStream = new File(jsonSchema).newInputStream()
JSONObject rawSchema = new JSONObject(new JSONTokener(inputStream))
InputStream input_stream = new File(getSchemaPath(workflow, schema_filename=schema_filename)).newInputStream()
JSONObject raw_schema = new JSONObject(new JSONTokener(input_stream))

// Remove anything that's in params.schema_ignore_params
rawSchema = removeIgnoredParams(rawSchema, params)
raw_schema = removeIgnoredParams(raw_schema, params)

Schema schema = SchemaLoader.load(rawSchema)
Schema schema = SchemaLoader.load(raw_schema)

// Clean the parameters
def cleanedParams = cleanParameters(params)

// Convert to JSONObject
def jsonParams = new JsonBuilder(cleanedParams)
JSONObject paramsJSON = new JSONObject(jsonParams.toString())
JSONObject params_json = new JSONObject(jsonParams.toString())

// Validate
try {
schema.validate(paramsJSON)
schema.validate(params_json)
} catch (ValidationException e) {
println ''
log.error 'ERROR: Validation of pipeline parameters failed!'
JSONObject exceptionJSON = e.toJSON()
printExceptions(exceptionJSON, paramsJSON, log)
printExceptions(exceptionJSON, params_json, log)
println ''
has_error = true
}

// Check for unexpected parameters
if (unexpectedParams.size() > 0) {
Map colors = Utils.logColours(params.monochrome_logs)
Map colors = NfcoreTemplate.logColours(params.monochrome_logs)
println ''
def warn_msg = 'Found unexpected parameters:'
for (unexpectedParam in unexpectedParams) {
Expand All @@ -167,13 +174,13 @@ class NfcoreSchema {
/*
* Beautify parameters for --help
*/
public static String paramsHelp(workflow, params, json_schema, command) {
Map colors = Utils.logColours(params.monochrome_logs)
public static String paramsHelp(workflow, params, command, schema_filename='nextflow_schema.json') {
Map colors = NfcoreTemplate.logColours(params.monochrome_logs)
Integer num_hidden = 0
String output = ''
output += 'Typical pipeline command:\n\n'
output += " ${colors.cyan}${command}${colors.reset}\n\n"
Map params_map = paramsLoad(json_schema)
Map params_map = paramsLoad(getSchemaPath(workflow, schema_filename=schema_filename))
Integer max_chars = paramsMaxChars(params_map) + 1
Integer desc_indent = max_chars + 14
Integer dec_linewidth = 160 - desc_indent
Expand Down Expand Up @@ -217,14 +224,14 @@ class NfcoreSchema {
if (num_hidden > 0){
output += colors.dim + "!! Hiding $num_hidden params, use --show_hidden_params to show them !!\n" + colors.reset
}
output += Utils.dashedLine(params.monochrome_logs)
output += NfcoreTemplate.dashedLine(params.monochrome_logs)
return output
}

/*
* Groovy Map summarising parameters/workflow options used by the pipeline
*/
public static LinkedHashMap paramsSummaryMap(workflow, params, json_schema) {
public static LinkedHashMap paramsSummaryMap(workflow, params, schema_filename='nextflow_schema.json') {
// Get a selection of core Nextflow workflow options
def Map workflow_summary = [:]
if (workflow.revision) {
Expand All @@ -247,7 +254,7 @@ class NfcoreSchema {
// Get pipeline parameters defined in JSON Schema
def Map params_summary = [:]
def blacklist = ['hostnames']
def params_map = paramsLoad(json_schema)
def params_map = paramsLoad(getSchemaPath(workflow, schema_filename=schema_filename))
for (group in params_map.keySet()) {
def sub_params = new LinkedHashMap()
def group_params = params_map.get(group) // This gets the parameters of that particular group
Expand Down Expand Up @@ -293,10 +300,10 @@ class NfcoreSchema {
/*
* Beautify parameters for summary and return as string
*/
public static String paramsSummaryLog(workflow, params, json_schema) {
Map colors = Utils.logColours(params.monochrome_logs)
public static String paramsSummaryLog(workflow, params) {
Map colors = NfcoreTemplate.logColours(params.monochrome_logs)
String output = ''
def params_map = paramsSummaryMap(workflow, params, json_schema)
def params_map = paramsSummaryMap(workflow, params)
def max_chars = paramsMaxChars(params_map)
for (group in params_map.keySet()) {
def group_params = params_map.get(group) // This gets the parameters of that particular group
Expand All @@ -309,52 +316,59 @@ class NfcoreSchema {
}
}
output += "!! Only displaying parameters that differ from the pipeline defaults !!\n"
output += Utils.dashedLine(params.monochrome_logs)
output += NfcoreTemplate.dashedLine(params.monochrome_logs)
return output
}

// Loop over nested exceptions and print the causingException
private static void printExceptions(exJSON, paramsJSON, log) {
def causingExceptions = exJSON['causingExceptions']
/*
* Loop over nested exceptions and print the causingException
*/
private static void printExceptions(ex_json, params_json, log) {
def causingExceptions = ex_json['causingExceptions']
if (causingExceptions.length() == 0) {
def m = exJSON['message'] =~ /required key \[([^\]]+)\] not found/
def m = ex_json['message'] =~ /required key \[([^\]]+)\] not found/
// Missing required param
if (m.matches()) {
log.error "* Missing required parameter: --${m[0][1]}"
}
// Other base-level error
else if (exJSON['pointerToViolation'] == '#') {
log.error "* ${exJSON['message']}"
else if (ex_json['pointerToViolation'] == '#') {
log.error "* ${ex_json['message']}"
}
// Error with specific param
else {
def param = exJSON['pointerToViolation'] - ~/^#\//
def param_val = paramsJSON[param].toString()
log.error "* --${param}: ${exJSON['message']} (${param_val})"
def param = ex_json['pointerToViolation'] - ~/^#\//
def param_val = params_json[param].toString()
log.error "* --${param}: ${ex_json['message']} (${param_val})"
}
}
for (ex in causingExceptions) {
printExceptions(ex, paramsJSON, log)
printExceptions(ex, params_json, log)
}
}

// Remove an element from a JSONArray
private static JSONArray removeElement(jsonArray, element) {
/*
* Remove an element from a JSONArray
*/
private static JSONArray removeElement(json_array, element) {
def list = []
int len = jsonArray.length()
int len = json_array.length()
for (int i=0;i<len;i++){
list.add(jsonArray.get(i).toString())
list.add(json_array.get(i).toString())
}
list.remove(element)
JSONArray jsArray = new JSONArray(list)
return jsArray
}

private static JSONObject removeIgnoredParams(rawSchema, params) {
/*
* Remove ignored parameters
*/
private static JSONObject removeIgnoredParams(raw_schema, params) {
// Remove anything that's in params.schema_ignore_params
params.schema_ignore_params.split(',').each{ ignore_param ->
if(rawSchema.keySet().contains('definitions')){
rawSchema.definitions.each { definition ->
if(raw_schema.keySet().contains('definitions')){
raw_schema.definitions.each { definition ->
for (key in definition.keySet()){
if (definition[key].get("properties").keySet().contains(ignore_param)){
// Remove the param to ignore
Expand All @@ -368,17 +382,20 @@ class NfcoreSchema {
}
}
}
if(rawSchema.keySet().contains('properties') && rawSchema.get('properties').keySet().contains(ignore_param)) {
rawSchema.get("properties").remove(ignore_param)
if(raw_schema.keySet().contains('properties') && raw_schema.get('properties').keySet().contains(ignore_param)) {
raw_schema.get("properties").remove(ignore_param)
}
if(rawSchema.keySet().contains('required') && rawSchema.required.contains(ignore_param)) {
def cleaned_required = removeElement(rawSchema.required, ignore_param)
rawSchema.put("required", cleaned_required)
if(raw_schema.keySet().contains('required') && raw_schema.required.contains(ignore_param)) {
def cleaned_required = removeElement(raw_schema.required, ignore_param)
raw_schema.put("required", cleaned_required)
}
}
return rawSchema
return raw_schema
}

/*
* Clean and check parameters relative to Nextflow native classes
*/
private static Map cleanParameters(params) {
def new_params = params.getClass().newInstance(params)
for (p in params) {
Expand All @@ -403,7 +420,7 @@ class NfcoreSchema {
}

/*
* This method tries to read a JSON params file
* This function tries to read a JSON params file
*/
private static LinkedHashMap paramsLoad(String json_schema) {
def params_map = new LinkedHashMap()
Expand Down
Loading

0 comments on commit 736dfad

Please sign in to comment.