From 5ae74e166f9c5f5771d63c73b8ecb8d2f7f58f75 Mon Sep 17 00:00:00 2001 From: Aaron Dodson Date: Mon, 12 Jan 2026 15:56:29 -0800 Subject: [PATCH] chore: Remove unused scripts (#9561) --- scripts/goog_module/convert-file.sh | 406 ---------------------------- scripts/gulpfiles/config.mjs | 1 - scripts/migration/cjs2esm | 162 ----------- scripts/migration/js2ts | 168 ------------ tests/scripts/compile_typings.sh | 32 --- 5 files changed, 769 deletions(-) delete mode 100755 scripts/goog_module/convert-file.sh delete mode 100755 scripts/migration/cjs2esm delete mode 100755 scripts/migration/js2ts delete mode 100755 tests/scripts/compile_typings.sh diff --git a/scripts/goog_module/convert-file.sh b/scripts/goog_module/convert-file.sh deleted file mode 100755 index 4d6c13345..000000000 --- a/scripts/goog_module/convert-file.sh +++ /dev/null @@ -1,406 +0,0 @@ -#!/bin/bash - -# This file makes extensive use of perl for the purpose of extracting and -# replacing string (regex) patterns in a way that is both GNU and macOS -# compatible. -# -# Common perl flags used (also described at https://perldoc.perl.org/perlrun): -# -e : Used to execute perl programs on the command line -# -p : Assumes an input loop around script. Prints every processed line. -# -n : Assumes an input loop around script. Does not print every line. -# -i : Used for in-place editing. Used in commands for find/replace. -# -l[octnum] : Assigns the output record separator "$/" as an octal number. If -# octnum is not present, sets output record separator to the current -# value of the input record separator "$\". -# -# Common perl commands found: -# 1. perl -pi -e 's/regex/replacement/modifiers' -# This command does an in-place search-and-replace. The global ("/g") modifier -# causes it to replace all occurrences, rather than only the first match. -# 2. perl -ne 'print m/regex/modifiers' -# This command returns a string containing the regex match (designated by the -# capture group "()" in the regex). This will return the first match, unless -# the global modifier is specified, in which case, it will return all matches. -# If this command is used without a capture group it returns true or false (in -# the form a truthy or falsy value). -# 3. perl -nle 'print $& while m{regex}modifiers' -# Similar to (2), but returns regex matches separated by newlines. -# The "m{regex}modifiers" is equivalent to "m/regex/modifiers" syntax. -# -# Additional information on regex: -# This script makes use of some advanced regex syntax such as "capture groups" -# and "lookaround assertions". -# Additionally, characters are escaped from regex with a backslash "\". -# Single quotes need to be escaped in both regex and the string, resulting in -# '\'' being used to represent a single quote character. -# For a reference to syntax of regular expressions in Perl, see: -# https://perldoc.perl.org/perlre - -####################################### -# Logging functions. -####################################### -COLOR_NONE="\033[0m" -GREEN="\033[0;32m" -BLUE="\033[0;34m" -ORANGE="\033[0;33m" -RED="\033[0;31m" -success() { - echo -e "${GREEN}[SUCCESS]:${COLOR_NONE} $*" >&2 -} -inf() { - echo -e "${BLUE}[INFO]:${COLOR_NONE} $*" >&2 -} -warn() { - echo -e "${ORANGE}[WARN]:${COLOR_NONE} $*" >&2 -} -err() { - echo -e "${RED}[ERROR]:${COLOR_NONE} $*" >&2 -} -reenter_instructions() { - echo -e "${ORANGE}$*${COLOR_NONE}" >&2 -} - -####################################### -# Checks whether the provided filepath exists. -# Arguments: -# The filepath to check for existence. -# Optional: Whether to log an error. -####################################### -verify-filepath() { - local filepath="$1" - local no_log="$2" - if [[ ! -f "${filepath}" ]]; then - if [[ -z "${no_log}" || "${no_log}" == 'true' ]]; then - err "File ${filepath} does not exist" - fi - return 1 - fi -} - -####################################### -# Creates a commit with a message based on the specified step and file. -# Arguments: -# Which conversion step this message is for. -# The filepath of the file being converted. -####################################### -commit-step() { - local step="$1" - local filepath="$2" - if [[ -z "${step}" ]]; then - err "Missing argument (1-4)" - return 1 - fi - if [[ -z "${filepath}" ]]; then - err "Missing argument filepath" - return 1 - fi - verify-filepath "${filepath}" - if [[ $? -eq 1 ]]; then return 1; fi - - local message='' - case $1 in - 1) - message="Migrate ${filepath} to ES6 const/let" - ;; - 2) - message="Migrate ${filepath} to goog.module" - ;; - 3) - message="Migrate ${filepath} named requires" - ;; - 4) - message="clang-format ${filepath}" - ;; - *) - err 'INVALID ARGUMENT' - return 1 - ;; - esac - git add . - if [[ -z $(git status --porcelain) ]]; then - success "Nothing to commit" - return 0 - fi - git commit -m "${message}" - success "created commit with message: \"${message}\"" -} - -####################################### -# Extracts a list of properties that are accessed on the specified module name. -# Excludes any matches -# Arguments: -# The module name to find properties accessed for. -# The modules required by the specified module as a single string. -# The filepath to extract requires from. -# Optional: The top-level module. -# Outputs: -# Writes list of properties to stdout as items separated by spaces. -####################################### -getPropertiesAccessed() { - local module_name="$1" - local requires="$2" - local filepath="$3" - local top_module_name="$4" - # Get any strings that follow "$module_name.", excluding matches for - # "$module_name.prototype" and remove list item duplicates (sort -u). - local properties_accessed=$(perl -nle 'print $& while m{(?<='"${module_name}"'\.)(?!prototype)\w+}g' "${filepath}" | sort -u) - - # Get a list of any requires that are a child of $module_name. - # Ex: Blockly.utils.dom is a child of Blockly.utils, this would return "dom" - local requires_overlap=$(echo "${requires}" | perl -nle 'print $& while m{(?<='"${module_name}"'\.)\w+}g') - # Detect if there was any overlap. - if [[ -n "${requires_overlap}" ]]; then - while read -r requires_overlap_prop; do - # Removes any instances of $requires_overlap_prop. Includes regex - # lookarounds so that it does not simply match string contains. - # Ex: if $requires_overlap is "Svg", then it would update the list - # "isTargetInput mouseToSvg noEvent Svg" to - # "isTargetInput mouseToSvg noEvent " (note that mouseToSvg is unchanged). - properties_accessed=$(echo "${properties_accessed}" | perl -pe 's/(?> "${filepath}" - echo "exports = ${class_name};" >> "${filepath}" - - npm run build:deps - - success "Completed automated conversion to goog.module. Please manually review before committing." - return 0 - fi - - # No top level class. - inf 'Updating top-level property declarations...' - perl -pi -e 's/^'"${module_name}"'\.([^ ]+) =/const \1 =/g' "${filepath}" - - # Extract specific properties accessed so that properties from requires that - # are children of the module aren't changed. - # Ex: The module Blockly.utils shouldn't update Blockly.utils.dom (since it is - # a require from another module. - local requires=$(getRequires "${filepath}") - local properties_accessed=$(getPropertiesAccessed "${module_name}" "${requires}" "${filepath}") - inf "Updating local references to module..." - for property in $(echo "${properties_accessed}"); do - inf "Updating references of ${module_name}.${property} to ${property}..." - perl -pi -e 's/'"${module_name}"'\.'"${property}"'(?!\w)/'"${property}"'/g' "${filepath}" - done - - npm run build:deps - success "Completed automation for step 2. Please manually review and add exports for non-private top-level functions." -} - -####################################### -# Runs step 3 of the automated conversion. -# Arguments: -# The filepath of the file being converted. -####################################### -step3() { - inf "Extracting module name..." - local module_name=$(perl -ne 'print m/(?<=^goog\.module\('\'')([^'\'']+)/' "${filepath}") - if [[ -z "${module_name}" ]]; then - err "Could not extract module name" - return 1 - fi - inf "Extracted module name \"${module_name}\"" - - local requires=$(getRequires "${filepath}") - - # Process each require - echo "${requires}" | while read -r require; do - inf "Processing require \"${require}\"" - local usages=$(perl -nle 'print $& while m{'"${require}"'(?!'\'')}g' "${filepath}" | wc -l) - - if [[ "${usages}" -eq "0" ]]; then - warn "Unused require \"${require}\"" - continue - fi - - local require_name=$(echo "${require}" | perl -pe 's/(\w+\.)+(\w+)/\2/g') - inf "Updating require declaration for ${require}..." - perl -pi -e 's/^(goog\.(require|requireType)\('\'"${require}"\''\);)/const '"${require_name}"' = \1/' "${filepath}" - - # Parse property access of module - local direct_access_count=$(perl -nle 'print $& while m{'"${require}"'[^\.'\'']}g' "${filepath}" | wc -l) - local properties_accessed=$(getPropertiesAccessed "${require}" "${requires}" "${filepath}") - - # Remove $module_name in case it is a child of $require. - # Ex: Blockly.utils.dom would be a child of Blockly, module_overlap would be - # "utils" - local module_overlap=$(echo "${module_name}" | perl -nle 'print $& while m{(?<='"${require}"'\.)\w+}g') - if [[ -n "${module_overlap}" ]]; then - properties_accessed=$(echo "${properties_accessed}" | perl -pe 's/'"${module_overlap}"'//g') - # Trim any extra whitespace created. - properties_accessed=$(echo "${properties_accessed}" | xargs) - fi - - if [[ -n "${properties_accessed}" ]]; then - local comma_properties=$(echo "${properties_accessed}" | perl -pe 's/\s+/, /g' | perl -pe 's/, $//') - inf "Detected references of ${require}: ${comma_properties}" - - for require_prop in $(echo "${properties_accessed}"); do - inf "Updating references of ${require}.${require_prop} to ${require_name}.${require_prop}..." - perl -pi -e 's/'"${require}"'\.'"${require_prop}"'(?!\w)/'"${require_name}"'\.'"${require_prop}"'/g' "${filepath}" - done - fi - - inf "Updating direct references of ${require} to ${require_name}..." - perl -pi -e 's/'"${require}"'(?!['\''\w\.])/'"${require_name}"'/g' "${filepath}" - done - - local missing_requires=$(perl -nle'print $& while m{(? |-s ]" - echo " -h Display help and exit" - echo " -c Create a commit for the specified step [1-4]" - echo " -s Run the specified step [2-4]" -} - -####################################### -# Main entry point. -####################################### -main() { - if [ "$1" = "" ]; then - help - else - local filepath="" - # Support filepath as first argument. - verify-filepath "$1" "false" - if [[ $? -eq 0 ]]; then - filepath="$1" - shift - fi - - local command="$1" - shift - case $command in - -c) commit-step "$@" "${filepath}" ;; - -s) run-step "$@" "${filepath}" ;; - *) err "INVALID ARGUMENT ${command}";; - esac - fi -} - -main "$@" diff --git a/scripts/gulpfiles/config.mjs b/scripts/gulpfiles/config.mjs index 52e4cd06f..9d461231a 100644 --- a/scripts/gulpfiles/config.mjs +++ b/scripts/gulpfiles/config.mjs @@ -16,7 +16,6 @@ import * as path from 'path'; // TODO(#5007): If you modify these values, you must also modify the // corresponding values in the following files: // -// - tests/scripts/compile_typings.sh // - tests/scripts/check_metadata.sh // - tests/scripts/update_metadata.sh diff --git a/scripts/migration/cjs2esm b/scripts/migration/cjs2esm deleted file mode 100755 index 99a0e2223..000000000 --- a/scripts/migration/cjs2esm +++ /dev/null @@ -1,162 +0,0 @@ -#!/usr/bin/env node - -const fs = require('fs'); -const path = require('path'); - -const filenames = process.argv.slice(2); // Trim off node and script name. - -/** Absolute path of repository root. */ -const repoPath = path.resolve(__dirname, '..', '..'); - -////////////////////////////////////////////////////////////////////// -// Process files mentioned on the command line. -////////////////////////////////////////////////////////////////////// - -/** RegExp matching require statements. */ -const requireRE = - /(?:const\s+(?:([$\w]+)|(\{[^}]*\}))\s*=\s*)?require\('([^']+)'\);/g; - -/** RegExp matching key: value pairs in destructuring assignments. */ -const keyValueRE = /([$\w]+)\s*:\s*([$\w]+)\s*(?=,|})/g; - -/** Prefix for RegExp matching a top-level declaration. */ -const declPrefix = '(?:const|let|var|(?:async\\s+)?function(?:\\s*\\*)?|class)'; - -for (const filename of filenames) { - let contents = null; - try { - contents = String(fs.readFileSync(filename)); - } catch (e) { - console.error(`error while reading ${filename}: ${e.message}`); - continue; - } - console.log(`Converting ${filename} from CJS to ESM...`); - - // Remove "use strict". - contents = contents.replace(/^\s*["']use strict["']\s*; *\n/m, ''); - - // Migrate from require to import. - contents = contents.replace( - requireRE, - function ( - orig, // Whole statement to be replaced. - name, // Name of named import of whole module (if applicable). - names, // {}-enclosed list of destructured imports. - moduleName, // Imported module name or path. - ) { - if (moduleName[0] === '.') { - // Relative path. Could check and add '.mjs' suffix if desired. - } - if (name) { - return `import * as ${name} from '${moduleName}';`; - } else if (names) { - names = names.replace(keyValueRE, '$1 as $2'); - return `import ${names} from '${moduleName}';`; - } else { - // Side-effect only require. - return `import '${moduleName}';`; - } - }, - ); - - // Find and update or remove old-style single-export assignments - // like: - // - // exports.bar = foo; // becomes export {foo as bar}; - // exports.foo = foo; // remove the export and export at declaration - // // instead, if possible. - /** @type {!Array<{name: string, re: RegExp>}>} */ - const easyExports = []; - contents = contents.replace( - /^\s*exports\.([$\w]+)\s*=\s*([$\w]+)\s*;\n/gm, - function ( - orig, // Whole statement to be replaced. - exportName, // Name to export item as. - declName, // Already-declared name for item being exported. - ) { - // Renamed exports have to be translated as-is. - if (exportName !== declName) { - return `export {${declName} as ${exportName}};\n`; - } - // OK, we're doing "export.foo = foo;". Can we update the - // declaration? We can't actualy modify it yet as we're in - // the middle of a search-and-replace on contents already, but - // we can delete the old export and later update the - // declaration into an export. - const declRE = new RegExp( - `^(\\s*)(${declPrefix}\\s+${declName})\\b`, - 'gm', - ); - if (contents.match(declRE)) { - easyExports.push({exportName, declRE}); - return ''; // Delete existing export assignment. - } else { - return `export ${exportName};\n`; // Safe fallback. - } - }, - ); - - // Find and update or remove old-style module.exports assignment - // like: - // - // module.exports = {foo, bar: baz, quux}; - // - // which becomes export {baz as bar}, with foo and quux exported at - // declaration instead, if possible. - contents = contents.replace( - /^module\.exports\s*=\s*\{([^\}]+)\};?(\n?)/m, - function ( - orig, // Whole statement to be replaced. - items, // List of items to be exported. - ) { - items = items.replace( - /( *)([$\w]+)\s*(?::\s*([$\w]+)\s*)?,?(\s*?\n?)/gm, - function ( - origItem, // Whole item being replaced. - indent, // Optional leading whitespace. - exportName, // Name to export item as. - declName, // Already-declared name being exported, if different. - newline, // Optional trailing whitespace. - ) { - if (!declName) declName = exportName; - - // Renamed exports have to be translated as-is. - if (exportName !== declName) { - return `${indent}${declName} as ${exportName},${newline}`; - } - // OK, this item has no rename. Can we update the - // declaration? We can't actualy modify it yet as we're in - // the middle of a search-and-replace on contents already, - // but we can delete the item and later update the - // declaration into an export. - const declRE = new RegExp( - `^(\\s*)(${declPrefix}\\s+${declName})\\b`, - 'gm', - ); - if (contents.match(declRE)) { - easyExports.push({exportName, declRE}); - return ''; // Delete existing item. - } else { - return `${indent}${exportName},${newline}`; // Safe fallback. - } - }, - ); - if (/^\s*$/s.test(items)) { - // No items left? - return ''; // Delete entire module.export assignment. - } else { - return `export {${items}};\n`; - } - }, - ); - - // Add 'export' to existing declarations where appropriate. - for (const {exportName, declRE} of easyExports) { - contents = contents.replace(declRE, '$1export $2'); - } - - // Write converted file with new extension. - const newFilename = filename.replace(/.c?js$/, '.mjs'); - fs.writeFileSync(newFilename, contents); - console.log(`Wrote ${newFilename}.`); -} diff --git a/scripts/migration/js2ts b/scripts/migration/js2ts deleted file mode 100755 index 068871df5..000000000 --- a/scripts/migration/js2ts +++ /dev/null @@ -1,168 +0,0 @@ -#!/usr/bin/env node - -const fs = require('fs'); -const path = require('path'); - -const filenames = process.argv.slice(2); // Trim off node and script name. - -////////////////////////////////////////////////////////////////////// -// Load deps files via require (since they're executalbe .js files). -////////////////////////////////////////////////////////////////////// - -/** - * Dictionary mapping goog.module ID to absolute pathname of the file - * containing the goog.declareModuleId for that ID. - * @type {!Object} - */ -const modulePaths = {}; - -/** Absolute path of repository root. */ -const repoPath = path.resolve(__dirname, '..', '..'); - -/** - * Absolute path of directory containing base.js (the version used as - * input to tsc, not the one output by it). - * @type {string} - */ -const closurePath = path.resolve(repoPath, 'closure', 'goog'); - -globalThis.goog = {}; - -/** - * Stub version of addDependency that store mappings in modulePaths. - * @param {string} relPath The path to the js file. - * @param {!Array} provides An array of strings with - * the names of the objects this file provides. - * @param {!Array} _requires An array of strings with - * the names of the objects this file requires (unused). - * @param {boolean|!Object=} opt_loadFlags Parameters indicating - * how the file must be loaded. The boolean 'true' is equivalent - * to {'module': 'goog'} for backwards-compatibility. Valid properties - * and values include {'module': 'goog'} and {'lang': 'es6'}. - */ -goog.addDependency = function (relPath, provides, _requires, opt_loadFlags) { - // Ignore any non-ESM files, as they can't be imported. - if (opt_loadFlags?.module !== 'es6') return; - - // There should be only one "provide" from an ESM, but... - for (const moduleId of provides) { - // Store absolute path to source file (i.e., treating relPath - // relative to closure/goog/, not build/src/closure/goog/). - modulePaths[moduleId] = path.resolve(closurePath, relPath); - } -}; - -// Load deps files relative to this script's location. -require(path.resolve(__dirname, '../../build/deps.js')); - -////////////////////////////////////////////////////////////////////// -// Process files mentioned on the command line. -////////////////////////////////////////////////////////////////////// - -/** RegExp matching goog.require statements. */ -const requireRE = - /(?:const\s+(?:([$\w]+)|(\{[^}]*\}))\s+=\s+)?goog.require(Type)?\('([^']+)'\);/gm; - -/** RegExp matching key: value pairs in destructuring assignments. */ -const keyValueRE = /([$\w]+)\s*:\s*([$\w]+)\s*(?=,|})/g; - -for (const filename of filenames) { - let contents = null; - try { - contents = String(fs.readFileSync(filename)); - } catch (e) { - console.error(`error while reading ${filename}: ${e.message}`); - continue; - } - console.log(`Converting ${filename} to TypeScript...`); - - // Remove "use strict". - contents = contents.replace(/^\s*["']use strict["']\s*; *\n/m, ''); - - // Migrate from goog.module to goog.declareModuleId. - const closurePathRelative = path.relative( - path.dirname(path.resolve(filename)), - closurePath, - ); - contents = contents.replace( - /^goog.module\('([$\w.]+)'\);$/m, - `import * as goog from '${closurePathRelative}/goog.js';\n` + - `goog.declareModuleId('$1');`, - ); - - // Migrate from goog.require to import. - contents = contents.replace( - requireRE, - function ( - orig, // Whole statement to be replaced. - name, // Name of named import of whole module (if applicable). - names, // {}-enclosed list of destructured imports. - type, // If truthy, it is a requireType not require. - moduleId, // goog.module ID that was goog.require()d. - ) { - const importPath = modulePaths[moduleId]; - type = type ? ' type' : ''; - if (!importPath) { - console.warn( - `Unable to migrate goog.require('${moduleId}') as no ES module path known.`, - ); - return orig; - } - let relativePath = path.relative( - path.dirname(path.resolve(filename)), - importPath, - ); - if (relativePath[0] !== '.') relativePath = './' + relativePath; - if (name) { - return `import${type} * as ${name} from '${relativePath}';`; - } else if (names) { - names = names.replace(keyValueRE, '$1 as $2'); - return `import${type} ${names} from '${relativePath}';`; - } else { - // Side-effect only require. - return `import${type} '${relativePath}';`; - } - }, - ); - - // Find and update or remove old-style export assignemnts. - /** @type {!Array<{name: string, re: RegExp>}>} */ - const easyExports = []; - contents = contents.replace( - /^\s*exports\.([$\w]+)\s*=\s*([$\w]+)\s*;\n/gm, - function ( - orig, // Whole statement to be replaced. - exportName, // Name to export item as. - declName, // Already-declared name for item being exported. - ) { - // Renamed exports have to be transalted as-is. - if (exportName !== declName) { - return `export {${declName} as ${exportName}};\n`; - } - // OK, we're doing "export.foo = foo;". Can we update the - // declaration? We can't actualy modify it yet as we're in - // the middle of a search-and-replace on contents already, but - // we can delete the old export and later update the - // declaration into an export. - const declRE = new RegExp( - `^(\\s*)((?:const|let|var|function|class)\\s+${declName})\\b`, - 'gm', - ); - if (contents.match(declRE)) { - easyExports.push({exportName, declRE}); - return ''; // Delete existing export assignment. - } else { - return `export ${exportName};\n`; // Safe fallback. - } - }, - ); - // Add 'export' to existing declarations where appropriate. - for (const {exportName, declRE} of easyExports) { - contents = contents.replace(declRE, '$1export $2'); - } - - // Write converted file with new extension. - const newFilename = filename.replace(/.js$/, '.ts'); - fs.writeFileSync(newFilename, contents); - console.log(`Wrote ${newFilename}.`); -} diff --git a/tests/scripts/compile_typings.sh b/tests/scripts/compile_typings.sh deleted file mode 100755 index 35e9d56dc..000000000 --- a/tests/scripts/compile_typings.sh +++ /dev/null @@ -1,32 +0,0 @@ -#!/bin/bash - -# Location that npm run typings will write .d.ts files to. -# -# (TODO(#5007): Should fetch this from scripts/gulpfiles/config.js -# instead of hardcoding it here. -readonly BUILD_DIR='build' - -# ANSI colors -BOLD_GREEN='\033[1;32m' -BOLD_RED='\033[1;31m' -ANSI_RESET='\033[0m' - -# Terminate immediately with non-zero status if any command exits -# with non-zero status, printing a nice message. -set -e -function fail { - echo -e "${BOLD_RED}Failed to compile TypeScript typings.${ANSI_RESET}" >&2 -} -trap fail ERR - -# Generate Blockly typings. -echo "Generating Blockly typings" -npm run typings - -# Use the TypeScript compiler to compile the generated typings. -echo "Compiling typings" - -cd "${BUILD_DIR}" -../node_modules/.bin/tsc blockly.d.ts - -echo -e "${BOLD_GREEN}TypeScript typings compiled successfully.${ANSI_RESET}"