mirror of
https://github.com/sst/opencode.git
synced 2025-07-07 16:14:59 +00:00
ignore: add file status command
This commit is contained in:
parent
c68aeed8d9
commit
7e5941e14b
3 changed files with 122 additions and 28 deletions
|
@ -2,12 +2,6 @@ import { File } from "../../../file"
|
|||
import { bootstrap } from "../../bootstrap"
|
||||
import { cmd } from "../cmd"
|
||||
|
||||
export const FileCommand = cmd({
|
||||
command: "file",
|
||||
builder: (yargs) => yargs.command(FileReadCommand).demandCommand(),
|
||||
async handler() {},
|
||||
})
|
||||
|
||||
const FileReadCommand = cmd({
|
||||
command: "read <path>",
|
||||
builder: (yargs) =>
|
||||
|
@ -23,3 +17,21 @@ const FileReadCommand = cmd({
|
|||
})
|
||||
},
|
||||
})
|
||||
|
||||
const FileStatusCommand = cmd({
|
||||
command: "status",
|
||||
builder: (yargs) => yargs,
|
||||
async handler() {
|
||||
await bootstrap({ cwd: process.cwd() }, async () => {
|
||||
const status = await File.status()
|
||||
console.log(JSON.stringify(status, null, 2))
|
||||
})
|
||||
},
|
||||
})
|
||||
|
||||
export const FileCommand = cmd({
|
||||
command: "file",
|
||||
builder: (yargs) =>
|
||||
yargs.command(FileReadCommand).command(FileStatusCommand).demandCommand(),
|
||||
async handler() {},
|
||||
})
|
||||
|
|
|
@ -3,13 +3,13 @@ import { Bus } from "../bus"
|
|||
import { $ } from "bun"
|
||||
import { createPatch } from "diff"
|
||||
import path from "path"
|
||||
import { status } from "isomorphic-git"
|
||||
import * as git from "isomorphic-git"
|
||||
import { App } from "../app/app"
|
||||
import fs from "fs"
|
||||
import { Log } from "../util/log"
|
||||
|
||||
export namespace File {
|
||||
const log = Log.create({ service: "files" })
|
||||
const log = Log.create({ service: "file" })
|
||||
|
||||
export const Event = {
|
||||
Edited: Bus.event(
|
||||
|
@ -20,6 +20,84 @@ export namespace File {
|
|||
),
|
||||
}
|
||||
|
||||
export async function status() {
|
||||
const app = App.info()
|
||||
if (!app.git) return []
|
||||
|
||||
// Get all changed files with line counts in one command
|
||||
const diffOutput = await $`git diff --numstat HEAD`
|
||||
.cwd(app.path.root)
|
||||
.quiet()
|
||||
.nothrow()
|
||||
.text()
|
||||
|
||||
const changedFiles = []
|
||||
|
||||
if (diffOutput.trim()) {
|
||||
const lines = diffOutput.trim().split("\n")
|
||||
for (const line of lines) {
|
||||
const [added, removed, filepath] = line.split("\t")
|
||||
changedFiles.push({
|
||||
file: filepath,
|
||||
added: added === "-" ? 0 : parseInt(added, 10),
|
||||
removed: removed === "-" ? 0 : parseInt(removed, 10),
|
||||
status: "modified",
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// Get untracked files
|
||||
const untrackedOutput = await $`git ls-files --others --exclude-standard`
|
||||
.cwd(app.path.root)
|
||||
.quiet()
|
||||
.nothrow()
|
||||
.text()
|
||||
|
||||
if (untrackedOutput.trim()) {
|
||||
const untrackedFiles = untrackedOutput.trim().split("\n")
|
||||
for (const filepath of untrackedFiles) {
|
||||
try {
|
||||
const content = await Bun.file(
|
||||
path.join(app.path.root, filepath),
|
||||
).text()
|
||||
const lines = content.split("\n").length
|
||||
changedFiles.push({
|
||||
file: filepath,
|
||||
added: lines,
|
||||
removed: 0,
|
||||
status: "added",
|
||||
})
|
||||
} catch {
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Get deleted files
|
||||
const deletedOutput = await $`git diff --name-only --diff-filter=D HEAD`
|
||||
.cwd(app.path.root)
|
||||
.quiet()
|
||||
.nothrow()
|
||||
.text()
|
||||
|
||||
if (deletedOutput.trim()) {
|
||||
const deletedFiles = deletedOutput.trim().split("\n")
|
||||
for (const filepath of deletedFiles) {
|
||||
changedFiles.push({
|
||||
file: filepath,
|
||||
added: 0,
|
||||
removed: 0, // Could get original line count but would require another git command
|
||||
status: "deleted",
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return changedFiles.map((x) => ({
|
||||
...x,
|
||||
file: path.relative(app.path.cwd, path.join(app.path.root, x.file)),
|
||||
}))
|
||||
}
|
||||
|
||||
export async function read(file: string) {
|
||||
using _ = log.time("read", { file })
|
||||
const app = App.info()
|
||||
|
@ -27,7 +105,7 @@ export namespace File {
|
|||
const content = await Bun.file(full).text()
|
||||
if (app.git) {
|
||||
const rel = path.relative(app.path.root, full)
|
||||
const diff = await status({
|
||||
const diff = await git.status({
|
||||
fs,
|
||||
dir: app.path.root,
|
||||
filepath: rel,
|
||||
|
@ -38,7 +116,9 @@ export namespace File {
|
|||
.quiet()
|
||||
.nothrow()
|
||||
.text()
|
||||
const patch = createPatch(file, original, content)
|
||||
const patch = createPatch(file, original, content, "old", "new", {
|
||||
context: Infinity,
|
||||
})
|
||||
return patch
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,28 +22,30 @@ export namespace FileWatcher {
|
|||
"file.watcher",
|
||||
() => {
|
||||
const app = App.use()
|
||||
const watcher = fs.watch(
|
||||
app.info.path.cwd,
|
||||
{ recursive: true },
|
||||
(event, file) => {
|
||||
log.info("change", { file, event })
|
||||
if (!file) return
|
||||
// for some reason async local storage is lost here
|
||||
// https://github.com/oven-sh/bun/issues/20754
|
||||
App.provideExisting(app, async () => {
|
||||
Bus.publish(Event.Updated, {
|
||||
file,
|
||||
event,
|
||||
try {
|
||||
const watcher = fs.watch(
|
||||
app.info.path.cwd,
|
||||
{ recursive: true },
|
||||
(event, file) => {
|
||||
log.info("change", { file, event })
|
||||
if (!file) return
|
||||
// for some reason async local storage is lost here
|
||||
// https://github.com/oven-sh/bun/issues/20754
|
||||
App.provideExisting(app, async () => {
|
||||
Bus.publish(Event.Updated, {
|
||||
file,
|
||||
event,
|
||||
})
|
||||
})
|
||||
})
|
||||
},
|
||||
)
|
||||
return {
|
||||
watcher,
|
||||
},
|
||||
)
|
||||
return { watcher }
|
||||
} finally {
|
||||
return {}
|
||||
}
|
||||
},
|
||||
async (state) => {
|
||||
state.watcher.close()
|
||||
state.watcher?.close()
|
||||
},
|
||||
)()
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue