(self, paths: &SpacetimePaths)
| 11 | |
| 12 | impl List { |
| 13 | pub(super) fn exec(self, paths: &SpacetimePaths) -> anyhow::Result<()> { |
| 14 | // This `match` part is only here because at one point we had a bug where we were creating |
| 15 | // symlinks that contained the _entire_ path, rather than just the relative path to the |
| 16 | // version directory. It's not strictly necessary, it just fixes our determination of what |
| 17 | // the current version is, for the output of this command. |
| 18 | // |
| 19 | // That symlink bug was fixed in `crates/paths/src/cli.rs` in |
| 20 | // https://github.com/clockworklabs/SpacetimeDB/pull/2680, but this `match` means that this |
| 21 | // output will still be correct for any users that already have one of the bugged symlinks. |
| 22 | // |
| 23 | // Once users upgrade to a version containing #2680, they will have the code that creates |
| 24 | // the fixed symlinks. However, that code won't immediately run, since the upgrade will be |
| 25 | // running from the previous binary they had. So once they upgrade to a version containing |
| 26 | // #2680, _and then_ upgrade once more, their symlinks will be fixed. There's no real |
| 27 | // timeline on when everyone will have done that, but hopefully that helps give a sense of |
| 28 | // how long this code "should" exist for (but it doesn't do any harm afaik). |
| 29 | let current = match paths.cli_bin_dir.current_version()? { |
| 30 | None => None, |
| 31 | Some(path_str) => { |
| 32 | let file_name = Path::new(&path_str) |
| 33 | .file_name() |
| 34 | .and_then(|f| f.to_str()) |
| 35 | .ok_or(anyhow::anyhow!("Could not extract current version"))?; |
| 36 | Some(file_name.to_string()) |
| 37 | } |
| 38 | }; |
| 39 | |
| 40 | let versions = if self.all { |
| 41 | let client = super::reqwest_client()?; |
| 42 | super::tokio_block_on(super::install::available_releases(&client))?? |
| 43 | } else { |
| 44 | paths.cli_bin_dir.installed_versions()? |
| 45 | }; |
| 46 | |
| 47 | // Sort versions using semver ordering. Versions that fail to parse are |
| 48 | // placed at the end in their original listed order. |
| 49 | let mut parsed: Vec<(semver::Version, String)> = Vec::new(); |
| 50 | let mut unparsed: Vec<String> = Vec::new(); |
| 51 | for ver in versions { |
| 52 | match semver::Version::parse(&ver) { |
| 53 | Ok(sv) => parsed.push((sv, ver)), |
| 54 | Err(_) => unparsed.push(ver), |
| 55 | } |
| 56 | } |
| 57 | parsed.sort_by(|(a, _), (b, _)| b.cmp(a)); |
| 58 | |
| 59 | let sorted_versions: Vec<String> = parsed.into_iter().map(|(_, s)| s).chain(unparsed).collect(); |
| 60 | for ver in &sorted_versions { |
| 61 | let is_current = Some(ver) == current.as_ref(); |
| 62 | |
| 63 | if is_current { |
| 64 | println!("{} (current)", ver); |
| 65 | } else { |
| 66 | println!("{ver}"); |
| 67 | } |
| 68 | } |
| 69 | |
| 70 | Ok(()) |
nothing calls this directly
no test coverage detected