Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add ignore file configuration #1

Merged
merged 1 commit into from
Nov 22, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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