Skip to content

Commit

Permalink
chore(tools): add package selector to dev command
Browse files Browse the repository at this point in the history
  • Loading branch information
forehalo committed Dec 26, 2024
1 parent cf17303 commit 26b521f
Show file tree
Hide file tree
Showing 10 changed files with 185 additions and 39 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/build-images.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion packages/backend/server/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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": {
Expand Down
6 changes: 2 additions & 4 deletions packages/frontend/apps/electron/scripts/generate-assets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,20 +43,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,
Expand Down
4 changes: 2 additions & 2 deletions packages/frontend/apps/ios/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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:*",
Expand Down
2 changes: 1 addition & 1 deletion packages/frontend/i18n/src/i18n.gen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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`
*/
Expand Down
1 change: 1 addition & 0 deletions tools/cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
57 changes: 54 additions & 3 deletions tools/cli/src/command.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -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, {
Expand Down Expand Up @@ -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 };
22 changes: 19 additions & 3 deletions tools/cli/src/dev.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,32 @@
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/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(this.package, 'dev');
args.push(name, 'dev');

await this.cli.run(args);
}
Expand Down
99 changes: 77 additions & 22 deletions tools/cli/src/run.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,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.
Expand Down Expand Up @@ -88,7 +88,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);
}
}

Expand All @@ -98,31 +98,37 @@ 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;
}

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,
}
);
})
);

if (opts.waitDependencies) {
await depsRun;
} else {
Expand All @@ -132,34 +138,83 @@ 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);
}

await this.cli.run(args);
}

async runCommand(pkg: Package, scriptName: string, args: string[]) {
async runCommand(pkg: Package, args: string[]) {
const { args: extractedArgs, envs } = this.extractEnvs(args);
args = extractedArgs;

const bin = args[0] === 'yarn' ? args[1] : args[0];

// 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)
new RegExp(ignore).test(bin)
);

await execAsync(pkg.name, ['yarn', scriptName, ...args], {
const NODE_OPTIONS = [
process.env.NODE_OPTIONS,
`--import=${currentDir.join('../register.js').toFileUrl()}`,
]
.filter(Boolean)
.join(' ');

if (args[0] !== 'yarn') {
// add 'yarn' to the command so we can bypass bin execution to it
args.unshift('yarn');
}

await execAsync(pkg.name, args, {
cwd: pkg.path.value,
...(isLoaderRequired
? {
env: {
NODE_OPTIONS: `--import=${currentDir.join('../register.js').toFileUrl()}`,
},
}
: {}),
env: {
...envs,
...(isLoaderRequired ? { NODE_OPTIONS } : {}),
},
});
}

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,
};
}
}
Loading

0 comments on commit 26b521f

Please sign in to comment.