# 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 subprocess import threading import time import mozpack.path as mozpath from mach.decorators import Command, CommandArgument, SubCommand @Command( "storybook", category="misc", description="Start the Storybook server and launch the site in a local build of Firefox. This will install npm dependencies, if necessary.", ) @CommandArgument( "--no-open", action="store_true", help="Start the Storybook server without opening a local Firefox build.", ) def storybook_server(command_context, no_open=False): ensure_env(command_context) if not no_open: start_browser_thread = threading.Thread( target=start_browser, args=(command_context,) ) start_browser_thread.start() return run_npm(command_context, args=["run", "storybook"]) @SubCommand( "storybook", "build", description="Build the Storybook for export.", ) def storybook_build(command_context): ensure_env(command_context) return run_npm(command_context, args=["run", "build-storybook"]) @SubCommand( "storybook", "launch", description="Launch the Storybook site in your local build." ) def storybook_launch(command_context): return run_mach( command_context, "run", argv=["http://localhost:5703"], setpref=[ "svg.context-properties.content.enabled=true", "layout.css.light-dark.enabled=true", ], ) def start_browser(command_context): # This delay is used to avoid launching the browser before the Storybook server has started. time.sleep(5) subprocess.run(run_mach(command_context, "storybook", subcommand="launch")) def build_storybook_manifest(command_context): print("Build ChromeMap backend") run_mach(command_context, "build-backend", backend=["ChromeMap"]) config_environment = command_context.config_environment storybook_chrome_map_path = "browser/components/storybook/.storybook/chrome-map.js" chrome_map_path = mozpath.join(config_environment.topobjdir, "chrome-map.json") with open(chrome_map_path, "r") as chrome_map_f: with open(storybook_chrome_map_path, "w") as storybook_chrome_map_f: storybook_chrome_map_f.write("module.exports = ") storybook_chrome_map_f.write(chrome_map_f.read()) storybook_chrome_map_f.write(";") def run_mach(command_context, cmd, **kwargs): return command_context._mach_context.commands.dispatch( cmd, command_context._mach_context, **kwargs ) def run_npm(command_context, args): return run_mach( command_context, "npm", args=[*args, "--prefix=browser/components/storybook"] ) def ensure_env(command_context): ensure_npm_deps(command_context) build_storybook_manifest(command_context) def ensure_npm_deps(command_context): if not check_npm_deps(command_context): install_npm_deps(command_context) else: print("Dependencies up to date\n") def check_npm_deps(command_context): print("Checking installed npm dependencies") return not run_npm(command_context, args=["ls"]) def install_npm_deps(command_context): print("Installing missing npm dependencies") run_npm(command_context, args=["ci"])