Skip to content

Commit c14c1c0

Browse files
authored
fix: Respect --frozen everywhere --offline or --locked is accepted (#15263)
### What does this PR try to resolve? Fixes #15239 This also makes `--frozen` be respected in more situations, including * `cargo add` * `cargo install` * Git fetches * HTTP registry access ### How should we test and review this PR? To prevent this from happening again, I removed `offline()` and `locked()` accessors. To maintain the quality of error messages, I added `offline_flag()` and `locked_flag()` that will pick up `--frozen`, if present. ### Additional information
2 parents 615a6f8 + 5a1a223 commit c14c1c0

File tree

14 files changed

+65
-82
lines changed

14 files changed

+65
-82
lines changed

src/cargo/core/resolver/errors.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -393,13 +393,13 @@ pub(super) fn activation_error(
393393
);
394394

395395
if let Some(gctx) = gctx {
396-
if gctx.offline() {
396+
if let Some(offline_flag) = gctx.offline_flag() {
397397
let _ = write!(
398398
&mut hints,
399-
"\nAs a reminder, you're using offline mode (--offline) \
399+
"\nAs a reminder, you're using offline mode ({offline_flag}) \
400400
which can sometimes cause surprising resolution failures, \
401401
if this error is too confusing you may wish to retry \
402-
without the offline flag.",
402+
without `{offline_flag}`.",
403403
);
404404
}
405405
}

src/cargo/ops/cargo_add/mod.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -251,11 +251,11 @@ pub fn add(workspace: &Workspace<'_>, options: &AddOptions<'_>) -> CargoResult<(
251251
}
252252
}
253253

254-
if options.gctx.locked() {
254+
if let Some(locked_flag) = options.gctx.locked_flag() {
255255
let new_raw_manifest = manifest.to_string();
256256
if original_raw_manifest != new_raw_manifest {
257257
anyhow::bail!(
258-
"the manifest file {} needs to be updated but --locked was passed to prevent this",
258+
"the manifest file {} needs to be updated but {locked_flag} was passed to prevent this",
259259
manifest.path.display()
260260
);
261261
}

src/cargo/ops/cargo_install.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,7 @@ impl<'gctx> InstallablePackage<'gctx> {
189189
lockfile_path.clone(),
190190
)?;
191191

192-
if gctx.locked() {
192+
if !gctx.lock_update_allowed() {
193193
// When --lockfile-path is set, check that passed lock file exists
194194
// (unlike the usual flag behavior, lockfile won't be created as we imply --locked)
195195
if let Some(requested_lockfile_path) = ws.requested_lockfile_path() {

src/cargo/ops/lockfile.rs

+3-8
Original file line numberDiff line numberDiff line change
@@ -50,19 +50,14 @@ pub fn write_pkg_lockfile(ws: &Workspace<'_>, resolve: &mut Resolve) -> CargoRes
5050
}
5151
}
5252

53-
if !ws.gctx().lock_update_allowed() {
54-
let flag = if ws.gctx().locked() {
55-
"--locked"
56-
} else {
57-
"--frozen"
58-
};
53+
if let Some(locked_flag) = ws.gctx().locked_flag() {
5954
anyhow::bail!(
6055
"the lock file {} needs to be updated but {} was passed to prevent this\n\
6156
If you want to try to generate the lock file without accessing the network, \
6257
remove the {} flag and use --offline instead.",
6358
lock_root.as_path_unlocked().join(LOCKFILE_NAME).display(),
64-
flag,
65-
flag
59+
locked_flag,
60+
locked_flag
6661
);
6762
}
6863

src/cargo/ops/registry/info/mod.rs

+2-6
Original file line numberDiff line numberDiff line change
@@ -198,12 +198,8 @@ fn validate_locked_and_frozen_options(
198198
) -> Result<(), anyhow::Error> {
199199
// Only in workspace, we can use --frozen or --locked.
200200
if !in_workspace {
201-
if gctx.locked() {
202-
bail!("the option `--locked` can only be used within a workspace");
203-
}
204-
205-
if gctx.frozen() {
206-
bail!("the option `--frozen` can only be used within a workspace");
201+
if let Some(locked_flag) = gctx.locked_flag() {
202+
bail!("the option `{locked_flag}` can only be used within a workspace");
207203
}
208204
}
209205
Ok(())

src/cargo/sources/git/source.rs

+11-5
Original file line numberDiff line numberDiff line change
@@ -299,10 +299,16 @@ impl<'gctx> Source for GitSource<'gctx> {
299299
// If we're in offline mode, we're not locked, and we have a
300300
// database, then try to resolve our reference with the preexisting
301301
// repository.
302-
(Revision::Deferred(git_ref), Some(db)) if self.gctx.offline() => {
302+
(Revision::Deferred(git_ref), Some(db)) if !self.gctx.network_allowed() => {
303+
let offline_flag = self
304+
.gctx
305+
.offline_flag()
306+
.expect("always present when `!network_allowed`");
303307
let rev = db.resolve(&git_ref).with_context(|| {
304-
"failed to lookup reference in preexisting repository, and \
305-
can't check for updates in offline mode (--offline)"
308+
format!(
309+
"failed to lookup reference in preexisting repository, and \
310+
can't check for updates in offline mode ({offline_flag})"
311+
)
306312
})?;
307313
(db, rev)
308314
}
@@ -312,9 +318,9 @@ impl<'gctx> Source for GitSource<'gctx> {
312318
// situation that we have a locked revision but the database
313319
// doesn't have it.
314320
(locked_rev, db) => {
315-
if self.gctx.offline() {
321+
if let Some(offline_flag) = self.gctx.offline_flag() {
316322
anyhow::bail!(
317-
"can't checkout from '{}': you are in the offline mode (--offline)",
323+
"can't checkout from '{}': you are in the offline mode ({offline_flag})",
318324
self.remote.url()
319325
);
320326
}

src/cargo/sources/git/utils.rs

+2-5
Original file line numberDiff line numberDiff line change
@@ -955,15 +955,12 @@ pub fn fetch(
955955
gctx: &GlobalContext,
956956
remote_kind: RemoteKind,
957957
) -> CargoResult<()> {
958-
if gctx.frozen() {
958+
if let Some(offline_flag) = gctx.offline_flag() {
959959
anyhow::bail!(
960-
"attempting to update a git repository, but --frozen \
960+
"attempting to update a git repository, but {offline_flag} \
961961
was specified"
962962
)
963963
}
964-
if !gctx.network_allowed() {
965-
anyhow::bail!("can't update a git repository in the offline mode")
966-
}
967964

968965
let shallow = remote_kind.to_shallow_setting(repo.is_shallow(), gctx);
969966

src/cargo/sources/registry/http_remote.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -376,7 +376,7 @@ impl<'gctx> HttpRegistry<'gctx> {
376376
} else if self.gctx.cli_unstable().no_index_update {
377377
trace!("using local {} in no_index_update mode", path.display());
378378
true
379-
} else if self.gctx.offline() {
379+
} else if !self.gctx.network_allowed() {
380380
trace!("using local {} in offline mode", path.display());
381381
true
382382
} else if self.fresh.contains(path) {
@@ -511,7 +511,7 @@ impl<'gctx> RegistryData for HttpRegistry<'gctx> {
511511
return Poll::Ready(Ok(LoadResponse::NotFound));
512512
}
513513

514-
if self.gctx.offline() || self.gctx.cli_unstable().no_index_update {
514+
if !self.gctx.network_allowed() || self.gctx.cli_unstable().no_index_update {
515515
// Return NotFound in offline mode when the file doesn't exist in the cache.
516516
// If this results in resolution failure, the resolver will suggest
517517
// removing the --offline flag.

src/cargo/sources/registry/index/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -482,7 +482,7 @@ impl<'gctx> RegistryIndex<'gctx> {
482482
load: &mut dyn RegistryData,
483483
f: &mut dyn FnMut(IndexSummary),
484484
) -> Poll<CargoResult<()>> {
485-
if self.gctx.offline() {
485+
if !self.gctx.network_allowed() {
486486
// This should only return `Poll::Ready(Ok(()))` if there is at least 1 match.
487487
//
488488
// If there are 0 matches it should fall through and try again with online.

src/cargo/sources/registry/remote.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -345,7 +345,7 @@ impl<'gctx> RegistryData for RemoteRegistry<'gctx> {
345345
}
346346
self.mark_updated();
347347

348-
if self.gctx.offline() {
348+
if !self.gctx.network_allowed() {
349349
return Ok(());
350350
}
351351
if self.gctx.cli_unstable().no_index_update {

src/cargo/util/context/mod.rs

+20-12
Original file line numberDiff line numberDiff line change
@@ -1161,27 +1161,35 @@ impl GlobalContext {
11611161
}
11621162

11631163
pub fn network_allowed(&self) -> bool {
1164-
!self.frozen() && !self.offline()
1164+
!self.offline_flag().is_some()
11651165
}
11661166

1167-
pub fn offline(&self) -> bool {
1168-
self.offline
1169-
}
1170-
1171-
pub fn frozen(&self) -> bool {
1172-
self.frozen
1173-
}
1174-
1175-
pub fn locked(&self) -> bool {
1176-
self.locked
1167+
pub fn offline_flag(&self) -> Option<&'static str> {
1168+
if self.frozen {
1169+
Some("--frozen")
1170+
} else if self.offline {
1171+
Some("--offline")
1172+
} else {
1173+
None
1174+
}
11771175
}
11781176

11791177
pub fn set_locked(&mut self, locked: bool) {
11801178
self.locked = locked;
11811179
}
11821180

11831181
pub fn lock_update_allowed(&self) -> bool {
1184-
!self.frozen && !self.locked
1182+
!self.locked_flag().is_some()
1183+
}
1184+
1185+
pub fn locked_flag(&self) -> Option<&'static str> {
1186+
if self.frozen {
1187+
Some("--frozen")
1188+
} else if self.locked {
1189+
Some("--locked")
1190+
} else {
1191+
None
1192+
}
11851193
}
11861194

11871195
/// Loads configuration from the filesystem.

src/cargo/util/network/http.rs

+2-8
Original file line numberDiff line numberDiff line change
@@ -25,15 +25,9 @@ pub fn http_handle(gctx: &GlobalContext) -> CargoResult<Easy> {
2525
}
2626

2727
pub fn http_handle_and_timeout(gctx: &GlobalContext) -> CargoResult<(Easy, HttpTimeout)> {
28-
if gctx.frozen() {
28+
if let Some(offline_flag) = gctx.offline_flag() {
2929
bail!(
30-
"attempting to make an HTTP request, but --frozen was \
31-
specified"
32-
)
33-
}
34-
if gctx.offline() {
35-
bail!(
36-
"attempting to make an HTTP request, but --offline was \
30+
"attempting to make an HTTP request, but {offline_flag} was \
3731
specified"
3832
)
3933
}

tests/testsuite/offline.rs

+7-7
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,7 @@ fn cargo_compile_offline_not_try_update() {
184184
[ERROR] no matching package named `not_cached_dep` found
185185
location searched: crates.io index
186186
required by package `bar v0.1.0 ([ROOT]/bar)`
187-
As a reminder, you're using offline mode (--offline) which can sometimes cause surprising resolution failures, if this error is too confusing you may wish to retry without the offline flag.
187+
As a reminder, you're using offline mode (--offline) which can sometimes cause surprising resolution failures, if this error is too confusing you may wish to retry without `--offline`.
188188
189189
"#]])
190190
.run();
@@ -195,7 +195,7 @@ As a reminder, you're using offline mode (--offline) which can sometimes cause s
195195
[ERROR] no matching package named `not_cached_dep` found
196196
location searched: crates.io index
197197
required by package `bar v0.1.0 ([ROOT]/bar)`
198-
As a reminder, you're using offline mode (--offline) which can sometimes cause surprising resolution failures, if this error is too confusing you may wish to retry without the offline flag.
198+
As a reminder, you're using offline mode (--offline) which can sometimes cause surprising resolution failures, if this error is too confusing you may wish to retry without `--offline`.
199199
200200
"#]]).run();
201201
}
@@ -384,13 +384,13 @@ fn update_offline_not_cached() {
384384

385385
p.cargo("update --offline")
386386
.with_status(101)
387-
.with_stderr_data(str![["
387+
.with_stderr_data(str![[r#"
388388
[ERROR] no matching package named `bar` found
389389
location searched: [..]
390390
required by package `foo v0.0.1 ([ROOT]/foo)`
391-
As a reminder, you're using offline mode (--offline) which can sometimes cause surprising resolution failures, if this error is too confusing you may wish to retry without the offline flag.
391+
As a reminder, you're using offline mode (--offline) which can sometimes cause surprising resolution failures, if this error is too confusing you may wish to retry without `--offline`.
392392
393-
"]])
393+
"#]])
394394
.run();
395395
}
396396

@@ -607,7 +607,7 @@ candidate versions found which didn't match: 1.0.0
607607
location searched: `dummy-registry` index (which is replacing registry `crates-io`)
608608
required by package `foo v0.1.0 ([ROOT]/foo)`
609609
perhaps a crate was updated and forgotten to be re-vendored?
610-
As a reminder, you're using offline mode (--offline) which can sometimes cause surprising resolution failures, if this error is too confusing you may wish to retry without the offline flag.
610+
As a reminder, you're using offline mode (--offline) which can sometimes cause surprising resolution failures, if this error is too confusing you may wish to retry without `--offline`.
611611
612612
"#]]
613613
)
@@ -754,7 +754,7 @@ fn main(){
754754
[ERROR] no matching package named `present_dep` found
755755
location searched: `dummy-registry` index (which is replacing registry `crates-io`)
756756
required by package `foo v0.1.0 ([ROOT]/foo)`
757-
As a reminder, you're using offline mode (--offline) which can sometimes cause surprising resolution failures, if this error is too confusing you may wish to retry without the offline flag.
757+
As a reminder, you're using offline mode (--offline) which can sometimes cause surprising resolution failures, if this error is too confusing you may wish to retry without `--offline`.
758758
759759
"#]]
760760
)

tests/testsuite/registry.rs

+8-21
Original file line numberDiff line numberDiff line change
@@ -2431,14 +2431,10 @@ fn disallow_network_http() {
24312431
p.cargo("check --frozen")
24322432
.with_status(101)
24332433
.with_stderr_data(str![[r#"
2434-
[UPDATING] `dummy-registry` index
2435-
[ERROR] failed to get `foo` as a dependency of package `bar v0.5.0 ([ROOT]/foo)`
2436-
2437-
Caused by:
2438-
failed to query replaced source registry `crates-io`
2439-
2440-
Caused by:
2441-
attempting to make an HTTP request, but --frozen was specified
2434+
[ERROR] no matching package named `foo` found
2435+
location searched: `dummy-registry` index (which is replacing registry `crates-io`)
2436+
required by package `bar v0.5.0 ([ROOT]/foo)`
2437+
As a reminder, you're using offline mode (--frozen) which can sometimes cause surprising resolution failures, if this error is too confusing you may wish to retry without `--frozen`.
24422438
24432439
"#]])
24442440
.run();
@@ -2467,19 +2463,10 @@ fn disallow_network_git() {
24672463
p.cargo("check --frozen")
24682464
.with_status(101)
24692465
.with_stderr_data(str![[r#"
2470-
[ERROR] failed to get `foo` as a dependency of package `bar v0.5.0 ([ROOT]/foo)`
2471-
2472-
Caused by:
2473-
failed to load source for dependency `foo`
2474-
2475-
Caused by:
2476-
Unable to update registry `crates-io`
2477-
2478-
Caused by:
2479-
failed to update replaced source registry `crates-io`
2480-
2481-
Caused by:
2482-
attempting to make an HTTP request, but --frozen was specified
2466+
[ERROR] no matching package named `foo` found
2467+
location searched: `dummy-registry` index (which is replacing registry `crates-io`)
2468+
required by package `bar v0.5.0 ([ROOT]/foo)`
2469+
As a reminder, you're using offline mode (--frozen) which can sometimes cause surprising resolution failures, if this error is too confusing you may wish to retry without `--frozen`.
24832470
24842471
"#]])
24852472
.run();

0 commit comments

Comments
 (0)