minimatch
Signed-off-by: Florian Dold <florian@dold.me>
This commit is contained in:
parent
a576fdfbf8
commit
45f1346990
93
packages/taler-util/src/globbing/balanced-match.ts
Normal file
93
packages/taler-util/src/globbing/balanced-match.ts
Normal file
@ -0,0 +1,93 @@
|
||||
/*
|
||||
Original work Copyright (C) 2013 Julian Gruber <julian@juliangruber.com>
|
||||
Modified work Copyright (C) 2021 Taler Systems S.A.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
to deal in the Software without restriction, including without limitation
|
||||
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
and/or sell copies of the Software, and to permit persons to whom the
|
||||
Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
*/
|
||||
|
||||
export function balanced(a: RegExp | string, b: RegExp | string, str: string) {
|
||||
let myA: string;
|
||||
let myB: string;
|
||||
if (a instanceof RegExp) myA = maybeMatch(a, str)!;
|
||||
else myA = a;
|
||||
if (b instanceof RegExp) myB = maybeMatch(b, str)!;
|
||||
else myB = b;
|
||||
|
||||
const r = range(myA, myB, str);
|
||||
|
||||
return (
|
||||
r && {
|
||||
start: r[0],
|
||||
end: r[1],
|
||||
pre: str.slice(0, r[0]),
|
||||
body: str.slice(r[0]! + myA!.length, r[1]),
|
||||
post: str.slice(r[1]! + myB!.length),
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {RegExp} reg
|
||||
* @param {string} str
|
||||
*/
|
||||
function maybeMatch(reg: RegExp, str: string) {
|
||||
const m = str.match(reg);
|
||||
return m ? m[0] : null;
|
||||
}
|
||||
|
||||
balanced.range = range;
|
||||
|
||||
/**
|
||||
* @param {string} a
|
||||
* @param {string} b
|
||||
* @param {string} str
|
||||
*/
|
||||
function range(a: string, b: string, str: string) {
|
||||
let begs: number[];
|
||||
let beg: number;
|
||||
let left, right, result;
|
||||
let ai = str.indexOf(a);
|
||||
let bi = str.indexOf(b, ai + 1);
|
||||
let i = ai;
|
||||
|
||||
if (ai >= 0 && bi > 0) {
|
||||
if (a === b) {
|
||||
return [ai, bi];
|
||||
}
|
||||
begs = [];
|
||||
left = str.length;
|
||||
|
||||
while (i >= 0 && !result) {
|
||||
if (i === ai) {
|
||||
begs.push(i);
|
||||
ai = str.indexOf(a, i + 1);
|
||||
} else if (begs.length === 1) {
|
||||
result = [begs.pop(), bi];
|
||||
} else {
|
||||
beg = begs.pop()!;
|
||||
if (beg < left) {
|
||||
left = beg;
|
||||
right = bi;
|
||||
}
|
||||
|
||||
bi = str.indexOf(b, i + 1);
|
||||
}
|
||||
|
||||
i = ai < bi && ai >= 0 ? ai : bi;
|
||||
}
|
||||
|
||||
if (begs.length) {
|
||||
result = [left, right];
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
249
packages/taler-util/src/globbing/brace-expansion.ts
Normal file
249
packages/taler-util/src/globbing/brace-expansion.ts
Normal file
@ -0,0 +1,249 @@
|
||||
/*
|
||||
Original work Copyright (C) 2013 Julian Gruber <julian@juliangruber.com>
|
||||
Modified work Copyright (C) 2021 Taler Systems S.A.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
to deal in the Software without restriction, including without limitation
|
||||
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
and/or sell copies of the Software, and to permit persons to whom the
|
||||
Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
*/
|
||||
|
||||
import { balanced } from "./balanced-match.js";
|
||||
|
||||
var escSlash = "\0SLASH" + Math.random() + "\0";
|
||||
var escOpen = "\0OPEN" + Math.random() + "\0";
|
||||
var escClose = "\0CLOSE" + Math.random() + "\0";
|
||||
var escComma = "\0COMMA" + Math.random() + "\0";
|
||||
var escPeriod = "\0PERIOD" + Math.random() + "\0";
|
||||
|
||||
/**
|
||||
* @return {number}
|
||||
*/
|
||||
function numeric(str: string): number {
|
||||
return parseInt(str, 10).toString() == str
|
||||
? parseInt(str, 10)
|
||||
: str.charCodeAt(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} str
|
||||
*/
|
||||
function escapeBraces(str: string) {
|
||||
return str
|
||||
.split("\\\\")
|
||||
.join(escSlash)
|
||||
.split("\\{")
|
||||
.join(escOpen)
|
||||
.split("\\}")
|
||||
.join(escClose)
|
||||
.split("\\,")
|
||||
.join(escComma)
|
||||
.split("\\.")
|
||||
.join(escPeriod);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} str
|
||||
*/
|
||||
function unescapeBraces(str: string) {
|
||||
return str
|
||||
.split(escSlash)
|
||||
.join("\\")
|
||||
.split(escOpen)
|
||||
.join("{")
|
||||
.split(escClose)
|
||||
.join("}")
|
||||
.split(escComma)
|
||||
.join(",")
|
||||
.split(escPeriod)
|
||||
.join(".");
|
||||
}
|
||||
|
||||
/**
|
||||
* Basically just str.split(","), but handling cases
|
||||
* where we have nested braced sections, which should be
|
||||
* treated as individual members, like {a,{b,c},d}
|
||||
* @param {string} str
|
||||
*/
|
||||
function parseCommaParts(str: string) {
|
||||
if (!str) return [""];
|
||||
|
||||
var parts: string[] = [];
|
||||
var m = balanced("{", "}", str);
|
||||
|
||||
if (!m) return str.split(",");
|
||||
|
||||
var pre = m.pre;
|
||||
var body = m.body;
|
||||
var post = m.post;
|
||||
var p = pre.split(",");
|
||||
|
||||
p[p.length - 1] += "{" + body + "}";
|
||||
var postParts = parseCommaParts(post);
|
||||
if (post.length) {
|
||||
p[p.length - 1] += postParts.shift();
|
||||
p.push.apply(p, postParts);
|
||||
}
|
||||
|
||||
parts.push.apply(parts, p);
|
||||
|
||||
return parts;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} str
|
||||
*/
|
||||
function expandTop(str: string) {
|
||||
if (!str) return [];
|
||||
|
||||
// I don't know why Bash 4.3 does this, but it does.
|
||||
// Anything starting with {} will have the first two bytes preserved
|
||||
// but *only* at the top level, so {},a}b will not expand to anything,
|
||||
// but a{},b}c will be expanded to [a}c,abc].
|
||||
// One could argue that this is a bug in Bash, but since the goal of
|
||||
// this module is to match Bash's rules, we escape a leading {}
|
||||
if (str.substr(0, 2) === "{}") {
|
||||
str = "\\{\\}" + str.substr(2);
|
||||
}
|
||||
|
||||
return expand(escapeBraces(str), true).map(unescapeBraces);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} str
|
||||
*/
|
||||
function embrace(str: string) {
|
||||
return "{" + str + "}";
|
||||
}
|
||||
/**
|
||||
* @param {string} el
|
||||
*/
|
||||
function isPadded(el: string) {
|
||||
return /^-?0\d/.test(el);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {number} i
|
||||
* @param {number} y
|
||||
*/
|
||||
function lte(i: number, y: number) {
|
||||
return i <= y;
|
||||
}
|
||||
/**
|
||||
* @param {number} i
|
||||
* @param {number} y
|
||||
*/
|
||||
function gte(i: number, y: number) {
|
||||
return i >= y;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} str
|
||||
* @param {boolean} [isTop]
|
||||
*/
|
||||
export function expand(str: string, isTop?: boolean): any {
|
||||
/** @type {string[]} */
|
||||
var expansions: string[] = [];
|
||||
|
||||
var m = balanced("{", "}", str);
|
||||
if (!m) return [str];
|
||||
|
||||
// no need to expand pre, since it is guaranteed to be free of brace-sets
|
||||
var pre = m.pre;
|
||||
var post = m.post.length ? expand(m.post, false) : [""];
|
||||
|
||||
if (/\$$/.test(m.pre)) {
|
||||
for (var k = 0; k < post.length; k++) {
|
||||
var expansion = pre + "{" + m.body + "}" + post[k];
|
||||
expansions.push(expansion);
|
||||
}
|
||||
} else {
|
||||
var isNumericSequence = /^-?\d+\.\.-?\d+(?:\.\.-?\d+)?$/.test(m.body);
|
||||
var isAlphaSequence = /^[a-zA-Z]\.\.[a-zA-Z](?:\.\.-?\d+)?$/.test(m.body);
|
||||
var isSequence = isNumericSequence || isAlphaSequence;
|
||||
var isOptions = m.body.indexOf(",") >= 0;
|
||||
if (!isSequence && !isOptions) {
|
||||
// {a},b}
|
||||
if (m.post.match(/,.*\}/)) {
|
||||
str = m.pre + "{" + m.body + escClose + m.post;
|
||||
return expand(str);
|
||||
}
|
||||
return [str];
|
||||
}
|
||||
|
||||
var n: string[];
|
||||
if (isSequence) {
|
||||
n = m.body.split(/\.\./);
|
||||
} else {
|
||||
n = parseCommaParts(m.body);
|
||||
if (n.length === 1) {
|
||||
// x{{a,b}}y ==> x{a}y x{b}y
|
||||
n = expand(n[0], false).map(embrace);
|
||||
if (n.length === 1) {
|
||||
return post.map(function (p: string) {
|
||||
return m!.pre + n[0] + p;
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// at this point, n is the parts, and we know it's not a comma set
|
||||
// with a single entry.
|
||||
var N: string[];
|
||||
|
||||
if (isSequence) {
|
||||
var x = numeric(n[0]);
|
||||
var y = numeric(n[1]);
|
||||
var width = Math.max(n[0].length, n[1].length);
|
||||
var incr = n.length == 3 ? Math.abs(numeric(n[2])) : 1;
|
||||
var test = lte;
|
||||
var reverse = y < x;
|
||||
if (reverse) {
|
||||
incr *= -1;
|
||||
test = gte;
|
||||
}
|
||||
var pad = n.some(isPadded);
|
||||
|
||||
N = [];
|
||||
|
||||
for (var i = x; test(i, y); i += incr) {
|
||||
var c;
|
||||
if (isAlphaSequence) {
|
||||
c = String.fromCharCode(i);
|
||||
if (c === "\\") c = "";
|
||||
} else {
|
||||
c = String(i);
|
||||
if (pad) {
|
||||
var need = width - c.length;
|
||||
if (need > 0) {
|
||||
var z = new Array(need + 1).join("0");
|
||||
if (i < 0) c = "-" + z + c.slice(1);
|
||||
else c = z + c;
|
||||
}
|
||||
}
|
||||
}
|
||||
N.push(c);
|
||||
}
|
||||
} else {
|
||||
N = [];
|
||||
|
||||
for (var j = 0; j < n.length; j++) {
|
||||
N.push.apply(N, expand(n[j], false));
|
||||
}
|
||||
}
|
||||
|
||||
for (var j = 0; j < N.length; j++) {
|
||||
for (var k = 0; k < post.length; k++) {
|
||||
var expansion = pre + N[j] + post[k];
|
||||
if (!isTop || isSequence || expansion) expansions.push(expansion);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return expansions;
|
||||
}
|
1004
packages/taler-util/src/globbing/minimatch.ts
Normal file
1004
packages/taler-util/src/globbing/minimatch.ts
Normal file
File diff suppressed because it is too large
Load Diff
@ -20,3 +20,4 @@ export * from "./walletTypes.js";
|
||||
export * from "./i18n.js";
|
||||
export * from "./logging.js";
|
||||
export * from "./url.js";
|
||||
export * from "./globbing/minimatch.js";
|
@ -46,10 +46,8 @@
|
||||
"dependencies": {
|
||||
"@gnu-taler/taler-util": "workspace:*",
|
||||
"@gnu-taler/taler-wallet-core": "workspace:*",
|
||||
"@types/minimatch": "^3.0.3",
|
||||
"axios": "^0.21.1",
|
||||
"cancellationtoken": "^2.2.0",
|
||||
"minimatch": "^3.0.4",
|
||||
"source-map-support": "^0.5.19",
|
||||
"tslib": "^2.1.0"
|
||||
}
|
||||
|
@ -15,7 +15,9 @@
|
||||
*/
|
||||
|
||||
import {
|
||||
delayMs,
|
||||
minimatch
|
||||
} from "@gnu-taler/taler-util";
|
||||
import {
|
||||
GlobalTestState,
|
||||
runTestWithState,
|
||||
shouldLingerInTest,
|
||||
@ -53,7 +55,6 @@ import { runWallettestingTest } from "./test-wallettesting";
|
||||
import { runTestWithdrawalManualTest } from "./test-withdrawal-manual";
|
||||
import { runWithdrawalAbortBankTest } from "./test-withdrawal-abort-bank";
|
||||
import { runWithdrawalBankIntegratedTest } from "./test-withdrawal-bank-integrated";
|
||||
import M from "minimatch";
|
||||
import { runMerchantExchangeConfusionTest } from "./test-merchant-exchange-confusion";
|
||||
import { runLibeufinBasicTest } from "./test-libeufin-basic";
|
||||
import { runLibeufinKeyrotationTest } from "./test-libeufin-keyrotation";
|
||||
@ -231,7 +232,7 @@ export async function runTests(spec: TestRunSpec) {
|
||||
|
||||
for (const [n, testCase] of allTests.entries()) {
|
||||
const testName = getTestName(testCase);
|
||||
if (spec.includePattern && !M(testName, spec.includePattern)) {
|
||||
if (spec.includePattern && !minimatch(testName, spec.includePattern)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -70,11 +70,9 @@ importers:
|
||||
'@rollup/plugin-json': ^4.1.0
|
||||
'@rollup/plugin-node-resolve': ^11.1.0
|
||||
'@rollup/plugin-replace': ^2.3.4
|
||||
'@types/minimatch': ^3.0.3
|
||||
'@types/node': ^14.14.22
|
||||
axios: ^0.21.1
|
||||
cancellationtoken: ^2.2.0
|
||||
minimatch: ^3.0.4
|
||||
prettier: ^2.2.1
|
||||
rimraf: ^3.0.2
|
||||
rollup: ^2.37.1
|
||||
@ -87,10 +85,8 @@ importers:
|
||||
dependencies:
|
||||
'@gnu-taler/taler-util': link:../taler-util
|
||||
'@gnu-taler/taler-wallet-core': link:../taler-wallet-core
|
||||
'@types/minimatch': 3.0.3
|
||||
axios: 0.21.1
|
||||
cancellationtoken: 2.2.0
|
||||
minimatch: 3.0.4
|
||||
source-map-support: 0.5.19
|
||||
tslib: 2.1.0
|
||||
devDependencies:
|
||||
@ -6275,10 +6271,6 @@ packages:
|
||||
'@types/braces': 3.0.0
|
||||
dev: true
|
||||
|
||||
/@types/minimatch/3.0.3:
|
||||
resolution: {integrity: sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==}
|
||||
dev: false
|
||||
|
||||
/@types/minimatch/3.0.4:
|
||||
resolution: {integrity: sha512-1z8k4wzFnNjVK/tlxvrWuK5WMt6mydWWP7+zvH5eFep4oj+UkrfiJTRtjCeBXNpwaA/FYqqtb4/QS4ianFpIRA==}
|
||||
dev: true
|
||||
@ -7712,6 +7704,7 @@ packages:
|
||||
|
||||
/balanced-match/1.0.2:
|
||||
resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==}
|
||||
dev: true
|
||||
|
||||
/base/0.11.2:
|
||||
resolution: {integrity: sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==}
|
||||
@ -7879,6 +7872,7 @@ packages:
|
||||
dependencies:
|
||||
balanced-match: 1.0.2
|
||||
concat-map: 0.0.1
|
||||
dev: true
|
||||
|
||||
/braces/2.3.2:
|
||||
resolution: {integrity: sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==}
|
||||
@ -8706,6 +8700,7 @@ packages:
|
||||
|
||||
/concat-map/0.0.1:
|
||||
resolution: {integrity: sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=}
|
||||
dev: true
|
||||
|
||||
/concat-stream/1.6.2:
|
||||
resolution: {integrity: sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==}
|
||||
@ -14215,6 +14210,7 @@ packages:
|
||||
resolution: {integrity: sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==}
|
||||
dependencies:
|
||||
brace-expansion: 1.1.11
|
||||
dev: true
|
||||
|
||||
/minimist/1.2.5:
|
||||
resolution: {integrity: sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==}
|
||||
|
Loading…
Reference in New Issue
Block a user