diff --git a/build-tests/sparo-outputs/.eslintrc.js b/build-tests/sparo-output-test/.eslintrc.js similarity index 100% rename from build-tests/sparo-outputs/.eslintrc.js rename to build-tests/sparo-output-test/.eslintrc.js diff --git a/build-tests/sparo-outputs/LICENSE b/build-tests/sparo-output-test/LICENSE similarity index 100% rename from build-tests/sparo-outputs/LICENSE rename to build-tests/sparo-output-test/LICENSE diff --git a/build-tests/sparo-output-test/README.md b/build-tests/sparo-output-test/README.md new file mode 100644 index 0000000..e33eac7 --- /dev/null +++ b/build-tests/sparo-output-test/README.md @@ -0,0 +1,11 @@ +# sparo-output-test + +Building this project tests sparo command outputs + +# Details + +`lib/start-test.js` is run after building the project. This scripts generate the output text files under `temp/etc`. In local builds, those files are copied to `etc` folder. During a CI build, the files under these two folders are compared and the CI build fails if they are different. This ensures that files under `etc` folder must be up to date in the PR, and people who review the PR must approve any changes. + +# How to fix the build errors + +Run `rush build -t sparo-output-test` to regenerate files under `etc` folder and commit them into Git. \ No newline at end of file diff --git a/build-tests/sparo-outputs/config/heft.json b/build-tests/sparo-output-test/config/heft.json similarity index 90% rename from build-tests/sparo-outputs/config/heft.json rename to build-tests/sparo-output-test/config/heft.json index e2987a3..acf3ab4 100644 --- a/build-tests/sparo-outputs/config/heft.json +++ b/build-tests/sparo-output-test/config/heft.json @@ -14,7 +14,7 @@ "pluginPackage": "@rushstack/heft", "options": { - "scriptPath": "lib/generateOutputs.js" + "scriptPath": "lib/start-test.js" } } } diff --git a/build-tests/sparo-outputs/config/rig.json b/build-tests/sparo-output-test/config/rig.json similarity index 100% rename from build-tests/sparo-outputs/config/rig.json rename to build-tests/sparo-output-test/config/rig.json diff --git a/build-tests/sparo-outputs/etc/checkout-help.txt b/build-tests/sparo-output-test/etc/checkout-help.txt similarity index 100% rename from build-tests/sparo-outputs/etc/checkout-help.txt rename to build-tests/sparo-output-test/etc/checkout-help.txt diff --git a/build-tests/sparo-outputs/etc/clone-help.txt b/build-tests/sparo-output-test/etc/clone-help.txt similarity index 100% rename from build-tests/sparo-outputs/etc/clone-help.txt rename to build-tests/sparo-output-test/etc/clone-help.txt diff --git a/build-tests/sparo-outputs/etc/top-level-help.txt b/build-tests/sparo-output-test/etc/top-level-help.txt similarity index 100% rename from build-tests/sparo-outputs/etc/top-level-help.txt rename to build-tests/sparo-output-test/etc/top-level-help.txt diff --git a/build-tests/sparo-outputs/etc/top-level-nonexistent-command.txt b/build-tests/sparo-output-test/etc/top-level-nonexistent-command.txt similarity index 100% rename from build-tests/sparo-outputs/etc/top-level-nonexistent-command.txt rename to build-tests/sparo-output-test/etc/top-level-nonexistent-command.txt diff --git a/build-tests/sparo-outputs/package.json b/build-tests/sparo-output-test/package.json similarity index 79% rename from build-tests/sparo-outputs/package.json rename to build-tests/sparo-output-test/package.json index 001b129..d5b6105 100644 --- a/build-tests/sparo-outputs/package.json +++ b/build-tests/sparo-output-test/package.json @@ -1,17 +1,16 @@ { - "name": "sparo-outputs", + "name": "sparo-output-test", "description": "Building this project tests sparo command outputs", "version": "1.0.0", "private": true, "scripts": { "_phase:build": "heft run --only build -- --clean", - "_phase:test": "heft run --only test -- --clean", - "test": "heft test --clean", "build": "heft build --clean" }, "dependencies": { "@rushstack/node-core-library": "~3.64.2", - "sparo": "workspace:*" + "sparo": "workspace:*", + "jest-diff": "~29.7.0" }, "devDependencies": { "@rushstack/heft": "0.64.3", diff --git a/build-tests/sparo-outputs/src/generateOutputs.ts b/build-tests/sparo-output-test/src/start-test.ts similarity index 81% rename from build-tests/sparo-outputs/src/generateOutputs.ts rename to build-tests/sparo-output-test/src/start-test.ts index 06b6c15..9911907 100644 --- a/build-tests/sparo-outputs/src/generateOutputs.ts +++ b/build-tests/sparo-output-test/src/start-test.ts @@ -1,5 +1,6 @@ import * as path from 'path'; import { Async, Executable, FileSystem, type FolderItem, Text } from '@rushstack/node-core-library'; +import { diff } from 'jest-diff'; import type { SpawnSyncReturns } from 'child_process'; import type { IRunScriptOptions } from '@rushstack/heft'; @@ -57,33 +58,31 @@ export async function runAsync(runScriptOptions: IRunScriptOptions): Promise { - const { name, args } = scenario; - const result: SpawnSyncReturns = Executable.spawnSync(binPath, args); - - if (result.status !== 0) { - throw new Error( - `Failed to run "sparo ${args.join(' ')}" with exit code ${result.status}\n${result.stderr}` - ); + for (const scenario of scenarios) { + const { name, args } = scenario; + const result: SpawnSyncReturns = Executable.spawnSync(binPath, args, { + environment: { + ...process.env + // Always use color for the output + // FORCE_COLOR: 'true' } + }); - const outputPath: string = path.join(tempFolder, `${name}.txt`); - FileSystem.writeFile( - outputPath, - `Running "sparo ${args.join(' ')}":\n${processVersionString(result.stdout)}` + if (result.status !== 0) { + throw new Error( + `Failed to run "sparo ${args.join(' ')}" with exit code ${result.status}\n${result.stderr}` ); - }, - { - concurrency: 10 } - ); + + const outputPath: string = path.join(tempFolder, `${name}.txt`); + FileSystem.writeFile( + outputPath, + `Running "sparo ${args.join(' ')}":\n${processVersionString(result.stdout)}` + ); + } /** * Files under outFolderPath are tracked by Git, files under inFolderPath are temporary files. During a local build, @@ -106,6 +105,7 @@ export async function runAsync(runScriptOptions: IRunScriptOptions): Promise = new Map(); await Async.forEachAsync( inFolderPaths, async (folderItemPath: string) => { @@ -130,6 +130,13 @@ export async function runAsync(runScriptOptions: IRunScriptOptions): Promise -
- - Sparo - -

