From b377208f1755f5b1d007cf9035042a12302e4f52 Mon Sep 17 00:00:00 2001 From: Johan Nyman Date: Thu, 19 Mar 2026 15:32:59 +0100 Subject: [PATCH] chore: change names of scripts, to align better with established patterns in rest of the world --- DEVELOPER.md | 19 +++++++++----- package.json | 5 ++-- scripts/lib.js | 19 +++++++------- scripts/run.mjs | 69 +++++++++++++++++++++++++++++-------------------- 4 files changed, 67 insertions(+), 45 deletions(-) diff --git a/DEVELOPER.md b/DEVELOPER.md index bae711b60d1..422a704cc82 100644 --- a/DEVELOPER.md +++ b/DEVELOPER.md @@ -30,7 +30,13 @@ Follow these instructions to start up Sofie Core in development mode. (For produ git clone -b main https://github.com/Sofie-Automation/sofie-core.git cd sofie-core yarn -yarn start +yarn dev # Install and build all packages, then start in dev mode with file watching + +# Or + +yarn +yarn build # Install and build all packages +yarn start # Start Sofie Core (no file watching) ``` > 💡 First startup may take a while, especially on Windows. To speed things up, consider adding `%LOCALAPPDATA%\.meteor` and the directory where you cloned `server-core` to your Windows Defender virus protection exclusions. @@ -60,22 +66,23 @@ The Sofie ui (served by Vite) can be accessed at `http://localhost:3005`. The me 4. Start development mode ```bash - yarn dev + yarn dev # Install and build all packages, then start in dev mode with file watching ``` 5. In another window, start the playout-gateway. You will need to manually restart this upon making changes ```bash cd sofie-core/packages/playout-gateway - yarn buildstart + yarn build # If needed + yarn start ``` ### Lowering memory, CPU footprint in development -If you find yourself in a situation where running Sofie in development mode is too heavy, but you're not planning on modifying any of the low-level packages in the `packages` directory, you may want to run Sofie in the _UI-only mode_, in which only meteor and the ui will be rebuilt and type-checked on modification: +If you find yourself in a situation where running Sofie in development mode is too heavy, but you're not planning on modifying any of the low-level packages in the `packages` directory, you may want to run Sofie without file watching and type-checking. ```bash -yarn dev --ui-only +yarn start # Start Sofie Core (no file watching, requires a `yarn build` first) ``` ### Dealing with Strange Errors @@ -84,7 +91,7 @@ If you get any strange errors (such as the application crashing, "Unable to reso ```bash yarn reset # Removes all installed dependencies and build artifacts -yarn start # Set up, install and run in dev mode +yarn dev # Set up, install and run in dev mode ``` ## Editing the Code diff --git a/package.json b/package.json index f011d29dd3d..d897c7446b0 100644 --- a/package.json +++ b/package.json @@ -7,13 +7,14 @@ "node": ">=22.20.0" }, "scripts": { + "dev": "yarn build && yarn start --watch", + "build": "run install-and-build", + "start": "node ./scripts/run.mjs", "prepare": "husky", "postinstall": "run install:packages && run install:meteor", "install:meteor": "yarn restart:meteor && cd meteor && meteor --version && meteor npm install -g yarn && node ../scripts/fix-windows-yarn.js && yarn install", "install:packages": "cd packages && yarn install", - "start": "yarn install && run install-and-build && run dev", "install-and-build": "node ./scripts/install-and-build.mjs", - "dev": "node ./scripts/run.mjs", "restart:meteor": "node ./scripts/meteor-force-restart.js", "build:packages": "cd packages && run build", "test:packages": "cd packages && run test", diff --git a/scripts/lib.js b/scripts/lib.js index ea9fad5917d..c08846eea15 100644 --- a/scripts/lib.js +++ b/scripts/lib.js @@ -23,23 +23,24 @@ Options: --db-list List all available database directories and show which is active Examples: - yarn start # Install, build, then run in dev mode - yarn dev # Run in normal dev mode (requires prior build) - yarn dev --db-list # List all available databases - yarn dev --db=testing # Use a separate database for testing - yarn dev --db=demo # Switch to demo database - yarn dev --ui-only # Only watch UI, skip backend packages - yarn dev --inspect-meteor # Debug Meteor with inspector + yarn dev # Install, build, then run start with --watch + yarn start # Run in normal dev mode (requires prior build) + yarn start --watch # Run in dev mode with file watching + yarn start --db-list # List all available databases + yarn start --db=testing # Use a separate database for testing + yarn start --db=demo # Switch to demo database + yarn start --inspect-meteor # Debug Meteor with inspector yarn start --db=demo # Install, build, and run with demo database `); process.exit(0); } // Parse --db=name option -const dbArg = args.find(arg => arg.startsWith('--db=')); -const dbName = dbArg ? dbArg.split('=')[1] : null; +const dbArg = args.find((arg) => arg.startsWith("--db=")); +const dbName = dbArg ? dbArg.split("=")[1] : null; const config = { + watchMode: args.indexOf("--watch") >= 0 || false, uiOnly: args.indexOf("--ui-only") >= 0 || false, inspectMeteor: args.indexOf("--inspect-meteor") >= 0 || false, verbose: args.indexOf("--verbose") >= 0 || false, diff --git a/scripts/run.mjs b/scripts/run.mjs index a7020c5e1f1..dde002c25f5 100644 --- a/scripts/run.mjs +++ b/scripts/run.mjs @@ -11,7 +11,7 @@ function joinCommand(...parts) { function watchPackages() { return [ { - command: 'yarn watch --preserveWatchOutput', + command: "yarn watch --preserveWatchOutput", cwd: "packages", name: "TSC", prefixColor: "red", @@ -33,21 +33,21 @@ function watchWorker() { function watchMeteor() { const settingsFileExists = fs.existsSync("meteor-settings.json"); if (settingsFileExists) { - console.log('Found meteor-settings.json') + console.log("Found meteor-settings.json"); } else { - console.log('No meteor-settings.json') + console.log("No meteor-settings.json"); } // If a ROOT_URL is defined, meteor will serve under that. We should use the same for vite, to get the correct proxying - const rootUrl = process.env.ROOT_URL ? new URL(process.env.ROOT_URL) : null + const rootUrl = process.env.ROOT_URL ? new URL(process.env.ROOT_URL) : null; return [ { command: joinCommand( - 'yarn debug', + "yarn debug", config.inspectMeteor ? " --inspect" : "", config.verbose ? " --verbose" : "", - settingsFileExists ? " --settings ../meteor-settings.json" : "" + settingsFileExists ? " --settings ../meteor-settings.json" : "", ), cwd: "meteor", name: "METEOR", @@ -59,7 +59,8 @@ function watchMeteor() { name: "VITE", prefixColor: "yellow", env: { - SOFIE_BASE_PATH: rootUrl && rootUrl.pathname.length > 1 ? rootUrl.pathname : '', + SOFIE_BASE_PATH: + rootUrl && rootUrl.pathname.length > 1 ? rootUrl.pathname : "", }, }, ]; @@ -73,11 +74,11 @@ function hr() { } function listDatabases() { - const meteorLocalDir = path.join('meteor', '.meteor', 'local'); - const dbLink = path.join(meteorLocalDir, 'db'); + const meteorLocalDir = path.join("meteor", ".meteor", "local"); + const dbLink = path.join(meteorLocalDir, "db"); if (!fs.existsSync(meteorLocalDir)) { - console.log('No databases found (meteor/.meteor/local does not exist yet)'); + console.log("No databases found (meteor/.meteor/local does not exist yet)"); return; } @@ -92,22 +93,26 @@ function listDatabases() { currentDb = match[1]; } } else { - currentDb = '(unnamed - real directory)'; + currentDb = "(unnamed - real directory)"; } } // List all db.* directories const files = fs.readdirSync(meteorLocalDir); const dbDirs = files - .filter(file => file.startsWith('db.') && fs.lstatSync(path.join(meteorLocalDir, file)).isDirectory()) - .map(file => file.substring(3)); - - console.log('\nAvailable databases:'); + .filter( + (file) => + file.startsWith("db.") && + fs.lstatSync(path.join(meteorLocalDir, file)).isDirectory(), + ) + .map((file) => file.substring(3)); + + console.log("\nAvailable databases:"); if (dbDirs.length === 0) { - console.log(' (none found)'); + console.log(" (none found)"); } else { - dbDirs.sort().forEach(db => { - const marker = db === currentDb ? ' ← current' : ''; + dbDirs.sort().forEach((db) => { + const marker = db === currentDb ? " ← current" : ""; console.log(` ${db}${marker}`); }); } @@ -115,12 +120,12 @@ function listDatabases() { if (currentDb && !dbDirs.includes(currentDb)) { console.log(`\nCurrent: ${currentDb}`); } - console.log(''); + console.log(""); } function switchDatabase(dbName) { - const meteorLocalDir = path.join('meteor', '.meteor', 'local'); - const dbLink = path.join(meteorLocalDir, 'db'); + const meteorLocalDir = path.join("meteor", ".meteor", "local"); + const dbLink = path.join(meteorLocalDir, "db"); const dbTarget = path.join(meteorLocalDir, `db.${dbName}`); // Check if we're already using this database @@ -148,21 +153,29 @@ function switchDatabase(dbName) { fs.unlinkSync(dbLink); } else { // It's a real directory - back it up with timestamp - const defaultDb = path.join(meteorLocalDir, 'db.default'); + const defaultDb = path.join(meteorLocalDir, "db.default"); if (!fs.existsSync(defaultDb)) { console.log(`Backing up existing database to: default`); fs.renameSync(dbLink, defaultDb); } else { // Default already exists, create timestamped backup instead of deleting - const timestamp = new Date().toISOString().replace(/[:.]/g, '-').substring(0, 19); + const timestamp = new Date() + .toISOString() + .replace(/[:.]/g, "-") + .substring(0, 19); let backupName = path.join(meteorLocalDir, `db.backup.${timestamp}`); // Ensure unique backup name let suffix = 0; while (fs.existsSync(backupName)) { suffix++; - backupName = path.join(meteorLocalDir, `db.backup.${timestamp}.${suffix}`); + backupName = path.join( + meteorLocalDir, + `db.backup.${timestamp}.${suffix}`, + ); } - console.log(`Backing up existing database to: ${path.basename(backupName)}`); + console.log( + `Backing up existing database to: ${path.basename(backupName)}`, + ); fs.renameSync(dbLink, backupName); } } @@ -193,15 +206,15 @@ try { console.log(hr()); await concurrently( [ - ...(config.uiOnly ? [] : watchPackages()), - ...(config.uiOnly ? [] : watchWorker()), + ...(config.watchMode ? watchPackages() : []), + ...(config.watchMode ? watchWorker() : []), ...watchMeteor(), ], { prefix: "name", killOthers: ["failure", "success"], restartTries: 0, - } + }, ).result; } catch (e) { console.error(e.message);