Skip to content

Commit a073aab

Browse files
runspiredMehulKChaudhari
authored andcommitted
chore: tooling upgrades to support WarpDrive package unification (emberjs#9752)
1 parent e56f697 commit a073aab

File tree

494 files changed

+13638
-676
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

494 files changed

+13638
-676
lines changed

CODE_OF_CONDUCT.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Code Of Conduct
22

3-
The `ember-data` core team and and the broader `Ember` community are committed to everyone
3+
The `warp-drive` core team and and the broader `Ember` community are committed to everyone
44
having a safe and inclusive experience.
55

66
- Our **Community Guidelines / Code of Conduct** can be found at [emberjs.com/guidelines](https://emberjs.com/guidelines/)

CONTRIBUTING.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
## Welcome!
44

5-
We are so glad you are considering contributing to `EmberData`. Before that, kindly take a minute to read the [Code of Conduct](https://github.com/emberjs/data/blob/main/CODE_OF_CONDUCT.md). Below you'll find links to topics
5+
We are so glad you are considering contributing to `WarpDrive`. Before that, kindly take a minute to read the [Code of Conduct](https://github.com/emberjs/data/blob/main/CODE_OF_CONDUCT.md). Below you'll find links to topics
66
detailing how to become involved to best ensure your contributions are successful!
77

88
- [Reporting Issues](./contributing/issues.md)

LICENSE.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
MIT License
22

3-
Copyright (c) 2017-2024 Ember.js and contributors
3+
Copyright (c) 2017-2025 Ember.js and contributors
44
Copyright (c) 2011-2017 Tilde, Inc. and contributors
55
Copyright (c) 2011 LivingSocial Inc.
66

internal-tooling/.gitignore

+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
# dependencies (bun install)
2+
node_modules
3+
4+
# output
5+
out
6+
dist
7+
*.tgz
8+
9+
# code coverage
10+
coverage
11+
*.lcov
12+
13+
# logs
14+
logs
15+
_.log
16+
report.[0-9]_.[0-9]_.[0-9]_.[0-9]_.json
17+
18+
# dotenv environment variable files
19+
.env
20+
.env.development.local
21+
.env.test.local
22+
.env.production.local
23+
.env.local
24+
25+
# caches
26+
.eslintcache
27+
.cache
28+
*.tsbuildinfo
29+
30+
# IntelliJ based IDEs
31+
.idea
32+
33+
# Finder (MacOS) folder config
34+
.DS_Store

internal-tooling/README.md

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# @warp-drive/internal-tooling
2+
3+
This internal (private) project provides a number of tooling scripts
4+
for use with the monorepo.
5+
6+
These scripts can be run as bin-scripts from root.
7+
8+
## bun sync-logos
9+
10+
Will sync the logo directory from root to each public package and
11+
ensure that the logos directory is included in published files.
12+
13+
## bun sync-license
14+
15+
Will sync the LICENSE.md file from root to each public package and
16+
ensure that the license is both set to `MIT` in the package.json and
17+
included in the published files for each package.
18+
19+
## bun sync-references
20+
21+
Will ensure that `paths` and `references` are both correctly specified
22+
in tsconfig.json for any other workspace package specified by package.json
23+
as a dependency, peer-dependency, or dev-dependency.
24+
25+
Will also ensure the proper settings for composite etc. are in use.

internal-tooling/package.json

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
{
2+
"name": "@warp-drive/internal-tooling",
3+
"version": "5.4.0-alpha.142",
4+
"description": "Internal Tooling for the WarpDrive Project Monorepo | Unpublished",
5+
"private": true,
6+
"type": "module",
7+
"files": [
8+
"src"
9+
],
10+
"bin": {
11+
"sync-logos": "src/sync-logos.ts",
12+
"sync-license": "src/sync-license.ts",
13+
"sync-references": "src/sync-references.ts"
14+
},
15+
"dependencies": {
16+
"@types/bun": "^1.2.4",
17+
"typescript": "^5.8.2",
18+
"chalk": "5.4.1",
19+
"debug": "4.4.0",
20+
"@types/debug": "4.1.12",
21+
"comment-json": "^4.2.5",
22+
"@pnpm/find-workspace-dir": "1000.1.0",
23+
"@pnpm/find-workspace-packages": "6.0.9",
24+
"@pnpm/logger": "1000.0.0"
25+
},
26+
"volta": {
27+
"extends": "../package.json"
28+
}
29+
}

internal-tooling/src/-utils.ts

+179
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,179 @@
1+
import type { BunFile } from 'bun';
2+
import path from 'path';
3+
import type { CommentObject } from 'comment-json';
4+
import { findWorkspaceDir } from '@pnpm/find-workspace-dir';
5+
import { findWorkspacePackages, type Project } from '@pnpm/find-workspace-packages';
6+
7+
export async function getMonorepoRoot() {
8+
const workspaceDir = await findWorkspaceDir(process.cwd());
9+
10+
if (workspaceDir) {
11+
return workspaceDir;
12+
}
13+
14+
const MAX_DEPTH = 10;
15+
// are we in the root?
16+
let currentDir = process.cwd();
17+
let depth = 0;
18+
while (depth < MAX_DEPTH) {
19+
const lockfileFile = path.join(currentDir, 'pnpm-lock.yaml');
20+
if (await Bun.file(lockfileFile).exists()) {
21+
return currentDir;
22+
}
23+
currentDir = path.join(currentDir, '../');
24+
depth++;
25+
}
26+
27+
throw new Error(`Could not find monorepo root from cwd ${process.cwd()}`);
28+
}
29+
30+
export async function getPackageJson({ packageDir, packagesDir }: { packageDir: string; packagesDir: string }) {
31+
const packageJsonPath = path.join(packagesDir, packageDir, 'package.json');
32+
const packageJsonFile = Bun.file(packageJsonPath);
33+
const pkg = await packageJsonFile.json();
34+
return { file: packageJsonFile, pkg, path: packageJsonPath, nicePath: path.join(packageDir, 'package.json') };
35+
}
36+
37+
type PkgJsonFile = {
38+
name: string;
39+
version: string;
40+
files?: string[];
41+
license?: string;
42+
private?: boolean;
43+
dependencies?: Record<string, string>;
44+
devDependencies?: Record<string, string>;
45+
peerDependencies?: Record<string, string>;
46+
scripts?: Record<string, string>;
47+
main?: string;
48+
peerDependenciesMeta?: Record<string, { optional: boolean }>;
49+
};
50+
51+
export type TsConfigFile = {
52+
include?: string[];
53+
compilerOptions?: {
54+
lib?: string[];
55+
module?: string;
56+
target?: string;
57+
moduleResolution?: string;
58+
moduleDetection?: string;
59+
erasableSyntaxOnly?: boolean;
60+
allowImportingTsExtensions?: boolean;
61+
verbatimModuleSyntax?: boolean;
62+
isolatedModules?: boolean;
63+
isolatedDeclarations?: boolean;
64+
pretty?: boolean;
65+
strict?: boolean;
66+
experimentalDecorators?: boolean;
67+
allowJs?: boolean;
68+
checkJs?: boolean;
69+
rootDir?: string;
70+
baseUrl?: string;
71+
declarationMap?: boolean;
72+
inlineSourceMap?: boolean;
73+
inlineSources?: boolean;
74+
skipLibCheck?: boolean;
75+
declaration?: boolean;
76+
declarationDir?: string;
77+
incremental?: boolean;
78+
composite?: boolean;
79+
emitDeclarationOnly?: boolean;
80+
noEmit?: boolean;
81+
paths?: Record<string, string[]>;
82+
types?: string[];
83+
};
84+
references?: { path: string }[];
85+
};
86+
87+
interface BaseProjectPackage {
88+
project: Project;
89+
packages: Map<string, Project>;
90+
pkgFile: BunFile;
91+
tsconfigFile: BunFile;
92+
pkgPath: string;
93+
tsconfigPath: string;
94+
pkg: PkgJsonFile;
95+
save: (editStatus: { pkgEdited: boolean; configEdited: Boolean }) => Promise<void>;
96+
}
97+
98+
export interface ProjectPackageWithTsConfig extends BaseProjectPackage {
99+
tsconfig: CommentObject & TsConfigFile;
100+
hasTsConfig: true;
101+
}
102+
103+
interface ProjectPackageWithoutTsConfig extends BaseProjectPackage {
104+
tsconfig: null;
105+
hasTsConfig: false;
106+
}
107+
108+
export type ProjectPackage = ProjectPackageWithTsConfig | ProjectPackageWithoutTsConfig;
109+
110+
async function collectAllPackages(dir: string) {
111+
const packages = await findWorkspacePackages(dir);
112+
const pkgMap = new Map<string, Project>();
113+
for (const pkg of packages) {
114+
if (!pkg.manifest.name) {
115+
throw new Error(`Package at ${pkg.dir} does not have a name`);
116+
}
117+
pkgMap.set(pkg.manifest.name, pkg);
118+
}
119+
120+
return pkgMap;
121+
}
122+
123+
export async function walkPackages(
124+
cb: (pkg: ProjectPackage, projects: Map<string, ProjectPackage>) => void | Promise<void>,
125+
options: {
126+
excludeTests?: boolean;
127+
excludePrivate?: boolean;
128+
excludeRoot?: boolean;
129+
excludeTooling?: boolean;
130+
excludeConfig?: boolean;
131+
} = {}
132+
) {
133+
const config = Object.assign(
134+
{ excludeTests: false, excludePrivate: false, excludeRoot: true, excludeTooling: true, excludeConfig: true },
135+
options
136+
);
137+
const JSONC = await import('comment-json');
138+
const dir = await getMonorepoRoot();
139+
const packages = await collectAllPackages(dir);
140+
const projects = new Map<string, ProjectPackageWithTsConfig>();
141+
142+
for (const [name, project] of packages) {
143+
if (config.excludeRoot && name === 'root') continue;
144+
if (config.excludePrivate && project.manifest.private) continue;
145+
if (config.excludeTooling && name === '@warp-drive/internal-tooling') continue;
146+
if (config.excludeConfig && name === '@warp-drive/config') continue;
147+
if (config.excludeTests && project.dir === 'tests') continue;
148+
149+
const pkgPath = path.join(project.dir, 'package.json');
150+
const tsconfigPath = path.join(project.dir, 'tsconfig.json');
151+
const pkgFile = Bun.file(pkgPath);
152+
const tsconfigFile = Bun.file(tsconfigPath);
153+
const pkg = (await pkgFile.json()) as PkgJsonFile;
154+
const hasTsConfig = await tsconfigFile.exists();
155+
const tsconfig = hasTsConfig ? (JSONC.parse(await tsconfigFile.text()) as CommentObject & TsConfigFile) : null;
156+
157+
const pkgObj = {
158+
project,
159+
packages,
160+
pkgFile,
161+
tsconfigFile,
162+
pkgPath,
163+
hasTsConfig,
164+
tsconfigPath,
165+
pkg,
166+
tsconfig,
167+
save: async ({ pkgEdited, configEdited }: { pkgEdited: boolean; configEdited: Boolean }) => {
168+
if (pkgEdited) await pkgFile.write(JSON.stringify(pkg, null, 2));
169+
if (configEdited) await tsconfigFile.write(JSONC.stringify(tsconfig, null, 2));
170+
},
171+
} as ProjectPackageWithTsConfig;
172+
173+
projects.set(name, pkgObj);
174+
}
175+
176+
for (const project of projects.values()) {
177+
await cb(project, projects);
178+
}
179+
}

internal-tooling/src/sync-license.ts

+74
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
#! /usr/bin/env bun
2+
3+
import path from 'path';
4+
import fs from 'fs';
5+
import debug from 'debug';
6+
import chalk from 'chalk';
7+
import type { BunFile } from 'bun';
8+
import { getMonorepoRoot, getPackageJson } from './-utils';
9+
10+
const log = debug('wd:sync-license');
11+
12+
async function updatePackageJson({ pkg, file, nicePath }: { pkg: any; file: BunFile; path: string; nicePath: string }) {
13+
let edited = false;
14+
// ensure "files" field in package.json includes "LICENSE.md"
15+
if (!pkg.files) {
16+
pkg.files = ['LICENSE.md'];
17+
edited = true;
18+
log(`\t\t📝 Added "LICENSE.md" to "files" in ${nicePath}`);
19+
} else if (!pkg.files.includes('LICENSE.md')) {
20+
pkg.files.push('LICENSE.md');
21+
edited = true;
22+
log(`\t\t📝 Added "LICENSE.md" to "files" in ${nicePath}`);
23+
}
24+
25+
if (pkg.license !== 'MIT') {
26+
pkg.license = 'MIT';
27+
edited = true;
28+
log(`\t\t⚖️ Updated "license" to "MIT" in ${nicePath}`);
29+
}
30+
31+
if (edited) {
32+
await file.write(JSON.stringify(pkg, null, 2));
33+
}
34+
}
35+
36+
async function main() {
37+
log(
38+
`\n\t${chalk.gray('=').repeat(60)}\n\t\t${chalk.magentaBright('@warp-drive/')}${chalk.greenBright('internal-tooling')} Sync LICENSE.md\n\t${chalk.gray('=').repeat(60)}\n\n\t\t${chalk.gray(`Syncing LICENSE.md from monorepo root to each public package`)}\n\n`
39+
);
40+
const monorepoRoot = await getMonorepoRoot();
41+
42+
// sync the LICENSE.md file from the monorepo root to each
43+
// public package
44+
45+
const licenseFilePath = path.join(monorepoRoot, 'LICENSE.md');
46+
const packagesDir = path.join(monorepoRoot, 'packages');
47+
48+
for (const packageDir of fs.readdirSync(packagesDir)) {
49+
const details = await getPackageJson({ packageDir, packagesDir });
50+
51+
if (details.pkg.private) {
52+
log(`\t\t🔒 Skipping private package ${details.nicePath}`);
53+
continue;
54+
}
55+
56+
const packageFullDir = path.join(packagesDir, packageDir);
57+
const packageLicensePath = path.join(packageFullDir, 'LICENSE.md');
58+
59+
// remove th existing LICENSE.md file if it exists
60+
if (fs.existsSync(packageLicensePath)) {
61+
fs.rmSync(packageLicensePath);
62+
log(`\t\t💨 Deleted existing LICENSE.md in ${packageDir}`);
63+
}
64+
65+
fs.copyFileSync(licenseFilePath, packageLicensePath);
66+
log(`\t\t⚖️ Copied LICENSE.md to ${packageDir}`);
67+
68+
await updatePackageJson(details);
69+
70+
log('\n');
71+
}
72+
}
73+
74+
main();

0 commit comments

Comments
 (0)