如何导致编译因 CI 警告而失败并在 .cargo/config 中设置额外的 rustflags?

问题描述 投票:0回答:3

我试图让 Cargo 在 CI 上出现警告时失败,但在本地开发时不会失败。

我有一个可行的解决方案,即在 CI 作业中设置

RUSTFLAGS=“-D warnings”
。这很有效,因为它确实会使本地板条箱的构建失败,但不会导致依赖项板条箱的构建失败(由于
—cap-lints
)。

最近,必须在(签入)

.cargo/config
文件中设置一些 rustflags:

[target.’cfg(target_os = “linux”)’]
rustflags = [“some”, “options”]

这不起作用,因为

RUSTFLAGS
优先并且
.cargo/config
标志将被忽略。我不想将
-D warnings
添加到
config
,因为这在开发时可能会很痛苦。

当前的解决方法是在 CI 作业之前调整

config
的脚本:

sed -i "s:\(rustflags = .*\)]:\1, \"-D\", \"warnings\"]:g" .cargo/config
echo '[build]' >> .cargo/config
echo 'rustflags = [ "-D", "warnings"]' >> .cargo/config

这会将

-D warnings
附加到配置中现有的
rustflags
,并且 创建一个额外的包罗万象的
config
条目,以确保
-D warnings
在非 Linux CI 构建上也启用。

这太hacky了;我缺少更好的解决方案吗?

也许这应该是 Cargo 存储库上的一个功能请求,但我不知道理想的解决方案是什么样的。

rust continuous-integration rust-cargo
3个回答
0
投票

您可以使用

built::util::detect_ci()
来确定当前构建是否在 CI 下执行。然后您可以使用一个小的构建脚本来设置 cfg

Cargo.toml

[package]
build = true

[build-dependencies]
built = { version = "0.3", default_features = false }

build.rs

fn main() {
    if let Some(ci) = built::util::detect_ci() {
        // There may be a better way to do this
        println!("cargo:rustc-cfg=DENY_WARNINGS");
        println!("cargo:warning=Denying warnings because we are in CI \"{}\"", ci);
    }
}

请注意,构建脚本的结果被缓存,因此一旦此构建脚本运行并且 Cargo 决定我们是否在 CI 下运行,它将遵循此结果,直到您修改构建脚本或

cargo clean
。这对于本地开发或 CI 来说都不是问题,除非 Scotty 定期向您发送信息。

main.rslib.rs

#![cfg_attr(DENY_WARNINGS, deny(warnings))]

fn main() {
    // This will be a warning locally but fail to compile e.g. if built on Travis
    Result::<(), ()>::Err(());
}

0
投票

使用环境变量覆盖:

CARGO_BUILD_RUSTFLAGS='-D warnings' cargo check

如果您对其工作原理感兴趣,请使用:https://doc.rust-lang.org/cargo/reference/config.html#environment-variables(简而言之,此类环境变量名称是通用的,不仅仅是这个变量名有任何作用)。

如果您在没有环境变量的情况下运行

cargo check
,即使存在编译警告,它也会继续编译。


0
投票

作为替代解决方案,为了区分“CI严格模式”和“本地宽松模式”,您可以简单地在CI中使用

clippy
,在本地使用
cargo check
clippy
可以轻松配置为“严格”,如果出现警告则失败。它也是确保整个项目统一良好代码质量的好工具。

© www.soinside.com 2019 - 2024. All rights reserved.