Skip to content

Commit 7c474cc

Browse files
committed
improved progress tracking for multi step commands
1 parent 3c90d4a commit 7c474cc

File tree

3 files changed

+72
-19
lines changed

3 files changed

+72
-19
lines changed

tmc-langs-cli/src/main.rs

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1053,6 +1053,7 @@ fn run_core(matches: &ArgMatches) -> Result<PrintToken> {
10531053
if save_old_state {
10541054
let submission_url = matches.value_of("submission_url").unwrap();
10551055
let submission_url = into_url(submission_url)?;
1056+
core.increment_progress_steps();
10561057
core.submit(submission_url, exercise_path, None)?;
10571058
}
10581059
core.reset(exercise_id, exercise_path)?;
@@ -1078,20 +1079,24 @@ fn run_core(matches: &ArgMatches) -> Result<PrintToken> {
10781079

10791080
let save_old_state = matches.is_present("save-old-state");
10801081

1082+
core.increment_progress_steps();
10811083
if save_old_state {
10821084
let submission_url = matches.value_of("submission_url").unwrap();
10831085
let submission_url = into_url(submission_url)?;
1086+
core.increment_progress_steps();
10841087
core.submit(submission_url, output_path, None)?;
1088+
log::debug!("finished submission");
10851089
}
10861090

10871091
// reset old exercise if it exists
1088-
if output_path.exists() {
1089-
core.reset(exercise_id, output_path)?;
1090-
}
1092+
core.reset(exercise_id, output_path)?;
1093+
log::debug!("reset exercise");
10911094

10921095
let temp_zip = NamedTempFile::new().context("Failed to create a temporary archive")?;
10931096
core.download_old_submission(submission_id, temp_zip.path())?;
1094-
task_executor::extract_project(temp_zip.path(), output_path)?;
1097+
log::debug!("downloaded old submission to {}", temp_zip.path().display());
1098+
task_executor::extract_project(temp_zip.path(), output_path, false)?;
1099+
log::debug!("extracted project");
10951100

10961101
let output = Output::<()> {
10971102
status: Status::Finished,

tmc-langs-cli/src/output.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ pub enum OutputResult {
3838
Sending,
3939
WaitingForResults,
4040
Finished,
41+
IntermediateStepFinished,
4142
}
4243

4344
impl From<StatusType> for OutputResult {
@@ -50,6 +51,7 @@ impl From<StatusType> for OutputResult {
5051
StatusType::Sending => OutputResult::Sending,
5152
StatusType::WaitingForResults => OutputResult::WaitingForResults,
5253
StatusType::Finished => OutputResult::Finished,
54+
StatusType::IntermediateStepFinished => OutputResult::IntermediateStepFinished,
5355
}
5456
}
5557
}

tmc-langs-core/src/tmc_core.rs

Lines changed: 61 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ use oauth2::{
1212
};
1313
use reqwest::{blocking::Client, Url};
1414
use serde::Serialize;
15+
use std::cell::Cell;
1516
use std::collections::HashMap;
1617
use std::error::Error as StdError;
1718
use std::fs;
@@ -45,6 +46,7 @@ pub enum StatusType {
4546
Sending,
4647
WaitingForResults,
4748
Finished,
49+
IntermediateStepFinished,
4850
}
4951

5052
// compatible with anyhow
@@ -60,6 +62,8 @@ pub struct TmcCore {
6062
auth_url: String,
6163
token: Option<Token>,
6264
progress_report: Option<UpdateClosure>,
65+
progress_steps_done: Cell<u32>,
66+
progress_steps_total: u32,
6367
client_name: String,
6468
client_version: String,
6569
}
@@ -103,6 +107,8 @@ impl TmcCore {
103107
auth_url,
104108
token: None,
105109
progress_report: None,
110+
progress_steps_done: Cell::new(0),
111+
progress_steps_total: 1,
106112
client_name,
107113
client_version,
108114
})
@@ -139,12 +145,14 @@ impl TmcCore {
139145
self.progress_report = Some(Box::new(progress_report));
140146
}
141147

142-
pub fn report_progress(
143-
&self,
144-
message: &'static str,
145-
status_type: StatusType,
146-
percent_done: f64,
147-
) {
148+
pub fn increment_progress_steps(&mut self) {
149+
self.progress_steps_total += 1;
150+
}
151+
152+
fn report_progress(&self, message: &'static str, status_type: StatusType, percent_done: f64) {
153+
let from_prev_steps = self.progress_steps_done.get() as f64;
154+
let percent_done = (from_prev_steps + percent_done) / self.progress_steps_total as f64;
155+
148156
self.progress_report.as_ref().map(|f| {
149157
f(StatusUpdate {
150158
finished: false,
@@ -155,15 +163,21 @@ impl TmcCore {
155163
});
156164
}
157165

158-
pub fn report_complete(&self, message: &'static str) {
159-
self.progress_report.as_ref().map(|f| {
160-
f(StatusUpdate {
161-
finished: true,
162-
message,
163-
percent_done: 1.0,
164-
status_type: StatusType::Finished,
165-
})
166-
});
166+
fn report_complete(&self, message: &'static str) {
167+
self.progress_steps_done
168+
.set(self.progress_steps_done.get() + 1);
169+
if self.progress_steps_done.get() == self.progress_steps_total {
170+
self.progress_report.as_ref().map(|f| {
171+
f(StatusUpdate {
172+
finished: true,
173+
message,
174+
percent_done: 1.0,
175+
status_type: StatusType::Finished,
176+
})
177+
});
178+
} else {
179+
self.report_progress(message, StatusType::IntermediateStepFinished, 0.0);
180+
}
167181
}
168182

169183
/// Attempts to log in with the given credentials, returns an error if an authentication token is already present.
@@ -1286,4 +1300,36 @@ mod test {
12861300
serde_json::to_string(&f).unwrap()
12871301
);
12881302
}
1303+
1304+
#[test]
1305+
fn multi_step_progress() {
1306+
use std::sync::{Arc, Mutex};
1307+
1308+
let (mut core, _) = init();
1309+
let report = Arc::new(Mutex::default());
1310+
1311+
let report_clone = Arc::clone(&report);
1312+
core.set_progress_report(move |rep| {
1313+
log::debug!("got {:#?}", rep);
1314+
let report = Arc::clone(&report_clone);
1315+
*report.lock().unwrap() = Some(rep);
1316+
Ok(())
1317+
});
1318+
core.increment_progress_steps();
1319+
core.increment_progress_steps();
1320+
1321+
core.report_progress("msg", StatusType::Downloading, 0.2);
1322+
let err = f64::EPSILON;
1323+
assert!((report.lock().unwrap().as_ref().unwrap().percent_done - (0.2 / 3.0)).abs() < err);
1324+
core.report_progress("msg", StatusType::Downloading, 0.8);
1325+
assert!((report.lock().unwrap().as_ref().unwrap().percent_done - (0.8 / 3.0)).abs() < err);
1326+
core.report_complete("msg");
1327+
assert!((report.lock().unwrap().as_ref().unwrap().percent_done - (1.0 / 3.0)).abs() < err);
1328+
core.report_complete("msg");
1329+
assert!((report.lock().unwrap().as_ref().unwrap().percent_done - (2.0 / 3.0)).abs() < err);
1330+
core.report_progress("msg", StatusType::Downloading, 0.5);
1331+
assert!((report.lock().unwrap().as_ref().unwrap().percent_done - (2.5 / 3.0)).abs() < err);
1332+
core.report_complete("msg");
1333+
assert!((report.lock().unwrap().as_ref().unwrap().percent_done - 1.0).abs() < err);
1334+
}
12891335
}

0 commit comments

Comments
 (0)