GithubHelp home page GithubHelp logo

bpmn-io / bpmnlint Goto Github PK

View Code? Open in Web Editor NEW
119.0 12.0 36.0 3.34 MB

Validate BPMN diagrams based on configurable lint rules.

License: MIT License

JavaScript 100.00%
bpmn linter cli static-diagram-analysis validator

bpmnlint's Introduction

bpmnlint

CI

Validate your BPMN diagrams based on configurable lint rules.

Installation

Install the utility via npm:

npm install -g bpmnlint

Usage

Validate your diagrams via the commandline:

> bpmnlint invoice.bpmn

/Projects/process-application/resources/invoice.bpmn
  Flow_1    error    Sequence flow is missing condition  conditional-flows
  Process   error    Process is missing end event        end-event-required
  Task_13   warning  Element is missing label/name       label-required
  Event_12  warning  Element is missing label/name       label-required
  Event_27  warning  Element is missing label/name       label-required
  Process   error    Process is missing start event      start-event-required

✖ 6 problems (6 errors, 0 warnings)

Rules

Our documentation lists all currenty implemented rules, the ./rules folder contains each rules implementation.

Do you miss a rule that should be included? Propose a new rule.

Configuration

Create a .bpmnlintrc file in your working directory and inherit from a common configuration using the extends block:

{
  "extends": "bpmnlint:recommended"
}

Add or customize rules using the rules block:

{
  "extends": "bpmnlint:recommended",
  "rules": {
    "label-required": "off"
  }
}

API

Invoke the tool directly from NodeJS:

import Linter from 'bpmnlint';
import NodeResolver from 'bpmnlint/lib/resolver/node-resolver';

import BpmnModdle from 'bpmn-moddle';

const linter = new Linter({ 
  config: {
    extends: 'bpmnlint:recommended'
  },
  resolver: new NodeResolver()
});

const xmlStr = `
  <?xml version="1.0" encoding="UTF-8"?>
  <bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" 
                     id="definitions" 
                     targetNamespace="http://bpmn.io/schema/bpmn">
    <bpmn:process id="process" />
  </bpmn:definitions>
`;

const {
  rootElement: definitions
} = await moddle.fromXML(xmlStr);

const reports = linter.lint(definitions);

// {
//    "end-event-required": [
//      {
//        "id": "process",
//        "message": "Process is missing end event"
//      }
//    ],
//    ...
// }

Writing a Plug-in

Create your first plug-in using the plugin creator:

npm init bpmnlint-plugin {PLUGIN_NAME}

Checkout the bpmnlint-plugin-example for details on how to define, test, and consume custom lint rules. Use the bpmnlint playground to implement new rules with quick visual feedback.

Bundling

For browser usage include your linting configuration using your favorite bundler plug-in (Rollup, Webpack).

Visual Feedback

Integrate the linter via bpmn-js-bpmnlint into bpmn-js and get direct feedback during modeling.

To try out visual validation, checkout the bpmnlint playground.

Related

License

MIT

bpmnlint's People

Contributors

barmac avatar clementdessoude avatar david-d-le avatar maxtru avatar nikku avatar nlea avatar patoncrispy avatar philippfromme avatar siffogh avatar strangelookingnerd avatar thecampagnards avatar timkraeuter avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

bpmnlint's Issues

Be able to hook up custom moddle extension

For improved validation of extended BPMN models it would be beneficial to be able to register a custom moddle extension so that we can do the following, i.e. as part of rules:

function check(node, reporter) {
  if (is(node, 'camunda:Callable')) {
    // custom check, 1212
  }
}

no-inclusive-gateway is not usefull

Why the linter rule no-inclusive-gateway is allways an error? This kind of gateway is a usefull combination of an exclusive gateway and a parallel gateway. Its the missing link between both :)

An exclusive gateway need a clear decision, what single sequence flow should be used. A parallel gateway always run all following flows. But if I have to decide to run all possible flows depending on the condition, this means I can run all but I need not to run all. This is not possible with the 2 other gateways. Even if I have only 2 sequence flows following the gateway all 3 gateways can have a different behavior. The exclusive gateway always runs only 1 flow, the parallel gateway always run both flows and only the inclusive gateway has the capability to decide if it run 1 or 2 flows.

So, please remove this rule from the basic rule set.

