Skip to content

Commit

Permalink
new: Add interactive dependency and project graphs. (#439)
Browse files Browse the repository at this point in the history
* refactor(cli::graph): change module location

* feat(visualizer): add project

* build: hoist lazy_static to workspace root

Also add tiny-http dependency.

* feat(cli::project_graph): add workspace data to rendered html

* fix(cli/graph): get correct url for js static files

* ci(vis): specify port for serving js files

* build)vis): add cytoscape deps

* feat(vis): render basic graph

* build: hoist petgraph as workspace dependency

* feat(cli::vis): support rendering graph for deps

* chore(vis): fix linting issues

* feat(cli): add `dot` flag to dep and project graph

* chore(cli::graph): log server address

* fix(cli:graph): generate repr only when needed

* refactor(cli/graph): rename modules and templates

* refactor: extract core vis func to package

Also rename the visualizer package to
visualizer-browser.

* ci(prettier): ignore dist folder from formatter

* ci(prettier): ignore timestamp files

* test(cli): load workspace before generating dep graph

* test(graph): use new strategy

* chore(vis): change names of interfaces

* refactor(vis): extract func to respond to indv. requests

* refactor(cli/vis): rename function that serializes project

* ci(vis-browser): change extension to cjs

* ci(vis-browser): enable typecheck command

* build(vis-browser): use semver ranges

* ci(vis-browser): remove useless settings

This commit removes the common options
that were being repeated, since we are
extending from another tsconfig.

* fix(cli/graph): change names of expected env vars

* refactor(cli/graph): extract constants to module

* refactor(vis): move all code to single package

* refactor(cli/graph): add func to get node

* ci: add temp generated files to prettierignore

* refactor(website): move tailwind config to workspace root

This will allow us to share it as a preset across multiple projects.

ci(website): disable preflight only for project

* build(vis): add tailwind to project

* feat(cli/vis): pass page title in context

* feat(vis): enable dagre style graph

* feat(vis): render arrows in graph

* style(vis): fix formatting issues

* fix(core): add required imports

* Fix some stuff.

* Get build working.

* Test package.

* Fix lints.

* Add version.

Co-authored-by: Miles Johnson <[email protected]>
  • Loading branch information
IgnisDa and milesj committed Dec 19, 2022
1 parent 8437ff1 commit 4f997aa
Show file tree
Hide file tree
Showing 49 changed files with 1,423 additions and 329 deletions.
1 change: 1 addition & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ umd/
*.min.js
*.map
*.snap
*.d.ts

# Test fixtures
/tests
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ esm/
lib/
mjs/
umd/
dist/

# Artifacts
.eslintcache
Expand Down
4 changes: 4 additions & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,13 @@ lib/
mjs/
node_modules/
umd/
dist/

# Node.js formats differently
*.json

# These are Tera templates
crates/config/templates/

