Skip to content

Commit 7c2b7f6

Browse files
authored
Fix ark --install on Linux (#712)
1 parent 06153ba commit 7c2b7f6

File tree

5 files changed

+40
-36
lines changed

5 files changed

+40
-36
lines changed

CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,16 @@
22

33
# 0.1.9000
44

5+
## 2025-02
6+
7+
- Jupyter: The `--install` command now works on Linux (#648).
8+
9+
510
## 2024-12
611

712
- LSP: The statement range provider now has better support for expressions separated by `;` on a single line (posit-dev/positron#4317).
813

14+
915
## 2024-11
1016

1117
- LSP: Assignments in function calls (e.g. `list(x <- 1)`) are now detected by the missing symbol linter to avoid annoying false positive diagnostics (https://github.com/posit-dev/positron/issues/3048). The downside is that this causes false negatives when the assignment happens in a call with local scope, e.g. in `local()` or `test_that()`. We prefer to be overly permissive than overly cautious in these matters.
@@ -18,6 +24,7 @@
1824

1925
This solves a number of problems in situations that depend on these variables being defined (https://github.com/posit-dev/positron/issues/3637).
2026

27+
2128
## 2024-10
2229

2330
- Objects assigned at top level are now indexed, in addition to assigned functions. When a name is assigned multiple times, we now only index the first occurrence. This allows you to jump to the first "declaration" of the variable. In the future we'll improve this mechanism so that you can jump to the most recent assignment.

crates/ark/src/interface.rs

Lines changed: 2 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ use std::cell::UnsafeCell;
1515
use std::collections::HashMap;
1616
use std::ffi::*;
1717
use std::os::raw::c_uchar;
18-
use std::path::PathBuf;
1918
use std::result::Result::Ok;
2019
use std::sync::Arc;
2120
use std::sync::Mutex;
@@ -56,7 +55,7 @@ use crossbeam::channel::Receiver;
5655
use crossbeam::channel::Sender;
5756
use crossbeam::select;
5857
use harp::command::r_command;
59-
use harp::command::r_command_from_path;
58+
use harp::command::r_home_setup;
6059
use harp::environment::r_ns_env;
6160
use harp::environment::Environment;
6261
use harp::environment::R_ENVS;
@@ -376,28 +375,7 @@ impl RMain {
376375
args.push(CString::new(arg).unwrap().into_raw());
377376
}
378377

379-
let r_home = match std::env::var("R_HOME") {
380-
Ok(home) => {
381-
// Get `R_HOME` from env var, typically set by Positron / CI / kernel specification
382-
PathBuf::from(home)
383-
},
384-
Err(_) => {
385-
// Get `R_HOME` from `PATH`, via `R`
386-
let Ok(result) = r_command_from_path(|command| {
387-
command.arg("RHOME");
388-
}) else {
389-
panic!("Can't find R or `R_HOME`");
390-
};
391-
392-
let r_home = String::from_utf8(result.stdout).unwrap();
393-
let r_home = r_home.trim();
394-
395-
// Now set `R_HOME`. From now on, `r_command()` can be used to
396-
// run exactly the same R as is running in Ark.
397-
unsafe { std::env::set_var("R_HOME", r_home) };
398-
PathBuf::from(r_home)
399-
},
400-
};
378+
let r_home = r_home_setup();
401379

402380
// `R_HOME` is now defined no matter what and will be used by
403381
// `r_command()`. Let's discover the other important environment

crates/ark/src/main.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ fn main() -> anyhow::Result<()> {
128128
},
129129
"--install" => {
130130
install_kernel_spec()?;
131-
has_action = true;
131+
return Ok(());
132132
},
133133
"--help" => {
134134
print_usage();

crates/ark/src/version.rs

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ use std::path::PathBuf;
1111

1212
use anyhow::Context;
1313
use harp::command::r_command;
14+
use harp::command::r_home_setup;
1415
use harp::object::RObject;
1516
use itertools::Itertools;
1617
use libr::SEXP;
@@ -31,16 +32,7 @@ pub struct RVersion {
3132
}
3233

3334
pub fn detect_r() -> anyhow::Result<RVersion> {
34-
let output = r_command(|command| {
35-
command.arg("RHOME");
36-
})
37-
.context("Failed to execute R to determine R_HOME")?;
38-
39-
// Convert the output to a string
40-
let r_home = String::from_utf8(output.stdout)
41-
.context("Failed to convert R_HOME output to string")?
42-
.trim()
43-
.to_string();
35+
let r_home: String = r_home_setup().to_string_lossy().to_string();
4436

4537
let output = r_command(|command| {
4638
command

crates/harp/src/command.rs

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@ use crate::sys::command::COMMAND_R_NAMES;
1818
/// - For Windows, this looks at `R` (`R.exe`) and `R.bat` (for rig compatibility)
1919
///
2020
/// The executable name is joined to the path in `R_HOME`. If not set, this is a
21-
/// panic. Use `r_command_from_path()` to exectute R from `PATH` instead.
21+
/// panic. Use `r_home_setup()` to set `R_HOME` from the R on the `PATH` or use
22+
/// `r_command_from_path()` to exectute R from `PATH` directly.
2223
///
2324
/// Returns the `Ok()` value of the first success, or the `Err()` value of the
2425
/// last failure if all locations fail.
@@ -39,6 +40,32 @@ where
3940
r_command_from_locs(locations, build)
4041
}
4142

43+
/// Use this before calling `r_command()` to ensure that `R_HOME` is set consistently
44+
pub fn r_home_setup() -> PathBuf {
45+
match std::env::var("R_HOME") {
46+
Ok(home) => {
47+
// Get `R_HOME` from env var, typically set by Positron / CI / kernel specification
48+
PathBuf::from(home)
49+
},
50+
Err(_) => {
51+
// Get `R_HOME` from `PATH`, via `R`
52+
let Ok(result) = r_command_from_path(|command| {
53+
command.arg("RHOME");
54+
}) else {
55+
panic!("Can't find R or `R_HOME`");
56+
};
57+
58+
let r_home = String::from_utf8(result.stdout).unwrap();
59+
let r_home = r_home.trim();
60+
61+
// Now set `R_HOME`. From now on, `r_command()` can be used to
62+
// run exactly the same R as is running in Ark.
63+
unsafe { std::env::set_var("R_HOME", r_home) };
64+
PathBuf::from(r_home)
65+
},
66+
}
67+
}
68+
4269
/// Execute a `Command` for R found on the `PATH`
4370
///
4471
/// This is like `r_command()` but doesn't assume `R_HOME` is defined.

0 commit comments

Comments
 (0)