Skip to content

Commit 45031d4

Browse files
committed
Move Handler's ArtifactDirectory implementation to a separate type
Passing around `self` risks confusing the borrow checker if we need to invoke a method on a field, and it's rather confusing to begin with.
1 parent 0fa9c0b commit 45031d4

File tree

1 file changed

+87
-50
lines changed

1 file changed

+87
-50
lines changed

src/handler.rs

Lines changed: 87 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,51 @@ pub struct HandlerOptions {
228228
pub log_tail: u64,
229229
}
230230

231+
struct GitLabArtifacts<'a> {
232+
job: &'a Job,
233+
artifacts: &'a mut HashMap<Utf8PathBuf, ArtifactReader>,
234+
}
235+
236+
#[async_trait]
237+
impl ArtifactDirectory for GitLabArtifacts<'_> {
238+
#[instrument(skip(self, path), path = path.as_ref())]
239+
async fn open(&self, path: impl AsRef<Utf8Path> + Send) -> Result<ArtifactReader> {
240+
let path = path.as_ref();
241+
242+
if let Some(file) = self.artifacts.get(path) {
243+
let file = file
244+
.try_clone()
245+
.await
246+
.wrap_err("Failed to reopen artifact")?;
247+
return Ok(file);
248+
}
249+
250+
for dep in self.job.dependencies() {
251+
if let Some(file) = check_for_artifact(dep, path).await? {
252+
return Ok(file);
253+
}
254+
}
255+
256+
Err(MissingArtifact(path.to_owned()).into())
257+
}
258+
259+
#[tracing::instrument(skip(self, path, func), path = path.as_ref())]
260+
async fn save_with<Ret, Err, F, P>(&mut self, path: P, func: F) -> Result<Ret>
261+
where
262+
Report: From<Err>,
263+
Ret: Send,
264+
Err: Send,
265+
F: for<'a> SaveCallback<'a, Ret, Err> + Send,
266+
P: AsRef<Utf8Path> + Send,
267+
{
268+
let mut writer = ArtifactWriter::new().await?;
269+
let ret = func(&mut writer).await?;
270+
self.artifacts
271+
.insert(path.as_ref().to_owned(), writer.into_reader().await?);
272+
Ok(ret)
273+
}
274+
}
275+
231276
pub struct ObsJobHandler {
232277
job: Job,
233278
client: obs::Client,
@@ -289,6 +334,11 @@ impl ObsJobHandler {
289334

290335
#[instrument(skip(self))]
291336
async fn run_dput(&mut self, args: DputAction) -> Result<()> {
337+
let mut artifacts = GitLabArtifacts {
338+
job: &self.job,
339+
artifacts: &mut self.artifacts,
340+
};
341+
292342
let branch_to = if !args.branch_to.is_empty() {
293343
Some(args.branch_to)
294344
} else {
@@ -305,7 +355,7 @@ impl ObsJobHandler {
305355
args.project.clone(),
306356
branch_to,
307357
args.dsc.as_str().into(),
308-
self,
358+
&artifacts,
309359
)
310360
.await?;
311361

@@ -318,7 +368,10 @@ impl ObsJobHandler {
318368
enabled_repos: HashMap::new(),
319369
};
320370
debug!("Saving initial build info: {:?}", build_info);
321-
build_info.clone().save(self, &args.build_info_out).await?;
371+
build_info
372+
.clone()
373+
.save(&mut artifacts, &args.build_info_out)
374+
.await?;
322375

323376
let initial_build_meta = BuildMeta::get_if_package_exists(
324377
self.client.clone(),
@@ -334,7 +387,7 @@ impl ObsJobHandler {
334387
.await?;
335388
debug!(?initial_build_meta);
336389

337-
let result = uploader.upload_package(self).await?;
390+
let result = uploader.upload_package(&artifacts).await?;
338391

339392
// If we couldn't get the metadata before because the package didn't
340393
// exist yet, get it now but without history, so we leave the previous
@@ -392,14 +445,21 @@ impl ObsJobHandler {
392445
..build_info
393446
};
394447
debug!("Saving complete build info: {:?}", build_info);
395-
build_info.save(self, &args.build_info_out).await?;
448+
build_info
449+
.save(&mut artifacts, &args.build_info_out)
450+
.await?;
396451

397452
Ok(())
398453
}
399454

400455
#[instrument(skip(self))]
401456
async fn run_generate_monitor(&mut self, args: GenerateMonitorAction) -> Result<()> {
402-
let build_info_data = self.read_string(&args.build_info).await?;
457+
let mut artifacts = GitLabArtifacts {
458+
job: &self.job,
459+
artifacts: &mut self.artifacts,
460+
};
461+
462+
let build_info_data = artifacts.read_string(&args.build_info).await?;
403463
let build_info: ObsBuildInfo = serde_yaml::from_str(&build_info_data)
404464
.wrap_err("Failed to parse provided build info file")?;
405465

@@ -432,14 +492,21 @@ impl ObsJobHandler {
432492
},
433493
)?;
434494

435-
self.write(&args.pipeline_out, pipeline.as_bytes()).await?;
495+
artifacts
496+
.write(&args.pipeline_out, pipeline.as_bytes())
497+
.await?;
436498
outputln!("Wrote pipeline file '{}'.", args.pipeline_out);
437499

438500
Ok(())
439501
}
440502

441503
#[instrument(skip(self))]
442504
async fn run_monitor(&mut self, args: MonitorAction) -> Result<()> {
505+
let mut artifacts = GitLabArtifacts {
506+
job: &self.job,
507+
artifacts: &mut self.artifacts,
508+
};
509+
443510
let monitor = ObsMonitor::new(
444511
self.client.clone(),
445512
MonitoredPackage {
@@ -459,7 +526,7 @@ impl ObsJobHandler {
459526
debug!("Completed with: {:?}", completion);
460527

461528
let mut log_file = monitor
462-
.download_build_log(&args.build_log_out, self)
529+
.download_build_log(&args.build_log_out, &mut artifacts)
463530
.await?;
464531

465532
match completion {
@@ -506,13 +573,18 @@ impl ObsJobHandler {
506573

507574
#[instrument(skip(self))]
508575
async fn run_download_binaries(&mut self, args: DownloadBinariesAction) -> Result<()> {
576+
let mut artifacts = GitLabArtifacts {
577+
job: &self.job,
578+
artifacts: &mut self.artifacts,
579+
};
580+
509581
let binaries = download_binaries(
510582
self.client.clone(),
511583
&args.project,
512584
&args.package,
513585
&args.repository,
514586
&args.arch,
515-
self,
587+
&mut artifacts,
516588
&args.build_results_dir,
517589
)
518590
.await?;
@@ -528,8 +600,13 @@ impl ObsJobHandler {
528600
return Ok(());
529601
}
530602

603+
let artifacts = GitLabArtifacts {
604+
job: &self.job,
605+
artifacts: &mut self.artifacts,
606+
};
607+
531608
let build_info_data = if args.ignore_missing_build_info {
532-
if let Some(build_info_data) = self
609+
if let Some(build_info_data) = artifacts
533610
.read_string(&args.build_info)
534611
.await
535612
.missing_artifact_to_none()?
@@ -543,7 +620,7 @@ impl ObsJobHandler {
543620
return Ok(());
544621
}
545622
} else {
546-
self.read_string(&args.build_info).await?
623+
artifacts.read_string(&args.build_info).await?
547624
};
548625

549626
let build_info: ObsBuildInfo = serde_yaml::from_str(&build_info_data)
@@ -701,46 +778,6 @@ async fn check_for_artifact(
701778
Ok(None)
702779
}
703780

704-
#[async_trait]
705-
impl ArtifactDirectory for ObsJobHandler {
706-
#[instrument(skip(self, path), path = path.as_ref())]
707-
async fn open(&self, path: impl AsRef<Utf8Path> + Send) -> Result<ArtifactReader> {
708-
let path = path.as_ref();
709-
710-
if let Some(file) = self.artifacts.get(path) {
711-
let file = file
712-
.try_clone()
713-
.await
714-
.wrap_err("Failed to reopen artifact")?;
715-
return Ok(file);
716-
}
717-
718-
for dep in self.job.dependencies() {
719-
if let Some(file) = check_for_artifact(dep, path).await? {
720-
return Ok(file);
721-
}
722-
}
723-
724-
Err(MissingArtifact(path.to_owned()).into())
725-
}
726-
727-
#[tracing::instrument(skip(self, path, func), path = path.as_ref())]
728-
async fn save_with<Ret, Err, F, P>(&mut self, path: P, func: F) -> Result<Ret>
729-
where
730-
Report: From<Err>,
731-
Ret: Send,
732-
Err: Send,
733-
F: for<'a> SaveCallback<'a, Ret, Err> + Send,
734-
P: AsRef<Utf8Path> + Send,
735-
{
736-
let mut writer = ArtifactWriter::new().await?;
737-
let ret = func(&mut writer).await?;
738-
self.artifacts
739-
.insert(path.as_ref().to_owned(), writer.into_reader().await?);
740-
Ok(ret)
741-
}
742-
}
743-
744781
#[cfg(test)]
745782
mod tests {
746783
use std::{

0 commit comments

Comments
 (0)