Skip to content
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

improve defmt version mismatch diagnostics #242

Merged
merged 1 commit into from Nov 13, 2020
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
68 changes: 62 additions & 6 deletions decoder/src/lib.rs
Expand Up @@ -98,13 +98,69 @@ pub struct Table {
/// Checks if the version encoded in the symbol table is compatible with this version of the
/// `decoder` crate
pub fn check_version(version: &str) -> Result<(), String> {
enum Kind {
// "1" or "0.1"
Semver,
// commit hash "e739d0ac703dfa629a159be329e8c62a1c3ed206"
Git,
}

impl Kind {
Copy link
Contributor

Choose a reason for hiding this comment

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

question: why are these defined within the function instead of outside?

Copy link
Member Author

Choose a reason for hiding this comment

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

the enum is only used within the function body so putting it inside avoids adding yet another type to the outer (src/lib.rs) type namespace.

Another way to keep the namespace tidy is use modules so this could have been written as: mod version { enum Kind { .. } pub fn check(version: &str) -> Result<(), String> { .. } }. We have not used modules in this crate at all so the file is over 1.6K lines ... we should eventually come back and refactor this into modules.

Copy link
Contributor

Choose a reason for hiding this comment

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

alrighty, thank you for the clarification! +1 to the refactoring, but that's for another day ofc

fn of(version: &str) -> Kind {
if version.contains('.') {
// "0.1"
Kind::Semver
} else if version.parse::<u64>().is_ok() {
// "1"
Kind::Semver
} else {
// "e739d0ac703dfa629a159be329e8c62a1c3ed206" (should be)
Kind::Git
}
}
}

if version != DEFMT_VERSION {
return Err(format!(
"defmt version mismatch (firmware is using {}, host is using {}); \
are you using the same git version of defmt and related tools?
Try `cargo install`-ing the latest git version of `probe-run` AND updating your project's `Cargo.lock` with `cargo update`",
version, DEFMT_VERSION,
));
let mut msg = format!(
"defmt version mismatch: firmware is using {}, `probe-run` supports {}\nsuggestion: ",
version, DEFMT_VERSION
);

match (Kind::of(version), Kind::of(DEFMT_VERSION)) {
(Kind::Git, Kind::Git) => {
write!(
msg,
"pin _all_ `defmt` related dependencies to revision {0}; modify Cargo.toml files as shown below

[dependencies]
defmt = {{ git = \"https://github.com/knurling-rs/defmt\", rev = \"{0}\" }}
defmt-rtt = {{ git = \"https://github.com/knurling-rs/defmt\", rev = \"{0}\" }}
# ONLY pin this dependency if you are using the `print-defmt` feature
panic-probe = {{ git = \"https://github.com/knurling-rs/defmt\", features = [\"print-defmt\"], rev = \"{0}\" }}",
Copy link
Member Author

@japaric japaric Nov 12, 2020

Choose a reason for hiding this comment

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

panic-probe currently lives in the probe-run repo so it's not really possible to pin it to the correct defmt rev (panic-probe also already pins to a particular defmt and that cannot be changed from an application project). I think that to simplify the use of the git-version of defmt we'll have to move panic-probe (back) into the defmt repo. This PR is blocked on that migration.

Copy link
Member Author

Choose a reason for hiding this comment

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

migration PR: #244

DEFMT_VERSION
)
.ok();
}
(Kind::Git, Kind::Semver) => {
msg.push_str("migrate your firmware to a crates.io version of defmt (check https://https://defmt.ferrous-systems.com) OR
`cargo install` a _git_ version of `probe-run`: `cargo install --git https://github.com/knurling-rs/probe-run --branch main`");
}
(Kind::Semver, Kind::Git) => {
msg.push_str(
"`cargo install` a non-git version of `probe-run`: `cargo install probe-run`",
);
}
(Kind::Semver, Kind::Semver) => {
write!(
msg,
"`cargo install` a different non-git version of `probe-run` that supports defmt {}",
version,
)
.ok();
}
}

return Err(msg);
}

Ok(())
Expand Down