BTW: maybe you can enhance the conditional-flows rule? At the moment this rule only checks if the sequence flows are marked as default oder have a condition. Maybe it's not a big effort to check, that only 1 flow is marked as default and all other conditions are unique for this gateway (not checking for possible results, just comparing the values).

Regards
Frank

Roadmap for this repo?

Hi there, do you intend to add a Roadmap or create a gh-project so that others can also take on the rules to be implemented?

Is there a special source (like the official docs from OMG) that is used to define the rules that need to be implemented?

Add sufficient test coverage

  • bin/bpmnlint
  • add rule tester
  • rules
    • start-event-required
    • end-event-required
    • label-required
  • traverse
  • linter
  • testRule
  • utils

Happy path

The rule should detect the following modeling patterns

A process should have a "happy path". Only have one starting point and one "happy path"-end point. All other outcomes should be expected to be exceptions. If one need "many" outcomes, then one should model the process as capturing and/or processing the many outcomes in the process.

How does the rule improve the BPMN diagram?

The process becomes clear and not cluttered. Readability is improved as well as automation.

Rule Details

  • Name: ThereCanBeOnlyOneHappyPath
  • Default notification level: warning

What alternatives did you consider?

Spaghetti process/code is always an option.

Be able to resolve local rules / define rules outside of a plug-in

Is your feature request related to a problem? Please describe

