mirror of
https://github.com/nilbuild/diffity.git
synced 2026-09-19 07:26:16 +08:00
Fix PR URL arg parsing and tour file check
This commit is contained in:
Generated
+2
-28
@@ -7,7 +7,7 @@
|
||||
"": {
|
||||
"name": "@diffity",
|
||||
"version": "0.3.0",
|
||||
"license": "PolyForm-Shield-1.0.0",
|
||||
"license": "MIT",
|
||||
"workspaces": [
|
||||
"packages/cli",
|
||||
"packages/git",
|
||||
@@ -596,7 +596,6 @@
|
||||
"cpu": [
|
||||
"ppc64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -613,7 +612,6 @@
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -630,7 +628,6 @@
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -647,7 +644,6 @@
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -664,7 +660,6 @@
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -681,7 +676,6 @@
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -698,7 +692,6 @@
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -715,7 +708,6 @@
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -732,7 +724,6 @@
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -749,7 +740,6 @@
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -766,7 +756,6 @@
|
||||
"cpu": [
|
||||
"ia32"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -783,7 +772,6 @@
|
||||
"cpu": [
|
||||
"loong64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -800,7 +788,6 @@
|
||||
"cpu": [
|
||||
"mips64el"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -817,7 +804,6 @@
|
||||
"cpu": [
|
||||
"ppc64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -834,7 +820,6 @@
|
||||
"cpu": [
|
||||
"riscv64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -851,7 +836,6 @@
|
||||
"cpu": [
|
||||
"s390x"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -868,7 +852,6 @@
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -885,7 +868,6 @@
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -902,7 +884,6 @@
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -919,7 +900,6 @@
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -936,7 +916,6 @@
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -953,7 +932,6 @@
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -970,7 +948,6 @@
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -987,7 +964,6 @@
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -1004,7 +980,6 @@
|
||||
"cpu": [
|
||||
"ia32"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -1021,7 +996,6 @@
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -8191,7 +8165,7 @@
|
||||
"packages/cli": {
|
||||
"name": "diffity",
|
||||
"version": "0.9.5",
|
||||
"license": "PolyForm-Shield-1.0.0",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"better-sqlite3": "^12.8.0",
|
||||
"commander": "^14.0.3",
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import { existsSync, statSync } from 'node:fs';
|
||||
import { join, isAbsolute } from 'node:path';
|
||||
import type { Command } from 'commander';
|
||||
import pc from 'picocolors';
|
||||
import { isGitRepo, getDiffFiles, resolveRef } from '@diffity/git';
|
||||
import { isGitRepo, getDiffFiles, resolveRef, getRepoRoot } from '@diffity/git';
|
||||
import { getCurrentSession } from './session.js';
|
||||
import {
|
||||
createThread,
|
||||
@@ -28,6 +30,24 @@ function requireSession() {
|
||||
return session;
|
||||
}
|
||||
|
||||
function assertFileExists(filePath: string): void {
|
||||
if (isAbsolute(filePath)) {
|
||||
console.error(pc.red(`Error: --file must be relative to the repo root, got absolute path: ${filePath}`));
|
||||
process.exit(1);
|
||||
}
|
||||
const abs = join(getRepoRoot(), filePath);
|
||||
if (!existsSync(abs) || !statSync(abs).isFile()) {
|
||||
console.error(pc.red(`Error: File not found at repo root: ${filePath}`));
|
||||
console.error(pc.dim(` Checked: ${abs}`));
|
||||
if (filePath.includes('..')) {
|
||||
console.error(pc.dim(` Tip: consecutive dots suggest a shell variable expanded to empty.`));
|
||||
console.error(pc.dim(` If your path contains "$" (e.g. "teams.$teamId.tsx"), single-quote the --file value`));
|
||||
console.error(pc.dim(` or escape it: --file 'apps/routes/teams.$teamId.tsx'`));
|
||||
}
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
function resolveThreadId(shortId: string, sessionId: string): Thread {
|
||||
const thread = getThread(shortId);
|
||||
if (!thread) {
|
||||
@@ -120,6 +140,7 @@ Examples:
|
||||
process.exit(1);
|
||||
}
|
||||
const session = requireSession();
|
||||
assertFileExists(opts.file);
|
||||
if (session.ref !== '__tree__') {
|
||||
const diffFiles = getDiffFiles(session.ref);
|
||||
if (!diffFiles.includes(opts.file)) {
|
||||
@@ -245,6 +266,7 @@ Examples:
|
||||
.option('--json', 'Output as JSON')
|
||||
.action((opts) => {
|
||||
requireSession();
|
||||
assertFileExists(opts.file);
|
||||
const endLine = opts.endLine ?? opts.line;
|
||||
const step = addTourStep(opts.tour, opts.file, opts.line, endLine, opts.body, opts.annotation);
|
||||
if (opts.json) {
|
||||
|
||||
@@ -80,6 +80,26 @@ range syntax (main..feature, main...feature) also work.`)
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
// When the first positional is a PR URL, `passThroughOptions()` above slurps any
|
||||
// trailing flags (e.g. `diffity <url> --no-open`) into `refs` as positional args.
|
||||
// Without this reparse, `refs.length === 1` would be false and the PR URL path
|
||||
// would be skipped, producing a confusing "not a valid git reference" error.
|
||||
if (refs.length > 1 && isGitHubPrUrl(refs[0])) {
|
||||
const extras = refs.splice(1);
|
||||
for (const arg of extras) {
|
||||
switch (arg) {
|
||||
case '--no-open': opts.open = false; break;
|
||||
case '--quiet': opts.quiet = true; break;
|
||||
case '--dark': opts.dark = true; break;
|
||||
case '--unified': opts.unified = true; break;
|
||||
case '--new': opts.new = true; break;
|
||||
default:
|
||||
console.error(pc.red(`Error: Unexpected argument after PR URL: ${arg}`));
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (refs.length === 1 && isGitHubPrUrl(refs[0])) {
|
||||
const parsed = parseGitHubPrUrl(refs[0]);
|
||||
if (!parsed) {
|
||||
|
||||
@@ -36,7 +36,7 @@ When the argument is a **GitHub PR URL** (matching `github.com/owner/repo/pull/N
|
||||
2. **If the argument is a GitHub PR URL**:
|
||||
- Check `gh` is installed and authenticated: run `gh auth status`. If not authenticated, stop and ask the user to run `gh auth login`.
|
||||
- Verify the current repo matches the PR's repo: run `gh repo view --json nameWithOwner -q .nameWithOwner` and confirm it matches the `owner/repo` in the URL. If it doesn't, stop and tell the user they need to be inside the PR's repository clone — diffity can't tour a PR for a repo you don't have checked out.
|
||||
- Start diffity against the PR: run `{{binary}} <pr-url> --no-open` using the Bash tool with `run_in_background: true`. This checks out the PR's branch locally and starts a diff-scoped session. Wait 2 seconds, then run `{{binary}} list --json` to get the port. You do **not** also need a tree instance — the diff session supports `agent tour-*` commands.
|
||||
- Start diffity against the PR: run `{{binary}} --no-open <pr-url>` using the Bash tool with `run_in_background: true`. **The `--no-open` flag must come BEFORE the URL** — commander's `passThroughOptions()` will slurp any flag that appears after the positional URL into the refs array, skipping PR handling and producing an "unknown ref" error. This command checks out the PR's branch locally and starts a diff-scoped session. Wait 2 seconds, then run `{{binary}} list --json` to get the port. You do **not** also need a tree instance — the diff session supports `agent tour-*` commands.
|
||||
3. **Otherwise**, ensure a tree instance is running: run `{{binary}} list --json`.
|
||||
- If no instance is running, start one: run `{{binary}} tree --no-open` using the Bash tool with `run_in_background: true`, wait 2 seconds, then run `{{binary}} list --json` to get the port.
|
||||
|
||||
|
||||
@@ -39,7 +39,7 @@ diffity list --json
|
||||
2. **If the argument is a GitHub PR URL**:
|
||||
- Check `gh` is installed and authenticated: run `gh auth status`. If not authenticated, stop and ask the user to run `gh auth login`.
|
||||
- Verify the current repo matches the PR's repo: run `gh repo view --json nameWithOwner -q .nameWithOwner` and confirm it matches the `owner/repo` in the URL. If it doesn't, stop and tell the user they need to be inside the PR's repository clone — diffity can't tour a PR for a repo you don't have checked out.
|
||||
- Start diffity against the PR: run `diffity <pr-url> --no-open` using the Bash tool with `run_in_background: true`. This checks out the PR's branch locally and starts a diff-scoped session. Wait 2 seconds, then run `diffity list --json` to get the port. You do **not** also need a tree instance — the diff session supports `agent tour-*` commands.
|
||||
- Start diffity against the PR: run `diffity --no-open <pr-url>` using the Bash tool with `run_in_background: true`. **The `--no-open` flag must come BEFORE the URL** — commander's `passThroughOptions()` will slurp any flag that appears after the positional URL into the refs array, skipping PR handling and producing an "unknown ref" error. This command checks out the PR's branch locally and starts a diff-scoped session. Wait 2 seconds, then run `diffity list --json` to get the port. You do **not** also need a tree instance — the diff session supports `agent tour-*` commands.
|
||||
3. **Otherwise**, ensure a tree instance is running: run `diffity list --json`.
|
||||
- If no instance is running, start one: run `diffity tree --no-open` using the Bash tool with `run_in_background: true`, wait 2 seconds, then run `diffity list --json` to get the port.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user