Skip to content

Commit

Permalink
Command output to file
Browse files Browse the repository at this point in the history
  • Loading branch information
ianthomas23 committed May 24, 2024
1 parent 82f67fb commit 59f4994
Show file tree
Hide file tree
Showing 5 changed files with 60 additions and 12 deletions.
2 changes: 2 additions & 0 deletions src/file_system.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,6 @@ export interface IFileSystem {

// Assume new file ...
touch(path: string): Promise<void>

write(path: string, content: string): Promise<void>
}
6 changes: 5 additions & 1 deletion src/io/file_output.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,15 @@ export class FileOutput extends BufferedOutput {
this.fs = fs
this.path = path
this.append = append

if (this.append) {
throw Error("FileOutput in append mode not implemented")
}
}

override async flush(): Promise<void> {
const all_data = this.data.join()
console.log("TO FILE:", this.fs, this.path, this.append, all_data)
this.fs.write(this.path, all_data);
this.clear()
}

Expand Down
23 changes: 16 additions & 7 deletions src/jupyter_file_system.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,18 @@ export class JupyterFileSystem implements IFileSystem {
}

async list(path: string): Promise<string[]> {
const listing = await this._contentsManager.get(path, { content: true })
if (listing.type == "file") {
return [listing.name]
} else { // listing.type == "directory"
const content = listing.content as Contents.IModel[]
const filenames = content.map((model) => model.name)
return filenames.sort()
try {
const listing = await this._contentsManager.get(path, { content: true })
if (listing.type == "file") {
return [listing.name]
} else { // listing.type == "directory"
const content = listing.content as Contents.IModel[]
const filenames = content.map((model) => model.name)
return filenames.sort()
}
} catch (error: any) {
// Need to handle possible error cases here.
return []
}
}

Expand All @@ -34,5 +39,9 @@ export class JupyterFileSystem implements IFileSystem {
await this._contentsManager.rename(model.path, path)
}

async write(path: string, content: string): Promise<void> {
await this._contentsManager.save(path, { content })
}

private _contentsManager: Contents.IManager
}
22 changes: 18 additions & 4 deletions src/shell.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { CommandRegistry } from "./command_registry"
import { Context } from "./context"
import { TerminalOutput } from "./io"
import { FileOutput, Output, TerminalOutput } from "./io"
import { OutputCallback } from "./output_callback"
import { CommandNode, parse } from "./parse"
import { IFileSystem } from "./file_system"
Expand Down Expand Up @@ -105,11 +105,25 @@ export class Shell {
throw new Error(`Unknown command: '${cmdName}'`)
}

let output: Output = stdout
if (cmd.redirects) {
// Support single redirect only, write (not append) to file.
if (cmd.redirects.length > 1) {
throw Error("Only implemented a single redirect per command")
}
if (cmd.redirects[0].token.value != ">") {
throw Error("Only implemented redirect write to file")
}

const path = cmd.redirects[0].target.value
output = new FileOutput(this._filesystem, path, false)
}

const cmdArgs = cmd.suffix.map((token) => token.value)
const context = new Context(cmdArgs, this._filesystem, stdout, this._env)
//const exit_code = await command?.run(context)
const context = new Context(cmdArgs, this._filesystem, output, this._env)
//const exit_code = await command?.run(context) // Do something with exit_code
await command?.run(context)
await stdout.flush()
await output.flush()
}
} catch (error: any) {
// Send result via output?????? With color. Should be to stderr.
Expand Down
19 changes: 19 additions & 0 deletions tests/shell.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,25 @@ describe("Shell", () => {
await shell._runCommands("env")
expect(output.text).toEqual("PS1=\x1b[1;31mjs-shell:$\x1b[1;0m \r\nPWD=/\r\nCOLUMNS=0\r\nLINES=0\r\n")
})

it("should echo to terminal", async () => {
const fs = await file_system_setup("jupyter")
const output = new MockTerminalOutput()
const shell = new Shell(fs, output.callback)
await shell._runCommands("echo sometext")
expect(output.text).toEqual("sometext\r\n")
})

it("should echo to file", async () => {
const fs = await file_system_setup("jupyter")
const output = new MockTerminalOutput()
const shell = new Shell(fs, output.callback)
expect(await fs.list("afile.txt")).toEqual([])
await shell._runCommands("echo sometext > afile.txt")
expect(await fs.list("afile.txt")).toEqual(["afile.txt"])
// Should this really have appended \r\n ???
expect(await fs.get("afile.txt")).toEqual("sometext\r\n")
})
})

describe("input", () => {
Expand Down

0 comments on commit 59f4994

Please sign in to comment.