Skip to content

Commit

Permalink
Add watch function
Browse files Browse the repository at this point in the history
  • Loading branch information
xiwenc committed Dec 19, 2024
1 parent 66fec82 commit 3b74a3a
Show file tree
Hide file tree
Showing 5 changed files with 142 additions and 1 deletion.
52 changes: 52 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,58 @@ PASS (0.00158s) modelsource/MyFirstModule/DomainModels$DomainModel.yaml
![Mendix Lint report](./resources/lint-xunit-report.png)
Lint Mendix Yaml files. This tool checks for common mistakes and enforces best practices. It uses OPA as policy engine. Therefore policies must be written in the powerful Rego language. Please refer to [Rego language reference](https://www.openpolicyagent.org/docs/latest/policy-reference/) for more information on the syntax and semantics.

## watch

Watch for changes in the model and lint the changes.

```
./bin/mxlint-darwin-arm64 watch --input resources/app/ --rules resources/rules
FILE "triggered event" CREATE [-]
INFO[0000] Watching for changes in /Users/xcheng/private/git/mxlint-cli/resources/app
INFO[0000] Output directory: modelsource
INFO[0000] Rules directory: resources/rules
INFO[0000] Mode: basic
INFO[0000] Exporting resources/app/App.mpr to modelsource
INFO[0000] Transforming microflow UpdateUserHelper
INFO[0000] Transforming microflow AssertTrue
INFO[0000] Transforming microflow CreateUserIfNotExists
INFO[0000] Transforming microflow AssertTrue_2
INFO[0000] Transforming microflow ChangeMyPassword
INFO[0000] Transforming microflow ShowMyPasswordForm
INFO[0000] Transforming microflow ManageMyAccount
INFO[0000] Loop detected; not traversing
INFO[0000] Transforming microflow NewAccount
INFO[0000] Transforming microflow ChangePassword
INFO[0000] Transforming microflow NewWebServiceAccount
INFO[0000] Transforming microflow ShowPasswordForm
INFO[0000] Transforming microflow SaveNewAccount
INFO[0000] Transforming microflow MicroflowSplit
INFO[0000] Transforming microflow MicroflowSimple
INFO[0000] Transforming microflow MicroflowComplexSplit
INFO[0000] Loop detected; not traversing
INFO[0000] Transforming microflow MicroflowLoopNested
INFO[0000] Loop detected; not traversing
INFO[0000] Loop detected; not traversing
INFO[0000] Loop detected; not traversing
INFO[0000] Loop detected; not traversing
INFO[0000] Transforming microflow MicroflowSplitThenMerge
INFO[0000] Loop detected; not traversing
INFO[0000] Transforming microflow MicroflowLoop
INFO[0000] Loop detected; not traversing
INFO[0000] Loop detected; not traversing
INFO[0000] Transforming microflow MyFirstLogic
INFO[0000] Transforming microflow MicroflowForLoop
INFO[0000] Transforming microflow VA_Age
INFO[0000] Found 361 documents
INFO[0000] Completed resources/app/App.mpr
## resources/rules/001_0003_security_checks.rego
FAIL (0.00171s) modelsource/Security$ProjectSecurity.yaml
WARN[0000] Rule resources/rules/001_0003_security_checks.rego: 1 failures
WARN[0000] Document modelsource/Security$ProjectSecurity.yaml: [HIGH, Security, 4099] Security check is not enabled in Project Security
WARN[0000] Lint failed: 1 failures
```

### Features

- Export Mendix model to Yaml
Expand Down
73 changes: 73 additions & 0 deletions cmd/mxlint/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,12 @@ package main
import (
"fmt"
"os"
"path/filepath"
"time"

"github.com/cinaq/mendix-cli/lint"
"github.com/cinaq/mendix-cli/mpr"
"github.com/radovskyb/watcher"
"github.com/sirupsen/logrus"
"github.com/spf13/cobra"
)
Expand Down Expand Up @@ -78,6 +81,76 @@ func main() {
cmdLint.Flags().Bool("verbose", false, "Turn on for debug logs")
rootCmd.AddCommand(cmdLint)

var cmdWatch = &cobra.Command{
Use: "watch",
Short: "Watch for changes in the model, export-model and lint continuously",
Long: "Continuous linting of the model. This is useful when you are developing your application and want to be notified of any changes that might break the rules.",
Run: func(cmd *cobra.Command, args []string) {
inputDirectory, _ := cmd.Flags().GetString("input")
outputDirectory, _ := cmd.Flags().GetString("output")
mode, _ := cmd.Flags().GetString("mode")
rulesDirectory, _ := cmd.Flags().GetString("rules")

w := watcher.New()
w.IgnoreHiddenFiles(true)

log := logrus.New()
log.SetLevel(logrus.InfoLevel)

mpr.SetLogger(log)
lint.SetLogger(log)

expandedPath, err := filepath.Abs(inputDirectory)
if err != nil {
log.Fatalln(err)
}

go func() {
for {
select {
case event := <-w.Event:
fmt.Println(event)

log.Infof("Watching for changes in %s", expandedPath)
log.Infof("Output directory: %s", outputDirectory)
log.Infof("Rules directory: %s", rulesDirectory)
log.Infof("Mode: %s", mode)
mpr.ExportModel(inputDirectory, outputDirectory, false, mode)
err := lint.EvalAll(rulesDirectory, outputDirectory, "", "")
if err != nil {
log.Warningf("Lint failed: %s", err)
}
case err := <-w.Error:
log.Fatalln(err)
case <-w.Closed:
return
}
}
}()

if err := w.AddRecursive(inputDirectory); err != nil {
log.Fatalln(err)
}
w.Ignore(outputDirectory)

// first run
go func() {
w.Wait()
w.TriggerEvent(watcher.Create, nil)
}()

if err := w.Start(time.Millisecond * 100); err != nil {
log.Fatalln(err)
}
},
}

cmdWatch.Flags().StringP("input", "i", ".", "Path to directory or mpr file to export. If it's a directory, all mpr files will be exported")
cmdWatch.Flags().StringP("output", "o", "modelsource", "Path to directory to write the yaml files. If it doesn't exist, it will be created")
cmdWatch.Flags().StringP("mode", "m", "basic", "Export mode. Valid options: basic, advanced")
cmdWatch.Flags().StringP("rules", "r", "rules", "Path to directory with rules")
rootCmd.AddCommand(cmdWatch)

if err := rootCmd.Execute(); err != nil {
fmt.Println(err)
os.Exit(1)
Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ require (
github.com/ghodss/yaml v1.0.0
github.com/glebarez/go-sqlite v1.22.0
github.com/open-policy-agent/opa v0.62.1
github.com/radovskyb/watcher v1.0.7
github.com/sirupsen/logrus v1.9.3
github.com/spf13/cobra v1.8.0
go.mongodb.org/mongo-driver v1.14.0
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,8 @@ github.com/prometheus/common v0.48.0 h1:QO8U2CdOzSn1BBsmXJXduaaW+dY/5QLjfB8svtSz
github.com/prometheus/common v0.48.0/go.mod h1:0/KsvlIEfPQCQ5I2iNSAWKPZziNCvRs5EC6ILDTlAPc=
github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo=
github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo=
github.com/radovskyb/watcher v1.0.7 h1:AYePLih6dpmS32vlHfhCeli8127LzkIgwJGcwwe8tUE=
github.com/radovskyb/watcher v1.0.7/go.mod h1:78okwvY5wPdzcb1UYnip1pvrZNIVEIh/Cm+ZuvsUYIg=
github.com/rcrowley/go-metrics v0.0.0-20200313005456-10cdbea86bc0 h1:MkV+77GLUNo5oJ0jf870itWm3D0Sjh7+Za9gazKc5LQ=
github.com/rcrowley/go-metrics v0.0.0-20200313005456-10cdbea86bc0/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE=
Expand Down
15 changes: 14 additions & 1 deletion lint/lint.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,21 @@ func EvalAll(rulesPath string, modelSourcePath string, xunitReport string, jsonF
}
}

for _, ts := range testsuites {
if ts.Failures > 0 {
log.Warningf("Rule %s: %d failures", ts.Name, ts.Failures)
for _, tc := range ts.Testcases {
if tc.Failure != nil {
log.Warningf(" Document %s: %s", tc.Name, tc.Failure.Message)
}
}
}
}

if failuresCount > 0 {
return fmt.Errorf("%d failures", failuresCount)
} else {
log.Infof("All good my friend")
}
return nil
}
Expand Down Expand Up @@ -180,7 +193,7 @@ func evalTestcase(rulePath string, queryString string, inputFilePath string) (*T
if !result {
myErrors := make([]string, 0)
for _, err := range errors {
log.Warnf("Rule failed: %s", err)
//log.Warnf("Rule failed: %s", err)
myErrors = append(myErrors, fmt.Sprintf("%s", err))
}
failure = &Failure{
Expand Down

0 comments on commit 3b74a3a

Please sign in to comment.