Skip to content

Commit

Permalink
feat(scripts): support build command
Browse files Browse the repository at this point in the history
  • Loading branch information
shigma committed Feb 20, 2022
1 parent 9911e72 commit a8e19a3
Show file tree
Hide file tree
Showing 4 changed files with 92 additions and 3 deletions.
6 changes: 4 additions & 2 deletions packages/scripts/src/bin.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
#!/usr/bin/env node

import registerCreateCommand from './create'
import registerBuildCommand from './build'
import registerInitCommand from './init'
import registerPublishCommand from './publish'
import CAC from 'cac'

const { version } = require('../package.json')

const cli = CAC('koishi-scripts').help().version(version)

registerCreateCommand(cli)
registerBuildCommand(cli)
registerInitCommand(cli)
registerPublishCommand(cli)

cli.parse()
Expand Down
74 changes: 74 additions & 0 deletions packages/scripts/src/build.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import { CAC } from 'cac'
import { writeFile } from 'fs-extra'
import { cwd, getPackages, PackageJson, spawnAsync, TsConfig } from './utils'

interface Node {
path?: string
meta?: PackageJson
prev?: string[]
next?: Set<string>
}

function initGraph(names: string[]) {
const packages = getPackages(names)
const nodes: Record<string, Node> = {}
for (const path in packages) {
const meta = packages[path]
if (!meta || meta.private) return
nodes[meta.name] = { path, meta, prev: [], next: new Set() }
}

for (const name in nodes) {
const { meta } = nodes[name]
const deps = {
...meta.dependencies,
...meta.devDependencies,
...meta.peerDependencies,
}
for (const dep in deps) {
if (!nodes[dep]) continue
nodes[name].prev.push(dep)
nodes[dep].next.add(name)
}
delete nodes[name].meta
}

return nodes
}

async function buildGraph(nodes: Record<string, Node>) {
function check(name: string) {
const node = nodes[name]
if (node.next.size) return true
delete nodes[name]
config.references.unshift({ path: './' + node.path })
node.prev.forEach(dep => {
nodes[dep].next.delete(name)
})
}

let names: string[]
const config: TsConfig = { files: [], references: [] }
do {
names = Object.keys(nodes)
} while (names.length && !names.every(check))

if (names.length) {
console.log(nodes)
throw new Error('circular dependency detected')
}

if (!config.references.length) return
await writeFile(cwd + '/tsconfig.temp.json', JSON.stringify(config, null, 2))

const code = await spawnAsync(['tsc', '-b', 'tsconfig.temp.json'])
if (code) process.exit(code)
}

export default function (cli: CAC) {
cli.command('build [...name]', 'build packages')
.action(async (names: string[], options) => {
const nodes = initGraph(names)
await buildGraph(nodes)
})
}
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ class Runner {
async writeManifest() {
await fsp.writeFile(this.root + '/package.json', JSON.stringify({
name: this.fullname,
private: true,
version: '1.0.0',
main: 'lib/index.js',
typings: 'lib/index.d.ts',
Expand Down Expand Up @@ -96,7 +97,8 @@ class Runner {
}

export default function (cli: CAC) {
cli.command('create [name]', 'create a new plugin')
cli.command('init [name]', 'init a new plugin')
.alias('create')
.action(async (name: string, options) => {
const meta = require(process.cwd() + '/package.json')
new Runner(meta).start(name)
Expand Down
11 changes: 11 additions & 0 deletions packages/scripts/src/utils.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import spawn from 'cross-spawn'
import globby from 'globby'
import ts from 'typescript'

export const cwd = process.cwd()
export const meta: PackageJson = require(cwd + '/package.json')
Expand Down Expand Up @@ -51,6 +52,16 @@ export interface PackageJson extends Partial<Record<DependencyType, Record<strin
workspaces: string[]
}

interface Reference {
path: string
}

export interface TsConfig {
files?: string[]
references?: Reference[]
compilerOptions?: ts.CompilerOptions
}

export function spawnAsync(args: string[]) {
const child = spawn(args[0], args.slice(1), { cwd, stdio: 'inherit' })
return new Promise<number>((resolve) => {
Expand Down

0 comments on commit a8e19a3

Please sign in to comment.