Skip to content

Commit

Permalink
feat: add --check option
Browse files Browse the repository at this point in the history
  • Loading branch information
sxzz committed Aug 26, 2023
1 parent 3af346a commit c97b126
Show file tree
Hide file tree
Showing 10 changed files with 139 additions and 64 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

[![Unit Test](https://github.com/sxzz/monoman/actions/workflows/unit-test.yml/badge.svg)](https://github.com/sxzz/monoman/actions/workflows/unit-test.yml)

Manage monorepo common files.

## Install

```bash
Expand Down
3 changes: 2 additions & 1 deletion bin/monoman.mjs
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
#!/usr/bin/env node
import '../dist/run-cli.js'
import { runCli } from '../dist/index.mjs'
runCli()
2 changes: 1 addition & 1 deletion monoman.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ export default defineConfig([
{
include: 'package.json',
type: 'json',
write(data: any) {
contents(data: any) {
data.name = 'monoman'
return data
},
Expand Down
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "monoman",
"version": "0.2.0",
"packageManager": "[email protected]",
"description": "Monorepo manager.",
"description": "Manage monorepo common files.",
"license": "MIT",
"homepage": "https://github.com/sxzz/monoman#readme",
"bugs": {
Expand Down Expand Up @@ -38,6 +38,8 @@
},
"dependencies": {
"@antfu/utils": "^0.7.6",
"citty": "^0.1.3",
"consola": "^3.2.3",
"fast-glob": "^3.3.1",
"unconfig": "^0.3.10"
},
Expand Down
17 changes: 17 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

82 changes: 30 additions & 52 deletions src/cli.ts
Original file line number Diff line number Diff line change
@@ -1,55 +1,33 @@
import { readFile, unlink, writeFile } from 'node:fs/promises'
import { loadConfig } from 'unconfig'
import glob from 'fast-glob'
import { toArray } from '@antfu/utils'
import { type Config, type Context } from './types'
import { defineCommand, runMain } from 'citty'
import { description, name, version } from '../package.json'
import { run } from '.'

export async function runCli() {
const config = await getConfig()

for (const item of Array.from(config)) {
const files = await glob(item.include, {
ignore: toArray(item.exclude),
absolute: true,
const main = defineCommand({
meta: {
name,
version,
description,
},
args: {
write: {
alias: 'w',
type: 'boolean',
default: true,
description: 'Write the files if they are not up to date',
},
check: {
alias: 'c',
type: 'boolean',
default: false,
description: 'Check if the files are up to date',
},
},
run: (ctx) => {
return run({
write: ctx.args.write,
check: ctx.args.check,
})
},
})

for (const filepath of files) {
const context: Context = { files, filepath }
let contents = await readFile(filepath, 'utf-8').catch(() => null)
const exists = contents !== null
if (item.type === 'text') {
if (item.write) {
contents = await item.write(contents, context)
}
} else if (item.type === 'json') {
// eslint-disable-next-line unicorn/no-lonely-if
if (item.write) {
contents = `${JSON.stringify(
await item.write(contents ? JSON.parse(contents) : null, context),
null,
2
)}\n`
}
}

if (contents != null) {
await writeFile(filepath, contents, 'utf-8')
} else if (exists) {
await unlink(filepath)
}
}
}
}

async function getConfig() {
const { config } = await loadConfig<Config>({
defaults: [],
sources: [
{
files: 'monoman.config',
extensions: ['ts', 'mts', 'cts', 'js', 'mjs', 'cjs', 'json', ''],
},
],
})
return Object.values(config)
}
export const runCli = () => runMain(main)
84 changes: 81 additions & 3 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,86 @@
import { type Config } from './types'
import { readFile, unlink, writeFile } from 'node:fs/promises'
import { loadConfig } from 'unconfig'
import { toArray } from '@antfu/utils'
import consola from 'consola'
import glob from 'fast-glob'
import { type Config, type Context } from './types'

export * from './types'
export * from './cli'

export function defineConfig(config: Config): Config {
return config
}

export * from './types'
export * from './cli'
export async function run({
write = true,
check,
}: {
check?: boolean
write?: boolean
}) {
const config = await getConfig()

for (const item of Array.from(config)) {
const files = await glob(item.include, {
ignore: toArray(item.exclude),
absolute: true,
})

for (const filepath of files) {
if (check) consola.info(`Checking ${filepath}`)

const context: Context = { files, filepath }

const actual = await readFile(filepath, 'utf-8').catch(() => null)
let expected: string | null | undefined

if (item.type === 'text') {
if (item.contents) expected = await item.contents(actual, context)
} else if (item.type === 'json') {
// eslint-disable-next-line unicorn/no-lonely-if
if (item.contents)
expected = `${JSON.stringify(
await item.contents(actual ? JSON.parse(actual) : null, context),
null,
2
)}\n`
}

if (expected === actual) continue

if (check) {
if (expected === null) {
throw new TypeError(`File ${filepath} should be deleted but exists`)
} else {
consola.fatal(
`File ${filepath} is not up to date, run with --write to update it.`
)
return
}
} else if (write) {
if (expected === null) {
// should be deleted
await unlink(filepath)
} else if (expected !== undefined)
await writeFile(filepath, expected, 'utf-8')
}
}
}

if (check) consola.success('Check passed!')
else if (write) consola.success('Files are up to date!')
}

export async function getConfig() {
const { config } = await loadConfig<Config>({
defaults: [],
sources: [
{
files: 'monoman.config',
extensions: ['ts', 'mts', 'cts', 'js', 'mjs', 'cjs', 'json', ''],
},
],
})
return Object.values(config)
}
3 changes: 0 additions & 3 deletions src/run-cli.ts

This file was deleted.

4 changes: 2 additions & 2 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@ export type Config = ({
} & (
| {
type: 'text'
write?(text: string | null, context: Context): Awaitable<string>
contents?(text: string | null, context: Context): Awaitable<string>
}
| {
type: 'json'
write?(data: unknown | null, context: Context): Awaitable<unknown>
contents?(data: unknown | null, context: Context): Awaitable<unknown>
}
))[]
2 changes: 1 addition & 1 deletion tsup.config.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { defineConfig } from 'tsup'

export default defineConfig({
entry: ['./src'],
entry: ['./src/index.ts'],
format: ['cjs', 'esm'],
target: 'node16.14',
clean: true,
Expand Down

0 comments on commit c97b126

Please sign in to comment.