Skip to content

feat: add instructions for self-update#6433

Merged
jdx merged 10 commits intomainfrom
self-update-instructions
Sep 26, 2025
Merged

feat: add instructions for self-update#6433
jdx merged 10 commits intomainfrom
self-update-instructions

Conversation

@jdx
Copy link
Owner

@jdx jdx commented Sep 26, 2025

No description provided.

@jdx jdx marked this pull request as ready for review September 26, 2025 19:02
Copilot AI review requested due to automatic review settings September 26, 2025 19:02
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR adds support for self-update instructions by introducing mechanisms to detect and display upgrade instructions when mise self-update is not directly available through the built-in updater.

  • Introduces environment variables and file-based configuration for self-update instructions
  • Updates minimum version validation to support both hard and soft version requirements with custom upgrade messaging
  • Refactors self-update availability detection to use centralized configuration

Reviewed Changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
src/env.rs Adds environment variable definitions for self-update instruction paths and availability detection
src/config/mod.rs Updates version validation to handle hard/soft requirements and display upgrade instructions
src/config/config_file/mod.rs Changes min_version trait method signature to work with new MinVersionSpec type
src/config/config_file/mise_toml.rs Updates deserialization to support the new MinVersionSpec format with hard/soft versions
src/config/config_file/min_version.rs Introduces new MinVersionSpec struct to handle version requirement specifications
src/cli/version.rs Adds upgrade instruction display when self-update is unavailable
src/cli/self_update.rs Refactors self-update availability logic and adds instruction file reading functionality

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

#[derive(Debug, Clone, Default, PartialEq, Eq)]
pub struct MinVersionSpec {
hard: Option<Versioning>,
soft: Option<Versioning>,
Copy link

Copilot AI Sep 26, 2025

Choose a reason for hiding this comment

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

The struct is missing the upgrade_instructions field that is referenced in line 15 of the new method and other methods like to_owned and merge_with.

Suggested change
soft: Option<Versioning>,
soft: Option<Versioning>,
upgrade_instructions: Option<String>,

Copilot uses AI. Check for mistakes.
@@ -0,0 +1,64 @@
#[derive(Debug, Clone, Default, PartialEq, Eq)]
Copy link

Copilot AI Sep 26, 2025

Choose a reason for hiding this comment

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

Missing import statement for Versioning type. The struct uses Versioning but doesn't import it.

Copilot uses AI. Check for mistakes.
let version = Versioning::new(v)
.ok_or_else(|| versions::Error::IllegalVersioning(v.to_string()))
.map_err(E::custom)?;
Ok(MinVersionSpec::new(Some(version), None))
Copy link

Copilot AI Sep 26, 2025

Choose a reason for hiding this comment

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

The MinVersionSpec::new method returns Option<Self> but this code expects it to return Self. Either unwrap the Option or change the method signature.

Copilot uses AI. Check for mistakes.
}
}
}
Ok(MinVersionSpec::new(hard, soft))
Copy link

Copilot AI Sep 26, 2025

Choose a reason for hiding this comment

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

The MinVersionSpec::new method returns Option<Self> but this code expects it to return Self. Either unwrap the Option or change the method signature.

Suggested change
Ok(MinVersionSpec::new(hard, soft))
MinVersionSpec::new(hard, soft).ok_or_else(|| de::Error::custom("invalid min_version spec"))

Copilot uses AI. Check for mistakes.
@jdx jdx force-pushed the self-update-instructions branch from e238421 to a5a6711 Compare September 26, 2025 19:05
…aults for self-update; e2e coverage

- Support min_version {hard,soft} with legacy string
- Soft violations warn and show instructions
- Hard violations error and include instructions
- env.rs discovers instructions/disable defaults
- Show instructions in self-update unavailable and version::show_latest
- Add e2e for soft/hard min_version behavior
cursor[bot]

This comment was marked as outdated.

jdx and others added 2 commits September 26, 2025 14:13
@github-actions
Copy link

github-actions bot commented Sep 26, 2025

Hyperfine Performance

mise x -- echo

Command Mean [ms] Min [ms] Max [ms] Relative
mise-2025.9.19 x -- echo 20.7 ± 0.5 19.5 22.6 1.00
mise x -- echo 21.3 ± 0.6 19.5 24.6 1.03 ± 0.04

mise env

Command Mean [ms] Min [ms] Max [ms] Relative
mise-2025.9.19 env 19.9 ± 0.5 18.7 23.1 1.00
mise env 20.5 ± 0.8 18.7 24.6 1.03 ± 0.05

mise hook-env

Command Mean [ms] Min [ms] Max [ms] Relative
mise-2025.9.19 hook-env 19.8 ± 0.4 18.7 21.3 1.00
mise hook-env 20.2 ± 0.5 18.8 22.0 1.02 ± 0.03

mise ls

Command Mean [ms] Min [ms] Max [ms] Relative
mise-2025.9.19 ls 17.9 ± 0.6 16.4 21.6 1.00
mise ls 18.4 ± 0.5 17.2 20.0 1.03 ± 0.04

xtasks/test/perf

