99
1010 "github.com/mendixlabs/mxcli/mdl/ast"
1111 "github.com/mendixlabs/mxcli/mdl/executor"
12+ "github.com/mendixlabs/mxcli/mdl/linter"
1213 "github.com/mendixlabs/mxcli/mdl/visitor"
1314 "github.com/spf13/cobra"
1415)
@@ -26,18 +27,25 @@ that are created within the script itself. For example, if your script creates
2627a module "MyModule" and then creates entities in it, no error will be reported
2728for the module reference.
2829
30+ Output includes structured rule IDs (MDL prefix) for each validation issue.
31+
2932Examples:
3033 # Check syntax only (no project needed)
3134 mxcli check script.mdl
3235
3336 # Check syntax and validate references against a project
3437 mxcli check script.mdl -p app.mpr --references
38+
39+ # Output as JSON or SARIF
40+ mxcli check script.mdl --format json
41+ mxcli check script.mdl --format sarif
3542` ,
3643 Args : cobra .ExactArgs (1 ),
3744 Run : func (cmd * cobra.Command , args []string ) {
3845 filePath := args [0 ]
3946 projectPath , _ := cmd .Flags ().GetString ("project" )
4047 checkRefs , _ := cmd .Flags ().GetBool ("references" )
48+ format , _ := cmd .Flags ().GetString ("format" )
4149
4250 // Read the file
4351 content , err := os .ReadFile (filePath )
@@ -67,54 +75,41 @@ Examples:
6775 fmt .Printf ("✓ Syntax OK (%d statements)\n " , len (prog .Statements ))
6876
6977 // Validate statements (doesn't require project connection)
70- var oqlErrors []string
71- for i , stmt := range prog .Statements {
78+ var violations []linter. Violation
79+ for _ , stmt := range prog .Statements {
7280 // Check enumeration values for reserved words
7381 if enumStmt , ok := stmt .(* ast.CreateEnumerationStmt ); ok {
74- if errs := executor .ValidateEnumeration (enumStmt ); len (errs ) > 0 {
75- for _ , e := range errs {
76- oqlErrors = append (oqlErrors , fmt .Sprintf ("statement %d (%s): %s" , i + 1 , enumStmt .Name .String (), e ))
77- }
78- }
82+ violations = append (violations , executor .ValidateEnumeration (enumStmt )... )
7983 }
8084 // Check entity attributes for reserved system names
8185 if entityStmt , ok := stmt .(* ast.CreateEntityStmt ); ok {
82- if errs := executor .ValidateEntity (entityStmt ); len (errs ) > 0 {
83- for _ , e := range errs {
84- oqlErrors = append (oqlErrors , fmt .Sprintf ("statement %d (%s): %s" , i + 1 , entityStmt .Name .String (), e ))
85- }
86- }
86+ violations = append (violations , executor .ValidateEntity (entityStmt )... )
8787 }
8888 // Check microflow body for common issues
8989 if mfStmt , ok := stmt .(* ast.CreateMicroflowStmt ); ok {
90- if warns := executor .ValidateMicroflow (mfStmt ); len (warns ) > 0 {
91- for _ , w := range warns {
92- oqlErrors = append (oqlErrors , fmt .Sprintf ("statement %d (%s): %s" , i + 1 , mfStmt .Name .String (), w ))
93- }
94- }
90+ violations = append (violations , executor .ValidateMicroflow (mfStmt )... )
9591 }
9692 // Check view entity OQL
9793 if viewStmt , ok := stmt .(* ast.CreateViewEntityStmt ); ok {
9894 if viewStmt .Query .RawQuery != "" {
99- if errs := executor .ValidateOQLSyntax (viewStmt .Query .RawQuery ); len (errs ) > 0 {
100- for _ , e := range errs {
101- oqlErrors = append (oqlErrors , fmt .Sprintf ("statement %d (%s): %s" , i + 1 , viewStmt .Name .String (), e ))
102- }
103- }
104- if errs := executor .ValidateOQLTypes (viewStmt .Query .RawQuery , viewStmt .Attributes ); len (errs ) > 0 {
105- for _ , e := range errs {
106- oqlErrors = append (oqlErrors , fmt .Sprintf ("statement %d (%s): %s" , i + 1 , viewStmt .Name .String (), e ))
107- }
108- }
95+ violations = append (violations , executor .ValidateOQLSyntax (viewStmt .Query .RawQuery )... )
96+ violations = append (violations , executor .ValidateOQLTypes (viewStmt .Query .RawQuery , viewStmt .Attributes )... )
10997 }
11098 }
11199 }
112- if len (oqlErrors ) > 0 {
113- fmt .Fprintf (os .Stderr , "\n Validation errors found:\n " )
114- for _ , e := range oqlErrors {
115- fmt .Fprintf (os .Stderr , " - %s\n " , e )
100+
101+ if len (violations ) > 0 {
102+ // Use structured output
103+ outputFormat := linter .OutputFormat (format )
104+ formatter := linter .GetFormatter (outputFormat , format == "" || format == "text" )
105+ fmt .Fprintln (os .Stderr )
106+ formatter .Format (violations , os .Stderr )
107+
108+ // Exit with error if there are any error-severity violations
109+ summary := linter .Summarize (violations )
110+ if summary .Errors > 0 {
111+ os .Exit (1 )
116112 }
117- os .Exit (1 )
118113 }
119114
120115 // If reference checking requested
0 commit comments