Skip to content

Commit ff9a214

Browse files
committed
feat: add depth arg
1 parent 8cc08da commit ff9a214

File tree

2 files changed

+59
-59
lines changed

2 files changed

+59
-59
lines changed

bin/src/main.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@ use clap::Subcommand;
2121
use env_logger::Env;
2222
use log::{error, info};
2323

24-
use gt::manager::Signal;
2524
use gt::*;
25+
use gt::manager::Signal;
2626

2727
use crate::cs::{ClientArgs, ServerArgs};
2828
use crate::manager::ManagerArgs;
@@ -33,9 +33,12 @@ struct Cli {
3333
#[command(subcommand)]
3434
command: Option<Commands>,
3535

36-
/// Path to the config file or the directory contains the config files
36+
/// Path to the config file or the directory containing the config files
3737
#[arg(short, long)]
3838
config: Option<PathBuf>,
39+
/// The maximum allowed depth of the subdirectory to be traversed to search config files
40+
#[arg(long)]
41+
depth: Option<u8>,
3942
/// Send signal to the running GT processes
4043
#[arg(short, long, value_enum)]
4144
signal: Option<Signal>,
@@ -69,6 +72,7 @@ fn main() {
6972
}
7073
let mut manager_args = ManagerArgs {
7174
config: cli.config,
75+
depth: cli.depth,
7276
server_args: None,
7377
client_args: None,
7478
};

bin/src/manager.rs

Lines changed: 53 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
* limitations under the License.
1515
*/
1616

17+
use std::{env, fs, future, io, process};
1718
use std::collections::{BTreeMap, HashMap};
1819
use std::ffi::OsStr;
1920
use std::future::Future;
@@ -24,28 +25,28 @@ use std::os::unix::process::CommandExt;
2425
use std::os::windows::process::CommandExt;
2526
use std::path::PathBuf;
2627
use std::process::Stdio;
27-
use std::sync::atomic::{AtomicUsize, Ordering};
2828
use std::sync::Arc;
29+
use std::sync::atomic::{AtomicUsize, Ordering};
2930
use std::time::{Duration, Instant};
30-
use std::{env, fs, future, io, process};
3131

3232
use anyhow::{anyhow, Context, Error, Result};
3333
use clap::ValueEnum;
3434
use futures::future::{BoxFuture, FutureExt};
3535
use log::{error, info, warn};
3636
use notify::{ErrorKind, Event, PollWatcher, RecommendedWatcher, RecursiveMode, Watcher};
37-
use serde::{de, ser, Deserialize, Serialize};
37+
use serde::{de, Deserialize, ser, Serialize};
3838
use tokio::io::{AsyncReadExt, AsyncWriteExt};
3939
use tokio::process::{Child, ChildStdin, ChildStdout, Command};
40+
use tokio::sync::{mpsc, Mutex, oneshot};
4041
use tokio::sync::oneshot::{Receiver, Sender};
41-
use tokio::sync::{mpsc, oneshot, Mutex};
4242
use tokio::time::timeout;
4343

4444
use crate::cs::{ClientArgs, ServerArgs};
4545

4646
#[derive(Debug)]
4747
pub struct ManagerArgs {
4848
pub config: Option<PathBuf>,
49+
pub depth: Option<u8>,
4950
pub server_args: Option<ServerArgs>,
5051
pub client_args: Option<ClientArgs>,
5152
}
@@ -87,6 +88,46 @@ impl Manager {
8788
}
8889
}
8990

