summaryrefslogtreecommitdiffstats
path: root/tools/ts/mach_commands.py
diff options
context:
space:
mode:
Diffstat (limited to 'tools/ts/mach_commands.py')
-rw-r--r--tools/ts/mach_commands.py114
1 files changed, 114 insertions, 0 deletions
diff --git a/tools/ts/mach_commands.py b/tools/ts/mach_commands.py
new file mode 100644
index 0000000000..5e933b463b
--- /dev/null
+++ b/tools/ts/mach_commands.py
@@ -0,0 +1,114 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+import json
+import os
+
+import mozpack.path as mozpath
+from mach.decorators import Command, CommandArgument, SubCommand
+
+
+@Command("ts", category="misc", description="Run TypeScript and related commands.")
+def ts(ctx):
+ """
+ TypeScript related commands to build/update typelibs and type-check js.
+
+ Example:
+ # Use tsc to check types in extensions framework code:
+ $ ./mach ts check toolkit/components/extensions
+ """
+ ctx._sub_mach(["help", "ts"])
+ return 1
+
+
+@SubCommand("ts", "build", description="Build typelibs.")
+@CommandArgument("lib", choices=["nsresult", "services", "xpcom"])
+def buld(ctx, lib):
+ """Command to build one of the typelibs."""
+
+ types_dir = mozpath.join(ctx.distdir, "@types")
+ lib_dts = mozpath.join(types_dir, f"lib.gecko.{lib}.d.ts")
+ if not os.path.exists(types_dir):
+ os.makedirs(types_dir)
+
+ if lib == "nsresult":
+ xpc_msg = mozpath.join(ctx.topsrcdir, "js/xpconnect/src/xpc.msg")
+ errors_json = mozpath.join(ctx.topsrcdir, "tools/ts/error_list.json")
+ return node(ctx, "build_nsresult", lib_dts, xpc_msg, errors_json)
+
+ if lib == "services":
+ services_json = mozpath.join(ctx.topobjdir, "xpcom/components/services.json")
+ if not os.path.isfile(services_json):
+ return build_required(lib, services_json)
+ return node(ctx, "build_services", lib_dts, services_json)
+
+ if lib == "xpcom":
+ # When we hook this up to be part of the build, we'll have
+ # an explicit list of files. For now, just get all of them.
+ dir = mozpath.join(ctx.topobjdir, "config/makefiles/xpidl")
+ if not os.path.isdir(dir):
+ return build_required(lib, dir)
+
+ files = [f for f in os.listdir(dir) if f.endswith(".d.json")]
+ if not len(files):
+ return build_required(lib, f"*.d.json files in {dir}")
+
+ return node(ctx, "build_xpcom", lib_dts, dir, *files)
+
+ raise ValueError(f"Unknown typelib: {lib}")
+
+
+@SubCommand("ts", "check", description="Check types in a project using tsc.")
+@CommandArgument("paths", nargs="+", help="Path to a (dir with) tsconfig.json.")
+def check(ctx, paths):
+ for p in paths:
+ rv = node(ctx, "node_modules/typescript/bin/tsc", "--project", p)
+ if rv:
+ return rv
+ return 0
+
+
+@SubCommand("ts", "setup", description="Install TypeScript and other dependencies.")
+def setup(ctx):
+ # Install locally under tools/ts/node_modules, to avoid any conflicts for now.
+ os.chdir(mozpath.dirname(__file__))
+ return ctx._sub_mach(["npm", "ci"])
+
+
+@SubCommand("ts", "update", description="Update tools/@types lib references.")
+def update(ctx):
+ types_dir = mozpath.join(ctx.distdir, "@types")
+ index_dts = mozpath.join(ctx.topsrcdir, "tools/@types/index.d.ts")
+ return node(ctx, "update_refs", index_dts, types_dir)
+
+
+def node(ctx, script, *args):
+ maybe_setup(ctx)
+ path = mozpath.join(mozpath.dirname(__file__), script)
+ return ctx._sub_mach(["node", path, *args])
+
+
+def maybe_setup(ctx):
+ """Check if npm modules are installed, and run setup if needed."""
+ dir = mozpath.dirname(__file__)
+ package_json = json.load(open(mozpath.join(dir, "package.json")))
+ needs_setup = False
+
+ # TODO: Use proper version checking from tools/lint/eslint/setup_helper.py.
+ for module in package_json.get("devDependencies", {}):
+ path = mozpath.join(dir, "node_modules", module, "package.json")
+ if not os.path.isfile(path):
+ print(f"Missing node module {path}.")
+ needs_setup = True
+ break
+
+ if needs_setup:
+ print("Running npm install.")
+ setup(ctx)
+
+
+def build_required(lib, item):
+ print(f"Missing {item}.")
+ print(f"Building {lib} typelib requires a full Firefox build.")
+ return 1