mirror of
https://github.com/dorny/paths-filter.git
synced 2025-06-08 00:59:04 +00:00
Export files matching rules (#32)
* Export files matching rules * Improve debug output * Fix PR test workflow * Always quote output path + fix PR test * Use proper single quote escaping in workflow file * Improve error handling and docs for list-files input parameter
This commit is contained in:
parent
483986d0a7
commit
3f845744aa
8 changed files with 205 additions and 125 deletions
102
dist/index.js
vendored
102
dist/index.js
vendored
|
@ -4533,9 +4533,10 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|||
const fs = __importStar(__webpack_require__(747));
|
||||
const core = __importStar(__webpack_require__(470));
|
||||
const github = __importStar(__webpack_require__(469));
|
||||
const filter_1 = __importDefault(__webpack_require__(235));
|
||||
const filter_1 = __webpack_require__(235);
|
||||
const file_1 = __webpack_require__(258);
|
||||
const git = __importStar(__webpack_require__(136));
|
||||
const shell_escape_1 = __importDefault(__webpack_require__(751));
|
||||
function run() {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
try {
|
||||
|
@ -4546,22 +4547,21 @@ function run() {
|
|||
const token = core.getInput('token', { required: false });
|
||||
const filtersInput = core.getInput('filters', { required: true });
|
||||
const filtersYaml = isPathInput(filtersInput) ? getConfigFileContent(filtersInput) : filtersInput;
|
||||
const filter = new filter_1.default(filtersYaml);
|
||||
const listFiles = core.getInput('list-files', { required: false }).toLowerCase() || 'none';
|
||||
if (!isExportFormat(listFiles)) {
|
||||
core.setFailed(`Input parameter 'list-files' is set to invalid value '${listFiles}'`);
|
||||
return;
|
||||
}
|
||||
const filter = new filter_1.Filter(filtersYaml);
|
||||
const files = yield getChangedFiles(token);
|
||||
let results;
|
||||
if (files === null) {
|
||||
// Change detection was not possible
|
||||
core.info('All filters will be set to true.');
|
||||
results = {};
|
||||
for (const key of Object.keys(filter.rules)) {
|
||||
results[key] = true;
|
||||
}
|
||||
exportNoMatchingResults(filter);
|
||||
}
|
||||
else {
|
||||
results = filter.match(files);
|
||||
const results = filter.match(files);
|
||||
exportResults(results, listFiles);
|
||||
}
|
||||
exportFiles(files !== null && files !== void 0 ? files : []);
|
||||
exportResults(results);
|
||||
}
|
||||
catch (error) {
|
||||
core.setFailed(error.message);
|
||||
|
@ -4669,35 +4669,42 @@ function getChangedFilesFromApi(token, pullRequest) {
|
|||
return files;
|
||||
});
|
||||
}
|
||||
function exportFiles(files) {
|
||||
var _a;
|
||||
const output = {};
|
||||
output[file_1.ChangeStatus.Added] = [];
|
||||
output[file_1.ChangeStatus.Deleted] = [];
|
||||
output[file_1.ChangeStatus.Modified] = [];
|
||||
for (const file of files) {
|
||||
const arr = (_a = output[file.status]) !== null && _a !== void 0 ? _a : [];
|
||||
arr.push(file.filename);
|
||||
output[file.status] = arr;
|
||||
}
|
||||
core.setOutput('files', output);
|
||||
// Files grouped by status
|
||||
for (const [status, paths] of Object.entries(output)) {
|
||||
core.startGroup(`${status.toUpperCase()} files:`);
|
||||
for (const filename of paths) {
|
||||
core.info(filename);
|
||||
}
|
||||
core.endGroup();
|
||||
function exportNoMatchingResults(filter) {
|
||||
core.info('All filters will be set to true but no matched files will be exported.');
|
||||
for (const key of Object.keys(filter.rules)) {
|
||||
core.setOutput(key, true);
|
||||
}
|
||||
}
|
||||
function exportResults(results) {
|
||||
core.startGroup('Filters results:');
|
||||
for (const [key, value] of Object.entries(results)) {
|
||||
core.info(`${key}: ${value}`);
|
||||
function exportResults(results, format) {
|
||||
for (const [key, files] of Object.entries(results)) {
|
||||
const value = files.length > 0;
|
||||
core.startGroup(`Filter ${key} = ${value}`);
|
||||
core.info('Matching files:');
|
||||
for (const file of files) {
|
||||
core.info(`${file.filename} [${file.status}]`);
|
||||
}
|
||||
core.setOutput(key, value);
|
||||
if (format !== 'none') {
|
||||
const filesValue = serializeExport(files, format);
|
||||
core.setOutput(`${key}_files`, filesValue);
|
||||
}
|
||||
}
|
||||
core.endGroup();
|
||||
}
|
||||
function serializeExport(files, format) {
|
||||
const fileNames = files.map(file => file.filename);
|
||||
switch (format) {
|
||||
case 'json':
|
||||
return JSON.stringify(fileNames);
|
||||
case 'shell':
|
||||
return fileNames.map(shell_escape_1.default).join(' ');
|
||||
default:
|
||||
return '';
|
||||
}
|
||||
}
|
||||
function isExportFormat(value) {
|
||||
return value === 'none' || value === 'shell' || value === 'json';
|
||||
}
|
||||
run();
|
||||
|
||||
|
||||
|
@ -4785,6 +4792,7 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|||
return result;
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.Filter = void 0;
|
||||
const jsyaml = __importStar(__webpack_require__(414));
|
||||
const minimatch = __importStar(__webpack_require__(595));
|
||||
// Minimatch options used in all matchers
|
||||
|
@ -4812,15 +4820,16 @@ class Filter {
|
|||
this.rules[key] = this.parseFilterItemYaml(item);
|
||||
}
|
||||
}
|
||||
// Returns dictionary with match result per rule
|
||||
match(files) {
|
||||
const result = {};
|
||||
for (const [key, patterns] of Object.entries(this.rules)) {
|
||||
const match = files.some(file => patterns.some(rule => (rule.status === undefined || rule.status.includes(file.status)) && rule.matcher.match(file.filename)));
|
||||
result[key] = match;
|
||||
result[key] = files.filter(file => this.isMatch(file, patterns));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
isMatch(file, patterns) {
|
||||
return patterns.some(rule => (rule.status === undefined || rule.status.includes(file.status)) && rule.matcher.match(file.filename));
|
||||
}
|
||||
parseFilterItemYaml(item) {
|
||||
if (Array.isArray(item)) {
|
||||
return flat(item.map(i => this.parseFilterItemYaml(i)));
|
||||
|
@ -4849,7 +4858,7 @@ class Filter {
|
|||
throw new Error(`Invalid filter YAML format: ${message}.`);
|
||||
}
|
||||
}
|
||||
exports.default = Filter;
|
||||
exports.Filter = Filter;
|
||||
// Creates a new array with all sub-array elements concatenated
|
||||
// In future could be replaced by Array.prototype.flat (supported on Node.js 11+)
|
||||
function flat(arr) {
|
||||
|
@ -15288,6 +15297,23 @@ function sync (path, options) {
|
|||
|
||||
module.exports = require("fs");
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 751:
|
||||
/***/ (function(__unusedmodule, exports) {
|
||||
|
||||
"use strict";
|
||||
|
||||
// Credits to https://github.com/xxorax/node-shell-escape
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
function shellEscape(value) {
|
||||
return `'${value.replace(/'/g, "'\\''")}'`
|
||||
.replace(/^(?:'')+/g, '') // unduplicate single-quote at the beginning
|
||||
.replace(/\\'''/g, "\\'"); // remove non-escaped single-quote if there are enclosed between 2 escaped
|
||||
}
|
||||
exports.default = shellEscape;
|
||||
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 753:
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue