Skip to content

Commit

Permalink
automatically update the lockfile and support --locked
Browse files Browse the repository at this point in the history
There is a problem because cargo2nix is not using the cargo binary here, which
could result in the lockfile being different than the project's lock file.

We want the behavior that cargo implements privately, to see that the lockfile
is out of date and to ask if the user wants to update it.

Cargo2nix could offload the work via metadata and json parsing, which may make
more sense as a cargo plugin.

Cargo2nix will be limited in its capability to work seemlessly with newer or
older projects if they generate lockfiles that clash with the output of
cargo2nix.  The use of the cargo library further cements the potential for
disparity.
  • Loading branch information
psionic-k committed Oct 16, 2023
1 parent 5f02705 commit 3dab03f
Showing 1 changed file with 24 additions and 4 deletions.
28 changes: 24 additions & 4 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,14 @@ use cargo::{
core::{
compiler::{CompileKind, RustcTargetData},
dependency::DepKind,
registry::PackageRegistry,
resolver::{
features::{ForceAllTargets, HasDevUnits},
CliFeatures, Resolve,
},
Package, PackageId, PackageIdSpec, Workspace,
},
ops::{resolve_ws_with_opts, Packages},
ops::{resolve_with_previous, resolve_ws_with_opts, Packages},
util::important_paths::find_root_manifest_for_wd,
};
use cargo_platform::Platform;
Expand Down Expand Up @@ -59,6 +60,9 @@ struct Opt {
/// Overwrite existing output filepath without prompting
#[arg(action, long, short)]
overwrite: bool,
/// Don't attempt to update the lockfile
#[arg(action, long, short, value_name = "LOCKED")]
locked: bool,
/// Output to stdout
#[arg(conflicts_with = "file", action, long, short)]
stdout: bool,
Expand All @@ -77,7 +81,8 @@ fn main() -> std::io::Result<()> {
let workspace_directory = opt.workspace_directory.unwrap_or(std::env::current_dir()?).canonicalize()?;
let file = opt.file.unwrap_or(PathBuf::from("./Cargo.nix"));

let rendered = generate_cargo_nix(&workspace_directory).expect("Error generating nix expressions");
let rendered = generate_cargo_nix(&workspace_directory, opt.locked)
.expect("Error generating nix expressions");

if opt.stdout { write_to_stdout(&rendered).expect("Error writing to stdout"); }
else { write_to_file(&file, &rendered, &opt.overwrite).expect("Error writing to file"); }
Expand Down Expand Up @@ -187,10 +192,10 @@ fn write_to_stdout(rendered: &str) -> Result<()> {
Ok(())
}

fn generate_cargo_nix(workspace_directory: &PathBuf) -> Result<String> {
fn generate_cargo_nix(workspace_directory: &PathBuf, locked: bool) -> Result<String> {
let config = {
let mut config = cargo::Config::default()?;
config.configure(0, true, None, false, true, false, &None, &[], &[])?;
config.configure(0, false, None, false, locked, false, &None, &[], &[])?;
config
};

Expand All @@ -204,6 +209,21 @@ fn generate_cargo_nix(workspace_directory: &PathBuf) -> Result<String> {
let cargo_lock_hash: String = format!("{:x}", hasher.finalize());
let ws = Workspace::new(&root_manifest_path, &config)?;

if !locked {
let mut registry = PackageRegistry::new(ws.config())?;
let mut resolve = resolve_with_previous(
&mut registry,
&ws,
&CliFeatures::new_all(true),
HasDevUnits::Yes,
None,
None,
&[],
true,
)?;
cargo::ops::write_pkg_lockfile(&ws, &mut resolve)?;
}

// To get a list of all packages with all features and dependencies that
// might be enabled present, we first resolve with all features turned on
let requested_kinds = CompileKind::from_requested_targets(ws.config(), &[])?;
Expand Down

0 comments on commit 3dab03f

Please sign in to comment.