91+
fn collect_files(&self, path: PathBuf, depth: u8) -> io::Result<Vec<ProcessConfigEnum>> {
92+
let mut files = vec![];
93+
if path.is_dir() {
94+
for entry in fs::read_dir(path)? {
95+
let entry = entry?;
96+
let path = entry.path();
97+
if path.is_dir() {
98+
let max = self.args.depth.unwrap_or(3);
99+
if max != 0 && depth + 1 > max {
100+
info!("{} is too deep", path.display());
101+
continue;
102+
}
103+
files.append(self.collect_files(path, depth + 1)?.as_mut());
104+
} else {
105+
match path.extension().and_then(OsStr::to_str) {
106+
Some("yaml") | Some("yml") => {}
107+
None | Some(_) => {
108+
info!(
109+
"ignored file {} is not end with yml or yaml",
110+
path.display()
111+
);
112+
continue;
113+
}
114+
}
115+
let fm = entry.metadata()?.len();
116+
if fm > 10 * 1024 * 1024 {
117+
info!("ignored file {} is too large", path.display());
118+
continue;
119+
}
120+
info!("collected file {}", path.display());
121+
files.push(ProcessConfigEnum::Config(path));
122+
}
123+
}
124+
} else {
125+
info!("collected file {}", path.display());
126+
files.push(ProcessConfigEnum::Config(path));
127+
}
128+
Ok(files)
129+
}
130+
90131
async fn collect_configs(
91132
&self,
92133
) -> Result<(Vec<ProcessConfigEnum>, Option<Vec<ProcessConfigEnum>>)> {
@@ -100,7 +141,7 @@ impl Manager {
100141
None => env::current_dir()?,
101142
Some(path) => path.into(),
102143
};
103-
configs = collect_files(config.clone())?;
144+
configs = self.collect_files(config.clone(), 1)?;
104145
}
105146
if configs.is_empty() {
106147
return Err(anyhow!("no target found"));
@@ -324,9 +365,7 @@ impl Manager {
324365
let reconnect = async {
325366
let cmds = cmd_map.clone();
326367
let config = config.clone();
327-
if let Err(e) =
328-
Self::sync_run(cmds, vec![config.clone()], sub_cmd).await
329-
{
368+
if let Err(e) = Self::sync_run(cmds, vec![config.clone()], sub_cmd).await {
330369
error!("{sub_cmd} ({config:?}) reconnect sync_run failed: {:?}", e);
331370
}
332371
};
@@ -427,23 +466,15 @@ impl Manager {
427466
}
428467
}
429468
if !server_config.is_empty() {
430-
Self::run(
431-
self.cmds.clone(),
432-
server_config,
433-
"sub-server",
434-
)
435-
.await
436-
.context("run_server failed")?;
469+
Self::run(self.cmds.clone(), server_config, "sub-server")
470+
.await
471+
.context("run_server failed")?;
437472
}
438473

439474
if !client_config.is_empty() {
440-
Self::run(
441-
self.cmds.clone(),
442-
client_config,
443-
"sub-client",
444-
)
445-
.await
446-
.context("run_client failed")?;
475+
Self::run(self.cmds.clone(), client_config, "sub-client")
476+
.await
477+
.context("run_client failed")?;
447478
}
448479
Ok(())
449480
}
@@ -759,41 +790,6 @@ pub fn send_signal(signal: Signal) -> Result<()> {
759790
Ok(())
760791
}
761792

762-
fn collect_files(path: PathBuf) -> io::Result<Vec<ProcessConfigEnum>> {
763-
let mut files = vec![];
764-
if path.is_dir() {
765-
for entry in fs::read_dir(path)? {
766-
let entry = entry?;
767-
let path = entry.path();
768-
if path.is_dir() {
769-
collect_files(path)?;
770-
} else {
771-
let fm = entry.metadata()?.len();
772-
if fm > 10 * 1024 * 1024 {
773-
info!("ignored file {} is too large", path.display());
774-
continue;
775-
}
776-
match path.extension().and_then(OsStr::to_str) {
777-
Some("yaml") | Some("yml") => {}
778-
None | Some(_) => {
779-
info!(
780-
"ignored file {} is not end with yml or yaml",
781-
path.display()
782-
);
783-
continue;
784-
}
785-
}
786-
info!("collected file {}", path.display());
787-
files.push(ProcessConfigEnum::Config(path));
788-
}
789-
}
790-
} else {
791-
info!("collected file {}", path.display());
792-
files.push(ProcessConfigEnum::Config(path));
793-
}
794-
Ok(files)
795-
}
796-
797793
#[derive(Serialize, Deserialize, Debug)]
798794
struct Config {
799795
#[serde(rename = "type")]

0 commit comments

Comments
 (0)