- - -## Is Git too slow in your frontend monorepo? - -By default `git clone` will download every file in your Git repository, as well as the complete history of every file. For small repositories, that's no big deal. But as your monorepo accumulates projects and years of history, Git operations become slower and slower, until one day `git status` is taking 10 seconds or more. What to do? - - - - -## Clone faster! - -Sparo optimizes performance of Git operations for your large frontend monorepo. - -## Key features - -- **Familiar interface:** The `sparo` command-line interface (CLI) wrapper offers **better defaults** and **performance suggestions** without altering the familiar `git` syntax. (The native `git` CLI is also supported.) -- **A proven solution:** Git provides [quite a lot of ingredients](https://tiktok.github.io/sparo/pages/reference/git_optimization/) for optimizing very large repos; Sparo is your recipe for combining these features intelligently. -- **Simplified sparse checkout:** Work with sparse checkout [profiles](https://tiktok.github.io/sparo/pages/guide/sparo_profiles/) instead of confusing "cones" and globs -- **Frontend integration:** Sparo leverages [Rush](https://rushjs.io/) and [PNPM](https://pnpm.io/) workspace configurations, including the ability to automatically checkout project dependencies -- **Dual workflows:** The `sparo-ci` tool implements a specialized checkout model optimized for continuous integration (CI) pipelines -- **Extra safeguards**: Avoid common Git mistakes such as checkouts with staged files outside the active view -- **Go beyond Git hooks:** Optionally collect anonymized Git timing metrics in your monorepo, enabling your build team to set data-driven goals for _local_ developer experience (not just CI!) - - _(Metrics are transmitted to your own service and are not accessible by any other party.)_ - - - - -## Links - -- [Quick demo](https://tiktok.github.io/sparo/#quick-demo): See for yourself in 3 minutes! -- [Getting Started](https://tiktok.github.io/sparo/pages/guide/getting_started/): Step by step instructions -- [CHANGELOG.md]( - https://github.com/tiktok/sparo/blob/main/apps/sparo/CHANGELOG.md): Find - out what's new in the latest version diff --git a/build-tests/sparo-outputs/config/jest.config.json b/build-tests/sparo-outputs/config/jest.config.json deleted file mode 100644 index 4bb17bd..0000000 --- a/build-tests/sparo-outputs/config/jest.config.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "extends": "@rushstack/heft-node-rig/profiles/default/config/jest.config.json" -} diff --git a/common/config/rush/pnpm-lock.yaml b/common/config/rush/pnpm-lock.yaml index 402687e..46081a7 100644 --- a/common/config/rush/pnpm-lock.yaml +++ b/common/config/rush/pnpm-lock.yaml @@ -149,11 +149,14 @@ importers: specifier: ~5.3.3 version: 5.3.3 - ../../build-tests/sparo-outputs: + ../../build-tests/sparo-output-test: dependencies: '@rushstack/node-core-library': specifier: ~3.64.2 version: 3.64.2(@types/node@20.11.16) + jest-diff: + specifier: ~29.7.0 + version: 29.7.0 sparo: specifier: workspace:* version: link:../../apps/sparo @@ -4205,7 +4208,6 @@ packages: /ansi-styles@5.2.0: resolution: {integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==} engines: {node: '>=10'} - dev: true /ansi-styles@6.2.1: resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} @@ -5512,7 +5514,6 @@ packages: /diff-sequences@29.6.3: resolution: {integrity: sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dev: true /dir-glob@3.0.1: resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} @@ -7775,7 +7776,6 @@ packages: diff-sequences: 29.6.3 jest-get-type: 29.6.3 pretty-format: 29.7.0 - dev: true /jest-docblock@29.7.0: resolution: {integrity: sha512-q617Auw3A612guyaFgsbFeYpNP5t2aoUNLwBUbc/0kD1R4t9ixDbyFTHd1nok4epoVFpr7PmeWHrhvuV3XaJ4g==} @@ -7822,7 +7822,6 @@ packages: /jest-get-type@29.6.3: resolution: {integrity: sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dev: true /jest-haste-map@29.7.0: resolution: {integrity: sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA==} @@ -10031,7 +10030,6 @@ packages: '@jest/schemas': 29.6.3 ansi-styles: 5.2.0 react-is: 18.2.0 - dev: true /pretty-time@1.1.0: resolution: {integrity: sha512-28iF6xPQrP8Oa6uxE6a1biz+lWeTOAPKggvjB8HAs6nVMKZwf5bG++632Dx614hIWgUPkgivRfG+a8uAXGTIbA==} @@ -10263,7 +10261,6 @@ packages: /react-is@18.2.0: resolution: {integrity: sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==} - dev: true /react-json-view-lite@1.2.1(react@18.2.0): resolution: {integrity: sha512-Itc0g86fytOmKZoIoJyGgvNqohWSbh3NXIKNgH6W6FT9PC1ck4xas1tT3Rr/b3UlFXyA9Jjaw9QSXdZy2JwGMQ==} @@ -12303,6 +12300,7 @@ time: /eslint@8.56.0: '2023-12-15T22:55:11.833Z' /git-repo-info@2.1.1: '2019-10-18T15:12:09.674Z' /inversify@6.0.2: '2023-10-20T23:35:39.918Z' + /jest-diff@29.7.0: '2023-09-12T06:43:43.883Z' /lunr@2.3.9: '2020-08-19T20:30:07.948Z' /prism-react-renderer@2.3.1: '2023-12-18T14:23:38.265Z' /prismjs@1.29.0: '2022-08-23T10:42:14.395Z' diff --git a/rush.json b/rush.json index 2e52e3f..d72a82a 100644 --- a/rush.json +++ b/rush.json @@ -437,8 +437,8 @@ // Build tests { - "packageName": "sparo-outputs", - "projectFolder": "build-tests/sparo-outputs" + "packageName": "sparo-output-test", + "projectFolder": "build-tests/sparo-output-test" }, // Sparo