Initial commit

This commit is contained in:
zhongjin
2020-06-15 10:58:47 +08:00
commit 4f1dfe7564
8590 changed files with 1516878 additions and 0 deletions
+7
View File
@@ -0,0 +1,7 @@
module.exports = {
task: function () {
return {
tasks: {}
};
}
};
+62
View File
@@ -0,0 +1,62 @@
var bundles = require('../files/browserify_files');
module.exports = {
task: function () {
var cfg = {};
for (var name in bundles) {
var bundle = bundles[name];
var options = {
transform: [
[
'stringify', {
appliesTo: {
includeExtensions: ['.mustache']
}
}
],
[
'babelify', {
'presets': ['es2015'],
'extensions': ['.babel']
}
]
],
// enables watchify when grunt is run with a watch task
// must be evaluated lazily (using template var) to allow override by setConfig task.
watch: '<%= env.browserify_watch %>',
browserifyOptions: {
debug: true,
cache: {}
}
};
if (bundle.options) {
if (bundle.options.transform) {
options.transform = options.transform.concat(bundle.options.transform);
}
if (bundle.options.external) {
options.external = bundle.options.external;
}
if (bundle.options.require) {
options.require = bundle.options.require;
}
if (bundle.options.plugin) {
options.plugin = bundle.options.plugin;
}
if (bundle.options.cache) {
options.cache = bundle.options.cache;
}
}
cfg[name] = {
src: bundle.src,
dest: bundle.dest || ('<%= editor_assets_dir %>/javascripts/' + name + '.js'),
options: options
};
}
return cfg;
}
};
+19
View File
@@ -0,0 +1,19 @@
/**
* Clean task config
*/
exports.task = function () {
return {
options: {
force: true
},
dist: [
'.grunt',
'.sass-cache',
'tmp/sass',
'lib/build/app_config.js',
'<%= assets_dir %>',
'<%= editor_assets_dir %>'
]
};
};
+31
View File
@@ -0,0 +1,31 @@
/**
* Compass task config
*/
exports.task = function () {
return {
dist: {
options: {
importPath: [
'tmp/sass/cartoassets'
],
sassDir: 'tmp/sass/editor',
cssDir: '<%= editor_assets_dir %>/stylesheets',
fontsDir: '<%= editor_assets_dir %>/fonts',
httpFontsPath: '<%= env.http_path_prefix %>/assets/editor/<%= editor_assets_version %>/fonts',
imagesDir: 'app/assets/images/',
generatedImagesDir: '<%= editor_assets_dir %>/images/',
httpImagesPath: '<%= env.http_path_prefix %>/assets/editor/<%= editor_assets_version %>/images/',
httpGeneratedImagesPath: '<%= env.http_path_prefix %>/assets/editor/<%= editor_assets_version %>/images/',
environment: 'production',
outputStyle: 'compressed',
noLineComments: true,
force: false,
time: true,
raw: 'Encoding.default_external = \'utf-8\'\n'
}
}
};
};
+24
View File
@@ -0,0 +1,24 @@
exports.task = function () {
return {
main: {
options: {
archive: '<%= public_dir %>/static.tar.gz'
},
files: [
{
expand: true,
cwd: '<%= public_dir %>',
dest: '/',
src: [
'*.html',
'crossdomain.xml',
'robots.txt',
'static/**',
'maintenance/**',
'favicons/**'
]
}
]
}
};
};
+24
View File
@@ -0,0 +1,24 @@
/**
* Concat assets generation task
*/
var srcToDestHash = function (files, basePath, fileExt) {
var hash = {};
for (var f in files) {
if (f[0] !== '_') {
hash[basePath + f + fileExt] = files[f];
}
}
return hash;
};
exports.task = function () {
return {
js: {
files: srcToDestHash(require('../files/js_files'), '<%= editor_assets_dir %>/javascripts/', '.js')
},
css: {
files: srcToDestHash(require('../files/css_files'), '<%= editor_assets_dir %>/stylesheets/', '.css')
}
};
};
+54
View File
@@ -0,0 +1,54 @@
const DEFAULT_CONFIG = {
livereload: false,
hostname: '0.0.0.0', // to be able to access the server not only from localhost
base: {
path: '.'
}
};
function generateConfig (cfg) {
return Object.assign({}, DEFAULT_CONFIG, cfg);
}
module.exports = {
task: function () {
return {
server: {
options: {
port: 8089,
livereload: false,
open: 'http://localhost:8089/editor_specs.html',
hostname: '0.0.0.0', // to be able to access the server not only from localhost
base: {
path: '.'
}
}
},
// For Headless chrome tests (grunt test)
test: {
options: {
port: 8088,
livereload: false,
hostname: '0.0.0.0', // to be able to access the server not only from localhost
base: {
path: '.'
}
}
},
// Watching the specs during development
specs_dashboard: {
options: generateConfig({
port: 8090,
open: 'http://localhost:8090/_SpecRunner_dashboard.html'
})
},
specs_builder: {
options: generateConfig({
port: 8088,
open: 'http://localhost:8088/_SpecRunner_builder.html'
})
}
};
}
};
+190
View File
@@ -0,0 +1,190 @@
/**
* Copy task config
*/
exports.task = function (grunt) {
return {
vendor: {
expand: true,
cwd: 'vendor/assets/stylesheets/',
src: ['**/*.css'],
dest: 'tmp/sass/vendor/',
rename: function (dest, src) {
return dest + src.replace(/\.css$/, '.scss');
},
options: {
// Change all routes from img to asset version path
process: function (content, srcpath) {
// return content.replace(/\.\.\/img/gi,"/assets/<%= pkg.version %>/images/themes");
var path = grunt.template.process('<%= env.http_path_prefix %>/assets/editor/<%= editor_assets_version %>/images/themes');
return content.replace(/\.\.\/img/gi, path);
}
}
},
app: {
files: [{
expand: true,
dot: true,
cwd: 'node_modules/cartoassets/src/fonts',
src: '**/*.*',
dest: '<%= editor_assets_dir %>/fonts/'
}, {
expand: true,
cwd: 'node_modules/cartoassets/src/scss/',
src: '**/*.scss',
dest: 'tmp/sass/cartoassets/'
}, {
expand: true,
cwd: 'node_modules/bootstrap-colorpicker/dist/css/',
src: 'bootstrap-colorpicker.css',
dest: 'tmp/sass/colorpicker/bootstrap-colorpicker/',
rename: function (dest, src) {
return dest + src.replace(/\.css$/, '.scss');
}
}, {
expand: true,
cwd: 'app/assets/stylesheets/deep-insights/themes/scss',
src: '**/*.scss',
dest: 'tmp/sass/deep-insights/'
}, {
expand: true,
cwd: 'node_modules/internal-carto.js/themes/scss',
src: '**/*.scss',
dest: 'tmp/sass/cartodbjs_v4/'
}, {
expand: true,
cwd: 'lib/assets/javascripts/cdb/themes/css/',
src: ['cartodb.css'],
dest: '<%= editor_assets_dir %>/stylesheets/tmp/embeds/',
rename: function (dest, src) {
return dest + src.replace(/\.css$/, '.scss');
}
}, {
// Client stylesheets
expand: true,
cwd: 'app/assets/client/stylesheets/',
src: ['**/*.scss'],
dest: 'tmp/sass/client/',
rename: function (dest, src) {
return dest + src.replace(/\.css.scss$/, '.scss');
}
}, {
expand: true,
cwd: 'app/assets/images/',
src: ['**/*'],
dest: '<%= editor_assets_dir %>/images/'
}, {
// Some images should be placed in a unversioned folder
expand: true,
cwd: 'app/assets/images/',
src: ['avatars/*.png', 'alphamarker.png', 'google-maps-basemap-icons/*.jpg', 'carto.png'],
dest: '<%= root_assets_dir %>/unversioned/images/'
}, {
// CARTO.js images
expand: true,
cwd: 'lib/assets/javascripts/cdb/themes/img/',
src: ['**/*'],
dest: '<%= editor_assets_dir %>/images/themes/'
}, {
// Fonts
expand: true,
cwd: 'app/assets/fonts/',
src: ['*.{svg,ttf,eot,woff,woff2}'],
dest: '<%= editor_assets_dir %>/fonts/'
}, {
// Client fonts
expand: true,
cwd: 'app/assets/client/fonts/',
src: ['*.{svg,ttf,eot,woff,woff2}'],
dest: '<%= editor_assets_dir %>/fonts/'
}, {
// Flash
expand: true,
cwd: 'app/assets/flash/',
src: ['**/*'],
dest: '<%= editor_assets_dir %>/flash/'
}, {
// Favicons
expand: true,
cwd: 'public/favicons/',
src: ['**/*'],
dest: '<%= editor_assets_dir %>/favicons/'
}, {
// Client favicons
expand: true,
cwd: 'app/assets/client/favicons/',
src: ['**/*'],
dest: '<%= editor_assets_dir %>/favicons/'
}]
},
css_cartodb: {
files: [{
// TODO: remove editor
expand: true,
cwd: 'app/assets/stylesheets',
src: [
'**/*.scss',
'!editor-3/**/*.scss',
'!new_dashboard/**/*.scss'
],
dest: 'tmp/sass/editor/',
rename: function (dest, src) {
return dest + src.replace(/\.css.scss$/, '.scss');
}
}]
},
css_builder: {
files: [{
// TODO: remove editor
expand: true,
cwd: 'app/assets/stylesheets/editor-3/',
src: ['**/*.scss'],
dest: 'tmp/sass/editor-3/'
}]
},
css_dashboard: {
files: [{
// TODO: remove editor
expand: true,
cwd: 'app/assets/stylesheets/new_dashboard/',
src: ['**/*.scss'],
dest: 'tmp/sass/new_dashboard/'
}]
},
css_vendor_builder: {
files: [{
expand: true,
cwd: 'node_modules/cartoassets/src/scss/',
src: '**/*.scss',
dest: 'tmp/sass/cartoassets/'
}, {
expand: true,
cwd: 'app/assets/stylesheets/deep-insights/themes/scss',
src: '**/*.scss',
dest: 'tmp/sass/deep-insights/'
}, {
expand: true,
cwd: 'node_modules/internal-carto.js/themes/scss',
src: '**/*.scss',
dest: 'tmp/sass/cartodbjs_v4/'
}]
},
js: {
files: [{
expand: true,
cwd: '<%= editor_assets_dir %>/javascripts/',
src: ['**/*.js'],
dest: '<%= editor_assets_dir %>/javascripts/',
rename: function (dest, src) {
return dest + src.replace(/\.js$/, '.uncompressed.js');
}
}]
}
};
};
+33
View File
@@ -0,0 +1,33 @@
var browserifyBundles = require('../files/browserify_files');
var _ = require('underscore');
/**
* Extracts inlined source map from files (browserify bundles in this case).
*
* Expected to be run after copy:js task
*/
exports.task = function () {
var excludedBundles = [
'test_specs_for_browserify_modules',
'dashboard_static',
'show_static',
'public_map_static'
];
var files = {};
for (var bundleName in browserifyBundles) {
if (!_.contains(excludedBundles, bundleName)) {
var filePath = '<%= editor_assets_dir %>/javascripts/' + bundleName + '.uncompressed.js';
files[filePath + '.map'] = filePath;
}
}
return {
bundle: {
options: {
strict: true // fail task if sourcemaps are missing
},
files: files
}
};
};
+62
View File
@@ -0,0 +1,62 @@
var js_files = require('../files/js_files');
const DEFAULT_CONFIG = {
browser: 'phantomjs',
headless: true,
timeout: 20000,
keepRunner: true,
// grunt:test (CI) always generates a server on port 8088
host: 'http://localhost:8088',
summary: true,
display: 'none',
helpers: js_files._spec_helpers3,
reportSlowerThan: 2000,
vendor: [
'node_modules/jasmine-ajax/lib/mock-ajax.js',
'node_modules/underscore/underscore-min.js'
]
};
const getJasmineConfig = (config) => (Object.assign({}, DEFAULT_CONFIG, config));
module.exports = {
cartodbui: {
src: js_files.all.concat([
'lib/build/user_data.js',
'<%= editor_assets_dir %>/javascripts/templates_mustache.js',
'<%= editor_assets_dir %>/javascripts/templates.js',
'lib/build/test_init.js']),
options: {
browser: 'phantomjs',
headless: true,
keepRunner: true, // do not delete the runner (added to gitignore anyway), makes sure the runner is up-to-date
outfile: '_SpecRunner.html',
host: 'http://localhost:8088',
summary: true,
display: 'none',
specs: js_files.specs,
helpers: ['http://maps.googleapis.com/maps/api/js?v=3.32&sensor=false'].concat(js_files._spec_helpers)
// '--remote-debugger-port': 9000
}
},
dashboard: {
options: getJasmineConfig({
outfile: '_SpecRunner_dashboard.html',
specs: [
'.grunt/dashboard_specs/vendor.affected-specs.js',
'.grunt/dashboard_specs/main.affected-specs.js'
]
})
},
builder: {
options: getJasmineConfig({
outfile: '_SpecRunner_builder.html',
specs: [
'.grunt/builder_specs/vendor.affected-specs.js',
'.grunt/builder_specs/main.affected-specs.js'
]
})
}
};
+51
View File
@@ -0,0 +1,51 @@
var jsFiles = require('../files/js_files');
var jsFiles_PATH_REGEX = /^lib\/assets\/javascripts\//;
var jsFiles_EXTENSION_REGEX = /\.jst\.ejs$/;
var MUSTACHE_EXTENSION_REGEX = /\.jst\.mustache/;
exports.task = function () {
return {
compile: {
options: {
processName: function (filename) {
return filename
.replace(jsFiles_PATH_REGEX, '')
.replace(jsFiles_EXTENSION_REGEX, '');
}
},
files: [
{
src: jsFiles._templates,
dest: '<%= editor_assets_dir %>/javascripts/templates.js'
}, {
src: jsFiles._public_map_templates,
dest: '<%= editor_assets_dir %>/javascripts/public_map_templates.js'
}, {
src: jsFiles._public_templates,
dest: '<%= editor_assets_dir %>/javascripts/public_templates.js'
}
]
},
mustache: {
options: {
processName: function (filename) {
return filename
.replace(jsFiles_PATH_REGEX, '')
.replace(MUSTACHE_EXTENSION_REGEX, '');
},
template: function (source) {
var src = source.replace(/\n/g, '\\n').replace(/'/g, '\\\'');
return {
source: 'cdb.core.Template.compile(\'' + src + '\', \'mustache\')'
};
}
},
files: [
{
'<%= editor_assets_dir %>/javascripts/templates_mustache.js': jsFiles._templates_mustache
}
]
}
};
};
+78
View File
@@ -0,0 +1,78 @@
function alldeps (mod, deps, name, parentVersion) {
name = name || mod.name;
return Object.keys(mod.dependencies).reduce(function (all, dependency) {
if (!all.hasOwnProperty(dependency)) {
all[dependency] = {};
}
var version = mod.dependencies[dependency].version;
var resolved = mod.dependencies[dependency].resolved;
if (!all[dependency].hasOwnProperty(version)) {
all[dependency][resolved] = {};
}
all[dependency][resolved][name] = parentVersion || version;
if (mod.dependencies[dependency].dependencies) {
alldeps(mod.dependencies[dependency], all, dependency, version);
}
return all;
}, deps || {});
}
/**
* Checks all modules dependencies versions within a package-lock to not be
* duplicated from different parent dependencies.
*
* For instance if there are a couple of dependencies using a different version
* of backbone it will return backbone with its parent dependencies.
*/
function duplicatedDependencies (lockFileContent, modulesToValidate) {
var all = alldeps(lockFileContent);
modulesToValidate = modulesToValidate || Object.keys(all);
return modulesToValidate.reduce(function (duplicatedMods, mod) {
if (all[mod] === undefined) {
console.error('!!! ERROR !!!');
console.error('Trying to get all dependencies from ', mod, ' but it does not exist.');
console.error('!!! ERROR !!!');
}
var modVersions = Object.keys(all[mod]);
if (modVersions.length > 1) {
var invalidMod = { name: mod, versions: [] };
modVersions.forEach(function (modVersion) {
invalidMod.versions.push({version: modVersion, from: all[mod][modVersion]});
});
duplicatedMods.push(invalidMod);
}
return duplicatedMods;
}, []);
}
/**
* Checks if the version of a package-lock file matches with the version of another lock file.
* It is necessary to pass the modules to validate.
*
* It will return the modules where the version differs.
*/
function dependenciesVersion (lockFileContentOne, lockFileContentTwo, modulesToValidate) {
var allDependenciesOne = alldeps(lockFileContentOne);
var allDependenciesTwo = alldeps(lockFileContentTwo);
return modulesToValidate.reduce(function (depWithDiffVer, mod) {
var verDepFromOne = Object.keys(allDependenciesOne[mod])[0];
var verDepFromTwo = Object.keys(allDependenciesTwo[mod])[0];
if (verDepFromOne !== verDepFromTwo) {
depWithDiffVer.push(mod);
}
return depWithDiffVer;
}, []);
}
module.exports = {
checkDuplicatedDependencies: duplicatedDependencies,
checkDependenciesVersion: dependenciesVersion
};
+38
View File
@@ -0,0 +1,38 @@
module.exports = {
task: function () {
return {};
},
register: function (grunt, ASSETS_DIR) {
grunt.registerTask('manifest', 'creates rails manifest', function () {
var assets = grunt.template.process(ASSETS_DIR);
var version = grunt.template.process('<%= pkg.version %>');
var s = assets + '/**/*';
var mapping = grunt.file.expandMapping(s);
var manifest = assets.replace(version, '') + '/manifest.yml';
var minify_js = grunt.config.get('env').use_minify;
grunt.file.write(manifest, '---\n' + mapping.filter(function (s) {
return !grunt.file.isDir(s.src[0]);
}).map(function (s) {
function fixResource (p) {
return p.replace(assets + '/', '')
.replace('javascripts/', '')
.replace('stylesheets/', '')
.replace('images/', '');
}
function fixPath (p) {
p = p.replace(assets, version);
if (minify_js) {
p = p.replace('.js', '.min.js');
}
return p;
}
return fixResource(s.src[0]) + ': ' + fixPath(s.dest);
}).join('\n'));
grunt.log.write(manifest + ' generated');
});
}
};
+142
View File
@@ -0,0 +1,142 @@
module.exports = {
task: function () {
return {
options: {
accessKeyId: '<%= aws.key%>',
secretAccessKey: '<%= aws.secret %>',
bucket: '<%= aws.bucket %>'
},
frozen: {
options: {
headers: {
'CacheControl': 'max-age=630720000, public',
'Expires': new Date(Date.now() + 63072000000).toUTCString()
},
gzip: true
},
cwd: '<%= editor_assets_dir %>',
src: [
'javascripts/*.js',
'javascripts/**/*.map',
'!javascripts/all.js',
'stylesheets/*.css',
'!stylesheets/all_css.css',
'images/**/*',
'fonts/*',
'flash/*.swf',
'favicons/*'
],
dest: 'cartodbui/assets/editor/<%= editor_assets_version %>/'
},
js: {
options: {
headers: {
'CacheControl': 'max-age=630720000, public',
'Expires': new Date(Date.now() + 63072000000).toUTCString()
},
gzip: true
},
cwd: '<%= assets_dir %>',
src: [
'javascripts/*.js',
'javascripts/**/*.map',
'!javascripts/all.js'
],
dest: 'cartodbui/assets/<%= pkg.version %>/'
},
css: {
options: {
headers: {
'CacheControl': 'max-age=630720000, public',
'Expires': new Date(Date.now() + 63072000000).toUTCString()
},
gzip: true
},
cwd: '<%= assets_dir %>',
src: [
'stylesheets/*.css',
'!stylesheets/all_css.css'
],
dest: 'cartodbui/assets/<%= pkg.version %>/'
},
images: {
options: {
headers: {
'CacheControl': 'max-age=630720000, public',
'Expires': new Date(Date.now() + 63072000000).toUTCString()
}
},
cwd: '<%= assets_dir %>',
src: 'images/**/*',
dest: 'cartodbui/assets/<%= pkg.version %>/'
},
fonts: {
options: {
headers: {
'CacheControl': 'max-age=630720000, public',
'Expires': new Date(Date.now() + 63072000000).toUTCString()
}
},
cwd: '<%= assets_dir %>',
src: 'fonts/*',
dest: 'cartodbui/assets/<%= pkg.version %>/'
},
flash: {
options: {
headers: {
'CacheControl': 'max-age=630720000, public',
'Expires': new Date(Date.now() + 63072000000).toUTCString()
}
},
cwd: '<%= assets_dir %>',
src: 'flash/*.swf',
dest: 'cartodbui/assets/<%= pkg.version %>/'
},
favicons: {
options: {
headers: {
'CacheControl': 'max-age=630720000, public',
'Expires': new Date(Date.now() + 63072000000).toUTCString()
}
},
cwd: '<%= assets_dir %>',
src: 'favicons/*',
dest: 'cartodbui/assets/<%= pkg.version %>/'
},
unversioned: {
options: {
headers: {
'CacheControl': 'max-age=864000, public',
'Expires': new Date(Date.now() + 86400000).toUTCString()
}
},
cwd: '<%= assets_dir %>',
src: ['images/avatars/*.png', 'images/alphamarker.png', 'images/google-maps-basemap-icons/*.jpg', 'images/carto.png'],
dest: 'cartodbui/assets/unversioned/'
},
unversioned_onboarding: {
options: {
headers: {
'ContentType': 'application/octet-stream',
'CacheControl': 'max-age=864000, public',
'Expires': new Date(Date.now() + 86400000).toUTCString()
}
},
cwd: '<%= root_assets_dir %>',
src: ['unversioned/onboarding/*'],
dest: 'cartodbui/assets/'
},
static_pages: {
cwd: '<%= public_dir %>',
src: ['static.tar.gz'],
dest: 'cartodbui/'
}
};
}
};
+28
View File
@@ -0,0 +1,28 @@
/**
* Compass task config
*/
exports.task = function () {
return {
options: {
sourceMap: true,
sourceMapEmbed: true,
sourceMapContents: true,
includePaths: [
'node_modules/cartoassets/src/scss'
]
},
dist: {
files: [{
expand: true,
cwd: 'tmp/sass/',
src: [
'**/*.scss',
'!editor/**/*'
],
dest: '<%= editor_assets_dir %>/stylesheets',
ext: '.css'
}]
}
};
};
+72
View File
@@ -0,0 +1,72 @@
var jsBundles = require('../files/js_files');
var browserifyBundles = require('../files/browserify_files');
var _ = require('underscore');
exports.task = function () {
var js = {};
var bundleName;
var excludedBundles = [
'test_specs_for_browserify_modules',
'dashboard_static',
'profile_static',
'show_static',
'public_map_static',
'embed_map_static',
'account_static'
];
// Files to be uglified that are created outside of this process
var files = [
'templates',
'templates_mustache'
];
for (var i in files) {
var f = files[i];
if (f[0] !== '_' && f !== 'all') {
js['<%= editor_assets_dir %>/javascripts/' + f + '.js'] = ['<%= editor_assets_dir %>/javascripts/' + f + '.uncompressed.js'];
}
}
// Bundle definitions, concat'ed and uglified in one go
for (bundleName in jsBundles) {
var src = jsBundles[bundleName];
if (bundleName[0] !== '_' && bundleName !== 'all') {
js['<%= editor_assets_dir %>/javascripts/' + bundleName + '.js'] = src;
}
}
var defaultOptions = {
sourceMap: true,
banner: '/*! v<%= pkg.version %> - <%= grunt.template.today("yyyy-mm-dd") %> */'
};
var cfg = {
production: {
options: _.extend({
sourceMapIncludeSources: true
}, defaultOptions),
files: js
}
};
// Uglify browserify bundles too, but maintain original sourcemaps (expected to be extracted by 'exorcise' task, prior to this task)
for (bundleName in browserifyBundles) {
if (!_.contains(excludedBundles, bundleName)) {
files = {};
var basePath = '<%= editor_assets_dir %>/javascripts/' + bundleName;
var filePath = basePath + '.uncompressed.js';
files[basePath + '.js'] = [filePath];
cfg[bundleName] = {
options: _.extend({
sourceMapIn: filePath + '.map'
}, defaultOptions),
files: files
};
}
}
return cfg;
};
+78
View File
@@ -0,0 +1,78 @@
/**
* Watch/listen for assets
*/
exports.task = function () {
return {
css: {
files: [
'app/assets/stylesheets/editor-3/**/*.scss',
'app/assets/stylesheets/deep-insights/**/*.scss',
'app/assets/stylesheets/new_dashboard/**/*.scss',
'node_modules/cartoassets/src/scss/**/*.scss',
'node_modules/internal-carto.js/themes/scss/**/*.scss'
],
tasks: [
'copy:css_vendor_builder',
'copy:css_builder',
'copy:css_dashboard',
'sass',
'concat:css'
],
options: {
spawn: false,
atBegin: false
}
},
js_affected: {
files: [
'lib/assets/javascripts/builder/**/*',
'lib/assets/test/spec/builder/**/*',
'lib/assets/javascripts/deep-insights/**/*',
'lib/assets/test/spec/deep-insights/**/*',
'lib/assets/javascripts/locale/*'
],
tasks: [
'generate_builder_specs',
'webpack:builder_specs',
'jasmine:builder:build'
],
options: {
spawn: false,
atBegin: false
}
},
dashboard_specs: {
files: [
'lib/assets/javascripts/dashboard/**/*',
'lib/assets/test/spec/dashboard/**/*',
'lib/assets/javascripts/locale/*',
'lib/assets/test/spec/fixtures/**/*'
],
tasks: [
'generate_dashboard_specs',
'webpack:dashboard_specs',
'jasmine:dashboard:build'
],
options: {
spawn: false,
atBegin: false
}
},
js_affected_editor: {
files: [
'lib/assets/javascripts/cartodb/**/*',
'lib/assets/test/spec/cartodb/**/*'
],
tasks: [
'concat:js',
'jst',
'jasmine:cartodbui:build'
],
options: {
spawn: false,
atBegin: false
}
}
};
};
+103
View File
@@ -0,0 +1,103 @@
var path = require('path');
var webpack = require('webpack');
/*
This function will be called with the config name (dashboard_specs, builder_spec) so
you have a change to customize webpack for each bundle.
*/
module.exports = {
task: function (config) {
return {
mode: 'development',
entry: {
main: [
// To be filled by grunt
]
},
output: {
path: path.resolve(path.resolve('.'), '.grunt', config),
filename: '[name].affected-specs.js'
},
resolve: {
symlinks: false,
modules: require('../../../../webpack/common/modules.js'),
alias: require('../../../../webpack/common/alias')
},
module: {
rules: [
{
test: /\.js$/,
loader: 'shim-loader',
query: {
shim: {
'html-css-sanitizer': {
exports: 'html'
}
}
}
},
{
test: /\.js$/,
loader: 'babel-loader',
include: [
path.resolve(path.resolve('.'), 'lib/assets/javascripts/carto-node'),
path.resolve(path.resolve('.'), 'lib/assets/test/spec/carto-node'),
path.resolve(path.resolve('.'), 'lib/assets/javascripts/dashboard'),
path.resolve(path.resolve('.'), 'lib/assets/javascripts/builder'),
path.resolve(path.resolve('.'), 'lib/assets/test/spec/dashboard'),
path.resolve(path.resolve('.'), 'lib/assets/test/spec/fixtures'),
path.resolve(path.resolve('.'), 'lib/assets/test/spec/builder'),
path.resolve(path.resolve('.'), 'node_modules/internal-carto.js')
],
options: {
presets: [
['es2015', { 'modules': false }]
],
plugins: ['transform-object-assign', 'transform-object-rest-spread']
}
},
{
test: /\.tpl$/,
use: 'tpl-loader'
},
{
test: /\.mustache$/,
use: 'raw-loader'
}
],
exprContextRegExp: /$^/,
exprContextCritical: false
},
optimization: {
splitChunks: {
cacheGroups: {
vendor: {
name: 'vendor',
chunks: 'all',
test: /[\\/]node_modules[\\/]/
}
}
}
},
plugins: [
new webpack.ProvidePlugin({
$: 'jquery',
jQuery: 'jquery',
L: 'leaflet',
'window.jQuery': 'jquery'
}),
new webpack.SourceMapDevToolPlugin({
filename: '[file].map',
exclude: /vendor/
}),
new webpack.DefinePlugin({
__ENV__: JSON.stringify('test')
})
],
target: 'web',
node: {
fs: 'empty'
}
};
}
};
+145
View File
@@ -0,0 +1,145 @@
var webpack = require('webpack');
var _ = require('underscore');
var colors = require('colors');
var pretty = require('prettysize');
var glob = require('glob');
var StatsWriterPlugin = require('webpack-stats-plugin').StatsWriterPlugin;
var configGenerator = require('./webpack.config.js').task;
var compiler = {};
var affectedSpecs = [];
var cache = {};
var paths = {
builder_specs: './lib/assets/test/spec/builder/**/*.spec.js',
dashboard_specs: './lib/assets/test/spec/dashboard/**/*.spec.js',
deep_insights_specs: './lib/assets/test/spec/deep-insights/**/*.spec.js'
};
// Filter a list of files with a string
// the string will be converted to a RegExp
function filterSpecs (affectedSpecs, match) {
const re = new RegExp(match);
return affectedSpecs.filter(specFile => {
const fileName = specFile.split(/spec\//)[1];
return re.test(fileName);
});
}
/**
* affected - To be used as part of a 'registerTask' Grunt definition
*/
var affected = function (option, grunt) {
var done = this.async();
affectedSpecs = [
'./lib/assets/javascripts/builder/components/form-components/index.js',
'./lib/assets/test/spec/builder/components/modals/add-analysis/analysis-options.spec.js',
'./lib/assets/test/spec/builder/routes/router.spec.js'
];
let allSpecs = glob.sync(paths.builder_specs).concat(glob.sync(paths.deep_insights_specs));
const match = grunt.option('match');
if (match) {
allSpecs = filterSpecs(allSpecs, match);
}
console.log(colors.yellow('All specs. ' + allSpecs.length + ' specs found.'));
affectedSpecs = affectedSpecs.concat(allSpecs);
affectedSpecs = _.uniq(affectedSpecs);
done();
};
/**
* dashboard - To be used as part of a 'registerTask' Grunt definition
*/
var dashboard = function (option, grunt) {
affectedSpecs = glob.sync(paths.dashboard_specs);
const match = grunt.option('match');
if (match) {
affectedSpecs = filterSpecs(affectedSpecs, match);
}
affectedSpecs = _.uniq(affectedSpecs);
console.log(colors.yellow('All specs. ' + affectedSpecs.length + ' specs found.'));
};
var bootstrap = function (config, grunt) {
if (!config) {
throw new Error('Please provide subconfiguration key for webpack.');
}
const cfg = configGenerator(config);
cfg.entry.main = affectedSpecs;
compiler[config] = webpack(cfg);
cache[config] = {};
compiler[config].apply(new webpack.CachePlugin(cache[config]));
// Flag stats === true -> write stats.json
if (grunt.option('stats')) {
compiler[config].apply(new StatsWriterPlugin({
transform: function (data, opts) {
var stats = opts.compiler.getStats().toJson({chunkModules: true});
return JSON.stringify(stats, null, 2);
}
}));
}
};
function logAssets (assets) {
_.each(assets, function (asset) {
var trace = asset.name;
trace += ' ' + pretty(asset.size);
console.log(colors.yellow(trace));
});
}
/**
* compile - To be used as part of a 'registerTask' Grunt definition
*/
var compile = function (config) {
if (!config) {
throw new Error('Please provide subconfiguration key for webpack.');
}
var done = this.async();
compiler[config].run(function (err, stats) {
if (err) {
console.error(err.stack || err);
if (err.details) {
console.error(err.details);
}
done();
return;
}
var info = stats.toJson();
if (stats.hasErrors()) {
console.error(colors.red(info.errors));
console.error('');
console.error('🔥 🔥 🔥 🔥 🔥 🔥 🔥 🔥 🔥 🔥 🔥 🔥 🔥 🔥 🔥 🔥 🔥 🔥 🔥 🔥');
console.error(colors.red('THERE WAS AN ERROR WHILE BUNDLING!!!'));
console.error('🔥 🔥 🔥 🔥 🔥 🔥 🔥 🔥 🔥 🔥 🔥 🔥 🔥 🔥 🔥 🔥 🔥 🔥 🔥 🔥');
}
if (!stats.hasErrors()) {
logAssets(info.assets);
console.log(colors.yellow('Time: ' + info.time));
}
done();
});
};
module.exports = {
affected: affected,
dashboard: dashboard,
bootstrap: bootstrap,
compile: compile
};