Skip to content

Commit

Permalink
Added stdin/out stream options to CLI (david-yz-liu#52)
Browse files Browse the repository at this point in the history
  • Loading branch information
sarahsonder authored Jul 19, 2024
1 parent b340931 commit 058023f
Show file tree
Hide file tree
Showing 7 changed files with 227 additions and 132 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ and adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

### ✨ Enhancements

- Changed the `filePath` argument in the MemoryViz CLI to be optional and added `--output` option.

### 🐛 Bug fixes

- Fixed issue where object boxes would be drawn on top of stack frames in diagrams with large left margins.
Expand Down
10 changes: 8 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,13 +54,19 @@ For more information, check out the project [documentation website](https://www.

### MemoryViz CLI

To run MemoryViz from your terminal, run:
To use the MemoryViz CLI, run:

```console
$ npx memory-viz <path-to-file>
```

replacing `<path-to-file>` with the path to a file containing MemoryViz-compatible JSON. The output is an SVG image generated by MemoryViz and the image is saved in the current working directory. For more information, check out the project [documentation website](https://www.cs.toronto.edu/~david/memory-viz/docs/cli).
where `<path-to-file>` is the path to a file containing MemoryViz-compatible JSON. If a file path is not provided, the CLI will take input from standard input.

You may also specify an output path using the `--output` option (see documentation). If no output path is provided, the CLI will print to standard output.

_Note_: The CLI currently does not support typing input directly into the terminal. Instead, use piping or other strategies to pass data into standard input.

For more information, check out the project [documentation website](https://www.cs.toronto.edu/~david/memory-viz/docs/cli).

## Developers

Expand Down
46 changes: 30 additions & 16 deletions docs/docs/06-cli.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,48 +4,62 @@ title: MemoryViz CLI

# MemoryViz CLI

You can run MemoryViz straight from your terminal!
Run MemoryViz straight from your terminal!

## Input
The MemoryViz CLI takes in MemoryViz-compatible JSON and returns an SVG of the memory model.

To run the MemoryViz CLI, run:
## Usage

To use the MemoryViz CLI, run:

```console
$ npx memory-viz <path-to-file>
```

replacing `<path-to-file>` with the path to a file containing MemoryViz-compatible JSON. If the file content is not compatible with MemoryViz, an error will be thrown.
where `<path-to-file>` is the path to a file containing MemoryViz-compatible JSON. If a file path is not provided, the CLI will take input from standard input.

## Output
You may also specify an output path using the `--output` option (see below). If no output path is provided, the CLI will print to standard output.

The output is an SVG image generated by MemoryViz and the image is saved in the current working directory. The name of the SVG will be the same as that of the inputted file (i.e., if the inputted file is `david-is-cool.json`, the output will be `david-is-cool.svg`).
_Note_: The CLI currently does not support typing input directly into the terminal. Instead, use piping or other strategies to pass data into standard input.

## Options

Below are optional arguments used to specify the way in which the SVG image is generated.
Below are optional arguments used to specify the way in which the SVG is outputed and generated.

### `--output=<path>`

Writes generated SVG to specified path.

### `--width`

Specifies the width of the generated SVG.

```console
$ npx memory-viz <path-to-file> --width=700
```

### `--height`

Specifies the height of the generated SVG.

### `--roughjs_config<arg>`

Specifies the style of the generated SVG. Please refer to the [Rough.js documentation](https://github.com/rough-stuff/rough/wiki#options) for available options.

The argument is a comma-separated list of key-value pairs in the form `<key1=value1,key2=value2,...>`.

## Examples

This takes input from a file and prints to `stdout`.

```console
$ npx memory-viz <path-to-file> --height=700
$ npx memory-viz <path-to-file>
```

### `--roughjs_config`
This takes input from `stdin`, generates the SVG with a width of 200, and prints to `stdout`.

Specifies the style of the generated SVG. Please refer to the [Rough.js documentation](https://github.com/rough-stuff/rough/wiki#options) for available options.
```console
$ npx memory-viz --width=200
```

The argument is a comma-separated list of key-value pairs in the form `<key1=value1,key2=value2,...>`.
This takes input from a file, generates the SVG with a solid red fill, and writes the SVG to the specified path.

```console
$ npx memory-viz <path-to-file> --roughjs-config fill=red,fillStyle=solid
$ npx memory-viz <path-to-file> --output=<path> --roughjs-config fill=red,fillStyle=solid
```
10 changes: 8 additions & 2 deletions memory-viz/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,13 +54,19 @@ For more information, check out the project [documentation website](https://www.

### MemoryViz CLI

To run MemoryViz from your terminal, run:
To use the MemoryViz CLI, run:

```console
$ npx memory-viz <path-to-file>
```

replacing `<path-to-file>` with the path to a file containing MemoryViz-compatible JSON. The output is an SVG image generated by MemoryViz and the image is saved in the current working directory. For more information, check out the project [documentation website](https://www.cs.toronto.edu/~david/memory-viz/docs/cli).
where `<path-to-file>` is the path to a file containing MemoryViz-compatible JSON. If a file path is not provided, the CLI will take input from standard input.

You may also specify an output path using the `--output` option (see documentation). If no output path is provided, the CLI will print to standard output.

_Note_: The CLI currently does not support typing input directly into the terminal. Instead, use piping or other strategies to pass data into standard input.

For more information, check out the project [documentation website](https://www.cs.toronto.edu/~david/memory-viz/docs/cli).

## Developers

Expand Down
112 changes: 77 additions & 35 deletions memory-viz/bin/cli.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,30 @@ const fs = require("fs");
const path = require("path");
const { draw } = require("memory-viz");
const { program } = require("commander");
const { json } = require("node:stream/consumers");

function parseFilePath(input) {
if (input) {
return pathExists(input, `File`);
} else {
return undefined;
}
}

function parseOutputPath(input) {
return pathExists(input, `Output path`);
}

// helper function for parsing paths
function pathExists(inputPath, errMsg) {
const fullPath = path.resolve(process.cwd(), inputPath);
if (!fs.existsSync(fullPath)) {
console.error(`Error: ${errMsg} ${fullPath} does not exist.`);
process.exit(1);
} else {
return fullPath;
}
}

function parseRoughjsConfig(input) {
const pairs = input.split(",");
Expand All @@ -16,8 +40,14 @@ program
"Command line interface for generating memory model diagrams with MemoryViz"
)
.argument(
"<filepath>",
"path to a file containing MemoryViz-compatible JSON"
"[filePath]",
"path to a file containing MemoryViz-compatible JSON",
parseFilePath
)
.option(
"--output <path>",
"writes generated SVG to specified path",
parseOutputPath
)
.option("--width <value>", "width of generated SVG", "1300")
.option("--height <value>", "height of generated SVG")
Expand All @@ -29,43 +59,55 @@ program
);

program.parse();
const filePath = program.processedArgs[0];
const options = program.opts();

const filePath = program.args[0];
const absolutePath = path.resolve(process.cwd(), filePath);
if (filePath) {
const fileContent = fs.readFileSync(filePath, "utf8");

// Checks if absolutePath exists
let fileContent;
if (!fs.existsSync(absolutePath)) {
console.error(`Error: File ${absolutePath} does not exist.`);
process.exit(1);
} else {
fileContent = fs.readFileSync(absolutePath, "utf8");
}
let jsonContent;
try {
jsonContent = JSON.parse(fileContent);
} catch (err) {
console.error(`Error: Invalid JSON\n${err.message}.`);
process.exit(1);
}

let data;
try {
data = JSON.parse(fileContent);
} catch (err) {
console.error(`Error: Invalid JSON\n${err.message}.`);
process.exit(1);
runMemoryViz(jsonContent);
} else {
json(process.stdin)
.then((jsonContent) => {
runMemoryViz(jsonContent);
})
.catch((err) => {
console.error(`Error: ${err.message}.`);
process.exit(1);
});
}

let m;
try {
m = draw(data, true, {
width: program.opts().width,
height: program.opts().height,
roughjs_config: { options: program.opts().roughjsConfig },
});
} catch (err) {
console.error(`Error: ${err.message}`);
process.exit(1);
}
function runMemoryViz(jsonContent) {
let m;
try {
m = draw(jsonContent, true, {
width: options.width,
height: options.height,
roughjs_config: { options: options.roughjsConfig },
});
} catch (err) {
console.error(`Error: ${err.message}`);
process.exit(1);
}

const outputName = path.parse(filePath).name + ".svg";
try {
m.save(outputName);
} catch (err) {
console.error(`Error: ${err.message}`);
process.exit(1);
try {
if (options.output) {
const outputName = path.parse(options.output).name + ".svg";
const outputPath = path.join(options.output, outputName);
m.save(outputPath);
} else {
m.save();
}
} catch (err) {
console.error(`Error: ${err.message}`);
process.exit(1);
}
}
Loading

0 comments on commit 058023f

Please sign in to comment.