Check for unused initial (untested) implementation
This commit is contained in:
parent
e599bef72e
commit
d55786f744
|
|
@ -1,6 +1,6 @@
|
|||
module.exports = {
|
||||
SOURCE: 'templates',
|
||||
DIST: 'dist',
|
||||
SOURCE_DIR: 'templates',
|
||||
DIST_DIR: 'dist',
|
||||
WORKING_DIR: 'tmp',
|
||||
CONFIGURATION_FILE: 'conf.json'
|
||||
}
|
||||
|
|
|
|||
23
gulpfile.js
23
gulpfile.js
|
|
@ -1,11 +1,11 @@
|
|||
const gulp = require('gulp');
|
||||
const plumber = require('gulp-plumber');
|
||||
|
||||
const { SOURCE, DIST, WORKING_DIR, CONFIGURATION_FILE } = require('./constants');
|
||||
const { SOURCE_DIR, DIST_DIR, WORKING_DIR, CONFIGURATION_FILE } = require('./constants');
|
||||
|
||||
const options = {
|
||||
source: SOURCE,
|
||||
dist: DIST,
|
||||
sourceDir: SOURCE_DIR,
|
||||
distDir: DIST_DIR,
|
||||
workingDir: WORKING_DIR,
|
||||
configurationFile: CONFIGURATION_FILE,
|
||||
src: function plumbedSrc() {
|
||||
|
|
@ -22,11 +22,14 @@ require('./tasks/less')(options);
|
|||
require('./tasks/lint')(options);
|
||||
require('./tasks/postcss')(options);
|
||||
require('./tasks/sass')(options);
|
||||
require('./tasks/check-for-missing')(options);
|
||||
require('./tasks/check-for-unused').checkForUnusedTask(options);
|
||||
require('./tasks/check-deps')(options);
|
||||
|
||||
/* Runs the entire pipeline once. */
|
||||
gulp.task('run-pipeline', gulp.series('dupe', 'less', 'sass', 'postcss', 'lint', 'build', 'check-for-missing'));
|
||||
gulp.task(
|
||||
'run-pipeline',
|
||||
gulp.series('dupe', 'less', 'sass', 'postcss', 'lint', 'build', gulp.parallel('check-for-unused'))
|
||||
);
|
||||
|
||||
/* By default templates will be built into '/dist'. */
|
||||
gulp.task(
|
||||
|
|
@ -35,11 +38,11 @@ gulp.task(
|
|||
/* gulp will watch for changes in '/templates'. */
|
||||
gulp.watch(
|
||||
[
|
||||
options.source + '/**/*.html',
|
||||
options.source + '/**/*.css',
|
||||
options.source + '/**/*.scss',
|
||||
options.source + '/**/*.less',
|
||||
options.source + '/**/conf.json'
|
||||
options.sourceDir + '/**/*.html',
|
||||
options.sourceDir + '/**/*.css',
|
||||
options.sourceDir + '/**/*.scss',
|
||||
options.sourceDir + '/**/*.less',
|
||||
options.sourceDir + '/**/conf.json'
|
||||
],
|
||||
{ delay: 500 },
|
||||
gulp.series('run-pipeline')
|
||||
|
|
|
|||
|
|
@ -1635,9 +1635,9 @@
|
|||
}
|
||||
},
|
||||
"chalk": {
|
||||
"version": "2.4.1",
|
||||
"resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz",
|
||||
"integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==",
|
||||
"version": "2.4.2",
|
||||
"resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
|
||||
"integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
|
||||
"requires": {
|
||||
"ansi-styles": "^3.2.1",
|
||||
"escape-string-regexp": "^1.0.5",
|
||||
|
|
|
|||
10
package.json
10
package.json
|
|
@ -26,13 +26,13 @@
|
|||
"start": "node ./node_modules/.bin/gulp",
|
||||
"once": "node ./node_modules/.bin/gulp run-pipeline",
|
||||
"deploy": "npm run test && cp -r dist demo && git push origin `git subtree split --prefix demo develop`:gh-pages --force",
|
||||
"test": "npm run once && node ./node_modules/.bin/ava",
|
||||
"test:watch": "npm run once && node ./node_modules/.bin/ava --watch",
|
||||
"format": "node ./node_modules/.bin/prettier {tasks,tests}/**/*.js gulpfile.js .eslintrc.js --write",
|
||||
"lint": "node ./node_modules/.bin/eslint ./**/*.js gulpfile.js"
|
||||
"e2e-test": "npm run once && node ./node_modules/.bin/ava",
|
||||
"format": "prettier {tasks,tests}/**/*.js gulpfile.js .eslintrc.js --write",
|
||||
"lint": "eslint ./**/*.js gulpfile.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"autoprefixer": "^9.7.4",
|
||||
"autoprefixer": "^9.6.1",
|
||||
"chalk": "^2.4.2",
|
||||
"del": "^5.1.0",
|
||||
"graceful-fs": "^4.2.3",
|
||||
"gulp": "^4.0.2",
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@ function buildTask(options) {
|
|||
return path;
|
||||
})
|
||||
)
|
||||
.pipe(gulp.dest(options.dist));
|
||||
.pipe(gulp.dest(options.distDir));
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -66,7 +66,7 @@ function buildTask(options) {
|
|||
* Clean up & then read from workingDir to generate templates.
|
||||
* For each found config, a template group will be generated through `makeTemplates`.
|
||||
*/
|
||||
return del(options.dist)
|
||||
return del(options.distDir)
|
||||
.then(() => {
|
||||
/**
|
||||
* Loop through dirs and load their conf files.
|
||||
|
|
|
|||
|
|
@ -1,28 +1,9 @@
|
|||
const gulp = require('gulp');
|
||||
const { getConfigsForDir, getFilePathsForDir } = require('./util/util');
|
||||
|
||||
function checkForMissingTask(options) {
|
||||
gulp.task('check-for-missing', done => {
|
||||
const configs = getConfigsForDir(options.workingDir, options.configurationFile);
|
||||
|
||||
configs.map(({ dir, confItems }) => {
|
||||
confItems.forEach(async confItem => {
|
||||
const definedStrings = Object.keys(confItem).map(key => {
|
||||
return {
|
||||
src: `@echo ${key}`,
|
||||
used: false
|
||||
};
|
||||
});
|
||||
|
||||
const cwd = `${options.workingDir}/${dir}`;
|
||||
const files = await getFilePathsForDir(cwd);
|
||||
const htmlTemplates = files.filter(file => !!file.match(/.*\.html/) && !file.match(/.*\.inc*\.html/)); // Read only CSS files.
|
||||
console.log(definedStrings, htmlTemplates);
|
||||
});
|
||||
|
||||
done();
|
||||
});
|
||||
function checkForUnusedTask(options) {
|
||||
gulp.task('check-for-unused', async done => {
|
||||
done();
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = checkForMissingTask;
|
||||
module.exports = checkForUnusedTask;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,81 @@
|
|||
const gulp = require('gulp');
|
||||
const fs = require('fs');
|
||||
const chalk = require('chalk');
|
||||
const { getConfigsForDir, getFilePathsForDir, log } = require('./util/util');
|
||||
|
||||
const OUTPUT_KEYWORD = '@echo';
|
||||
|
||||
// todo: needs a proper refactor.
|
||||
function checkForUnusedTask(options) {
|
||||
gulp.task('check-for-unused', async done => {
|
||||
const configs = getConfigsForDir(options.workingDir, options.configurationFile);
|
||||
const unusedItems = await checkForUnusedItemsInConfigs(options.workingDir, configs);
|
||||
outputWarningsForUnusedItems(unusedItems, configs);
|
||||
|
||||
done();
|
||||
});
|
||||
}
|
||||
|
||||
// todo: find configs by id instead of using the index?
|
||||
const outputWarningsForUnusedItems = (unusedItems, configs) => {
|
||||
const find = OUTPUT_KEYWORD;
|
||||
const regex = new RegExp(find, 'g');
|
||||
unusedItems.forEach((unusedInConfigs, index) => {
|
||||
const { dir } = configs[index];
|
||||
|
||||
unusedInConfigs.forEach((unusedInConfItems, index) => {
|
||||
log.warn(
|
||||
`${unusedInConfItems.length} unused properties in ${dir}: ${unusedInConfItems
|
||||
.reduce((acc, cur) => (acc ? `${acc}, ${chalk.white(cur)}` : chalk.white(cur)), '')
|
||||
.replace(regex, '')}`
|
||||
);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
const checkForUnusedItemsInConfigs = (rootDir, configs) => {
|
||||
return Promise.all(
|
||||
configs.map(async ({ dir, confItems }) => {
|
||||
return Promise.all(
|
||||
confItems.map(async confItem => {
|
||||
const definedStrings = Object.keys(confItem).map(key => `${OUTPUT_KEYWORD} ${key}`);
|
||||
const cwd = `${rootDir}/${dir}`;
|
||||
const files = await getFilePathsForDir(cwd);
|
||||
const htmlTemplates = await self.getHtmlTemplatesFromFilelist(files);
|
||||
const concatenatedTemplates = htmlTemplates.join('');
|
||||
|
||||
return definedStrings.filter(str => concatenatedTemplates.includes(str));
|
||||
})
|
||||
);
|
||||
})
|
||||
);
|
||||
};
|
||||
|
||||
// todo: should be util, so should the one in build.js
|
||||
const getHtmlTemplatesFromFilelist = filelist => {
|
||||
return Promise.all(
|
||||
filelist
|
||||
.filter(file => !!file.match(/.*\.html/) && !file.match(/.*\.inc*\.html/))
|
||||
.map(
|
||||
htmlTemplate =>
|
||||
new Promise((resolve, reject) => {
|
||||
fs.readFile(htmlTemplate, 'utf8', (error, data) => {
|
||||
if (error) {
|
||||
reject(error);
|
||||
}
|
||||
|
||||
resolve(data);
|
||||
});
|
||||
})
|
||||
)
|
||||
);
|
||||
};
|
||||
|
||||
const self = {
|
||||
checkForUnusedTask,
|
||||
outputWarningsForUnusedItems,
|
||||
checkForUnusedItemsInConfigs,
|
||||
getHtmlTemplatesFromFilelist
|
||||
};
|
||||
|
||||
module.exports = self;
|
||||
|
|
@ -5,7 +5,7 @@ function dupeTask(options) {
|
|||
gulp.task('dupe', function() {
|
||||
del.sync([options.workingDir]);
|
||||
|
||||
return options.src([options.source + '/**/*']).pipe(gulp.dest('./' + options.workingDir));
|
||||
return options.src([options.sourceDir + '/**/*']).pipe(gulp.dest('./' + options.workingDir));
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,9 @@
|
|||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const klaw = require('klaw');
|
||||
const chalk = require('chalk');
|
||||
|
||||
// todo test
|
||||
/**
|
||||
* Given a directory, scans all directories in it (not deep) and returns found config items.
|
||||
*
|
||||
|
|
@ -16,7 +18,7 @@ const getConfigsForDir = (rootDir, configFileName) => {
|
|||
|
||||
/** Exit with warn if no configuration file found. */
|
||||
if (!fs.existsSync(path.resolve(rootDir, confPath))) {
|
||||
console.warn(`Missing configuration in "${dir}". Did you remember to create "${dir}/${configFileName}"?`);
|
||||
self.log.warn(`Missing configuration in "${dir}". Did you remember to create "${dir}/${configFileName}"?`);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -41,8 +43,11 @@ const getConfigsForDir = (rootDir, configFileName) => {
|
|||
.filter(config => config);
|
||||
};
|
||||
|
||||
// todo test
|
||||
/**
|
||||
* Given a directory, gets all file paths in it.
|
||||
*
|
||||
* @param { string } dir Dir to get files paths for.
|
||||
*/
|
||||
const getFilePathsForDir = dir => {
|
||||
const files = [];
|
||||
|
|
@ -63,7 +68,24 @@ const getFilePathsForDir = dir => {
|
|||
});
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
const log = {
|
||||
warn: (...messages) => {
|
||||
console.warn('🔵 ', chalk.yellow(messages));
|
||||
},
|
||||
|
||||
log: (...messages) => {
|
||||
console.log('🔘 ', chalk.gray(messages));
|
||||
},
|
||||
|
||||
error: (...messages) => {
|
||||
console.error('🔴 ', chalk.red(messages));
|
||||
}
|
||||
};
|
||||
|
||||
const self = {
|
||||
log,
|
||||
getConfigsForDir,
|
||||
getFilePathsForDir
|
||||
};
|
||||
|
||||
module.exports = self;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,40 @@
|
|||
const test = require('ava');
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
const readFileSync = path => fs.readFileSync(('../', path), 'utf8');
|
||||
|
||||
test('dark signature output', async t => {
|
||||
const expected = readFileSync('tests/sample/dark/signature-dark.html');
|
||||
const built = readFileSync('dist/dark/signature-dark.html');
|
||||
|
||||
t.deepEqual(expected, built);
|
||||
});
|
||||
|
||||
test('dark signature reply output', async t => {
|
||||
const expected = readFileSync('tests/sample/dark/signature-reply-dark.html');
|
||||
const built = readFileSync('dist/dark/signature-reply-dark.html');
|
||||
|
||||
t.deepEqual(expected, built);
|
||||
});
|
||||
|
||||
test('light signature output', async t => {
|
||||
const expected = readFileSync('tests/sample/light/signature-light.html');
|
||||
const built = readFileSync('dist/light/signature-light.html');
|
||||
|
||||
t.deepEqual(expected, built);
|
||||
});
|
||||
|
||||
test('light signature reply output', async t => {
|
||||
const expected = readFileSync('tests/sample/light/signature-reply-light.html');
|
||||
const built = readFileSync('dist/light/signature-reply-light.html');
|
||||
|
||||
t.deepEqual(expected, built);
|
||||
});
|
||||
|
||||
test('light full mail output', async t => {
|
||||
const expected = readFileSync('tests/sample/light/full-mail-light.html');
|
||||
const built = readFileSync('dist/light/full-mail-light.html');
|
||||
|
||||
t.deepEqual(expected, built);
|
||||
});
|
||||
|
|
@ -1,38 +0,0 @@
|
|||
const test = require('ava');
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
test('dark signature output', async t => {
|
||||
const expected = fs.readFileSync(path.resolve('tests/sample/dark/signature-dark.html'), 'utf8');
|
||||
const built = fs.readFileSync(path.resolve('dist/dark/signature-dark.html'), 'utf8');
|
||||
|
||||
t.deepEqual(expected, built);
|
||||
});
|
||||
|
||||
test('dark signature reply output', async t => {
|
||||
const expected = fs.readFileSync(path.resolve('tests/sample/dark/signature-reply-dark.html'), 'utf8');
|
||||
const built = fs.readFileSync(path.resolve('dist/dark/signature-reply-dark.html'), 'utf8');
|
||||
|
||||
t.deepEqual(expected, built);
|
||||
});
|
||||
|
||||
test('light signature output', async t => {
|
||||
const expected = fs.readFileSync(path.resolve('tests/sample/light/signature-light.html'), 'utf8');
|
||||
const built = fs.readFileSync(path.resolve('dist/light/signature-light.html'), 'utf8');
|
||||
|
||||
t.deepEqual(expected, built);
|
||||
});
|
||||
|
||||
test('light signature reply output', async t => {
|
||||
const expected = fs.readFileSync(path.resolve('tests/sample/light/signature-reply-light.html'), 'utf8');
|
||||
const built = fs.readFileSync(path.resolve('dist/light/signature-reply-light.html'), 'utf8');
|
||||
|
||||
t.deepEqual(expected, built);
|
||||
});
|
||||
|
||||
test('light full mail output', async t => {
|
||||
const expected = fs.readFileSync(path.resolve('tests/sample/light/full-mail-light.html'), 'utf8');
|
||||
const built = fs.readFileSync(path.resolve('dist/light/full-mail-light.html'), 'utf8');
|
||||
|
||||
t.deepEqual(expected, built);
|
||||
});
|
||||
Loading…
Reference in New Issue