Skip to content
Open
Show file tree
Hide file tree
Changes from 5 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
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,6 @@ from*/
logs/
dist/
global-cache/
drift-reviews/
drift-reviews/

temp-pkg
2 changes: 2 additions & 0 deletions src/cli/commands/init.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ const INITIAL_CONFIG: &str = r#"[project]
name = "%project_name%"
r_version = "%r_version%"
%use_devel%
# Optional: base URL for `rv add owner/repo` shorthand (defaults to https://github.com).
# git_shorthand_base_url = "https://github.example.com"
Comment thread
Keats marked this conversation as resolved.
# A list of repositories to fetch packages from. Order matters: we will try to get a package from each repository in order.
# The alias is only used in this file if you want to specifically require a dependency to come from a certain repository.
# Example: { alias = "PPM", url = "https://packagemanager.posit.co/cran/latest" },
Expand Down
81 changes: 80 additions & 1 deletion src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use std::str::FromStr;

use crate::SystemInfo;
use crate::consts::LOCKFILE_NAME;
use crate::dependency_edit::DEFAULT_GIT_SHORTHAND_BASE_URL;
use crate::git::url::GitUrl;
use crate::lockfile::Source;
use crate::package::{Version, deserialize_version, serialize_version};
Expand Down Expand Up @@ -351,6 +352,10 @@ pub(crate) struct Project {
/// Package-specific configure.args with system targeting
#[serde(default)]
pub configure_args: HashMap<String, Vec<ConfigureArgsRule>>,
/// Base URL used by `rv add <owner>/<repo>` shorthand.
/// Defaults to https://github.com when not specified.
#[serde(default)]
git_shorthand_base_url: Option<String>,
}

// That's the way to do it with serde :/
Expand Down Expand Up @@ -428,13 +433,33 @@ impl Config {
} => match (tag.is_some(), branch.is_some(), commit.is_some()) {
(true, false, false) | (false, true, false) | (false, false, true) => (),
_ => {
errors.push(format!("A git dependency `{git}` requires ons and only one of tag/branch/commit set. "));
errors.push(format!(
"A git dependency `{git}` requires one and only one of tag/branch/commit set."
));
}
},
_ => (),
}
}

if let Some(base_url) = self.project.git_shorthand_base_url.as_deref() {
let base_url = base_url.trim();
if base_url.is_empty() {
errors.push("`project.git_shorthand_base_url` cannot be empty.".to_string());
} else {
let probe_url = if base_url.ends_with(':') {
format!("{base_url}owner/repo")
} else {
format!("{}/owner/repo", base_url.trim_end_matches('/'))
};
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is that the same for gitlab/gitea?

if let Err(e) = GitUrl::try_from(probe_url.as_str()) {
errors.push(format!(
"Invalid `project.git_shorthand_base_url` `{base_url}`: {e}"
));
}
}
}

if !errors.is_empty() {
return Err(ConfigLoadError {
path: Path::new(".").into(),
Expand Down Expand Up @@ -509,6 +534,13 @@ impl Config {
pub fn configure_args(&self) -> &HashMap<String, Vec<ConfigureArgsRule>> {
&self.project.configure_args
}

pub fn git_shorthand_base_url(&self) -> &str {
self.project
.git_shorthand_base_url
.as_deref()
.unwrap_or(DEFAULT_GIT_SHORTHAND_BASE_URL)
}
}

impl FromStr for Config {
Expand Down Expand Up @@ -582,4 +614,51 @@ repositories = []
deserialized.r_version().original
);
}

#[test]
fn git_shorthand_base_url_defaults_and_overrides() {
let default_toml = r#"
[project]
name = "test"
r_version = "4.4"
repositories = []
"#;
let default_config = Config::from_str(default_toml).unwrap();
assert_eq!(
default_config.git_shorthand_base_url(),
crate::dependency_edit::DEFAULT_GIT_SHORTHAND_BASE_URL
);

let custom_toml = r#"
[project]
name = "test"
r_version = "4.4"
repositories = []
git_shorthand_base_url = "https://git.example.com/scm"
"#;
let custom_config = Config::from_str(custom_toml).unwrap();
assert_eq!(
custom_config.git_shorthand_base_url(),
"https://git.example.com/scm"
);
}

#[test]
fn invalid_git_shorthand_base_url_errors() {
let toml_str = r#"
[project]
name = "test"
r_version = "4.4"
repositories = []
git_shorthand_base_url = "git.example.com"
"#;
let err = Config::from_str(toml_str).unwrap_err();
assert!(
err.source
.to_string()
.contains("Invalid `project.git_shorthand_base_url`"),
"unexpected error: {}",
err.source
);
}
}
Loading