Skip to content

Check whether to load databases after sync mode check #207

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
May 1, 2025
Merged
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
3 changes: 2 additions & 1 deletion example_projects/project-upgrade/rproject.toml
Original file line number Diff line number Diff line change
@@ -4,7 +4,8 @@
name = "project-upgrade"
r_version = "4.4"
repositories = [
{alias = "PPM", url = "https://packagemanager.posit.co/cran/2024-12-22"}
{alias = "PPM", url = "https://packagemanager.posit.co/cran/2025-04-12"},
{alias = "PPM-old", url = "https://packagemanager.posit.co/cran/2025-04-01"}
]

dependencies = [
118 changes: 34 additions & 84 deletions example_projects/project-upgrade/rv.lock
Original file line number Diff line number Diff line change
@@ -3,79 +3,59 @@
version = 1
r_version = "4.4"

[[packages]]
name = "MASS"
version = "7.3-60.2"
source = { repository = "https://packagemanager.posit.co/cran/2024-02-22" }
path = "4.4.0/Recommended"
force_source = false
dependencies = []

[[packages]]
name = "Matrix"
version = "1.6-5"
source = { repository = "https://packagemanager.posit.co/cran/2024-02-22" }
path = "4.4.0/Recommended"
force_source = false
dependencies = [
"lattice",
]

[[packages]]
name = "R6"
version = "2.5.1"
source = { repository = "https://packagemanager.posit.co/cran/2024-02-22" }
version = "2.6.1"
source = { repository = "https://packagemanager.posit.co/cran/2025-04-01" }
force_source = false
dependencies = []

[[packages]]
name = "RColorBrewer"
version = "1.1-3"
source = { repository = "https://packagemanager.posit.co/cran/2024-02-22" }
source = { repository = "https://packagemanager.posit.co/cran/2025-04-01" }
force_source = false
dependencies = []

[[packages]]
name = "cli"
version = "3.6.2"
source = { repository = "https://packagemanager.posit.co/cran/2024-02-22" }
version = "3.6.4"
source = { repository = "https://packagemanager.posit.co/cran/2025-04-01" }
force_source = false
dependencies = []

[[packages]]
name = "colorspace"
version = "2.1-0"
source = { repository = "https://packagemanager.posit.co/cran/2024-02-22" }
version = "2.1-1"
source = { repository = "https://packagemanager.posit.co/cran/2025-04-01" }
force_source = false
dependencies = []

[[packages]]
name = "fansi"
version = "1.0.6"
source = { repository = "https://packagemanager.posit.co/cran/2024-02-22" }
source = { repository = "https://packagemanager.posit.co/cran/2025-04-01" }
force_source = false
dependencies = []

[[packages]]
name = "farver"
version = "2.1.1"
source = { repository = "https://packagemanager.posit.co/cran/2024-02-22" }
version = "2.1.2"
source = { repository = "https://packagemanager.posit.co/cran/2025-04-01" }
force_source = false
dependencies = []

[[packages]]
name = "ggplot2"
version = "3.4.4"
source = { repository = "https://packagemanager.posit.co/cran/2024-02-22" }
version = "3.5.1"
source = { repository = "https://packagemanager.posit.co/cran/2025-04-01" }
force_source = false
dependencies = [
"cli",
"glue",
"gtable",
"isoband",
"lifecycle",
"MASS",
"mgcv",
"rlang",
"scales",
"tibble",
@@ -85,15 +65,15 @@ dependencies = [

[[packages]]
name = "glue"
version = "1.7.0"
source = { repository = "https://packagemanager.posit.co/cran/2024-02-22" }
version = "1.8.0"
source = { repository = "https://packagemanager.posit.co/cran/2025-04-01" }
force_source = false
dependencies = []

[[packages]]
name = "gtable"
version = "0.3.4"
source = { repository = "https://packagemanager.posit.co/cran/2024-02-22" }
version = "0.3.6"
source = { repository = "https://packagemanager.posit.co/cran/2025-04-01" }
force_source = false
dependencies = [
"cli",
@@ -105,29 +85,21 @@ dependencies = [
[[packages]]
name = "isoband"
version = "0.2.7"
source = { repository = "https://packagemanager.posit.co/cran/2024-02-22" }
source = { repository = "https://packagemanager.posit.co/cran/2025-04-01" }
force_source = false
dependencies = []

[[packages]]
name = "labeling"
version = "0.4.3"
source = { repository = "https://packagemanager.posit.co/cran/2024-02-22" }
force_source = false
dependencies = []

[[packages]]
name = "lattice"
version = "0.22-5"
source = { repository = "https://packagemanager.posit.co/cran/2024-02-22" }
path = "4.4.0/Recommended"
source = { repository = "https://packagemanager.posit.co/cran/2025-04-01" }
force_source = false
dependencies = []

[[packages]]
name = "lifecycle"
version = "1.0.4"
source = { repository = "https://packagemanager.posit.co/cran/2024-02-22" }
source = { repository = "https://packagemanager.posit.co/cran/2025-04-01" }
force_source = false
dependencies = [
"cli",
@@ -138,48 +110,26 @@ dependencies = [
[[packages]]
name = "magrittr"
version = "2.0.3"
source = { repository = "https://packagemanager.posit.co/cran/2024-02-22" }
source = { repository = "https://packagemanager.posit.co/cran/2025-04-01" }
force_source = false
dependencies = []

[[packages]]
name = "mgcv"
version = "1.9-1"
source = { repository = "https://packagemanager.posit.co/cran/2024-02-22" }
path = "4.4.0/Recommended"
force_source = false
dependencies = [
"nlme",
"Matrix",
]

[[packages]]
name = "munsell"
version = "0.5.0"
source = { repository = "https://packagemanager.posit.co/cran/2024-02-22" }
version = "0.5.1"
source = { repository = "https://packagemanager.posit.co/cran/2025-04-01" }
force_source = false
dependencies = [
"colorspace",
]

[[packages]]
name = "nlme"
version = "3.1-164"
source = { repository = "https://packagemanager.posit.co/cran/2024-02-22" }
path = "4.4.0/Recommended"
force_source = false
dependencies = [
"lattice",
]

[[packages]]
name = "pillar"
version = "1.9.0"
source = { repository = "https://packagemanager.posit.co/cran/2024-02-22" }
version = "1.10.1"
source = { repository = "https://packagemanager.posit.co/cran/2025-04-01" }
force_source = false
dependencies = [
"cli",
"fansi",
"glue",
"lifecycle",
"rlang",
@@ -190,21 +140,21 @@ dependencies = [
[[packages]]
name = "pkgconfig"
version = "2.0.3"
source = { repository = "https://packagemanager.posit.co/cran/2024-02-22" }
source = { repository = "https://packagemanager.posit.co/cran/2025-04-01" }
force_source = false
dependencies = []

[[packages]]
name = "rlang"
version = "1.1.3"
source = { repository = "https://packagemanager.posit.co/cran/2024-02-22" }
version = "1.1.5"
source = { repository = "https://packagemanager.posit.co/cran/2025-04-01" }
force_source = false
dependencies = []

[[packages]]
name = "scales"
version = "1.3.0"
source = { repository = "https://packagemanager.posit.co/cran/2024-02-22" }
source = { repository = "https://packagemanager.posit.co/cran/2025-04-01" }
force_source = false
dependencies = [
"cli",
@@ -222,7 +172,7 @@ dependencies = [
[[packages]]
name = "tibble"
version = "3.2.1"
source = { repository = "https://packagemanager.posit.co/cran/2024-02-22" }
source = { repository = "https://packagemanager.posit.co/cran/2025-04-01" }
force_source = false
dependencies = [
"fansi",
@@ -237,14 +187,14 @@ dependencies = [
[[packages]]
name = "utf8"
version = "1.2.4"
source = { repository = "https://packagemanager.posit.co/cran/2024-02-22" }
source = { repository = "https://packagemanager.posit.co/cran/2025-04-01" }
force_source = false
dependencies = []

[[packages]]
name = "vctrs"
version = "0.6.5"
source = { repository = "https://packagemanager.posit.co/cran/2024-02-22" }
source = { repository = "https://packagemanager.posit.co/cran/2025-04-01" }
force_source = false
dependencies = [
"cli",
@@ -256,13 +206,13 @@ dependencies = [
[[packages]]
name = "viridisLite"
version = "0.4.2"
source = { repository = "https://packagemanager.posit.co/cran/2024-02-22" }
source = { repository = "https://packagemanager.posit.co/cran/2025-04-01" }
force_source = false
dependencies = []

[[packages]]
name = "withr"
version = "3.0.0"
source = { repository = "https://packagemanager.posit.co/cran/2024-02-22" }
version = "3.0.2"
source = { repository = "https://packagemanager.posit.co/cran/2025-04-01" }
force_source = false
dependencies = []
3 changes: 1 addition & 2 deletions src/activate.rs
Original file line number Diff line number Diff line change
@@ -97,8 +97,7 @@ fn scripts_as_paths(is_home: bool) -> (PathBuf, PathBuf) {

fn write_activate_file(dir: impl AsRef<Path>, is_home: bool) -> Result<(), ActivateError> {
let template = ACTIVATE_FILE_TEMPLATE.to_string();
let global_wd_content = if is_home
{
let global_wd_content = if is_home {
r#"
owd <- getwd()
setwd("~")
10 changes: 10 additions & 0 deletions src/lockfile.rs
Original file line number Diff line number Diff line change
@@ -481,6 +481,16 @@ impl Lockfile {
true
}

pub fn contains_resolved_dep(&self, dep: &ResolvedDependency) -> bool {
self.packages
.iter()
.find(|lock_pkg| {
lock_pkg.name == dep.name.as_ref()
&& lock_pkg.version == dep.version.as_ref().original
})
.is_some()
}

/// Gets a set of all the package names listed in the lockfile
pub fn package_names(&self) -> HashSet<&str> {
let mut out = HashSet::new();
72 changes: 54 additions & 18 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -123,16 +123,24 @@ pub enum MigrateSubcommand {
},
}

#[derive(Debug, Clone)]
enum SyncMode {
#[derive(Debug, Clone, PartialEq)]
enum ResolveMode {
Default,
FullUpgrade,
// TODO: PartialUpgrade -- allow user to specify packages to upgrade
}

/// Resolve dependencies for the project. If there are any unmet dependencies, they will be printed
/// to stderr and the cli will exit.
fn resolve_dependencies(context: &CliContext) -> Vec<ResolvedDependency> {
fn resolve_dependencies<'a>(
context: &'a CliContext,
resolve_mode: &ResolveMode,
) -> Vec<ResolvedDependency<'a>> {
let lockfile = match resolve_mode {
ResolveMode::Default => &context.lockfile,
ResolveMode::FullUpgrade => &None,
};

let mut resolver = Resolver::new(
&context.project_dir,
&context.databases,
@@ -143,8 +151,9 @@ fn resolve_dependencies(context: &CliContext) -> Vec<ResolvedDependency> {
.map(|x| x.url())
.collect(),
&context.r_version,
context.lockfile.as_ref(),
lockfile.as_ref(),
);

if context.show_progress_bar {
resolver.show_progress_bar();
}
@@ -164,24 +173,46 @@ fn resolve_dependencies(context: &CliContext) -> Vec<ResolvedDependency> {
::std::process::exit(1)
}

resolution.found
// If upgrade and there is a lockfile, we want to adjust the resolved dependencies s.t. if the resolved dep has the same
// name and version in the lockfile, we say that it was resolved from the lockfile
let resolved = if resolve_mode == &ResolveMode::FullUpgrade && context.lockfile.is_some() {
resolution
.found
.into_iter()
.map(|mut dep| {
dep.from_lockfile = context
.lockfile
.as_ref()
.unwrap()
.contains_resolved_dep(&dep);
dep
})
.collect::<Vec<_>>()
} else {
resolution.found
};

resolved
}

fn _sync(
mut context: CliContext,
dry_run: bool,
has_logs_enabled: bool,
sync_mode: SyncMode,
resolve_mode: ResolveMode,
) -> Result<()> {
if !has_logs_enabled {
context.show_progress_bar();
}
context.load_databases_if_needed()?;
match sync_mode {
SyncMode::Default => (),
SyncMode::FullUpgrade => context.lockfile = None,

// If the sync mode is an upgrade, we want to load the databases even if all packages are contained in the lockfile
// because we ignore the lockfile during initial resolution
match resolve_mode {
ResolveMode::Default => context.load_databases_if_needed()?,
ResolveMode::FullUpgrade => context.load_databases()?,
}
let resolved = resolve_dependencies(&context);

let resolved = resolve_dependencies(&context, &resolve_mode);

match timeit!(
if dry_run {
@@ -312,16 +343,21 @@ fn try_main() -> Result<()> {
}
Command::Plan { upgrade } => {
let upgrade = if upgrade {
SyncMode::FullUpgrade
ResolveMode::FullUpgrade
} else {
SyncMode::Default
ResolveMode::Default
};
let context = CliContext::new(&cli.config_file)?;
_sync(context, true, cli.verbose.is_present(), upgrade)?;
}
Command::Sync => {
let context = CliContext::new(&cli.config_file)?;
_sync(context, false, cli.verbose.is_present(), SyncMode::Default)?;
_sync(
context,
false,
cli.verbose.is_present(),
ResolveMode::Default,
)?;
}
Command::Add {
packages,
@@ -349,7 +385,7 @@ fn try_main() -> Result<()> {
context,
dry_run,
cli.verbose.is_present(),
SyncMode::Default,
ResolveMode::Default,
)?;
}
Command::Upgrade { dry_run } => {
@@ -358,7 +394,7 @@ fn try_main() -> Result<()> {
context,
dry_run,
cli.verbose.is_present(),
SyncMode::FullUpgrade,
ResolveMode::FullUpgrade,
)?;
}
Command::Info {
@@ -396,7 +432,7 @@ fn try_main() -> Result<()> {
let info = CacheInfo::new(
&context.config,
&context.cache,
resolve_dependencies(&context),
resolve_dependencies(&context, &ResolveMode::Default),
);
if json {
println!(
@@ -451,7 +487,7 @@ fn try_main() -> Result<()> {
Command::Summary { json } => {
let mut context = CliContext::new(&cli.config_file)?;
context.load_databases()?;
let resolved = resolve_dependencies(&context);
let resolved = resolve_dependencies(&context, &ResolveMode::Default);
let summary = ProjectSummary::new(
&context.library,
&resolved,
2 changes: 1 addition & 1 deletion src/resolver/dependency.rs
Original file line number Diff line number Diff line change
@@ -27,7 +27,7 @@ pub struct ResolvedDependency<'d> {
pub(crate) kind: PackageType,
pub(crate) installation_status: InstallationStatus,
pub(crate) path: Option<Cow<'d, str>>,
pub(crate) from_lockfile: bool,
pub from_lockfile: bool,
pub(crate) from_remote: bool,
// Remotes are only for local/git deps so the values will always be owned
pub(crate) remotes: HashMap<String, (Option<String>, PackageRemote)>,