# visualizer
packages/visualizer/*timestamp*
17 changes: 9 additions & 8 deletions .yarn/versions/95a4fdd8.yml
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
releases:
"@moonrepo/cli": minor
"@moonrepo/core-linux-arm64-gnu": minor
"@moonrepo/core-linux-arm64-musl": minor
"@moonrepo/core-linux-x64-gnu": minor
"@moonrepo/core-linux-x64-musl": minor
"@moonrepo/core-macos-arm64": minor
"@moonrepo/core-macos-x64": minor
"@moonrepo/core-windows-x64-msvc": minor
'@moonrepo/cli': minor
'@moonrepo/core-linux-arm64-gnu': minor
'@moonrepo/core-linux-arm64-musl': minor
'@moonrepo/core-linux-x64-gnu': minor
'@moonrepo/core-linux-x64-musl': minor
'@moonrepo/core-macos-arm64': minor
'@moonrepo/core-macos-x64': minor
'@moonrepo/core-windows-x64-msvc': minor
'@moonrepo/visualizer': minor
27 changes: 27 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ default-members = ["crates/cli"]
cached = "0.40.0"
clap = "4.0.23"
criterion = { version = "0.4.0", features = ["async_tokio"] }
lazy_static = "1.4.0"
petgraph = "0.6.2"
reqwest = "0.11.12"
rustc-hash = "1.1.0"
serde = { version = "1.0.145", features = ["derive"] }
Expand Down
3 changes: 3 additions & 0 deletions crates/cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -44,13 +44,16 @@ console-subscriber = "0.1.8"
dialoguer = "0.10.2"
indicatif = "0.17.2"
itertools = "0.10.5"
lazy_static = { workspace = true }
mimalloc = { version = "0.1.32", default-features = false }
petgraph = { workspace = true }
rustc-hash = { workspace = true }
serde = { workspace = true }
serde_json = { workspace = true }
serde_yaml = { workspace = true }
strum = { version = "0.24.1", features = ["derive"] }
tera = { version = "1.17.1", features = ["preserve_order"] }
tiny_http = "0.12.0"
tokio = { workspace = true }

[dev-dependencies]
Expand Down
6 changes: 6 additions & 0 deletions crates/cli/src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,9 @@ pub enum Commands {
DepGraph {
#[arg(help = "Target to *only* graph")]
target: Option<String>,

#[arg(long, help = "Print the graph in DOT format")]
dot: bool,
},

// moon project <id>
Expand All @@ -222,6 +225,9 @@ pub enum Commands {
ProjectGraph {
#[arg(help = "ID of project to *only* graph")]
id: Option<ProjectID>,

#[arg(long, help = "Print the graph in DOT format")]
dot: bool,
},

#[command(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,15 @@
use crate::helpers::AnyError;
use crate::commands::graph::{
utils::{dep_graph_repr, respond_to_request, setup_server},
LOG_TARGET,
};
use moon::{build_dep_graph, generate_project_graph, load_workspace};
use moon_logger::info;
use moon_task::Target;

pub async fn dep_graph(target_id: &Option<String>) -> Result<(), AnyError> {
pub async fn dep_graph(
target_id: &Option<String>,
dot: bool,
) -> Result<(), Box<dyn std::error::Error>> {
let mut workspace = load_workspace().await?;
let project_graph = generate_project_graph(&mut workspace)?;
let mut dep_builder = build_dep_graph(&workspace, &project_graph);
Expand All @@ -23,7 +30,26 @@ pub async fn dep_graph(target_id: &Option<String>) -> Result<(), AnyError> {
}
}

println!("{}", dep_builder.build().to_dot());
let dep_graph = dep_builder.build();

if dot {
println!("{}", dep_graph.to_dot());

return Ok(());
}

let (server, mut tera) = setup_server().await?;
let graph_info = dep_graph_repr(&dep_graph).await;

info!(
target: LOG_TARGET,
r#"Starting server on "{}""#,
server.server_addr()
);

for req in server.incoming_requests() {
respond_to_request(req, &mut tera, &graph_info, "Dependency".to_owned())?;
}

Ok(())
}
21 changes: 21 additions & 0 deletions crates/cli/src/commands/graph/dto.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
use moon_config::ProjectID;
use serde::{Deserialize, Serialize};

#[derive(Debug, Hash, Eq, PartialEq, Serialize, Deserialize)]
pub struct GraphNodeDto {
pub id: usize,
pub label: String,
}

#[derive(Debug, Serialize, Deserialize)]
pub struct GraphEdgeDto {
pub id: ProjectID,
pub source: usize,
pub target: usize,
}

#[derive(Debug, Serialize, Deserialize)]
pub struct GraphInfoDto {
pub nodes: Vec<GraphNodeDto>,
pub edges: Vec<GraphEdgeDto>,
}
16 changes: 16 additions & 0 deletions crates/cli/src/commands/graph/graph.html.tera
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Moon Visualizer</title>
<script type="module" crossorigin src="{{ js_url }}"></script>
</head>
<body>
<script>
window.GRAPH_DATA = '{{ graph_data | safe }}';
window.PAGE_TITLE = '{{ page_title }}';
</script>
<div id="app"></div>
</body>
</html>
6 changes: 6 additions & 0 deletions crates/cli/src/commands/graph/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
pub mod dep;
mod dto;
pub mod project;
mod utils;

pub const LOG_TARGET: &str = "moon:graph";
43 changes: 43 additions & 0 deletions crates/cli/src/commands/graph/project.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
use crate::commands::graph::{
utils::{project_graph_repr, respond_to_request, setup_server},
LOG_TARGET,
};
use moon::{build_project_graph, load_workspace};
use moon_logger::info;

pub async fn project_graph(
project_id: &Option<String>,
dot: bool,
) -> Result<(), Box<dyn std::error::Error>> {
let mut workspace = load_workspace().await?;
let mut project_build = build_project_graph(&mut workspace)?;

if let Some(id) = project_id {
project_build.load(id)?;
} else {
project_build.load_all()?;
}

let project_graph = project_build.build();

if dot {
println!("{}", project_graph.to_dot());

return Ok(());
}

let (server, mut tera) = setup_server().await?;
let graph_info = project_graph_repr(&project_graph).await;

info!(
target: LOG_TARGET,
r#"Starting server on "{}""#,
server.server_addr()
);

for req in server.incoming_requests() {
respond_to_request(req, &mut tera, &graph_info, "Project".to_owned())?;
}

Ok(())
}
Loading

0 comments on commit 4f997aa

Please sign in to comment.