From c8268d29170260ed94941f7291864eebfa726eb4 Mon Sep 17 00:00:00 2001 From: "Jose D. Gomez R" Date: Tue, 24 Oct 2023 22:08:20 +0200 Subject: [PATCH] Centralize perl linters - Mixed all linter configurations from os-autoinst, openQA, os-autoinst-distri-opensuse. Perlcritic RC & Perltidy RC files are centralized now here. For convenience, the most laxed rules were picked, this is still subject of discussion. - Improved perltidy & perlcritic wrappers Downstream repositories have a divergent copy of a tidyall wrapper that validates before that perltidy is in the correct version before running. The wrapper does *quite a lot* of text processing to assert the correct version of perltidy. The new and improved version will get the detected perltidy version directly from perl in a clean manner, and will invoke tidyall with all arguments passed to it. Additionally, perlcritic has a wrapper in Makefiles to inject a custom Perl critic policy that it's now provided in this repository. Both scripts are intended to be symlinked by downstream repositories that receive this repository via the subrepo flow. So rules can be enforced uniformly across repositories. - `Perl::Critic::Policy::HashKeyQuotes` is now enforced automatically via .perlcriticrc. Added `|` symbol as an exception to `Perl::Critic::Policy::HashKeyQuotes`. --- .gitignore | 6 ++++ .perlcriticrc | 21 ++++++++++++ .perltidyrc | 17 ++++++++++ .tidyallrc | 3 ++ .../Perl/Critic/Policy/HashKeyQuotes.pm | 31 +++++++++++++++++ tools/perlcritic | 15 ++++++++ tools/tidyall | 34 +++++++++++++++++++ 7 files changed, 127 insertions(+) create mode 100644 .gitignore create mode 100644 .perlcriticrc create mode 100644 .perltidyrc create mode 100644 .tidyallrc create mode 100644 lib/perlcritic/Perl/Critic/Policy/HashKeyQuotes.pm create mode 100755 tools/perlcritic create mode 100755 tools/tidyall diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..13eda00 --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +.perltidyrc +*.tdy +.*.swp +*~ +__pycache__/ +.tidyall.d/ diff --git a/.perlcriticrc b/.perlcriticrc new file mode 100644 index 0000000..38fb17e --- /dev/null +++ b/.perlcriticrc @@ -0,0 +1,21 @@ +# TODO: These rules are not longer called "Freenode" but "Community". +# Evaluate if they still apply. + +theme = freenode +severity = 4 +include = strict Perl::Critic::Policy::HashKeyQuotes + +[Freenode::DiscouragedModules] +severity = 3 + +# Test modules have no package declaration +[Freenode::PackageMatchesFilename] +severity = 1 + +[Perl::Critic::Policy::HashKeyQuotes] +severity = 5 + +[ControlStructures::ProhibitDeepNests] +severity = 4 +add_themes = freenode +max_nests = 4 diff --git a/.perltidyrc b/.perltidyrc new file mode 100644 index 0000000..fd4d360 --- /dev/null +++ b/.perltidyrc @@ -0,0 +1,17 @@ +# Workaround needed for handling non-ASCII in files. +# # See . +--character-encoding=none +--no-valign + +# TBD: openqa defines: -l=120 vs -l=160 in os-autoinst-distri-opensuse +# taking the most relaxed for now. + +-l=160 +-fbl # don't change blank lines +-nsfs # no spaces before semicolons +-baao # space after operators +-bbao # space before operators +-pt=2 # no spaces around () +-bt=2 # no spaces around [] +-sbt=2 # no spaces around {} +-sct # stack closing tokens )} diff --git a/.tidyallrc b/.tidyallrc new file mode 100644 index 0000000..7e0352c --- /dev/null +++ b/.tidyallrc @@ -0,0 +1,3 @@ +[PerlTidy] +select = **/*.{pl,pm,t} +argv = --profile=$ROOT/.perltidyrc diff --git a/lib/perlcritic/Perl/Critic/Policy/HashKeyQuotes.pm b/lib/perlcritic/Perl/Critic/Policy/HashKeyQuotes.pm new file mode 100644 index 0000000..f1d9c14 --- /dev/null +++ b/lib/perlcritic/Perl/Critic/Policy/HashKeyQuotes.pm @@ -0,0 +1,31 @@ +package Perl::Critic::Policy::HashKeyQuotes; + +use Mojo::Base 'Perl::Critic::Policy'; + +use Perl::Critic::Utils qw( :severities :classification :ppi ); + +our $VERSION = '0.0.1'; + +sub default_severity { return $SEVERITY_HIGH } +sub default_themes { return qw(openqa) } +sub applies_to { return qw(PPI::Token::Quote::Single PPI::Token::Quote::Double) } + +# check that hashes are not overly using quotes +# (os-autoinst coding style) + +sub violates { + my ($self, $elem) = @_; + + #we only want the check hash keys + return if !is_hash_key($elem); + + my $c = $elem->content; + # special characters + return if $c =~ m/[- \/<>.=_:\\\$\|]/; + + my $desc = q{Hash key with quotes}; + my $expl = q{Avoid useless quotes}; + return $self->violation($desc, $expl, $elem); +} + +1; diff --git a/tools/perlcritic b/tools/perlcritic new file mode 100755 index 0000000..d290186 --- /dev/null +++ b/tools/perlcritic @@ -0,0 +1,15 @@ +#!/bin/bash -e +# +# Wrap perlcritic to provide custom critic rules transparently. + +if ! command -v perlcritic > /dev/null 2>&1; then + echo "perlcritic not found: make sure you've installed all dependencies." + exit 1 +fi + +# This script will either be called directly from this project or symlinked from +# downstream projects. + +OS_AUTOINST_COMMONS_DIR=$(dirname $(dirname $(readlink -e "$0"))) + +PERL5LIB="${OS_AUTOINST_COMMONS_DIR}/lib/perlcritic:${PERL5LIB}" perlcritic $@ diff --git a/tools/tidyall b/tools/tidyall new file mode 100755 index 0000000..23f76c2 --- /dev/null +++ b/tools/tidyall @@ -0,0 +1,34 @@ +#!/usr/bin/env perl +# +# Tidyall command with perltidy version constraint. +use Perl::Tidy; +use strict; +use warnings "all"; + +use constant REQUIRED_VERSION => '20230912'; +my $detected_version = $Perl::Tidy::VERSION; +my @tidyall_argv = @ARGV; + +sub is_force_flag { $_ eq '--force' } + +unless ($detected_version == REQUIRED_VERSION) { + print STDERR "Incorrect version of perltidy.\n"; + printf STDERR "- Detected: %s\n+ Required: %s\n\n", $detected_version, REQUIRED_VERSION; + + my $force_run = grep { is_force_flag } @ARGV; + + unless ($force_run) { + printf STDERR "Please install the appropriate version of perltidy.\n"; + printf STDERR "If you want to proceed anyways, re run with --force flag.\n"; + exit 1; + } + + # tidyall does not know about the --force flag. + @tidyall_argv = grep { !is_force_flag } @tidyall_argv; + + print STDERR "Proceeding to run with incorrect version of perltidy. "; + print STDERR "Results might not be consistent.\n"; + print STDERR "==================\n"; +} + +exit exec('tidyall', @tidyall_argv);