diff --git a/Cargo.lock b/Cargo.lock
index 89f666e5..2d0d25f5 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -794,6 +794,7 @@ dependencies = [
"dora-core",
"eyre",
"serde_yaml 0.9.11",
+ "tempfile",
]
[[package]]
diff --git a/binaries/cli/Cargo.toml b/binaries/cli/Cargo.toml
index 3cf09970..9c8a921d 100644
--- a/binaries/cli/Cargo.toml
+++ b/binaries/cli/Cargo.toml
@@ -14,3 +14,4 @@ clap = { version = "3.2.20", features = ["derive"] }
eyre = "0.6.8"
dora-core = { path = "../../libraries/core" }
serde_yaml = "0.9.11"
+tempfile = "3.3.0"
diff --git a/binaries/cli/src/graph/mermaid-template.html b/binaries/cli/src/graph/mermaid-template.html
new file mode 100644
index 00000000..2cd06c63
--- /dev/null
+++ b/binaries/cli/src/graph/mermaid-template.html
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+ ____insert____
+
+
+
+
+
+
diff --git a/binaries/cli/src/graph.rs b/binaries/cli/src/graph/mod.rs
similarity index 64%
rename from binaries/cli/src/graph.rs
rename to binaries/cli/src/graph/mod.rs
index 119ed428..bf53fb9b 100644
--- a/binaries/cli/src/graph.rs
+++ b/binaries/cli/src/graph/mod.rs
@@ -1,12 +1,16 @@
-use std::{
- fs,
- path::{Path, PathBuf},
-};
+use std::{fs, path::Path};
use dora_core::descriptor::Descriptor;
use eyre::Context;
-pub fn visualize_as_mermaid(dataflow: PathBuf) -> eyre::Result {
+const MERMAID_TEMPLATE: &str = include_str!("mermaid-template.html");
+
+pub fn visualize_as_html(dataflow: &Path) -> eyre::Result {
+ let mermaid = visualize_as_mermaid(dataflow)?;
+ Ok(MERMAID_TEMPLATE.replacen("____insert____", &mermaid, 1))
+}
+
+pub fn visualize_as_mermaid(dataflow: &Path) -> eyre::Result {
let descriptor = read_descriptor(&dataflow)
.with_context(|| format!("failed to read dataflow at `{}`", dataflow.display()))?;
let visualized = descriptor
diff --git a/binaries/cli/src/main.rs b/binaries/cli/src/main.rs
index 5736e158..a842b507 100644
--- a/binaries/cli/src/main.rs
+++ b/binaries/cli/src/main.rs
@@ -1,5 +1,7 @@
use clap::Parser;
-use std::path::PathBuf;
+use eyre::Context;
+use std::{io::Write, path::PathBuf};
+use tempfile::NamedTempFile;
mod build;
mod check;
@@ -20,6 +22,8 @@ enum Command {
},
Graph {
dataflow: PathBuf,
+ #[clap(long, action)]
+ mermaid: bool,
},
Build {
dataflow: PathBuf,
@@ -44,13 +48,28 @@ fn main() -> eyre::Result<()> {
dataflow,
runtime_path,
} => check::check(&dataflow, &runtime_path)?,
- Command::Graph { dataflow } => {
- let visualized = graph::visualize_as_mermaid(dataflow)?;
- println!("{visualized}");
- println!(
- "Paste the above output on https://mermaid.live/ or in a \
- ```mermaid code block on GitHub to display it."
- );
+ Command::Graph { dataflow, mermaid } => {
+ if mermaid {
+ let visualized = graph::visualize_as_mermaid(&dataflow)?;
+ println!("{visualized}");
+ println!(
+ "Paste the above output on https://mermaid.live/ or in a \
+ ```mermaid code block on GitHub to display it."
+ );
+ } else {
+ let html = graph::visualize_as_html(&dataflow)?;
+ let mut file = NamedTempFile::new().context("failed to create temp file")?;
+ file.as_file_mut().write_all(html.as_bytes())?;
+
+ let path = file.path();
+
+ println!(
+ "View graph by opening the following in your browser:\n file://{}",
+ path.display()
+ );
+
+ file.keep()?;
+ }
}
Command::Build { dataflow } => {
build::build(&dataflow)?;