chore(tools): add package selector to dev command (#9328)

This commit is contained in:
liuyi
2024-12-26 20:34:17 +08:00
committed by GitHub
parent 4ae8c2f4ef
commit 0af46c966d
18 changed files with 224 additions and 232 deletions

View File

@@ -27,7 +27,7 @@ jobs:
electron-install: false
extra-flags: workspaces focus @affine/server
- name: Build Server
run: yarn affine @affine/server build
run: yarn workspace @affine/server build
- name: Upload server dist
uses: actions/upload-artifact@v4
with:
@@ -257,7 +257,7 @@ jobs:
yarn workspaces focus @affine/server --production
- name: Generate Prisma client
run: yarn affine @affine/server prisma generate
run: yarn workspace @affine/server prisma generate
- name: Setup Version
id: version

View File

@@ -15,7 +15,7 @@
"test:coverage": "c8 ava --concurrency 1 --serial",
"test:copilot:coverage": "c8 ava --timeout=5m \"tests/**/copilot-*.spec.ts\"",
"data-migration": "cross-env NODE_ENV=script node ./src/data/index.ts",
"predeploy": "yarn prisma migrate deploy && node --import ./scripts/register.js ./dist/data/index.js run",
"predeploy": "yarn prisma migrate deploy && NODE_ENV=script node --import ./scripts/register.js ./dist/data/index.js run",
"postinstall": "prisma generate"
},
"dependencies": {

View File

@@ -206,13 +206,6 @@ export default {
cp.spawnSync('yarn', ['generate-assets'], {
stdio: 'inherit',
env: {
...process.env,
NODE_OPTIONS: (process.env.NODE_OPTIONS ?? '').replace(
'--loader ts-node/esm',
''
),
},
cwd: __dirname,
});
},

View File

@@ -42,20 +42,18 @@ if (releaseVersionEnv && electronPackageJson.version !== releaseVersionEnv) {
}
// copy web dist files to electron dist
process.env.DISTRIBUTION = 'desktop';
const cwd = repoRootDir;
// step 1: build web dist
if (!process.env.SKIP_WEB_BUILD) {
spawnSync('yarn', ['build'], {
spawnSync('yarn', ['affine', '@affine/electron', 'bundle'], {
stdio: 'inherit',
env: process.env,
cwd,
shell: true,
});
spawnSync('yarn', ['workspace', '@affine/electron', 'build'], {
spawnSync('yarn', ['affine', '@affine/electron', 'build'], {
stdio: 'inherit',
env: process.env,
cwd,

View File

@@ -7,8 +7,8 @@
"scripts": {
"build": "affine bundle",
"dev": "affine bundle --dev",
"sync": "yarn cap sync",
"sync:dev": "CAP_SERVER_URL=http://localhost:8080 yarn cap sync"
"sync": "cap sync",
"sync:dev": "CAP_SERVER_URL=http://localhost:8080 cap sync"
},
"dependencies": {
"@affine/component": "workspace:*",

View File

@@ -6302,7 +6302,7 @@ export function useAFFiNEI18N(): {
/**
* `Loading...`
*/
["com.affine.editor.at-menu.recent-docs.loading"](): string;
["com.affine.editor.at-menu.loading"](): string;
/**
* `New`
*/

View File

@@ -23,7 +23,7 @@ const config: PlaywrightTestConfig = {
webServer: [
// Intentionally not building the web, reminds you to run it by yourself.
{
command: 'yarn run -T affine bundle -p @affine/electron --dev',
command: 'yarn run -T affine dev -p @affine/electron-renderer',
port: 8080,
timeout: 120 * 1000,
reuseExistingServer: !process.env.CI,

View File

@@ -46,7 +46,7 @@ yarn affine init
```json
{
"name": "@affine/demo"
"name": "@affine/demo",
"scripts": {
"dev": "node ./dev.ts"
}
@@ -57,6 +57,20 @@ yarn affine init
affine @affine/demo dev
```
or
```json
{
"name": "@affine/demo",
"scripts": {
"dev": "r ./src/index.ts"
},
"devDependencies": {
"@affine-tools/cli": "workspace:*"
}
}
```
### Short your key presses
```bash
@@ -111,3 +125,7 @@ restart all the integrated terminals and now you get:
```bash
af web build
```
```
```

View File

@@ -27,6 +27,7 @@
"css-loader": "^7.1.2",
"cssnano": "^7.0.6",
"html-webpack-plugin": "^5.6.3",
"inquirer": "^12.3.0",
"lodash-es": "^4.17.21",
"mime-types": "^2.1.35",
"mini-css-extract-plugin": "^2.9.2",

View File

@@ -7,7 +7,7 @@ export class BuildCommand extends PackageCommand {
const args: string[] = [];
if (this.deps) {
args.push('--deps');
args.push('--deps', '--wait-deps');
}
args.push(this.package, 'build');

View File

@@ -2,6 +2,7 @@ import { AliasToPackage } from '@affine-tools/utils/distribution';
import { Logger } from '@affine-tools/utils/logger';
import { type PackageName, Workspace } from '@affine-tools/utils/workspace';
import { Command as BaseCommand, Option } from 'clipanion';
import inquirer from 'inquirer';
import * as t from 'typanion';
import type { CliContext } from './context';
@@ -32,10 +33,14 @@ export abstract class PackageCommand extends Command {
});
get package(): PackageName {
return (
const name =
AliasToPackage.get(this.packageNameOrAlias as any) ??
(this.packageNameOrAlias as PackageName)
);
(this.packageNameOrAlias as PackageName);
// check
this.workspace.getPackage(name);
return name;
}
protected _deps = Option.Boolean('--deps', false, {
@@ -76,4 +81,50 @@ export abstract class PackagesCommand extends Command {
});
}
export abstract class PackageSelectorCommand extends Command {
protected availablePackages = Workspace.PackageNames;
protected availablePackageNameArgs = (
Workspace.PackageNames as string[]
).concat(Array.from(AliasToPackage.keys()));
protected packageNameValidator = t.isOneOf(
this.availablePackageNameArgs.map(k => t.isLiteral(k))
);
protected packageNameOrAlias = Option.String('--package,-p', {
validator: this.packageNameValidator,
description: 'The package name or alias to be run with',
});
async getPackage(): Promise<PackageName> {
let name = this.packageNameOrAlias
? (AliasToPackage.get(this.packageNameOrAlias as any) ??
this.packageNameOrAlias)
: undefined;
if (!name) {
const answer = await inquirer.prompt([
{
type: 'list',
name: 'package',
message: 'Which package do you want to dev?',
choices: this.availablePackages.map(name => ({
name,
value: name,
})),
default: '@affine/web',
},
]);
name = answer.package as PackageName;
}
// check
this.workspace.getPackage(name as PackageName);
return name as PackageName;
}
}
export { Option };

View File

@@ -1,16 +1,33 @@
import { PackageCommand } from './command';
import type { PackageName } from '@affine-tools/utils/workspace';
export class DevCommand extends PackageCommand {
import { Option, PackageSelectorCommand } from './command';
export class DevCommand extends PackageSelectorCommand {
static override paths = [['dev'], ['d']];
protected override availablePackages: PackageName[] = [
'@affine/web',
'@affine/server',
'@affine/electron',
'@affine/electron-renderer',
'@affine/mobile',
'@affine/ios',
'@affine/android',
];
protected deps = Option.Boolean('--deps', {
description: 'Run dev with dependencies',
});
async execute() {
const name = await this.getPackage();
const args = [];
if (this.deps) {
args.push('--deps', '--wait-deps');
args.push('--deps');
}
args.push(this.package, 'dev');
args.push(name, 'dev');
await this.cli.run(args);
}

View File

@@ -19,6 +19,7 @@ const ignoreLoaderScripts = [
'prisma',
'cap',
'tsc',
/^r$/,
/electron(?!-)/,
];
@@ -30,7 +31,7 @@ export class RunCommand extends PackageCommand {
details: `
\`affine web <script>\` Run any script defined in package's package.json
\`affine codegen\` Generate the required files if there are any package added or removed
\`affine init\` Generate the required files if there are any package added or removed
\`affine clean\` Clean the output files of ts, cargo, webpack, etc.
@@ -88,7 +89,7 @@ export class RunCommand extends PackageCommand {
if (pkgScript) {
await this.runScript(pkg, scriptName, args.slice(1), opts);
} else {
await this.runCommand(pkg, scriptName, args.slice(1));
await this.runCommand(pkg, args);
}
}
@@ -98,9 +99,9 @@ export class RunCommand extends PackageCommand {
args: string[],
opts: RunScriptOptions = {}
) {
const script = pkg.scripts[scriptName];
const rawScript = pkg.scripts[scriptName];
if (!script) {
if (!rawScript) {
if (opts.ignoreIfNotFound) {
return;
}
@@ -108,14 +109,19 @@ export class RunCommand extends PackageCommand {
throw new Error(`Script ${scriptName} not found in ${pkg.name}`);
}
const isAFFiNECommand = script.startsWith('affine ');
const rawArgs = [...rawScript.split(' '), ...args];
const { args: extractedArgs, envs } = this.extractEnvs(rawArgs);
args = extractedArgs;
if (opts.includeDependencies) {
const depsRun = Promise.all(
pkg.deps.map(dep => {
return this.runScript(
pkg.workspace.getPackage(dep.name),
scriptName,
args,
[],
{
...opts,
ignoreIfNotFound: true,
@@ -123,6 +129,7 @@ export class RunCommand extends PackageCommand {
);
})
);
if (opts.waitDependencies) {
await depsRun;
} else {
@@ -132,34 +139,87 @@ export class RunCommand extends PackageCommand {
}
}
args = [...script.split(' '), ...args];
const isAFFiNECommand = args[0] === 'affine';
if (isAFFiNECommand) {
// remove 'affine' from 'affine xxx' command
args.shift();
args.push('-p', pkg.name);
process.env = {
...process.env,
...envs,
};
await this.cli.run(args);
} else {
args.unshift(pkg.name);
await this.runCommand(pkg, rawArgs);
}
}
async runCommand(pkg: Package, args: string[]) {
const { args: extractedArgs, envs } = this.extractEnvs(args);
args = extractedArgs;
const bin = args[0] === 'yarn' ? args[1] : args[0];
const loader = currentDir.join('../register.js').toFileUrl().toString();
// very simple test for auto ts/mjs scripts
const isLoaderRequired =
!ignoreLoaderScripts.some(ignore => new RegExp(ignore).test(bin)) ||
process.env.NODE_OPTIONS?.includes('ts-node/esm') ||
process.env.NODE_OPTIONS?.includes(loader);
let NODE_OPTIONS = process.env.NODE_OPTIONS
? [process.env.NODE_OPTIONS]
: [];
if (isLoaderRequired) {
NODE_OPTIONS.push(`--import=${loader}`);
}
await this.cli.run(args);
}
if (args[0] !== 'yarn') {
// add 'yarn' to the command so we can bypass bin execution to it
args.unshift('yarn');
}
async runCommand(pkg: Package, scriptName: string, args: string[]) {
// very simple test for auto ts/mjs scripts
// TODO(@forehalo): bypass cross-env and fetch the next script after envs
const isLoaderRequired = !ignoreLoaderScripts.some(ignore =>
new RegExp(ignore).test(scriptName)
);
await execAsync(pkg.name, ['yarn', scriptName, ...args], {
await execAsync(pkg.name, args, {
cwd: pkg.path.value,
...(isLoaderRequired
? {
env: {
NODE_OPTIONS: `--import=${currentDir.join('../register.js').toFileUrl()}`,
},
}
: {}),
env: {
...envs,
NODE_OPTIONS: NODE_OPTIONS.join(' '),
},
});
}
private extractEnvs(args: string[]): {
args: string[];
envs: Record<string, string>;
} {
const envs: Record<string, string> = {};
let i = 0;
while (i < args.length) {
const arg = args[i];
if (arg === 'cross-env') {
i++;
continue;
}
const match = arg.match(/^([A-Z_]+)=(.+)$/);
if (match) {
envs[match[1]] = match[2];
i++;
} else {
// not envs any more
break;
}
}
return {
args: args.slice(i),
envs,
};
}
}

View File

@@ -316,7 +316,6 @@ export function createWebpackConfig(
// copy the shared public assets into dist
from: pkg.workspace.getPackage('@affine/core').join('public')
.value,
to: pkg.distPath.value,
},
],
}),

View File

@@ -6,15 +6,15 @@
"description": "Automatically bump the versionCode and versionName of an Android app from the Google Play Store versions",
"main": "index.ts",
"scripts": {
"bump": "node --import @oxc-node/core/register index.ts"
"bump": "r ./index.ts"
},
"dependencies": {
"@affine-tools/cli": "workspace:*",
"@affine-tools/utils": "workspace:*",
"@googleapis/androidpublisher": "^22.0.0",
"@oxc-node/core": "^0.0.16"
"typescript": "^5.7.2"
},
"devDependencies": {
"@types/node": "^20.17.10",
"typescript": "^5.7.2"
"@types/node": "^20.17.10"
}
}

View File

@@ -9,6 +9,7 @@ export const PackageToDistribution = new Map<
['@affine/admin', 'admin'],
['@affine/web', 'web'],
['@affine/electron-renderer', 'desktop'],
['@affine/electron', 'desktop'],
['@affine/mobile', 'mobile'],
['@affine/ios', 'ios'],
['@affine/android', 'android'],

View File

@@ -534,7 +534,7 @@ export const PackageList = [
{
location: 'tools/playstore-auto-bump',
name: '@affine/playstore-auto-bump',
workspaceDependencies: ['tools/utils'],
workspaceDependencies: ['tools/cli', 'tools/utils'],
},
{
location: 'tools/utils',

200
yarn.lock
View File

@@ -114,6 +114,7 @@ __metadata:
css-loader: "npm:^7.1.2"
cssnano: "npm:^7.0.6"
html-webpack-plugin: "npm:^5.6.3"
inquirer: "npm:^12.3.0"
lodash-es: "npm:^4.17.21"
mime-types: "npm:^2.1.35"
mini-css-extract-plugin: "npm:^2.9.2"
@@ -723,9 +724,9 @@ __metadata:
version: 0.0.0-use.local
resolution: "@affine/playstore-auto-bump@workspace:tools/playstore-auto-bump"
dependencies:
"@affine-tools/cli": "workspace:*"
"@affine-tools/utils": "workspace:*"
"@googleapis/androidpublisher": "npm:^22.0.0"
"@oxc-node/core": "npm:^0.0.16"
"@types/node": "npm:^20.17.10"
typescript: "npm:^5.7.2"
languageName: unknown
@@ -7041,7 +7042,7 @@ __metadata:
languageName: node
linkType: hard
"@inquirer/prompts@npm:^7.0.0":
"@inquirer/prompts@npm:^7.0.0, @inquirer/prompts@npm:^7.2.1":
version: 7.2.1
resolution: "@inquirer/prompts@npm:7.2.1"
dependencies:
@@ -10289,177 +10290,6 @@ __metadata:
languageName: node
linkType: hard
"@oxc-node/core-android-arm-eabi@npm:0.0.16":
version: 0.0.16
resolution: "@oxc-node/core-android-arm-eabi@npm:0.0.16"
conditions: os=android & cpu=arm
languageName: node
linkType: hard
"@oxc-node/core-android-arm64@npm:0.0.16":
version: 0.0.16
resolution: "@oxc-node/core-android-arm64@npm:0.0.16"
conditions: os=android & cpu=arm64
languageName: node
linkType: hard
"@oxc-node/core-darwin-arm64@npm:0.0.16":
version: 0.0.16
resolution: "@oxc-node/core-darwin-arm64@npm:0.0.16"
conditions: os=darwin & cpu=arm64
languageName: node
linkType: hard
"@oxc-node/core-darwin-x64@npm:0.0.16":
version: 0.0.16
resolution: "@oxc-node/core-darwin-x64@npm:0.0.16"
conditions: os=darwin & cpu=x64
languageName: node
linkType: hard
"@oxc-node/core-freebsd-x64@npm:0.0.16":
version: 0.0.16
resolution: "@oxc-node/core-freebsd-x64@npm:0.0.16"
conditions: os=freebsd & cpu=x64
languageName: node
linkType: hard
"@oxc-node/core-linux-arm-gnueabihf@npm:0.0.16":
version: 0.0.16
resolution: "@oxc-node/core-linux-arm-gnueabihf@npm:0.0.16"
conditions: os=linux & cpu=arm
languageName: node
linkType: hard
"@oxc-node/core-linux-arm64-gnu@npm:0.0.16":
version: 0.0.16
resolution: "@oxc-node/core-linux-arm64-gnu@npm:0.0.16"
conditions: os=linux & cpu=arm64 & libc=glibc
languageName: node
linkType: hard
"@oxc-node/core-linux-arm64-musl@npm:0.0.16":
version: 0.0.16
resolution: "@oxc-node/core-linux-arm64-musl@npm:0.0.16"
conditions: os=linux & cpu=arm64 & libc=musl
languageName: node
linkType: hard
"@oxc-node/core-linux-ppc64-gnu@npm:0.0.16":
version: 0.0.16
resolution: "@oxc-node/core-linux-ppc64-gnu@npm:0.0.16"
conditions: os=linux & cpu=ppc64 & libc=glibc
languageName: node
linkType: hard
"@oxc-node/core-linux-s390x-gnu@npm:0.0.16":
version: 0.0.16
resolution: "@oxc-node/core-linux-s390x-gnu@npm:0.0.16"
conditions: os=linux & cpu=s390x & libc=glibc
languageName: node
linkType: hard
"@oxc-node/core-linux-x64-gnu@npm:0.0.16":
version: 0.0.16
resolution: "@oxc-node/core-linux-x64-gnu@npm:0.0.16"
conditions: os=linux & cpu=x64 & libc=glibc
languageName: node
linkType: hard
"@oxc-node/core-linux-x64-musl@npm:0.0.16":
version: 0.0.16
resolution: "@oxc-node/core-linux-x64-musl@npm:0.0.16"
conditions: os=linux & cpu=x64 & libc=musl
languageName: node
linkType: hard
"@oxc-node/core-wasm32-wasi@npm:0.0.16":
version: 0.0.16
resolution: "@oxc-node/core-wasm32-wasi@npm:0.0.16"
dependencies:
"@napi-rs/wasm-runtime": "npm:^0.2.5"
conditions: cpu=wasm32
languageName: node
linkType: hard
"@oxc-node/core-win32-arm64-msvc@npm:0.0.16":
version: 0.0.16
resolution: "@oxc-node/core-win32-arm64-msvc@npm:0.0.16"
conditions: os=win32 & cpu=arm64
languageName: node
linkType: hard
"@oxc-node/core-win32-ia32-msvc@npm:0.0.16":
version: 0.0.16
resolution: "@oxc-node/core-win32-ia32-msvc@npm:0.0.16"
conditions: os=win32 & cpu=ia32
languageName: node
linkType: hard
"@oxc-node/core-win32-x64-msvc@npm:0.0.16":
version: 0.0.16
resolution: "@oxc-node/core-win32-x64-msvc@npm:0.0.16"
conditions: os=win32 & cpu=x64
languageName: node
linkType: hard
"@oxc-node/core@npm:^0.0.16":
version: 0.0.16
resolution: "@oxc-node/core@npm:0.0.16"
dependencies:
"@oxc-node/core-android-arm-eabi": "npm:0.0.16"
"@oxc-node/core-android-arm64": "npm:0.0.16"
"@oxc-node/core-darwin-arm64": "npm:0.0.16"
"@oxc-node/core-darwin-x64": "npm:0.0.16"
"@oxc-node/core-freebsd-x64": "npm:0.0.16"
"@oxc-node/core-linux-arm-gnueabihf": "npm:0.0.16"
"@oxc-node/core-linux-arm64-gnu": "npm:0.0.16"
"@oxc-node/core-linux-arm64-musl": "npm:0.0.16"
"@oxc-node/core-linux-ppc64-gnu": "npm:0.0.16"
"@oxc-node/core-linux-s390x-gnu": "npm:0.0.16"
"@oxc-node/core-linux-x64-gnu": "npm:0.0.16"
"@oxc-node/core-linux-x64-musl": "npm:0.0.16"
"@oxc-node/core-wasm32-wasi": "npm:0.0.16"
"@oxc-node/core-win32-arm64-msvc": "npm:0.0.16"
"@oxc-node/core-win32-ia32-msvc": "npm:0.0.16"
"@oxc-node/core-win32-x64-msvc": "npm:0.0.16"
dependenciesMeta:
"@oxc-node/core-android-arm-eabi":
optional: true
"@oxc-node/core-android-arm64":
optional: true
"@oxc-node/core-darwin-arm64":
optional: true
"@oxc-node/core-darwin-x64":
optional: true
"@oxc-node/core-freebsd-x64":
optional: true
"@oxc-node/core-linux-arm-gnueabihf":
optional: true
"@oxc-node/core-linux-arm64-gnu":
optional: true
"@oxc-node/core-linux-arm64-musl":
optional: true
"@oxc-node/core-linux-ppc64-gnu":
optional: true
"@oxc-node/core-linux-s390x-gnu":
optional: true
"@oxc-node/core-linux-x64-gnu":
optional: true
"@oxc-node/core-linux-x64-musl":
optional: true
"@oxc-node/core-wasm32-wasi":
optional: true
"@oxc-node/core-win32-arm64-msvc":
optional: true
"@oxc-node/core-win32-ia32-msvc":
optional: true
"@oxc-node/core-win32-x64-msvc":
optional: true
checksum: 10/aecafd078baa2440306d33e4ccd6b5c911be17a4297f3828202d81ebf01ddaea35ec64f94f20a89cdaf57d1b4f9a68e3e5f3fcf241b0fa3223060ae9e746e1c8
languageName: node
linkType: hard
"@oxlint/darwin-arm64@npm:0.15.0":
version: 0.15.0
resolution: "@oxlint/darwin-arm64@npm:0.15.0"
@@ -23559,6 +23389,23 @@ __metadata:
languageName: node
linkType: hard
"inquirer@npm:^12.3.0":
version: 12.3.0
resolution: "inquirer@npm:12.3.0"
dependencies:
"@inquirer/core": "npm:^10.1.2"
"@inquirer/prompts": "npm:^7.2.1"
"@inquirer/type": "npm:^3.0.2"
ansi-escapes: "npm:^4.3.2"
mute-stream: "npm:^2.0.0"
run-async: "npm:^3.0.0"
rxjs: "npm:^7.8.1"
peerDependencies:
"@types/node": ">=18"
checksum: 10/58c3cea920468c2f8905f64989d27990fabb6a028814360e5ae3be866a3285b10991656e164ac56eb6d3a365bc7460a16660bde740509f9bd48f531c8b9837dc
languageName: node
linkType: hard
"internal-slot@npm:^1.1.0":
version: 1.1.0
resolution: "internal-slot@npm:1.1.0"
@@ -30511,6 +30358,13 @@ __metadata:
languageName: node
linkType: hard
"run-async@npm:^3.0.0":
version: 3.0.0
resolution: "run-async@npm:3.0.0"
checksum: 10/97fb8747f7765b77ebcd311d3a33548099336f04c6434e0763039b98c1de0f1b4421000695aff8751f309c0b995d8dfd620c1f1e4c35572da38c101488165305
languageName: node
linkType: hard
"run-parallel@npm:^1.1.9":
version: 1.2.0
resolution: "run-parallel@npm:1.2.0"