172 lines
4.2 KiB
JavaScript
Executable File
172 lines
4.2 KiB
JavaScript
Executable File
#!/usr/bin/env node
|
|
|
|
const { config } = require('../package.json');
|
|
const { exists } = require('mz/fs');
|
|
const sgf = require('staged-git-files');
|
|
const forceArray = require('force-array');
|
|
const awaitify = require('apr-awaitify');
|
|
const asyncFilter = require('apr-filter');
|
|
const map = require('apr-map');
|
|
const reduce = require('apr-reduce');
|
|
const parallel = require('apr-parallel');
|
|
const execa = require('execa');
|
|
const globby = require('globby');
|
|
const main = require('apr-main');
|
|
const argv = require('yargs').argv;
|
|
const path = require('path');
|
|
const checksum = require('checksum');
|
|
|
|
const getStaged = awaitify(sgf);
|
|
const asyncChecksum = awaitify(checksum.file);
|
|
|
|
const ROOT = path.join(__dirname, '../');
|
|
const SCRIPTS = path.resolve(__dirname);
|
|
|
|
const statuses = ['Added', 'Modified'];
|
|
|
|
const filter = (files = []) =>
|
|
files
|
|
.filter(file => !/node_modules|dist/.test(file))
|
|
.map(file => path.resolve(ROOT, file));
|
|
|
|
const run = async (files = []) => {
|
|
const filteredFiles = filter(files);
|
|
|
|
const _files = filteredFiles.reduce(
|
|
(files, file) => {
|
|
const ext = path.extname(file).replace(/^./, '');
|
|
|
|
if (!ext) {
|
|
return files;
|
|
}
|
|
|
|
return Object.assign(files, {
|
|
[ext]: (files[ext] || []).concat(file)
|
|
});
|
|
},
|
|
{
|
|
js: [],
|
|
gql: [],
|
|
json: []
|
|
}
|
|
);
|
|
|
|
return parallel({
|
|
js: () =>
|
|
_files.js.length
|
|
? execa(
|
|
'prettier',
|
|
['--write', '--single-quote', '--parser=babylon'].concat(_files.js),
|
|
{
|
|
stdio: 'inherit'
|
|
}
|
|
)
|
|
: Promise.resolve(),
|
|
gql: () =>
|
|
_files.gql.length
|
|
? execa(
|
|
'prettier',
|
|
['--write', '--single-quote', '--parser=graphql'].concat(
|
|
_files.gql
|
|
),
|
|
{
|
|
stdio: 'inherit'
|
|
}
|
|
)
|
|
: Promise.resolve(),
|
|
json: () =>
|
|
_files.json.length
|
|
? execa(
|
|
'prettier',
|
|
['--write', '--single-quote', '--parser=json'].concat(_files.json),
|
|
{
|
|
stdio: 'inherit'
|
|
}
|
|
)
|
|
: Promise.resolve()
|
|
});
|
|
};
|
|
|
|
const add = async filename => execa('git', ['add', filename]);
|
|
|
|
const all = async () => {
|
|
const files = await globby(['packages/**/*.{js,gql,json}', 'scripts/*'], {
|
|
cwd: path.join(__dirname, '..')
|
|
});
|
|
|
|
return run(files);
|
|
};
|
|
|
|
const getUnstaged = async () => {
|
|
const unstaged = await execa('git', ['ls-files', '-m']);
|
|
return unstaged.stdout.split('\n');
|
|
};
|
|
|
|
const staged = async () => {
|
|
const unstaged = (await getUnstaged())
|
|
.map(file => path.resolve(ROOT, file))
|
|
.filter(file => /\.js|gql|json$/.test(file) || file.indexOf(SCRIPTS) === 0);
|
|
|
|
const files = (await getStaged())
|
|
.filter(({ status }) => statuses.indexOf(status) >= 0)
|
|
.map(file =>
|
|
Object.assign({}, file, { filename: path.resolve(ROOT, file.filename) })
|
|
)
|
|
.filter(
|
|
file =>
|
|
/\.js|gql|json$/.test(file.filename) ||
|
|
file.filename.indexOf(SCRIPTS) === 0
|
|
);
|
|
|
|
const existing = await asyncFilter(
|
|
files,
|
|
({ filename }) => exists(filename)
|
|
);
|
|
|
|
if (!existing.length) {
|
|
return;
|
|
}
|
|
|
|
const checksums = await map(existing, async file => {
|
|
const checksum = await asyncChecksum(file.filename);
|
|
return Object.assign({}, file, { checksum });
|
|
});
|
|
|
|
const filenames = existing.map(file => file.filename);
|
|
await run(filenames);
|
|
|
|
const changed = await asyncFilter(
|
|
checksums,
|
|
async ({ filename, checksum }) => {
|
|
const newChecksum = await asyncChecksum(filename);
|
|
return checksum != newChecksum;
|
|
}
|
|
);
|
|
|
|
const modifieds = await reduce(
|
|
changed,
|
|
async (modifieds, file) => {
|
|
const isUnstaged = unstaged.filter(f => f === file.filename).length;
|
|
if (
|
|
(file.status === 'Modified' || file.status === 'Added') &&
|
|
isUnstaged
|
|
) {
|
|
modifieds.push(file);
|
|
} else {
|
|
await add(file.filename);
|
|
}
|
|
return modifieds;
|
|
},
|
|
[]
|
|
);
|
|
|
|
if (modifieds.length) {
|
|
modifieds.forEach(modified =>
|
|
console.log('PARTIALLY STAGED FILE ', modified.filename)
|
|
);
|
|
process.exit(1);
|
|
}
|
|
};
|
|
|
|
main(argv._.length ? run(argv._) : argv.staged ? staged() : all());
|