diff --git a/.gitignore b/.gitignore index 189944ab9e..4b1dccf38a 100644 --- a/.gitignore +++ b/.gitignore @@ -120,3 +120,4 @@ src/smc-webapp/_colors.sass # pytest cache src/smc_sagews/.pytest_cache/ +.mypy_cache/ diff --git a/src/package.json b/src/package.json index c072ee5d00..9aa93cd8a4 100644 --- a/src/package.json +++ b/src/package.json @@ -92,7 +92,7 @@ "lint": "node_modules/.bin/coffeelint -f smc-util/coffeelint.json -c *.coffee && cd smc-hub && npm run lint && cd ../smc-webapp && npm run lint && cd ../smc-util && npm run lint && cd ../smc-util-node && npm run lint", "test": "export SMC_TEST=true&& cd smc-util && npm test && cd ../smc-util-node && npm test && cd ../smc-hub && npm test && cd ../smc-webapp && npm test && cd ../smc-project && npm test", "coverage": "cd smc-util && npm run coverage && cd ../smc-util-node && npm run coverage && cd ../smc-hub && npm run coverage && cd ../smc-webapp && npm run coverage", - "webpack-watch": "cd $SALVUS_ROOT; scripts/update_color_scheme.coffee; webapp-lib/primus/update_primus; unset CC_STATICPAGES; CC_NOCLEAN=true SOURCE_MAP=true NODE_ENV=development node --max_old_space_size=8192 node_modules/webpack/bin/webpack.js --debug --output-pathinfo --progress --colors --watch --watch-poll=1000", + "webpack-watch": "cd $SALVUS_ROOT; scripts/check_npm_packages.py; scripts/update_color_scheme.coffee; webapp-lib/primus/update_primus; unset CC_STATICPAGES; CC_NOCLEAN=true SOURCE_MAP=true NODE_ENV=development node --max_old_space_size=8192 node_modules/webpack/bin/webpack.js --debug --output-pathinfo --progress --colors --watch --watch-poll=1000", "webpack-debug": "cd $SALVUS_ROOT; scripts/update_color_scheme.coffee; webapp-lib/primus/update_primus; SOURCE_MAP=true NODE_ENV=development webpack --debug --progress --colors", "webpack-production": "cd $SALVUS_ROOT; scripts/update_color_scheme.coffee; webapp-lib/primus/update_primus; NODE_ENV=production node --max_old_space_size=8192 node_modules/webpack/bin/webpack.js --progress --colors", "webpack-clean": "rm -rvf $SALVUS_ROOT/static/", diff --git a/src/scripts/check_npm_packages.py b/src/scripts/check_npm_packages.py new file mode 100755 index 0000000000..0ffe1dde77 --- /dev/null +++ b/src/scripts/check_npm_packages.py @@ -0,0 +1,85 @@ +#!/usr/bin/env python3 +""" +Consistency check for npm packages across node modules + +Hint: to get a "real time" info while working on resolving this, run + $ /usr/bin/watch -n1 check_npm_packages.py + in the SMC_ROOT dir in a separate terminal. +""" + +import os +from os.path import abspath, dirname, basename +import json +from collections import defaultdict +from pprint import pprint +from subprocess import run, PIPE +from typing import List, Set, Dict, Tuple, Optional +from typing_extensions import Final + +T_installs = Dict[str, Dict[str, str]] + +root: Final[str] = os.environ.get('SMC_ROOT', abspath(os.curdir)) + + +def pkg_dirs() -> List[str]: + search = run(['git', 'ls-files', '--', '../**/package.json'], stdout=PIPE) + data = search.stdout.decode('utf8') + packages = [abspath(_) for _ in data.splitlines()] + return packages + + +def get_versions(packages, dep_type) -> Tuple[T_installs, Set[str]]: + installs: T_installs = defaultdict(dict) + modules: Set[str] = set() + + for pkg in packages: + pkgs = json.load(open(pkg)) + module = basename(dirname(pkg)) + modules.add(module) + for name, vers in pkgs.get(dep_type, {}).items(): + installs[name][module] = vers + return installs, modules + + +def print_table(installs: T_installs, modules) -> Tuple[str, int]: + cnt = 0 + table = "" + + table += f"{'':<30s}" + for mod in sorted(modules): + table += f"{mod:<15s}" + table += "\n" + + for pkg, inst in sorted(installs.items()): + if len(set(inst.values())) == 1: continue + cnt += 1 + table += f"{pkg:<30s}" + for mod in sorted(modules): + vers = inst.get(mod, '') + table += f"{vers:<15s}" + table += "\n" + return table, cnt + + +def main() -> None: + packages: Final = pkg_dirs() + + main_pkgs, main_mods = get_versions(packages, 'dependencies') + dev_pkgs, dev_mods = get_versions(packages, 'devDependencies') + + dev_table, dev_incon = print_table(dev_pkgs, dev_mods) + if dev_incon > 0: + print("Development Modules") + print(dev_table) + print("\nRegular Code Modules") + + table, incons = print_table(main_pkgs, main_mods) + + if incons > 0: + print(table) + print(f"\nThere are {incons} inconsistencies") + exit(1) + + +if __name__ == '__main__': + main()