test/style: refactor remaining grunt tasks to use promises instead of callbacks

This commit is contained in:
Nils Knappmeier
2019-12-14 01:49:55 +01:00
committed by Nils Knappmeier
parent 1ebce2b53c
commit 1ec1737d24
4 changed files with 209 additions and 257 deletions
+20 -17
View File
@@ -1,26 +1,29 @@
const _ = require('underscore'),
async = require('neo-async'),
metrics = require('../bench');
const metrics = require('../bench');
const { createRegisterAsyncTaskFn } = require('./util/async-grunt-task');
module.exports = function(grunt) {
grunt.registerTask('metrics', function() {
const done = this.async(),
execName = grunt.option('name'),
events = {};
const registerAsyncTask = createRegisterAsyncTaskFn(grunt);
async.each(
_.keys(metrics),
function(name, complete) {
if (/^_/.test(name) || (execName && name !== execName)) {
return complete();
}
registerAsyncTask('metrics', function() {
const onlyExecuteName = grunt.option('name');
const events = {};
const promises = Object.keys(metrics).map(async name => {
if (/^_/.test(name)) {
return;
}
if (onlyExecuteName != null && name !== onlyExecuteName) {
return;
}
return new Promise(resolve => {
metrics[name](grunt, function(data) {
events[name] = data;
complete();
resolve();
});
},
done
);
});
});
return Promise.all(promises);
});
};
+77 -81
View File
@@ -1,54 +1,38 @@
const _ = require('underscore'),
async = require('neo-async'),
AWS = require('aws-sdk'),
git = require('./util/git'),
semver = require('semver');
const AWS = require('aws-sdk');
const git = require('./util/git');
const { createRegisterAsyncTaskFn } = require('./util/async-grunt-task');
const semver = require('semver');
module.exports = function(grunt) {
grunt.registerTask('publish:latest', function() {
const done = this.async();
const registerAsyncTask = createRegisterAsyncTaskFn(grunt);
git.debug(function(remotes, branches) {
grunt.log.writeln('remotes: ' + remotes);
grunt.log.writeln('branches: ' + branches);
registerAsyncTask('publish:latest', async () => {
grunt.log.writeln('remotes: ' + (await git.remotes()));
grunt.log.writeln('branches: ' + (await git.branches()));
git.commitInfo(function(err, info) {
grunt.log.writeln('tag: ' + info.tagName);
const commitInfo = await git.commitInfo();
grunt.log.writeln('tag: ' + commitInfo.tagName);
const files = [];
const suffixes = [];
// Publish the master as "latest" and with the commit-id
if (info.isMaster) {
files.push('-latest');
files.push('-' + info.head);
}
// Publish the master as "latest" and with the commit-id
if (commitInfo.isMaster) {
suffixes.push('-latest');
suffixes.push('-' + commitInfo.headSha);
}
// Publish tags by their tag-name
if (info.tagName && semver.valid(info.tagName)) {
files.push('-' + info.tagName);
}
// Publish tags by their tag-name
if (commitInfo.tagName && semver.valid(commitInfo.tagName)) {
suffixes.push('-' + commitInfo.tagName);
}
if (files.length > 0) {
initSDK();
grunt.log.writeln('publishing files: ' + JSON.stringify(files));
publish(fileMap(files), done);
} else {
// Silently ignore for branches
done();
}
});
});
});
grunt.registerTask('publish:version', function() {
const done = this.async();
initSDK();
git.commitInfo(function(err, info) {
if (!info.tagName) {
throw new Error('The current commit must be tagged');
}
publish(fileMap(['-' + info.tagName]), done);
});
if (suffixes.length > 0) {
initSDK();
grunt.log.writeln(
'publishing file-suffixes: ' + JSON.stringify(suffixes)
);
await publish(suffixes);
}
});
function initSDK() {
@@ -62,45 +46,57 @@ module.exports = function(grunt) {
AWS.config.update({ accessKeyId: key, secretAccessKey: secret });
}
function publish(files, callback) {
const s3 = new AWS.S3(),
bucket = process.env.S3_BUCKET_NAME;
async.each(
_.keys(files),
function(file, callback) {
const params = {
Bucket: bucket,
Key: file,
Body: grunt.file.read(files[file])
};
s3.putObject(params, function(err) {
if (err) {
throw err;
} else {
grunt.log.writeln('Published ' + file + ' to build server.');
callback();
}
});
},
callback
);
async function publish(suffixes) {
const publishPromises = suffixes.map(suffix => publishSuffix(suffix));
return Promise.all(publishPromises);
}
function fileMap(suffixes) {
const map = {};
_.each(
[
'handlebars.js',
'handlebars.min.js',
'handlebars.runtime.js',
'handlebars.runtime.min.js'
],
function(file) {
_.each(suffixes, function(suffix) {
map[file.replace(/\.js$/, suffix + '.js')] = 'dist/' + file;
});
}
);
return map;
async function publishSuffix(suffix) {
const filenames = [
'handlebars.js',
'handlebars.min.js',
'handlebars.runtime.js',
'handlebars.runtime.min.js'
];
const publishPromises = filenames.map(filename => {
const nameInBucket = getNameInBucket(filename, suffix);
const localFile = getLocalFile(filename);
uploadToBucket(localFile, nameInBucket);
grunt.log.writeln(
`Published ${localFile} to build server (${nameInBucket})`
);
});
return Promise.all(publishPromises);
}
async function uploadToBucket(localFile, nameInBucket) {
const bucket = process.env.S3_BUCKET_NAME;
const uploadParams = {
Bucket: bucket,
Key: nameInBucket,
Body: grunt.file.read(localFile)
};
return s3PutObject(uploadParams);
}
};
function s3PutObject(uploadParams) {
const s3 = new AWS.S3();
return new Promise((resolve, reject) => {
s3.putObject(uploadParams, err => {
if (err != null) {
return reject(err);
}
resolve();
});
});
}
function getNameInBucket(filename, suffix) {
return filename.replace(/\.js$/, suffix + '.js');
}
function getLocalFile(filename) {
return 'dist/' + filename;
}
+61 -102
View File
@@ -1,115 +1,74 @@
const childProcess = require('child_process');
module.exports = {
debug: function(callback) {
childProcess.exec('git remote -v', {}, function(err, remotes) {
if (err) {
throw new Error('git.remote: ' + err.message);
async remotes() {
return git('remotes', '-v');
},
async branches() {
return git('branch', '-a');
},
async clean() {
const stdout = git('diff-index', '--name-only', 'HEAD', '--');
return stdout === '';
},
async commitInfo() {
const headSha = await this.headSha();
const masterSha = await this.masterSha();
return {
headSha,
masterSha,
tagName: await this.tagName(),
isMaster: headSha === masterSha
};
},
async headSha() {
const stdout = await git(' rev-parse', '--short', 'HEAD');
return stdout.trim();
},
async masterSha() {
try {
const stdout = await git('rev-parse', '--short', 'origin/master');
return stdout.trim();
} catch (error) {
if (/Needed a single revision/.test(error.message)) {
// Master was not checked out but in this case, so we know we are not master. We can ignore this
return '';
}
childProcess.exec('git branch -a', {}, function(err, branches) {
if (err) {
throw new Error('git.branch: ' + err.message);
}
callback(remotes, branches);
});
});
},
clean: function(callback) {
childProcess.exec('git diff-index --name-only HEAD --', {}, function(
err,
stdout
) {
callback(undefined, !err && !stdout);
});
throw error;
}
},
commitInfo: function(callback) {
module.exports.head(function(err, headSha) {
module.exports.master(function(err, masterSha) {
module.exports.tagName(function(err, tagName) {
callback(undefined, {
head: headSha,
master: masterSha,
tagName: tagName,
isMaster: headSha === masterSha
});
});
});
});
async add(path) {
return git('add', '-f', path);
},
head: function(callback) {
childProcess.exec('git rev-parse --short HEAD', {}, function(err, stdout) {
if (err) {
throw new Error('git.head: ' + err.message);
}
callback(undefined, stdout.trim());
});
async commit(message) {
return git('commit', '--message', message);
},
master: function(callback) {
childProcess.exec('git rev-parse --short origin/master', {}, function(
err,
stdout
) {
// This will error if master was not checked out but in this case we know we are not master
// so we can ignore.
if (err && !/Needed a single revision/.test(err.message)) {
throw new Error('git.master: ' + err.message);
}
callback(undefined, stdout.trim());
});
async tag(name) {
return git('tag', '-a', `--message=${name}`, name);
},
async tagName() {
const stdout = await git('tag', '-l', '--points-at', 'HEAD');
add: function(path, callback) {
childProcess.exec('git add -f ' + path, {}, function(err) {
if (err) {
throw new Error('git.add: ' + err.message);
}
const tags = stdout.trim().split(/\n|\r\n/);
const versionTags = tags.filter(tag => /^v/.test(tag));
callback();
});
},
commit: function(name, callback) {
childProcess.exec('git commit --message=' + name, {}, function(err) {
if (err) {
throw new Error('git.commit: ' + err.message);
}
callback();
});
},
tag: function(name, callback) {
childProcess.exec('git tag -a --message=' + name + ' ' + name, {}, function(
err
) {
if (err) {
throw new Error('git.tag: ' + err.message);
}
callback();
});
},
tagName: function(callback) {
childProcess.exec('git describe --tags', {}, function(err, stdout) {
if (err) {
throw new Error('git.tagName: ' + err.message);
}
let tags = stdout.trim().split(/\n/);
tags = tags.filter(function(info) {
info = info.split('-');
return info.length == 1;
});
const versionTags = tags.filter(function(info) {
return /^v/.test(info[0]);
});
callback(undefined, versionTags[0] || tags[0]);
});
if (versionTags[0] != null) {
return versionTags;
}
return tags[0];
}
};
async function git(...args) {
return new Promise((resolve, reject) =>
childProcess.execFile('git', args, (err, stdout) => {
if (err != null) {
return reject(
new Error(`"git ${args.join(' ')}" caused error: ${err.message}`)
);
}
resolve(stdout);
})
);
}
+51 -57
View File
@@ -1,68 +1,62 @@
const async = require('neo-async'),
git = require('./util/git'),
semver = require('semver');
const git = require('./util/git');
const semver = require('semver');
const { createRegisterAsyncTaskFn } = require('./util/async-grunt-task');
module.exports = function(grunt) {
grunt.registerTask(
'version',
'Updates the current release version',
function() {
const done = this.async(),
pkg = grunt.config('pkg'),
version = grunt.option('ver');
const registerAsyncTask = createRegisterAsyncTaskFn(grunt);
if (!semver.valid(version)) {
throw new Error(
'Must provide a version number (Ex: --ver=1.0.0):\n\t' +
version +
'\n\n'
);
}
pkg.version = version;
grunt.config('pkg', pkg);
grunt.log.writeln('Updating to version ' + version);
async.each(
[
[
'lib/handlebars/base.js',
/const VERSION = ['"](.*)['"];/,
"const VERSION = '" + version + "';"
],
[
'components/bower.json',
/"version":.*/,
'"version": "' + version + '",'
],
[
'components/package.json',
/"version":.*/,
'"version": "' + version + '",'
],
[
'components/handlebars.js.nuspec',
/<version>.*<\/version>/,
'<version>' + version + '</version>'
]
],
function(args, callback) {
replace.apply(undefined, args);
grunt.log.writeln(' - ' + args[0]);
git.add(args[0], callback);
},
function() {
grunt.task.run(['default']);
done();
}
registerAsyncTask('version', async () => {
const pkg = grunt.config('pkg');
const version = grunt.option('ver');
if (!semver.valid(version)) {
throw new Error(
'Must provide a version number (Ex: --ver=1.0.0):\n\t' +
version +
'\n\n'
);
}
);
pkg.version = version;
grunt.config('pkg', pkg);
function replace(path, regex, value) {
const replaceSpec = [
{
path: 'lib/handlebars/base.js',
regex: /const VERSION = ['"](.*)['"];/,
replacement: `const VERSION = '${version}';`
},
{
path: 'components/bower.json',
regex: /"version":.*/,
replacement: `"version": "${version}",`
},
{
path: 'components/package.json',
regex: /"version":.*/,
replacement: `"version": "${version}",`
},
{
path: 'components/handlebars.js.nuspec',
regex: /<version>.*<\/version>/,
replacement: `<version>${version}</version>`
}
];
await Promise.all(
replaceSpec.map(replaceSpec =>
replaceAndAdd(
replaceSpec.path,
replaceSpec.regex,
replaceSpec.replacement
)
)
);
grunt.task.run(['default']);
});
async function replaceAndAdd(path, regex, value) {
let content = grunt.file.read(path);
content = content.replace(regex, value);
grunt.file.write(path, content);
await git.add(path);
}
};