Skip to content

Commit

Permalink
new: Add moon action-graph command. (#1101)
Browse files Browse the repository at this point in the history
* Add action.

* Update app.

* Update tests.

* Update docs.

* Polish.

* Polish.
  • Loading branch information
milesj committed Oct 9, 2023
1 parent 216ccc7 commit dc1ac39
Show file tree
Hide file tree
Showing 20 changed files with 292 additions and 244 deletions.
10 changes: 5 additions & 5 deletions .github/workflows/benchmark.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ jobs:
runs-on: ubuntu-latest
# strategy:
# matrix:
# bench: [dep_graph_benchmark, emitter_benchmark, pipeline_benchmark]
# bench: [emitter_benchmark, pipeline_benchmark]
# fail-fast: false
steps:
- run: echo ${{ github.event.pull_request.head.sha }}
Expand All @@ -37,8 +37,8 @@ jobs:
- name: Run benchmarks
# args: --workspace --bench ${{ matrix.bench }} -- --save-baseline base-sha
run:
cargo bench --workspace --bench dep_graph_benchmark --bench emitter_benchmark --bench
pipeline_benchmark --bench tar_benchmark -- --save-baseline head-sha
cargo bench --workspace --bench emitter_benchmark --bench pipeline_benchmark --bench
tar_benchmark -- --save-baseline head-sha

# Run on base branch to get a baseline
- name: Checkout base branch
Expand All @@ -49,8 +49,8 @@ jobs:
- name: Run benchmarks
# args: --workspace --bench ${{ matrix.bench }} -- --save-baseline base-sha
run:
cargo bench --workspace --bench dep_graph_benchmark --bench emitter_benchmark --bench
pipeline_benchmark --bench tar_benchmark -- --save-baseline base-sha
cargo bench --workspace --bench emitter_benchmark --bench pipeline_benchmark --bench
tar_benchmark -- --save-baseline base-sha

# Compare diffs
- name: Install critcmp
Expand Down
15 changes: 12 additions & 3 deletions crates/cli/src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use crate::commands::clean::CleanArgs;
use crate::commands::completions::CompletionsArgs;
use crate::commands::docker::DockerScaffoldArgs;
use crate::commands::generate::GenerateArgs;
use crate::commands::graph::dep::DepGraphArgs;
use crate::commands::graph::action::ActionGraphArgs;
use crate::commands::graph::project::ProjectGraphArgs;
use crate::commands::init::InitArgs;
use crate::commands::migrate::FromPackageJsonArgs;
Expand Down Expand Up @@ -178,13 +178,22 @@ pub enum Commands {

// PROJECTS

// moon action-graph [target]
#[command(
alias = "ag",
name = "action-graph",
about = "Display an interactive dependency graph of all tasks and actions."
)]
ActionGraph(ActionGraphArgs),

// moon dep-graph [target]
#[command(
name = "dep-graph",
about = "Display an interactive dependency graph of all tasks and actions.",
alias = "dg"
alias = "dg",
hide = true
)]
DepGraph(DepGraphArgs),
DepGraph(ActionGraphArgs),

// moon project <id>
#[command(
Expand Down
75 changes: 75 additions & 0 deletions crates/cli/src/commands/graph/action.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
use crate::commands::graph::utils::{action_graph_repr, respond_to_request, setup_server};
use clap::Args;
use miette::IntoDiagnostic;
use moon::{build_dep_graph, generate_project_graph};
use moon_target::TargetLocator;
use moon_workspace::Workspace;
use starbase::{system, SystemResult};

#[derive(Args, Clone, Debug)]
pub struct ActionGraphArgs {
#[arg(help = "Target to *only* graph")]
target: Option<TargetLocator>,

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

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

pub async fn internal_action_graph(
args: &ActionGraphArgs,
workspace: &mut Workspace,
) -> SystemResult {
let project_graph = generate_project_graph(workspace).await?;
let mut action_graph_builder = build_dep_graph(&project_graph);

// Focus a target and its dependencies/dependents
if let Some(locator) = args.target.clone() {
for target in action_graph_builder.run_targets_by_locator(&[locator], None)? {
action_graph_builder.run_dependents_for_target(&target)?;
}

// Show all targets and actions
} else {
for project in project_graph.get_all_unexpanded() {
for task in project.tasks.values() {
action_graph_builder.run_target(&task.target, None)?;
}
}
}

let action_graph = action_graph_builder.build();

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

return Ok(());
}

let graph_info = action_graph_repr(&action_graph).await;

if args.json {
println!("{}", serde_json::to_string(&graph_info).into_diagnostic()?);

return Ok(());
}

let (server, mut tera) = setup_server().await?;
let url = format!("http://{}", server.server_addr());
let _ = open::that(&url);

println!("Started server on {url}");

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

Ok(())
}

