Add Explorer++ and Minecraft installers and implement ExtractFile and ExecuteCommand
This commit is contained in:
parent
35a3451061
commit
d962fc5870
|
@ -874,6 +874,15 @@ dependencies = [
|
|||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "signal-hook-registry"
|
||||
version = "1.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e51e73328dc4ac0c7ccbda3a494dfa03df1de2f46018127f60c693f2648455b0"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "slab"
|
||||
version = "0.4.6"
|
||||
|
@ -1017,6 +1026,7 @@ dependencies = [
|
|||
"mio",
|
||||
"once_cell",
|
||||
"pin-project-lite",
|
||||
"signal-hook-registry",
|
||||
"socket2",
|
||||
"tokio-macros",
|
||||
"winapi",
|
||||
|
|
|
@ -11,6 +11,6 @@ ramhorns = "0.14"
|
|||
reqwest = { version = "0.11.10", features = [ "json" ] }
|
||||
serde = { version = "1", features = [ "derive" ] }
|
||||
serde_json = "1"
|
||||
tokio = { version = "1.19", features = [ "fs", "macros", "rt" ] }
|
||||
tokio = { version = "1.19", features = [ "fs", "macros", "process", "rt" ] }
|
||||
url = "2.2"
|
||||
|
||||
|
|
|
@ -16,7 +16,10 @@ pub struct Pipeline<'a> {
|
|||
impl<'a> Pipeline<'a> {
|
||||
#[inline(always)]
|
||||
pub fn new(name: &'a str, steps: impl Into<Vec<Step<'a>>>) -> Self {
|
||||
Self { name, steps: steps.into() }
|
||||
Self {
|
||||
name,
|
||||
steps: steps.into(),
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn invoke(&self, ctx: &Context) -> Result<()> {
|
||||
|
@ -69,7 +72,10 @@ impl<'a> Step<'a> {
|
|||
pub async fn invoke(&self, ctx: &Context) -> Result<()> {
|
||||
match self {
|
||||
Self::DownloadFile { res, file } => {
|
||||
println!("Downloading file {file} from {res:?}...", file = file.to_str().unwrap_or("<NON UTF-8>"));
|
||||
println!(
|
||||
"Downloading file {file} from {res:?}...",
|
||||
file = file.to_str().unwrap_or("<NON UTF-8>")
|
||||
);
|
||||
const FETCH_FILE_ERROR_MSG: &'static str = "Fetching the remote resource failed.";
|
||||
const WRITE_FILE_ERROR_MSG: &'static str =
|
||||
"Writing the remote resource to disk failed.";
|
||||
|
@ -85,7 +91,9 @@ impl<'a> Step<'a> {
|
|||
))
|
||||
.into_diagnostic()
|
||||
.wrap_err("Invalid GitHub repo for download step.")?;
|
||||
let mut release: GitHubRelease = ctx.reqwest.get(url)
|
||||
let mut release: GitHubRelease = ctx
|
||||
.reqwest
|
||||
.get(url)
|
||||
.send()
|
||||
.await
|
||||
.into_diagnostic()
|
||||
|
@ -111,15 +119,22 @@ impl<'a> Step<'a> {
|
|||
)?
|
||||
}
|
||||
};
|
||||
let mut resp = ctx.reqwest.get(url)
|
||||
let mut resp = ctx
|
||||
.reqwest
|
||||
.get(url)
|
||||
.send()
|
||||
.await
|
||||
.into_diagnostic()
|
||||
.wrap_err(FETCH_FILE_ERROR_MSG)?;
|
||||
let _content_length = resp.content_length();
|
||||
mkdir_all(file.parent().ok_or_else(|| miette!("Destination file for download step has no parent."))?).await?;
|
||||
mkdir_all(
|
||||
file.parent().ok_or_else(|| {
|
||||
miette!("Destination file for download step has no parent.")
|
||||
})?,
|
||||
)
|
||||
.await?;
|
||||
let mut writer = tokio::io::BufWriter::new(
|
||||
tokio::fs::File::create(file)
|
||||
tokio::fs::File::create(file.as_os_str())
|
||||
.await
|
||||
.into_diagnostic()
|
||||
.wrap_err(WRITE_FILE_ERROR_MSG)?,
|
||||
|
@ -143,14 +158,43 @@ impl<'a> Step<'a> {
|
|||
.wrap_err(WRITE_FILE_ERROR_MSG)?;
|
||||
}
|
||||
Self::ExtractFile { file, dest } => {
|
||||
mkdir_all(dest).await?;
|
||||
todo!();
|
||||
const EXTRACT_FILE_ERROR_MSG: &'static str = "Extracting file failed.";
|
||||
let dest = tokio::fs::canonicalize(&dest)
|
||||
.await
|
||||
.into_diagnostic()
|
||||
.wrap_err(EXTRACT_FILE_ERROR_MSG)?;
|
||||
mkdir_all(&dest).await.wrap_err(EXTRACT_FILE_ERROR_MSG)?;
|
||||
let status = tokio::process::Command::new("tar")
|
||||
.arg("-xf")
|
||||
.arg(file.as_os_str())
|
||||
.current_dir(dest)
|
||||
.stdout(std::process::Stdio::inherit())
|
||||
.stderr(std::process::Stdio::inherit())
|
||||
.status()
|
||||
.await
|
||||
.into_diagnostic()
|
||||
.wrap_err(EXTRACT_FILE_ERROR_MSG)?;
|
||||
ensure!(status.success(), EXTRACT_FILE_ERROR_MSG);
|
||||
}
|
||||
Self::ExecuteCommand { file, args } => {
|
||||
todo!();
|
||||
const EXECUTE_COMMAND_ERROR_MSG: &'static str = "Executing command failed.";
|
||||
let status = tokio::process::Command::new(file.as_os_str())
|
||||
.args(*args)
|
||||
.stdout(std::process::Stdio::inherit())
|
||||
.stderr(std::process::Stdio::inherit())
|
||||
.status()
|
||||
.await
|
||||
.into_diagnostic()
|
||||
.wrap_err(EXECUTE_COMMAND_ERROR_MSG)?;
|
||||
ensure!(status.success(), EXECUTE_COMMAND_ERROR_MSG);
|
||||
}
|
||||
Self::CreateShortcut { target, icon, file } => {
|
||||
mkdir_all(file.parent().ok_or_else(|| miette!("Destination file for shortcut step has no parent."))?).await?;
|
||||
mkdir_all(
|
||||
file.parent().ok_or_else(|| {
|
||||
miette!("Destination file for shortcut step has no parent.")
|
||||
})?,
|
||||
)
|
||||
.await?;
|
||||
todo!();
|
||||
}
|
||||
}
|
||||
|
@ -247,5 +291,10 @@ const fn empty_str<'a>() -> &'a str {
|
|||
}
|
||||
|
||||
async fn mkdir_all(path: impl AsRef<Path>) -> Result<()> {
|
||||
tokio::fs::DirBuilder::new().recursive(true).create(path).await.into_diagnostic().wrap_err("Creating directory and any missing parents failed.")
|
||||
tokio::fs::DirBuilder::new()
|
||||
.recursive(true)
|
||||
.create(path)
|
||||
.await
|
||||
.into_diagnostic()
|
||||
.wrap_err("Creating directory and any missing parents failed.")
|
||||
}
|
||||
|
|
64
src/main.rs
64
src/main.rs
|
@ -34,24 +34,58 @@ async fn main() -> Result<()> {
|
|||
bail!("Could not find or access {}", SWTOOLS_PATH);
|
||||
}
|
||||
|
||||
let utilities = [Pipeline::new(
|
||||
"Install Notepad++",
|
||||
vec![
|
||||
Step::DownloadFile {
|
||||
file: swtools_path()
|
||||
.join("temp")
|
||||
.join("notepad-plus-plus.zip")
|
||||
.into(),
|
||||
res: RemoteResource::GitHubArtifact {
|
||||
repo: "notepad-plus-plus/notepad-plus-plus",
|
||||
pattern: "npp.{{tag_name_strip_prefix}}.portable.x64.zip",
|
||||
let nppp_zip = swtools_path().join("temp").join("notepad-plus-plus.zip");
|
||||
let epp_zip = swtools_path().join("temp").join("explorer-plus-plus.zip");
|
||||
|
||||
let utilities = [
|
||||
Pipeline::new(
|
||||
"Install Notepad++",
|
||||
vec![
|
||||
Step::DownloadFile {
|
||||
file: nppp_zip.as_path().into(),
|
||||
res: RemoteResource::GitHubArtifact {
|
||||
repo: "notepad-plus-plus/notepad-plus-plus",
|
||||
pattern: "npp.{{tag_name_strip_prefix}}.portable.x64.zip",
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
)];
|
||||
Step::ExtractFile {
|
||||
file: nppp_zip.as_path().into(),
|
||||
dest: swtools_path().join("notepad-plus-plus").into(),
|
||||
},
|
||||
],
|
||||
),
|
||||
Pipeline::new(
|
||||
"Install Explorer++",
|
||||
vec![
|
||||
Step::DownloadFile {
|
||||
file: epp_zip.as_path().into(),
|
||||
res: RemoteResource::Url(
|
||||
"https://explorerplusplus.com/software/explorer++_1.3.5_x64.zip",
|
||||
),
|
||||
},
|
||||
Step::ExtractFile {
|
||||
file: epp_zip.as_path().into(),
|
||||
dest: swtools_path().join("explorer-plus-plus").into(),
|
||||
},
|
||||
],
|
||||
),
|
||||
Pipeline::new(
|
||||
"Install Minecraft (Java Edition)",
|
||||
vec![Step::DownloadFile {
|
||||
file: swtools_path()
|
||||
.join("minecraft")
|
||||
.join("Minecraft.exe")
|
||||
.into(),
|
||||
res: RemoteResource::Url("https://launcher.mojang.com/download/Minecraft.exe"),
|
||||
}],
|
||||
),
|
||||
];
|
||||
|
||||
let ctx = Context {
|
||||
reqwest: reqwest::Client::builder().build().into_diagnostic().wrap_err("Could not initialize HTTP client.")?,
|
||||
reqwest: reqwest::Client::builder()
|
||||
.build()
|
||||
.into_diagnostic()
|
||||
.wrap_err("Could not initialize HTTP client.")?,
|
||||
};
|
||||
|
||||
for utility in utilities {
|
||||
|
|
Loading…
Reference in New Issue