Skip to content

Commit 7046739

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 0db6343 commit 7046739

File tree

1 file changed

+92
-55
lines changed

1 file changed

+92
-55
lines changed

src/handler.rs

Lines changed: 92 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,56 @@ pub struct HandlerOptions {
230230
pub log_tail: u64,
231231
}
232232

233+
struct GitLabArtifacts<'a> {
234+
job: &'a Job,
235+
artifacts: &'a mut HashMap<Utf8PathBuf, AsyncFile>,
236+
}
237+
238+
#[async_trait]
239+
impl ArtifactDirectory for GitLabArtifacts<'_> {
240+
#[instrument(skip(self, path), path = path.as_ref())]
241+
async fn open(&self, path: impl AsRef<Utf8Path> + Send) -> Result<AsyncFile> {
242+
let path = path.as_ref();
243+
244+
if let Some(file) = self.artifacts.get(path) {
245+
let file = file.reopen().await.wrap_err("Failed to reopen artifact")?;
246+
return Ok(file);
247+
}
248+
249+
for dep in self.job.dependencies() {
250+
if let Some(file) = check_for_artifact(dep, path).await? {
251+
return Ok(file);
252+
}
253+
}
254+
255+
Err(MissingArtifact(path.to_owned()).into())
256+
}
257+
258+
#[tracing::instrument(skip(self, path, func), path = path.as_ref())]
259+
async fn save_with<
260+
Ret: Send,
261+
Err: Send,
262+
Fut: Future<Output = Result<Ret, Err>> + Send,
263+
F: (FnOnce(ScopedCell<AsyncFile>) -> Fut) + Send,
264+
>(
265+
&mut self,
266+
path: impl AsRef<Utf8Path> + Send,
267+
func: F,
268+
) -> Result<Ret>
269+
where
270+
Report: From<Err>,
271+
{
272+
let file = async_tempfile().await?;
273+
let (mut file, ret) = ScopedCell::run(file, func).await;
274+
let ret = ret?;
275+
276+
file.flush().await?;
277+
self.artifacts
278+
.insert(path.as_ref().to_owned(), file.reopen().await?);
279+
Ok(ret)
280+
}
281+
}
282+
233283
pub struct ObsJobHandler {
234284
job: Job,
235285
client: obs::Client,
@@ -291,6 +341,11 @@ impl ObsJobHandler {
291341

292342
#[instrument(skip(self))]
293343
async fn run_dput(&mut self, args: DputAction) -> Result<()> {
344+
let mut artifacts = GitLabArtifacts {
345+
job: &self.job,
346+
artifacts: &mut self.artifacts,
347+
};
348+
294349
let branch_to = if !args.branch_to.is_empty() {
295350
Some(args.branch_to)
296351
} else {
@@ -307,7 +362,7 @@ impl ObsJobHandler {
307362
args.project.clone(),
308363
branch_to,
309364
args.dsc.as_str().into(),
310-
self,
365+
&artifacts,
311366
)
312367
.await?;
313368

@@ -320,7 +375,10 @@ impl ObsJobHandler {
320375
enabled_repos: HashMap::new(),
321376
};
322377
debug!("Saving initial build info: {:?}", build_info);
323-
build_info.clone().save(self, &args.build_info_out).await?;
378+
build_info
379+
.clone()
380+
.save(&mut artifacts, &args.build_info_out)
381+
.await?;
324382

325383
let initial_build_meta = BuildMeta::get_if_package_exists(
326384
self.client.clone(),
@@ -336,7 +394,7 @@ impl ObsJobHandler {
336394
.await?;
337395
debug!(?initial_build_meta);
338396

339-
let result = uploader.upload_package(self).await?;
397+
let result = uploader.upload_package(&artifacts).await?;
340398

341399
// If we couldn't get the metadata before because the package didn't
342400
// exist yet, get it now but without history, so we leave the previous
@@ -394,14 +452,21 @@ impl ObsJobHandler {
394452
..build_info
395453
};
396454
debug!("Saving complete build info: {:?}", build_info);
397-
build_info.save(self, &args.build_info_out).await?;
455+
build_info
456+
.save(&mut artifacts, &args.build_info_out)
457+
.await?;
398458

399459
Ok(())
400460
}
401461

402462
#[instrument(skip(self))]
403463
async fn run_generate_monitor(&mut self, args: GenerateMonitorAction) -> Result<()> {
404-
let build_info_data = self.read_string(&args.build_info).await?;
464+
let mut artifacts = GitLabArtifacts {
465+
job: &self.job,
466+
artifacts: &mut self.artifacts,
467+
};
468+
469+
let build_info_data = artifacts.read_string(&args.build_info).await?;
405470
let build_info: ObsBuildInfo = serde_yaml::from_str(&build_info_data)
406471
.wrap_err("Failed to parse provided build info file")?;
407472

@@ -434,14 +499,21 @@ impl ObsJobHandler {
434499
},
435500
)?;
436501

437-
self.write(&args.pipeline_out, pipeline.as_bytes()).await?;
502+
artifacts
503+
.write(&args.pipeline_out, pipeline.as_bytes())
504+
.await?;
438505
outputln!("Wrote pipeline file '{}'.", args.pipeline_out);
439506

440507
Ok(())
441508
}
442509

443510
#[instrument(skip(self))]
444511
async fn run_monitor(&mut self, args: MonitorAction) -> Result<()> {
512+
let mut artifacts = GitLabArtifacts {
513+
job: &self.job,
514+
artifacts: &mut self.artifacts,
515+
};
516+
445517
let monitor = ObsMonitor::new(
446518
self.client.clone(),
447519
MonitoredPackage {
@@ -461,7 +533,7 @@ impl ObsJobHandler {
461533
debug!("Completed with: {:?}", completion);
462534

463535
let mut log_file = monitor
464-
.download_build_log(&args.build_log_out, self)
536+
.download_build_log(&args.build_log_out, &mut artifacts)
465537
.await?;
466538

467539
match completion {
@@ -508,13 +580,18 @@ impl ObsJobHandler {
508580

509581
#[instrument(skip(self))]
510582
async fn run_download_binaries(&mut self, args: DownloadBinariesAction) -> Result<()> {
583+
let mut artifacts = GitLabArtifacts {
584+
job: &self.job,
585+
artifacts: &mut self.artifacts,
586+
};
587+
511588
let binaries = download_binaries(
512589
self.client.clone(),
513590
&args.project,
514591
&args.package,
515592
&args.repository,
516593
&args.arch,
517-
self,
594+
&mut artifacts,
518595
&args.build_results_dir,
519596
)
520597
.await?;
@@ -530,8 +607,13 @@ impl ObsJobHandler {
530607
return Ok(());
531608
}
532609

610+
let artifacts = GitLabArtifacts {
611+
job: &self.job,
612+
artifacts: &mut self.artifacts,
613+
};
614+
533615
let build_info_data = if args.ignore_missing_build_info {
534-
if let Some(build_info_data) = self
616+
if let Some(build_info_data) = artifacts
535617
.read_string(&args.build_info)
536618
.await
537619
.missing_artifact_to_none()?
@@ -545,7 +627,7 @@ impl ObsJobHandler {
545627
return Ok(());
546628
}
547629
} else {
548-
self.read_string(&args.build_info).await?
630+
artifacts.read_string(&args.build_info).await?
549631
};
550632

551633
let build_info: ObsBuildInfo = serde_yaml::from_str(&build_info_data)
@@ -698,51 +780,6 @@ async fn check_for_artifact(dep: Dependency<'_>, path: &Utf8Path) -> Result<Opti
698780
Ok(None)
699781
}
700782

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

0 commit comments

Comments
 (0)