@@ -519,41 +519,54 @@ fn run_vscode_compatible(variant: VSCodeVariant, ctx: &ExecutionContext) -> Resu
519519 let bin = require ( bin_name) ?;
520520
521521 // VSCode has update command only since 1.86 version ("january 2024" update), disable the update for prior versions
522- // Use command `code --version` which returns 3 lines: version, git commit, instruction set. We parse only the first one
523522 //
523+ // The output of `code --version` has two possible formats:
524+ // 1. 3 lines: version, git commit, instruction set. We parse only the first one
525+ // This is confirmed on an install from the apt repository
526+ // 2. 1 line: 'bin-name 1.2.3 (commit 123abc)', example: `code-insiders 1.106.0 (commit 48cdf17f0e856e1daca2ad2747814085a2453df0)`
527+ // See https://github.com/topgrade-rs/topgrade/issues/1605, confirmed from Microsoft website
524528 // This should apply to VSCodium as well.
525- let version: Result < Version > = match Command :: new ( & bin)
526- . arg ( "--version" )
527- . output_checked_utf8 ( ) ?
528- . stdout
529- . lines ( )
530- . next ( )
531- {
532- Some ( item) => {
533- // Insiders versions have "-insider" suffix which we can simply ignore.
534- let item = item. trim_end_matches ( "-insider" ) ;
535- // Strip leading zeroes because `semver` does not allow them, but VSCodium uses them sometimes.
536- // This is not the case for VSCode, but just in case, and it can't really cause any issues.
537- let item = item
538- . split ( '.' )
539- . map ( |s| if s == "0" { "0" } else { s. trim_start_matches ( '0' ) } )
540- . collect :: < Vec < _ > > ( )
541- . join ( "." ) ;
542- Version :: parse ( & item) . map_err ( std:: convert:: Into :: into)
543- }
544- None => {
545- return Err ( eyre ! ( output_changed_message!(
529+
530+ let version_output = Command :: new ( & bin) . arg ( "--version" ) . output_checked_utf8 ( ) ?;
531+
532+ debug ! ( version_output. stdout) ;
533+
534+ let line = version_output. stdout . lines ( ) . next ( ) . ok_or_else ( || {
535+ eyre ! ( output_changed_message!(
536+ & format!( "{bin_name} --version" ) ,
537+ "No first line"
538+ ) )
539+ } ) ?;
540+
541+ let version_string = if line. starts_with ( bin_name) {
542+ // Case 2
543+ line. split_whitespace ( ) . nth ( 1 ) . ok_or_else ( || {
544+ eyre ! ( output_changed_message!(
546545 & format!( "{bin_name} --version" ) ,
547- "No first line"
548- ) ) )
549- }
546+ format!( "No version after '{bin_name}'" )
547+ ) )
548+ } ) ?
549+ } else {
550+ // Case 1
551+ // The whole line should be the version
552+ // Insiders versions have "-insider" suffix which we can simply ignore.
553+ line. trim_end_matches ( "-insider" )
550554 } ;
551555
552- // Raise any errors in parsing the version
553- // The benefit of handling VSCodium versions so old that the version format is something
554- // unexpected is outweighed by the benefit of failing fast on new breaking versions
555- let version =
556- version. wrap_err_with ( || output_changed_message ! ( & format!( "{bin_name} --version" ) , "Invalid version" ) ) ?;
556+ // Strip leading zeroes because `semver` does not allow them, but VSCodium uses them sometimes.
557+ // This is not the case for VSCode, but just in case, and it can't really cause any issues.
558+ let version_string = version_string
559+ . split ( '.' )
560+ . map ( |s| if s == "0" { "0" } else { s. trim_start_matches ( '0' ) } )
561+ . collect :: < Vec < _ > > ( )
562+ . join ( "." ) ;
563+
564+ let version = Version :: parse ( & version_string)
565+ // Raise any errors in parsing the version
566+ // The benefit of handling VSCodium versions so old that the version format is something
567+ // unexpected is outweighed by the benefit of failing fast on new breaking versions
568+ . wrap_err_with ( || output_changed_message ! ( & format!( "{bin_name} --version" ) , "Invalid version" ) ) ?;
569+
557570 debug ! ( "Detected {name} version as: {version}" ) ;
558571
559572 if version < Version :: new ( 1 , 86 , 0 ) {
0 commit comments