mixio 1.10.0
This commit is contained in:
105
blockly/scripts/gulpfiles/appengine_tasks.js
Normal file
105
blockly/scripts/gulpfiles/appengine_tasks.js
Normal file
@@ -0,0 +1,105 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2020 Google LLC
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileoverview Gulp script to deploy Blockly demos on appengine.
|
||||
*/
|
||||
|
||||
var gulp = require('gulp');
|
||||
|
||||
var fs = require('fs');
|
||||
var rimraf = require('rimraf');
|
||||
var path = require('path');
|
||||
var execSync = require('child_process').execSync;
|
||||
|
||||
var packageJson = require('../../package.json');
|
||||
|
||||
const demoTmpDir = '../_deploy';
|
||||
const demoStaticTmpDir = '../_deploy/static';
|
||||
|
||||
/**
|
||||
* Cleans and creates the tmp directory used for deploying.
|
||||
*/
|
||||
function prepareDeployDir(done) {
|
||||
// Clean directory if exists.
|
||||
if (fs.existsSync(demoTmpDir)) {
|
||||
rimraf.sync(demoTmpDir);
|
||||
}
|
||||
fs.mkdirSync(demoStaticTmpDir, { recursive: true });
|
||||
done()
|
||||
}
|
||||
|
||||
/**
|
||||
* Copies all files into static deploy directory except for those under
|
||||
* appengine.
|
||||
*/
|
||||
function copyStaticSrc(done) {
|
||||
execSync(`git archive HEAD | tar -x -C ${demoStaticTmpDir}`,
|
||||
{ stdio: 'inherit' });
|
||||
done()
|
||||
}
|
||||
|
||||
/**
|
||||
* Copies appengine files into deploy directory.
|
||||
*/
|
||||
function copyAppengineSrc() {
|
||||
const appengineSrc = [
|
||||
path.join(demoStaticTmpDir, 'appengine/**/*'),
|
||||
path.join(demoStaticTmpDir, 'appengine/.gcloudignore'),
|
||||
];
|
||||
return gulp.src(appengineSrc).pipe(gulp.dest(demoTmpDir));
|
||||
}
|
||||
|
||||
/**
|
||||
* Copies playground deps into deploy directory.
|
||||
*/
|
||||
function copyPlaygroundDeps() {
|
||||
const playgroundDeps = [
|
||||
'./node_modules/@blockly/dev-tools/dist/index.js',
|
||||
'./node_modules/@blockly/theme-modern/dist/index.js',
|
||||
'./node_modules/@blockly/block-test/dist/index.js',
|
||||
];
|
||||
return gulp.src(playgroundDeps, {base: '.'}).pipe(gulp.dest(demoStaticTmpDir));
|
||||
}
|
||||
|
||||
/**
|
||||
* Deploys files from tmp directory to appengine to version based on the version
|
||||
* specified in package.json and then cleans the tmp directory.
|
||||
*/
|
||||
function deployAndClean(done) {
|
||||
const minorVersion = packageJson.version.split('.')[1];
|
||||
const patchVersion = packageJson.version.split('.')[2];
|
||||
let demoVersion = minorVersion;
|
||||
if (patchVersion != 0) {
|
||||
demoVersion += '-' + patchVersion
|
||||
}
|
||||
try {
|
||||
execSync(`gcloud app deploy --project blockly-demo --version ${demoVersion} --no-promote`, { stdio: 'inherit', cwd: demoTmpDir });
|
||||
} finally {
|
||||
// Clean up tmp directory.
|
||||
if (fs.existsSync(demoTmpDir)) {
|
||||
rimraf.sync(demoTmpDir);
|
||||
}
|
||||
}
|
||||
done();
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepares demos.
|
||||
*/
|
||||
const prepareDemos = gulp.series(
|
||||
prepareDeployDir, copyStaticSrc, copyAppengineSrc, copyPlaygroundDeps);
|
||||
|
||||
|
||||
/**
|
||||
* Deploys demos.
|
||||
*/
|
||||
const deployDemos = gulp.series(prepareDemos, deployAndClean);
|
||||
|
||||
module.exports = {
|
||||
deployDemos: deployDemos,
|
||||
prepareDemos: prepareDemos
|
||||
}
|
||||
522
blockly/scripts/gulpfiles/build_tasks.js
Normal file
522
blockly/scripts/gulpfiles/build_tasks.js
Normal file
@@ -0,0 +1,522 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2018 Google LLC
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileoverview Gulp script to build Blockly for Node & NPM.
|
||||
*/
|
||||
|
||||
var gulp = require('gulp');
|
||||
gulp.replace = require('gulp-replace');
|
||||
gulp.rename = require('gulp-rename');
|
||||
gulp.sourcemaps = require('gulp-sourcemaps');
|
||||
|
||||
var path = require('path');
|
||||
var fs = require('fs');
|
||||
var execSync = require('child_process').execSync;
|
||||
var through2 = require('through2');
|
||||
|
||||
var closureCompiler = require('google-closure-compiler').gulp();
|
||||
var closureDeps = require('google-closure-deps');
|
||||
var argv = require('yargs').argv;
|
||||
var { getPackageJson } = require('./helper_tasks');
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// Build //
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
const licenseRegex = `\\/\\*\\*
|
||||
\\* @license
|
||||
\\* (Copyright \\d+ (Google LLC|Massachusetts Institute of Technology))
|
||||
( \\* All rights reserved.
|
||||
)? \\* SPDX-License-Identifier: Apache-2.0
|
||||
\\*\\/`;
|
||||
|
||||
/**
|
||||
* Helper method for stripping the Google's and MIT's Apache Licenses.
|
||||
*/
|
||||
function stripApacheLicense() {
|
||||
// Strip out Google's and MIT's Apache licences.
|
||||
// Closure Compiler preserves dozens of Apache licences in the Blockly code.
|
||||
// Remove these if they belong to Google or MIT.
|
||||
// MIT's permission to do this is logged in Blockly issue #2412.
|
||||
return gulp.replace(new RegExp(licenseRegex, "g"), '\n\n\n\n');
|
||||
// Replace with the same number of lines so that source-maps are not affected.
|
||||
}
|
||||
|
||||
/**
|
||||
* Closure compiler warning groups used to treat warnings as errors.
|
||||
* For a full list of closure compiler groups, consult:
|
||||
* https://github.com/google/closure-compiler/blob/master/src/com/google/javascript/jscomp/DiagnosticGroups.java#L113
|
||||
*/
|
||||
var JSCOMP_ERROR = [
|
||||
'accessControls',
|
||||
'checkPrototypalTypes',
|
||||
'checkRegExp',
|
||||
'checkTypes',
|
||||
'checkVars',
|
||||
'conformanceViolations',
|
||||
'const',
|
||||
'constantProperty',
|
||||
'deprecated',
|
||||
'deprecatedAnnotations',
|
||||
'duplicateMessage',
|
||||
'es5Strict',
|
||||
'externsValidation',
|
||||
'extraRequire',
|
||||
'functionParams',
|
||||
'globalThis',
|
||||
'invalidCasts',
|
||||
'misplacedTypeAnnotation',
|
||||
// 'missingOverride',
|
||||
'missingPolyfill',
|
||||
'missingProperties',
|
||||
'missingProvide',
|
||||
// 'missingRequire', As of Jan 8 2021, this enables the strict require check.
|
||||
// Disabling this until we have fixed all the require issues.
|
||||
'missingReturn',
|
||||
// 'missingSourcesWarnings',
|
||||
'moduleLoad',
|
||||
'msgDescriptions',
|
||||
'nonStandardJsDocs',
|
||||
// 'polymer',
|
||||
// 'reportUnknownTypes',
|
||||
// 'strictCheckTypes',
|
||||
// 'strictMissingProperties',
|
||||
'strictModuleDepCheck',
|
||||
// 'strictPrimitiveOperators',
|
||||
// 'stricterMissingRequire',
|
||||
'suspiciousCode',
|
||||
'typeInvalidation',
|
||||
'undefinedNames',
|
||||
'undefinedVars',
|
||||
'underscore',
|
||||
'unknownDefines',
|
||||
'unusedLocalVariables',
|
||||
'unusedPrivateMembers',
|
||||
'uselessCode',
|
||||
'untranspilableFeatures',
|
||||
'visibility'
|
||||
];
|
||||
|
||||
/**
|
||||
* Helper method for calling the Closure compiler.
|
||||
* @param {*} compilerOptions
|
||||
* @param {boolean=} opt_verbose Optional option for verbose logging
|
||||
* @param {boolean=} opt_warnings_as_error Optional option for treating warnings
|
||||
* as errors.
|
||||
* @param {boolean=} opt_strict_typechecker Optional option for enabling strict
|
||||
* type checking.
|
||||
*/
|
||||
function compile(compilerOptions, opt_verbose, opt_warnings_as_error,
|
||||
opt_strict_typechecker) {
|
||||
const options = {};
|
||||
options.compilation_level = 'SIMPLE_OPTIMIZATIONS';
|
||||
options.warning_level = opt_verbose ? 'VERBOSE' : 'DEFAULT';
|
||||
options.language_out = 'ECMASCRIPT5_STRICT';
|
||||
options.rewrite_polyfills = false;
|
||||
options.hide_warnings_for = 'node_modules';
|
||||
if (opt_warnings_as_error || opt_strict_typechecker) {
|
||||
options.jscomp_error = JSCOMP_ERROR;
|
||||
if (opt_strict_typechecker) {
|
||||
options.jscomp_error.push('strictCheckTypes');
|
||||
}
|
||||
}
|
||||
|
||||
const platform = ['native', 'java', 'javascript'];
|
||||
|
||||
return closureCompiler({...options, ...compilerOptions}, { platform });
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method for possibly adding the Closure library into a sources array.
|
||||
* @param {Array<string>} srcs
|
||||
*/
|
||||
function maybeAddClosureLibrary(srcs) {
|
||||
if (argv.closureLibrary) {
|
||||
// If you require Google's Closure library, you can include it in your
|
||||
// build by adding the --closure-library flag.
|
||||
// You will also need to include the "google-closure-library" in your list
|
||||
// of devDependencies.
|
||||
console.log('Including the google-closure-library in your build.');
|
||||
if (!fs.existsSync('./node_modules/google-closure-library')) {
|
||||
throw Error('You must add the google-closure-library to your ' +
|
||||
'devDependencies in package.json, and run `npm install`.');
|
||||
}
|
||||
srcs.push('./node_modules/google-closure-library/closure/goog/**/**/*.js');
|
||||
}
|
||||
return srcs;
|
||||
}
|
||||
|
||||
/**
|
||||
* A helper method to return an closure compiler output wrapper that wraps the
|
||||
* body in a Universal Module Definition.
|
||||
* @param {string} namespace The export namespace.
|
||||
* @param {Array<Object>} dependencies An array of dependencies to inject.
|
||||
*/
|
||||
function outputWrapperUMD(namespace, dependencies) {
|
||||
const amdDeps = dependencies.map(d => '\'' + d.amd + '\'' ).join(', ');
|
||||
const cjsDeps = dependencies.map(d => `require('${d.cjs}')`).join(', ');
|
||||
const browserDeps = dependencies.map(d => 'root.' + d.name).join(', ');
|
||||
const imports = dependencies.map(d => d.name).join(', ');
|
||||
return `// Do not edit this file; automatically generated by gulp.
|
||||
|
||||
/* eslint-disable */
|
||||
;(function(root, factory) {
|
||||
if (typeof define === 'function' && define.amd) { // AMD
|
||||
define([${amdDeps}], factory);
|
||||
} else if (typeof exports === 'object') { // Node.js
|
||||
module.exports = factory(${cjsDeps});
|
||||
} else { // Browser
|
||||
root.${namespace} = factory(${browserDeps});
|
||||
}
|
||||
}(this, function(${imports}) {
|
||||
%output%
|
||||
return ${namespace};
|
||||
}));
|
||||
`;
|
||||
};
|
||||
|
||||
/**
|
||||
* This task builds Blockly's core files.
|
||||
* blockly_compressed.js
|
||||
*/
|
||||
function buildCompressed() {
|
||||
var packageJson = getPackageJson();
|
||||
const defines = 'Blockly.VERSION="' + packageJson.version + '"';
|
||||
return gulp.src(maybeAddClosureLibrary(['core/**/**/*.js']), {base: './'})
|
||||
.pipe(stripApacheLicense())
|
||||
.pipe(gulp.sourcemaps.init())
|
||||
// Directories in Blockly are used to group similar files together
|
||||
// but are not used to limit access with @package, instead the
|
||||
// method means something is internal to Blockly and not a public
|
||||
// API.
|
||||
// Flatten all files so they're in the same directory, but ensure that
|
||||
// files with the same name don't conflict.
|
||||
.pipe(gulp.rename(function(p) {
|
||||
var dirname = p.dirname.replace(
|
||||
new RegExp(path.sep.replace(/\\/, '\\\\'), "g"), "-");
|
||||
p.dirname = "";
|
||||
p.basename = dirname + "-" + p.basename;
|
||||
}))
|
||||
.pipe(compile(
|
||||
{
|
||||
dependency_mode: 'PRUNE',
|
||||
entry_point: './core-requires.js',
|
||||
js_output_file: 'blockly_compressed.js',
|
||||
externs: ['./externs/svg-externs.js', './externs/goog-externs.js'],
|
||||
define: defines,
|
||||
output_wrapper: outputWrapperUMD('Blockly', [])
|
||||
},
|
||||
argv.verbose, argv.debug, argv.strict))
|
||||
.pipe(gulp.sourcemaps.mapSources(function(sourcePath, file) {
|
||||
return sourcePath.replace(/-/g, '/');
|
||||
}))
|
||||
.pipe(
|
||||
gulp.sourcemaps.write('.', {includeContent: false, sourceRoot: './'}))
|
||||
.pipe(gulp.dest('./'));
|
||||
};
|
||||
|
||||
/**
|
||||
* This task builds the Blockly's built in blocks.
|
||||
* blocks_compressed.js
|
||||
*/
|
||||
function buildBlocks() {
|
||||
return gulp.src(['blocks/*.js'], {base: './'})
|
||||
.pipe(stripApacheLicense())
|
||||
.pipe(gulp.sourcemaps.init())
|
||||
.pipe(compile({
|
||||
dependency_mode: 'NONE',
|
||||
externs: ['./externs/goog-externs.js', './externs/block-externs.js'],
|
||||
js_output_file: 'blocks_compressed.js',
|
||||
output_wrapper: outputWrapperUMD('Blockly.Blocks', [{
|
||||
name: 'Blockly',
|
||||
amd: './blockly_compressed.js',
|
||||
cjs: './blockly_compressed.js'
|
||||
}])
|
||||
}, argv.verbose, argv.debug, argv.strict))
|
||||
.pipe(gulp.sourcemaps.write('.', {
|
||||
includeContent: false,
|
||||
sourceRoot: './'
|
||||
}))
|
||||
.pipe(gulp.dest('./'));
|
||||
};
|
||||
|
||||
/**
|
||||
* A helper method for building a Blockly code generator.
|
||||
* @param {string} language Generator language.
|
||||
* @param {string} namespace Language namespace.
|
||||
*/
|
||||
function buildGenerator(language, namespace) {
|
||||
return gulp.src([`generators/${language}.js`, `generators/${language}/*.js`], {base: './'})
|
||||
.pipe(stripApacheLicense())
|
||||
.pipe(gulp.sourcemaps.init())
|
||||
.pipe(compile({
|
||||
dependency_mode: 'NONE',
|
||||
externs: ['./externs/goog-externs.js', './externs/generator-externs.js'],
|
||||
js_output_file: `${language}_compressed.js`,
|
||||
output_wrapper: outputWrapperUMD(`Blockly.${namespace}`, [{
|
||||
name: 'Blockly',
|
||||
amd: './blockly_compressed.js',
|
||||
cjs: './blockly_compressed.js'
|
||||
}])
|
||||
}, argv.verbose, argv.debug, argv.strict))
|
||||
.pipe(gulp.sourcemaps.write('.', {
|
||||
includeContent: false,
|
||||
sourceRoot: './'
|
||||
}))
|
||||
.pipe(gulp.dest('./'));
|
||||
};
|
||||
|
||||
/**
|
||||
* This task builds the javascript generator.
|
||||
* javascript_compressed.js
|
||||
*/
|
||||
function buildJavascript() {
|
||||
return buildGenerator('javascript', 'JavaScript');
|
||||
};
|
||||
|
||||
/**
|
||||
* This task builds the python generator.
|
||||
* python_compressed.js
|
||||
*/
|
||||
function buildPython() {
|
||||
return buildGenerator('python', 'Python');
|
||||
};
|
||||
|
||||
/**
|
||||
* This task builds the php generator.
|
||||
* php_compressed.js
|
||||
*/
|
||||
function buildPHP() {
|
||||
return buildGenerator('php', 'PHP');
|
||||
};
|
||||
|
||||
/**
|
||||
* This task builds the lua generator.
|
||||
* lua_compressed.js
|
||||
*/
|
||||
function buildLua() {
|
||||
return buildGenerator('lua', 'Lua');
|
||||
};
|
||||
|
||||
/**
|
||||
* This task builds the dart generator:
|
||||
* dart_compressed.js
|
||||
*/
|
||||
function buildDart() {
|
||||
return buildGenerator('dart', 'Dart');
|
||||
};
|
||||
|
||||
/**
|
||||
* This tasks builds all the generators:
|
||||
* javascript_compressed.js
|
||||
* python_compressed.js
|
||||
* php_compressed.js
|
||||
* lua_compressed.js
|
||||
* dart_compressed.js
|
||||
*/
|
||||
const buildGenerators = gulp.parallel(
|
||||
buildJavascript,
|
||||
buildPython,
|
||||
buildPHP,
|
||||
buildLua,
|
||||
buildDart
|
||||
);
|
||||
|
||||
/**
|
||||
* This task builds Blockly's uncompressed file.
|
||||
* blockly_uncompressed.js
|
||||
*/
|
||||
function buildUncompressed() {
|
||||
const closurePath = argv.closureLibrary ?
|
||||
'node_modules/google-closure-library/closure/goog' :
|
||||
'closure/goog';
|
||||
const header = `// Do not edit this file; automatically generated by gulp.
|
||||
'use strict';
|
||||
|
||||
this.IS_NODE_JS = !!(typeof module !== 'undefined' && module.exports);
|
||||
|
||||
this.BLOCKLY_DIR = (function(root) {
|
||||
if (!root.IS_NODE_JS) {
|
||||
// Find name of current directory.
|
||||
var scripts = document.getElementsByTagName('script');
|
||||
var re = new RegExp('(.+)[\\\/]blockly_(.*)uncompressed\\\.js$');
|
||||
for (var i = 0, script; script = scripts[i]; i++) {
|
||||
var match = re.exec(script.src);
|
||||
if (match) {
|
||||
return match[1];
|
||||
}
|
||||
}
|
||||
alert('Could not detect Blockly\\'s directory name.');
|
||||
}
|
||||
return '';
|
||||
})(this);
|
||||
|
||||
this.BLOCKLY_BOOT = function(root) {
|
||||
// Execute after Closure has loaded.
|
||||
`;
|
||||
const footer = `
|
||||
delete root.BLOCKLY_DIR;
|
||||
delete root.BLOCKLY_BOOT;
|
||||
delete root.IS_NODE_JS;
|
||||
};
|
||||
|
||||
if (this.IS_NODE_JS) {
|
||||
this.BLOCKLY_BOOT(this);
|
||||
module.exports = Blockly;
|
||||
} else {
|
||||
document.write('<script src="' + this.BLOCKLY_DIR +
|
||||
'/${closurePath}/base.js"></script>');
|
||||
document.write('<script>this.BLOCKLY_BOOT(this);</script>');
|
||||
}
|
||||
`;
|
||||
|
||||
let deps = [];
|
||||
return gulp.src(maybeAddClosureLibrary(['core/**/**/*.js']))
|
||||
.pipe(through2.obj((file, _enc, cb) => {
|
||||
const result = closureDeps.parser.parseFile(file.path);
|
||||
for (const dep of result.dependencies) {
|
||||
deps.push(dep);
|
||||
}
|
||||
cb(null);
|
||||
}))
|
||||
.on('end', () => {
|
||||
// Update the path to closure for any files that we don't know the full path
|
||||
// of (parsed from a goog.addDependency call).
|
||||
for (const dep of deps) {
|
||||
dep.setClosurePath(closurePath);
|
||||
}
|
||||
|
||||
const addDependency = closureDeps.depFile
|
||||
.getDepFileText(closurePath, deps)
|
||||
.replace(/\\/g, '\/');
|
||||
|
||||
const requires = `goog.addDependency("base.js", [], []);
|
||||
|
||||
// Load Blockly.
|
||||
goog.require('Blockly.requires');
|
||||
`;
|
||||
fs.writeFileSync('blockly_uncompressed.js',
|
||||
header +
|
||||
addDependency +
|
||||
requires +
|
||||
footer);
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* This task builds Blockly's lang files.
|
||||
* msg/*.js
|
||||
*/
|
||||
function buildLangfiles(done) {
|
||||
// Run js_to_json.py
|
||||
const jsToJsonCmd = `python ./scripts/i18n/js_to_json.py \
|
||||
--input_file ${path.join('msg', 'messages.js')} \
|
||||
--output_dir ${path.join('msg', 'json')} \
|
||||
--quiet`;
|
||||
execSync(jsToJsonCmd, { stdio: 'inherit' });
|
||||
|
||||
// Run create_messages.py
|
||||
let json_files = fs.readdirSync(path.join('msg', 'json'));
|
||||
json_files = json_files.filter(file => file.endsWith('json') &&
|
||||
!(new RegExp(/(keys|synonyms|qqq|constants)\.json$/).test(file)));
|
||||
json_files = json_files.map(file => path.join('msg', 'json', file));
|
||||
const createMessagesCmd = `python ./scripts/i18n/create_messages.py \
|
||||
--source_lang_file ${path.join('msg', 'json', 'en.json')} \
|
||||
--source_synonym_file ${path.join('msg', 'json', 'synonyms.json')} \
|
||||
--source_constants_file ${path.join('msg', 'json', 'constants.json')} \
|
||||
--key_file ${path.join('msg', 'json', 'keys.json')} \
|
||||
--output_dir ${path.join('msg', 'js')} \
|
||||
--quiet ${json_files.join(' ')}`;
|
||||
execSync(createMessagesCmd, { stdio: 'inherit' });
|
||||
|
||||
done();
|
||||
};
|
||||
|
||||
/**
|
||||
* This task builds Blockly core, blocks and generators together and uses
|
||||
* closure compiler's ADVANCED_COMPILATION mode.
|
||||
*/
|
||||
function buildAdvancedCompilationTest() {
|
||||
const srcs = [
|
||||
'tests/compile/main.js', 'tests/compile/test_blocks.js', 'core/**/**/*.js',
|
||||
'blocks/*.js', 'generators/**/*.js'
|
||||
];
|
||||
return gulp.src(maybeAddClosureLibrary(srcs), {base: './'})
|
||||
.pipe(stripApacheLicense())
|
||||
.pipe(gulp.sourcemaps.init())
|
||||
// Directories in Blockly are used to group similar files together
|
||||
// but are not used to limit access with @package, instead the
|
||||
// method means something is internal to Blockly and not a public
|
||||
// API.
|
||||
// Flatten all files so they're in the same directory, but ensure that
|
||||
// files with the same name don't conflict.
|
||||
.pipe(gulp.rename(function(p) {
|
||||
if (p.dirname.indexOf('core') === 0) {
|
||||
var dirname = p.dirname.replace(
|
||||
new RegExp(path.sep.replace(/\\/, '\\\\'), "g"), "-");
|
||||
p.dirname = "";
|
||||
p.basename = dirname + "-" + p.basename;
|
||||
}
|
||||
}))
|
||||
.pipe(compile(
|
||||
{
|
||||
dependency_mode: 'PRUNE',
|
||||
compilation_level: 'ADVANCED_OPTIMIZATIONS',
|
||||
entry_point: './tests/compile/main.js',
|
||||
js_output_file: 'main_compressed.js',
|
||||
externs: ['./externs/svg-externs.js', './externs/goog-externs.js'],
|
||||
},
|
||||
argv.verbose, argv.strict))
|
||||
.pipe(gulp.sourcemaps.mapSources(function(sourcePath, file) {
|
||||
return sourcePath.replace(/-/g, '/');
|
||||
}))
|
||||
.pipe(gulp.sourcemaps.write(
|
||||
'.', {includeContent: false, sourceRoot: '../../'}))
|
||||
.pipe(gulp.dest('./tests/compile/'));
|
||||
}
|
||||
|
||||
/**
|
||||
* This tasks builds Blockly's core files:
|
||||
* blockly_compressed.js
|
||||
* blocks_compressed.js
|
||||
* blockly_uncompressed.js
|
||||
*/
|
||||
const buildCore = gulp.parallel(
|
||||
buildCompressed,
|
||||
buildBlocks,
|
||||
buildUncompressed
|
||||
);
|
||||
|
||||
/**
|
||||
* This task builds all of Blockly:
|
||||
* blockly_compressed.js
|
||||
* blocks_compressed.js
|
||||
* javascript_compressed.js
|
||||
* python_compressed.js
|
||||
* php_compressed.js
|
||||
* lua_compressed.js
|
||||
* dart_compressed.js
|
||||
* blockly_uncompressed.js
|
||||
* msg/json/*.js
|
||||
*/
|
||||
const build = gulp.parallel(
|
||||
buildCore,
|
||||
buildGenerators,
|
||||
buildLangfiles
|
||||
);
|
||||
|
||||
module.exports = {
|
||||
build: build,
|
||||
core: buildCore,
|
||||
blocks: buildBlocks,
|
||||
langfiles: buildLangfiles,
|
||||
uncompressed: buildUncompressed,
|
||||
compressed: buildCompressed,
|
||||
generators: buildGenerators,
|
||||
advancedCompilationTest: buildAdvancedCompilationTest,
|
||||
}
|
||||
85
blockly/scripts/gulpfiles/cleanup_tasks.js
Normal file
85
blockly/scripts/gulpfiles/cleanup_tasks.js
Normal file
@@ -0,0 +1,85 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2018 Google LLC
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileoverview Gulp tasks to complete various clean up tasks.
|
||||
*/
|
||||
|
||||
const gulp = require('gulp');
|
||||
const path = require('path');
|
||||
const through2 = require('through2');
|
||||
|
||||
/**
|
||||
* Sorts goog.requires in core, blocks and generators.
|
||||
*/
|
||||
function sortRequires() {
|
||||
const srcs = ['core/**/**/*.js', 'blocks/*.js', 'generators/**/*.js'];
|
||||
const excludes = ['core/requires.js'];
|
||||
return gulp.src(srcs, {base: './'})
|
||||
.pipe(through2.obj((file, _enc, next) => {
|
||||
if (file.isNull() || file.isDirectory()) {
|
||||
next(null, file);
|
||||
return;
|
||||
}
|
||||
|
||||
if (file.extname !== '.js' && path.extname(file.history[0]) !== '.js') {
|
||||
next(null, file);
|
||||
return;
|
||||
}
|
||||
|
||||
const relPath = path.relative(path.join(file.cwd, file.base), file.path);
|
||||
if (excludes.indexOf(relPath) > -1) {
|
||||
next(null, file);
|
||||
return;
|
||||
}
|
||||
|
||||
const contents = file.contents.toString();
|
||||
|
||||
// Capture requires.
|
||||
const re = /goog\.(require|requireType)\('(.*)'\);/gm;
|
||||
const requiresList = [];
|
||||
const requireTypesList = [];
|
||||
let firstIndex;
|
||||
let lastIndex;
|
||||
while ((match = re.exec(contents)) != null) {
|
||||
if (match[1] == 'require') requiresList.push(match[2]);
|
||||
if (match[1] == 'requireType') requireTypesList.push(match[2]);
|
||||
if (firstIndex == undefined) {
|
||||
firstIndex = match.index;
|
||||
} else {
|
||||
lastIndex = re.lastIndex;
|
||||
}
|
||||
}
|
||||
|
||||
// Sort requires.
|
||||
requiresList.sort(
|
||||
(a, b) => a.toLowerCase().localeCompare(b.toLowerCase()));
|
||||
requireTypesList.sort(
|
||||
(a, b) => a.toLowerCase().localeCompare(b.toLowerCase()));
|
||||
|
||||
// Replace in file.
|
||||
const requiresSection = requiresList.length ?
|
||||
requiresList.map(r => `goog.require('${r}');`).join('\n') + '\n\n' :
|
||||
'';
|
||||
const requireTypesSection = requireTypesList.length ?
|
||||
requireTypesList.map(r => `goog.requireType('${r}');`).join('\n') +
|
||||
'\n\n' :
|
||||
'';
|
||||
const requires = `${requiresSection}${requireTypesSection}\n`;
|
||||
|
||||
if (firstIndex != undefined & lastIndex != undefined) {
|
||||
file.contents = Buffer.from(
|
||||
contents.substring(0, firstIndex) + requires +
|
||||
contents.substring(lastIndex).trimStart());
|
||||
}
|
||||
next(null, file);
|
||||
}))
|
||||
.pipe(gulp.dest('./'));
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
sortRequires: sortRequires
|
||||
};
|
||||
121
blockly/scripts/gulpfiles/git_tasks.js
Normal file
121
blockly/scripts/gulpfiles/git_tasks.js
Normal file
@@ -0,0 +1,121 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2018 Google LLC
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileoverview Git-related gulp tasks for Blockly.
|
||||
*/
|
||||
|
||||
var gulp = require('gulp');
|
||||
var execSync = require('child_process').execSync;
|
||||
|
||||
var buildTasks = require('./build_tasks');
|
||||
|
||||
const upstream_url = "https://github.com/google/blockly.git";
|
||||
|
||||
// Stash current state, check out the named branch, and sync with
|
||||
// google/blockly.
|
||||
function syncBranch(branchName) {
|
||||
return function(done) {
|
||||
execSync('git stash save -m "Stash for sync"', { stdio: 'inherit' });
|
||||
checkoutBranch(branchName);
|
||||
execSync('git pull ' + upstream_url + ' ' + branchName,
|
||||
{ stdio: 'inherit' });
|
||||
execSync('git push origin ' + branchName, { stdio: 'inherit' });
|
||||
done();
|
||||
}
|
||||
}
|
||||
|
||||
// Stash current state, check out develop, and sync with google/blockly.
|
||||
function syncDevelop() {
|
||||
return syncBranch('develop');
|
||||
};
|
||||
|
||||
// Stash current state, check out master, and sync with google/blockly.
|
||||
function syncMaster() {
|
||||
return syncBranch('master');
|
||||
};
|
||||
|
||||
// Helper function: get a name for a rebuild branch. Format: rebuild_mm_dd_yyyy.
|
||||
function getRebuildBranchName() {
|
||||
var date = new Date();
|
||||
var mm = date.getMonth() + 1; // Month, 0-11
|
||||
var dd = date.getDate(); // Day of the month, 1-31
|
||||
var yyyy = date.getFullYear();
|
||||
return 'rebuild_' + mm + '_' + dd + '_' + yyyy;
|
||||
};
|
||||
|
||||
// Helper function: get a name for a rebuild branch. Format: rebuild_yyyy_mm.
|
||||
function getRCBranchName() {
|
||||
var date = new Date();
|
||||
var mm = date.getMonth() + 1; // Month, 0-11
|
||||
var yyyy = date.getFullYear();
|
||||
return 'rc_' + yyyy + '_' + mm;
|
||||
};
|
||||
|
||||
// If branch does not exist then create the branch.
|
||||
// If branch exists switch to branch.
|
||||
function checkoutBranch(branchName) {
|
||||
execSync('git checkout ' + branchName + ' || git checkout -b ' + branchName,
|
||||
{ stdio: 'inherit' });
|
||||
}
|
||||
|
||||
// Create and push an RC branch.
|
||||
// Note that this pushes to google/blockly.
|
||||
const createRC = gulp.series(
|
||||
syncDevelop(),
|
||||
function(done) {
|
||||
var branchName = getRCBranchName();
|
||||
execSync('git checkout -b ' + branchName, { stdio: 'inherit' });
|
||||
execSync('git push ' + upstream_url + ' ' + branchName,
|
||||
{ stdio: 'inherit' });
|
||||
done();
|
||||
}
|
||||
);
|
||||
|
||||
// Create the rebuild branch.
|
||||
function createRebuildBranch(done) {
|
||||
var branchName = getRebuildBranchName();
|
||||
console.log('make-rebuild-branch: creating branch ' + branchName);
|
||||
execSync('git checkout -b ' + branchName, { stdio: 'inherit' });
|
||||
done();
|
||||
}
|
||||
|
||||
// Push the rebuild branch to origin.
|
||||
function pushRebuildBranch(done) {
|
||||
console.log('push-rebuild-branch: committing rebuild');
|
||||
execSync('git commit -am "Rebuild"', { stdio: 'inherit' });
|
||||
var branchName = getRebuildBranchName();
|
||||
execSync('git push origin ' + branchName, { stdio: 'inherit' });
|
||||
console.log('Branch ' + branchName + ' pushed to GitHub.');
|
||||
console.log('Next step: create a pull request against develop.');
|
||||
done();
|
||||
}
|
||||
|
||||
// Update github pages with what is currently in develop.
|
||||
const updateGithubPages = gulp.series(
|
||||
function(done) {
|
||||
execSync('git stash save -m "Stash for sync"', { stdio: 'inherit' });
|
||||
execSync('git checkout gh-pages || git checkout -b gh-pages', { stdio: 'inherit' });
|
||||
execSync('git fetch upstream', { stdio: 'inherit' });
|
||||
execSync('git reset --hard upstream/develop', { stdio: 'inherit' });
|
||||
done();
|
||||
},
|
||||
buildTasks.build,
|
||||
function(done) {
|
||||
execSync('git commit -am "Rebuild"', { stdio: 'inherit' });
|
||||
execSync('git push ' + upstream_url + ' gh-pages --force', { stdio: 'inherit' });
|
||||
done();
|
||||
}
|
||||
);
|
||||
|
||||
module.exports = {
|
||||
syncDevelop: syncDevelop,
|
||||
syncMaster: syncMaster,
|
||||
createRC: createRC,
|
||||
updateGithubPages: updateGithubPages,
|
||||
createRebuildBranch: createRebuildBranch,
|
||||
pushRebuildBranch: pushRebuildBranch
|
||||
}
|
||||
19
blockly/scripts/gulpfiles/helper_tasks.js
Normal file
19
blockly/scripts/gulpfiles/helper_tasks.js
Normal file
@@ -0,0 +1,19 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2021 Google LLC
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileoverview Any gulp helper functions.
|
||||
*/
|
||||
|
||||
// Clears the require cache to ensure the package.json is up to date.
|
||||
function getPackageJson() {
|
||||
delete require.cache[require.resolve('../../package.json')]
|
||||
return require('../../package.json');
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
getPackageJson: getPackageJson
|
||||
}
|
||||
21
blockly/scripts/gulpfiles/license_tasks.js
Normal file
21
blockly/scripts/gulpfiles/license_tasks.js
Normal file
@@ -0,0 +1,21 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2018 Google LLC
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileoverview Gulp tasks to check the licenses of Blockly dependencies.
|
||||
*/
|
||||
|
||||
const jsgl = require('js-green-licenses');
|
||||
|
||||
function checkLicenses() {
|
||||
const checker = new jsgl.LicenseChecker();
|
||||
checker.setDefaultHandlers();
|
||||
return checker.checkLocalDirectory('.');
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
checkLicenses: checkLicenses
|
||||
};
|
||||
397
blockly/scripts/gulpfiles/package_tasks.js
Normal file
397
blockly/scripts/gulpfiles/package_tasks.js
Normal file
@@ -0,0 +1,397 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2018 Google LLC
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileoverview Gulp tasks to package Blockly for distribution on NPM.
|
||||
*/
|
||||
|
||||
var gulp = require('gulp');
|
||||
gulp.concat = require('gulp-concat');
|
||||
gulp.replace = require('gulp-replace');
|
||||
gulp.rename = require('gulp-rename');
|
||||
gulp.insert = require('gulp-insert');
|
||||
gulp.umd = require('gulp-umd');
|
||||
|
||||
var path = require('path');
|
||||
var fs = require('fs');
|
||||
var { getPackageJson } = require('./helper_tasks');
|
||||
|
||||
const blocklyRoot = '../../';
|
||||
|
||||
// The destination path where all the NPM distribution files will go.
|
||||
const packageDistribution = 'dist';
|
||||
|
||||
|
||||
/**
|
||||
* A helper method for wrapping a file into a Universal Module Definition.
|
||||
* @param {string} namespace The export namespace.
|
||||
* @param {Array<Object>} dependencies An array of dependencies to inject.
|
||||
*/
|
||||
function packageUMD(namespace, dependencies) {
|
||||
return gulp.umd({
|
||||
dependencies: function () { return dependencies; },
|
||||
namespace: function () { return namespace; },
|
||||
exports: function () { return namespace; },
|
||||
template: path.join(__dirname, `${blocklyRoot}/scripts/package/templates/umd.template`)
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* A helper method for wrapping a file into a CommonJS module for Node.js.
|
||||
* @param {string} namespace The export namespace.
|
||||
* @param {Array<Object>} dependencies An array of dependencies to inject.
|
||||
*/
|
||||
function packageCommonJS(namespace, dependencies) {
|
||||
return gulp.umd({
|
||||
dependencies: function () { return dependencies; },
|
||||
namespace: function () { return namespace; },
|
||||
exports: function () { return namespace; },
|
||||
template: path.join(__dirname, `${blocklyRoot}/scripts/package/templates/node.template`)
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* This task copies source files into the distribution directory.
|
||||
*/
|
||||
function packageSources() {
|
||||
return gulp.src(['core/**/**.js', 'blocks/**.js', 'generators/**/**.js'],
|
||||
{base: '.'})
|
||||
.pipe(gulp.dest(packageDistribution));
|
||||
};
|
||||
|
||||
/**
|
||||
* This task copies the compressed files and their source maps into the
|
||||
* distribution directory.
|
||||
*/
|
||||
function packageCompressed() {
|
||||
return gulp.src('*_compressed.js?(.map)')
|
||||
.pipe(gulp.dest(packageDistribution));
|
||||
};
|
||||
|
||||
/**
|
||||
* This task wraps scripts/package/blockly.js into a UMD module.
|
||||
* @example import 'blockly/blockly';
|
||||
*/
|
||||
function packageBlockly() {
|
||||
return gulp.src('scripts/package/blockly.js')
|
||||
.pipe(packageUMD('Blockly', [{
|
||||
name: 'Blockly',
|
||||
amd: './blockly_compressed',
|
||||
cjs: './blockly_compressed',
|
||||
}]))
|
||||
.pipe(gulp.rename('blockly.js'))
|
||||
.pipe(gulp.dest(packageDistribution));
|
||||
};
|
||||
|
||||
/**
|
||||
* This task wraps scripts/package/blocks.js into a UMD module.
|
||||
* @example import 'blockly/blocks';
|
||||
*/
|
||||
function packageBlocks() {
|
||||
return gulp.src('scripts/package/blocks.js')
|
||||
.pipe(packageUMD('Blockly.Blocks', [{
|
||||
name: 'Blockly',
|
||||
amd: './blocks_compressed',
|
||||
cjs: './blocks_compressed',
|
||||
}]))
|
||||
.pipe(gulp.rename('blocks.js'))
|
||||
.pipe(gulp.dest(packageDistribution));
|
||||
};
|
||||
|
||||
/**
|
||||
* This task wraps scripts/package/index.js into a UMD module.
|
||||
* We implicitly require the Node entry point in CommonJS environments,
|
||||
* and the Browser entry point for AMD environments.
|
||||
* @example import * as Blockly from 'blockly';
|
||||
*/
|
||||
function packageIndex() {
|
||||
return gulp.src('scripts/package/index.js')
|
||||
.pipe(packageUMD('Blockly', [{
|
||||
name: 'Blockly',
|
||||
amd: './browser',
|
||||
cjs: './node',
|
||||
}]))
|
||||
.pipe(gulp.rename('index.js'))
|
||||
.pipe(gulp.dest(packageDistribution));
|
||||
};
|
||||
|
||||
/**
|
||||
* This task wraps scripts/package/browser/index.js into a UMD module.
|
||||
* By default, the module includes Blockly core and built-in blocks,
|
||||
* as well as the JavaScript code generator and the English block
|
||||
* localization files.
|
||||
* This module is configured (in package.json) to replaces the module
|
||||
* built by package-node in browser environments.
|
||||
* @example import * as Blockly from 'blockly/browser';
|
||||
*/
|
||||
function packageBrowser() {
|
||||
return gulp.src('scripts/package/browser/index.js')
|
||||
.pipe(packageUMD('Blockly', [{
|
||||
name: 'Blockly',
|
||||
amd: './core-browser',
|
||||
cjs: './core-browser',
|
||||
},{
|
||||
name: 'En',
|
||||
amd: './msg/en',
|
||||
cjs: './msg/en',
|
||||
},{
|
||||
name: 'BlocklyBlocks',
|
||||
amd: './blocks',
|
||||
cjs: './blocks',
|
||||
},{
|
||||
name: 'BlocklyJS',
|
||||
amd: './javascript',
|
||||
cjs: './javascript',
|
||||
}]))
|
||||
.pipe(gulp.rename('browser.js'))
|
||||
.pipe(gulp.dest(packageDistribution));
|
||||
};
|
||||
|
||||
/**
|
||||
* This task wraps scripts/package/browser/core.js into a UMD module.
|
||||
* By default, the module includes the Blockly core package and a
|
||||
* helper method to set the locale.
|
||||
* This module is configured (in package.json) to replaces the module
|
||||
* built by package-node-core in browser environments.
|
||||
* @example import * as Blockly from 'blockly/core';
|
||||
*/
|
||||
function packageCore() {
|
||||
return gulp.src('scripts/package/browser/core.js')
|
||||
.pipe(packageUMD('Blockly', [{
|
||||
name: 'Blockly',
|
||||
amd: './blockly',
|
||||
cjs: './blockly',
|
||||
}]))
|
||||
.pipe(gulp.rename('core-browser.js'))
|
||||
.pipe(gulp.dest(packageDistribution));
|
||||
};
|
||||
|
||||
/**
|
||||
* This task wraps scripts/package/node/index.js into a CommonJS module for Node.js.
|
||||
* By default, the module includes Blockly core and built-in blocks,
|
||||
* as well as all the code generators and the English block localization files.
|
||||
* This module is configured (in package.json) to be replaced by the module
|
||||
* built by package-browser in browser environments.
|
||||
* @example import * as Blockly from 'blockly/node';
|
||||
*/
|
||||
function packageNode() {
|
||||
return gulp.src('scripts/package/node/index.js')
|
||||
.pipe(packageCommonJS('Blockly', [{
|
||||
name: 'Blockly',
|
||||
cjs: './core',
|
||||
},{
|
||||
name: 'En',
|
||||
cjs: './msg/en',
|
||||
},{
|
||||
name: 'BlocklyBlocks',
|
||||
cjs: './blocks',
|
||||
},{
|
||||
name: 'BlocklyJS',
|
||||
cjs: './javascript',
|
||||
},{
|
||||
name: 'BlocklyPython',
|
||||
cjs: './python',
|
||||
},{
|
||||
name: 'BlocklyPHP',
|
||||
cjs: './php',
|
||||
},{
|
||||
name: 'BlocklyLua',
|
||||
cjs: './lua',
|
||||
}, {
|
||||
name: 'BlocklyDart',
|
||||
cjs: './dart',
|
||||
}]))
|
||||
.pipe(gulp.rename('node.js'))
|
||||
.pipe(gulp.dest(packageDistribution));
|
||||
};
|
||||
|
||||
/**
|
||||
* This task wraps scripts/package/node/core.js into a CommonJS module for Node.js.
|
||||
* By default, the module includes the Blockly core package for Node.js
|
||||
* and a helper method to set the locale.
|
||||
* This module is configured (in package.json) to be replaced by the module
|
||||
* built by package-core in browser environments.
|
||||
* @example import * as Blockly from 'blockly/core';
|
||||
*/
|
||||
function packageNodeCore() {
|
||||
return gulp.src('scripts/package/node/core.js')
|
||||
.pipe(packageCommonJS('Blockly', [{
|
||||
name: 'Blockly',
|
||||
amd: './blockly',
|
||||
cjs: './blockly',
|
||||
}]))
|
||||
.pipe(gulp.rename('core.js'))
|
||||
.pipe(gulp.dest(packageDistribution));
|
||||
};
|
||||
|
||||
/**
|
||||
* A helper method for wrapping a generator file into a UMD module.
|
||||
* @param {string} file Source file name.
|
||||
* @param {string} rename Destination file name.
|
||||
* @param {string} namespace Export namespace.
|
||||
*/
|
||||
function packageGenerator(file, rename, namespace) {
|
||||
return gulp.src(`scripts/package/${rename}`)
|
||||
.pipe(packageUMD(`Blockly${namespace}`, [{
|
||||
name: 'Blockly',
|
||||
amd: './core',
|
||||
cjs: './core',
|
||||
}, {
|
||||
name: `Blockly${namespace}`,
|
||||
amd: `./${file}`,
|
||||
cjs: `./${file}`,
|
||||
}]))
|
||||
.pipe(gulp.rename(rename))
|
||||
.pipe(gulp.dest(packageDistribution));
|
||||
};
|
||||
|
||||
/**
|
||||
* This task wraps javascript_compressed.js into a UMD module.
|
||||
* @example import 'blockly/javascript';
|
||||
*/
|
||||
function packageJavascript() {
|
||||
return packageGenerator('javascript_compressed.js', 'javascript.js', 'JavaScript');
|
||||
};
|
||||
|
||||
/**
|
||||
* This task wraps python_compressed.js into a UMD module.
|
||||
* @example import 'blockly/python';
|
||||
*/
|
||||
function packagePython() {
|
||||
return packageGenerator('python_compressed.js', 'python.js', 'Python');
|
||||
};
|
||||
|
||||
/**
|
||||
* This task wraps lua_compressed.js into a UMD module.
|
||||
* @example import 'blockly/lua';
|
||||
*/
|
||||
function packageLua() {
|
||||
return packageGenerator('lua_compressed.js', 'lua.js', 'Lua');
|
||||
};
|
||||
|
||||
/**
|
||||
* This task wraps dart_compressed.js into a UMD module.
|
||||
* @example import 'blockly/dart';
|
||||
*/
|
||||
function packageDart() {
|
||||
return packageGenerator('dart_compressed.js', 'dart.js', 'Dart');
|
||||
};
|
||||
|
||||
/**
|
||||
* This task wraps php_compressed.js into a UMD module.
|
||||
* @example import 'blockly/php';
|
||||
*/
|
||||
function packagePHP() {
|
||||
return packageGenerator('php_compressed.js', 'php.js', 'PHP');
|
||||
};
|
||||
|
||||
/**
|
||||
* This task wraps each of the msg/js/* files into a UMD module.
|
||||
* @example import * as En from 'blockly/msg/en';
|
||||
*/
|
||||
function packageLocales() {
|
||||
// Remove references to goog.provide and goog.require.
|
||||
return gulp.src('msg/js/*.js')
|
||||
.pipe(gulp.replace(/goog\.[^\n]+/g, ''))
|
||||
.pipe(gulp.insert.prepend(`
|
||||
var Blockly = {};Blockly.Msg={};`))
|
||||
.pipe(packageUMD('Blockly.Msg', [{
|
||||
name: 'Blockly',
|
||||
amd: '../core',
|
||||
cjs: '../core',
|
||||
}]))
|
||||
.pipe(gulp.dest(`${packageDistribution}/msg`));
|
||||
};
|
||||
|
||||
/**
|
||||
* This task creates a UMD bundle of Blockly which includes the Blockly
|
||||
* core files, the built-in blocks, the JavaScript code generator and the
|
||||
* English localization files.
|
||||
* @example <script src="https://unpkg.com/blockly/blockly.min.js"></script>
|
||||
*/
|
||||
function packageUMDBundle() {
|
||||
var srcs = [
|
||||
'blockly_compressed.js',
|
||||
'msg/js/en.js',
|
||||
'blocks_compressed.js',
|
||||
'javascript_compressed.js'
|
||||
];
|
||||
return gulp.src(srcs)
|
||||
.pipe(gulp.concat('blockly.min.js'))
|
||||
.pipe(gulp.dest(`${packageDistribution}`))
|
||||
};
|
||||
|
||||
/**
|
||||
* This task copies all the media/* files into the distribution directory.
|
||||
*/
|
||||
function packageMedia() {
|
||||
return gulp.src('./media/*')
|
||||
.pipe(gulp.dest(`${packageDistribution}/media`));
|
||||
};
|
||||
|
||||
/**
|
||||
* This task copies the package.json file into the distribution directory.
|
||||
*/
|
||||
function packageJSON(cb) {
|
||||
const packageJson = getPackageJson();
|
||||
const json = Object.assign({}, packageJson);
|
||||
delete json['scripts'];
|
||||
if (!fs.existsSync(packageDistribution)) {
|
||||
fs.mkdirSync(packageDistribution);
|
||||
}
|
||||
fs.writeFileSync(`${packageDistribution}/package.json`,
|
||||
JSON.stringify(json, null, 2));
|
||||
cb();
|
||||
};
|
||||
|
||||
/**
|
||||
* This task copies the scripts/package/README.md file into the distribution directory.
|
||||
* This file is what developers will see at https://www.npmjs.com/package/blockly.
|
||||
*/
|
||||
function packageReadme() {
|
||||
return gulp.src('./scripts/package/README.md')
|
||||
.pipe(gulp.dest(`${packageDistribution}`));
|
||||
};
|
||||
|
||||
/**
|
||||
* This task copies the typings/blockly.d.ts TypeScript definition file into the
|
||||
* distribution directory.
|
||||
* The bundled declaration file is referenced in package.json in the types property.
|
||||
*/
|
||||
function packageDTS() {
|
||||
return gulp.src(['./typings/*.d.ts', './typings/msg/*.d.ts'], {base: './typings'})
|
||||
.pipe(gulp.dest(`${packageDistribution}`));
|
||||
};
|
||||
|
||||
/**
|
||||
* This task prepares the NPM distribution files under the /dist directory.
|
||||
*/
|
||||
const package = gulp.parallel(
|
||||
packageIndex,
|
||||
packageSources,
|
||||
packageCompressed,
|
||||
packageBrowser,
|
||||
packageNode,
|
||||
packageCore,
|
||||
packageNodeCore,
|
||||
packageBlockly,
|
||||
packageBlocks,
|
||||
packageJavascript,
|
||||
packagePython,
|
||||
packageLua,
|
||||
packageDart,
|
||||
packagePHP,
|
||||
packageLocales,
|
||||
packageMedia,
|
||||
packageUMDBundle,
|
||||
packageJSON,
|
||||
packageReadme,
|
||||
packageDTS
|
||||
);
|
||||
|
||||
module.exports = {
|
||||
package: package,
|
||||
};
|
||||
179
blockly/scripts/gulpfiles/release_tasks.js
Normal file
179
blockly/scripts/gulpfiles/release_tasks.js
Normal file
@@ -0,0 +1,179 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2020 Google LLC
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileoverview Gulp scripts for releasing Blockly.
|
||||
*/
|
||||
|
||||
var execSync = require('child_process').execSync;
|
||||
var fs = require('fs');
|
||||
var gulp = require('gulp');
|
||||
var readlineSync = require('readline-sync');
|
||||
var typings = require('./typings');
|
||||
|
||||
var buildTasks = require('./build_tasks');
|
||||
var gitTasks = require('./git_tasks');
|
||||
var packageTasks = require('./package_tasks');
|
||||
var { getPackageJson } = require('./helper_tasks');
|
||||
|
||||
const RELEASE_DIR = 'dist';
|
||||
|
||||
// Gets the current major version.
|
||||
function getMajorVersion() {
|
||||
var { version } = getPackageJson();
|
||||
var re = new RegExp(/^(\d)./);
|
||||
var match = re.exec(version);
|
||||
if (!match[0]) {
|
||||
return null;
|
||||
}
|
||||
console.log(match[0]);
|
||||
return parseInt(match[0]);
|
||||
}
|
||||
|
||||
// Updates the version depending on user input.
|
||||
function updateVersion(done, updateType) {
|
||||
var majorVersion = getMajorVersion();
|
||||
if (!majorVersion) {
|
||||
done(new Error('Something went wrong when getting the major version number.'));
|
||||
} else if (!updateType) {
|
||||
// User selected to cancel.
|
||||
done(new Error('Cancelling process.'));
|
||||
}
|
||||
|
||||
switch (updateType.toLowerCase()) {
|
||||
case 'major':
|
||||
majorVersion++;
|
||||
execSync(`npm --no-git-tag-version version ${majorVersion}.$(date +'%Y%m%d').0`, {stdio: 'inherit'});
|
||||
done();
|
||||
break;
|
||||
case 'minor':
|
||||
execSync(`npm --no-git-tag-version version ${majorVersion}.$(date +'%Y%m%d').0`, {stdio: 'inherit'});
|
||||
done();
|
||||
break;
|
||||
case 'patch':
|
||||
execSync(`npm --no-git-tag-version version patch`, {stdio: 'inherit'});
|
||||
done();
|
||||
break;
|
||||
default:
|
||||
done(new Error('Unexpected update type was chosen.'))
|
||||
}
|
||||
}
|
||||
|
||||
// Prompt the user to figure out what kind of version update we should do.
|
||||
function updateVersionPrompt(done) {
|
||||
var releaseTypes = ['Major', 'Minor', 'Patch'];
|
||||
var index = readlineSync.keyInSelect(releaseTypes, 'Which version type?');
|
||||
updateVersion(done, releaseTypes[index]);
|
||||
}
|
||||
|
||||
// Checks with the user that they are on the correct git branch.
|
||||
function checkBranch(done) {
|
||||
var gitBranchName = execSync('git rev-parse --abbrev-ref HEAD').toString();
|
||||
if (readlineSync.keyInYN(`You are on '${gitBranchName.trim()}'. Is this the correct branch?`)) {
|
||||
done();
|
||||
} else {
|
||||
done(new Error('Not on correct branch'));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Sanity check that the dist folder exists, and that certain files are in the dist folder.
|
||||
function checkDist(done) {
|
||||
const sanityFiles = ['blockly_compressed.js', 'blocks_compressed.js', 'core', 'blocks', 'generators'];
|
||||
// Check that dist exists.
|
||||
if (fs.existsSync(RELEASE_DIR)) {
|
||||
// Sanity check that certain files exist in dist.
|
||||
sanityFiles.forEach((fileName) => {
|
||||
if (!fs.existsSync(`${RELEASE_DIR}/${fileName}`)) {
|
||||
done(new Error(`Your dist folder does not contain:${fileName}`));
|
||||
}
|
||||
});
|
||||
done();
|
||||
} else {
|
||||
done(new Error('The dist directory does not exist. Is packageTasks.package being run?'));
|
||||
}
|
||||
}
|
||||
|
||||
// Check with the user that the version number is correct, then login and publish to npm.
|
||||
function loginAndPublish_(done, isBeta) {
|
||||
var { version } = getPackageJson();
|
||||
if(readlineSync.keyInYN(`You are about to publish blockly with the version number:${version}. Do you want to continue?`)) {
|
||||
execSync(`npm login --registry https://wombat-dressing-room.appspot.com`, {stdio: 'inherit'});
|
||||
execSync(`npm publish --registry https://wombat-dressing-room.appspot.com ${isBeta ? '--tag beta' : ''}`, {cwd: RELEASE_DIR, stdio: 'inherit'});
|
||||
done();
|
||||
} else {
|
||||
done(new Error('User quit due to the version number not being correct.'));
|
||||
}
|
||||
}
|
||||
|
||||
// Login and publish.
|
||||
function loginAndPublish(done) {
|
||||
return loginAndPublish_(done, false);
|
||||
}
|
||||
|
||||
// Login and publish the beta version.
|
||||
function loginAndPublishBeta(done) {
|
||||
return loginAndPublish_(done, true);
|
||||
}
|
||||
|
||||
// Repeatedly prompts the user for a beta version number until a valid one is given.
|
||||
// A valid version number must have '-beta.x' and can not have already been used to publish to npm.
|
||||
function updateBetaVersion(done) {
|
||||
var isValid = false;
|
||||
var newVersion = null;
|
||||
var blocklyVersions = JSON.parse(execSync('npm view blockly versions --json').toString());
|
||||
var re = new RegExp(/-beta\.(\d)/);
|
||||
var latestBetaVersion = execSync('npm show blockly version --tag beta').toString().trim();
|
||||
while(!isValid) {
|
||||
newVersion = readlineSync.question(`What is the new beta version? (latest beta version: ${latestBetaVersion})`);
|
||||
var existsOnNpm = blocklyVersions.indexOf(newVersion) > -1;
|
||||
var isFormatted = newVersion.search(re) > -1;
|
||||
if (!existsOnNpm && isFormatted) {
|
||||
isValid = true;
|
||||
} else if (existsOnNpm) {
|
||||
console.log("This version already exists. Please enter a new version.");
|
||||
} else if (!isFormatted) {
|
||||
console.log("To publish a beta version you must have -beta.x in the version.");
|
||||
}
|
||||
}
|
||||
// Allow the same version here, since we already check the version does not exist on npm.
|
||||
execSync(`npm --no-git-tag-version --allow-same-version version ${newVersion}`, {stdio: 'inherit'});
|
||||
done();
|
||||
}
|
||||
|
||||
// Package and publish to npm.
|
||||
const publish = gulp.series(
|
||||
packageTasks.package,
|
||||
checkBranch,
|
||||
checkDist,
|
||||
loginAndPublish
|
||||
);
|
||||
|
||||
// Publish a beta version of Blockly.
|
||||
const publishBeta = gulp.series(
|
||||
updateBetaVersion,
|
||||
buildTasks.build,
|
||||
packageTasks.package,
|
||||
checkBranch,
|
||||
checkDist,
|
||||
loginAndPublishBeta
|
||||
);
|
||||
|
||||
// Switch to a new branch, update the version number, and build Blockly.
|
||||
const recompile = gulp.series(
|
||||
gitTasks.syncDevelop(),
|
||||
gitTasks.createRebuildBranch,
|
||||
updateVersionPrompt,
|
||||
buildTasks.build,
|
||||
typings.typings,
|
||||
gitTasks.pushRebuildBranch
|
||||
);
|
||||
|
||||
module.exports = {
|
||||
recompile: recompile,
|
||||
publishBeta: publishBeta,
|
||||
publish: publish
|
||||
}
|
||||
121
blockly/scripts/gulpfiles/typings.js
Normal file
121
blockly/scripts/gulpfiles/typings.js
Normal file
@@ -0,0 +1,121 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2018 Google LLC
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileoverview Gulp script to generate the Typescript definition file (d.ts)
|
||||
* for Blockly.
|
||||
*/
|
||||
|
||||
var gulp = require('gulp');
|
||||
gulp.concat = require('gulp-concat');
|
||||
|
||||
var path = require('path');
|
||||
var fs = require('fs');
|
||||
var rimraf = require('rimraf');
|
||||
var execSync = require('child_process').execSync;
|
||||
|
||||
/**
|
||||
* Recursively generates a list of file paths with the specified extension
|
||||
* contained within the specified basePath.
|
||||
* @param {string} basePath The base path to use.
|
||||
* @param {string} filter The extension name to filter for.
|
||||
* @param {Array<string>} excludePaths The paths to exclude from search.
|
||||
* @return {Array<string>} The generated file paths.
|
||||
*/
|
||||
function getFilePath(basePath, filter, excludePaths) {
|
||||
const files = [];
|
||||
const dirContents = fs.readdirSync(basePath);
|
||||
dirContents.forEach((fn) => {
|
||||
const filePath = path.join(basePath, fn);
|
||||
const excluded =
|
||||
!excludePaths.every((exPath) => !filePath.startsWith(exPath));
|
||||
if (excluded) {
|
||||
return;
|
||||
}
|
||||
const stat = fs.lstatSync(filePath);
|
||||
if (stat.isDirectory()) {
|
||||
files.push(...getFilePath(filePath, filter, excludePaths));
|
||||
} else if (filePath.endsWith(filter)) {
|
||||
files.push(filePath);
|
||||
}
|
||||
});
|
||||
return files;
|
||||
}
|
||||
|
||||
// Generates the TypeScript definition file (d.ts) for Blockly.
|
||||
// As well as generating the typings of each of the files under core/ and msg/,
|
||||
// the script also pulls in a number of part files from typings/parts.
|
||||
// This includes the header (incl License), additional useful interfaces
|
||||
// including Blockly Options and Google Closure typings.
|
||||
function typings() {
|
||||
const tmpDir = './typings/tmp';
|
||||
|
||||
// Clean directory if exists.
|
||||
if (fs.existsSync(tmpDir)) {
|
||||
rimraf.sync(tmpDir);
|
||||
}
|
||||
fs.mkdirSync(tmpDir);
|
||||
|
||||
const excludePaths = [
|
||||
"core/renderers/geras",
|
||||
"core/renderers/minimalist",
|
||||
"core/renderers/thrasos",
|
||||
"core/renderers/zelos",
|
||||
];
|
||||
const blocklySrcs = [
|
||||
'core',
|
||||
'msg'
|
||||
]
|
||||
// Find all files that will be included in the typings file.
|
||||
let files = [];
|
||||
blocklySrcs.forEach((basePath) => {
|
||||
files.push(...getFilePath(basePath, '.js', excludePaths));
|
||||
});
|
||||
|
||||
// Generate typings file for each file.
|
||||
files.forEach((file) => {
|
||||
const typescriptFileName = `${path.join(tmpDir, file)}.d.ts`;
|
||||
if (file.indexOf('core/msg.js') > -1) {
|
||||
return;
|
||||
}
|
||||
const cmd = `node ./node_modules/typescript-closure-tools/definition-generator/src/main.js ${file} ${typescriptFileName}`;
|
||||
console.log(`Generating typings for ${file}`);
|
||||
execSync(cmd, { stdio: 'inherit' });
|
||||
});
|
||||
|
||||
const srcs = [
|
||||
'typings/templates/blockly-header.template',
|
||||
'typings/templates/blockly-interfaces.template',
|
||||
`${tmpDir}/core/**/*`,
|
||||
`${tmpDir}/msg/**`
|
||||
];
|
||||
return gulp.src(srcs)
|
||||
.pipe(gulp.concat('blockly.d.ts'))
|
||||
.pipe(gulp.dest('typings'))
|
||||
.on('end', function () {
|
||||
// Clean up tmp directory.
|
||||
if (fs.existsSync(tmpDir)) {
|
||||
rimraf.sync(tmpDir);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// Generates the TypeScript definition files (d.ts) for Blockly locales.
|
||||
function msgTypings(cb) {
|
||||
const template = fs.readFileSync(path.join('typings/templates/msg.template'), 'utf-8');
|
||||
const msgFiles = fs.readdirSync(path.join('msg', 'json'));
|
||||
msgFiles.forEach(msg => {
|
||||
const localeName = msg.substring(0, msg.indexOf('.json'));
|
||||
const msgTypings = template.slice().replace(/<%= locale %>/gi, localeName);
|
||||
fs.writeFileSync(path.join('typings', 'msg', localeName + '.d.ts'), msgTypings, 'utf-8');
|
||||
})
|
||||
cb();
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
typings: typings,
|
||||
msgTypings: msgTypings
|
||||
};
|
||||
Reference in New Issue
Block a user