Migration Guide: v0.15 to v0.16 with the JSON output format

Enabling json output

In v0.15, json lines output could be enabled by providing the --output-format json option as part of the top level cargo msrv (find) command. cargo msrv find --output-format json verify was a valid way to specify the output-format option, while cargo msrv verify --output-format json would not work (because --output-format was not defined for the subcommand, verify in this example).

This is no longer required; --output-format is now a global option, so in the above examples, both cases will now work.

NB: To determine the MSRV for a project, you should now run cargo msrv find instead of just cargo msrv. The top level command was moved to its own subcommand for consistency and more correct CLI argument parsing.

Message type tag

In v0.15, json messages were tagged using a field named reason. From v0.16 onwards, this field has been renamed to type instead. Please refer to the JSON output format page for a list of supported messages.

Message replacements

In this section, we will discuss the previously supported json messages, and provide suggestions of their replacements.

Mode

A json message with reason mode reported what command was running. Its direct replacement is the subcommand_init message. The v0.15 mode message also reported about the toolchain used, and which rustup run command was used to check for compatibility. These however are only relevant when running a command which checks for compatibility. Since we now also have command which do not check for compatibility, such as cargo msrv show and cargo msrv set, this was a good moment to move these fields out of this type of message. The new check_method message can tell you both about the toolchain used for compatibility checks, and about the compatibility check method via its method field. If this method has type rustup_run, then the args will contain the compatibility check arguments, previously known as the check_cmd.

The v0.15 mode message consisted of:

{
  "reason": "mode",
  // The mode in which cargo-msrv will operate
  "mode": "determine-msrv" /* OR */ "mode": "verify-msrv" /* OR */ "list-msrv" ,
   // The toolchain that will be used
  "toolchain":"x86_64-unknown-linux-gnu",
  // Command used to check a version. The key will be absent for mode 'list'
  "check_cmd":"cargo check"
}

Examples of messages which replace the information reported by the v0.15 mode message:

...
{
  "type": "subcommand_init",
  "subcommand_id": "find"
}
...
{
  "type": "check_method",
  "toolchain": {
    "version": "1.38.0",
    "target": "x86_64-pc-windows-msvc"
  },
  "method": {
    "type": "rustup_run",
    "args": [
      "1.38.0-x86_64-pc-windows-msvc",
      "cargo",
      "check"
    ],
    "path": "..\\air3"
  }
}
...

Installing and Checking

The installing and checking messages reported respectively about locating or installing a specific Rust toolchain and checking that toolchain for compatibility. The former has been replaced by the setup_toolchain event, while the latter has been replaced by the check_toolchain event. Reporting about the progress has been replaced by the progress event.

Previously, you would receive the following event:

{
  "reason": "installing", /* OR */ "reason": "checking",
  // The current version being installed or checked
  "version": "1.25.0",
  // The number of versions checked before this
  "step": 0,
  // The total number of versions to be checked
  "total": 55,
  // The toolchain that is being used
  "toolchain": "x86_64-unknown-linux-gnu",
  // The command used to check each version. The key will be absent for mode 'list'
  "check_cmd": "cargo check"
}

And now, you instead receive these events:

...
{
  "type": "progress",
  "current": 25,
  "search_space_size": 34,
  "iteration": 2
}
...
{
  "type": "setup_toolchain",
  "toolchain": {
    "version": "1.38.0",
    "target": "x86_64-pc-windows-msvc"
  },
  "scope": {
    "id": 2,
    "marker": "start"
  }
}
{
  "type": "setup_toolchain",
  "toolchain": {
    "version": "1.38.0",
    "target": "x86_64-pc-windows-msvc"
  },
  "scope": {
    "id": 2,
    "marker": "end"
  }
}
...
{
  "type": "check_toolchain",
  "toolchain": {
    "version": "1.39.0",
    "target": "x86_64-pc-windows-msvc"
  },
  "scope": {
    "id": 4,
    "marker": "start"
  }
}
{
  "type": "check_toolchain",
  "toolchain": {
    "version": "1.39.0",
    "target": "x86_64-pc-windows-msvc"
  },
  "scope": {
    "id": 4,
    "marker": "end"
  }
}

Check complete

The check-complete message would be reported when a check, which determined whether the toolchain version under test is compatible, completed. It has been replaced by the check_result event. The result of the compatibility check is now reported via the is_compatible field, instead of the success field. The progress report can be followed via the progress event, and the check_cmd may be found by inspecting the check_method event, via the method.args field, assuming that the rustup_run method (method.type) is used.

Previously, you would receive the following event:

{
  "reason": "check-complete",
  // The version that was just checked
  "version": "1.25.0",
  // The number of versions checked before this
  "step": 0,
  // The total number of versions to be checked
  "total": 55,
  // true if this version is supported
  "success": false,
  // The toolchain that is being used
  "toolchain": "x86_64-unknown-linux-gnu",
  // The command used to check each version
  "check_cmd": "cargo check"
}

And now, you instead receive these events, if the toolchain is compatible:

