Use Prettier for JS files (#3913)
Co-authored-by: Hadrien Croubois <hadrien.croubois@gmail.com>
This commit is contained in:
@ -7,7 +7,7 @@ const { argv } = require('yargs')
|
||||
.options({
|
||||
style: {
|
||||
type: 'string',
|
||||
choices: [ 'shell', 'markdown' ],
|
||||
choices: ['shell', 'markdown'],
|
||||
default: 'shell',
|
||||
},
|
||||
});
|
||||
@ -16,52 +16,55 @@ const { argv } = require('yargs')
|
||||
const BASE_TX_COST = 21000;
|
||||
|
||||
// Utilities
|
||||
function sum (...args) {
|
||||
function sum(...args) {
|
||||
return args.reduce((a, b) => a + b, 0);
|
||||
}
|
||||
|
||||
function average (...args) {
|
||||
function average(...args) {
|
||||
return sum(...args) / args.length;
|
||||
}
|
||||
|
||||
function variation (current, previous, offset = 0) {
|
||||
function variation(current, previous, offset = 0) {
|
||||
return {
|
||||
value: current,
|
||||
delta: current - previous,
|
||||
prcnt: 100 * (current - previous) / (previous - offset),
|
||||
prcnt: (100 * (current - previous)) / (previous - offset),
|
||||
};
|
||||
}
|
||||
|
||||
// Report class
|
||||
class Report {
|
||||
// Read report file
|
||||
static load (filepath) {
|
||||
static load(filepath) {
|
||||
return JSON.parse(fs.readFileSync(filepath, 'utf8'));
|
||||
}
|
||||
|
||||
// Compare two reports
|
||||
static compare (update, ref, opts = { hideEqual: true }) {
|
||||
static compare(update, ref, opts = { hideEqual: true }) {
|
||||
if (JSON.stringify(update.config.metadata) !== JSON.stringify(ref.config.metadata)) {
|
||||
throw new Error('Reports produced with non matching metadata');
|
||||
}
|
||||
|
||||
const deployments = update.info.deployments
|
||||
.map(contract => Object.assign(
|
||||
contract,
|
||||
{ previousVersion: ref.info.deployments.find(({ name }) => name === contract.name) },
|
||||
))
|
||||
.map(contract =>
|
||||
Object.assign(contract, { previousVersion: ref.info.deployments.find(({ name }) => name === contract.name) }),
|
||||
)
|
||||
.filter(contract => contract.gasData?.length && contract.previousVersion?.gasData?.length)
|
||||
.flatMap(contract => [{
|
||||
contract: contract.name,
|
||||
method: '[bytecode length]',
|
||||
avg: variation(contract.bytecode.length / 2 - 1, contract.previousVersion.bytecode.length / 2 - 1),
|
||||
}, {
|
||||
contract: contract.name,
|
||||
method: '[construction cost]',
|
||||
avg: variation(
|
||||
...[contract.gasData, contract.previousVersion.gasData].map(x => Math.round(average(...x))),
|
||||
BASE_TX_COST),
|
||||
}])
|
||||
.flatMap(contract => [
|
||||
{
|
||||
contract: contract.name,
|
||||
method: '[bytecode length]',
|
||||
avg: variation(contract.bytecode.length / 2 - 1, contract.previousVersion.bytecode.length / 2 - 1),
|
||||
},
|
||||
{
|
||||
contract: contract.name,
|
||||
method: '[construction cost]',
|
||||
avg: variation(
|
||||
...[contract.gasData, contract.previousVersion.gasData].map(x => Math.round(average(...x))),
|
||||
BASE_TX_COST,
|
||||
),
|
||||
},
|
||||
])
|
||||
.sort((a, b) => `${a.contract}:${a.method}`.localeCompare(`${b.contract}:${b.method}`));
|
||||
|
||||
const methods = Object.keys(update.info.methods)
|
||||
@ -77,21 +80,22 @@ class Report {
|
||||
}))
|
||||
.sort((a, b) => `${a.contract}:${a.method}`.localeCompare(`${b.contract}:${b.method}`));
|
||||
|
||||
return [].concat(deployments, methods)
|
||||
return []
|
||||
.concat(deployments, methods)
|
||||
.filter(row => !opts.hideEqual || row.min?.delta || row.max?.delta || row.avg?.delta);
|
||||
}
|
||||
}
|
||||
|
||||
// Display
|
||||
function center (text, length) {
|
||||
function center(text, length) {
|
||||
return text.padStart((text.length + length) / 2).padEnd(length);
|
||||
}
|
||||
|
||||
function plusSign (num) {
|
||||
function plusSign(num) {
|
||||
return num > 0 ? '+' : '';
|
||||
}
|
||||
|
||||
function formatCellShell (cell) {
|
||||
function formatCellShell(cell) {
|
||||
const format = chalk[cell?.delta > 0 ? 'red' : cell?.delta < 0 ? 'green' : 'reset'];
|
||||
return [
|
||||
format((!isFinite(cell?.value) ? '-' : cell.value.toString()).padStart(8)),
|
||||
@ -100,7 +104,7 @@ function formatCellShell (cell) {
|
||||
];
|
||||
}
|
||||
|
||||
function formatCmpShell (rows) {
|
||||
function formatCmpShell(rows) {
|
||||
const contractLength = Math.max(8, ...rows.map(({ contract }) => contract.length));
|
||||
const methodLength = Math.max(7, ...rows.map(({ method }) => method.length));
|
||||
|
||||
@ -113,54 +117,60 @@ function formatCmpShell (rows) {
|
||||
{ txt: 'Avg', length: 30 },
|
||||
{ txt: '', length: 0 },
|
||||
];
|
||||
const HEADER = COLS.map(entry => chalk.bold(center(entry.txt, entry.length || 0))).join(' | ').trim();
|
||||
const SEPARATOR = COLS.map(({ length }) => length > 0 ? '-'.repeat(length + 2) : '').join('|').trim();
|
||||
const HEADER = COLS.map(entry => chalk.bold(center(entry.txt, entry.length || 0)))
|
||||
.join(' | ')
|
||||
.trim();
|
||||
const SEPARATOR = COLS.map(({ length }) => (length > 0 ? '-'.repeat(length + 2) : ''))
|
||||
.join('|')
|
||||
.trim();
|
||||
|
||||
return [
|
||||
'',
|
||||
HEADER,
|
||||
...rows.map(entry => [
|
||||
'',
|
||||
chalk.grey(entry.contract.padEnd(contractLength)),
|
||||
entry.method.padEnd(methodLength),
|
||||
...formatCellShell(entry.min),
|
||||
...formatCellShell(entry.max),
|
||||
...formatCellShell(entry.avg),
|
||||
'',
|
||||
].join(' | ').trim()),
|
||||
...rows.map(entry =>
|
||||
[
|
||||
'',
|
||||
chalk.grey(entry.contract.padEnd(contractLength)),
|
||||
entry.method.padEnd(methodLength),
|
||||
...formatCellShell(entry.min),
|
||||
...formatCellShell(entry.max),
|
||||
...formatCellShell(entry.avg),
|
||||
'',
|
||||
]
|
||||
.join(' | ')
|
||||
.trim(),
|
||||
),
|
||||
'',
|
||||
].join(`\n${SEPARATOR}\n`).trim();
|
||||
]
|
||||
.join(`\n${SEPARATOR}\n`)
|
||||
.trim();
|
||||
}
|
||||
|
||||
function alignPattern (align) {
|
||||
function alignPattern(align) {
|
||||
switch (align) {
|
||||
case 'left':
|
||||
case undefined:
|
||||
return ':-';
|
||||
case 'right':
|
||||
return '-:';
|
||||
case 'center':
|
||||
return ':-:';
|
||||
case 'left':
|
||||
case undefined:
|
||||
return ':-';
|
||||
case 'right':
|
||||
return '-:';
|
||||
case 'center':
|
||||
return ':-:';
|
||||
}
|
||||
}
|
||||
|
||||
function trend (value) {
|
||||
return value > 0
|
||||
? ':x:'
|
||||
: value < 0
|
||||
? ':heavy_check_mark:'
|
||||
: ':heavy_minus_sign:';
|
||||
function trend(value) {
|
||||
return value > 0 ? ':x:' : value < 0 ? ':heavy_check_mark:' : ':heavy_minus_sign:';
|
||||
}
|
||||
|
||||
function formatCellMarkdown (cell) {
|
||||
function formatCellMarkdown(cell) {
|
||||
return [
|
||||
(!isFinite(cell?.value) ? '-' : cell.value.toString()),
|
||||
(!isFinite(cell?.delta) ? '-' : plusSign(cell.delta) + cell.delta.toString()),
|
||||
(!isFinite(cell?.prcnt) ? '-' : plusSign(cell.prcnt) + cell.prcnt.toFixed(2) + '%' + trend(cell.delta)),
|
||||
!isFinite(cell?.value) ? '-' : cell.value.toString(),
|
||||
!isFinite(cell?.delta) ? '-' : plusSign(cell.delta) + cell.delta.toString(),
|
||||
!isFinite(cell?.prcnt) ? '-' : plusSign(cell.prcnt) + cell.prcnt.toFixed(2) + '%' + trend(cell.delta),
|
||||
];
|
||||
}
|
||||
|
||||
function formatCmpMarkdown (rows) {
|
||||
function formatCmpMarkdown(rows) {
|
||||
const COLS = [
|
||||
{ txt: '' },
|
||||
{ txt: 'Contract', align: 'left' },
|
||||
@ -176,36 +186,48 @@ function formatCmpMarkdown (rows) {
|
||||
{ txt: '%', align: 'right' },
|
||||
{ txt: '' },
|
||||
];
|
||||
const HEADER = COLS.map(entry => entry.txt).join(' | ').trim();
|
||||
const SEPARATOR = COLS.map(entry => entry.txt ? alignPattern(entry.align) : '').join('|').trim();
|
||||
const HEADER = COLS.map(entry => entry.txt)
|
||||
.join(' | ')
|
||||
.trim();
|
||||
const SEPARATOR = COLS.map(entry => (entry.txt ? alignPattern(entry.align) : ''))
|
||||
.join('|')
|
||||
.trim();
|
||||
|
||||
return [
|
||||
'# Changes to gas costs',
|
||||
'',
|
||||
HEADER,
|
||||
SEPARATOR,
|
||||
rows.map(entry => [
|
||||
'',
|
||||
entry.contract,
|
||||
entry.method,
|
||||
...formatCellMarkdown(entry.min),
|
||||
...formatCellMarkdown(entry.max),
|
||||
...formatCellMarkdown(entry.avg),
|
||||
'',
|
||||
].join(' | ').trim()).join('\n'),
|
||||
rows
|
||||
.map(entry =>
|
||||
[
|
||||
'',
|
||||
entry.contract,
|
||||
entry.method,
|
||||
...formatCellMarkdown(entry.min),
|
||||
...formatCellMarkdown(entry.max),
|
||||
...formatCellMarkdown(entry.avg),
|
||||
'',
|
||||
]
|
||||
.join(' | ')
|
||||
.trim(),
|
||||
)
|
||||
.join('\n'),
|
||||
'',
|
||||
].join('\n').trim();
|
||||
]
|
||||
.join('\n')
|
||||
.trim();
|
||||
}
|
||||
|
||||
// MAIN
|
||||
const report = Report.compare(Report.load(argv._[0]), Report.load(argv._[1]));
|
||||
|
||||
switch (argv.style) {
|
||||
case 'markdown':
|
||||
console.log(formatCmpMarkdown(report));
|
||||
break;
|
||||
case 'shell':
|
||||
default:
|
||||
console.log(formatCmpShell(report));
|
||||
break;
|
||||
case 'markdown':
|
||||
console.log(formatCmpMarkdown(report));
|
||||
break;
|
||||
case 'shell':
|
||||
default:
|
||||
console.log(formatCmpShell(report));
|
||||
break;
|
||||
}
|
||||
|
||||
@ -21,28 +21,32 @@ for (const artifact of artifacts) {
|
||||
names[contractDef.id] = contractDef.name;
|
||||
linearized.push(contractDef.linearizedBaseContracts);
|
||||
|
||||
contractDef.linearizedBaseContracts.forEach((c1, i, contracts) => contracts.slice(i + 1).forEach(c2 => {
|
||||
graph.setEdge(c1, c2);
|
||||
}));
|
||||
contractDef.linearizedBaseContracts.forEach((c1, i, contracts) =>
|
||||
contracts.slice(i + 1).forEach(c2 => {
|
||||
graph.setEdge(c1, c2);
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// graphlib.alg.findCycles will not find minimal cycles.
|
||||
/// We are only interested int cycles of lengths 2 (needs proof)
|
||||
graph.nodes().forEach((x, i, nodes) => nodes
|
||||
.slice(i + 1)
|
||||
.filter(y => graph.hasEdge(x, y) && graph.hasEdge(y, x))
|
||||
.forEach(y => {
|
||||
console.log(`Conflict between ${names[x]} and ${names[y]} detected in the following dependency chains:`);
|
||||
linearized
|
||||
.filter(chain => chain.includes(parseInt(x)) && chain.includes(parseInt(y)))
|
||||
.forEach(chain => {
|
||||
const comp = chain.indexOf(parseInt(x)) < chain.indexOf(parseInt(y)) ? '>' : '<';
|
||||
console.log(`- ${names[x]} ${comp} ${names[y]} in ${names[chain.find(Boolean)]}`);
|
||||
// console.log(`- ${names[x]} ${comp} ${names[y]}: ${chain.reverse().map(id => names[id]).join(', ')}`);
|
||||
});
|
||||
process.exitCode = 1;
|
||||
}));
|
||||
graph.nodes().forEach((x, i, nodes) =>
|
||||
nodes
|
||||
.slice(i + 1)
|
||||
.filter(y => graph.hasEdge(x, y) && graph.hasEdge(y, x))
|
||||
.forEach(y => {
|
||||
console.log(`Conflict between ${names[x]} and ${names[y]} detected in the following dependency chains:`);
|
||||
linearized
|
||||
.filter(chain => chain.includes(parseInt(x)) && chain.includes(parseInt(y)))
|
||||
.forEach(chain => {
|
||||
const comp = chain.indexOf(parseInt(x)) < chain.indexOf(parseInt(y)) ? '>' : '<';
|
||||
console.log(`- ${names[x]} ${comp} ${names[y]} in ${names[chain.find(Boolean)]}`);
|
||||
// console.log(`- ${names[x]} ${comp} ${names[y]}: ${chain.reverse().map(id => names[id]).join(', ')}`);
|
||||
});
|
||||
process.exitCode = 1;
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
if (!process.exitCode) {
|
||||
|
||||
@ -10,18 +10,18 @@ const files = glob.sync(baseDir + '/**/*.adoc').map(f => path.relative(baseDir,
|
||||
|
||||
console.log('.API');
|
||||
|
||||
function getPageTitle (directory) {
|
||||
function getPageTitle(directory) {
|
||||
switch (directory) {
|
||||
case 'metatx':
|
||||
return 'Meta Transactions';
|
||||
case 'common':
|
||||
return 'Common (Tokens)';
|
||||
default:
|
||||
return startCase(directory);
|
||||
case 'metatx':
|
||||
return 'Meta Transactions';
|
||||
case 'common':
|
||||
return 'Common (Tokens)';
|
||||
default:
|
||||
return startCase(directory);
|
||||
}
|
||||
}
|
||||
|
||||
const links = files.map((file) => {
|
||||
const links = files.map(file => {
|
||||
const doc = file.replace(baseDir, '');
|
||||
const title = path.parse(file).name;
|
||||
|
||||
|
||||
@ -1,14 +1,14 @@
|
||||
function formatLines (...lines) {
|
||||
function formatLines(...lines) {
|
||||
return [...indentEach(0, lines)].join('\n') + '\n';
|
||||
}
|
||||
|
||||
function *indentEach (indent, lines) {
|
||||
function* indentEach(indent, lines) {
|
||||
for (const line of lines) {
|
||||
if (Array.isArray(line)) {
|
||||
yield * indentEach(indent + 1, line);
|
||||
yield* indentEach(indent + 1, line);
|
||||
} else {
|
||||
const padding = ' '.repeat(indent);
|
||||
yield * line.split('\n').map(subline => subline === '' ? '' : padding + subline);
|
||||
yield* line.split('\n').map(subline => (subline === '' ? '' : padding + subline));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -5,17 +5,15 @@ const fs = require('fs');
|
||||
const path = require('path');
|
||||
const format = require('./format-lines');
|
||||
|
||||
function getVersion (path) {
|
||||
function getVersion(path) {
|
||||
try {
|
||||
return fs
|
||||
.readFileSync(path, 'utf8')
|
||||
.match(/\/\/ OpenZeppelin Contracts \(last updated v[^)]+\)/)[0];
|
||||
return fs.readFileSync(path, 'utf8').match(/\/\/ OpenZeppelin Contracts \(last updated v[^)]+\)/)[0];
|
||||
} catch (err) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
for (const [ file, template ] of Object.entries({
|
||||
for (const [file, template] of Object.entries({
|
||||
'utils/math/SafeCast.sol': './templates/SafeCast.js',
|
||||
'utils/structs/EnumerableSet.sol': './templates/EnumerableSet.js',
|
||||
'utils/structs/EnumerableMap.sol': './templates/EnumerableMap.js',
|
||||
@ -27,7 +25,7 @@ for (const [ file, template ] of Object.entries({
|
||||
const version = getVersion(output);
|
||||
const content = format(
|
||||
'// SPDX-License-Identifier: MIT',
|
||||
...(version ? [ version + ` (${file})` ] : []),
|
||||
...(version ? [version + ` (${file})`] : []),
|
||||
`// This file was procedurally generated from ${input}.`,
|
||||
'',
|
||||
require(template),
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
const format = require('../format-lines');
|
||||
|
||||
const VALUE_SIZES = [ 224, 160 ];
|
||||
const VALUE_SIZES = [224, 160];
|
||||
|
||||
const header = `\
|
||||
pragma solidity ^0.8.0;
|
||||
@ -264,7 +264,7 @@ function _unsafeAccess(${opts.checkpointTypeName}[] storage self, uint256 pos)
|
||||
/* eslint-enable max-len */
|
||||
|
||||
// OPTIONS
|
||||
const defaultOpts = (size) => ({
|
||||
const defaultOpts = size => ({
|
||||
historyTypeName: `Trace${size}`,
|
||||
checkpointTypeName: `Checkpoint${size}`,
|
||||
checkpointFieldName: '_checkpoints',
|
||||
@ -293,11 +293,7 @@ module.exports = format(
|
||||
legacyOperations(LEGACY_OPTS),
|
||||
common(LEGACY_OPTS),
|
||||
// New flavors
|
||||
...OPTS.flatMap(opts => [
|
||||
types(opts),
|
||||
operations(opts),
|
||||
common(opts),
|
||||
]),
|
||||
...OPTS.flatMap(opts => [types(opts), operations(opts), common(opts)]),
|
||||
],
|
||||
'}',
|
||||
);
|
||||
|
||||
@ -245,9 +245,6 @@ function values(${name} storage set) internal view returns (${type}[] memory) {
|
||||
module.exports = format(
|
||||
header.trimEnd(),
|
||||
'library EnumerableSet {',
|
||||
[
|
||||
defaultSet(),
|
||||
TYPES.map(details => customSet(details).trimEnd()).join('\n\n'),
|
||||
],
|
||||
[defaultSet(), TYPES.map(details => customSet(details).trimEnd()).join('\n\n')],
|
||||
'}',
|
||||
);
|
||||
|
||||
@ -8,55 +8,55 @@ const LENGTHS = range(8, 256, 8).reverse(); // 248 → 8 (in steps of 8)
|
||||
// This is used in the docs for each function.
|
||||
const version = (selector, length) => {
|
||||
switch (selector) {
|
||||
case 'toUint(uint)': {
|
||||
switch (length) {
|
||||
case 8:
|
||||
case 16:
|
||||
case 32:
|
||||
case 64:
|
||||
case 128:
|
||||
return '2.5';
|
||||
case 96:
|
||||
case 224:
|
||||
return '4.2';
|
||||
default:
|
||||
assert(LENGTHS.includes(length));
|
||||
return '4.7';
|
||||
case 'toUint(uint)': {
|
||||
switch (length) {
|
||||
case 8:
|
||||
case 16:
|
||||
case 32:
|
||||
case 64:
|
||||
case 128:
|
||||
return '2.5';
|
||||
case 96:
|
||||
case 224:
|
||||
return '4.2';
|
||||
default:
|
||||
assert(LENGTHS.includes(length));
|
||||
return '4.7';
|
||||
}
|
||||
}
|
||||
}
|
||||
case 'toInt(int)': {
|
||||
switch (length) {
|
||||
case 8:
|
||||
case 16:
|
||||
case 32:
|
||||
case 64:
|
||||
case 128:
|
||||
return '3.1';
|
||||
default:
|
||||
assert(LENGTHS.includes(length));
|
||||
return '4.7';
|
||||
case 'toInt(int)': {
|
||||
switch (length) {
|
||||
case 8:
|
||||
case 16:
|
||||
case 32:
|
||||
case 64:
|
||||
case 128:
|
||||
return '3.1';
|
||||
default:
|
||||
assert(LENGTHS.includes(length));
|
||||
return '4.7';
|
||||
}
|
||||
}
|
||||
case 'toUint(int)': {
|
||||
switch (length) {
|
||||
case 256:
|
||||
return '3.0';
|
||||
default:
|
||||
assert(false);
|
||||
return;
|
||||
}
|
||||
}
|
||||
case 'toInt(uint)': {
|
||||
switch (length) {
|
||||
case 256:
|
||||
return '3.0';
|
||||
default:
|
||||
assert(false);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
case 'toUint(int)': {
|
||||
switch (length) {
|
||||
case 256:
|
||||
return '3.0';
|
||||
default:
|
||||
assert(false);
|
||||
return;
|
||||
}
|
||||
}
|
||||
case 'toInt(uint)': {
|
||||
switch (length) {
|
||||
case 256:
|
||||
return '3.0';
|
||||
default:
|
||||
assert(false);
|
||||
return;
|
||||
}
|
||||
}
|
||||
default:
|
||||
assert(false);
|
||||
}
|
||||
};
|
||||
|
||||
@ -158,11 +158,6 @@ function toUint${length}(int${length} value) internal pure returns (uint${length
|
||||
module.exports = format(
|
||||
header.trimEnd(),
|
||||
'library SafeCast {',
|
||||
[
|
||||
...LENGTHS.map(toUintDownCast),
|
||||
toUint(256),
|
||||
...LENGTHS.map(toIntDownCast),
|
||||
toInt(256),
|
||||
],
|
||||
[...LENGTHS.map(toUintDownCast), toUint(256), ...LENGTHS.map(toIntDownCast), toInt(256)],
|
||||
'}',
|
||||
);
|
||||
|
||||
@ -1,26 +1,26 @@
|
||||
function toBytes32 (type, value) {
|
||||
function toBytes32(type, value) {
|
||||
switch (type) {
|
||||
case 'bytes32':
|
||||
return value;
|
||||
case 'uint256':
|
||||
return `bytes32(${value})`;
|
||||
case 'address':
|
||||
return `bytes32(uint256(uint160(${value})))`;
|
||||
default:
|
||||
throw new Error(`Conversion from ${type} to bytes32 not supported`);
|
||||
case 'bytes32':
|
||||
return value;
|
||||
case 'uint256':
|
||||
return `bytes32(${value})`;
|
||||
case 'address':
|
||||
return `bytes32(uint256(uint160(${value})))`;
|
||||
default:
|
||||
throw new Error(`Conversion from ${type} to bytes32 not supported`);
|
||||
}
|
||||
}
|
||||
|
||||
function fromBytes32 (type, value) {
|
||||
function fromBytes32(type, value) {
|
||||
switch (type) {
|
||||
case 'bytes32':
|
||||
return value;
|
||||
case 'uint256':
|
||||
return `uint256(${value})`;
|
||||
case 'address':
|
||||
return `address(uint160(uint256(${value})))`;
|
||||
default:
|
||||
throw new Error(`Conversion from bytes32 to ${type} not supported`);
|
||||
case 'bytes32':
|
||||
return value;
|
||||
case 'uint256':
|
||||
return `uint256(${value})`;
|
||||
case 'address':
|
||||
return `address(uint160(uint256(${value})))`;
|
||||
default:
|
||||
throw new Error(`Conversion from bytes32 to ${type} not supported`);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1,18 +1,27 @@
|
||||
function chunk (array, size = 1) {
|
||||
function chunk(array, size = 1) {
|
||||
return Array.range(Math.ceil(array.length / size)).map(i => array.slice(i * size, i * size + size));
|
||||
}
|
||||
|
||||
function range (start, stop = undefined, step = 1) {
|
||||
if (!stop) { stop = start; start = 0; }
|
||||
return start < stop ? Array(Math.ceil((stop - start) / step)).fill().map((_, i) => start + i * step) : [];
|
||||
function range(start, stop = undefined, step = 1) {
|
||||
if (!stop) {
|
||||
stop = start;
|
||||
start = 0;
|
||||
}
|
||||
return start < stop
|
||||
? Array(Math.ceil((stop - start) / step))
|
||||
.fill()
|
||||
.map((_, i) => start + i * step)
|
||||
: [];
|
||||
}
|
||||
|
||||
function unique (array, op = x => x) {
|
||||
function unique(array, op = x => x) {
|
||||
return array.filter((obj, i) => array.findIndex(entry => op(obj) === op(entry)) === i);
|
||||
}
|
||||
|
||||
function zip (...args) {
|
||||
return Array(Math.max(...args.map(arg => arg.length))).fill(null).map((_, i) => args.map(arg => arg[i]));
|
||||
function zip(...args) {
|
||||
return Array(Math.max(...args.map(arg => arg.length)))
|
||||
.fill(null)
|
||||
.map((_, i) => args.map(arg => arg[i]));
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
|
||||
@ -92,7 +92,7 @@ const pathUpdates = {
|
||||
'token/ERC20/extensions/draft-IERC20Permit.sol': 'token/ERC20/extensions/IERC20Permit.sol',
|
||||
};
|
||||
|
||||
async function main (paths = [ 'contracts' ]) {
|
||||
async function main(paths = ['contracts']) {
|
||||
const files = await listFilesRecursively(paths, /\.sol$/);
|
||||
|
||||
const updatedFiles = [];
|
||||
@ -112,7 +112,7 @@ async function main (paths = [ 'contracts' ]) {
|
||||
}
|
||||
}
|
||||
|
||||
async function listFilesRecursively (paths, filter) {
|
||||
async function listFilesRecursively(paths, filter) {
|
||||
const queue = paths;
|
||||
const files = [];
|
||||
|
||||
@ -133,7 +133,7 @@ async function listFilesRecursively (paths, filter) {
|
||||
return files;
|
||||
}
|
||||
|
||||
async function updateFile (file, update) {
|
||||
async function updateFile(file, update) {
|
||||
const content = await fs.readFile(file, 'utf8');
|
||||
const updatedContent = update(content);
|
||||
if (updatedContent !== content) {
|
||||
@ -144,8 +144,8 @@ async function updateFile (file, update) {
|
||||
}
|
||||
}
|
||||
|
||||
function updateImportPaths (source) {
|
||||
for (const [ oldPath, newPath ] of Object.entries(pathUpdates)) {
|
||||
function updateImportPaths(source) {
|
||||
for (const [oldPath, newPath] of Object.entries(pathUpdates)) {
|
||||
source = source.replace(
|
||||
path.join('@openzeppelin/contracts', oldPath),
|
||||
path.join('@openzeppelin/contracts', newPath),
|
||||
@ -159,7 +159,7 @@ function updateImportPaths (source) {
|
||||
return source;
|
||||
}
|
||||
|
||||
function getUpgradeablePath (file) {
|
||||
function getUpgradeablePath(file) {
|
||||
const { dir, name, ext } = path.parse(file);
|
||||
const upgradeableName = name + 'Upgradeable';
|
||||
return path.format({ dir, ext, name: upgradeableName });
|
||||
|
||||
@ -8,7 +8,7 @@ const cp = require('child_process');
|
||||
|
||||
setVersion('contracts/package.json');
|
||||
|
||||
function setVersion (file) {
|
||||
function setVersion(file) {
|
||||
const json = JSON.parse(fs.readFileSync(file));
|
||||
json.version = process.env.npm_package_version;
|
||||
fs.writeFileSync(file, JSON.stringify(json, null, 2) + '\n');
|
||||
|
||||
@ -25,9 +25,8 @@ if (!header.test(changelog)) {
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const newHeader = pkg.version.indexOf(suffix) === -1
|
||||
? `## ${version} (${new Date().toISOString().split('T')[0]})`
|
||||
: `## ${version}`;
|
||||
const newHeader =
|
||||
pkg.version.indexOf(suffix) === -1 ? `## ${version} (${new Date().toISOString().split('T')[0]})` : `## ${version}`;
|
||||
|
||||
fs.writeFileSync('CHANGELOG.md', changelog.replace(header, newHeader));
|
||||
|
||||
|
||||
@ -13,7 +13,7 @@ if (gitStatus.length > 0) {
|
||||
const { version } = require('../../package.json');
|
||||
|
||||
// Get latest tag according to semver.
|
||||
const [ tag ] = run('git', 'tag')
|
||||
const [tag] = run('git', 'tag')
|
||||
.split(/\r?\n/)
|
||||
.filter(semver.coerce) // check version can be processed
|
||||
.filter(v => semver.lt(semver.coerce(v), version)) // only consider older tags, ignore current prereleases
|
||||
|
||||
@ -6,7 +6,7 @@ const fs = require('fs');
|
||||
const path = require('path');
|
||||
const match = require('micromatch');
|
||||
|
||||
function readJSON (path) {
|
||||
function readJSON(path) {
|
||||
return JSON.parse(fs.readFileSync(path));
|
||||
}
|
||||
|
||||
@ -15,11 +15,11 @@ const pkgFiles = readJSON('package.json').files;
|
||||
// Get only negated patterns.
|
||||
const ignorePatterns = pkgFiles
|
||||
.filter(pat => pat.startsWith('!'))
|
||||
// Remove the negation part. Makes micromatch usage more intuitive.
|
||||
// Remove the negation part. Makes micromatch usage more intuitive.
|
||||
.map(pat => pat.slice(1));
|
||||
|
||||
const ignorePatternsSubtrees = ignorePatterns
|
||||
// Add **/* to ignore all files contained in the directories.
|
||||
// Add **/* to ignore all files contained in the directories.
|
||||
.concat(ignorePatterns.map(pat => path.join(pat, '**/*')))
|
||||
.map(p => p.replace(/^\//, ''));
|
||||
|
||||
|
||||
@ -1,7 +1,15 @@
|
||||
const proc = require('child_process');
|
||||
const read = cmd => proc.execSync(cmd, { encoding: 'utf8' }).trim();
|
||||
const run = cmd => { proc.execSync(cmd, { stdio: 'inherit' }); };
|
||||
const tryRead = cmd => { try { return read(cmd); } catch (e) { return undefined; } };
|
||||
const run = cmd => {
|
||||
proc.execSync(cmd, { stdio: 'inherit' });
|
||||
};
|
||||
const tryRead = cmd => {
|
||||
try {
|
||||
return read(cmd);
|
||||
} catch (e) {
|
||||
return undefined;
|
||||
}
|
||||
};
|
||||
|
||||
const releaseBranchRegex = /^release-v(?<version>(?<major>\d+)\.(?<minor>\d+)(?:\.(?<patch>\d+))?)$/;
|
||||
|
||||
@ -33,7 +41,7 @@ if (!matchingDocsBranches) {
|
||||
if (others.length > 0) {
|
||||
console.error(
|
||||
`Found conflicting ${docsBranch} branches.\n` +
|
||||
'Either local branch is outdated or there are multiple matching remote branches.',
|
||||
'Either local branch is outdated or there are multiple matching remote branches.',
|
||||
);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user