Skip to content

Commit 436a466

Browse files
committed
Use tempfile instead of hardcode name
1 parent 352384f commit 436a466

File tree

5 files changed

+39
-34
lines changed

5 files changed

+39
-34
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,3 +31,4 @@ tokio = { version = "1.44", features = ["full"] }
3131
truncatable = "0.1"
3232
anyhow = "1.0"
3333
base64 = "0.22"
34+
tempfile = "3.18"

src/config.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -129,11 +129,10 @@ impl Config {
129129
/// * If config file does not exist, creates default config file to path and returns error.
130130
/// * If found, tries to parse the file and returns error if parse fails or fields found undefined.
131131
pub fn parse_config(path: &str) -> Result<Config> {
132-
// Create `~/.config` directory if not exists
133-
create_parent_dir(path)?;
134-
135132
// Create mihoro default config if not exists
136133
let config_path = Path::new(path);
134+
create_parent_dir(config_path)?;
135+
137136
if !config_path.exists() {
138137
Config::new().write(config_path)?;
139138
bail!(

src/mihoro.rs

Lines changed: 16 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,14 @@ use crate::utils::{
88

99
use std::fs;
1010
use std::os::unix::prelude::PermissionsExt;
11+
use std::path::Path;
1112

1213
use anyhow::{anyhow, Result};
1314
use colored::Colorize;
1415
use local_ip_address::local_ip;
1516
use reqwest::Client;
1617
use shellexpand::tilde;
18+
use tempfile::NamedTempFile;
1719

1820
#[derive(Debug)]
1921
pub struct Mihoro {
@@ -31,7 +33,7 @@ pub struct Mihoro {
3133
impl Mihoro {
3234
pub fn new(config_path: &String) -> Result<Mihoro> {
3335
let config = parse_config(tilde(&config_path).as_ref())?;
34-
return Ok(Mihoro {
36+
Ok(Mihoro {
3537
prefix: String::from("mihoro:"),
3638
config: config.clone(),
3739
mihomo_target_binary_path: tilde(&config.mihomo_binary_path).to_string(),
@@ -43,7 +45,7 @@ impl Mihoro {
4345
config.user_systemd_root
4446
))
4547
.to_string(),
46-
});
48+
})
4749
}
4850

4951
pub async fn setup(&self, client: Client, overwrite_binary: bool) -> Result<()> {
@@ -69,20 +71,15 @@ impl Mihoro {
6971
);
7072
}
7173

74+
// Create a temporary file for downloading
75+
let temp_file = NamedTempFile::new()?;
76+
let temp_path = temp_file.path();
77+
7278
// Download mihomo binary and set permission to executable
73-
download_file(
74-
&client,
75-
&self.config.remote_mihomo_binary_url,
76-
"mihomo-downloaded-binary.tar.gz",
77-
)
78-
.await?;
79+
download_file(&client, &self.config.remote_mihomo_binary_url, temp_path).await?;
7980

8081
// Try to extract the binary, handle "Text file busy" error if overwriting
81-
match extract_gzip(
82-
"mihomo-downloaded-binary.tar.gz",
83-
&self.mihomo_target_binary_path,
84-
&self.prefix,
85-
) {
82+
match extract_gzip(temp_path, &self.mihomo_target_binary_path, &self.prefix) {
8683
Ok(_) => {
8784
// Set executable permission
8885
let executable = fs::Permissions::from_mode(0o755);
@@ -103,7 +100,7 @@ impl Mihoro {
103100
download_file(
104101
&client,
105102
&self.config.remote_config_url,
106-
&self.mihomo_target_config_path,
103+
Path::new(&self.mihomo_target_config_path),
107104
)
108105
.await?;
109106

@@ -133,7 +130,7 @@ impl Mihoro {
133130
download_file(
134131
&client,
135132
&self.config.remote_config_url,
136-
&self.mihomo_target_config_path,
133+
Path::new(&self.mihomo_target_config_path),
137134
)
138135
.await?;
139136

@@ -160,20 +157,20 @@ impl Mihoro {
160157
download_file(
161158
&client,
162159
&geox_url.geoip,
163-
format!("{}/geoip.dat", &self.mihomo_target_config_root).as_str(),
160+
&Path::new(&self.mihomo_target_config_root).join("geoip.dat"),
164161
)
165162
.await?;
166163
download_file(
167164
&client,
168165
&geox_url.geosite,
169-
format!("{}/geosite.dat", &self.mihomo_target_config_root).as_str(),
166+
&Path::new(&self.mihomo_target_config_root).join("geosite.dat"),
170167
)
171168
.await?;
172169
} else {
173170
download_file(
174171
&client,
175172
&geox_url.mmdb,
176-
format!("{}/country.mmdb", &self.mihomo_target_config_root).as_str(),
173+
&Path::new(&self.mihomo_target_config_root).join("country.mmdb"),
177174
)
178175
.await?;
179176
}
@@ -312,7 +309,7 @@ WantedBy=default.target",
312309
);
313310

314311
// Create mihomo service directory if not exists
315-
create_parent_dir(mihomo_service_path)?;
312+
create_parent_dir(Path::new(mihomo_service_path))?;
316313

317314
// Write mihomo.service contents to file
318315
fs::write(mihomo_service_path, service)?;

src/utils.rs

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,14 @@ use truncatable::Truncatable;
1919
/// # Arguments
2020
///
2121
/// * `path` - A string slice that holds the path for which the parent directory should be created.
22-
pub fn create_parent_dir(path: &str) -> Result<()> {
23-
let parent_dir = Path::new(path)
24-
.parent()
25-
.with_context(|| format!("parent directory of `{}` invalid", path))?;
22+
pub fn create_parent_dir(path: &Path) -> Result<()> {
23+
// let parent_dir = Path::new(path)
24+
let parent_dir = path.parent().with_context(|| {
25+
format!(
26+
"parent directory of `{}` invalid",
27+
path.to_string_lossy()
28+
)
29+
})?;
2630
if !parent_dir.exists() {
2731
fs::create_dir_all(parent_dir)?;
2832
}
@@ -40,7 +44,7 @@ pub fn create_parent_dir(path: &str) -> Result<()> {
4044
///
4145
/// Note: Allow `clippy::unused_io_amount` because we are writing downloaded chunks on the fly.
4246
#[allow(clippy::unused_io_amount)]
43-
pub async fn download_file(client: &Client, url: &str, path: &str) -> Result<()> {
47+
pub async fn download_file(client: &Client, url: &str, path: &Path) -> Result<()> {
4448
// Create parent directory for download destination if not exists
4549
create_parent_dir(path)?;
4650

@@ -97,7 +101,10 @@ pub async fn download_file(client: &Client, url: &str, path: &str) -> Result<()>
97101
}
98102
}
99103

100-
pb.finish_with_message(format!("Downloaded to {}", path.underline()));
104+
pb.finish_with_message(format!(
105+
"Downloaded to {}",
106+
path.to_str().unwrap().underline()
107+
));
101108
Ok(())
102109
}
103110

@@ -111,19 +118,19 @@ pub fn delete_file(path: &str, prefix: &str) -> Result<()> {
111118
Ok(())
112119
}
113120

114-
pub fn extract_gzip(gzip_path: &str, filename: &str, prefix: &str) -> Result<()> {
121+
pub fn extract_gzip(from_path: &Path, to_path: &str, prefix: &str) -> Result<()> {
115122
// Create parent directory for extraction dest if not exists
116-
create_parent_dir(filename)?;
123+
create_parent_dir(Path::new(to_path))?;
117124

118125
// Extract gzip file
119-
let mut archive = GzDecoder::new(fs::File::open(gzip_path)?);
120-
let mut file = fs::File::create(filename)?;
126+
let mut archive = GzDecoder::new(File::open(from_path)?);
127+
let mut file = File::create(to_path)?;
121128
io::copy(&mut archive, &mut file)?;
122-
fs::remove_file(gzip_path)?;
129+
// fs::remove_file(gzip_path)?;
123130
println!(
124131
"{} Extracted to {}",
125132
prefix.green(),
126-
filename.underline().yellow()
133+
to_path.underline().yellow()
127134
);
128135
Ok(())
129136
}

0 commit comments

Comments
 (0)