|
1 | 1 | use clap::{Parser, Subcommand}; |
2 | | -use codeowners::{ |
3 | | - cache::{Cache, Caching, file::GlobalCache, noop::NoopCache}, |
4 | | - config::Config, |
5 | | - ownership::{FileOwner, Ownership}, |
6 | | - project_builder::ProjectBuilder, |
7 | | -}; |
8 | | -use core::fmt; |
9 | | -use error_stack::{Context, Result, ResultExt}; |
| 2 | +use codeowners::runner::Error as RunnerError; |
| 3 | +use codeowners::runner::{RunConfig, Runner}; |
| 4 | +use error_stack::{Result, ResultExt}; |
10 | 5 | use path_clean::PathClean; |
11 | | -use std::{ |
12 | | - fs::File, |
13 | | - path::{Path, PathBuf}, |
14 | | -}; |
| 6 | +use std::path::{Path, PathBuf}; |
15 | 7 |
|
16 | 8 | #[derive(Subcommand, Debug)] |
17 | 9 | enum Command { |
@@ -64,105 +56,52 @@ struct Args { |
64 | 56 | } |
65 | 57 |
|
66 | 58 | impl Args { |
67 | | - fn absolute_project_root(&self) -> Result<PathBuf, Error> { |
68 | | - self.project_root.canonicalize().change_context(Error::Io) |
| 59 | + fn absolute_project_root(&self) -> Result<PathBuf, RunnerError> { |
| 60 | + self.project_root.canonicalize().change_context(RunnerError::Io) |
69 | 61 | } |
70 | 62 |
|
71 | | - fn absolute_config_path(&self) -> Result<PathBuf, Error> { |
| 63 | + fn absolute_config_path(&self) -> Result<PathBuf, RunnerError> { |
72 | 64 | Ok(self.absolute_path(&self.config_path)?.clean()) |
73 | 65 | } |
74 | 66 |
|
75 | | - fn absolute_codeowners_path(&self) -> Result<PathBuf, Error> { |
| 67 | + fn absolute_codeowners_path(&self) -> Result<PathBuf, RunnerError> { |
76 | 68 | Ok(self.absolute_path(&self.codeowners_file_path)?.clean()) |
77 | 69 | } |
78 | 70 |
|
79 | | - fn absolute_path(&self, path: &Path) -> Result<PathBuf, Error> { |
| 71 | + fn absolute_path(&self, path: &Path) -> Result<PathBuf, RunnerError> { |
80 | 72 | Ok(self.absolute_project_root()?.join(path)) |
81 | 73 | } |
82 | 74 | } |
83 | 75 |
|
84 | | -#[derive(Debug)] |
85 | | -pub enum Error { |
86 | | - Io, |
87 | | - ValidationFailed, |
88 | | -} |
89 | | - |
90 | | -impl Context for Error {} |
91 | | - |
92 | | -pub fn cli() -> Result<(), Error> { |
| 76 | +pub fn cli() -> Result<(), RunnerError> { |
93 | 77 | let args = Args::parse(); |
94 | 78 |
|
95 | 79 | let config_path = args.absolute_config_path()?; |
96 | 80 | let codeowners_file_path = args.absolute_codeowners_path()?; |
97 | 81 | let project_root = args.absolute_project_root()?; |
98 | 82 |
|
99 | | - let config_file = File::open(&config_path) |
100 | | - .change_context(Error::Io) |
101 | | - .attach_printable(format!("Can't open config file: {}", config_path.to_string_lossy()))?; |
102 | | - |
103 | | - let config: Config = serde_yaml::from_reader(config_file).change_context(Error::Io)?; |
104 | | - let cache: Cache = if args.no_cache { |
105 | | - NoopCache::default().into() |
106 | | - } else { |
107 | | - GlobalCache::new(project_root.clone(), config.cache_directory.clone()) |
108 | | - .change_context(Error::Io)? |
109 | | - .into() |
| 83 | + let run_config = RunConfig { |
| 84 | + config_path, |
| 85 | + codeowners_file_path, |
| 86 | + project_root, |
| 87 | + no_cache: args.no_cache, |
110 | 88 | }; |
111 | 89 |
|
112 | | - let mut project_builder = ProjectBuilder::new(&config, project_root.clone(), codeowners_file_path.clone(), &cache); |
113 | | - let project = project_builder.build().change_context(Error::Io)?; |
114 | | - let ownership = Ownership::build(project); |
115 | | - |
116 | | - cache.persist_cache().change_context(Error::Io)?; |
| 90 | + let runner = Runner::new(run_config).change_context(RunnerError::Io)?; |
117 | 91 |
|
118 | 92 | match args.command { |
119 | | - Command::Validate => ownership.validate().change_context(Error::ValidationFailed)?, |
120 | | - Command::Generate => { |
121 | | - std::fs::write(codeowners_file_path, ownership.generate_file()).change_context(Error::Io)?; |
122 | | - } |
| 93 | + Command::Validate => runner.validate()?, |
| 94 | + Command::Generate => runner.generate()?, |
123 | 95 | Command::GenerateAndValidate => { |
124 | | - std::fs::write(codeowners_file_path, ownership.generate_file()).change_context(Error::Io)?; |
125 | | - ownership.validate().change_context(Error::ValidationFailed)? |
| 96 | + runner.generate()?; |
| 97 | + runner.validate()?; |
126 | 98 | } |
127 | 99 | Command::ForFile { name } => { |
128 | | - let file_owners = ownership.for_file(&name).change_context(Error::Io)?; |
129 | | - match file_owners.len() { |
130 | | - 0 => println!("{}", FileOwner::default()), |
131 | | - 1 => println!("{}", file_owners[0]), |
132 | | - _ => { |
133 | | - println!("Error: file is owned by multiple teams!"); |
134 | | - for file_owner in file_owners { |
135 | | - println!("\n{}", file_owner); |
136 | | - } |
137 | | - } |
138 | | - } |
139 | | - } |
140 | | - Command::ForTeam { name } => match ownership.for_team(&name) { |
141 | | - Ok(team_ownerships) => { |
142 | | - println!("# Code Ownership Report for `{}` Team", name); |
143 | | - for team_ownership in team_ownerships { |
144 | | - println!("\n#{}", team_ownership.heading); |
145 | | - match team_ownership.globs.len() { |
146 | | - 0 => println!("This team owns nothing in this category."), |
147 | | - _ => println!("{}", team_ownership.globs.join("\n")), |
148 | | - } |
149 | | - } |
150 | | - } |
151 | | - Err(err) => println!("{}", err), |
152 | | - }, |
153 | | - Command::DeleteCache => { |
154 | | - cache.delete_cache().change_context(Error::Io)?; |
| 100 | + runner.for_file(&name)?; |
155 | 101 | } |
| 102 | + Command::ForTeam { name } => runner.for_team(&name)?, |
| 103 | + Command::DeleteCache => runner.delete_cache()?, |
156 | 104 | } |
157 | 105 |
|
158 | 106 | Ok(()) |
159 | 107 | } |
160 | | - |
161 | | -impl fmt::Display for Error { |
162 | | - fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { |
163 | | - match self { |
164 | | - Error::Io => fmt.write_str("Error::Io"), |
165 | | - Error::ValidationFailed => fmt.write_str("Error::ValidationFailed"), |
166 | | - } |
167 | | - } |
168 | | -} |
0 commit comments