Command mise-2025.9.19 mise Variance
install (cached) 174ms ✅ 109ms +59%
ls (cached) 66ms 66ms +0%
bin-paths (cached) 73ms 74ms -1%
task-ls (cached) 536ms 512ms +4%

✅ Performance improvement: install cached is 59%

@jdx jdx requested a review from Copilot September 26, 2025 20:00
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

Copilot reviewed 9 out of 9 changed files in this pull request and generated 2 comments.


Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

Comment on lines +45 to +51
pub fn to_owned(&self) -> Self {
Self {
hard: self.hard.clone(),
soft: self.soft.clone(),
}
}

Copy link

Copilot AI Sep 26, 2025

Choose a reason for hiding this comment

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

The method to_owned is redundant since MinVersionSpec already implements Clone. Use the standard clone() method instead or remove this method entirely.

Suggested change
pub fn to_owned(&self) -> Self {
Self {
hard: self.hard.clone(),
soft: self.soft.clone(),
}
}

Copilot uses AI. Check for mistakes.
Comment on lines +842 to +843
Ok(MinVersionSpec::new(hard, soft))
}
Copy link

Copilot AI Sep 26, 2025

Choose a reason for hiding this comment

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

The MinVersionSpec::new() method returns Option<MinVersionSpec> but this code assumes it always returns Some. Consider handling the None case or change the method signature if this case is impossible.

Suggested change
Ok(MinVersionSpec::new(hard, soft))
}
match MinVersionSpec::new(hard, soft) {
Some(spec) => Ok(Some(spec)),
None => Err(de::Error::custom("invalid min_version map: must specify at least one of 'hard' or 'soft'")),
}

Copilot uses AI. Check for mistakes.
@jdx jdx force-pushed the self-update-instructions branch from 4a403ea to 864a001 Compare September 26, 2025 20:03
@jdx jdx force-pushed the self-update-instructions branch from 590ecb1 to 0826f5a Compare September 26, 2025 20:03
@jdx jdx requested a review from Copilot September 26, 2025 20:11
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

Copilot reviewed 14 out of 14 changed files in this pull request and generated 3 comments.


Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

Comment on lines +38 to +42
pub fn hard_violation<'a>(&'a self, current: &Versioning) -> Option<&'a Versioning> {
self.hard().filter(|required| current < *required)
}

pub fn soft_violation<'a>(&'a self, current: &Versioning) -> Option<&'a Versioning> {
Copy link

Copilot AI Sep 26, 2025

Choose a reason for hiding this comment

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

The explicit lifetime annotations 'a are unnecessary here as they can be elided. The compiler can infer these lifetimes automatically.

Suggested change
pub fn hard_violation<'a>(&'a self, current: &Versioning) -> Option<&'a Versioning> {
self.hard().filter(|required| current < *required)
}
pub fn soft_violation<'a>(&'a self, current: &Versioning) -> Option<&'a Versioning> {
pub fn hard_violation(&self, current: &Versioning) -> Option<&Versioning> {
self.hard().filter(|required| current < *required)
}
pub fn soft_violation(&self, current: &Versioning) -> Option<&Versioning> {

Copilot uses AI. Check for mistakes.
Comment on lines +38 to +42
pub fn hard_violation<'a>(&'a self, current: &Versioning) -> Option<&'a Versioning> {
self.hard().filter(|required| current < *required)
}

pub fn soft_violation<'a>(&'a self, current: &Versioning) -> Option<&'a Versioning> {
Copy link

Copilot AI Sep 26, 2025

Choose a reason for hiding this comment

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

The explicit lifetime annotations 'a are unnecessary here as they can be elided. The compiler can infer these lifetimes automatically.

