Commit 88fcbd81 authored by Wohlgemuth, Jason's avatar Wohlgemuth, Jason
Browse files

feat: Improve vale package download and log output for check command

parent dfbf694b
Loading
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -3,13 +3,13 @@ use acorn::prelude::PathBuf;
use acorn::util::constants::{ENV_CACHE_TTL, ENV_DATABASE_BACKEND, ENV_DATABASE_PATH, ENV_NO_LOCAL_DATABASE};
use acorn::util::{regex_inverse, regex_join};
use bon::Builder;
use fancy_regex::Regex;
use clap::builder::{
    styling::{Ansi256Color, AnsiColor},
    Styles,
};
use clap::{ArgAction, Parser, Subcommand, ValueHint};
use clap_verbosity_flag::Verbosity;
use fancy_regex::Regex;
use tracing::error;

pub mod arguments;
+5 −20
Original line number Diff line number Diff line
use crate::cli::{filter_by_pattern, resolve_paths, Arguments, CommandOptions};
use acorn::prelude::PathBuf;
use acorn::prelude::{Path, PathBuf};
use clap::{CommandFactory, Parser};
use futures::executor::block_on;

fn has_suffix(path: &PathBuf, suffix: &str) -> bool {
fn has_suffix(path: &Path, suffix: &str) -> bool {
    path.to_string_lossy().replace('\\', "/").ends_with(suffix)
}

fn fixture_content_root() -> PathBuf {
    PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("../tests/fixtures/filter")
}
@@ -39,13 +38,7 @@ fn test_filter_paths_by_pattern_keeps_only_matching_relative_paths() {
    ];
    let pattern = "^(?!.*(?:(?:acorn)|(?:sansr))).*$".to_string();
    let filtered = filter_by_pattern(paths, pattern, root.clone());
    assert_eq!(
        filtered,
        vec![
            root.join("acorn/index.json"),
            root.join("sansr/index.yaml"),
        ]
    );
    assert_eq!(filtered, vec![root.join("acorn/index.json"), root.join("sansr/index.yaml"),]);
}
#[test]
fn test_filter_paths_by_pattern_applies_ignore_pattern_to_relative_paths() {
@@ -57,13 +50,7 @@ fn test_filter_paths_by_pattern_applies_ignore_pattern_to_relative_paths() {
    ];
    let pattern = "(?:acorn)".to_string();
    let filtered = filter_by_pattern(paths, pattern, root.clone());
    assert_eq!(
        filtered,
        vec![
            root.join("sansr/index.yaml"),
            root.join("other/index.json"),
        ]
    );
    assert_eq!(filtered, vec![root.join("sansr/index.yaml"), root.join("other/index.json"),]);
}
#[test]
fn test_filter_paths_by_pattern_returns_empty_for_invalid_regex() {
@@ -75,9 +62,7 @@ fn test_filter_paths_by_pattern_returns_empty_for_invalid_regex() {
#[test]
fn test_resolve_paths_applies_filter_to_relative_local_paths() {
    let root = fixture_content_root();
    let options = CommandOptions::init()
        .maybe_filter(Some("(?:acorn)|(?:sansr)".to_string()))
        .build();
    let options = CommandOptions::init().maybe_filter(Some("(?:acorn)|(?:sansr)".to_string())).build();
    let resolved = block_on(resolve_paths(&Some(root), &options));
    assert_eq!(resolved.len(), 2);
    assert!(resolved.iter().any(|path| has_suffix(path, "acorn/index.json")));
+4 −12
Original line number Diff line number Diff line
@@ -113,7 +113,7 @@ fn handle(issues: &[Check], paths: &[PathBuf], options: &CheckOptions) -> Result
    let CheckOptions { quiet, no_fail, terse, .. } = options.clone();
    let print_summary = || {
        let file_count = paths.len();
        let headers = vec!["Item", "Count"];
        let headers = vec!["", "Count"];
        let rows = (file_count > 1)
            .then(|| vec!["Files checked".to_string(), file_count.to_string()])
            .into_iter()
@@ -123,7 +123,7 @@ fn handle(issues: &[Check], paths: &[PathBuf], options: &CheckOptions) -> Result
    };
    if !quiet {
        render(issues, terse);
        if !(no_fail || terse) && has_failures(issues) {
        if !(no_fail || terse || issues.is_empty()) {
            print_summary();
        }
    }
@@ -145,18 +145,10 @@ fn handle(issues: &[Check], paths: &[PathBuf], options: &CheckOptions) -> Result
    }
}
fn failure_count(issues: &[Check]) -> usize {
    issues
        .iter()
        .filter(|issue| issue.is_failure())
        .map(Check::issue_count)
        .sum::<usize>()
    issues.iter().filter(|issue| issue.is_failure()).map(Check::issue_count).sum::<usize>()
}
fn filter_by_visibility(issues: &[Check], all: bool) -> Vec<Check> {
    issues
        .iter()
        .filter(|issue| all || issue.is_failure())
        .cloned()
        .collect::<Vec<Check>>()
    issues.iter().filter(|issue| all || issue.is_failure()).cloned().collect::<Vec<Check>>()
}
fn has_failures(issues: &[Check]) -> bool {
    issues.iter().any(Check::is_failure)
+2 −2
Original line number Diff line number Diff line
@@ -35,8 +35,8 @@ use futures::future::ready;
use futures::TryFutureExt;
use owo_colors::OwoColorize;
use std::process::exit;
use tracing::info;
use tracing::instrument;
use tracing::{debug, info};
use tracing_indicatif::IndicatifLayer;
use tracing_log::AsTrace;
use tracing_subscriber::fmt::{self};
@@ -142,8 +142,8 @@ async fn main() -> Void {
        env::set_var(ENV_CACHE_TTL, ttl.to_string());
    }
    if threads > 0 {
        info!("{} {} threads", Label::using(), threads.cyan().bold());
        rayon::ThreadPoolBuilder::new().num_threads(threads).build_global().unwrap();
        debug!("{} {} threads", Label::using(), threads.cyan().bold());
    }
    let database_initialization = if no_local_database {
        Ok(())
+25 −6
Original line number Diff line number Diff line
@@ -16,7 +16,7 @@ use crate::schema::standard::cff::{Cff, Identifier, IdentifierType, Reference};
use crate::schema::standard::text::Text;
use crate::schema::{Organization, ProgrammingLanguage, Website};
use crate::util::constants::{APPLICATION, CUSTOM_VALE_PACKAGE_NAME, DEFAULT_VALE_PACKAGE_URL, DEFAULT_VALE_ROOT, VALE_RELEASES_URL, VALE_VERSION};
use crate::util::{Constant, Label, SemanticVersion, StringConversion};
use crate::util::{is_uri_or_path, Constant, Label, SemanticVersion, StringConversion};
use crate::{check, check_err, check_ok};
use crate::{cmd, skip};
use crate::{Location, Repository};
@@ -93,6 +93,8 @@ pub trait StaticAnalyzerConfig {
    async fn save(self) -> Self;
    /// Set parent path of configuration
    fn with_path(self, path: PathBuf) -> Self;
    /// Resolve package source: convert bare package name to download URL or pass through existing URL/path
    fn resolve_package(value: impl AsRef<str>) -> String;
}
#[async_trait]
impl Analysis for Cff {
@@ -312,10 +314,11 @@ impl Analysis for ResearchActivity {
        });
        join_all(futures).await.into_iter().flatten().collect()
    }
    fn output_path(_path: &Path, data: &Self) -> PathBuf {
    fn output_path(path: &Path, data: &Self) -> PathBuf {
        let filename = path.file_name().and_then(|n| n.to_str()).unwrap_or("index.json");
        standard_project_folder("check", None)
            .join(data.meta.identifier.to_lowercase())
            .join("index.json")
            .join(filename)
    }
}
#[async_trait]
@@ -712,6 +715,7 @@ impl StaticAnalyzerConfig for ValeConfig {
            disabled,
            ..
        } = self;
        let package_names = packages.clone();
        let mut conf = Ini::new();
        let package_repository = Repository::GitLab {
            id: None,
@@ -724,18 +728,33 @@ impl StaticAnalyzerConfig for ValeConfig {
            }
            | None => DEFAULT_VALE_PACKAGE_URL.to_string(),
        };
        let package_sources = package_names
            .iter()
            .map(Self::resolve_package)
            .chain(core::iter::once(package_url))
            .collect::<Vec<String>>();
        // CAUTION: Order of attributes in INI file matter. "StylesPath" must come before "Vocab"
        conf.with_section::<String>(None)
            .set("StylesPath", "styles")
            .set("Vocab", vocabularies.join(", "))
            .set("Packages", format!("{}, {}", packages.join(", "), package_url));
        conf.with_section(Some("*"))
            .set("BasedOnStyles", format!("Vale, {}, {}", CUSTOM_VALE_PACKAGE_NAME, packages.join(", ")));
            .set("Packages", package_sources.join(", "));
        conf.with_section(Some("*")).set(
            "BasedOnStyles",
            format!("Vale, {}, {}", CUSTOM_VALE_PACKAGE_NAME, package_names.join(", ")),
        );
        disabled.iter().for_each(|rule| {
            conf.with_section(Some("*")).set(rule, "NO");
        });
        conf
    }
    fn resolve_package(value: impl AsRef<str>) -> String {
        let value = value.as_ref().trim();
        if is_uri_or_path(value) {
            value.to_string()
        } else {
            format!("https://github.com/errata-ai/{value}/releases/latest/download/{value}.zip")
        }
    }
    async fn save(self) -> ValeConfig {
        let path = self.clone().path;
        let parent = path.parent().unwrap().to_path_buf();
Loading