aboutsummaryrefslogtreecommitdiffstats
path: root/library/moment/tasks/transpile.js
diff options
context:
space:
mode:
Diffstat (limited to 'library/moment/tasks/transpile.js')
-rw-r--r--library/moment/tasks/transpile.js284
1 files changed, 284 insertions, 0 deletions
diff --git a/library/moment/tasks/transpile.js b/library/moment/tasks/transpile.js
new file mode 100644
index 000000000..d253407d1
--- /dev/null
+++ b/library/moment/tasks/transpile.js
@@ -0,0 +1,284 @@
+module.exports = function (grunt) {
+ var esperanto = require('esperanto');
+ var path = require('path');
+ var Promise = require('es6-promise').Promise;
+ var TMP_DIR = 'build/tmp';
+
+ function moveComments(code) {
+ var comments = [], rest = [];
+ code.split('\n').forEach(function (line) {
+ if (line.trim().slice(0, 3) === '//!') {
+ comments.push(line.trim());
+ } else {
+ rest.push(line);
+ }
+ });
+
+ return comments.concat([''], rest).join('\n');
+ }
+
+ var headerCache = {};
+ function getHeaderByFile(headerFile) {
+ if (!(headerFile in headerCache)) {
+ headerCache[headerFile] = grunt.file.read(headerFile);
+ }
+ return headerCache[headerFile];
+ }
+
+ function transpile(opts) {
+ // base, entry, skip, headerFile, skipLines, target
+ var umdName = opts.headerFile ? 'not_used' : opts.umdName,
+ header = opts.headerFile ? getHeaderByFile(opts.headerFile) : '',
+ skipLines = opts.skipLines ? opts.skipLines : 0;
+
+ return esperanto.bundle({
+ base: opts.base,
+ entry: opts.entry,
+ skip: opts.skip || []
+ }).then(function (bundle) {
+ var umd = bundle.toUmd({name: umdName}),
+ fixed = header + umd.code.split('\n').slice(skipLines).join('\n');
+ if (opts.moveComments) {
+ fixed = moveComments(fixed);
+ }
+ grunt.file.write(opts.target, fixed);
+ });
+ }
+
+ function transpileMany(opts) {
+ var batchSize = 50,
+ promise = Promise.resolve(null),
+ files = grunt.file.expand({cwd: opts.base}, opts.pattern),
+ i,
+ transpileOne = function (i) {
+ promise = promise.then(function () {
+ return Promise.all(files.slice(i, i + batchSize).map(function (file) {
+ return transpile({
+ base: opts.base,
+ entry: file,
+ headerFile: opts.headerFile,
+ skip: opts.skip,
+ skipLines: opts.skipLines,
+ moveComments: opts.moveComments,
+ target: path.join(opts.targetDir, file)
+ });
+ }));
+ });
+ };
+
+ for (i = 0; i < files.length; i += batchSize) {
+ transpileOne(i);
+ }
+
+ return promise;
+ }
+
+ function prepareTemp(base) {
+ var files = grunt.file.expand({cwd: base}, '**/*.js'),
+ tmpDir = TMP_DIR;
+ if (grunt.file.exists(tmpDir)) {
+ return;
+ }
+ files.forEach(function (file) {
+ grunt.file.copy(path.join(base, file), path.join(tmpDir, file));
+ });
+ }
+
+ function transpileCode(opts) {
+ var entry = opts.entry || path.basename(opts.target);
+ prepareTemp(opts.base);
+ grunt.file.write(path.join(TMP_DIR, entry), opts.code);
+ return transpile({
+ base: TMP_DIR,
+ entry: entry,
+ umdName: opts.umdName || 'not_used',
+ headerFile: opts.headerFile,
+ skipLines: opts.skipLines,
+ moveComments: opts.moveComments,
+ target: opts.target,
+ skip: opts.skip
+ });
+ }
+
+ function generateLocales(target, localeFiles) {
+ var files = localeFiles,
+ code = files.map(function (file) {
+ var identifier = path.basename(file, '.js').replace('-', '_');
+ return 'import ' + identifier + ' from "./' + file + '";';
+ }).join('\n');
+ return transpileCode({
+ base: 'src',
+ code: code,
+ target: target,
+ skip: ['moment'],
+ headerFile: 'templates/locale-header.js',
+ skipLines: 5
+ });
+ }
+
+ function generateMomentWithLocales(target, localeFiles) {
+ var files = localeFiles,
+ importCode = files.map(function (file) {
+ var identifier = path.basename(file, '.js').replace('-', '_');
+ var fileNoExt = file.replace('.js', '');
+ return 'import ' + identifier + ' from "./' + fileNoExt + '";';
+ }).join('\n'),
+ code = 'import * as moment_export from "./moment";\n\n' +
+ importCode + '\n\n' +
+ 'export default moment_export;';
+
+ return transpileCode({
+ base: 'src',
+ code: code,
+ umdName: 'moment',
+ target: target
+ }).then(function () {
+ var code = grunt.file.read(target);
+ var getDefaultRegExp = new RegExp('var ([a-z$_]+) =\\s+{[^]\\s+get default \\(\\) { return ([a-z$_]+); }[^]\\s+}', '');
+ var crap = code.match(getDefaultRegExp);
+ if (crap.length !== 3) {
+ grunt.file.write('/tmp/crap.js', code);
+ throw new Error('Failed to detect get default crap, check /tmp/crap.js');
+ }
+ code = code.replace(getDefaultRegExp, '');
+
+ var buildExportVars = ['moment_with_locales', 'moment_with_locales_custom'];
+ buildExportVars.forEach(function (buildExportVar) {
+ var languageReset = buildExportVar + '.locale(\'en\');';
+ code = code.replace('var ' + buildExportVar + ' = ' + crap[1] + ';',
+ 'var ' + buildExportVar + ' = ' + crap[2] + ';\n' +
+ ' ' + languageReset);
+ });
+
+ if (code.match('get default')) {
+ grunt.file.write('/tmp/crap.js', code);
+ throw new Error('Stupid shit es6 get default plaguing the code, check /tmp/crap.js');
+ }
+ grunt.file.write(target, code);
+ });
+ }
+
+ grunt.task.registerTask('transpile-raw', 'convert es6 to umd', function () {
+ var done = this.async();
+
+ transpile({
+ base: 'src',
+ entry: 'moment.js',
+ umdName: 'moment',
+ target: 'build/umd/moment.js',
+ moveComments: true
+ }).then(function () {
+ grunt.log.ok('build/umd/moment.js');
+ }).then(function () {
+ return transpileMany({
+ base: 'src',
+ pattern: 'locale/*.js',
+ headerFile: 'templates/locale-header.js',
+ skipLines: 5,
+ moveComments: true,
+ targetDir: 'build/umd',
+ skip: ['moment']
+ });
+ }).then(function () {
+ grunt.log.ok('build/umd/locale/*.js');
+ }).then(function () {
+ return transpileMany({
+ base: 'src',
+ pattern: 'test/moment/*.js',
+ headerFile: 'templates/test-header.js',
+ skipLines: 5,
+ moveComments: true,
+ targetDir: 'build/umd',
+ skip: ['moment']
+ });
+ }).then(function () {
+ grunt.log.ok('build/umd/test/moment/*.js');
+ }).then(function () {
+ return transpileMany({
+ base: 'src',
+ pattern: 'test/locale/*.js',
+ headerFile: 'templates/test-header.js',
+ skipLines: 5,
+ moveComments: true,
+ targetDir: 'build/umd',
+ skip: ['moment']
+ });
+ }).then(function () {
+ grunt.log.ok('build/umd/test/locale/*.js');
+ }).then(function () {
+ return generateLocales('build/umd/min/locales.js',
+ grunt.file.expand({cwd: 'src'}, 'locale/*.js'));
+ }).then(function () {
+ grunt.log.ok('build/umd/min/locales.js');
+ }).then(function () {
+ return generateMomentWithLocales('build/umd/min/moment-with-locales.js',
+ grunt.file.expand({cwd: 'src'}, 'locale/*.js'));
+ }).then(function () {
+ grunt.log.ok('build/umd/min/moment-with-locales.js');
+ }).then(done, function (e) {
+ grunt.log.error('error transpiling', e);
+ done(e);
+ });
+ });
+
+ grunt.task.registerTask('transpile-custom-raw',
+ 'build just custom language bundles',
+ function (locales) {
+ var done = this.async();
+
+ var localeFiles = locales.split(',').map(function (locale) {
+ var file = grunt.file.expand({cwd: 'src'}, 'locale/' + locale + '.js');
+ if (file.length !== 1) {
+ // we failed to find a locale
+ done(new Error('could not find locale: ' + locale));
+ done = null;
+ } else {
+ return file[0];
+ }
+ });
+
+ // There was an issue with a locale
+ if (done == null) {
+ return;
+ }
+
+ return generateLocales(
+ 'build/umd/min/locales.custom.js', localeFiles
+ ).then(function () {
+ grunt.log.ok('build/umd/min/locales.custom.js');
+ }).then(function () {
+ return generateMomentWithLocales('build/umd/min/moment-with-locales.custom.js',
+ localeFiles);
+ }).then(function () {
+ grunt.log.ok('build/umd/min/moment-with-locales.custom.js');
+ }).then(done, function (e) {
+ grunt.log.error('error transpiling-custom', e);
+ done(e);
+ });
+ });
+
+ grunt.config('clean.build', [
+ 'build'
+ ]);
+
+ grunt.config('concat.tests', {
+ src: 'build/umd/test/**/*.js',
+ dest: 'build/umd/min/tests.js'
+ });
+
+ grunt.task.registerTask('transpile',
+ 'builds all es5 files, optinally creating custom locales',
+ function (locales) {
+ var tasks = [
+ 'clean:build',
+ 'transpile-raw',
+ 'concat:tests'
+ ];
+
+ if (locales) {
+ tasks.push('transpile-custom-raw:' + locales);
+ }
+
+ grunt.task.run(tasks);
+ });
+};