Skip to content

Commit

Permalink
Some refactoring (#111)
Browse files Browse the repository at this point in the history
Signed-off-by: Sergio Castaño Arteaga <[email protected]>
  • Loading branch information
tegioz authored Mar 1, 2022
1 parent 9c0adc1 commit 43049e0
Show file tree
Hide file tree
Showing 32 changed files with 157 additions and 151 deletions.
3 changes: 3 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
*.snap linguist-generated
*.sql linguist-detectable=true
*.sql linguist-language=sql
4 changes: 2 additions & 2 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Contributing Guide

The CloMonitor project accepts contributions via [GitHub pull requests](https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/about-pull-requests). This document outlines the process to help get your contribution accepted.
The CLOMonitor project accepts contributions via [GitHub pull requests](https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/about-pull-requests). This document outlines the process to help get your contribution accepted.

## Issues and discussions

Expand All @@ -23,7 +23,7 @@ You can get some information about the project's **architecture** and how to set

## Developer Certificate of Origin

The CloMonitor project uses a [Developers Certificate of Origin (DCO)](https://developercertificate.org/) to sign-off that you have the right to contribute the code being contributed. The full text of the DCO reads:
The CLOMonitor project uses a [Developers Certificate of Origin (DCO)](https://developercertificate.org/) to sign-off that you have the right to contribute the code being contributed. The full text of the DCO reads:

```text
Developer Certificate of Origin
Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
# CloMonitor
# CLOMonitor

[![CI](https://github.com/cncf/clomonitor/workflows/CI/badge.svg)](https://github.com/cncf/clomonitor/actions?query=workflow%3ACI)
[![Gitpod Ready-to-Code](https://img.shields.io/badge/Gitpod-ready--to--code-blue?logo=gitpod)](https://gitpod.io/#https://github.com/cncf/clomonitor)

[**CloMonitor**](https://clomonitor.io) is a tool that periodically checks CNCF projects repositories to verify they meet a certain project health best practices.
[**CLOMonitor**](https://clomonitor.io) is a tool that periodically checks CNCF projects repositories to verify they meet a certain project health best practices.

<br/>
<table>
Expand All @@ -29,4 +29,4 @@ This project follows the [CNCF Code of Conduct](https://github.com/cncf/foundati

## License

CloMonitor is an Open Source project licensed under the [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0).
CLOMonitor is an Open Source project licensed under the [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0).
2 changes: 1 addition & 1 deletion chart/Chart.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
apiVersion: v2
name: clomonitor
description: CloMonitor is a tool that periodically checks CNCF projects' repositories to verify they meet a certain set of standards.
description: CLOMonitor is a tool that periodically checks CNCF projects' repositories to verify they meet a certain set of standards.
type: application
version: 0.1.0
appVersion: 0.1.0
Expand Down
2 changes: 1 addition & 1 deletion chart/values.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# CloMonitor chart default configuration values
# CLOMonitor chart default configuration values

imagePullSecrets: []
imageTag: ""
Expand Down
2 changes: 1 addition & 1 deletion clomonitor-apiserver/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "clomonitor-apiserver"
description = "Server that exposes the CloMonitor HTTP API and serves static assets"
description = "Server that exposes the CLOMonitor HTTP API and serves static assets"
version = "0.1.0"
edition = "2021"
rust-version = "1.58"
Expand Down
2 changes: 1 addition & 1 deletion clomonitor-apiserver/src/handlers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ pub(crate) async fn badge(
"namedLogo": "cncf",
"logoColor": "BEB5C8",
"logoWidth": 10,
"label": "CloMonitor Report",
"label": "CLOMonitor Report",
"message": message,
"color": color,
"schemaVersion": 1,
Expand Down
81 changes: 1 addition & 80 deletions clomonitor-core/src/linter/check.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
use anyhow::{format_err, Error};
use anyhow::Error;
use askalono::*;
use chrono::{Duration, Utc};
use glob::{glob_with, MatchOptions, PatternError};
use lazy_static::lazy_static;
use regex::{Regex, RegexSet};
Expand Down Expand Up @@ -82,31 +81,6 @@ where
}))
}

/// Check if the repository has released a new version in the last year.
pub(crate) async fn has_recent_release(repo_url: &str) -> Result<bool, Error> {
let (owner, repo) = get_owner_and_repo(repo_url)?;
let github = octocrab::instance();
let mut page = github
.repos(&owner, &repo)
.releases()
.list()
.per_page(1)
.send()
.await?;
let releases = page.take_items();
if let Some(last_release) = releases.first() {
if let Some(created_at) = last_release.created_at {
return Ok(created_at > Utc::now() - Duration::days(365));
}
}
Ok(false)
}

/// Check if the project has added a website to the Github repository.
pub(crate) async fn has_website(repo_url: &str) -> Result<bool, Error> {
Ok(get_website(repo_url).await?.is_some())
}

/// Check if the license provided is an approved one.
pub(crate) fn is_approved_license(spdx_id: &str) -> bool {
APPROVED_LICENSES.contains(&spdx_id)
Expand Down Expand Up @@ -144,35 +118,6 @@ where
Ok(!matching_paths(globs)?.is_empty())
}

/// Extract the owner and repository from the repository url provided.
fn get_owner_and_repo(repo_url: &str) -> Result<(String, String), Error> {
lazy_static! {
static ref GITHUB_RE: Regex =
Regex::new("^https://github.com/(?P<org>[^/]+)/(?P<repo>[^/]+)/?$").unwrap();
}
let c = GITHUB_RE
.captures(repo_url)
.ok_or(format_err!("invalid repository url"))?;
Ok((c["org"].to_string(), c["repo"].to_string()))
}

/// Get project's website from Github repository.
async fn get_website(repo_url: &str) -> Result<Option<String>, Error> {
let (owner, repo) = get_owner_and_repo(repo_url)?;
let github = octocrab::instance();
match github.repos(&owner, &repo).get().await {
Ok(repo) => {
if let Some(url) = repo.homepage {
if !url.is_empty() {
return Ok(Some(url));
}
}
Ok(None)
}
Err(err) => Err(err.into()),
}
}

/// Return all paths that match any of the globs provided.
fn matching_paths<P>(globs: Globs<P>) -> Result<Vec<PathBuf>, PatternError>
where
Expand Down Expand Up @@ -354,30 +299,6 @@ mod tests {
));
}

#[test]
fn get_owner_and_repo_valid_url() {
assert_eq!(
get_owner_and_repo("https://github.com/org/repo").unwrap(),
("org".to_string(), "repo".to_string())
);
}

#[test]
fn get_owner_and_repo_valid_url_trailing_slash() {
assert_eq!(
get_owner_and_repo("https://github.com/org/repo/").unwrap(),
("org".to_string(), "repo".to_string())
);
}

#[test]
fn get_owner_and_repo_invalid_url() {
assert!(matches!(
get_owner_and_repo("https://github.com/org"),
Err(_)
));
}

#[test]
fn approved_license() {
assert!(is_approved_license("Apache-2.0"));
Expand Down
76 changes: 76 additions & 0 deletions clomonitor-core/src/linter/github.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
use anyhow::{format_err, Error};
use chrono::{Duration, Utc};
use lazy_static::lazy_static;
use octocrab::models::Repository;
use regex::Regex;

/// Get repository's metadata from the Github API.
pub(crate) async fn get_metadata(repo_url: &str) -> Result<Repository, Error> {
let (owner, repo) = get_owner_and_repo(repo_url)?;
let github = octocrab::instance();
match github.repos(&owner, &repo).get().await {
Ok(repo) => Ok(repo),
Err(err) => Err(err.into()),
}
}

/// Check if the repository has released a new version in the last year.
pub(crate) async fn has_recent_release(repo_url: &str) -> Result<bool, Error> {
let (owner, repo) = get_owner_and_repo(repo_url)?;
let github = octocrab::instance();
let mut page = github
.repos(&owner, &repo)
.releases()
.list()
.per_page(1)
.send()
.await?;
let releases = page.take_items();
if let Some(last_release) = releases.first() {
if let Some(created_at) = last_release.created_at {
return Ok(created_at > Utc::now() - Duration::days(365));
}
}
Ok(false)
}

/// Extract the owner and repository from the repository url provided.
fn get_owner_and_repo(repo_url: &str) -> Result<(String, String), Error> {
lazy_static! {
static ref GITHUB_RE: Regex =
Regex::new("^https://github.com/(?P<org>[^/]+)/(?P<repo>[^/]+)/?$").unwrap();
}
let c = GITHUB_RE
.captures(repo_url)
.ok_or(format_err!("invalid repository url"))?;
Ok((c["org"].to_string(), c["repo"].to_string()))
}

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn get_owner_and_repo_valid_url() {
assert_eq!(
get_owner_and_repo("https://github.com/org/repo").unwrap(),
("org".to_string(), "repo".to_string())
);
}

#[test]
fn get_owner_and_repo_valid_url_trailing_slash() {
assert_eq!(
get_owner_and_repo("https://github.com/org/repo/").unwrap(),
("org".to_string(), "repo".to_string())
);
}

#[test]
fn get_owner_and_repo_invalid_url() {
assert!(matches!(
get_owner_and_repo("https://github.com/org"),
Err(_)
));
}
}
2 changes: 1 addition & 1 deletion clomonitor-core/src/linter/metadata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use std::path::Path;
/// Metadata file name.
pub const METADATA_FILE: &str = ".clomonitor.yml";

/// CloMonitor metadata.
/// CLOMonitor metadata.
#[derive(Debug, Deserialize)]
pub struct Metadata {
pub license_scanning: Option<LicenseScanning>,
Expand Down
1 change: 1 addition & 0 deletions clomonitor-core/src/linter/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use std::path::Path;
use std::str::FromStr;

mod check;
mod github;
mod metadata;
mod patterns;
pub mod primary;
Expand Down
25 changes: 15 additions & 10 deletions clomonitor-core/src/linter/primary.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
use super::{
check::{self, Globs},
github,
metadata::*,
patterns::*,
LintOptions,
};
use anyhow::Error;
use octocrab::models::Repository;
use serde::{Deserialize, Serialize};
use std::path::Path;

Expand Down Expand Up @@ -61,25 +63,25 @@ pub struct Security {

/// Lint the path provided and return a report.
pub async fn lint(options: LintOptions<'_>) -> Result<Report, Error> {
// Read and parse metadata
// Get CLOMonitor metadata
let md = Metadata::from(options.root.join(METADATA_FILE))?;

// Async checks: documentation, best_practices
let (documentation, best_practices) = tokio::try_join!(
lint_documentation(options.root, options.url),
lint_best_practices(options.root, options.url),
// 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)
)?;

Ok(Report {
documentation,
documentation: lint_documentation(options.root, &gh_md)?,
license: lint_license(options.root, &md)?,
best_practices,
security: lint_security(options.root)?,
})
}

/// Run documentation checks and prepare the report's documentation section.
async fn lint_documentation(root: &Path, repo_url: &str) -> Result<Documentation, Error> {
fn lint_documentation(root: &Path, gh_md: &Repository) -> Result<Documentation, Error> {
// Adopters
let adopters = check::path_exists(Globs {
root,
Expand Down Expand Up @@ -171,8 +173,11 @@ async fn lint_documentation(root: &Path, repo_url: &str) -> Result<Documentation
ROADMAP_HEADER,
)?;

// Async checks: website
let (website,) = tokio::try_join!(check::has_website(repo_url))?;
// Website
let website = match &gh_md.homepage {
Some(url) => !url.is_empty(),
None => false,
};

Ok(Documentation {
adopters,
Expand Down Expand Up @@ -262,7 +267,7 @@ async fn lint_best_practices(root: &Path, repo_url: &str) -> Result<BestPractice
)?;

// Async checks: recent_release
let (recent_release,) = tokio::try_join!(check::has_recent_release(repo_url))?;
let (recent_release,) = tokio::try_join!(github::has_recent_release(repo_url))?;

Ok(BestPractices {
artifacthub_badge,
Expand Down
2 changes: 1 addition & 1 deletion clomonitor-linter/src/display.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ pub(crate) const FAILURE_SYMBOL: char = '✗';

/// Print the linter results provided.
pub(crate) fn display(report: &Report, score: &Score) {
println!("CloMonitor linter results\n");
println!("CLOMonitor linter results\n");

match report {
Report::Primary(report) => {
Expand Down
2 changes: 1 addition & 1 deletion clomonitor-linter/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ async fn main() -> Result<(), Error> {
let args = Args::parse();

// Lint repository provided and display results
println!("\nRunning CloMonitor linter...\n");
println!("\nRunning CLOMonitor linter...\n");
let options = LintOptions {
root: &args.path,
kind: &args.kind,
Expand Down
2 changes: 1 addition & 1 deletion database/migrations/schema/001_initial.sql
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ create table if not exists linter (
display_name text check (display_name <> '')
);

insert into linter (linter_id, name, display_name) values (0, 'core', 'CloMonitor Core Linter');
insert into linter (linter_id, name, display_name) values (0, 'core', 'CLOMonitor Core Linter');

create table if not exists report (
report_id uuid primary key default gen_random_uuid(),
Expand Down
2 changes: 1 addition & 1 deletion database/tests/schema/schema.sql
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ select results_eq(
select results_eq(
'select * from linter',
$$ values
(0, 'core', 'CloMonitor Core Linter')
(0, 'core', 'CLOMonitor Core Linter')
$$,
'Linters should exist'
);
Expand Down
Loading

0 comments on commit 43049e0

Please sign in to comment.