Skip to content

Commit

Permalink
Merge pull request #115 from trolit/develop
Browse files Browse the repository at this point in the history
Release/2022-09-05
  • Loading branch information
trolit authored Sep 5, 2022
2 parents bddbf9a + 5cad44c commit e8de791
Show file tree
Hide file tree
Showing 14 changed files with 1,285 additions and 434 deletions.
47 changes: 32 additions & 15 deletions .github/AVAILABLE_RULES.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,16 +82,36 @@
{
"keywords": [
{
"name": "require (packages)",
"regex": "require(?!.*@).*",
"name": "import (packages)",
"regex": "import.*(?:from(?!.*[@,.]/)|{)",
"order": "ascending",
"ignoreNewline": false
"ignoreNewline": false,
"multiLineOptions": [
{
"indicator": {
"notIncludes": "from"
},
"limiter": {
"regex": "from(?!.*[@,.]/)"
}
}
]
},
{
"name": "require (other)",
"regex": "require.*@.*",
"name": "import (files)",
"regex": "import.*(?:from.*[@,.]/|{)",
"order": "ascending",
"ignoreNewline": false
"ignoreNewline": false,
"multiLineOptions": [
{
"indicator": {
"notIncludes": "from"
},
"limiter": {
"regex": "from.*[@,.]/"
}
}
]
}
]
}
Expand Down Expand Up @@ -169,13 +189,10 @@
"keywords": [
{
"name": "import",
"regex": "import.*",
"regex": "import.*(?:from|{)",
"position": {
"custom": {
"name": "<script>",
"regex": "<script>",
"BOF": false
}
"BOF": true,
"custom": null
},
"maxLineBreaks": 0,
"enforced": true,
Expand All @@ -194,11 +211,11 @@
"order": [
{
"name": "packages",
"regex": "import(?!.*@).*"
"regex": "from(?!.*[@,.]/)"
},
{
"name": "other",
"regex": "import.*"
"name": "others",
"regex": "from.*[@,.]/"
}
]
}
Expand Down
61 changes: 28 additions & 33 deletions .github/DEV_OVERVIEW.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
## Short dev overview

## 1. Basics
- [Data acquisition](#1--basics)
- [Data processing](#2--data-processing)
- [Creating new rule](#3--rule-creation)

As mentioned earlier, Patchron knowledge is based upon patches. Patch contains latest changes done to particular file. To understand it better, here is example of how received data looks like:
## 1. 🎬 Basics

As mentioned earlier, Patchron knowledge is based upon patches. Patch contains latest changes done to particular file. To understand it better, here is an example of how received data looks like:

```js
// first part (hunk) of file
"@@ -10,13 +10,7 @@ const payload = require('./fixtures/pull_request.opened');\n" +
" const fs = require('fs');\n" +
" const path = require('path');\n" +
Expand All @@ -17,7 +20,6 @@ As mentioned earlier, Patchron knowledge is based upon patches. Patch contains l
"-} = require('@jest/globals');\n" +
"+const { expect, test } = require('@jest/globals');\n" +
' \n' +
// second part (hunk) of file
'@@ -27,7 +21,6 @@ const deployment = {\n' +
" schema: 'rocks!',\n" +
' },\n' +
Expand All @@ -26,10 +28,9 @@ As mentioned earlier, Patchron knowledge is based upon patches. Patch contains l
' };\n' +
```

To understand how git identifies what was changed, removed or added (and in which line it happend), check explanation tab:
### 1.1. 🆘 Patch details

<details>
<summary>Explanation</summary>
If you aren't familiar with patch indicators, here is short explanation:

- line that was added starts with `+`
- line that was removed starts with `-`
Expand All @@ -45,30 +46,20 @@ Hunk header e.g. `@@ -10,13 +10,7 @@` contains following information:
- 10 is number of first line that starts below hunk header
- 7 is right side hunk length (sum of unchanged and added lines)

</details>

## 2. Data processing
## 2. 🔄 Data processing

In almost all rules in Patchron, received data is organized via [setupData](https://github.com/trolit/Patchron/blob/0cefee8ba7437f55d98c07f3cc67b310851f47d8/src/rules/Base.js#L105) to easier further code analysis. Content is split by newline and each row contains default information mentioned below:
In all rules that analyze source code, received data is organized via [setupData](https://github.com/trolit/Patchron/blob/0cefee8ba7437f55d98c07f3cc67b310851f47d8/src/rules/Base.js#L105) method that "unpacks" patch content into collection. Each object contains information mentioned below:

```ts
{
index: number, // index in relation to full patch
index: number,
indentation: number,
content: string,
trimmedContent: string
}
```

Few things to note:

- Indentation can be sometimes a must to identify relation between particular parts of source code.
- `trimmedContent` and `content` have line state signs removed. To addition content of lines that:
- are spacers, are replaced with `<<< newline >>>`
- were removed, are replaced with `<<< merge >>>`
- were commented, are replaced with `<<< commented >>>`

Rules that require more than single line of patch to perform their checking, are using `getMultiLineStructure` helper. It allows to pass `multiLineOptions` array. Each element is built in the following manner:
Rules that are intended to focus on more than single line of patch are using [getMultiLineStructure](../src/helpers/getMultiLineStructure.js) helper. It allows to pass `multiLineOptions` array. Each array's object is built in the following manner:

```ts
{
Expand All @@ -77,16 +68,21 @@ Rules that require more than single line of patch to perform their checking, are
}
```

For more details on how those objects can be arranged, refer to [general type definitions](https://github.com/trolit/Patchron/blob/master/src/type-definitions/general.js) or check how it's used in config files.
For more details on how those objects can be arranged, refer to [general type definitions](https://github.com/trolit/Patchron/blob/master/src/type-definitions/general.js), implementation itself or examples.

## 3. 💡 Rule creation

In each rule we can mark out 3 to 4 steps: 1) loading configuration, 2) setting up data (does not refer to `pull` rules), 3) performing review and 4) returning comments. The things that we need to focus on are:

## 3. Rule creation
- awareness of how `file.splitPatch` (and `data` after `this.setupData(splitPatch)`) looks like
- concept how to determine case that should be commented out to the PR owner

Creating new rule is relatively simple. Before making first step, pin to IDE [type definitions](https://github.com/trolit/Patchron/blob/master/src/type-definitions/index.js) to see what lies under e.g. `patchronContext`. Copy rule structure from another file or refer to template below and start coding.
Once project is forked/pulled, as first step in rule creation, consider pinning to IDE [type definitions](https://github.com/trolit/Patchron/blob/master/src/type-definitions/index.js). To start scratching rule, copy structure from another file implementation or refer to template given below and start coding 🌞 If you prefer to write tests first, feel free to do so 👍

```js
const BaseRule = require('src/rules/Base');

class PredefinedFilenamesRule extends BaseRule {
class TemplateRule extends BaseRule {
/**
* @param {PatchronContext} patchronContext
* @param {object} config
Expand All @@ -99,28 +95,27 @@ class PredefinedFilenamesRule extends BaseRule {
}

invoke() {
const reviewComments = [];

// 1. setup data (if rule targets patch content)
const { splitPatch } = this.file;

const data = this.setupData(splitPatch);

const reviewComments = [];

// 2. apply logic to determine wrong cases

// 3. add comments to array
// 2. determine wrong cases and add comments to array

// 4. done
// 3. done
return reviewComments;
}

/**
* @returns {string}
*/
_getCommentBody(filename, expectedName) {
_getCommentBody(param1, param2) {
// if comment has complicated markdown structure (like in MarkedCommentsRule) use `dedent-js`
return '';
}
}

module.exports = PredefinedFilenamesRule;
module.exports = TemplateRule;
```
Loading

0 comments on commit e8de791

Please sign in to comment.