Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/fix-cli-diff-ref.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@zpress/cli': minor
---

Add `--ref` option to `zpress diff` for comparing between commits, enabling use as a Vercel `ignoreCommand`
5 changes: 5 additions & 0 deletions .changeset/fix-ui-filetree.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@zpress/ui': patch
---

Fix missing FileTree component by pinning rspress-plugin-file-tree to 1.0.3 and copying its component files into the published dist
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
"@iconify-json/material-icon-theme": "^1.2.56",
"@iconify-json/mdi": "^1.2.3",
"@iconify-json/pixelarticons": "^1.2.4",
"@iconify-json/simple-icons": "^1.2.74",
"@iconify-json/simple-icons": "^1.2.75",
"@iconify-json/skill-icons": "^1.2.4",
"@iconify-json/vscode-icons": "^1.2.45",
"@microsoft/api-extractor": "^7.57.7",
Expand Down
2 changes: 1 addition & 1 deletion packages/cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@
"@zpress/templates": "workspace:*",
"@zpress/ui": "workspace:*",
"es-toolkit": "catalog:",
"get-port": "^7.1.0",
"get-port": "^7.2.0",
"ts-pattern": "catalog:",
"zod": "catalog:"
},
Expand Down
79 changes: 73 additions & 6 deletions packages/cli/src/commands/diff.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,40 @@
/**
* Registers the `diff` CLI command to show changed files in watched directories.
*
* By default outputs a space-separated file list to stdout (suitable for
* lefthook, scripts, and piping). Use `--pretty` for human-readable output.
* By default uses `git status` to detect uncommitted changes and outputs a
* space-separated file list to stdout (suitable for lefthook, scripts, and piping).
*
* Use `--ref <ref>` to compare between commits instead of checking working tree
* status. This uses `git diff --name-only <ref> HEAD` under the hood and exits
* with code 1 when changes are detected — matching the Vercel `ignoreCommand`
* convention (exit 1 = proceed with build, exit 0 = skip).
*
* @example
* ```bash
* # Detect uncommitted changes (default, uses git status)
* zpress diff
*
* # Compare against parent commit (CI / Vercel ignoreCommand)
* zpress diff --ref HEAD^
*
* # Compare against main branch (PR context)
* zpress diff --ref main
*
* # Human-readable output
* zpress diff --ref main --pretty
* ```
*/
export const diffCommand = command({
description: 'Show changed files in configured source directories',
options: z.object({
pretty: z.boolean().optional().default(false),
ref: z
.string()
.optional()
.describe('Git ref to compare against HEAD (e.g. HEAD^, main). Exits 1 when changes are detected.'),
}),
handler: async (ctx) => {
const { pretty } = ctx.args
const { pretty, ref } = ctx.args
const paths = createPaths(process.cwd())

const [configErr, config] = await loadConfig(paths.repoRoot)
Expand Down Expand Up @@ -58,7 +82,9 @@
return
}

const [gitErr, changed] = gitChangedFiles({ repoRoot: paths.repoRoot, dirs })
const [gitErr, changed] = ref
? gitDiffFiles({ repoRoot: paths.repoRoot, dirs, ref })
: gitChangedFiles({ repoRoot: paths.repoRoot, dirs })

Check failure on line 87 in packages/cli/src/commands/diff.ts

View workflow job for this annotation

GitHub Actions / ci

eslint(no-ternary)

Unexpected use of ternary expression

if (gitErr) {
if (pretty) {
Expand All @@ -83,10 +109,15 @@
ctx.logger.step(`Watching ${dirs.length} path(s)`)
ctx.logger.note(changed.join('\n'), `${changed.length} changed file(s)`)
ctx.logger.outro('Done')
return
} else {
process.stdout.write(`${changed.join(' ')}\n`)
}

process.stdout.write(`${changed.join(' ')}\n`)
// When --ref is used (e.g. as a Vercel ignoreCommand), exit 1 signals
// "changes detected, proceed with build". Exit 0 (no changes) means skip.
if (ref) {
process.exit(1)
}
},
})

Expand Down Expand Up @@ -251,6 +282,42 @@
return trimmed
}

/**
* Run `git diff --name-only <ref> HEAD` scoped to the given directories and return changed file paths.
*
* Use this instead of `gitChangedFiles` when comparing between commits (e.g. for
* CI ignore commands like Vercel's `ignoreCommand`), since `git status` only
* detects uncommitted changes and always returns empty on clean checkouts.
*
* @private
* @param params - Parameters for the git diff query
* @param params.repoRoot - Absolute path to the repo root
* @param params.dirs - Directories to scope the git diff to
* @param params.ref - Git ref to compare against HEAD (e.g. `HEAD^`, `main`)
* @returns Result tuple with changed file paths (repo-relative) or an error
*/
function gitDiffFiles(params: {
readonly repoRoot: string
readonly dirs: readonly string[]
readonly ref: string
}): Result<readonly string[]> {
const [err, output] = execSilent({
file: 'git',
args: ['diff', '--name-only', params.ref, 'HEAD', '--', ...params.dirs],
cwd: params.repoRoot,
})
if (err) {
return [err, null]
}
if (!output) {
return [null, []]
}
const files = output
.split('\n')
.filter((line) => line.length > 0)
return [null, files]
}

/**
* Run a command silently with an explicit argument array, returning a Result
* tuple with trimmed stdout on success or an Error on failure.
Expand Down
2 changes: 1 addition & 1 deletion packages/core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@
"gray-matter": "^4.0.3",
"jiti": "^2.6.1",
"js-yaml": "^4.1.1",
"liquidjs": "^10.25.0",
"liquidjs": "^10.25.1",
"ts-pattern": "catalog:"
},
"devDependencies": {
Expand Down
4 changes: 2 additions & 2 deletions packages/ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@
"@iconify-json/material-icon-theme": "^1.2.56",
"@iconify-json/mdi": "^1.2.3",
"@iconify-json/pixelarticons": "^1.2.4",
"@iconify-json/simple-icons": "^1.2.74",
"@iconify-json/simple-icons": "^1.2.75",
"@iconify-json/skill-icons": "^1.2.4",
"@iconify-json/vscode-icons": "^1.2.45",
"@iconify/react": "^6.0.2",
Expand All @@ -78,7 +78,7 @@
"react": "^19.2.4",
"react-dom": "^19.2.4",
"rspress-plugin-devkit": "^1.0.0",
"rspress-plugin-file-tree": "^1.0.4",
"rspress-plugin-file-tree": "1.0.3",
"rspress-plugin-katex": "^1.0.0",
"rspress-plugin-supersub": "^1.0.0",
"typescript": "catalog:",
Expand Down
4 changes: 4 additions & 0 deletions packages/ui/rslib.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@ export default defineConfig({
from: './src/plugins/mermaid/mermaid.css',
to: 'plugins/mermaid/mermaid.css',
},
{
from: './node_modules/rspress-plugin-file-tree/dist/components',
to: 'components',
},
],
},
})
Loading
Loading