...
{
  "type": "progress",
  "current": 26,
  "search_space_size": 34,
  "iteration": 27
}
...
{
  "type": "check_method",
  "toolchain": {
    "version": "1.38.0",
    "target": "x86_64-pc-windows-msvc"
  },
  "method": {
    "type": "rustup_run",
    "args": [
      "1.38.0-x86_64-pc-windows-msvc",
      "cargo",
      "check"
    ],
    "path": "..\\air3"
  }
}
...
{
  "type": "check_result",
  "toolchain": {
    "version": "1.38.0",
    "target": "x86_64-pc-windows-msvc"
  },
  "is_compatible": true
}

Or, if the toolchain is deemed incompatible:

{
  "type": "progress",
  "current": 27,
  "search_space_size": 34,
  "iteration": 28
}
...
{
  "type": "check_method",
  "toolchain": {
    "version": "1.37.0",
    "target": "x86_64-pc-windows-msvc"
  },
  "method": {
    "type": "rustup_run",
    "args": [
      "1.37.0-x86_64-pc-windows-msvc",
      "cargo",
      "check"
    ],
    "path": "..\\air3"
  }
}
...
{
  "type": "check_result",
  "toolchain": {
    "version": "1.37.0",
    "target": "x86_64-pc-windows-msvc"
  },
  "is_compatible": false,
  "error": "error: failed to parse lock file at: ..\\air3\\Cargo.lock\n\nCaused by:\n  invalid serialized PackageId for key `package.dependencies`\n"
}

MSRV completed

When the find msrv command or the verify command would be completed, they would report about their result. The success field would respectively be used to report whether an MSRV had been found, or whether the MSRV being verified was compatible or not. These messages, msrv-complete and verify-complete have been replaced by the subcommand_result event. Please refer to the subcommand_result event for the complete description of output per command.

The v0.15 output had the following format:

{
  "reason": "msrv-complete" /* OR */ "reason": "verify-complete",
  // true if a msrv was found
  "success": true,
  // the msrv if found. The key will be absent if msrv wasn't found
  "msrv": "1.42.0",
  // The toolchain that is being used
  "toolchain": "x86_64-unknown-linux-gnu",
  // The command used to check each version. The key will be absent for mode 'list'
  "check_cmd": "cargo check"
}

Below, you can find an example of the new output when finding the MSRV, where one is found:

{
  "type": "subcommand_result",
  "subcommand_id": "find",
  "result": {
    "version": "1.38.0",
    "success": true
  }
}

And another example for the output of the verify command, where the verification failed:

{
  "type": "subcommand_result",
  "subcommand_id": "verify",
  "result": {
    "toolchain": {
      "version": "1.60.0",
      "target": "x86_64-pc-windows-msvc"
    },
    "is_compatible": false,
    "error": "    Checking air v0.0.0 (..\\air)\nerror: expected one of `:`, `<`, `=`, `where`, or `{`, found `<eof>`\n  --> src\\lib.rs:24:11\n   |\n24 | pub trait DisplayEvent\n   |           ^^^^^^^^^^^^ expected one of `:`, `<`, `=`, `where`, or `{`\n\nerror: could not compile `air` due to previous error\n"
  }
}

List MSRV's specified by crate authors

This event contains the output of the list command, which reports the MSRV of dependencies of a crate. The exact output depends on which variant is used, either ordered-by-msrv (default) or direct-deps.

The output of the list command is almost the same as it was before. The event is no longer called list; instead the output is given via the subcommand_result event, where the value of subcommand_id is list. The output of the command (variant and list fields) can now be found as part of the result field. The success field has been removed.

{
  "reason": "list",
  // output variant
  "variant": "ordered-by-msrv" /* OR */ "direct-deps",
  // always success when returning a result
  "success": true,
  // The output of the list subcommand
  "list": [
    /* when variant = 'ordered-by-msrv */
    {
        "msrv": "<msrv>",
        "dependencies": ["<dependencies which have this msrv>", ...]
    }
    /* OR, when variant = direct-deps */
    {
        "dependency": "<dependency crate name>",
        "version": "<dependency crate version>",
        "msrv": "<dependency crate msrv>",
        "depends_on": ["<dependencies of direct dependency crate>", ...]
    }
  ],
}

An example of the ordered-by-msrv variant:

{
  "type": "subcommand_result",
  "subcommand_id": "list",
  "result": {
    "variant": "ordered-by-msrv",
    "list": [
      {
        "msrv": "1.38.0",
        "dependencies": [
          "storyteller"
        ]
      },
      {
        "msrv": "1.36.0",
        "dependencies": [
          "crossbeam-channel",
          "crossbeam-utils"
        ]
      },
      {
        "msrv": null,
        "dependencies": [
          "cfg-if",
          "lazy_static"
        ]
      }
    ]
  }
}

An example of the direct-deps variant:

{
  "type": "subcommand_result",
  "subcommand_id": "list",
  "result": {
    "variant": "direct-deps",
    "list": [
      {
        "name": "crossbeam-channel",
        "version": "0.5.4",
        "msrv": "1.36.0",
        "dependencies": [
          "cfg-if",
          "crossbeam-utils",
          "num_cpus",
          "rand",
          "signal-hook"
        ]
      }
    ]
  }
}