zng_ext_setup/task/
copy_current_exe.rs1use std::path::PathBuf;
2
3use crate::task::{SetupTask, SetupTaskError};
4
5pub enum CopyCurrentExe {}
10impl SetupTask for CopyCurrentExe {
11 type InstallConfig = CopyCurrentExeConfig;
12
13 type PrepareInstall = PrepareInstallData;
14
15 type Install = InstallData;
16
17 fn task_type_id() -> super::TaskTypeId {
18 "zng-setup/CopyCurrentExe".into()
19 }
20
21 async fn prepare_install(args: super::PrepareInstallArgs<Self>) -> Result<Self::PrepareInstall, SetupTaskError> {
22 let exe = match std::env::current_exe() {
23 Ok(p) => p,
24 Err(e) => return Err(SetupTaskError::io(PathBuf::new(), e)),
25 };
26 let temp_exe = args.config.destination_exe.with_added_extension(".cce-tmp");
27
28 let target_dir = temp_exe.parent().unwrap();
29 if let Err(e) = zng_task::fs::create_dir_all(target_dir).await {
30 return Err(SetupTaskError::io(target_dir.to_path_buf(), e));
31 }
32
33 if let Err(e) = zng_task::fs::copy(&exe, &temp_exe).await {
34 return Err(SetupTaskError::io(temp_exe, e));
35 }
36
37 Ok(PrepareInstallData {
38 temp_exe,
39 destination_exe: args.config.destination_exe,
40 })
41 }
42
43 async fn install(args: super::InstallArgs<Self>) -> Result<Self::Install, super::InstallTaskError<Self::Install>> {
44 if let Err(e) = zng_task::fs::rename(&args.data.temp_exe, &args.data.destination_exe).await {
45 let _ = zng_task::fs::remove_file(&args.data.temp_exe).await;
46 return Err(super::InstallTaskError {
47 error: SetupTaskError::io(args.data.temp_exe, e),
48 clean_data: None,
49 });
50 }
51 Ok(InstallData {
52 destination_exe: args.data.destination_exe,
53 })
54 }
55
56 async fn cancel_install(args: super::CancelInstallArgs<Self>) -> Result<(), SetupTaskError> {
57 if let Err(e) = zng_task::fs::remove_file(&args.data.temp_exe).await
58 && !matches!(e.kind(), std::io::ErrorKind::NotFound)
59 {
60 return Err(SetupTaskError::io(args.data.temp_exe, e));
61 }
62 Ok(())
63 }
64
65 async fn validate_uninstall(args: super::ValidateUninstallArgs<Self>) -> Result<Self::Install, SetupTaskError> {
66 Ok(args.data)
67 }
68
69 async fn uninstall(args: super::UninstallArgs<Self>) -> Result<(), SetupTaskError> {
70 if let Err(e) = zng_task::fs::remove_file(&args.data.destination_exe).await
71 && !matches!(e.kind(), std::io::ErrorKind::NotFound)
72 {
73 return Err(SetupTaskError::io(args.data.destination_exe, e));
74 }
75 Ok(())
76 }
77}
78
79#[non_exhaustive]
81pub struct CopyCurrentExeConfig {
82 pub destination_exe: PathBuf,
84}
85impl CopyCurrentExeConfig {
86 pub fn new(destination_exe: PathBuf) -> Self {
88 Self { destination_exe }
89 }
90}
91
92#[doc(hidden)]
93#[derive(Debug, PartialEq, Clone, serde::Serialize, serde::Deserialize)]
94pub struct PrepareInstallData {
95 temp_exe: PathBuf,
96 destination_exe: PathBuf,
97}
98
99#[doc(hidden)]
100#[derive(Debug, PartialEq, Clone, serde::Serialize, serde::Deserialize)]
101pub struct InstallData {
102 destination_exe: PathBuf,
103}