Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions bin/enact.js
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ if (process.argv.indexOf('-v') >= 0 || process.argv.indexOf('--version') >= 0) {
case 'eject':
case 'template':
case 'lint':
case 'check':
case 'license': {
const task = require('../commands/' + command).cli;
task(process.argv.slice(3));
Expand Down
155 changes: 155 additions & 0 deletions commands/check.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
/* eslint-env node, es6 */
const fs = require('fs');
const {promisify} = require('util');
const path = require('path');
const glob = require('glob');
const minimist = require('minimist');

const globOpts = {
ignore: [
'**/node_modules/**',
'build/**',
'**/dist/**',
'coverage/**',
'tests/**',
'**/*-specs.js',
'**/index.js',
'samples/**',
'**/util.js',
'**/utils.js',
'**/validators.js'
],
nodir: true
};

const readFile = promisify(fs.readFile);
const globPromise = promisify(glob);

function displayHelp() {
let e = 'node ' + path.relative(process.cwd(), __filename);
if (require.main !== module) e = 'enact check';

console.log(' Checks for potential missing class definitions');
console.log();
console.log(' Usage');
console.log(` ${e} [options]`);
console.log();
console.log(' Arguments');
console.log();
console.log(' Options');
console.log(' -v, --version Display version information');
console.log(' -h, --help Display help information');
console.log();
process.exit(0);
}

function logWarnings(missingClassNames) {
if (missingClassNames.length) {
console.log();
console.warn(' There might be missing class definitions in the following less files:');
console.log();

missingClassNames.forEach(component => {
const componentName = Object.keys(component)[0];
console.log(` ${componentName}`);
console.log(component[componentName]);
console.log();
});
} else {
console.log(' No problems found.');
}
}

function getMissingClassNames(lessFile, classNames) {
return new Promise((resolve, reject) => {
const missingClassNames = {[lessFile]: []};

if (lessFile) {
readFile(lessFile, 'utf8')
.then(data => {
// const componentName = file.match(/([^\/]+)(?=\.\w+$)/g)[0];
// const lessFileName = data.match(/\w*\.module\.less/g);
classNames.forEach(name => {
if (!data.includes(name)) {
missingClassNames[lessFile].push(name);
}
});

resolve(missingClassNames[lessFile].length === 0 ? null : missingClassNames);
})
.catch(err => reject(err));
}
});
}

// function getDefaultClasses(classNameArray, component) {
// const newArray = [...getDefaultClasses];
// //TODO
// return newArray;
// }

function getClassNamesUsed(files) {
return new Promise((resolve, reject) => {
const promisesToResolve = [];

files.forEach((file, index) => {
readFile(file, 'utf8')
.then(data => {
const lessFileName = data.match(/\w*\.module\.less/g);
const dataWithoutComments = data.replace(/(\/\*([\s\S]*?)\*\/)|(\/\/(.*)$)/gm, '');
const classNamesUsed = dataWithoutComments.match(/css\.\w*/g);
// classNamesUsed = getDefaultClasses(classNamesUsed, dataWithoutComments);

if (lessFileName && classNamesUsed) {
const componentDirectory = file.match(/^(.+)\//g)[0];
const classNames = classNamesUsed.map(name => name.split('.')[1]);

promisesToResolve.push(
getMissingClassNames(`${componentDirectory}${lessFileName[0]}`, classNames)
);
}

if (index === files.length - 1) {
return promisesToResolve;
}
})
.then(promises => (promises ? resolve(promises) : null))
.catch(err => reject(err));
});
});
}

function getJSfiles() {
return new Promise((resolve, reject) => {
globPromise('**/*.js', globOpts)
.then(files => {
resolve(files);
})
.catch(err => reject(err));
});
}

function api() {
return Promise.resolve().then(() =>
getJSfiles()
.then(files => getClassNamesUsed(files))
.then(promises => Promise.all(promises))
.then(results => logWarnings(results.filter(result => result)))
.catch(err => console.err(err))
);
}

function cli(args) {
const opts = minimist(args, {
boolean: ['help'],
alias: {h: 'help'}
});
if (opts.help) displayHelp();

api(args).catch(() => {
process.exit(1);
});
}

module.exports = {api, cli};
if (require.main === module) cli(process.argv.slice(2));