1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
|
//! ref: composer/src/Composer/Downloader/RarDownloader.php
use anyhow::Result;
use shirabe_external_packages::react::promise::promise_interface::PromiseInterface;
use shirabe_php_shim::{class_exists, implode, RarArchive, RuntimeException, UnexpectedValueException};
use crate::downloader::archive_downloader::ArchiveDownloader;
use crate::package::package_interface::PackageInterface;
use crate::util::ini_helper::IniHelper;
use crate::util::platform::Platform;
pub struct RarDownloader {
inner: ArchiveDownloader,
}
impl RarDownloader {
pub(crate) fn extract(&self, _package: &dyn PackageInterface, file: &str, path: &str) -> Result<Box<dyn PromiseInterface>> {
let mut process_error: Option<String> = None;
if !Platform::is_windows() {
let command = vec![
"sh".to_string(),
"-c".to_string(),
r#"unrar x -- "$0" "$1" >/dev/null && chmod -R u+w "$1""#.to_string(),
file.to_string(),
path.to_string(),
];
if self.inner.process.execute(&command, &mut String::new()) == 0 {
return Ok(shirabe_external_packages::react::promise::resolve(None));
}
process_error = Some(format!(
"Failed to execute {}\n\n{}",
implode(" ", &command),
self.inner.process.get_error_output(),
));
}
if !class_exists("RarArchive") {
let ini_message = IniHelper::get_message();
let error = if !Platform::is_windows() {
format!("Could not decompress the archive, enable the PHP rar extension.\n{}", ini_message)
} else {
format!(
"Could not decompress the archive, enable the PHP rar extension or install unrar.\n{}\n{}",
ini_message,
process_error.as_deref().unwrap_or(""),
)
};
return Err(RuntimeException { message: error, code: 0 }.into());
}
let rar_archive = RarArchive::open(file);
if rar_archive.is_none() {
return Err(UnexpectedValueException {
message: format!("Could not open RAR archive: {}", file),
code: 0,
}.into());
}
let rar_archive = rar_archive.unwrap();
let entries = rar_archive.get_entries();
if entries.is_none() {
return Err(RuntimeException {
message: "Could not retrieve RAR archive entries".to_string(),
code: 0,
}.into());
}
for entry in entries.unwrap() {
if !entry.extract(path) {
return Err(RuntimeException {
message: "Could not extract entry".to_string(),
code: 0,
}.into());
}
}
rar_archive.close();
Ok(shirabe_external_packages::react::promise::resolve(None))
}
}
|