From a93cc80c43edaf73607ca6b30f8b0673b5d05115 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sergio=20Casta=C3=B1o=20Arteaga?= Date: Tue, 1 Mar 2022 14:16:17 +0100 Subject: [PATCH] Add trademark footer check MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Closes #73 Signed-off-by: Sergio CastaƱo Arteaga --- .gitattributes | 2 -- Cargo.lock | 1 + clomonitor-core/Cargo.toml | 1 + clomonitor-core/src/linter/check.rs | 13 +++++++++++ clomonitor-core/src/linter/patterns.rs | 2 ++ clomonitor-core/src/linter/primary.rs | 31 +++++++++++++++++++------- clomonitor-core/src/score/primary.rs | 7 +++++- clomonitor-linter/src/display.rs | 4 ++++ web/src/data.tsx | 8 ++++++- web/src/types.ts | 1 + 10 files changed, 58 insertions(+), 12 deletions(-) diff --git a/.gitattributes b/.gitattributes index 0137e99a..8b75a8c3 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,3 +1 @@ *.snap linguist-generated -*.sql linguist-detectable=true -*.sql linguist-language=sql diff --git a/Cargo.lock b/Cargo.lock index 7fe77dfa..63ce53fe 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -372,6 +372,7 @@ dependencies = [ "lazy_static", "octocrab", "regex", + "reqwest", "serde 1.0.136", "serde_yaml", "tokio", diff --git a/clomonitor-core/Cargo.toml b/clomonitor-core/Cargo.toml index 01cc23ce..82876428 100644 --- a/clomonitor-core/Cargo.toml +++ b/clomonitor-core/Cargo.toml @@ -12,6 +12,7 @@ glob = "0.3.0" lazy_static = "1.4.0" octocrab = "0.15.4" regex = "1.5.4" +reqwest = "0.11.9" serde = { version = "1.0", features = ["derive"] } serde_yaml = "0.8.23" tokio = { version = "1", features = ["macros", "rt-multi-thread"] } diff --git a/clomonitor-core/src/linter/check.rs b/clomonitor-core/src/linter/check.rs index 69c041cf..709626a0 100644 --- a/clomonitor-core/src/linter/check.rs +++ b/clomonitor-core/src/linter/check.rs @@ -3,6 +3,7 @@ use askalono::*; use glob::{glob_with, MatchOptions, PatternError}; use lazy_static::lazy_static; use regex::{Regex, RegexSet}; +use reqwest; use std::fs; use std::path::{Path, PathBuf}; @@ -81,6 +82,18 @@ where })) } +/// Check if the content of the url provided matches any of the regular +/// expressions given. +pub(crate) async fn content_url_matches(url: &str, regexps: R) -> Result +where + R: IntoIterator, + R::Item: AsRef, +{ + let content = reqwest::get(url).await?.text().await?; + let re = RegexSet::new(regexps)?; + Ok(re.is_match(&content)) +} + /// Check if the license provided is an approved one. pub(crate) fn is_approved_license(spdx_id: &str) -> bool { APPROVED_LICENSES.contains(&spdx_id) diff --git a/clomonitor-core/src/linter/patterns.rs b/clomonitor-core/src/linter/patterns.rs index da99428d..245b22f5 100644 --- a/clomonitor-core/src/linter/patterns.rs +++ b/clomonitor-core/src/linter/patterns.rs @@ -39,6 +39,8 @@ pub(crate) static COMMUNITY_MEETING_TEXT: [&str; 3] = [ ]; pub(crate) static OPENSSF_BADGE_URL: [&str; 1] = [r"https://bestpractices.coreinfrastructure.org/projects/\d+"]; +pub(crate) static TRADEMARK_FOOTER: [&str; 1] = + [r"https://www.linuxfoundation.org/trademark-usage"]; // Security pub(crate) static SECURITY_POLICY_FILE: [&str; 3] = diff --git a/clomonitor-core/src/linter/primary.rs b/clomonitor-core/src/linter/primary.rs index b2c5cacf..f59a7de3 100644 --- a/clomonitor-core/src/linter/primary.rs +++ b/clomonitor-core/src/linter/primary.rs @@ -52,6 +52,7 @@ pub struct BestPractices { pub community_meeting: bool, pub openssf_badge: bool, pub recent_release: bool, + pub trademark_footer: bool, } /// Security section of the report. @@ -66,11 +67,12 @@ pub async fn lint(options: LintOptions<'_>) -> Result { // Get CLOMonitor metadata let md = Metadata::from(options.root.join(METADATA_FILE))?; - // Run some async expressions and wait for them to complete - let (gh_md, best_practices) = tokio::try_join!( - github::get_metadata(options.url), - lint_best_practices(options.root, options.url) - )?; + // Get Github metadata + let gh_md = github::get_metadata(options.url).await?; + + // Async checks: best_practices + let (best_practices,) = + tokio::try_join!(lint_best_practices(options.root, options.url, &gh_md))?; Ok(Report { documentation: lint_documentation(options.root, &gh_md)?, @@ -235,7 +237,11 @@ fn lint_license(root: &Path, md: &Option) -> Result { } /// Run best practices checks and prepare the report's best practices section. -async fn lint_best_practices(root: &Path, repo_url: &str) -> Result { +async fn lint_best_practices( + root: &Path, + repo_url: &str, + gh_md: &Repository, +) -> Result { // Artifact Hub badge let artifacthub_badge = check::content_matches( Globs { @@ -266,14 +272,23 @@ async fn lint_best_practices(root: &Path, repo_url: &str) -> Result Score { score.best_practices += 25; } if report.best_practices.openssf_badge { - score.best_practices += 60; + score.best_practices += 50; } if report.best_practices.recent_release { score.best_practices += 10; } + if report.best_practices.trademark_footer { + score.best_practices += 10; + } // Security if report.security.security_policy { @@ -146,6 +149,7 @@ mod tests { community_meeting: true, openssf_badge: true, recent_release: true, + trademark_footer: true, }, security: Security { security_policy: true, @@ -186,6 +190,7 @@ mod tests { community_meeting: false, openssf_badge: false, recent_release: false, + trademark_footer: false, }, security: Security { security_policy: false, diff --git a/clomonitor-linter/src/display.rs b/clomonitor-linter/src/display.rs index 43d87eaf..a612e5d6 100644 --- a/clomonitor-linter/src/display.rs +++ b/clomonitor-linter/src/display.rs @@ -124,6 +124,10 @@ pub(crate) fn display_primary(report: &linter::primary::Report, score: &score::p cell_entry("Best practices / Recent release"), cell_check(report.best_practices.recent_release), ]) + .add_row(vec![ + cell_entry("Best practices / Trademark footer"), + cell_check(report.best_practices.trademark_footer), + ]) .add_row(vec![ cell_entry("Security / Security policy"), cell_check(report.security.security_policy), diff --git a/web/src/data.tsx b/web/src/data.tsx index 96b71513..7083f04f 100644 --- a/web/src/data.tsx +++ b/web/src/data.tsx @@ -1,7 +1,7 @@ import { BiLock, BiMedal, BiShieldQuarter, BiTrophy, BiWorld } from 'react-icons/bi'; import { BsCalendar3 } from 'react-icons/bs'; import { CgFileDocument, CgReadme } from 'react-icons/cg'; -import { FaBalanceScale, FaCheckDouble, FaTools } from 'react-icons/fa'; +import { FaBalanceScale, FaCheckDouble, FaTools, FaTrademark } from 'react-icons/fa'; import { FiHexagon } from 'react-icons/fi'; import { GiFountainPen, GiStamper, GiTiedScroll } from 'react-icons/gi'; import { GoLaw } from 'react-icons/go'; @@ -314,6 +314,12 @@ export const REPORT_OPTIONS: ReportOptionInfo = { ), }, + [ReportOption.TrademarkFooter]: { + icon: , + name: 'Trademark footer', + legend: Projects sites should have Linux Foundation trademark footer, + description: We check that the website defined in Github has the trademark footer, + }, [ReportOption.Website]: { icon: , name: 'Website', diff --git a/web/src/types.ts b/web/src/types.ts index f00ce7f9..ffe5fd08 100644 --- a/web/src/types.ts +++ b/web/src/types.ts @@ -172,6 +172,7 @@ export enum ReportOption { Roadmap = 'roadmap', SecurityPolicy = 'security_policy', SPDX = 'spdx_id', + TrademarkFooter = 'trademark_footer', Website = 'website', }