libpfu_style/
chkupd.rs

1//! `CHKUPDATE` checks.
2
3use anyhow::Result;
4use async_trait::async_trait;
5use libabbs::apml::value::union::Union;
6use libpfu::{
7	Linter, Session, declare_lint, declare_linter,
8	message::{LintMessage, Snippet},
9	walk_apml,
10};
11use log::debug;
12
13declare_linter! {
14	pub CHKUPDATE_LINTER,
15	ChkUpdateLinter,
16	[
17		"unknown-findupdate-tag",
18		"prefer-anitya",
19	]
20}
21
22declare_lint! {
23	pub UNKNOWN_FINDUPDATE_TAG_LINT,
24	"unknown-findupdate-tag",
25	Error,
26	"unknown handler found in CHKUPDATE"
27}
28
29declare_lint! {
30	pub PREFER_ANITYA_LINT,
31	"prefer-anitya",
32	Warning,
33	"prefer to use Anitya for version checking"
34}
35
36#[async_trait]
37impl Linter for ChkUpdateLinter {
38	async fn apply(&self, sess: &Session) -> Result<()> {
39		for mut apml in walk_apml(sess) {
40			debug!("Checking CHKUPDATE in {apml:?}");
41			let (chkupdate, chkupdate_idx) = apml.with_upgraded(|apml| {
42				(
43					apml.ctx().map(|ctx| ctx.read("CHKUPDATE").into_string()),
44					apml.read_with_editor(|editor| {
45						editor
46							.find_var("CHKUPDATE")
47							.unzip()
48							.0
49							.unwrap_or_default()
50					}),
51				)
52			});
53			let chkupdate = chkupdate?;
54			let chkupdate = chkupdate.trim();
55			if chkupdate.is_empty() {
56				debug!("CHKUPDATE is not defined");
57				return Ok(());
58			}
59
60			let un = Union::try_from(chkupdate)?;
61			match un.tag.to_ascii_lowercase().as_str() {
62				"anitya" => {}
63				"github" | "gitweb" | "git" | "html" | "gitlab" => {
64					LintMessage::new(PREFER_ANITYA_LINT)
65						.note(format!(
66							"CHKUPDATE with tag {} should be converted into anitya",
67							un.tag
68						))
69						.snippet(Snippet::new_index(sess, &apml, chkupdate_idx))
70						.emit(sess);
71				}
72				_ => {
73					LintMessage::new(UNKNOWN_FINDUPDATE_TAG_LINT)
74						.note(format!(
75							"CHKUPDATE with tag {} is unsupported",
76							un.tag
77						))
78						.snippet(Snippet::new_index(sess, &apml, chkupdate_idx))
79						.emit(sess);
80				}
81			}
82		}
83		Ok(())
84	}
85}