-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Copy in schema generated workflow parser (and linter) from gxformat2.
- Loading branch information
Showing
80 changed files
with
5,143 additions
and
0 deletions.
There are no files selected for viewing
15 changes: 15 additions & 0 deletions
15
src/main/java/org/galaxyproject/gxformat2/Format2Linter.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
package org.galaxyproject.gxformat2; | ||
|
||
import java.util.Map; | ||
import org.galaxyproject.gxformat2.v19_09.utils.RootLoader; | ||
import org.galaxyproject.gxformat2.v19_09.utils.ValidationException; | ||
|
||
public class Format2Linter implements GalaxyWorkflowLinter { | ||
public void lint(final LintContext lintContext, final Map<String, Object> workflow) { | ||
try { | ||
RootLoader.loadDocument(workflow); | ||
} catch (ValidationException e) { | ||
lintContext.error("Validation failed " + e.toString()); | ||
} | ||
} | ||
} |
7 changes: 7 additions & 0 deletions
7
src/main/java/org/galaxyproject/gxformat2/GalaxyWorkflowLinter.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
package org.galaxyproject.gxformat2; | ||
|
||
import java.util.Map; | ||
|
||
public interface GalaxyWorkflowLinter { | ||
public void lint(final LintContext lintContext, final Map<String, Object> workflow); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
package org.galaxyproject.gxformat2; | ||
|
||
import java.nio.file.Files; | ||
import java.nio.file.Path; | ||
import java.nio.file.Paths; | ||
import java.util.Map; | ||
import org.yaml.snakeyaml.Yaml; | ||
|
||
public class Lint { | ||
public static int EXIT_CODE_SUCCESS = 0; | ||
public static int EXIT_CODE_LINT_FAILED = 1; | ||
public static int EXIT_CODE_FORMAT_ERROR = 2; | ||
public static int EXIT_CODE_FILE_PARSE_FAILED = 3; | ||
|
||
public static void main(String[] args) throws Exception { | ||
final int exitCode = lint(args); | ||
System.exit(exitCode); | ||
} | ||
|
||
public static int lint(final String[] args) throws Exception { | ||
final Path path = Paths.get(args[0]); | ||
final String workflowContents = new String(Files.readAllBytes(path), "UTF8"); | ||
final Yaml yaml = new Yaml(); | ||
final Map<String, Object> object = (Map<String, Object>) yaml.load(workflowContents); | ||
final String wfClass = (String) object.get("class"); | ||
GalaxyWorkflowLinter linter; | ||
if (wfClass != null && wfClass.equals("GalaxyWorkflow")) { | ||
linter = new Format2Linter(); | ||
} else { | ||
linter = new NativeLinter(); | ||
} | ||
final LintContext lintContext = new LintContext(); | ||
linter.lint(lintContext, object); | ||
lintContext.printMessages(); | ||
int exitCode; | ||
if (lintContext.getFoundErrors()) { | ||
exitCode = EXIT_CODE_FORMAT_ERROR; | ||
} else if (lintContext.getFoundWarns()) { | ||
exitCode = EXIT_CODE_LINT_FAILED; | ||
} else { | ||
exitCode = EXIT_CODE_SUCCESS; | ||
} | ||
return exitCode; | ||
} | ||
} |
52 changes: 52 additions & 0 deletions
52
src/main/java/org/galaxyproject/gxformat2/LintContext.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
package org.galaxyproject.gxformat2; | ||
|
||
import java.util.ArrayList; | ||
import java.util.List; | ||
|
||
public class LintContext { | ||
private boolean foundErrors = false; | ||
private boolean foundWarns = false; | ||
|
||
private List<String> validMessages = new ArrayList<String>(); | ||
private List<String> infoMessages = new ArrayList<String>(); | ||
private List<String> warnMessages = new ArrayList<String>(); | ||
private List<String> errorMessages = new ArrayList<String>(); | ||
|
||
LintContext() {} | ||
|
||
boolean getFoundErrors() { | ||
return this.foundErrors; | ||
} | ||
|
||
boolean getFoundWarns() { | ||
return this.foundWarns; | ||
} | ||
|
||
void valid(String message, Object... args) { | ||
this.validMessages.add(String.format(message, args)); | ||
} | ||
|
||
void info(String message, Object... args) { | ||
this.infoMessages.add(String.format(message, args)); | ||
} | ||
|
||
void error(String message, Object... args) { | ||
this.errorMessages.add(String.format(message, args)); | ||
} | ||
|
||
void warn(String message, Object... args) { | ||
this.warnMessages.add(String.format(message, args)); | ||
} | ||
|
||
void printMessages() { | ||
for (final String message : this.errorMessages) { | ||
this.foundErrors = true; | ||
System.out.print(".. ERROR " + message); | ||
} | ||
|
||
for (final String message : this.warnMessages) { | ||
this.foundWarns = true; | ||
System.out.print(".. WARNING " + message); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
package org.galaxyproject.gxformat2; | ||
|
||
import java.util.Map; | ||
|
||
class LintUtils { | ||
static <T> T ensureKey( | ||
LintContext lintContext, Object hasKeys, String key, Class<T> hasClass, Object hasValue) { | ||
if (!(hasKeys instanceof Map)) { | ||
lintContext.error("expected [%s] to be a dictionary type", hasKeys); | ||
return null; | ||
} | ||
final Map<String, Object> map = (Map<String, Object>) hasKeys; | ||
if (!map.containsKey(key)) { | ||
lintContext.error("expected to have key [%s] but absent", key); | ||
} | ||
final Object value = map.get(key); | ||
return ensureKeyHasValue(lintContext, map, key, value, hasClass, hasValue); | ||
} | ||
|
||
static <T> T ensureKeyIfPresent( | ||
LintContext lintContext, Object hasKeys, String key, T defaultValue, Class<T> hasClass) { | ||
if (!(hasKeys instanceof Map)) { | ||
lintContext.error("expected [%s] to be a dictionary type", hasKeys); | ||
return null; | ||
} | ||
final Map<String, Object> map = (Map<String, Object>) hasKeys; | ||
if (!map.containsKey(key)) { | ||
return defaultValue; | ||
} | ||
final Object value = map.get(key); | ||
return ensureKeyHasValue(lintContext, map, key, value, hasClass, null); | ||
} | ||
|
||
static <T> T ensureKeyHasValue( | ||
LintContext lintContext, | ||
Map hasKeys, | ||
String key, | ||
Object value, | ||
Class<T> hasClass, | ||
Object hasValue) { | ||
if (!hasClass.isInstance(value)) { | ||
lintContext.error( | ||
"expected value [%s] with key [%s] to be of class %s", key, value, hasClass); | ||
return null; | ||
} | ||
if (hasValue != null && !hasValue.equals(value)) { | ||
lintContext.error("expected value [%s] with key [%s] to be %s", key, value, hasValue); | ||
} | ||
return (T) value; | ||
} | ||
} |
64 changes: 64 additions & 0 deletions
64
src/main/java/org/galaxyproject/gxformat2/NativeLinter.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
package org.galaxyproject.gxformat2; | ||
|
||
import java.util.ArrayList; | ||
import java.util.List; | ||
import java.util.Map; | ||
|
||
public class NativeLinter implements GalaxyWorkflowLinter { | ||
public static String LINT_FAILED_NO_OUTPUTS = "Workflow contained no outputs"; | ||
public static String LINT_FAILED_OUTPUT_NO_LABEL = "Workflow contained output without a label"; | ||
|
||
public void lint(final LintContext lintContext, final Map<String, Object> workflow) { | ||
LintUtils.ensureKey(lintContext, workflow, "format-version", String.class, "0.1"); | ||
LintUtils.ensureKey(lintContext, workflow, "a_galaxy_workflow", String.class, "true"); | ||
|
||
final Map<String, Object> steps = | ||
(Map<String, Object>) LintUtils.ensureKey(lintContext, workflow, "steps", Map.class, null); | ||
boolean foundOutputs = false; | ||
boolean foundOutputsWithoutLabel = false; | ||
if (steps != null) { | ||
for (Map.Entry<String, Object> stepEntry : steps.entrySet()) { | ||
final String orderIndexStr = stepEntry.getKey(); | ||
try { | ||
final int orderIndex = Integer.parseInt(orderIndexStr); | ||
} catch (NumberFormatException e) { | ||
lintContext.error("expected step_key to be integer not [%s]", orderIndexStr); | ||
} | ||
if (!(stepEntry.getValue() instanceof Map)) { | ||
lintContext.error("expected step value to be Map not [%s]", stepEntry.getValue()); | ||
} | ||
Map<String, Object> step = (Map<String, Object>) stepEntry.getValue(); | ||
List<String> workflowOutputs = | ||
LintUtils.ensureKeyIfPresent( | ||
lintContext, step, "workflow_outputs", new ArrayList<String>(), List.class); | ||
for (Object workflowOutputObject : workflowOutputs) { | ||
foundOutputs = true; | ||
if (!(workflowOutputObject instanceof Map)) { | ||
lintContext.error("Not a map"); | ||
} | ||
final Map<String, String> workflowOutput = (Map<String, String>) workflowOutputObject; | ||
final String label = workflowOutput.get("label"); | ||
if (label == null || label.length() == 0) { | ||
foundOutputsWithoutLabel = true; | ||
} | ||
} | ||
final String stepType = | ||
LintUtils.ensureKeyIfPresent(lintContext, step, "type", "tool", String.class); | ||
assert stepType != null; | ||
if (stepType != null && stepType.equals("subworkflow")) { | ||
final Map<String, Object> subworkflow = | ||
(Map<String, Object>) | ||
LintUtils.ensureKey(lintContext, step, "subworkflow", Map.class, null); | ||
assert subworkflow != null; | ||
lint(lintContext, subworkflow); | ||
} | ||
} | ||
} | ||
if (!foundOutputs) { | ||
lintContext.warn(LINT_FAILED_NO_OUTPUTS); | ||
} | ||
if (foundOutputsWithoutLabel) { | ||
lintContext.warn(LINT_FAILED_OUTPUT_NO_LABEL); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
package org.galaxyproject.gxformat2.v19_09; | ||
|
||
import org.galaxyproject.gxformat2.v19_09.utils.ValidationException; | ||
|
||
public enum Any { | ||
ANY("Any"); | ||
|
||
private static String[] symbols = new String[] {"Any"}; | ||
private String docVal; | ||
|
||
private Any(final String docVal) { | ||
this.docVal = docVal; | ||
} | ||
|
||
public static Any fromDocumentVal(final String docVal) { | ||
for (final Any val : Any.values()) { | ||
if (val.docVal.equals(docVal)) { | ||
return val; | ||
} | ||
} | ||
throw new ValidationException(String.format("Expected one of %s", Any.symbols, docVal)); | ||
} | ||
} |
30 changes: 30 additions & 0 deletions
30
src/main/java/org/galaxyproject/gxformat2/v19_09/ArraySchema.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
package org.galaxyproject.gxformat2.v19_09; | ||
|
||
import org.galaxyproject.gxformat2.v19_09.utils.Savable; | ||
|
||
/** | ||
* Auto-generated interface for <I>https://w3id.org/cwl/salad#ArraySchema</I><br> | ||
* This interface is implemented by {@link ArraySchemaImpl}<br> | ||
*/ | ||
public interface ArraySchema extends Savable { | ||
/** | ||
* Getter for property <I>https://w3id.org/cwl/salad#items</I><br> | ||
* | ||
* <BLOCKQUOTE> | ||
* | ||
* Defines the type of the array elements. * | ||
* | ||
* </BLOCKQUOTE> | ||
*/ | ||
Object getItems(); | ||
/** | ||
* Getter for property <I>https://w3id.org/cwl/salad#type</I><br> | ||
* | ||
* <BLOCKQUOTE> | ||
* | ||
* Must be `array` * | ||
* | ||
* </BLOCKQUOTE> | ||
*/ | ||
enum_d062602be0b4b8fd33e69e29a841317b6ab665bc getType(); | ||
} |
102 changes: 102 additions & 0 deletions
102
src/main/java/org/galaxyproject/gxformat2/v19_09/ArraySchemaImpl.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
package org.galaxyproject.gxformat2.v19_09; | ||
|
||
import org.galaxyproject.gxformat2.v19_09.utils.LoaderInstances; | ||
import org.galaxyproject.gxformat2.v19_09.utils.LoadingOptions; | ||
import org.galaxyproject.gxformat2.v19_09.utils.LoadingOptionsBuilder; | ||
import org.galaxyproject.gxformat2.v19_09.utils.SavableImpl; | ||
import org.galaxyproject.gxformat2.v19_09.utils.ValidationException; | ||
|
||
/** Auto-generated class implementation for <I>https://w3id.org/cwl/salad#ArraySchema</I><br> */ | ||
public class ArraySchemaImpl extends SavableImpl implements ArraySchema { | ||
private LoadingOptions loadingOptions_ = new LoadingOptionsBuilder().build(); | ||
private java.util.Map<String, Object> extensionFields_ = new java.util.HashMap<String, Object>(); | ||
|
||
private Object items; | ||
|
||
/** | ||
* Getter for property <I>https://w3id.org/cwl/salad#items</I><br> | ||
* | ||
* <BLOCKQUOTE> | ||
* | ||
* Defines the type of the array elements. * | ||
* | ||
* </BLOCKQUOTE> | ||
*/ | ||
public Object getItems() { | ||
return this.items; | ||
} | ||
|
||
private enum_d062602be0b4b8fd33e69e29a841317b6ab665bc type; | ||
|
||
/** | ||
* Getter for property <I>https://w3id.org/cwl/salad#type</I><br> | ||
* | ||
* <BLOCKQUOTE> | ||
* | ||
* Must be `array` * | ||
* | ||
* </BLOCKQUOTE> | ||
*/ | ||
public enum_d062602be0b4b8fd33e69e29a841317b6ab665bc getType() { | ||
return this.type; | ||
} | ||
|
||
/** | ||
* Used by {@link org.galaxyproject.gxformat2.v19_09.utils.RootLoader} to construct instances of | ||
* ArraySchemaImpl. | ||
* | ||
* @param __doc_ Document fragment to load this record object from (presumably a {@link | ||
* java.util.Map}). | ||
* @param __baseUri_ Base URI to generate child document IDs against. | ||
* @param __loadingOptions Context for loading URIs and populating objects. | ||
* @param __docRoot_ ID at this position in the document (if available) (maybe?) | ||
* @throws ValidationException If the document fragment is not a {@link java.util.Map} or | ||
* validation of fields fails. | ||
*/ | ||
public ArraySchemaImpl( | ||
final Object __doc_, | ||
final String __baseUri_, | ||
LoadingOptions __loadingOptions, | ||
final String __docRoot_) { | ||
super(__doc_, __baseUri_, __loadingOptions, __docRoot_); | ||
// Prefix plumbing variables with '__' to reduce likelihood of collision with | ||
// generated names. | ||
String __baseUri = __baseUri_; | ||
String __docRoot = __docRoot_; | ||
if (!(__doc_ instanceof java.util.Map)) { | ||
throw new ValidationException("ArraySchemaImpl called on non-map"); | ||
} | ||
final java.util.Map<String, Object> __doc = (java.util.Map<String, Object>) __doc_; | ||
final java.util.List<ValidationException> __errors = | ||
new java.util.ArrayList<ValidationException>(); | ||
if (__loadingOptions != null) { | ||
this.loadingOptions_ = __loadingOptions; | ||
} | ||
Object items; | ||
try { | ||
items = | ||
LoaderInstances | ||
.uri_union_of_PrimitiveType_or_RecordSchema_or_EnumSchema_or_ArraySchema_or_StringInstance_or_array_of_union_of_PrimitiveType_or_RecordSchema_or_EnumSchema_or_ArraySchema_or_StringInstance_False_True_2 | ||
.loadField(__doc.get("items"), __baseUri, __loadingOptions); | ||
} catch (ValidationException e) { | ||
items = null; // won't be used but prevents compiler from complaining. | ||
final String __message = "the `items` field is not valid because:"; | ||
__errors.add(new ValidationException(__message, e)); | ||
} | ||
enum_d062602be0b4b8fd33e69e29a841317b6ab665bc type; | ||
try { | ||
type = | ||
LoaderInstances.typedsl_enum_d062602be0b4b8fd33e69e29a841317b6ab665bc_2.loadField( | ||
__doc.get("type"), __baseUri, __loadingOptions); | ||
} catch (ValidationException e) { | ||
type = null; // won't be used but prevents compiler from complaining. | ||
final String __message = "the `type` field is not valid because:"; | ||
__errors.add(new ValidationException(__message, e)); | ||
} | ||
if (!__errors.isEmpty()) { | ||
throw new ValidationException("Trying 'RecordField'", __errors); | ||
} | ||
this.items = (Object) items; | ||
this.type = (enum_d062602be0b4b8fd33e69e29a841317b6ab665bc) type; | ||
} | ||
} |
Oops, something went wrong.