#![deny(unsafe_code, nonstandard_style)]
use anyhow::Result;
use async_std::path::PathBuf;
use clap::Parser;
use craftql::{
state::{GraphQL, State},
utils::{
find_and_print_neighbors, find_and_print_orphans, find_node, get_files,
populate_graph_from_ast, print_missing_definitions,
},
};
use petgraph::{
dot::{Config, Dot},
Direction,
};
#[derive(Parser)]
#[clap(about, author, version)]
struct Opts {
path: PathBuf,
#[clap(short, long)]
incoming_dependencies: Option<String>,
#[clap(short, long)]
missing_definitions: bool,
#[clap(short = 'O', long)]
orphans: bool,
#[clap(short, long)]
outgoing_dependencies: Option<String>,
#[clap(short, long)]
node: Option<String>,
#[clap(short = 'N', long)]
nodes: Vec<String>,
#[clap(short, long, verbatim_doc_comment)]
filter: Vec<GraphQL>,
}
#[async_std::main]
async fn main() -> Result<()> {
let opts: Opts = Opts::parse();
let state = State::default();
let shared_data = state.shared;
let shared_data_for_populate = shared_data.clone();
get_files(opts.path, shared_data.files).await?;
populate_graph_from_ast(
shared_data_for_populate.dependencies,
shared_data_for_populate.files,
&opts.filter,
shared_data_for_populate.graph,
shared_data_for_populate.missing_definitions,
)
.await?;
if let Some(ref node) = opts.incoming_dependencies {
find_and_print_neighbors(node, shared_data.graph.clone(), Direction::Incoming).await?;
return Ok(());
}
if let Some(ref node) = opts.outgoing_dependencies {
find_and_print_neighbors(node, shared_data.graph.clone(), Direction::Outgoing).await?;
return Ok(());
}
if let Some(ref node) = opts.node {
find_node(node, shared_data.graph.clone()).await?;
return Ok(());
}
if !opts.nodes.is_empty() {
for ref node in opts.nodes {
find_node(node, shared_data.graph.clone()).await?;
}
return Ok(());
}
if opts.missing_definitions {
print_missing_definitions(
shared_data.graph.clone(),
shared_data.missing_definitions.clone(),
)
.await?;
return Ok(());
}
if opts.orphans {
find_and_print_orphans(shared_data.graph.clone()).await?;
return Ok(());
}
let graph = &*shared_data.graph.lock().await;
println!("\n{:?}", Dot::with_config(&graph, &[Config::EdgeNoLabel]));
Ok(())
}