#[system]
pub async fn action_graph(args: ArgsRef<ActionGraphArgs>, workspace: ResourceMut<Workspace>) {
internal_action_graph(args, workspace).await?;
}
69 changes: 9 additions & 60 deletions crates/cli/src/commands/graph/dep.rs
Original file line number Diff line number Diff line change
@@ -1,66 +1,15 @@
use crate::commands::graph::utils::{dep_graph_repr, respond_to_request, setup_server};
use clap::Args;
use miette::IntoDiagnostic;
use moon::{build_dep_graph, generate_project_graph};
use moon_target::TargetLocator;
use super::action::*;
use moon_common::color;
use moon_workspace::Workspace;
use starbase::system;

#[derive(Args, Clone, Debug)]
pub struct DepGraphArgs {
#[arg(help = "Target to *only* graph")]
target: Option<TargetLocator>,

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

#[arg(long, help = "Print the graph in JSON format")]
json: bool,
}
use tracing::warn;

#[system]
pub async fn dep_graph(args: ArgsRef<DepGraphArgs>, workspace: ResourceMut<Workspace>) {
let project_graph = generate_project_graph(workspace).await?;
let mut dep_builder = build_dep_graph(&project_graph);

// Focus a target and its dependencies/dependents
if let Some(locator) = args.target.clone() {
for target in dep_builder.run_targets_by_locator(&[locator], None)? {
dep_builder.run_dependents_for_target(&target)?;
}

// Show all targets and actions
} else {
for project in project_graph.get_all_unexpanded() {
for task in project.tasks.values() {
dep_builder.run_target(&task.target, None)?;
}
}
}

let dep_graph = dep_builder.build();

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

return Ok(());
}

let graph_info = dep_graph_repr(&dep_graph).await;

if args.json {
println!("{}", serde_json::to_string(&graph_info).into_diagnostic()?);

return Ok(());
}

let (server, mut tera) = setup_server().await?;
let url = format!("http://{}", server.server_addr());
let _ = open::that(&url);

println!("Started server on {url}");
pub async fn dep_graph(args: ArgsRef<ActionGraphArgs>, workspace: ResourceMut<Workspace>) {
warn!(
"This command is deprecated. Use {} instead.",
color::shell("moon action-graph")
);

for req in server.incoming_requests() {
respond_to_request(req, &mut tera, &graph_info, "Dependency graph".to_owned())?;
}
internal_action_graph(args, workspace).await?;
}
1 change: 1 addition & 0 deletions crates/cli/src/commands/graph/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
pub mod action;
pub mod dep;
mod dto;
pub mod project;
Expand Down
2 changes: 1 addition & 1 deletion crates/cli/src/commands/graph/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ pub async fn project_graph_repr(project_graph: &ProjectGraph) -> GraphInfoDto {
}

/// Get a serialized representation of the dependency graph.
pub async fn dep_graph_repr(dep_graph: &DepGraph) -> GraphInfoDto {
pub async fn action_graph_repr(dep_graph: &DepGraph) -> GraphInfoDto {
let labeled_graph = dep_graph.labeled_graph();
extract_nodes_and_edges_from_graph(&labeled_graph, false)
}
Expand Down
3 changes: 2 additions & 1 deletion crates/cli/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use crate::commands::clean::clean;
use crate::commands::completions;
use crate::commands::docker;
use crate::commands::generate::generate;
use crate::commands::graph::{dep::dep_graph, project::project_graph};
use crate::commands::graph::{action::action_graph, dep::dep_graph, project::project_graph};
use crate::commands::init::init;
use crate::commands::migrate;
use crate::commands::node;
Expand Down Expand Up @@ -138,6 +138,7 @@ pub async fn run_cli() -> AppResult {
app.startup(systems::load_workspace);

match cli.command {
Commands::ActionGraph(args) => app.execute_with_args(action_graph, args),
Commands::Bin(args) => app.execute_with_args(bin, args),
Commands::Ci(args) => {
app.execute(systems::check_for_new_version);
Expand Down
Loading

0 comments on commit dc1ac39

Please sign in to comment.