checkPlugin: Promisify file system accesses
parent
b50c6d07d4
commit
753d16af8a
|
@ -16,6 +16,7 @@ process.on('unhandledRejection', (err) => { throw err; });
|
||||||
|
|
||||||
const assert = require('assert').strict;
|
const assert = require('assert').strict;
|
||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
|
const fsp = fs.promises;
|
||||||
const childProcess = require('child_process');
|
const childProcess = require('child_process');
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
|
|
||||||
|
@ -38,10 +39,10 @@ const execSync = (cmd, opts = {}) => (childProcess.execSync(cmd, {
|
||||||
...opts,
|
...opts,
|
||||||
}) || '').toString().replace(/\n+$/, '');
|
}) || '').toString().replace(/\n+$/, '');
|
||||||
|
|
||||||
const writePackageJson = (obj) => {
|
const writePackageJson = async (obj) => {
|
||||||
let s = JSON.stringify(obj, null, 2);
|
let s = JSON.stringify(obj, null, 2);
|
||||||
if (s.length && s.slice(s.length - 1) !== '\n') s += '\n';
|
if (s.length && s.slice(s.length - 1) !== '\n') s += '\n';
|
||||||
return fs.writeFileSync(`${pluginPath}/package.json`, s);
|
return await fsp.writeFile(`${pluginPath}/package.json`, s);
|
||||||
};
|
};
|
||||||
|
|
||||||
const checkEntries = (got, want) => {
|
const checkEntries = (got, want) => {
|
||||||
|
@ -61,7 +62,7 @@ const checkEntries = (got, want) => {
|
||||||
return changed;
|
return changed;
|
||||||
};
|
};
|
||||||
|
|
||||||
const updateDeps = (parsedPackageJson, key, wantDeps) => {
|
const updateDeps = async (parsedPackageJson, key, wantDeps) => {
|
||||||
const {[key]: deps = {}} = parsedPackageJson;
|
const {[key]: deps = {}} = parsedPackageJson;
|
||||||
let changed = false;
|
let changed = false;
|
||||||
for (const [pkg, verInfo] of Object.entries(wantDeps)) {
|
for (const [pkg, verInfo] of Object.entries(wantDeps)) {
|
||||||
|
@ -80,7 +81,7 @@ const updateDeps = (parsedPackageJson, key, wantDeps) => {
|
||||||
}
|
}
|
||||||
if (changed) {
|
if (changed) {
|
||||||
parsedPackageJson[key] = deps;
|
parsedPackageJson[key] = deps;
|
||||||
writePackageJson(parsedPackageJson);
|
await writePackageJson(parsedPackageJson);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -107,12 +108,12 @@ const prepareRepo = () => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const checkFile = (srcFn, dstFn) => {
|
const checkFile = async (srcFn, dstFn) => {
|
||||||
const outFn = path.join(pluginPath, dstFn);
|
const outFn = path.join(pluginPath, dstFn);
|
||||||
const wantContents = fs.readFileSync(srcFn, {encoding: 'utf8'});
|
const wantContents = await fsp.readFile(srcFn, {encoding: 'utf8'});
|
||||||
let gotContents = null;
|
let gotContents = null;
|
||||||
try {
|
try {
|
||||||
gotContents = fs.readFileSync(outFn, {encoding: 'utf8'});
|
gotContents = await fsp.readFile(outFn, {encoding: 'utf8'});
|
||||||
} catch (err) { /* treat as if the file doesn't exist */ }
|
} catch (err) { /* treat as if the file doesn't exist */ }
|
||||||
try {
|
try {
|
||||||
assert.equal(gotContents, wantContents);
|
assert.equal(gotContents, wantContents);
|
||||||
|
@ -120,8 +121,8 @@ const checkFile = (srcFn, dstFn) => {
|
||||||
console.warn(`File ${dstFn} is out of date`);
|
console.warn(`File ${dstFn} is out of date`);
|
||||||
console.warn(err.message);
|
console.warn(err.message);
|
||||||
if (autoFix) {
|
if (autoFix) {
|
||||||
fs.mkdirSync(path.dirname(outFn), {recursive: true});
|
await fsp.mkdir(path.dirname(outFn), {recursive: true});
|
||||||
fs.writeFileSync(outFn, wantContents);
|
await fsp.writeFile(outFn, wantContents);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -130,11 +131,8 @@ if (autoPush) {
|
||||||
console.warn('Auto push is enabled, I hope you know what you are doing...');
|
console.warn('Auto push is enabled, I hope you know what you are doing...');
|
||||||
}
|
}
|
||||||
|
|
||||||
fs.readdir(pluginPath, (err, rootFiles) => {
|
(async () => {
|
||||||
// handling error
|
const rootFiles = await fsp.readdir(pluginPath);
|
||||||
if (err) {
|
|
||||||
return console.log(`Unable to scan directory: ${err}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
// some files we need to know the actual file name. Not compulsory but might help in the future.
|
// some files we need to know the actual file name. Not compulsory but might help in the future.
|
||||||
let readMeFileName;
|
let readMeFileName;
|
||||||
|
@ -148,15 +146,16 @@ fs.readdir(pluginPath, (err, rootFiles) => {
|
||||||
if (!files.includes('.git')) throw new Error('No .git folder, aborting');
|
if (!files.includes('.git')) throw new Error('No .git folder, aborting');
|
||||||
prepareRepo();
|
prepareRepo();
|
||||||
|
|
||||||
for (const fn of ['backend-tests.yml', 'frontend-tests.yml', 'npmpublish.yml']) {
|
const workflows = ['backend-tests.yml', 'frontend-tests.yml', 'npmpublish.yml'];
|
||||||
checkFile(`src/bin/plugins/lib/${fn}`, `.github/workflows/${fn}`);
|
await Promise.all(workflows.map(async (fn) => {
|
||||||
}
|
await checkFile(`src/bin/plugins/lib/${fn}`, `.github/workflows/${fn}`);
|
||||||
|
}));
|
||||||
|
|
||||||
if (!files.includes('package.json')) {
|
if (!files.includes('package.json')) {
|
||||||
console.warn('no package.json, please create');
|
console.warn('no package.json, please create');
|
||||||
} else {
|
} else {
|
||||||
const packageJSON =
|
const packageJSON =
|
||||||
fs.readFileSync(`${pluginPath}/package.json`, {encoding: 'utf8', flag: 'r'});
|
await fsp.readFile(`${pluginPath}/package.json`, {encoding: 'utf8', flag: 'r'});
|
||||||
const parsedPackageJSON = JSON.parse(packageJSON);
|
const parsedPackageJSON = JSON.parse(packageJSON);
|
||||||
|
|
||||||
if (!packageJSON.toLowerCase().includes('repository')) {
|
if (!packageJSON.toLowerCase().includes('repository')) {
|
||||||
|
@ -169,7 +168,7 @@ fs.readdir(pluginPath, (err, rootFiles) => {
|
||||||
repository = parsedPackageJSON.repository.url;
|
repository = parsedPackageJSON.repository.url;
|
||||||
}
|
}
|
||||||
|
|
||||||
updateDeps(parsedPackageJSON, 'devDependencies', {
|
await updateDeps(parsedPackageJSON, 'devDependencies', {
|
||||||
'eslint': '^7.28.0',
|
'eslint': '^7.28.0',
|
||||||
'eslint-config-etherpad': '^2.0.0',
|
'eslint-config-etherpad': '^2.0.0',
|
||||||
'eslint-plugin-cypress': '^2.11.3',
|
'eslint-plugin-cypress': '^2.11.3',
|
||||||
|
@ -181,12 +180,12 @@ fs.readdir(pluginPath, (err, rootFiles) => {
|
||||||
'eslint-plugin-you-dont-need-lodash-underscore': '^6.12.0',
|
'eslint-plugin-you-dont-need-lodash-underscore': '^6.12.0',
|
||||||
});
|
});
|
||||||
|
|
||||||
updateDeps(parsedPackageJSON, 'peerDependencies', {
|
await updateDeps(parsedPackageJSON, 'peerDependencies', {
|
||||||
// Some plugins require a newer version of Etherpad so don't overwrite if already set.
|
// Some plugins require a newer version of Etherpad so don't overwrite if already set.
|
||||||
'ep_etherpad-lite': {ver: '>=1.8.6', overwrite: false},
|
'ep_etherpad-lite': {ver: '>=1.8.6', overwrite: false},
|
||||||
});
|
});
|
||||||
|
|
||||||
updateDeps(parsedPackageJSON, 'engines', {
|
await updateDeps(parsedPackageJSON, 'engines', {
|
||||||
node: '>=12.13.0',
|
node: '>=12.13.0',
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -201,13 +200,13 @@ fs.readdir(pluginPath, (err, rootFiles) => {
|
||||||
type: 'individual',
|
type: 'individual',
|
||||||
url: 'https://etherpad.org/',
|
url: 'https://etherpad.org/',
|
||||||
},
|
},
|
||||||
})) writePackageJson(parsedPackageJSON);
|
})) await writePackageJson(parsedPackageJSON);
|
||||||
|
|
||||||
if (parsedPackageJSON.scripts == null) parsedPackageJSON.scripts = {};
|
if (parsedPackageJSON.scripts == null) parsedPackageJSON.scripts = {};
|
||||||
if (checkEntries(parsedPackageJSON.scripts, {
|
if (checkEntries(parsedPackageJSON.scripts, {
|
||||||
'lint': 'eslint .',
|
'lint': 'eslint .',
|
||||||
'lint:fix': 'eslint --fix .',
|
'lint:fix': 'eslint --fix .',
|
||||||
})) writePackageJson(parsedPackageJSON);
|
})) await writePackageJson(parsedPackageJSON);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!files.includes('package-lock.json')) {
|
if (!files.includes('package-lock.json')) {
|
||||||
|
@ -221,14 +220,15 @@ fs.readdir(pluginPath, (err, rootFiles) => {
|
||||||
if (autoFix) {
|
if (autoFix) {
|
||||||
console.log('Autofixing missing README.md file');
|
console.log('Autofixing missing README.md file');
|
||||||
console.log('please edit the README.md file further to include plugin specific details.');
|
console.log('please edit the README.md file further to include plugin specific details.');
|
||||||
let readme = fs.readFileSync('src/bin/plugins/lib/README.md', {encoding: 'utf8', flag: 'r'});
|
let readme =
|
||||||
|
await fsp.readFile('src/bin/plugins/lib/README.md', {encoding: 'utf8', flag: 'r'});
|
||||||
readme = readme.replace(/\[plugin_name\]/g, pluginName);
|
readme = readme.replace(/\[plugin_name\]/g, pluginName);
|
||||||
if (repository) {
|
if (repository) {
|
||||||
const org = repository.split('/')[3];
|
const org = repository.split('/')[3];
|
||||||
const name = repository.split('/')[4];
|
const name = repository.split('/')[4];
|
||||||
readme = readme.replace(/\[org_name\]/g, org);
|
readme = readme.replace(/\[org_name\]/g, org);
|
||||||
readme = readme.replace(/\[repo_url\]/g, name);
|
readme = readme.replace(/\[repo_url\]/g, name);
|
||||||
fs.writeFileSync(`${pluginPath}/README.md`, readme);
|
await fsp.writeFile(`${pluginPath}/README.md`, readme);
|
||||||
} else {
|
} else {
|
||||||
console.warn('Unable to find repository in package.json, aborting.');
|
console.warn('Unable to find repository in package.json, aborting.');
|
||||||
}
|
}
|
||||||
|
@ -241,16 +241,16 @@ fs.readdir(pluginPath, (err, rootFiles) => {
|
||||||
console.log('Autofixing missing CONTRIBUTING.md file, please edit the CONTRIBUTING.md ' +
|
console.log('Autofixing missing CONTRIBUTING.md file, please edit the CONTRIBUTING.md ' +
|
||||||
'file further to include plugin specific details.');
|
'file further to include plugin specific details.');
|
||||||
let contributing =
|
let contributing =
|
||||||
fs.readFileSync('src/bin/plugins/lib/CONTRIBUTING.md', {encoding: 'utf8', flag: 'r'});
|
await fsp.readFile('src/bin/plugins/lib/CONTRIBUTING.md', {encoding: 'utf8', flag: 'r'});
|
||||||
contributing = contributing.replace(/\[plugin_name\]/g, pluginName);
|
contributing = contributing.replace(/\[plugin_name\]/g, pluginName);
|
||||||
fs.writeFileSync(`${pluginPath}/CONTRIBUTING.md`, contributing);
|
await fsp.writeFile(`${pluginPath}/CONTRIBUTING.md`, contributing);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (readMeFileName) {
|
if (readMeFileName) {
|
||||||
let readme =
|
let readme =
|
||||||
fs.readFileSync(`${pluginPath}/${readMeFileName}`, {encoding: 'utf8', flag: 'r'});
|
await fsp.readFile(`${pluginPath}/${readMeFileName}`, {encoding: 'utf8', flag: 'r'});
|
||||||
if (!readme.toLowerCase().includes('license')) {
|
if (!readme.toLowerCase().includes('license')) {
|
||||||
console.warn('No license section in README');
|
console.warn('No license section in README');
|
||||||
if (autoFix) {
|
if (autoFix) {
|
||||||
|
@ -269,7 +269,7 @@ fs.readdir(pluginPath, (err, rootFiles) => {
|
||||||
if (autoFix) {
|
if (autoFix) {
|
||||||
readme = `${publishBadge} ${testBadge}\n\n${readme}`;
|
readme = `${publishBadge} ${testBadge}\n\n${readme}`;
|
||||||
// write readme to file system
|
// write readme to file system
|
||||||
fs.writeFileSync(`${pluginPath}/${readMeFileName}`, readme);
|
await fsp.writeFile(`${pluginPath}/${readMeFileName}`, readme);
|
||||||
console.log('Wrote Github workflow badges to README');
|
console.log('Wrote Github workflow badges to README');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -280,10 +280,10 @@ fs.readdir(pluginPath, (err, rootFiles) => {
|
||||||
if (autoFix) {
|
if (autoFix) {
|
||||||
console.log('Autofixing missing LICENSE.md file, including Apache 2 license.');
|
console.log('Autofixing missing LICENSE.md file, including Apache 2 license.');
|
||||||
let license =
|
let license =
|
||||||
fs.readFileSync('src/bin/plugins/lib/LICENSE.md', {encoding: 'utf8', flag: 'r'});
|
await fsp.readFile('src/bin/plugins/lib/LICENSE.md', {encoding: 'utf8', flag: 'r'});
|
||||||
license = license.replace('[yyyy]', new Date().getFullYear());
|
license = license.replace('[yyyy]', new Date().getFullYear());
|
||||||
license = license.replace('[name of copyright owner]', execSync('git config user.name'));
|
license = license.replace('[name of copyright owner]', execSync('git config user.name'));
|
||||||
fs.writeFileSync(`${pluginPath}/LICENSE.md`, license);
|
await fsp.writeFile(`${pluginPath}/LICENSE.md`, license);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -293,17 +293,17 @@ fs.readdir(pluginPath, (err, rootFiles) => {
|
||||||
if (autoFix) {
|
if (autoFix) {
|
||||||
console.log('Autofixing missing .gitignore file');
|
console.log('Autofixing missing .gitignore file');
|
||||||
const gitignore =
|
const gitignore =
|
||||||
fs.readFileSync('src/bin/plugins/lib/gitignore', {encoding: 'utf8', flag: 'r'});
|
await fsp.readFile('src/bin/plugins/lib/gitignore', {encoding: 'utf8', flag: 'r'});
|
||||||
fs.writeFileSync(`${pluginPath}/.gitignore`, gitignore);
|
await fsp.writeFile(`${pluginPath}/.gitignore`, gitignore);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let gitignore =
|
let gitignore =
|
||||||
fs.readFileSync(`${pluginPath}/.gitignore`, {encoding: 'utf8', flag: 'r'});
|
await fsp.readFile(`${pluginPath}/.gitignore`, {encoding: 'utf8', flag: 'r'});
|
||||||
if (!gitignore.includes('node_modules/')) {
|
if (!gitignore.includes('node_modules/')) {
|
||||||
console.warn('node_modules/ missing from .gitignore');
|
console.warn('node_modules/ missing from .gitignore');
|
||||||
if (autoFix) {
|
if (autoFix) {
|
||||||
gitignore += 'node_modules/';
|
gitignore += 'node_modules/';
|
||||||
fs.writeFileSync(`${pluginPath}/.gitignore`, gitignore);
|
await fsp.writeFile(`${pluginPath}/.gitignore`, gitignore);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -321,7 +321,7 @@ fs.readdir(pluginPath, (err, rootFiles) => {
|
||||||
'and should only exist once the plugin has been executed one time.');
|
'and should only exist once the plugin has been executed one time.');
|
||||||
if (autoFix) {
|
if (autoFix) {
|
||||||
console.log('Autofixing incorrectly existing .ep_initialized file');
|
console.log('Autofixing incorrectly existing .ep_initialized file');
|
||||||
fs.unlinkSync(`${pluginPath}/.ep_initialized`);
|
await fsp.unlink(`${pluginPath}/.ep_initialized`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -330,16 +330,15 @@ fs.readdir(pluginPath, (err, rootFiles) => {
|
||||||
'your repository.');
|
'your repository.');
|
||||||
if (autoFix) {
|
if (autoFix) {
|
||||||
console.log('Autofixing incorrectly existing npm-debug.log file');
|
console.log('Autofixing incorrectly existing npm-debug.log file');
|
||||||
fs.unlinkSync(`${pluginPath}/npm-debug.log`);
|
await fsp.unlink(`${pluginPath}/npm-debug.log`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (files.includes('static')) {
|
if (files.includes('static')) {
|
||||||
fs.readdir(`${pluginPath}/static`, (errRead, staticFiles) => {
|
const staticFiles = await fsp.readdir(`${pluginPath}/static`);
|
||||||
if (!staticFiles.includes('tests')) {
|
if (!staticFiles.includes('tests')) {
|
||||||
console.warn('Test files not found, please create tests. https://github.com/ether/etherpad-lite/wiki/Creating-a-plugin#writing-and-running-front-end-tests-for-your-plugin');
|
console.warn('Test files not found, please create tests. https://github.com/ether/etherpad-lite/wiki/Creating-a-plugin#writing-and-running-front-end-tests-for-your-plugin');
|
||||||
}
|
}
|
||||||
});
|
|
||||||
} else {
|
} else {
|
||||||
console.warn('Test files not found, please create tests. https://github.com/ether/etherpad-lite/wiki/Creating-a-plugin#writing-and-running-front-end-tests-for-your-plugin');
|
console.warn('Test files not found, please create tests. https://github.com/ether/etherpad-lite/wiki/Creating-a-plugin#writing-and-running-front-end-tests-for-your-plugin');
|
||||||
}
|
}
|
||||||
|
@ -374,7 +373,7 @@ fs.readdir(pluginPath, (err, rootFiles) => {
|
||||||
env: {...process.env, GIT_INDEX_FILE: '.git/checkPlugin.index'},
|
env: {...process.env, GIT_INDEX_FILE: '.git/checkPlugin.index'},
|
||||||
stdio: 'inherit',
|
stdio: 'inherit',
|
||||||
});
|
});
|
||||||
fs.unlinkSync(`${pluginPath}/.git/checkPlugin.index`);
|
await fsp.unlink(`${pluginPath}/.git/checkPlugin.index`);
|
||||||
|
|
||||||
const commitCmd = [
|
const commitCmd = [
|
||||||
'git add -A',
|
'git add -A',
|
||||||
|
@ -401,4 +400,4 @@ fs.readdir(pluginPath, (err, rootFiles) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log('Finished');
|
console.log('Finished');
|
||||||
});
|
})();
|
||||||
|
|
Loading…
Reference in New Issue