Suggested change
pub fn hard_violation<'a>(&'a self, current: &Versioning) -> Option<&'a Versioning> {
self.hard().filter(|required| current < *required)
}
pub fn soft_violation<'a>(&'a self, current: &Versioning) -> Option<&'a Versioning> {
pub fn hard_violation(&self, current: &Versioning) -> Option<&Versioning> {
self.hard().filter(|required| current < *required)
}
pub fn soft_violation(&self, current: &Versioning) -> Option<&Versioning> {

Copilot uses AI. Check for mistakes.
Comment on lines +8 to +21
cat >mise.toml <<'TOML'
min_version = { soft = "9999.0.0" }
TOML

assert_contains 'MISE_SELF_UPDATE_AVAILABLE=false MISE_SELF_UPDATE_INSTRUCTIONS=./instructions.toml MISE_LOG_LEVEL=warn mise ls 2>&1' 'recommended'
assert_contains 'MISE_SELF_UPDATE_AVAILABLE=false MISE_SELF_UPDATE_INSTRUCTIONS=./instructions.toml MISE_LOG_LEVEL=warn mise ls 2>&1' 'brew upgrade mise'

# hard min_version: should fail and include instructions
cat >mise.toml <<'TOML'
min_version = { hard = "9999.0.0" }
TOML

assert_fail 'MISE_SELF_UPDATE_AVAILABLE=false MISE_SELF_UPDATE_INSTRUCTIONS=./instructions.toml mise ls 2>&1' 'is required'
assert_fail 'MISE_SELF_UPDATE_AVAILABLE=false MISE_SELF_UPDATE_INSTRUCTIONS=./instructions.toml mise ls 2>&1' 'brew upgrade mise'
Copy link

Copilot AI Sep 26, 2025

Choose a reason for hiding this comment

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

[nitpick] The long command line with multiple environment variables is repeated and hard to read. Consider extracting the common environment setup into a variable for better maintainability.

Suggested change
cat >mise.toml <<'TOML'
min_version = { soft = "9999.0.0" }
TOML
assert_contains 'MISE_SELF_UPDATE_AVAILABLE=false MISE_SELF_UPDATE_INSTRUCTIONS=./instructions.toml MISE_LOG_LEVEL=warn mise ls 2>&1' 'recommended'
assert_contains 'MISE_SELF_UPDATE_AVAILABLE=false MISE_SELF_UPDATE_INSTRUCTIONS=./instructions.toml MISE_LOG_LEVEL=warn mise ls 2>&1' 'brew upgrade mise'
# hard min_version: should fail and include instructions
cat >mise.toml <<'TOML'
min_version = { hard = "9999.0.0" }
TOML
assert_fail 'MISE_SELF_UPDATE_AVAILABLE=false MISE_SELF_UPDATE_INSTRUCTIONS=./instructions.toml mise ls 2>&1' 'is required'
assert_fail 'MISE_SELF_UPDATE_AVAILABLE=false MISE_SELF_UPDATE_INSTRUCTIONS=./instructions.toml mise ls 2>&1' 'brew upgrade mise'
# Common environment variables for assertions
COMMON_ENV="MISE_SELF_UPDATE_AVAILABLE=false MISE_SELF_UPDATE_INSTRUCTIONS=./instructions.toml MISE_LOG_LEVEL=warn"
COMMON_ENV_NO_LOG="MISE_SELF_UPDATE_AVAILABLE=false MISE_SELF_UPDATE_INSTRUCTIONS=./instructions.toml"
cat >mise.toml <<'TOML'
min_version = { soft = "9999.0.0" }
TOML
assert_contains "$COMMON_ENV mise ls 2>&1" 'recommended'
assert_contains "$COMMON_ENV mise ls 2>&1" 'brew upgrade mise'
# hard min_version: should fail and include instructions
cat >mise.toml <<'TOML'
min_version = { hard = "9999.0.0" }
TOML
assert_fail "$COMMON_ENV_NO_LOG mise ls 2>&1" 'is required'
assert_fail "$COMMON_ENV_NO_LOG mise ls 2>&1" 'brew upgrade mise'

Copilot uses AI. Check for mistakes.
@jdx jdx force-pushed the self-update-instructions branch 2 times, most recently from 06c9750 to 73a644a Compare September 26, 2025 20:13
@jdx jdx requested a review from Copilot September 26, 2025 20:13
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

Copilot reviewed 14 out of 14 changed files in this pull request and generated 1 comment.


Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

let version = Versioning::new(v)
.ok_or_else(|| versions::Error::IllegalVersioning(v.to_string()))
.map_err(E::custom)?;
Ok(MinVersionSpec::new(Some(version), None))
Copy link

Copilot AI Sep 26, 2025

Choose a reason for hiding this comment

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

The MinVersionSpec::new method returns Option<MinVersionSpec> but this code assumes it always returns Some. If both parameters are None, it returns None, but here the first parameter is Some(version), so it should be safe. However, the return type mismatch needs to be handled - this should be Ok(Some(MinVersionSpec::new(Some(version), None).unwrap())) or the function should be updated to handle the None case.

Suggested change
Ok(MinVersionSpec::new(Some(version), None))
Ok(Some(MinVersionSpec::new(Some(version), None).unwrap()))

Copilot uses AI. Check for mistakes.
@jdx jdx force-pushed the self-update-instructions branch from 73a644a to 5f4cee0 Compare September 26, 2025 20:17
@jdx jdx enabled auto-merge (squash) September 26, 2025 20:17
cursor[bot]

This comment was marked as outdated.

@jdx jdx disabled auto-merge September 26, 2025 20:23
@jdx jdx force-pushed the self-update-instructions branch 2 times, most recently from bd24b51 to 1c03167 Compare September 26, 2025 20:28
@jdx jdx enabled auto-merge (squash) September 26, 2025 20:28
@jdx jdx force-pushed the self-update-instructions branch from 1c03167 to f3a8d11 Compare September 26, 2025 20:30
@jdx jdx disabled auto-merge September 26, 2025 20:34
@jdx jdx force-pushed the self-update-instructions branch from f3a8d11 to 36e4c9e Compare September 26, 2025 20:57
@jdx
Copy link
Owner Author

jdx commented Sep 26, 2025

bugbot run

Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

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

✅ Bugbot reviewed your changes and found no bugs!


@jdx jdx enabled auto-merge (squash) September 26, 2025 21:09
@jdx jdx merged commit 0380465 into main Sep 26, 2025
19 checks passed
@jdx jdx deleted the self-update-instructions branch September 26, 2025 21:11
@jdx jdx mentioned this pull request Sep 26, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants