Commit Diff


commit - 6cf07ef229efdfd94c71c1db45528f686606bd7d
commit + 8f21cf58d999cc6348fbb851e505192645b9e4e6
blob - ce03734d18a04a393b07ddb9f8f2fa8f46efcdff
blob + 87a323f0cd68a2a423e03faa90aa1f49c2644dfc
--- Cargo.lock
+++ Cargo.lock
@@ -489,6 +489,7 @@ dependencies = [
  "aws-config",
  "aws-sdk-cognitoidentityprovider",
  "clap",
+ "indicatif",
  "tokio",
  "tracing",
  "tracing-subscriber",
@@ -645,6 +646,19 @@ source = "registry+https://github.com/rust-lang/crates
 checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75"
 
 [[package]]
+name = "console"
+version = "0.16.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b430743a6eb14e9764d4260d4c0d8123087d504eeb9c48f2b2a5e810dd369df4"
+dependencies = [
+ "encode_unicode",
+ "libc",
+ "once_cell",
+ "unicode-width",
+ "windows-sys 0.61.2",
+]
+
+[[package]]
 name = "core-foundation"
 version = "0.9.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -733,6 +747,12 @@ source = "registry+https://github.com/rust-lang/crates
 checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719"
 
 [[package]]
+name = "encode_unicode"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "34aa73646ffb006b8f5147f3dc182bd4bcb190227ce861fc4a4844bf8e3cb2c0"
+
+[[package]]
 name = "equivalent"
 version = "1.0.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1198,6 +1218,19 @@ dependencies = [
 ]
 
 [[package]]
+name = "indicatif"
+version = "0.18.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9375e112e4b463ec1b1c6c011953545c65a30164fbab5b581df32b3abf0dcb88"
+dependencies = [
+ "console",
+ "portable-atomic",
+ "unicode-width",
+ "unit-prefix",
+ "web-time",
+]
+
+[[package]]
 name = "ipnet"
 version = "2.11.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1428,6 +1461,12 @@ source = "registry+https://github.com/rust-lang/crates
 checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
 
 [[package]]
+name = "portable-atomic"
+version = "1.11.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f84267b20a16ea918e43c6a88433c2d54fa145c92a811b5b047ccbe153674483"
+
+[[package]]
 name = "potential_utf"
 version = "0.1.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2067,6 +2106,18 @@ source = "registry+https://github.com/rust-lang/crates
 checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5"
 
 [[package]]
+name = "unicode-width"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b4ac048d71ede7ee76d585517add45da530660ef4390e49b098733c6e897f254"
+
+[[package]]
+name = "unit-prefix"
+version = "0.5.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "81e544489bf3d8ef66c953931f56617f423cd4b5494be343d9b9d3dda037b9a3"
+
+[[package]]
 name = "untrusted"
 version = "0.9.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2200,6 +2251,16 @@ dependencies = [
 ]
 
 [[package]]
+name = "web-time"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb"
+dependencies = [
+ "js-sys",
+ "wasm-bindgen",
+]
+
+[[package]]
 name = "windows-link"
 version = "0.2.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
blob - 2221b8157522e67a09fad9f0c67101f15f5aff01
blob + 97e6bd47333745582dc8018d107abbc60d57c543
--- Cargo.toml
+++ Cargo.toml
@@ -14,6 +14,7 @@ anyhow = "1.0.100"
 aws-config = { version = "1.8.10", features = ["behavior-version-latest"] }
 aws-sdk-cognitoidentityprovider = "1.103.0"
 clap = { version = "4.5.52", features = ["derive", "env"] }
+indicatif = "0.18.3"
 tokio = { version = "1.48.0", features = ["full"] }
 tracing = "0.1.41"
 tracing-subscriber = { version = "0.3.20", features = ["env-filter"] }
blob - 5b1b9cc0bfb2cbcaa80fd6bb4625d74cbc26e6f1
blob + 86f1b35adb43ad500a4e6feb0f5530f53cd3bd85
--- src/main.rs
+++ src/main.rs
@@ -24,6 +24,7 @@ use anyhow::{Context, Result};
 use aws_sdk_cognitoidentityprovider::Client as CognitoClient;
 use aws_sdk_cognitoidentityprovider::types::UserType;
 use clap::{ArgAction, Parser, Subcommand};
+use indicatif::{ProgressBar, ProgressStyle};
 use tokio::fs::File;
 use tokio::io::{self, AsyncBufReadExt, AsyncWrite, AsyncWriteExt, BufReader};
 use tokio::sync::Semaphore;
@@ -232,11 +233,6 @@ struct GroupOperationArgs {
 
 #[tokio::main]
 async fn main() -> Result<()> {
-    // let users = read_sync_file_to_map(".mail_sync").await?;
-
-    // for (email, username) in &users {
-    // println!("{email} => {username}");
-    // }
     let cli = Cli::parse();
     init_tracing(cli.verbose);
 
@@ -617,8 +613,21 @@ pub async fn add_users_to_groups_from_files(
 
     // 2. Load target e-mails
     let emails = load_email_list(emails_list_path).await?;
-    info!(total_emails = emails.len(), "loaded target e-mail list");
+    let total_emails = emails.len();
+    info!(total_emails, "loaded target e-mail list");
 
+    let pb = Arc::new({
+        let bar = ProgressBar::new(total_emails as u64);
+        bar.set_style(
+            ProgressStyle::with_template(
+                "[{elapsed_precise}] [{bar:40.cyan/blue}] {pos}/{len} {msg}",
+            )
+            .unwrap_or_else(|_| ProgressStyle::default_bar()),
+        );
+        bar.set_message("processing users");
+        bar
+    });
+
     let semaphore = Arc::new(Semaphore::new(concurrency));
     let mut handles: Vec<JoinHandle<()>> = Vec::with_capacity(emails.len());
 
@@ -635,6 +644,8 @@ pub async fn add_users_to_groups_from_files(
         let client_clone = client.clone();
         let pool_id = pool_id.to_string();
         let groups = groups.to_vec();
+        let email_clone = email.clone();
+        let pb_clone = pb.clone();
 
         let handle = tokio::spawn(async move {
             let _permit = permit; // keep permit alive for the duration of this task
@@ -648,19 +659,21 @@ pub async fn add_users_to_groups_from_files(
             .await
             {
                 error!(
-                    %email,
+                    email = %email_clone,
                     %username,
                     error = ?err,
                     "failed to add user to one or more groups"
                 );
             } else {
                 info!(
-                    %email,
+                    email = %email_clone,
                     %username,
                     groups = ?groups,
                     "user successfully processed for all groups"
                 );
             }
+
+            pb_clone.inc(1);
         });
 
         handles.push(handle);
@@ -674,6 +687,7 @@ pub async fn add_users_to_groups_from_files(
         }
     }
 
+    pb.finish_with_message("done");
     info!("finished processing all users for add-groups operation");
     Ok(())
 }