Skip to content

Commit bbffc45

Browse files
authored
Print Kani version (rust-lang#2619)
1 parent 319d859 commit bbffc45

File tree

11 files changed

+154
-2
lines changed

11 files changed

+154
-2
lines changed

kani-driver/src/main.rs

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ use crate::args::StandaloneSubcommand;
1414
use crate::concrete_playback::playback::{playback_cargo, playback_standalone};
1515
use crate::project::Project;
1616
use crate::session::KaniSession;
17+
use crate::version::print_kani_version;
1718
use clap::Parser;
1819
use tracing::debug;
1920

@@ -35,12 +36,15 @@ mod metadata;
3536
mod project;
3637
mod session;
3738
mod util;
39+
mod version;
3840

3941
/// The main function for the `kani-driver`.
4042
/// The driver can be invoked via `cargo kani` and `kani` commands, which determines what kind of
4143
/// project should be verified.
4244
fn main() -> ExitCode {
43-
let result = match determine_invocation_type(Vec::from_iter(std::env::args_os())) {
45+
let invocation_type = determine_invocation_type(Vec::from_iter(std::env::args_os()));
46+
47+
let result = match invocation_type {
4448
InvocationType::CargoKani(args) => cargokani_main(args),
4549
InvocationType::Standalone => standalone_main(),
4650
};
@@ -59,10 +63,15 @@ fn main() -> ExitCode {
5963
/// The main function for the `cargo kani` command.
6064
fn cargokani_main(input_args: Vec<OsString>) -> Result<()> {
6165
let input_args = join_args(input_args)?;
62-
let args = args::CargoKaniArgs::parse_from(input_args);
66+
let args = args::CargoKaniArgs::parse_from(&input_args);
6367
check_is_valid(&args);
68+
6469
let session = session::KaniSession::new(args.verify_opts)?;
6570

71+
if !session.args.common_args.quiet {
72+
print_kani_version(InvocationType::CargoKani(input_args));
73+
}
74+
6675
match args.command {
6776
Some(CargoKaniSubcommand::Assess(args)) => {
6877
return assess::run_assess(session, *args);
@@ -91,6 +100,11 @@ fn standalone_main() -> Result<()> {
91100
}
92101

93102
let session = session::KaniSession::new(args.verify_opts)?;
103+
104+
if !session.args.common_args.quiet {
105+
print_kani_version(InvocationType::Standalone);
106+
}
107+
94108
let project = project::standalone_project(&args.input.unwrap(), &session)?;
95109
if session.args.only_codegen { Ok(()) } else { verify_project(project, session) }
96110
}

kani-driver/src/version.rs

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// Copyright Kani Contributors
2+
// SPDX-License-Identifier: Apache-2.0 OR MIT
3+
4+
use crate::InvocationType;
5+
6+
const KANI_RUST_VERIFIER: &str = "Kani Rust Verifier";
7+
/// We assume this is the same as the `kani-verifier` version, but we should
8+
/// make sure it's enforced through CI:
9+
/// <https://github.com/model-checking/kani/issues/2626>
10+
const KANI_VERSION: &str = env!("CARGO_PKG_VERSION");
11+
12+
/// Print Kani version. At present, this is only release version information.
13+
pub(crate) fn print_kani_version(invocation_type: InvocationType) {
14+
let kani_version = kani_version_release(invocation_type);
15+
// TODO: Print development version information.
16+
// <https://github.com/model-checking/kani/issues/2617>
17+
println!("{kani_version}");
18+
}
19+
20+
/// Print Kani release version as `Kani Rust Verifier <version> (<invocation>)`
21+
/// where:
22+
/// - `<version>` is the `kani-verifier` version
23+
/// - `<invocation>` is `cargo plugin` if Kani was invoked with `cargo kani` or
24+
/// `standalone` if it was invoked with `kani`.
25+
fn kani_version_release(invocation_type: InvocationType) -> String {
26+
let invocation_str = match invocation_type {
27+
InvocationType::CargoKani(_) => "cargo plugin",
28+
InvocationType::Standalone => "standalone",
29+
};
30+
format!("{KANI_RUST_VERIFIER} {KANI_VERSION} ({invocation_str})")
31+
}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
success: version printed agrees
2+
success: `(cargo plugin)` appears in version line
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
#!/usr/bin/env bash
2+
# Copyright Kani Contributors
3+
# SPDX-License-Identifier: Apache-2.0 OR MIT
4+
5+
set -eu
6+
7+
KANI_VERSION_CMD=`cargo kani --version`
8+
KANI_VERSION_CMD_VERSION=`echo ${KANI_VERSION_CMD} | awk '{print $2}'`
9+
10+
# Check that the version printed is the same. Note: We use `sed -n '1p'` instead
11+
# of `head -n 1` to avoid https://github.com/model-checking/kani/issues/2618
12+
KANI_CARGO_OUTPUT_HEAD=`cd dummy-project; cargo kani | sed -n '1p'`
13+
KANI_CARGO_OUTPUT_HEAD_VERSION=`echo ${KANI_CARGO_OUTPUT_HEAD} | awk '{print $4}'`
14+
15+
if [[ $KANI_VERSION_CMD_VERSION == $KANI_CARGO_OUTPUT_HEAD_VERSION ]]; then
16+
echo "success: version printed agrees"
17+
else
18+
echo "failed: version printed differs ($KANI_VERSION_CMD_VERSION - $KANI_CARGO_OUTPUT_HEAD_VERSION)"
19+
exit 1
20+
fi
21+
22+
KANI_CARGO_OUTPUT_HEAD_MODE=`echo ${KANI_CARGO_OUTPUT_HEAD} | awk '{print $5,$6}'`
23+
24+
# Check that `(cargo plugin)` appears in the version line
25+
if [[ $KANI_CARGO_OUTPUT_HEAD_MODE == "(cargo plugin)" ]]; then
26+
echo "success: \`(cargo plugin)\` appears in version line"
27+
else
28+
echo "failed: expected \`(cargo plugin)\` in version line"
29+
exit 1
30+
fi
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# Copyright Kani Contributors
2+
# SPDX-License-Identifier: Apache-2.0 OR MIT
3+
script: cargo-kani-version-flag-version.sh
4+
expected: cargo-kani-version-flag-version.expected
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# Copyright Kani Contributors
2+
# SPDX-License-Identifier: Apache-2.0 OR MIT
3+
4+
[package]
5+
name = "dummy-project"
6+
version = "0.1.0"
7+
edition = "2021"
8+
9+
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
10+
11+
[dependencies]
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// Copyright Kani Contributors
2+
// SPDX-License-Identifier: Apache-2.0 OR MIT
3+
4+
//! This test is used to check that an invocation of `cargo kani` prints the version
5+
//! and invocation type as expected.
6+
7+
fn main() {
8+
println!("Hello, world!");
9+
}
10+
11+
#[kani::proof]
12+
fn dummy() {
13+
assert!(1 + 1 == 2);
14+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# Copyright Kani Contributors
2+
# SPDX-License-Identifier: Apache-2.0 OR MIT
3+
script: kani-version-flag-version.sh
4+
expected: kani-version-flag-version.expected
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// Copyright Kani Contributors
2+
// SPDX-License-Identifier: Apache-2.0 OR MIT
3+
4+
//! This test is used to check that an invocation of `kani` or `cargo kani`
5+
//! prints the version and invocation type as expected.
6+
7+
#[kani::proof]
8+
fn dummy() {
9+
assert!(1 + 1 == 2);
10+
}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
success: version printed agrees
2+
success: `(standalone)` appears in version line
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
#!/usr/bin/env bash
2+
# Copyright Kani Contributors
3+
# SPDX-License-Identifier: Apache-2.0 OR MIT
4+
5+
set -eu
6+
7+
KANI_VERSION_CMD=`kani --version`
8+
KANI_VERSION_CMD_VERSION=`echo ${KANI_VERSION_CMD} | awk '{print $2}'`
9+
10+
# Check that the version printed is the same. Note: We use `sed -n '1p'` instead
11+
# of `head -n 1` to avoid https://github.com/model-checking/kani/issues/2618
12+
KANI_STANDALONE_OUTPUT_HEAD=`kani dummy-file.rs | sed -n '1p'`
13+
KANI_STANDALONE_OUTPUT_HEAD_VERSION=`echo ${KANI_STANDALONE_OUTPUT_HEAD} | awk '{print $4}'`
14+
15+
if [[ $KANI_VERSION_CMD_VERSION == $KANI_STANDALONE_OUTPUT_HEAD_VERSION ]]; then
16+
echo "success: version printed agrees"
17+
else
18+
echo "failed: version printed differs ($KANI_VERSION_CMD_VERSION - $KANI_STANDALONE_OUTPUT_HEAD_VERSION)"
19+
exit 1
20+
fi
21+
22+
KANI_STANDALONE_OUTPUT_HEAD_MODE=`echo ${KANI_STANDALONE_OUTPUT_HEAD} | awk '{print $5}'`
23+
24+
# Check that `(standalone)` appears in the version line
25+
if [[ $KANI_STANDALONE_OUTPUT_HEAD_MODE == "(standalone)" ]]; then
26+
echo "success: \`(standalone)\` appears in version line"
27+
else
28+
echo "failed: expected \`(standalone)\` in version line"
29+
exit 1
30+
fi

0 commit comments

Comments
 (0)