Skip to content

Commit 72a0cea

Browse files
committed
feat: add package-manager detector logic
1 parent f984082 commit 72a0cea

18 files changed

+378
-34
lines changed

bin/gx.mjs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
#!/usr/bin/env node
2+
3+
'use strict'
4+
5+
import '../dist/main.mjs'

build.config.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { defineBuildConfig } from 'unbuild'
22
import { resolve } from 'path'
33

44
export default defineBuildConfig({
5-
entries: ['bin/gx'],
5+
entries: ['src/main'],
66
declaration: true,
77
clean: true,
88
rollup: {
@@ -19,4 +19,4 @@ export default defineBuildConfig({
1919
alias: {
2020
'@': resolve(__dirname, 'src')
2121
}
22-
})
22+
})

package.json

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,21 +13,21 @@
1313
"url": "git+https://github.com/antfu/pkg-placeholder.git"
1414
},
1515
"bin": {
16-
"gx": "dist/bin/gx.cjs"
16+
"gx": "bin/gx.mjs"
1717
},
1818
"bugs": "https://github.com/antfu/pkg-placeholder/issues",
1919
"keywords": [],
2020
"sideEffects": false,
2121
"exports": {
2222
".": {
23-
"types": "./dist/bin/gx.d.ts",
24-
"import": "./dist/bin/gx.mjs",
25-
"require": "./dist/bin/gx.cjs"
23+
"types": "./dist/main.d.ts",
24+
"import": "./dist/main.mjs",
25+
"require": "./dist/main.cjs"
2626
}
2727
},
28-
"main": "./dist/bin/gx.mjs",
29-
"module": "./dist/bin/gx.mjs",
30-
"types": "./dist/bin/gx.d.ts",
28+
"main": "./dist/main.cjs",
29+
"module": "./dist/main.mjs",
30+
"types": "./dist/main.d.ts",
3131
"typesVersions": {
3232
"*": {
3333
"*": [
@@ -75,11 +75,13 @@
7575
"*": "eslint . --fix"
7676
},
7777
"dependencies": {
78+
"@neodx/fs": "^0.0.11",
7879
"@neodx/std": "^0.3.0",
7980
"@nestjs/common": "^10.3.3",
8081
"@nestjs/core": "^10.3.3",
8182
"@nestjs/platform-express": "^10.3.3",
8283
"eslint-kit": "^10.19.0",
84+
"execa": "^8.0.1",
8385
"nest-commander": "^3.12.5"
8486
}
8587
}

pnpm-lock.yaml

Lines changed: 29 additions & 12 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/app/app.module.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
import { Module } from '@nestjs/common'
22
import { InitCommand } from '@/commands/init.command'
3+
import { PackageManagerModule } from '@/pkg-manager'
34

45
@Module({
5-
imports: [],
6+
imports: [PackageManagerModule],
67
providers: [InitCommand]
78
})
89
export class AppModule {}

src/commands/init.command.ts

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import type { AnyRecord } from '@neodx/std'
2-
import { Command, CommandRunner, Option } from 'nest-commander'
2+
import { Command, CommandRunner } from 'nest-commander'
3+
import type { AbstractPackageManager } from '@/pkg-manager'
4+
import { InjectPackageManager } from '@/pkg-manager'
35

46
@Command({
57
name: 'init',
@@ -9,18 +11,22 @@ import { Command, CommandRunner, Option } from 'nest-commander'
911
description: ''
1012
})
1113
export class InitCommand extends CommandRunner {
14+
constructor(
15+
@InjectPackageManager() private readonly manager: AbstractPackageManager
16+
) {
17+
super()
18+
}
19+
1220
public async run(param: string[], options: AnyRecord) {
1321
console.log({
1422
param,
15-
options
23+
options,
24+
manager: this.manager
1625
})
17-
}
1826

19-
@Option({
20-
flags: '-n, --number [number]',
21-
description: ''
22-
})
23-
public parseNumber(val: string): number {
24-
return Number(val)
27+
// console.log(this.manager.agent)
28+
const workspaces = await this.manager.getWorkspaces()
29+
30+
console.log(workspaces)
2531
}
2632
}

bin/gx.ts renamed to src/main.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
1-
#!/usr/bin/env node
2-
31
import { CommandFactory } from 'nest-commander'
4-
import { AppModule } from '../src/app'
2+
import { AppModule } from './app'
53

64
async function bootstrap() {
75
await CommandFactory.run(AppModule, ['error', 'warn'])

src/pkg-manager/index.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
export { AbstractPackageManager } from './managers/abstract.pkg-manager'
2+
export { PACKAGE_MANAGER } from './pkg-manager.consts'
3+
export { InjectPackageManager } from './pkg-manager.decorator'
4+
export { PackageManagerModule } from './pkg-manager.module'
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import { execa as $ } from 'execa'
2+
import type { WorkspaceProject } from '@/pkg-manager/pkg-manager.types'
3+
4+
export abstract class AbstractPackageManager {
5+
constructor(private command: string) {}
6+
7+
public abstract getWorkspaces(): Promise<WorkspaceProject[]>
8+
9+
public async run(args: string[]) {
10+
const output = await $(this.command, args)
11+
12+
return output.stdout
13+
}
14+
15+
public get agent() {
16+
return this.command
17+
}
18+
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
import { scan } from '@neodx/fs'
2+
import { resolve } from 'node:path'
3+
import * as process from 'process'
4+
import { AbstractPackageManager } from '@/pkg-manager/managers/abstract.pkg-manager'
5+
import { PackageManager } from '@/pkg-manager/pkg-manager.consts'
6+
import type { WorkspaceProject } from '@/pkg-manager/pkg-manager.types'
7+
import type { PackageJson } from '@/shared/json'
8+
import { readJson } from '@/shared/json'
9+
10+
// TODO: add yarn@berry support
11+
// TODO: split file structure to modules
12+
13+
export class BunPackageManager extends AbstractPackageManager {
14+
constructor() {
15+
super(PackageManager.BUN)
16+
}
17+
18+
public async getWorkspaces(): Promise<WorkspaceProject[]> {
19+
const packageJson = await readJson('package.json')
20+
21+
if (!packageJson) return []
22+
23+
const rawWorkspaces = packageJson.workspaces
24+
25+
const workspaces = Array.isArray(rawWorkspaces)
26+
? rawWorkspaces
27+
: rawWorkspaces!.packages
28+
29+
const projectPatterns = await scan(
30+
process.cwd(),
31+
workspaces.map((match) => resolve(match, 'package.json'))
32+
)
33+
34+
const bunWorkspaces = await Promise.all(
35+
projectPatterns.map(async (pattern) => {
36+
const scopedPkgJson = (await readJson(pattern)) as PackageJson
37+
38+
const workspaceName = scopedPkgJson.name ?? null
39+
const workspaceDir = resolve(pattern, '..')
40+
41+
return {
42+
name: workspaceName,
43+
location: workspaceDir
44+
}
45+
})
46+
)
47+
48+
return bunWorkspaces
49+
}
50+
}

0 commit comments

Comments
 (0)