Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: Improve contributing experience #9759

Merged
merged 6 commits into from
Mar 11, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .npmrc
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,6 @@ link-workspace-packages=false # deep
## script to handle this.
##
sync-injected-deps-after-scripts[]=build:pkg
sync-injected-deps-after-scripts[]=build:infra
sync-injected-deps-after-scripts[]=build:glint
sync-injected-deps-after-scripts[]=sync

Expand Down
25 changes: 24 additions & 1 deletion contributing/setting-up-the-project.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,30 @@ pnpm dlx @warp-drive/holodeck ensure-cert

## Building the project

The project's packages will build whenever `pnpm install` is run.
The project's packages will build whenever `pnpm install` is run. They can be rebuilt by running `pnpm prepare`.

Both `install` and `prepare` will ensure turbo cache is ignored so that pnpm will automatically update "hardlinks" for
the build output files in the node_modules directory of the various other packages and test apps that depend upon the package.

However, this is pretty slow for development, so a fast albeit slightly manual approach is available for development
by running the below commands in order:

From the project root:

- install: `pnpm install` - installs all dependencies and sets up initial hardlinks
- start: `pnpm start` - starts the build for every public package in watch mode

Then, from an individual test app:

- `pnpm start` - starts the build for test assets in watch mode
- `pnpm test:start` - launches a test server (and by opens a browser window for debugging them)

Because the project uses hardlinks, even though the packages are rebuilding, the test apps won't be able
to see the results of the change in many scenarios unless the hardlinks are regenerated.

At anypoint, run `pnpm sync` from the root to regenerate the hardlinks. The test app server may
pick up this change automatically, but if it does not saving any file (even without changing it)
in the test app will trigger a rebuild.

## Run some commands

Expand Down
35 changes: 32 additions & 3 deletions internal-tooling/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,38 @@ for use with the monorepo.

These scripts can be run as bin-scripts from root.

## bun sync-logos
### sync-all

```sh
bun sync-all
```

Will run all of the other available scripts.

### sync-logos

```sh
bun sync-logos
```

Will sync the logo directory from root to each public package and
ensure that the logos directory is included in published files.

## bun sync-license
### sync-license

```sh
bun sync-license
```

Will sync the LICENSE.md file from root to each public package and
ensure that the license is both set to `MIT` in the package.json and
included in the published files for each package.

## bun sync-references
### sync-references

```sh
bun sync-references
```

Will ensure that `paths` and `references` are both correctly specified
in tsconfig.json for any other workspace package specified by package.json
Expand All @@ -26,3 +46,12 @@ Will also ensure the proper settings for composite etc. are in use.

For packages that should emit types (any non-test app package) it will
ensure that the declarationDir is added to the files array in package.json.

### sync-scripts

```sh
bun sync-scripts
```

Will ensure that scripts enumerated in package.json which should be the same
throughout the monorepo match expected configuration.
4 changes: 3 additions & 1 deletion internal-tooling/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@
"bin": {
"sync-logos": "src/sync-logos.ts",
"sync-license": "src/sync-license.ts",
"sync-references": "src/sync-references.ts"
"sync-references": "src/sync-references.ts",
"sync-scripts": "src/sync-scripts.ts",
"sync-all": "src/sync-all.ts"
},
"dependencies": {
"@types/bun": "^1.2.4",
Expand Down
4 changes: 4 additions & 0 deletions internal-tooling/src/sync-all.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#! /usr/bin/env bun
import { main } from './tasks/sync-all';

main();
4 changes: 4 additions & 0 deletions internal-tooling/src/sync-licence.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#! /usr/bin/env bun
import { main } from './tasks/sync-license';

main();
85 changes: 1 addition & 84 deletions internal-tooling/src/sync-logos.ts
Original file line number Diff line number Diff line change
@@ -1,87 +1,4 @@
#! /usr/bin/env bun

import path from 'path';
import fs from 'fs';
import debug from 'debug';
import chalk from 'chalk';
import type { BunFile } from 'bun';
import { getMonorepoRoot, getPackageJson } from './-utils';

const log = debug('wd:sync-logos');

async function copyFiles({
packageDir,
packageLogosDir,
logosDir,
isCopied,
}: {
packageDir: string;
packageLogosDir: string;
logosDir: string;
isCopied: boolean;
}) {
// if we are in copy mode, remove any existing symlink and copy the files
if (isCopied) {
fs.rmSync(packageLogosDir, { recursive: true, force: true });
log(`\t\t\t🗑️ Deleted existing copy of ${packageDir}/logos`);
}
fs.mkdirSync(packageLogosDir, { recursive: true });
log(`\t\t\t📁 Created ${packageDir}/logos`);

for (const logo of fs.readdirSync(logosDir, { recursive: true, encoding: 'utf-8' })) {
const logoPath = path.join(logosDir, logo);
const destPath = path.join(packageLogosDir, logo);
fs.copyFileSync(logoPath, destPath);
log(`\t\t\t📁 Copied ${logo} to ${packageDir}/logos`);
}
}

async function updatePackageJson({ pkg, file, nicePath }: { pkg: any; file: BunFile; path: string; nicePath: string }) {
// ensure "files" field in package.json includes "logos"
if (!pkg.files) {
pkg.files = ['logos'];
await file.write(JSON.stringify(pkg, null, 2));
log(`\t\t📝 Added "logos" to "files" in ${nicePath}`);
} else if (!pkg.files.includes('logos')) {
pkg.files.push('logos');
await file.write(JSON.stringify(pkg, null, 2));
log(`\t\t📝 Added "logos" to "files" in ${nicePath}`);
}
}

async function main() {
log(
`\n\t${chalk.gray('=').repeat(60)}\n\t\t${chalk.magentaBright('@warp-drive/')}${chalk.greenBright('internal-tooling')} Sync Logos\n\t${chalk.gray('=').repeat(60)}\n\n\t\t${chalk.gray(`Syncing logo files from monorepo root to each public package`)}\n\n`
);
const monorepoRoot = await getMonorepoRoot();

// sync the logos from the monorepo root to each
// package directory that has a logos directory

const logosDir = path.join(monorepoRoot, 'logos');
const packagesDir = path.join(monorepoRoot, 'packages');

for (const packageDir of fs.readdirSync(packagesDir)) {
const packageLogosDir = path.join(packagesDir, packageDir, 'logos');
const isCopied = fs.existsSync(packageLogosDir);
const details = await getPackageJson({ packageDir, packagesDir });

if (details.pkg.private) {
log(`\t\t🔒 Skipping private package ${details.nicePath}`);
continue;
}

log(`\t\t🔁 Syncing logos to ${packageDir}`);

await copyFiles({
packageDir,
packageLogosDir,
logosDir,
isCopied,
});

await updatePackageJson(details);
}
}
import { main } from './tasks/sync-logos';

main();
Loading
Loading