Skip to content

Commit

Permalink
Api improvements (#33)
Browse files Browse the repository at this point in the history
  • Loading branch information
DenysVuika authored Nov 21, 2024
1 parent c0cea74 commit bb28db9
Show file tree
Hide file tree
Showing 5 changed files with 89 additions and 43 deletions.
15 changes: 11 additions & 4 deletions src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,19 +40,26 @@ impl Default for Config {
base: Some("main".to_string()),
tasks: Some(vec![
Task {
name: "lint".to_string(),
description: Some("Runs eslint for all affected files (example)".to_string()),
name: "eslint".to_string(),
description: Some("Runs eslint for all affected files".to_string()),
patterns: Some(vec!["*.{ts,tsx,js,jsx}".to_string()]),
commands: vec!["npx eslint {files}".to_string()],
..Default::default()
},
Task {
name: "prettier".to_string(),
description: Some("Runs prettier for all affected files (example)".to_string()),
name: "prettier:check".to_string(),
description: Some("Runs prettier check for all affected files".to_string()),
patterns: Some(vec!["*.{ts,tsx,js,jsx}".to_string()]),
commands: vec!["npx prettier --check {files}".to_string()],
..Default::default()
},
Task {
name: "prettier:write".to_string(),
description: Some("Runs prettier write for all affected files".to_string()),
patterns: Some(vec!["*.{ts,tsx,js,jsx}".to_string()]),
commands: vec!["npx prettier --write {files}".to_string()],
..Default::default()
},
]),
}
}
Expand Down
38 changes: 38 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,42 @@ mod projects;
pub mod tasks;
pub mod workspace;

use anyhow::Result;
use clap::ValueEnum;
pub use config::Config;
use std::collections::HashSet;
use std::path::{Path, PathBuf};

#[derive(ValueEnum, Clone, Debug)]
pub enum OutputFormat {
Json,
Text,
}

pub fn print_lines(lines: &HashSet<String>, format: &OutputFormat) -> Result<()> {
match format {
OutputFormat::Json => {
let json_output = serde_json::to_string_pretty(&lines)?;
println!("{}", json_output);
}
_ => {
for line in lines {
println!("{}", line);
}
}
}
Ok(())
}

pub fn find_git_root(starting_dir: &Path) -> Option<PathBuf> {
let mut current_dir = starting_dir;

while current_dir != current_dir.parent()? {
if current_dir.join(".git").exists() {
return Some(current_dir.to_path_buf());
}
current_dir = current_dir.parent()?;
}

None
}
70 changes: 35 additions & 35 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
use affected::logger::init_logger;
use affected::workspace::Workspace;
use affected::Config;
use affected::{find_git_root, print_lines, Config, OutputFormat};
use anyhow::Result;
use clap::{Parser, Subcommand};
use dotenvy::dotenv;
use log::debug;
use log::{debug, error};
use std::path::PathBuf;

#[derive(Parser)]
Expand All @@ -27,32 +27,40 @@ struct Cli {
#[derive(Subcommand)]
enum Commands {
/// Initialize the configuration file
Init,
Init {
/// Overwrite the existing configuration file
#[arg(long)]
force: bool,
},

/// View affected files or projects
#[command(subcommand)]
View(ViewCommands),

/// Run a specific task
/// Run a specific task.
/// Supports glob patterns to filter tasks.
#[command(arg_required_else_help = true)]
Run {
/// The task to run
/// The task to run (supports glob patterns)
task: String,
},
}

#[derive(Subcommand)]
enum ViewCommands {
/// View affected files
Files {
/// Output format: json or text
#[arg(long, default_value = "text")]
format: String,
format: OutputFormat,
},
/// View affected projects
Projects {
/// Output format: json or text
#[arg(long, default_value = "text")]
format: String,
format: OutputFormat,
},
/// View tasks defined in the configuration.
Tasks,
}

Expand All @@ -65,12 +73,14 @@ async fn main() -> Result<()> {

let cli = Cli::parse();

let workspace_root = cli
let starting_dir = cli
.repo
.unwrap_or_else(|| std::env::current_dir().expect("Failed to get the repository path"));
let workspace_root = find_git_root(&starting_dir).expect("Failed to find the git repository");

debug!("Using repository: {:?}", &workspace_root);

// let config = Config::from_env();
let base = cli.base.clone().or(Some("main".to_string()));

let config_path = workspace_root.join(".affected.yml");
let config = if config_path.exists() {
Expand All @@ -79,41 +89,41 @@ async fn main() -> Result<()> {
} else {
debug!("Config file not found, using a default one");
Config {
base: cli.base.clone().or(Some("main".to_string())),
base: base.clone(),
..Default::default()
}
};

let mut workspace = Workspace::with_config(&workspace_root, config);

match &cli.command {
Commands::Init => {
let config = workspace.config().expect("No configuration found");
Commands::Init { force } => {
if config_path.exists() && !force {
error!("Config file already exists. Remove it to reinitialize, or use --force to overwrite.");
return Ok(());
}
let config = Config {
base: base.clone(),
..Default::default()
};
config.to_file(&config_path)?;
println!("Config file created at {:?}", &config_path);
}

Commands::View(subcommand) => match subcommand {
ViewCommands::Files { format } => {
workspace.load().await?;
if let Err(err) = workspace.load().await {
log::error!("Failed to load workspace: {}", err);
return Ok(());
}

let files = workspace.affected_files()?;
if files.is_empty() {
println!("No files affected");
return Ok(());
}

match format.as_str() {
"json" => {
let json_output = serde_json::to_string_pretty(&files)?;
println!("{}", json_output);
}
_ => {
for file in files {
println!("{}", file);
}
}
}
print_lines(&files, format)?;
}
ViewCommands::Projects { format } => {
workspace.load().await?;
Expand All @@ -125,17 +135,7 @@ async fn main() -> Result<()> {
return Ok(());
}

match format.as_str() {
"json" => {
let json_output = serde_json::to_string_pretty(&projects)?;
println!("{}", json_output);
}
_ => {
for project in projects {
println!("{}", project);
}
}
}
print_lines(&projects, format)?;

/*
let graph = affected::graph::build_graph(&workspace)?;
Expand Down
7 changes: 4 additions & 3 deletions src/nx/nx_project.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,10 @@ impl Project for NxProject {
fn load(workspace_root: &Path, project_path: &str) -> Result<Self> {
let path = workspace_root.join(project_path).join("project.json");
debug!("Loading project from {:?}", path);
let contents = fs::read_to_string(path).expect("Could not read project.json");
let mut project: NxProject =
serde_json::from_str(&contents).expect("Could not parse project.json");
let contents = fs::read_to_string(path)
.unwrap_or_else(|_| panic!("Could not read {}/project.json", &project_path));
let mut project: NxProject = serde_json::from_str(&contents)
.unwrap_or_else(|_| panic!("Could not parse {}/project.json", &project_path));

if project.root.is_none() {
project.root = Some(project_path.to_string());
Expand Down
2 changes: 1 addition & 1 deletion src/workspace.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ impl Workspace {

/// Loads the repository
pub async fn load(&mut self) -> Result<()> {
let repo = Repository::open(&self.root).expect("Could not open the repository");
let repo = Repository::open(&self.root).context("Could not open the repository")?;

// TODO: introduce flag to fetch from remote
// Fetch the latest changes from the remote repository
Expand Down

0 comments on commit bb28db9

Please sign in to comment.