mirror of
https://github.com/rust-lang/cargo.git
synced 2025-09-25 11:14:46 +00:00
Add EditionFixMode
This adds the `EditionFixMode` enum to control the behavior of `cargo fix --edition`. The main intent is to provide a way to force `cargo fix` to migrate to a specific edition, instead of just going to the "next". This will be needed for `-Zfix-edition` in order to force it to use the "future" edition, which is never the "next" edition. This requires being able to serialize and deserialize this setting as it is conveyed through an environment variable to the recursive cargo invocation.
This commit is contained in:
parent
9d93b42c4c
commit
331dcec02d
@ -95,7 +95,9 @@ pub fn exec(gctx: &mut GlobalContext, args: &ArgMatches) -> CliResult {
|
||||
gctx,
|
||||
&ws,
|
||||
&mut ops::FixOptions {
|
||||
edition: args.flag("edition"),
|
||||
edition: args
|
||||
.flag("edition")
|
||||
.then_some(ops::EditionFixMode::NextRelative),
|
||||
idioms: args.flag("edition-idioms"),
|
||||
compile_opts: opts,
|
||||
allow_dirty,
|
||||
|
@ -90,7 +90,7 @@ const IDIOMS_ENV_INTERNAL: &str = "__CARGO_FIX_IDIOMS";
|
||||
const SYSROOT_INTERNAL: &str = "__CARGO_FIX_RUST_SRC";
|
||||
|
||||
pub struct FixOptions {
|
||||
pub edition: bool,
|
||||
pub edition: Option<EditionFixMode>,
|
||||
pub idioms: bool,
|
||||
pub compile_opts: CompileOptions,
|
||||
pub allow_dirty: bool,
|
||||
@ -100,6 +100,46 @@ pub struct FixOptions {
|
||||
pub requested_lockfile_path: Option<PathBuf>,
|
||||
}
|
||||
|
||||
/// The behavior of `--edition` migration.
|
||||
#[derive(Clone, Copy)]
|
||||
pub enum EditionFixMode {
|
||||
/// Migrates the package from the current edition to the next.
|
||||
///
|
||||
/// This is the normal (stable) behavior of `--edition`.
|
||||
NextRelative,
|
||||
/// Migrates to a specific edition.
|
||||
///
|
||||
/// This is used by `-Zfix-edition` to force a specific edition like
|
||||
/// `future`, which does not have a relative value.
|
||||
OverrideSpecific(Edition),
|
||||
}
|
||||
|
||||
impl EditionFixMode {
|
||||
/// Returns the edition to use for the given current edition.
|
||||
pub fn next_edition(&self, current_edition: Edition) -> Edition {
|
||||
match self {
|
||||
EditionFixMode::NextRelative => current_edition.saturating_next(),
|
||||
EditionFixMode::OverrideSpecific(edition) => *edition,
|
||||
}
|
||||
}
|
||||
|
||||
/// Serializes to a string.
|
||||
fn to_string(&self) -> String {
|
||||
match self {
|
||||
EditionFixMode::NextRelative => "1".to_string(),
|
||||
EditionFixMode::OverrideSpecific(edition) => edition.to_string(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Deserializes from the given string.
|
||||
fn from_str(s: &str) -> EditionFixMode {
|
||||
match s {
|
||||
"1" => EditionFixMode::NextRelative,
|
||||
edition => EditionFixMode::OverrideSpecific(edition.parse().unwrap()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn fix(
|
||||
gctx: &GlobalContext,
|
||||
original_ws: &Workspace<'_>,
|
||||
@ -109,13 +149,13 @@ pub fn fix(
|
||||
|
||||
let mut target_data =
|
||||
RustcTargetData::new(original_ws, &opts.compile_opts.build_config.requested_kinds)?;
|
||||
if opts.edition {
|
||||
if let Some(edition_mode) = opts.edition {
|
||||
let specs = opts.compile_opts.spec.to_package_id_specs(&original_ws)?;
|
||||
let members: Vec<&Package> = original_ws
|
||||
.members()
|
||||
.filter(|m| specs.iter().any(|spec| spec.matches(m.package_id())))
|
||||
.collect();
|
||||
migrate_manifests(original_ws, &members)?;
|
||||
migrate_manifests(original_ws, &members, edition_mode)?;
|
||||
|
||||
check_resolver_change(&original_ws, &mut target_data, opts)?;
|
||||
}
|
||||
@ -133,8 +173,8 @@ pub fn fix(
|
||||
wrapper.env(BROKEN_CODE_ENV_INTERNAL, "1");
|
||||
}
|
||||
|
||||
if opts.edition {
|
||||
wrapper.env(EDITION_ENV_INTERNAL, "1");
|
||||
if let Some(mode) = &opts.edition {
|
||||
wrapper.env(EDITION_ENV_INTERNAL, mode.to_string());
|
||||
}
|
||||
if opts.idioms {
|
||||
wrapper.env(IDIOMS_ENV_INTERNAL, "1");
|
||||
@ -248,7 +288,11 @@ fn check_version_control(gctx: &GlobalContext, opts: &FixOptions) -> CargoResult
|
||||
);
|
||||
}
|
||||
|
||||
fn migrate_manifests(ws: &Workspace<'_>, pkgs: &[&Package]) -> CargoResult<()> {
|
||||
fn migrate_manifests(
|
||||
ws: &Workspace<'_>,
|
||||
pkgs: &[&Package],
|
||||
edition_mode: EditionFixMode,
|
||||
) -> CargoResult<()> {
|
||||
// HACK: Duplicate workspace migration logic between virtual manifests and real manifests to
|
||||
// reduce multiple Migrating messages being reported for the same file to the user
|
||||
if matches!(ws.root_maybe(), MaybePackage::Virtual(_)) {
|
||||
@ -259,7 +303,7 @@ fn migrate_manifests(ws: &Workspace<'_>, pkgs: &[&Package]) -> CargoResult<()> {
|
||||
.map(|p| p.manifest().edition())
|
||||
.max()
|
||||
.unwrap_or_default();
|
||||
let prepare_for_edition = highest_edition.saturating_next();
|
||||
let prepare_for_edition = edition_mode.next_edition(highest_edition);
|
||||
if highest_edition == prepare_for_edition
|
||||
|| (!prepare_for_edition.is_stable() && !ws.gctx().nightly_features_allowed)
|
||||
{
|
||||
@ -304,7 +348,7 @@ fn migrate_manifests(ws: &Workspace<'_>, pkgs: &[&Package]) -> CargoResult<()> {
|
||||
|
||||
for pkg in pkgs {
|
||||
let existing_edition = pkg.manifest().edition();
|
||||
let prepare_for_edition = existing_edition.saturating_next();
|
||||
let prepare_for_edition = edition_mode.next_edition(existing_edition);
|
||||
if existing_edition == prepare_for_edition
|
||||
|| (!prepare_for_edition.is_stable() && !ws.gctx().nightly_features_allowed)
|
||||
{
|
||||
@ -1191,10 +1235,10 @@ impl FixArgs {
|
||||
// ALLOWED: For the internal mechanism of `cargo fix` only.
|
||||
// Shouldn't be set directly by anyone.
|
||||
#[allow(clippy::disallowed_methods)]
|
||||
let prepare_for_edition = env::var(EDITION_ENV_INTERNAL).ok().map(|_| {
|
||||
enabled_edition
|
||||
.unwrap_or(Edition::Edition2015)
|
||||
.saturating_next()
|
||||
let prepare_for_edition = env::var(EDITION_ENV_INTERNAL).ok().map(|v| {
|
||||
let enabled_edition = enabled_edition.unwrap_or(Edition::Edition2015);
|
||||
let mode = EditionFixMode::from_str(&v);
|
||||
mode.next_edition(enabled_edition)
|
||||
});
|
||||
|
||||
// ALLOWED: For the internal mechanism of `cargo fix` only.
|
||||
|
@ -26,7 +26,7 @@ pub use self::cargo_update::upgrade_manifests;
|
||||
pub use self::cargo_update::write_manifest_upgrades;
|
||||
pub use self::cargo_update::UpdateOptions;
|
||||
pub use self::common_for_install_and_uninstall::{resolve_root, InstallTracker};
|
||||
pub use self::fix::{fix, fix_exec_rustc, fix_get_proxy_lock_addr, FixOptions};
|
||||
pub use self::fix::{fix, fix_exec_rustc, fix_get_proxy_lock_addr, EditionFixMode, FixOptions};
|
||||
pub use self::lockfile::{load_pkg_lockfile, resolve_to_string, write_pkg_lockfile};
|
||||
pub use self::registry::info;
|
||||
pub use self::registry::modify_owners;
|
||||
|
Loading…
x
Reference in New Issue
Block a user