Skip to content

Commit 8b6c275

Browse files
committed
Refactor
1 parent 0a0e5a5 commit 8b6c275

5 files changed

Lines changed: 183 additions & 299 deletions

File tree

lib/asimov-installer/src/installer.rs

Lines changed: 18 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,11 @@
22

33
use asimov_module::{InstalledModuleManifest, ModuleManifest, tracing};
44
use std::{path::Path, string::String};
5-
use tokio::io;
65

76
pub mod error;
87
use error::*;
98

10-
use asimov_registry::{Registry, error::ReadManifestError};
9+
use asimov_registry::Registry;
1110

1211
mod github;
1312
mod platform;
@@ -50,13 +49,8 @@ impl Installer {
5049
.preinstall(module_name.as_ref(), version.as_ref(), temp_dir.path())
5150
.await?;
5251

53-
self.finish_install(
54-
module_name.as_ref(),
55-
version.as_ref(),
56-
manifest,
57-
temp_dir.path(),
58-
)
59-
.await?;
52+
self.finish_install(version.as_ref(), manifest, temp_dir.path())
53+
.await?;
6054

6155
Ok(())
6256
}
@@ -98,7 +92,7 @@ impl Installer {
9892
// now ok to uninstall old version
9993
self.uninstall_module(module_name).await?;
10094

101-
self.finish_install(module_name, version, manifest, temp_dir.path())
95+
self.finish_install(version, manifest, temp_dir.path())
10296
.await?;
10397

10498
if was_enabled {
@@ -112,37 +106,19 @@ impl Installer {
112106
&self,
113107
module_name: impl AsRef<str>,
114108
) -> Result<(), UninstallError> {
115-
let manifest_path = self
116-
.registry
117-
.find_manifest_file(module_name.as_ref())
118-
.await?
119-
.ok_or(UninstallError::NotInstalled)?;
120-
121-
let manifest = read_manifest(&manifest_path).await?;
109+
let manifest = self.registry.read_manifest(&module_name).await?;
122110

123111
self.registry.disable_module(&module_name).await?;
124112

125-
tokio::fs::remove_file(&manifest_path).await.or_else(|e| {
126-
if e.kind() == io::ErrorKind::NotFound {
127-
Ok(())
128-
} else {
129-
Err(UninstallError::Delete(manifest_path, e))
130-
}
131-
})?;
132-
133-
let exec_dir = self.registry.exec_dir();
134-
135-
for program in manifest.manifest.provides.programs {
136-
let path = exec_dir.join(program);
137-
tokio::fs::remove_file(&path).await.or_else(|e| {
138-
if e.kind() == io::ErrorKind::NotFound {
139-
Ok(())
140-
} else {
141-
Err(UninstallError::Delete(path, e))
142-
}
143-
})?;
113+
for program in &manifest.manifest.provides.programs {
114+
self.registry
115+
.remove_binary(program)
116+
.await
117+
.map_err(|e| UninstallError::RemoveBinary(program.into(), e))?;
144118
}
145119

120+
self.registry.remove_manifest(&module_name).await?;
121+
146122
Ok(())
147123
}
148124

@@ -156,9 +132,7 @@ impl Installer {
156132

157133
let release = github::fetch_release(&self.client, module_name, version)
158134
.await
159-
.map_err(|_| {
160-
PreinstallError::CreateManifestDir(std::io::Error::other("Failed to fetch release"))
161-
})?;
135+
.map_err(PreinstallError::FetchRelease)?;
162136

163137
let Some(asset) = github::find_matching_asset(&release.assets, module_name, &platform)
164138
else {
@@ -193,58 +167,24 @@ impl Installer {
193167

194168
async fn finish_install(
195169
&self,
196-
module_name: &str,
197170
version: &str,
198171
manifest: ModuleManifest,
199172
temp_dir: &Path,
200173
) -> Result<(), FinishInstallError> {
201174
let extract_dir = temp_dir.join("extract");
202175

203-
let manifest_path = self
204-
.registry
205-
.install_dir()
206-
.join(std::format!("{module_name}.json"));
207-
208-
github::install_binaries(&manifest, &extract_dir, &self.registry.exec_dir())
209-
.await
210-
.map_err(FinishInstallError::BinaryInstall)?;
176+
for program in &manifest.provides.programs {
177+
let src = extract_dir.join(program);
178+
self.registry.add_binary(program, &src).await?;
179+
}
211180

212181
let installed_manifest = InstalledModuleManifest {
213182
version: Some(version.into()),
214183
manifest,
215184
};
216-
let mut manifest_json = serde_json::to_string_pretty(&installed_manifest)?;
217-
manifest_json.push('\n'); // always newline-terminate text files
218185

219-
tokio::fs::write(&manifest_path, &manifest_json)
220-
.await
221-
.map_err(FinishInstallError::SaveManifest)?;
186+
self.registry.add_manifest(installed_manifest).await?;
222187

223188
Ok(())
224189
}
225190
}
226-
227-
async fn read_manifest(
228-
path: impl AsRef<Path>,
229-
) -> Result<InstalledModuleManifest, ReadManifestError> {
230-
let manifest = match path.as_ref().extension().and_then(|ext| ext.to_str()) {
231-
Some("yaml") | Some("yml") => {
232-
let content = tokio::fs::read(&path)
233-
.await
234-
.map_err(ReadManifestError::InstalledManifestIo)?;
235-
236-
serde_yaml_ng::from_slice::<'_, InstalledModuleManifest>(&content)?
237-
},
238-
Some("json") => {
239-
let content = tokio::fs::read(&path)
240-
.await
241-
.map_err(ReadManifestError::InstalledManifestIo)?;
242-
243-
serde_json::from_slice::<'_, InstalledModuleManifest>(&content)?
244-
},
245-
ext => Err(ReadManifestError::UnknownManifestFormat(
246-
ext.map(Into::into),
247-
))?,
248-
};
249-
Ok(manifest)
250-
}

lib/asimov-installer/src/installer/error.rs

Lines changed: 14 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ use super::platform::PlatformInfo;
44
use asimov_registry::error as registry;
55
use std::{
66
io,
7-
path::PathBuf,
87
string::{String, ToString as _},
98
};
109
use thiserror::Error;
@@ -39,16 +38,14 @@ pub enum UpgradeError {
3938

4039
#[derive(Debug, Error)]
4140
pub enum UninstallError {
42-
#[error("error while searching for manifest file: {0}")]
43-
FindManifest(#[from] registry::FindManifestError),
4441
#[error("unable to read module manifest file: {0}")]
45-
Read(#[from] registry::ReadManifestError),
42+
Read(#[from] registry::ManifestError),
4643
#[error(transparent)]
4744
Disable(#[from] registry::DisableError),
48-
#[error("unable to remove installed module file `{0}`: {1}")]
49-
Delete(PathBuf, io::Error),
50-
#[error("module is not installed")]
51-
NotInstalled,
45+
#[error("unable to remove installed module binary `{0}`: {1}")]
46+
RemoveBinary(String, #[source] registry::RemoveBinaryError),
47+
#[error("unable to remove installed module manifest: {0}")]
48+
RemoveManifest(#[from] registry::RemoveManifestError),
5249
}
5350

5451
mod common {
@@ -120,12 +117,8 @@ mod common {
120117

121118
#[derive(Debug, Error)]
122119
pub enum PreinstallError {
123-
#[error("failed to create directory for installed manifests: {0}")]
124-
CreateManifestDir(io::Error),
125-
#[error("failed to create directory for installed binaries: {0}")]
126-
CreateExecDir(io::Error),
127-
#[error("failed to create directory for extracting: {0}")]
128-
CreateExtractDir(io::Error),
120+
#[error("failed fetch release: {0}")]
121+
FetchRelease(FetchError),
129122

130123
#[error("no binaries available for platform `{}-{}{}`", .0.os, .0.arch, if let Some(ref libc) = .0.libc { "-".to_string() + libc } else { "".to_string() })]
131124
NotAvailable(PlatformInfo),
@@ -140,18 +133,19 @@ mod common {
140133
#[error(transparent)]
141134
VerifyChecksum(#[from] VerifyChecksumError),
142135

136+
#[error("failed to create directory for extracting: {0}")]
137+
CreateExtractDir(io::Error),
138+
143139
#[error("failed to extract archive: {0}")]
144140
Extract(io::Error),
145141
}
146142

147143
#[derive(Debug, Error)]
148144
pub enum FinishInstallError {
149-
#[error("failed to install binaries: {0}")]
150-
BinaryInstall(io::Error),
151-
#[error("failed to serialize module manifest: {0}")]
152-
SerializeManifest(#[from] serde_json::Error),
153-
#[error("failed to save module manifest: {0}")]
154-
SaveManifest(io::Error),
145+
#[error("failed to install binary: {0}")]
146+
AddBinary(#[from] registry::AddBinaryError),
147+
#[error("failed to add manifest: {0}")]
148+
AddManifest(#[from] registry::AddManifestError),
155149
}
156150
}
157151
pub use common::*;

lib/asimov-installer/src/installer/github.rs

Lines changed: 0 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -247,25 +247,3 @@ pub async fn extract_files(
247247

248248
Ok(())
249249
}
250-
251-
pub async fn install_binaries(
252-
manifest: &ModuleManifest,
253-
extract_dir: &Path,
254-
install_dir: &Path,
255-
) -> Result<(), tokio::io::Error> {
256-
for program in &manifest.provides.programs {
257-
let src = extract_dir.join(program);
258-
let dst = install_dir.join(program);
259-
260-
tokio::fs::copy(&src, &dst).await?;
261-
262-
#[cfg(unix)]
263-
{
264-
use std::fs::Permissions;
265-
use std::os::unix::fs::PermissionsExt;
266-
tokio::fs::set_permissions(&dst, Permissions::from_mode(0o755)).await?;
267-
}
268-
}
269-
270-
Ok(())
271-
}

0 commit comments

Comments
 (0)