UNPKG

testeranto

Version:

the AI powered BDD test framework for typescript projects

259 lines (258 loc) 8.34 kB
/* eslint-disable @typescript-eslint/no-explicit-any */ /* eslint-disable @typescript-eslint/no-unused-vars */ // import { buffer } from "stream/consumers"; import { FileService, } from "../FileService"; export class GitFileService extends FileService { constructor() { super(...arguments); this.git = null; this.fs = null; this.dir = "/testeranto-git"; } files(path) { throw new Error("Method not implemented."); } projects(project) { throw new Error("Method not implemented."); } tests(project) { throw new Error("Method not implemented."); } report(project, test) { throw new Error("Method not implemented."); } fsTree(path) { throw new Error("Method not implemented."); } projectTree(project) { throw new Error("Method not implemented."); } async ensureGit() { // if (!this.git && typeof window !== "undefined") { // // Dynamically import isomorphic-git only in browser environment // // this.git = await import("isomorphic-git"); // // this.fs = await import("isomorphic-git/http/web"); // } } async ensureBufferPolyfill() { if (typeof window !== "undefined" && !window.Buffer) { try { // const buffer = await import("buffer"); window.Buffer = buffer.Buffer; } catch (error) { console.warn("Buffer polyfill not available:", error); } } } async readFile(path) { // Only run in browser environment if (typeof window === "undefined") { throw new Error("GitFileService is only available in browser environment"); } await this.ensureBufferPolyfill(); await this.ensureGit(); try { const content = await this.git.readBlob({ fs: window.fs, dir: this.dir, oid: await this.git.resolveRef({ fs: window.fs, dir: this.dir, ref: "HEAD", }), filepath: path, }); return new TextDecoder().decode(content.blob); } catch (error) { throw new Error(`Failed to read file: ${path}`); } } async readDirectory(path) { // Only run in browser environment if (typeof window === "undefined") { return []; } await this.ensureBufferPolyfill(); await this.ensureGit(); try { const files = await this.git.listFiles({ fs: window.fs, dir: this.dir, ref: "HEAD", }); return files.map((name) => ({ name, path: name, type: name.includes(".") ? "file" : "directory", })); } catch (error) { return []; } } async exists(path) { try { await this.readFile(path); return true; } catch (_a) { return false; } } async writeFile(path, content) { await this.ensureBufferPolyfill(); await this.ensureGit(); // In Git mode, files are written to the virtual file system // This would need proper implementation with IndexedDB or similar console.log("Git mode write:", path); } async createDirectory(path) { // Directories are created automatically when writing files console.log("Git mode create directory:", path); } async deleteFile(path) { await this.ensureBufferPolyfill(); await this.ensureGit(); // Mark file for deletion in next commit console.log("Git mode delete:", path); } async getFileStatus(path) { await this.ensureBufferPolyfill(); await this.ensureGit(); try { const status = await this.git.status({ fs: window.fs, dir: this.dir, filepath: path, }); return { status: status }; } catch (_a) { return { status: "unchanged" }; } } async getChanges() { await this.ensureBufferPolyfill(); await this.ensureGit(); try { const statusMatrix = await this.git.statusMatrix({ fs: window.fs, dir: this.dir, }); return statusMatrix .map(([file, head, workdir, stage]) => { let status = "unchanged"; if (head === 0 && workdir === 2) status = "added"; else if (head === 1 && workdir === 0) status = "deleted"; else if (workdir === 2) status = "modified"; else if (head !== workdir) status = "modified"; return { path: file, status }; }) .filter((change) => change.status !== "unchanged"); } catch (error) { console.warn("Failed to get changes:", error); return []; } } async commitChanges(message, description) { await this.ensureBufferPolyfill(); await this.ensureGit(); try { // Stage all changes const changes = await this.getChanges(); for (const change of changes) { if (change.status === "deleted") { await this.git.remove({ fs: window.fs, dir: this.dir, filepath: change.path, }); } else { await this.git.add({ fs: window.fs, dir: this.dir, filepath: change.path, }); } } // Commit await this.git.commit({ fs: window.fs, dir: this.dir, author: { name: "Testeranto User", email: "user@testeranto" }, message: description ? `${message}\n\n${description}` : message, }); } catch (error) { throw new Error(`Failed to commit changes: ${error instanceof Error ? error.message : "Unknown error"}`); } } async pushChanges() { await this.ensureBufferPolyfill(); await this.ensureGit(); try { await this.git.push({ fs: window.fs, http: this.fs, dir: this.dir, remote: "origin", ref: "main", onAuth: () => ({ username: "token" }), }); } catch (error) { throw new Error(`Failed to push changes: ${error instanceof Error ? error.message : "Unknown error"}`); } } async pullChanges() { await this.ensureBufferPolyfill(); await this.ensureGit(); try { await this.git.pull({ fs: window.fs, http: this.fs, dir: this.dir, remote: "origin", ref: "main", singleBranch: true, onAuth: () => ({ username: "token" }), }); } catch (error) { throw new Error(`Failed to pull changes: ${error instanceof Error ? error.message : "Unknown error"}`); } } async getCurrentBranch() { await this.ensureBufferPolyfill(); await this.ensureGit(); try { return ((await this.git.currentBranch({ fs: window.fs, dir: this.dir, })) || "main"); } catch (_a) { return "main"; } } async getRemoteStatus() { await this.ensureBufferPolyfill(); await this.ensureGit(); try { // For now, return mock data // In a real implementation, we'd compare local and remote branches return { ahead: 0, behind: 0 }; } catch (_a) { return { ahead: 0, behind: 0 }; } } }