diff --git a/.github/scripts/merge_manager.js b/.github/scripts/merge_manager.js index f55d6e4d3..c2b39de6a 100644 --- a/.github/scripts/merge_manager.js +++ b/.github/scripts/merge_manager.js @@ -1,5 +1,5 @@ const { Buffer } = require('node:buffer'); -const { minimatch } = require('./minimatch-lite.js'); +const { minimatch } = require('minimatch'); const { ensureRateLimitWrapped } = require('./github-rate-limited-wrapper.js'); async function fetchAllowlist(github, owner, repo, path, ref) { diff --git a/.github/scripts/minimatch-lite.js b/.github/scripts/minimatch-lite.js deleted file mode 100644 index 345b37fe9..000000000 --- a/.github/scripts/minimatch-lite.js +++ /dev/null @@ -1,176 +0,0 @@ -'use strict'; - -function escapeRegExp(value) { - return value.replace(/[\\^$.*+?()[\]{}|]/g, '\\$&'); -} - -function expandBraces(pattern) { - const start = pattern.indexOf('{'); - if (start === -1) { - return [pattern]; - } - let depth = 0; - let end = -1; - for (let i = start; i < pattern.length; i += 1) { - const char = pattern[i]; - if (char === '\\') { - i += 1; - continue; - } - if (char === '{') { - depth += 1; - } else if (char === '}') { - depth -= 1; - if (depth === 0) { - end = i; - break; - } - } - } - if (end === -1) { - return [pattern]; - } - const prefix = pattern.slice(0, start); - const suffix = pattern.slice(end + 1); - const body = pattern.slice(start + 1, end); - const parts = []; - let current = ''; - let nested = 0; - for (let i = 0; i < body.length; i += 1) { - const char = body[i]; - if (char === '\\') { - current += char; - if (i + 1 < body.length) { - current += body[i + 1]; - i += 1; - } - continue; - } - if (char === '{') { - nested += 1; - } else if (char === '}') { - nested -= 1; - } - if (char === ',' && nested === 0) { - parts.push(current); - current = ''; - continue; - } - current += char; - } - parts.push(current); - const expanded = []; - for (const part of parts) { - for (const next of expandBraces(`${prefix}${part}${suffix}`)) { - expanded.push(next); - } - } - return expanded; -} - -function globToRegExp(pattern) { - let regex = '^'; - for (let i = 0; i < pattern.length; i += 1) { - const char = pattern[i]; - if (char === '\\') { - const next = pattern[i + 1]; - if (next !== undefined) { - regex += escapeRegExp(next); - i += 1; - } else { - regex += '\\\\'; - } - continue; - } - if (char === '*') { - const next = pattern[i + 1]; - if (next === '*') { - const nextChar = pattern[i + 2]; - if (nextChar === '/') { - regex += '(?:.*/)?'; - i += 2; - } else { - regex += '.*'; - i += 1; - } - } else { - regex += '[^/]*'; - } - continue; - } - if (char === '?') { - regex += '[^/]'; - continue; - } - if (char === '[') { - let j = i + 1; - let content = ''; - let closed = false; - if (pattern[j] === '!' || pattern[j] === '^') { - content += '^'; - j += 1; - } - for (; j < pattern.length; j += 1) { - const inner = pattern[j]; - if (inner === '\\') { - if (j + 1 < pattern.length) { - content += `\\${pattern[j + 1]}`; - j += 1; - continue; - } - } - if (inner === ']') { - closed = true; - break; - } - content += inner; - } - if (closed) { - regex += `[${content}]`; - i = j; - } else { - regex += '\\['; - } - continue; - } - regex += escapeRegExp(char); - } - regex += '$'; - return new RegExp(regex); -} - -function minimatch(pathname, pattern, options = {}) { - if (typeof pathname !== 'string' || typeof pattern !== 'string') { - return false; - } - - const opts = options || {}; - - if (!opts.nocomment && pattern.startsWith('#')) { - return false; - } - - if (!opts.nonegate && pattern.startsWith('!')) { - const next = pattern.slice(1); - return !minimatch(pathname, next, { ...opts, nonegate: true }); - } - - let target = pathname; - let pat = pattern; - - if (opts.nocase) { - target = target.toLowerCase(); - pat = pat.toLowerCase(); - } - - const patterns = expandBraces(pat); - for (const expanded of patterns) { - const regex = globToRegExp(expanded); - if (regex.test(target)) { - return true; - } - } - return false; -} - -module.exports = { minimatch }; diff --git a/.github/scripts/pr-context-graphql.js b/.github/scripts/pr-context-graphql.js index 6eb3ffa1e..fafcc2d4c 100644 --- a/.github/scripts/pr-context-graphql.js +++ b/.github/scripts/pr-context-graphql.js @@ -1,7 +1,7 @@ 'use strict'; const { ensureRateLimitWrapped } = require('./github-rate-limited-wrapper.js'); -const { minimatch } = require('./minimatch-lite.js'); +const { minimatch } = require('minimatch'); /** * GraphQL-based PR Context Fetcher diff --git a/.github/sync-manifest.yml b/.github/sync-manifest.yml index ad794f0c0..6aad21089 100644 --- a/.github/sync-manifest.yml +++ b/.github/sync-manifest.yml @@ -248,6 +248,12 @@ scripts: - source: .github/scripts/node_modules/minimatch/ description: "Vendored minimatch dependency for .github scripts" + - source: .github/scripts/node_modules/brace-expansion/ + description: "Vendored brace-expansion dependency (transitive dep of minimatch)" + + - source: .github/scripts/node_modules/balanced-match/ + description: "Vendored balanced-match dependency (transitive dep of brace-expansion)" + # JavaScript scripts for issue/PR handling - source: .github/scripts/issue_pr_locator.js description: "Locates PRs associated with issues" diff --git a/templates/consumer-repo/.github/scripts/merge_manager.js b/templates/consumer-repo/.github/scripts/merge_manager.js index f55d6e4d3..c2b39de6a 100644 --- a/templates/consumer-repo/.github/scripts/merge_manager.js +++ b/templates/consumer-repo/.github/scripts/merge_manager.js @@ -1,5 +1,5 @@ const { Buffer } = require('node:buffer'); -const { minimatch } = require('./minimatch-lite.js'); +const { minimatch } = require('minimatch'); const { ensureRateLimitWrapped } = require('./github-rate-limited-wrapper.js'); async function fetchAllowlist(github, owner, repo, path, ref) { diff --git a/templates/consumer-repo/.github/scripts/node_modules/balanced-match/.github/FUNDING.yml b/templates/consumer-repo/.github/scripts/node_modules/balanced-match/.github/FUNDING.yml new file mode 100644 index 000000000..cea8b16e9 --- /dev/null +++ b/templates/consumer-repo/.github/scripts/node_modules/balanced-match/.github/FUNDING.yml @@ -0,0 +1,2 @@ +tidelift: "npm/balanced-match" +patreon: juliangruber diff --git a/templates/consumer-repo/.github/scripts/node_modules/balanced-match/LICENSE.md b/templates/consumer-repo/.github/scripts/node_modules/balanced-match/LICENSE.md new file mode 100644 index 000000000..2cdc8e414 --- /dev/null +++ b/templates/consumer-repo/.github/scripts/node_modules/balanced-match/LICENSE.md @@ -0,0 +1,21 @@ +(MIT) + +Copyright (c) 2013 Julian Gruber <julian@juliangruber.com> + +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. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/templates/consumer-repo/.github/scripts/node_modules/balanced-match/README.md b/templates/consumer-repo/.github/scripts/node_modules/balanced-match/README.md new file mode 100644 index 000000000..d2a48b6b4 --- /dev/null +++ b/templates/consumer-repo/.github/scripts/node_modules/balanced-match/README.md @@ -0,0 +1,97 @@ +# balanced-match + +Match balanced string pairs, like `{` and `}` or `` and ``. Supports regular expressions as well! + +[![build status](https://secure.travis-ci.org/juliangruber/balanced-match.svg)](http://travis-ci.org/juliangruber/balanced-match) +[![downloads](https://img.shields.io/npm/dm/balanced-match.svg)](https://www.npmjs.org/package/balanced-match) + +[![testling badge](https://ci.testling.com/juliangruber/balanced-match.png)](https://ci.testling.com/juliangruber/balanced-match) + +## Example + +Get the first matching pair of braces: + +```js +var balanced = require('balanced-match'); + +console.log(balanced('{', '}', 'pre{in{nested}}post')); +console.log(balanced('{', '}', 'pre{first}between{second}post')); +console.log(balanced(/\s+\{\s+/, /\s+\}\s+/, 'pre { in{nest} } post')); +``` + +The matches are: + +```bash +$ node example.js +{ start: 3, end: 14, pre: 'pre', body: 'in{nested}', post: 'post' } +{ start: 3, + end: 9, + pre: 'pre', + body: 'first', + post: 'between{second}post' } +{ start: 3, end: 17, pre: 'pre', body: 'in{nest}', post: 'post' } +``` + +## API + +### var m = balanced(a, b, str) + +For the first non-nested matching pair of `a` and `b` in `str`, return an +object with those keys: + +* **start** the index of the first match of `a` +* **end** the index of the matching `b` +* **pre** the preamble, `a` and `b` not included +* **body** the match, `a` and `b` not included +* **post** the postscript, `a` and `b` not included + +If there's no match, `undefined` will be returned. + +If the `str` contains more `a` than `b` / there are unmatched pairs, the first match that was closed will be used. For example, `{{a}` will match `['{', 'a', '']` and `{a}}` will match `['', 'a', '}']`. + +### var r = balanced.range(a, b, str) + +For the first non-nested matching pair of `a` and `b` in `str`, return an +array with indexes: `[ , ]`. + +If there's no match, `undefined` will be returned. + +If the `str` contains more `a` than `b` / there are unmatched pairs, the first match that was closed will be used. For example, `{{a}` will match `[ 1, 3 ]` and `{a}}` will match `[0, 2]`. + +## Installation + +With [npm](https://npmjs.org) do: + +```bash +npm install balanced-match +``` + +## Security contact information + +To report a security vulnerability, please use the +[Tidelift security contact](https://tidelift.com/security). +Tidelift will coordinate the fix and disclosure. + +## License + +(MIT) + +Copyright (c) 2013 Julian Gruber <julian@juliangruber.com> + +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. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/templates/consumer-repo/.github/scripts/node_modules/balanced-match/index.js b/templates/consumer-repo/.github/scripts/node_modules/balanced-match/index.js new file mode 100644 index 000000000..c67a64608 --- /dev/null +++ b/templates/consumer-repo/.github/scripts/node_modules/balanced-match/index.js @@ -0,0 +1,62 @@ +'use strict'; +module.exports = balanced; +function balanced(a, b, str) { + if (a instanceof RegExp) a = maybeMatch(a, str); + if (b instanceof RegExp) b = maybeMatch(b, str); + + var r = range(a, b, str); + + return r && { + start: r[0], + end: r[1], + pre: str.slice(0, r[0]), + body: str.slice(r[0] + a.length, r[1]), + post: str.slice(r[1] + b.length) + }; +} + +function maybeMatch(reg, str) { + var m = str.match(reg); + return m ? m[0] : null; +} + +balanced.range = range; +function range(a, b, str) { + var begs, beg, left, right, result; + var ai = str.indexOf(a); + var bi = str.indexOf(b, ai + 1); + var 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; +} diff --git a/templates/consumer-repo/.github/scripts/node_modules/balanced-match/package.json b/templates/consumer-repo/.github/scripts/node_modules/balanced-match/package.json new file mode 100644 index 000000000..ce6073e04 --- /dev/null +++ b/templates/consumer-repo/.github/scripts/node_modules/balanced-match/package.json @@ -0,0 +1,48 @@ +{ + "name": "balanced-match", + "description": "Match balanced character pairs, like \"{\" and \"}\"", + "version": "1.0.2", + "repository": { + "type": "git", + "url": "git://github.com/juliangruber/balanced-match.git" + }, + "homepage": "https://github.com/juliangruber/balanced-match", + "main": "index.js", + "scripts": { + "test": "tape test/test.js", + "bench": "matcha test/bench.js" + }, + "devDependencies": { + "matcha": "^0.7.0", + "tape": "^4.6.0" + }, + "keywords": [ + "match", + "regexp", + "test", + "balanced", + "parse" + ], + "author": { + "name": "Julian Gruber", + "email": "mail@juliangruber.com", + "url": "http://juliangruber.com" + }, + "license": "MIT", + "testling": { + "files": "test/*.js", + "browsers": [ + "ie/8..latest", + "firefox/20..latest", + "firefox/nightly", + "chrome/25..latest", + "chrome/canary", + "opera/12..latest", + "opera/next", + "safari/5.1..latest", + "ipad/6.0..latest", + "iphone/6.0..latest", + "android-browser/4.2..latest" + ] + } +} diff --git a/templates/consumer-repo/.github/scripts/node_modules/brace-expansion/.github/FUNDING.yml b/templates/consumer-repo/.github/scripts/node_modules/brace-expansion/.github/FUNDING.yml new file mode 100644 index 000000000..79d1eafce --- /dev/null +++ b/templates/consumer-repo/.github/scripts/node_modules/brace-expansion/.github/FUNDING.yml @@ -0,0 +1,2 @@ +tidelift: "npm/brace-expansion" +patreon: juliangruber diff --git a/templates/consumer-repo/.github/scripts/node_modules/brace-expansion/LICENSE b/templates/consumer-repo/.github/scripts/node_modules/brace-expansion/LICENSE new file mode 100644 index 000000000..de3226673 --- /dev/null +++ b/templates/consumer-repo/.github/scripts/node_modules/brace-expansion/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2013 Julian Gruber + +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. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/templates/consumer-repo/.github/scripts/node_modules/brace-expansion/README.md b/templates/consumer-repo/.github/scripts/node_modules/brace-expansion/README.md new file mode 100644 index 000000000..e55c583dd --- /dev/null +++ b/templates/consumer-repo/.github/scripts/node_modules/brace-expansion/README.md @@ -0,0 +1,135 @@ +# brace-expansion + +[Brace expansion](https://www.gnu.org/software/bash/manual/html_node/Brace-Expansion.html), +as known from sh/bash, in JavaScript. + +[![build status](https://secure.travis-ci.org/juliangruber/brace-expansion.svg)](http://travis-ci.org/juliangruber/brace-expansion) +[![downloads](https://img.shields.io/npm/dm/brace-expansion.svg)](https://www.npmjs.org/package/brace-expansion) +[![Greenkeeper badge](https://badges.greenkeeper.io/juliangruber/brace-expansion.svg)](https://greenkeeper.io/) + +[![testling badge](https://ci.testling.com/juliangruber/brace-expansion.png)](https://ci.testling.com/juliangruber/brace-expansion) + +## Example + +```js +var expand = require('brace-expansion'); + +expand('file-{a,b,c}.jpg') +// => ['file-a.jpg', 'file-b.jpg', 'file-c.jpg'] + +expand('-v{,,}') +// => ['-v', '-v', '-v'] + +expand('file{0..2}.jpg') +// => ['file0.jpg', 'file1.jpg', 'file2.jpg'] + +expand('file-{a..c}.jpg') +// => ['file-a.jpg', 'file-b.jpg', 'file-c.jpg'] + +expand('file{2..0}.jpg') +// => ['file2.jpg', 'file1.jpg', 'file0.jpg'] + +expand('file{0..4..2}.jpg') +// => ['file0.jpg', 'file2.jpg', 'file4.jpg'] + +expand('file-{a..e..2}.jpg') +// => ['file-a.jpg', 'file-c.jpg', 'file-e.jpg'] + +expand('file{00..10..5}.jpg') +// => ['file00.jpg', 'file05.jpg', 'file10.jpg'] + +expand('{{A..C},{a..c}}') +// => ['A', 'B', 'C', 'a', 'b', 'c'] + +expand('ppp{,config,oe{,conf}}') +// => ['ppp', 'pppconfig', 'pppoe', 'pppoeconf'] +``` + +## API + +```js +var expand = require('brace-expansion'); +``` + +### var expanded = expand(str) + +Return an array of all possible and valid expansions of `str`. If none are +found, `[str]` is returned. + +Valid expansions are: + +```js +/^(.*,)+(.+)?$/ +// {a,b,...} +``` + +A comma separated list of options, like `{a,b}` or `{a,{b,c}}` or `{,a,}`. + +```js +/^-?\d+\.\.-?\d+(\.\.-?\d+)?$/ +// {x..y[..incr]} +``` + +A numeric sequence from `x` to `y` inclusive, with optional increment. +If `x` or `y` start with a leading `0`, all the numbers will be padded +to have equal length. Negative numbers and backwards iteration work too. + +```js +/^-?\d+\.\.-?\d+(\.\.-?\d+)?$/ +// {x..y[..incr]} +``` + +An alphabetic sequence from `x` to `y` inclusive, with optional increment. +`x` and `y` must be exactly one character, and if given, `incr` must be a +number. + +For compatibility reasons, the string `${` is not eligible for brace expansion. + +## Installation + +With [npm](https://npmjs.org) do: + +```bash +npm install brace-expansion +``` + +## Contributors + +- [Julian Gruber](https://github.com/juliangruber) +- [Isaac Z. Schlueter](https://github.com/isaacs) + +## Sponsors + +This module is proudly supported by my [Sponsors](https://github.com/juliangruber/sponsors)! + +Do you want to support modules like this to improve their quality, stability and weigh in on new features? Then please consider donating to my [Patreon](https://www.patreon.com/juliangruber). Not sure how much of my modules you're using? Try [feross/thanks](https://github.com/feross/thanks)! + +## Security contact information + +To report a security vulnerability, please use the +[Tidelift security contact](https://tidelift.com/security). +Tidelift will coordinate the fix and disclosure. + +## License + +(MIT) + +Copyright (c) 2013 Julian Gruber <julian@juliangruber.com> + +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. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/templates/consumer-repo/.github/scripts/node_modules/brace-expansion/index.js b/templates/consumer-repo/.github/scripts/node_modules/brace-expansion/index.js new file mode 100644 index 000000000..a27f81ce0 --- /dev/null +++ b/templates/consumer-repo/.github/scripts/node_modules/brace-expansion/index.js @@ -0,0 +1,203 @@ +var balanced = require('balanced-match'); + +module.exports = expandTop; + +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'; + +function numeric(str) { + return parseInt(str, 10) == str + ? parseInt(str, 10) + : str.charCodeAt(0); +} + +function escapeBraces(str) { + return str.split('\\\\').join(escSlash) + .split('\\{').join(escOpen) + .split('\\}').join(escClose) + .split('\\,').join(escComma) + .split('\\.').join(escPeriod); +} + +function unescapeBraces(str) { + 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} +function parseCommaParts(str) { + if (!str) + return ['']; + + var parts = []; + 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; +} + +function expandTop(str) { + 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); +} + +function embrace(str) { + return '{' + str + '}'; +} +function isPadded(el) { + return /^-?0\d/.test(el); +} + +function lte(i, y) { + return i <= y; +} +function gte(i, y) { + return i >= y; +} + +function expand(str, isTop) { + var expansions = []; + + 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; + 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) { + 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; + + 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; +} + diff --git a/templates/consumer-repo/.github/scripts/node_modules/brace-expansion/package.json b/templates/consumer-repo/.github/scripts/node_modules/brace-expansion/package.json new file mode 100644 index 000000000..c7eee3451 --- /dev/null +++ b/templates/consumer-repo/.github/scripts/node_modules/brace-expansion/package.json @@ -0,0 +1,49 @@ +{ + "name": "brace-expansion", + "description": "Brace expansion as known from sh/bash", + "version": "2.0.2", + "repository": { + "type": "git", + "url": "git://github.com/juliangruber/brace-expansion.git" + }, + "homepage": "https://github.com/juliangruber/brace-expansion", + "main": "index.js", + "scripts": { + "test": "tape test/*.js", + "gentest": "bash test/generate.sh", + "bench": "matcha test/perf/bench.js" + }, + "dependencies": { + "balanced-match": "^1.0.0" + }, + "devDependencies": { + "@c4312/matcha": "^1.3.1", + "tape": "^4.6.0" + }, + "keywords": [], + "author": { + "name": "Julian Gruber", + "email": "mail@juliangruber.com", + "url": "http://juliangruber.com" + }, + "license": "MIT", + "testling": { + "files": "test/*.js", + "browsers": [ + "ie/8..latest", + "firefox/20..latest", + "firefox/nightly", + "chrome/25..latest", + "chrome/canary", + "opera/12..latest", + "opera/next", + "safari/5.1..latest", + "ipad/6.0..latest", + "iphone/6.0..latest", + "android-browser/4.2..latest" + ] + }, + "publishConfig": { + "tag": "2.x" + } +} diff --git a/templates/consumer-repo/.github/scripts/pr-context-graphql.js b/templates/consumer-repo/.github/scripts/pr-context-graphql.js index 6eb3ffa1e..fafcc2d4c 100644 --- a/templates/consumer-repo/.github/scripts/pr-context-graphql.js +++ b/templates/consumer-repo/.github/scripts/pr-context-graphql.js @@ -1,7 +1,7 @@ 'use strict'; const { ensureRateLimitWrapped } = require('./github-rate-limited-wrapper.js'); -const { minimatch } = require('./minimatch-lite.js'); +const { minimatch } = require('minimatch'); /** * GraphQL-based PR Context Fetcher