Skip to content

Commit

Permalink
feat: add ignore file configuration (#1)
Browse files Browse the repository at this point in the history
  • Loading branch information
danteay authored Nov 22, 2023
1 parent 9e6914a commit f318e61
Show file tree
Hide file tree
Showing 5 changed files with 313 additions and 1 deletion.
37 changes: 37 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,15 @@

A github action that compare a list of JSON files an return the missing keys between each other.

## Action configurations

| Input Name | Description | Required | Default |
|--------------|-----------------------------------------------------------------------------------------------------------------|----------|--------------------|
| `files` | List of JSON file paths to check between each other. Should be at least 2 files. | `false` | - |
| `search_path`| Path to a folder that will be inspected to search all JSON files and compare each other. | `false` | - |
| `search_pattern` | Regular expression used on search path to find desired files. | `false` | `\.json$` |
| `ignore_file`| Path to a specific ignore file configuration | `false` | `.json-diff-ignore.json` |

## Usage

You can compare specific files using the next configuration:
Expand All @@ -28,3 +37,31 @@ Or if you want to search on a specific route you can use the next configuration:
```

This will find on the specified route all files that match the `search_pattern` to compare each other

### Ignore rules

If you need to ignore some specific keys on certain files you can use an ignore json file on your project
root. By the fault the name of this files is `.json-diff-ignore.json` and has this structure:

```json
[
{
"pattern": "regexp/file\\.json$",
"ignoreKeys": ["key1"]
},
{
"pattern": "regexp/file2\\.json$",
"ignoreKeys": ["key2"]
}
]
```

If you what to specify a specific path to find the ignore file you can do that by adding the next configuration:

```yml
- name: Run JSON Diff Action
uses: Drafteame/json-diff-action@main
with:
# ...
ignore_file: /path/to/.json-diff-ignore.json
```
6 changes: 6 additions & 0 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,13 @@ inputs:
description: Regular expression used on search path to find desired files.
required: false
default: '\\.json$'
ignore_file:
description: Path to a specific ignore file configuration
required: false
default: '.json-diff-ignore.json'

runs:
using: "docker"
image: "Dockerfile"


1 change: 1 addition & 0 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ const main = () => {
core.getInput("files"),
core.getInput("search_path"),
core.getInput("search_pattern"),
core.getInput("ignore_file"),
);

try {
Expand Down
98 changes: 97 additions & 1 deletion src/Action.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import lodash from "lodash";
import fs from "fs";
import path from "path";
import core from "@actions/core";

import {
NotEnoughFiles,
Expand Down Expand Up @@ -30,13 +31,25 @@ export default class Action {
*/
#searchPattern;

/**
* Map with rules to ignore specified keys on specific files that match one or more patterns
* @type {Array<Object>}
*/
#ignoreRules;

/**
* Object with the loaded ignore keys by file
* @type {Object}
*/
#ignoreKeysByFile;

/**
* Final list of files after initial validations
* @type {Array<string>}
*/
#fileList;

constructor(files, searchPath, searchPattern) {
constructor(files, searchPath, searchPattern, ignoreFile) {
this.#files = files;
this.#searchPath = searchPath;

Expand All @@ -46,6 +59,9 @@ export default class Action {
this.#searchPattern = searchPattern;
}

this.#ignoreRules = this.#getIgnoreRules(ignoreFile);
this.#ignoreKeysByFile = {};

this.#fileList = this.#validateInputs();
}

Expand All @@ -58,6 +74,15 @@ export default class Action {
return this.#fileList;
}

/**
* Return the loaded ignore rules.
*
* @returns {Array<Object>}
*/
getIgnoreRules() {
return this.#ignoreRules;
}

/**
* Execute comparison of file keys and return the found differences.
*
Expand Down Expand Up @@ -94,6 +119,10 @@ export default class Action {

keysFile2
.filter((key) => {
if (this.#keyShouldBeIgnored(file1, key)) {
return false;
}

const notInKeys1 = !keysFile1.includes(key);
const notInMissing = !missing.includes(key);

Expand Down Expand Up @@ -237,4 +266,71 @@ export default class Action {

return newPath;
}

/**
* Return ignore file configuration to apply on checks
*
* @param {string} ignoreFile Path to the specified ignore file
*
* @return {Array<Object>}
*/
#getIgnoreRules(ignoreFile) {
let file = ".json-diff-ignore.json";

if (!lodash.isEmpty(ignoreFile)) {
file = ignoreFile;
}

if (!fs.existsSync(file)) {
return [];
}

const content = fs.readFileSync(file, { encoding: "utf-8" });

try {
return JSON.parse(content);
} catch (e) {
core.info(
`Error reading ignore file from '${file}', no rules will be applied...'`,
);
return [];
}
}

/**
* Validate if a given key should be ignored or not by the given file.
*
* @param {string} file File that should ignore or not the given key if not present on it.
* @param {string} key Key that should be ignored or not by the file.
*
* @returns {boolean}
*/
#keyShouldBeIgnored(file, key) {
if (file in this.#ignoreKeysByFile) {
return this.#ignoreKeysByFile[file].includes(key);
}

let keysToIgnore = [];

this.#ignoreRules.forEach((rule) => {
const pattern = rule.pattern || null;
const keys = rule.ignoreKeys || [];

if (lodash.isEmpty(pattern) || keys.length === 0) {
return;
}

const regexp = new RegExp(pattern);

if (regexp.test(file)) {
keys.forEach((item) => {
keysToIgnore.push(item);
});
}
});

this.#ignoreKeysByFile[file] = keysToIgnore;

return keysToIgnore.includes(key);
}
}
Loading

0 comments on commit f318e61

Please sign in to comment.