Skip to content

Commit 6a00488

Browse files
committed
clippy fixes
1 parent d1642e3 commit 6a00488

File tree

2 files changed

+59
-40
lines changed

2 files changed

+59
-40
lines changed

crates/cli/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ dialoguer = "0.11"
1919
libloading = "0.8"
2020
cargo_metadata = "0.20"
2121
semver = "1.0"
22-
sudo = "0.6.0"
22+
elevate = "0.6.1"
2323

2424
[lints.rust]
2525
missing_docs = "warn"

crates/cli/src/lib.rs

Lines changed: 58 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,10 @@ impl Install {
200200
)?;
201201

202202
if !self.bypass_root_check {
203-
escalate_root();
203+
anyhow::ensure!(
204+
elevate::check() == elevate::RunningAs::User,
205+
"Running as root is not recommended. Use --bypass-root-check to override."
206+
);
204207
}
205208

206209
let (mut ext_dir, mut php_ini) = if let Some(install_dir) = self.install_dir {
@@ -231,43 +234,74 @@ impl Install {
231234
ext_dir.push(ext_name);
232235
}
233236

234-
std::fs::copy(&ext_path, &ext_dir).with_context(|| {
237+
copy_extension(&ext_path, &ext_dir).with_context(|| {
235238
"Failed to copy extension from target directory to extension directory"
236239
})?;
237240

238241
if let Some(php_ini) = php_ini {
239-
let mut file = OpenOptions::new()
242+
copy_ini_file(&php_ini, ext_name, self.disable)
243+
.with_context(|| "Failed to update `php.ini`")?;
244+
}
245+
246+
Ok(())
247+
}
248+
}
249+
250+
// Copy ini file, if fails, try with sudo again.
251+
fn copy_ini_file(php_ini: &PathBuf, ext_name: &str, disable: bool) -> anyhow::Result<()> {
252+
let mut file = match OpenOptions::new().read(true).write(true).open(php_ini) {
253+
Ok(x) => x,
254+
Err(_e) => {
255+
#[cfg(unix)]
256+
{
257+
elevate::escalate_if_needed().expect("sudo failed");
258+
}
259+
OpenOptions::new()
240260
.read(true)
241261
.write(true)
242262
.open(php_ini)
243-
.with_context(|| "Failed to open `php.ini`")?;
263+
.with_context(|| "Failed to open `php.ini`")?
264+
}
265+
};
244266

245-
let mut ext_line = format!("extension={ext_name}");
267+
let mut ext_line = format!("extension={ext_name}");
246268

247-
let mut new_lines = vec![];
248-
for line in BufReader::new(&file).lines() {
249-
let line = line.with_context(|| "Failed to read line from `php.ini`")?;
250-
if line.contains(&ext_line) {
251-
bail!("Extension already enabled.");
252-
}
269+
let mut new_lines = vec![];
270+
for line in BufReader::new(&file).lines() {
271+
let line = line.with_context(|| "Failed to read line from `php.ini`")?;
272+
if line.contains(&ext_line) {
273+
bail!("Extension already enabled.");
274+
}
253275

254-
new_lines.push(line);
255-
}
276+
new_lines.push(line);
277+
}
256278

257-
// Comment out extension if user specifies disable flag
258-
if self.disable {
259-
ext_line.insert(0, ';');
260-
}
279+
// Comment out extension if user specifies disable flag
280+
if disable {
281+
ext_line.insert(0, ';');
282+
}
261283

262-
new_lines.push(ext_line);
263-
file.rewind()?;
264-
file.set_len(0)?;
265-
file.write(new_lines.join("\n").as_bytes())
266-
.with_context(|| "Failed to update `php.ini`")?;
267-
}
284+
new_lines.push(ext_line);
285+
file.rewind()?;
286+
file.set_len(0)?;
287+
let _ = file.write(new_lines.join("\n").as_bytes())?;
288+
Ok(())
289+
}
268290

269-
Ok(())
291+
// Copy extension, if fails, try with sudo again.
292+
//
293+
// We can check if we have write permission for ext_dir but due to ACL, group
294+
// list and and other nuances, it may not be reliable. See
295+
// https://doc.rust-lang.org/std/fs/struct.Permissions.html#method.readonly
296+
fn copy_extension(ext_path: &Utf8PathBuf, ext_dir: &PathBuf) -> anyhow::Result<()> {
297+
if let Err(_e) = std::fs::copy(ext_path, ext_dir) {
298+
#[cfg(unix)]
299+
{
300+
elevate::escalate_if_needed().expect("sudo failed");
301+
}
302+
std::fs::copy(ext_path, ext_dir)?;
270303
}
304+
Ok(())
271305
}
272306

273307
/// Returns the path to the extension directory utilised by the PHP interpreter,
@@ -328,12 +362,6 @@ impl Remove {
328362

329363
let artifact = find_ext(self.manifest.as_ref())?;
330364

331-
// Must be called after cargo_manifest call in find_path. Though we are setting PATHso that
332-
// sudo can find cargo but cargo_manifest doesn't use PATH to locate cargo!
333-
if !self.bypass_root_check {
334-
escalate_root();
335-
}
336-
337365
let (mut ext_path, mut php_ini) = if let Some(install_dir) = self.install_dir {
338366
(install_dir, None)
339367
} else {
@@ -584,12 +612,3 @@ fn build_ext(
584612

585613
bail!("Failed to retrieve extension path from artifact")
586614
}
587-
588-
fn escalate_root() {
589-
// use sudo and pass PATH for command like `cargo metadata` to keep working.
590-
#[cfg(unix)]
591-
{
592-
sudo::with_env(&["CARGO", "PATH"])
593-
.expect("sudo failed! Use --bypass-root-check to disable.");
594-
}
595-
}

0 commit comments

Comments
 (0)