Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion src/help-linux.in
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,9 @@ const HELP_ADD: &str = "
- `rig add x.y` adds the latest release within the `x.y` minor branch.
- `rig add oldrel/n` adds the latest release within the `n`th previous
minor branch (`oldrel` is the same as `oldrel/1`).
- `rig add renv.lock` or `rig add <dir>` installs the R version specified
in the renv.lock file. If a directory is given, rig looks for an
renv.lock file in that directory.

You need to run this command with `sudo`: `sudo rig add ...`,
otherwise rig will need to ask for your password.
Expand All @@ -130,7 +133,13 @@ const HELP_ADD_EXAMPLES: &str = "\x1b[4m\x1b[1mExamples:\x1b[22m\x1b[24m
rig add 4.1.2

# Install latest version within a minor branch
rig add 4.1";
rig add 4.1

# Install the R version specified in renv.lock
rig add renv.lock

# Install R version from a project's renv.lock
rig add path/to/project";

const HELP_RM: &str = "
\x1b[4m\x1b[1mDescription:\x1b[22m\x1b[24m
Expand Down
11 changes: 10 additions & 1 deletion src/help-macos.in
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,9 @@ const HELP_ADD: &str = "
- `rig add oldrel/n` adds the latest release within the `n`th previous
minor branch (`oldrel` is the same as `oldrel/1`).
- `rig add <url>` uses a `.pkg` installer from `<url>`.
- `rig add renv.lock` or `rig add <dir>` installs the R version specified
in the renv.lock file. If a directory is given, rig looks for an
renv.lock file in that directory.

Usually you need to run this command with `sudo`: `sudo rig add ...`,
otherwise rig will need to ask for your password.
Expand Down Expand Up @@ -150,7 +153,13 @@ const HELP_ADD_EXAMPLES: &str = "\x1b[4m\x1b[1mExamples:\x1b[22m\x1b[24m
rig add -a arm64 release

# Install x86_64 build of R (default on x86_64 macs)
rig add -a x86_64 release";
rig add -a x86_64 release

# Install the R version specified in renv.lock
rig add renv.lock

# Install R version from a project's renv.lock
rig add path/to/project";

const HELP_RM: &str = "
\x1b[4m\x1b[1mDescription:\x1b[22m\x1b[24m
Expand Down
11 changes: 10 additions & 1 deletion src/help-windows.in
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,9 @@ const HELP_ADD: &str = "
- `rig add oldrel/n` adds the latest release within the `n`th previous
minor branch (`oldrel` is the same as `oldrel/1`).
- `rig add <url>` uses a `.pkg` installer from `<url>`.
- `rig add renv.lock` or `rig add <dir>` installs the R version specified
in the renv.lock file. If a directory is given, rig looks for an
renv.lock file in that directory.

`rig add` will call the following rig command after the installation,
to set up the newly installed version:
Expand Down Expand Up @@ -149,7 +152,13 @@ const HELP_ADD_EXAMPLES: &str = "\x1b[4m\x1b[1mExamples:\x1b[22m\x1b[24m
rig add 4.1

# Install all needed Rtools versions
rig add rtools";
rig add rtools

# Install the R version specified in renv.lock
rig add renv.lock

# Install R version from a project's renv.lock
rig add path/to/project";

const HELP_RM: &str = "
\x1b[4m\x1b[1mDescription:\x1b[22m\x1b[24m
Expand Down
88 changes: 88 additions & 0 deletions src/resolve.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,22 +11,56 @@ use simple_error::bail;
#[cfg(target_os = "windows")]
use std::sync::{LazyLock, RwLock};

use std::path::Path;

use crate::common::*;
use crate::download::*;
#[cfg(target_os = "windows")]
use crate::hardcoded::*;
use crate::output::OUTPUT;
use crate::renv;
use crate::rversion::*;
use crate::utils::*;

const API_URI: &str = "https://api.r-hub.io/rversions/resolve/";
#[cfg(target_os = "windows")]
const API_ROOT: &str = "https://api.r-hub.io/rversions/";

pub fn resolve_lockfile_version(str: &str) -> Result<Option<String>, Box<dyn Error>> {
let path = Path::new(str);

// Direct path to renv.lock
if path.file_name() == Some(std::ffi::OsStr::new("renv.lock")) && path.exists() {
let ver = renv::parse_r_version(path.to_path_buf())?;
OUTPUT.info(&format!("Installing R {} from renv.lock", ver));
return Ok(Some(ver));
}

// Directory containing renv.lock
if path.is_dir() {
let lockfile = path.join("renv.lock");
if lockfile.exists() {
let ver = renv::parse_r_version(lockfile)?;
OUTPUT.info(&format!("Installing R {} from renv.lock", ver));
return Ok(Some(ver));
}
}

Ok(None)
}

pub fn get_resolve(args: &ArgMatches) -> Result<Rversion, Box<dyn Error>> {
let platform = get_platform(args)?;
let arch = get_arch(&platform, args);
let str: &String = args.get_one("str").unwrap();

// Check if str is a path to renv.lock or a directory containing one
let resolved_ver = resolve_lockfile_version(str)?;
let str = match &resolved_ver {
Some(ver) => ver.as_str(),
None => str.as_str(),
};

let eps = vec![str.to_string()];

if str.len() > 8 && (&str[..7] == "http://" || &str[..8] == "https://") {
Expand Down Expand Up @@ -186,3 +220,57 @@ pub fn get_rtools_version(version: &str, arch: &str) -> Result<RtoolsVersion, Bo
error!("{}", msg);
bail!(msg)
}

#[cfg(test)]
mod tests {
use super::*;
use std::env;

#[test]
fn test_resolve_lockfile_direct_path() {
let manifest_dir = env::var("CARGO_MANIFEST_DIR").unwrap();
let lockfile = format!("{}/tests/fixtures/renv-project/renv.lock", manifest_dir);
let result = resolve_lockfile_version(&lockfile).unwrap();
assert_eq!(result, Some("4.4.1".to_string()));
}

#[test]
fn test_resolve_lockfile_directory() {
let manifest_dir = env::var("CARGO_MANIFEST_DIR").unwrap();
let dir = format!("{}/tests/fixtures/renv-project", manifest_dir);
let result = resolve_lockfile_version(&dir).unwrap();
assert_eq!(result, Some("4.4.1".to_string()));
}

#[test]
fn test_resolve_lockfile_not_a_path() {
let result = resolve_lockfile_version("release").unwrap();
assert_eq!(result, None);
}

#[test]
fn test_resolve_lockfile_version_string() {
let result = resolve_lockfile_version("4.4.1").unwrap();
assert_eq!(result, None);
}

#[test]
fn test_resolve_lockfile_devel() {
let result = resolve_lockfile_version("devel").unwrap();
assert_eq!(result, None);
}

#[test]
fn test_resolve_lockfile_nonexistent_path() {
let result = resolve_lockfile_version("/nonexistent/renv.lock").unwrap();
assert_eq!(result, None);
}

#[test]
fn test_resolve_lockfile_dir_without_lockfile() {
let manifest_dir = env::var("CARGO_MANIFEST_DIR").unwrap();
let dir = format!("{}/tests/fixtures/app-shiny", manifest_dir);
let result = resolve_lockfile_version(&dir).unwrap();
assert_eq!(result, None);
}
}
19 changes: 19 additions & 0 deletions tests/fixtures/renv-project/renv.lock
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"R": {
"Version": "4.4.1",
"Repositories": [
{
"Name": "CRAN",
"URL": "https://cloud.r-project.org"
}
]
},
"Packages": {
"renv": {
"Package": "renv",
"Version": "1.1.5",
"Source": "Repository",
"Repository": "CRAN"
}
}
}
Loading