The linter can be configured using NodeResolver, StaticResolver or a custom one. Figuring out how to do this is quite difficult (cf. https://github.com/camunda/web-modeler/pull/1249#issuecomment-1125971172). In fact defining local rules is impossible at the moment.

Describe the solution you'd like

There should be a well documented way how to configure a custom lint rule outside of a plug-in:

  • Local rule can be discovered (NodeJS)
  • Local rule can be compiled to a bundle

Describe alternatives you've considered

Using the source code and the tests I eventually figured out how to configure the linter but it took me quite long, and I don't know if I did it the way it's intended (cf. camunda/camunda-modeler#2958).

Doesn't check missing an end

Describe the Bug

  • The codes don't seem to detect the issue with an activity that is missing an end event.
    I am attaching the bpmn file (in zip) for your convenience

image
Trial missing end.zip

Steps to Reproduce

  1. remove the check activity from the diagram and check for errors. The system spots three errors
  2. add an activity to the XOR gateway and name the activity issue
  3. check errors again. Only three errors are identified

Expected Behavior

    1. There should be an end event attached to the activity issue (which is incorrectly named by the way. I have submitted to you my request for a rule about naming conventions).

Environment

  • Host (Browser/Node version), if applicable: [e.g. MS Edge 18, Chrome 69, Node 10 LTS]
  • OS: [e.g. Windows 7]
  • Library version: [e.g. 2.0.0]
  • I used Google Chrome which is in the incognito mode
  • The operating system of my laptop is Windows 10

Rule that identifies missing bpmndi for a bpmn elements with visual representation

The rule should detect the following modeling patterns

We have a SupportCase, where a bpmndi is missing for boundary events, which therefore vanish -> leading to undersired effects on the engine. See https://jira.camunda.com/browse/SUPPORT-9121.

As a solution we could offer bpmnlint

Example:

<?xml version="1.0" encoding="UTF-8"?>
<bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" id="Definitions_0guwkgi" targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Modeler" exporterVersion="4.3.0">
  <bpmn:process id="Process_0so19rs" isExecutable="true">
    <bpmn:startEvent id="StartEvent_1">
      <bpmn:outgoing>Flow_0y554ej</bpmn:outgoing>
    </bpmn:startEvent>
    <bpmn:task id="Activity_0chj4yv">
      <bpmn:incoming>Flow_0y554ej</bpmn:incoming>
    </bpmn:task>
    <bpmn:sequenceFlow id="Flow_0y554ej" sourceRef="StartEvent_1" targetRef="Activity_0chj4yv" />
    <bpmn:boundaryEvent id="Event_16w15x0" attachedToRef="Activity_0chj4yv">
      <bpmn:timerEventDefinition id="TimerEventDefinition_1ybo5te" />
    </bpmn:boundaryEvent>
  </bpmn:process>
  <bpmndi:BPMNDiagram id="BPMNDiagram_1">
    <bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Process_0so19rs">
      <bpmndi:BPMNEdge id="Flow_0y554ej_di" bpmnElement="Flow_0y554ej">
        <di:waypoint x="215" y="117" />
        <di:waypoint x="270" y="117" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNShape id="_BPMNShape_StartEvent_2" bpmnElement="StartEvent_1">
        <dc:Bounds x="179" y="99" width="36" height="36" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="Activity_0chj4yv_di" bpmnElement="Activity_0chj4yv">
        <dc:Bounds x="270" y="77" width="100" height="80" />
      </bpmndi:BPMNShape>
    </bpmndi:BPMNPlane>
  </bpmndi:BPMNDiagram>
</bpmn:definitions>

Note that the boundary event will not be visible, because the bpmndi information is missing.

How does the rule improve the BPMN diagram?

By having this rule, the mismatch between the visual representation and the execution semantics (which does not care about the di) becomes apparent.

Rule Details

  • Name: no-bpmndi
  • Default notification level: error

What alternatives did you consider?

Error message on bpmn-js level when bpmdi is missing

Support scoped packages

We are using GitHub Registry which currently only supports scoped packages. As a result, none of our packages can start with bpmnlint-plugin-. Is it possible to allow packages that are scoped, but start with that rule? An example would be @myorg/bpmlint-plugin-my-org-rules.

Detect conflicting interrupting event subscriptions per scope

The rule should detect the following modeling patterns

event-scopes

How does the rule improve the BPMN diagram?

Interrupting events fire immediately, hence there can only be one interrupting event per scope that does something meaningful. If you model two conflicting interrupting events, then you are very likely to run into undefined behavior (execution wise) or make an error.

Rule Details

  • Name: event-scopes
  • Default notification level: warn

What alternatives did you consider?

None.

`no-implicit-start` doesn't consider boundary events

Describe the Bug

bpmnlint reports no-implicit-start on boundary events branching from a subprocess (for example a timer event). This seems like a common use case and an oversight in the rule. The rule checks for bpmn:StartEvent but doesn't seem to consider bpmn:timerEventDefinition.

Steps to Reproduce

  1. Given a bpmn
  2. With a subprocess
  3. And a timer boundary event
  4. When bpmnlint is ran
  5. Then an error occurs on the timer event node

Expected Behavior

I would expect this to succeed.

Environment

  • Host v16.15.0
  • OS: macos
  • Library version: 8.5.5

Be Able to Specify Path When Reporting Issue Through Reporter#report

When using Reporter#report one can only provide the element ID and the error message. There is no way to provide additional properties e.g. the path of the property that has caused the error to be reported. I'd image something along the lines of:

Reporter.report('ServiceTask_1', '<zeebe:TaskDefinition> must have <zeebe:type> property', {
  path: [ 'extensionElements', 'values', 0, 'zeebe:type' ]
});

Adding an optional third argument wouldn't introduce any breaking changes.


Related to https://github.com/bpmn-io/internal-docs/issues/430

Indicate rule evaluation error

When a lint rule throws an acutal error instead of reporting one the message is set to Rule error: .... Other than that prefix, there is no way to tell whether an actual error occurred. I'd like something like a flag indicating that there was an actual error. For example:

} catch (e) {
  console.error('rule <' + name + '> failed with error: ', e);

  return [
    {
      message: 'Rule error: ' + e.message,
      category: 'error',
      isRuleError: true
    }
  ];
}

Related to camunda/camunda-modeler#3637

Detect asymmetric modeling

The rule should detect the following modeling patterns

Asymetric use of parallel / exclusive gateways, causing deadlocks or unintended token splits.

image

image

How does the rule improve the BPMN diagram?

Modeling symmetric is a modeling good practice. Not doing it leads to bad BPMN diagrams (harder to understand) and causes errors (dead locks, token splits).

Rule Details

  • Name: symmetric-gateways
  • Default notification level: error

What alternatives did you consider?

None.

Expand built-in rules

New rules

  • bpmn:SubProcess must contain un-typed start events only
  • bpmn:EventBasedSubProcess must contain typed start events only
  • bpmn:Process should have only a single un-typed start event
  • bpmn:Gateway should not be joining and forking at the same time
  • bpmn:BoundaryEvent must have outgoing flows
  • non bpmn:StartEvent flow nodes other than compensation activity and event based sub-processes must be connected (have incoming and outgoing flows)
  • bpmn:InclusiveGateway should not be used
  • bpmn:ComplexGateway should not be used
  • bpmn:Event with multiple event definitions should not be used

Allow to use moddle extensions in the CLI tool

Is your feature request related to a problem? Please describe

In my favourite ruleset, I use a rule which requires Camunda namespace to be present. I cannot use it now with the CLI tool.

Describe the solution you'd like

I want to be able to load moddle extensions when I use the CLI tool.

This could be done via configuration:

.bpmnlinrc

{
  "moddleExtensions": [
    "camunda-bpmn-moddle/resources/camunda.json",
    "./nyan-cat.json"
  ],
  "extends": [
    "bpmnlint:recommended",
    "plugin:camunda/recommended"
  ],
  "rules": {
    "nyan-cat": "error"
  }
}

Describe alternatives you've considered

Rulesets could declare their moddle extensions in a similar way:

module.exports = {
  configs: {
    recommended: {
      moddleExtensions: [
        "camunda-bpmn-moddle/resources/camunda.json"
      ],
      rules: {
        'camunda/avoid-lanes': 'warn',
        'camunda/forking-conditions': 'error',
        'camunda/no-collapsed-sub-processes': 'error'
      }
    }
  }
};

Additional context

Be Able to Provide More Information When Reporting Error

Is your feature request related to a problem? Please describe

Recently, an optional path argument was added to Reporter#report to add more information to the error. In some cases there is still not enough information.

Example:

<bpmn:businessRuleTask />

This business rule task is missing an extension element that is required. The path could be specified as [ 'extensionElements', 'values' ] but there is no information about what type of extension element is missing. For any missing property that is isMany=true the information about the type is missing.

Describe the solution you'd like

Either

  • introduce a new concept of e.g. error types along with additional information (e.g. { type: 'missingProperty', missingPropertyType: 'foo:Bar' }

or

  • introduce a way of providing arbitrary information when calling Reporter#report (e.g. Reporter.report(id, message, path, { type: 'missingProperty', missingPropertyType: 'foo:Bar' })

Describe alternatives you've considered

Additional context

Assumptions about the error could be derived from the error message itself.

Check the name of activities

The rule should detect the following modeling patterns

  • A correct name for an activity should be a verb+noun phrase (e.g., Check problem)
  • An example of an Incorrect name for an activity is problem.

How does the rule improve the BPMN diagram?

Describe how people would benefit from this modeling rule. This will be included in the user documentation, cf. https://github.com/bpmn-io/bpmnlint/blob/master/docs/rules/label-required.md.

*This will help improve quality of business process diagrams and increase its wide adoption by users
-->

Rule Details

  • Name:
  • Default notification level: error|warning|off

What alternatives did you consider?

Improve label-required rule

Improvements

  • label-required: exclusiveGateway (joining) must not have a name
  • label-required: conditional flows must have a name
  • label-required: bpmn:Participant and bpmn:Lane should have labels
  • label-required: bpmn:TextAnnotation must have text

no-disconnected rule should also check for existence of incoming and outgoing connection, where needed

Is your feature request related to a problem? Please describe

  • Currently the no-disconnected rule checks whether an incoming or outgoing connection exists
  • However, in many cases (not in all though), an incoming and outgoing connection is needed

Describe the solution you'd like

  • no-disconnected rule should also check for existence of incoming and outgoing connection, where needed

Describe alternatives you've considered

Implement as seperate rule.

Additional context

Detect intermediate events overlapping tasks (looking like boundary events)

Is your feature request related to a problem? Please describe

There were user reported problems, where an intermediateCatchEvent appeared visually as a boundary event. See https://jira.camunda.com/browse/SUPPORT-12954.

Describe the solution you'd like

Add a rule non-boundary-event-overlaps-activity, which would give a warning if a catchEvent visually appears as a boundary event (e.g., overlaps a task).

Such situations could happen, if for example the positioning of elements is updated manually. They could also result from a modeling bug or using of modeling APIs.

Describe alternatives you've considered

n/a

Additional context

Could have been used to identify https://jira.camunda.com/browse/SUPPORT-12954

Support glob/pattern lint (e.g. bpmnlint **/*.bpmn)

Is your feature request related to a problem? Please describe

Hi !

First, thank you for this great tool !

We were trying to integrate it on our project, but we had some difficulties to make it work in a npm script, because it doesn't seems to support glob/pattern search.

For instance, when creating a script npm run check-bpmn, I got this kind of error:

bpmnlint src/**/*.bpmn

Error: Failed to read src/**/*.bpmn

Describe the solution you'd like

I would like to propose supporting glob search.

Describe alternatives you've considered

I think that otherwise, we'll try to implement a wrapper that will give us the same functionnality

Make library easily consumable in NodeJS and browsers

Right now the library works fine in NodeJS. As it uses a lot of ES 6 features it cannot easily be consumed cross browser though (i.e. IE and older versions of Chrome / Firefox may have issues).

Tasks

  • Figure out how to write ES module code, consumable in NodeJS and the Browser

Hint: Checkout didi build.

Adjust no-bpmndi rule to also catch messageFlows without visual representation

Is your feature request related to a problem? Please describe

The current implementation of the no-bpmndi rule seems to not catch the case where visual representation of a messageFlow is missing. Example:

<?xml version="1.0" encoding="UTF-8"?>
<bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:modeler="http://camunda.org/schema/modeler/1.0" xmlns:camunda="http://camunda.org/schema/1.0/bpmn" id="Definitions_0o87biy" targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Modeler" exporterVersion="5.0.0" modeler:executionPlatform="Camunda Cloud" modeler:executionPlatformVersion="8.0.0" camunda:diagramRelationId="c3dfa14f-62b5-469a-99c2-eea2474361c4">
  <bpmn:collaboration id="Collaboration_03svvle">
    <bpmn:participant id="Participant_19296tk" name="Camunda" processRef="optimizeRelease" />
    <bpmn:messageFlow id="Flow_02zjpio" />
    <bpmn:messageFlow id="Flow_02fgw1s" />
    <bpmn:messageFlow id="Flow_1tfrum1" />
    <bpmn:messageFlow id="Flow_0j117b6" />
    <bpmn:messageFlow id="Flow_1p82kq7" />
    <bpmn:messageFlow id="Flow_12ujv1h" />
    <bpmn:messageFlow id="Flow_1ud5vc7" />
    <bpmn:messageFlow id="Flow_1pgfh6h" />
    <bpmn:messageFlow id="Flow_1n7tpee" />
  </bpmn:collaboration>
  <bpmn:process id="optimizeRelease" name="Optimize Release Process" isExecutable="true">
    <bpmn:laneSet id="LaneSet_0vxjmiv">
      <bpmn:lane id="other-lane" name="Other">
        <bpmn:flowNodeRef>Event_14w2go1</bpmn:flowNodeRef>
      </bpmn:lane>
      <bpmn:lane id="product-manager-lane" name="Product Manager">
        <bpmn:flowNodeRef>Event_14w2go1</bpmn:flowNodeRef>
        <bpmn:flowNodeRef>Start_1</bpmn:flowNodeRef>
        <bpmn:flowNodeRef>Event_14a4ede</bpmn:flowNodeRef>
        <bpmn:flowNodeRef>add-cat-pic</bpmn:flowNodeRef>
      </bpmn:lane>
    </bpmn:laneSet>
    <bpmn:endEvent id="Event_14w2go1" />
    <bpmn:sequenceFlow id="Flow_1yoohwu" sourceRef="Start_1" targetRef="add-cat-pic" />
    <bpmn:startEvent id="Start_1" name="At beginning of release month">
      <bpmn:outgoing>Flow_1yoohwu</bpmn:outgoing>
    </bpmn:startEvent>
    <bpmn:endEvent id="Event_14a4ede">
      <bpmn:incoming>Flow_1opo8o2</bpmn:incoming>
    </bpmn:endEvent>
    <bpmn:sequenceFlow id="Flow_1opo8o2" sourceRef="add-cat-pic" targetRef="Event_14a4ede" />
    <bpmn:serviceTask id="add-cat-pic" name="Add cat pic of the month">
      <bpmn:incoming>Flow_1yoohwu</bpmn:incoming>
      <bpmn:outgoing>Flow_1opo8o2</bpmn:outgoing>
    </bpmn:serviceTask>
    <bpmn:textAnnotation id="TextAnnotation_1m4hg8y">
      <bpmn:text>Configure timer cycle</bpmn:text>
    </bpmn:textAnnotation>
    <bpmn:association id="Association_1srpwa7" sourceRef="Start_1" targetRef="TextAnnotation_1m4hg8y" />
  </bpmn:process>
  <bpmndi:BPMNDiagram id="BPMNDiagram_1">
    <bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Collaboration_03svvle">
      <bpmndi:BPMNShape id="Participant_19296tk_di" bpmnElement="Participant_19296tk" isHorizontal="true">
        <dc:Bounds x="175" y="45" width="4310" height="1085" />
        <bpmndi:BPMNLabel />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="Lane_1hg66tj_di" bpmnElement="product-manager-lane" isHorizontal="true">
        <dc:Bounds x="205" y="497.5" width="4280" height="632.5" />
        <bpmndi:BPMNLabel />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="Lane_1i9ntug_di" bpmnElement="other-lane" isHorizontal="true">
        <dc:Bounds x="205" y="45" width="4280" height="452.5" />
        <bpmndi:BPMNLabel />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNEdge id="Flow_1opo8o2_di" bpmnElement="Flow_1opo8o2">
        <di:waypoint x="495" y="625" />
        <di:waypoint x="622" y="625" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="Flow_1yoohwu_di" bpmnElement="Flow_1yoohwu">
        <di:waypoint x="273" y="625" />
        <di:waypoint x="395" y="625" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNShape id="Event_14w2go1_di" bpmnElement="Event_14w2go1">
        <dc:Bounds x="4412" y="477" width="36" height="36" />
        <bpmndi:BPMNLabel>
          <dc:Bounds x="4375" y="520" width="71" height="14" />
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="Event_06qyu4n_di" bpmnElement="Start_1">
        <dc:Bounds x="237" y="607" width="36" height="36" />
        <bpmndi:BPMNLabel>
          <dc:Bounds x="219" y="650" width="74" height="27" />
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="Event_14a4ede_di" bpmnElement="Event_14a4ede">
        <dc:Bounds x="622" y="607" width="36" height="36" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="Activity_1gbnx01_di" bpmnElement="add-cat-pic">
        <dc:Bounds x="395" y="585" width="100" height="80" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="TextAnnotation_1m4hg8y_di" bpmnElement="TextAnnotation_1m4hg8y">
        <dc:Bounds x="225" y="525" width="100" height="39" />
        <bpmndi:BPMNLabel />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNEdge id="Association_1srpwa7_di" bpmnElement="Association_1srpwa7">
        <di:waypoint x="259" y="608" />
        <di:waypoint x="269" y="564" />
      </bpmndi:BPMNEdge>
    </bpmndi:BPMNPlane>
  </bpmndi:BPMNDiagram>
</bpmn:definitions>

Describe the solution you'd like

no-bpmndi rule should error also for messageFlows without visual representation

Describe alternatives you've considered

seperate new rule

Additional context

Add bpmnlint playground

Add a simple example project that allows users to:

  • play around with bpmnlint using their diagrams
  • implement new rules and try them out on-the-fly

Customizing inherited rules leads to rule duplication

Reproduce

Given the following configuration:

{
  "extends": "bpmnlint:all",
  "rules": {
    "label-required": 1,
    "start-event-required": 2,
    "end-event-required": 2
  }
}

The linter will report an error (as defined in bpmnlint:all) and a warning (overridden in the config) for label-required.

Expected Behavior

  • label-required overrides inherited rule with warn severity

Add a rule that checks for duplicate sequence flows

Sometimes people may end up with diagrams that contain duplicate sequence flows, overlapped by each other:

image

Cf. example diagram.

We should add a lint rule that validates this and reports it to the user.

Tasks

  • Create duplicate-sequence-flow rule that detects and reports this issue

Add a rule `no-overlapping-elements`

Is your feature request related to a problem? Please describe

Overlapping elements are visually hard to comprehend (ie. you might miss a label). Ideally elements don't overlap, apart from some exceptions:

  • Boundary events overlap their host
  • Child elements overlap / are on top of their parent (e.g., elements within a subProcess)

Describe the solution you'd like

Introduce a rule no-overlapping-elements, which would give a warning, if two elements overlap (except for exceptions, see above).

Example of where the rule should give a warning:
Screenshot_20220216_163526

Describe alternatives you've considered

n/a

Additional context

Maybe this could be merged with rule to be built as part of #23


Required by camunda/camunda-modeler#3250

Two pools look like a pool with two lanes

The rule should detect the following modeling patterns

  • Create two pools with one lane each
  • Position the pools right next to each other such that there is no gap between them anymore
  • The pools look very similar to one pool with two lanes

How does the rule improve the BPMN diagram?

Since the two pools can be confused with one pool with two lanes, people would expect to be able to model sequence flows across the two pools. However, since only message flows are allowed in this case, they get confused and don't easily find the solution.

Rule Details

  • Name: Adjacent pools
  • Default notification level: warning

Complex rules need a 2nd pass traversal or at least callback after traversal finished

Is your feature request related to a problem? Please describe

Sometimes a rule is too complex to be calculated in a single pass.
With workarounds it is often possible to collect and cache relevant elements/structures during a single traversal pass, but then a callback after traversal has finished is needed.

Describe the solution you'd like

Ability to hook into a 2nd traversal pass. This would be two lines inside lib/test-rule.js:

module.exports = function testRule({ moddleRoot, rule }) {
  const reporter = new Reporter({ rule, moddleRoot });
  traverse(moddleRoot, node => rule.check(node, reporter));
  if (rule.check2)
    traverse(moddleRoot, node => rule.check2(node, reporter));
  return reporter.messages;
};

Describe alternatives you've considered

Provide a callback after traversal finished. Would also be two lines inside lib/test-rule.js:

module.exports = function testRule({ moddleRoot, rule }) {
  const reporter = new Reporter({ rule, moddleRoot });
  traverse(moddleRoot, node => rule.check(node, reporter));
  if (rule.onFinish)
    rule.onFinish(node, reporter)
  return reporter.messages;
};

Possible workarounds right now

Override the messages property on the reporter object to be a getter function.

    factory() {

        function onFinish(node, reporter) {
            reporter.report("TestID", "Test");
        }

        function check(node, reporter) {

            if (!reporter._messages) {
                reporter._messages = [];
                reporter.report = (id, message) => {
                    reporter._messages.push({ id, message });
                }
                Object.defineProperty(reporter, 'messages', {
                    get: () => {
                        onFinish(node, reporter);
                        return reporter._messages;
                    },
                });
            }

        }

        return { check };
    }

This is obviously not a pretty solution.

`no-bpmndi` fails with `Cannot read property 'filter' of undefined`

Describe the Bug

On certain diagrams the no-bpmndi rule fails with a cryptic error.

Steps to Reproduce

  1. Download example diagram
  2. Lint using bpmnlint:recommended configuration
  3. See linting blowing up with error Cannot read property 'filter' of undefined

Expected Behavior

no-bpmndi rule evaluation is robust and does not blow up.

Environment

  • Host (Browser/Node version), if applicable: Node 145
  • OS: Linux
  • Library version: 7.2.1

Accessing null for removed labels

After resetting a label using modeling.updateLabel(undefined), the ModdleElement looks like this: { $type: 'bpmndi:BPMNShape', label: null, ... }

The label being null leads to accessing null in traverse.js:

rule <fake-join> failed with error:  TypeError: Cannot read properties of null (reading '$instanceOf')
    at is$7 (lintRules.js:37:1)
    at lintRules.js:53:1
    at Array.some (<anonymous>)
    at isAny$4 (lintRules.js:52:1)
    at check (lintRules.js:118:1)
    at traverse.enter (test-rule.js:70:1)
    at traverse (traverse.js:13:1)
    at traverse.js:32:1
    at Array.forEach (<anonymous>)
    at traverse (traverse.js:23:1)

This behaviour has been reported to the bpmn.io forum and has been classified as bug in bpmnlint. See discussion.

Be Able to Specify Test Name When Using RuleTester.verify

Console output when using RuleTester.verify looks like this:

rules/camunda-cloud-1-0-integration
    should lint valid
      √ test case #1test case #2test case #3test case #4test case #5test case #6test case #7test case #8test case #9test case #10test case #11test case #12test case #13test case #14test case #15test case #16test case #17
    should lint invalid
      √ test case #0test case #1test case #2test case #3test case #4test case #5

Finding failing test cases is quite hard with this kind of output.

Changing https://github.com/bpmn-io/bpmnlint/blob/master/lib/testers/rule-tester.js#L36 to include a name would result in:

rules/camunda-cloud-1-0-integration
    should lint valid
      √ test case #1 (BpmnDiTest.xml)test case #2 (CollaborationParserTest.bpmn)test case #3 (ConditionalSequenceFlowTest.xml)test case #4 (DataStoreTest.bpmn)test case #5 (DefinitionsTest.shouldImportEmptyDefinitions.bpmn)test case #6 (DefinitionsTest.shouldNotAffectComments.bpmn)test case #7 (DefinitionsTest.shouldNotImportWrongOrderedSequence.bpmn)test case #8 (GenerateIdTest.bpmn)test case #9 (ProcessTest.shouldImportProcess.bpmn)test case #10 (ReferenceTest.shouldFindReferenceWithNamespace.bpmn)test case #11 (ResourceRolesTest.bpmn)test case #12 (TransactionTest.xml)test case #13 (instance/TextAnnotationTest.bpmn)test case #14 (validation/default-flow.bpmn)test case #15 (validation/multiple-timer-start-event-sub-process.bpmn)test case #16 (validation/no-start-event-sub-process.bpmn)test case #17 (validation/non-executable-elements.bpmn)
    should lint invalid
      √ test case #0 (CamundaExtensionsCompatabilityTest.xml)test case #1 (CamundaExtensionsTest.xml)test case #2 (DataObjectTest.bpmn)test case #3 (EventDefinitionsTest.xml)test case #4 (GatewaysTest.xml)test case #5 (validation/collaboration-with-lanes.bpmn)

Provide utils as main library export

There is not much benefit of passing the utils into a rule factory when we could have a library utility export, too. The API would slightly simplify though, possibly making it easier for users to write rules.

Current Rule Layout

// some-rule.js
module.exports = (utils) => {
  return {
    check: (...) => {}
  };
};

Proposed Rule Layout

// some-rule-new.js
import { is } from 'bpmnlint-utils';

export default function() {
  ...
  return {
    check: ...
  };
}

Add a rule that checks for elements overlapping sequence flows

Sometimes situations may happen where elements are overlapping sequence flows, leading to unintentional execution behavior.

This is the case in the following picture where a task is placed on a flow going directly from start to gateway:

image

Cf. example diagram.

Tasks

  • Create sequence-flow-overlap rule that detects and reports this issue

Performance: early return/abort of traversal algorithm

Is your feature request related to a problem? Please describe

I want to be able to abort the traversal process early.
Proposed solution is a performance optimization if a rule does not require a full traversal.

Describe the solution you'd like

Change line 9 in lib/traversal.js:

module.exports = function traverse(element, fn) {
  if (fn(element))
    return;

  // ...
};

Then you can abort traversal early by returning true, e.g.:

function check(node, reporter) {
  // do stuff ...

  if (something)
    return true; // stops traversal

  // ...
}

Describe alternatives you've considered

Change nothing and let the algorithm do its thing even though it costs performance.

Caveats

Proposed solution would not work with promises. But I think this is negligible.

Document `no-inclusive-gateway` rule

Is your feature request related to a problem? Please describe

Currently, no-inclusive-gateway is a rule in the recommended set. However, the documentation does not give grounds why this element should be disallowed. I couldn't find any sources which would discourage usage of this gateway. This has already caused confusion on Camunda forum.

Describe the solution you'd like

Add grounds why rule exists and should be used.

Describe alternatives you've considered

Remove the rule from the recommended set, but it has already been decided against in #41 (comment)

Additional context

https://forum.camunda.org/t/linter-plugin-error-element-has-disallowed-type-bpmn-inclusivegateway/23320

Be Able to Configure Rules

Is your feature request related to a problem? Please describe

Rules cannot be configured at the moment. In eslint this is possible allowing for the reuse of configurable rules.

Describe the solution you'd like

An example of a configuration:

module.exports = {
  configs: {
    'foo': {
      rules: {
        'bar': [ 'error', {
          types: [ 'bpmn:ServiceTask' ]
        } ]
      }
    }
  }
};

Describe alternatives you've considered

Alternatively, rules with different configurations can be created as separate files. However, this would not be my preferred solution.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.