From d995a897fa4cfd9ce7bbeb34e06f95f0914537a7 Mon Sep 17 00:00:00 2001 From: Eric Mueller Date: Tue, 23 May 2023 21:19:03 -0400 Subject: [PATCH 1/7] attempt a better README --- README.md | 144 +++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 122 insertions(+), 22 deletions(-) diff --git a/README.md b/README.md index 924a14c..b356c67 100644 --- a/README.md +++ b/README.md @@ -1,34 +1,134 @@ # QuietQuality +There are a lot of different tools that you need to run as you work - possibly before you commit, +or before you make a pull request, or after you make changes to a class.. style checkers, tests, +complexity metrics, static analyzers, etc. QuietQuality can make that simpler and faster! -Work in Progress +Or you may have a huge existing project, that's not _fully_ in compliance with your style guides, +but you want to avoid introducing _new_ issues, without having to first resolve all of the existing +ones. QuietQuality can help with that too. -But essentially, QuietQuality is intended for two purposes: +## Tool Support +So far, we have support for the following tools: -1. Let you conveniently run tools like rubocop, rspec, and standard against the _relevant_ - files locally (the files that have changed locally relative to the default branch) -2. Let you run those tools in CI (probably github actions) and annotate any issues found - with _new or modified_ code, without bothering you about existing issues that you didn't - touch. +* rubocop +* standardrb +* rspec +* haml-lint +* brakeman (though there's no way to run this against only changed files) +Supporting more tools is relatively straightforward - they're implemented by wrapping cli +invocations and parsing output files (which overall seem to be much more stable interfaces +than the code interfaces to the various tools), and each tool's support is built orthogonally +to the others, in a `QuietQuality::Tools::[Something]` namespace, with a `Runner` and a `Parser`. -Basic usage examples: +## Local Usage Examples +Working locally, you'll generally want to commit a `.quiet_quality.yml` configuration file into +the root of your repository - it'll specify which tools to run by default, and how to run them +(whether you want to only run each tool against the "changed files", whether to filter the +resulting messages down to only those targeting lines that have been changed), and allows you to +specify the 'comparison branch', so you don't have to make a request to your origin server every +time you run the tool to see whether you're comparing against `master` or `main` in this project. + +If you have a configuration set up like that, you might have details specified for `rubocop`, +`rspec`, `standardrb`, and `brakeman`, but have only `rubocop`, `standardrb`, and `rspec` set +to run by default. That configuration file would look like this: + +``` +--- +default_tools: ["standardrb", "rubocop", "rspec"] +executor: concurrent +comparison_branch: main +changed_files: true +filter_messages: true +brakeman: + changed_files: false + filter_messages: true +``` + +Then if you invoke `qq`, you'll see output like this: + +``` +❯ qq +--- Passed: standardrb +--- Passed: rubocop +--- Passed: rspec +``` + +But if you want to run brakeman, you could call `qq brakeman`: + +``` +❯ qq brakeman +--- Failed: brakeman + + +2 messages: + app/controllers/articles_controller.rb:3 [SQL Injection] Possible SQL injection + app/controllers/articles_controller.rb:11 [Remote Code Execution] `YAML.load` called with parameter value ``` -# you have five commits in your feature branch and 3 more files changes but not committed. -# this will run rubocop against all of those files. -qq rubocop -# run rspec against the changed specs, and annotate any failing specs (well, the first 10 -# of them) against the commit using github's inline output-based annotation approach. Which -# will of course only produce actual annotations if this happens to have been run in a -# github action. -qq rspec --annotate=github_stdout +## CI Usage Examples +Currently, QuietQuality is most useful from GitHub Actions - in that context, it's possible to +generate nice annotations for the analyzed commit (using Workflow Actions). But it can be used +from other CI systems as well, you just won't get nice annotations out of it (yet). -# run standardrb against all of the files (not just the changed ones). Still only print out -# problems to lines that have changed, so not particularly useful :-) -qq standard --all --incremental +For CI systems, you can either configure your execution entirely through command-line arguments, +or you can create additional configuration files and specify them on the command-line. -# run all of the tools against the entire repository, and print the first three messages -# out for each tool. -qq all --all --full --limit-per-tool=3 +Here is an invocation that executes rubocop and standardrb, expecting the full repository to pass +the latter, but not the former: + +``` +qq rubocop standardrb \ + --all-files --changed-files rubocop \ + --unfiltered --filter-messages rubocop \ + --comparison-branch main \ + --no-config \ + --executor serial \ + --annotate-github-stdout ``` + +Note the use of `--no-config`, to cause it to _not_ automatically load the `.quiet_quality.yml` +config included in the repository. + +Alternatively, we could have put all of that configuration into a config file like this: + +``` +# config/quiet_quality/linters_workflow.yml +--- +default_tools: ["standardrb", "rubocop"] +executor: serial +comparison_branch: main +changed_files: false +filter_messages: false + +rubocop: + changed_files: true + filter_messages: true +``` + +And then run `qq -C config/quiet_quality/linters_workflow.yml` + +# Available Options +The configuration file supports the following _global_ options (top-level keys): +* `executor`: 'serial' or 'concurrent' (the latter is the default) +* `annotator`: none set by default, and `github_stdout` is the only supported value so far. +* `comparison_branch`: by default, this will be _fetched_ from git, but that does require a remote + request. You should set this, it saves about half a second. This is normally 'main' or 'master', + but it could be 'trunk', or 'develop' - it is the branch that PR diffs are _against_. +* `changed_files`: defaults to false - should tools be run against only the files that have changed, + or against the entire repository? This is the global setting, but it is also settable per tool. +* `filter_messages`: defaults to false - should the resulting messages that do not refer to lines + that were changed or added relative to the comparison branch be skipped? Also possible to set + for each tool. + +And then each tool can have an entry, within which `changed_files` and `filter_messages` can be +specified - the tool-specific settings override the global ones. + +### CLI Options +The same options are all available on the CLI, plus some additional ones - run `qq --help` for a +detailed list of the options, but the notable additions are: + +* `--help/-H`: See a list of the options +* `--no-config/-N`: Do _not_ load a config file, even if present. +* `--config/-C` load the supplied config file (instead of the detected one, if found) From 969d34bd95f51bed3e21c74a93e2e19470820507 Mon Sep 17 00:00:00 2001 From: Eric Mueller Date: Wed, 24 May 2023 11:59:52 -0400 Subject: [PATCH 2/7] Add mdl to lint our readme file --- quiet_quality.gemspec | 1 + 1 file changed, 1 insertion(+) diff --git a/quiet_quality.gemspec b/quiet_quality.gemspec index 0485b15..941d119 100644 --- a/quiet_quality.gemspec +++ b/quiet_quality.gemspec @@ -41,4 +41,5 @@ Gem::Specification.new do |spec| spec.add_development_dependency "standard", "~> 1.28" spec.add_development_dependency "rubocop", "~> 1.50" spec.add_development_dependency "debug" + spec.add_development_dependency "mdl", "~> 0.12" end From 76f9d6ec1e2be442b6bf0dccc73d0766549578e0 Mon Sep 17 00:00:00 2001 From: Eric Mueller Date: Wed, 24 May 2023 12:01:20 -0400 Subject: [PATCH 3/7] configure mdl --- .mdl_rules.rb | 2 ++ .mdlrc | 2 ++ 2 files changed, 4 insertions(+) create mode 100644 .mdl_rules.rb create mode 100644 .mdlrc diff --git a/.mdl_rules.rb b/.mdl_rules.rb new file mode 100644 index 0000000..b66c5fd --- /dev/null +++ b/.mdl_rules.rb @@ -0,0 +1,2 @@ +all +rule "MD013", ignore_code_blocks: true diff --git a/.mdlrc b/.mdlrc new file mode 100644 index 0000000..9eedc91 --- /dev/null +++ b/.mdlrc @@ -0,0 +1,2 @@ +style File.expand_path("../.mdl_rules.rb", __FILE__) +git_recurse true From d9d6573a716af0906c5b0e92815c6b1c4aa16496 Mon Sep 17 00:00:00 2001 From: Eric Mueller Date: Wed, 24 May 2023 12:01:29 -0400 Subject: [PATCH 4/7] comply with markdown linting --- README.md | 123 +++++++++++++++++++++++----------------- docs/example-config.yml | 9 +++ 2 files changed, 81 insertions(+), 51 deletions(-) create mode 100644 docs/example-config.yml diff --git a/README.md b/README.md index b356c67..1a9d95b 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,17 @@ # QuietQuality -There are a lot of different tools that you need to run as you work - possibly before you commit, -or before you make a pull request, or after you make changes to a class.. style checkers, tests, -complexity metrics, static analyzers, etc. QuietQuality can make that simpler and faster! -Or you may have a huge existing project, that's not _fully_ in compliance with your style guides, -but you want to avoid introducing _new_ issues, without having to first resolve all of the existing -ones. QuietQuality can help with that too. +There are a lot of different tools that you need to run as you work - possibly +before you commit, or before you make a pull request, or after you make changes +to a class.. style checkers, tests, complexity metrics, static analyzers, etc. +QuietQuality can make that simpler and faster! + +Or you may have a huge existing project, that's not _fully_ in compliance with +your style guides, but you want to avoid introducing _new_ issues, without +having to first resolve all of the existing ones. QuietQuality can help with +that too. ## Tool Support + So far, we have support for the following tools: * rubocop @@ -16,24 +20,29 @@ So far, we have support for the following tools: * haml-lint * brakeman (though there's no way to run this against only changed files) -Supporting more tools is relatively straightforward - they're implemented by wrapping cli -invocations and parsing output files (which overall seem to be much more stable interfaces -than the code interfaces to the various tools), and each tool's support is built orthogonally -to the others, in a `QuietQuality::Tools::[Something]` namespace, with a `Runner` and a `Parser`. +Supporting more tools is relatively straightforward - they're implemented by +wrapping cli invocations and parsing output files (which overall seem to be much +more stable interfaces than the code interfaces to the various tools), and each +tool's support is built orthogonally to the others, in a +`QuietQuality::Tools::[Something]` namespace, with a `Runner` and a `Parser`. ## Local Usage Examples -Working locally, you'll generally want to commit a `.quiet_quality.yml` configuration file into -the root of your repository - it'll specify which tools to run by default, and how to run them -(whether you want to only run each tool against the "changed files", whether to filter the -resulting messages down to only those targeting lines that have been changed), and allows you to -specify the 'comparison branch', so you don't have to make a request to your origin server every -time you run the tool to see whether you're comparing against `master` or `main` in this project. - -If you have a configuration set up like that, you might have details specified for `rubocop`, -`rspec`, `standardrb`, and `brakeman`, but have only `rubocop`, `standardrb`, and `rspec` set -to run by default. That configuration file would look like this: -``` +Working locally, you'll generally want to commit a `.quiet_quality.yml` +configuration file into the root of your repository - it'll specify which tools +to run by default, and how to run them (whether you want to only run each tool +against the "changed files", whether to filter the resulting messages down to +only those targeting lines that have been changed), and allows you to specify +the 'comparison branch', so you don't have to make a request to your origin +server every time you run the tool to see whether you're comparing against +`master` or `main` in this project. + +If you have a configuration set up like that, you might have details specified +for `rubocop`, `rspec`, `standardrb`, and `brakeman`, but have only `rubocop`, +`standardrb`, and `rspec` set to run by default. That configuration file would +look like this (you can copy it from [here](docs/example-config.yml) + +```yaml --- default_tools: ["standardrb", "rubocop", "rspec"] executor: concurrent @@ -47,7 +56,7 @@ brakeman: Then if you invoke `qq`, you'll see output like this: -``` +```bash ❯ qq --- Passed: standardrb --- Passed: rubocop @@ -56,7 +65,7 @@ Then if you invoke `qq`, you'll see output like this: But if you want to run brakeman, you could call `qq brakeman`: -``` +```bash ❯ qq brakeman --- Failed: brakeman @@ -68,17 +77,20 @@ But if you want to run brakeman, you could call `qq brakeman`: ``` ## CI Usage Examples -Currently, QuietQuality is most useful from GitHub Actions - in that context, it's possible to -generate nice annotations for the analyzed commit (using Workflow Actions). But it can be used -from other CI systems as well, you just won't get nice annotations out of it (yet). -For CI systems, you can either configure your execution entirely through command-line arguments, -or you can create additional configuration files and specify them on the command-line. +Currently, QuietQuality is most useful from GitHub Actions - in that context, it's +possible to generate nice annotations for the analyzed commit (using Workflow +Actions). But it can be used from other CI systems as well, you just won't get +nice annotations out of it (yet). -Here is an invocation that executes rubocop and standardrb, expecting the full repository to pass -the latter, but not the former: +For CI systems, you can either configure your execution entirely through +command-line arguments, or you can create additional configuration files and +specify them on the command-line. -``` +Here is an invocation that executes rubocop and standardrb, expecting the full +repository to pass the latter, but not the former: + +```bash qq rubocop standardrb \ --all-files --changed-files rubocop \ --unfiltered --filter-messages rubocop \ @@ -88,12 +100,13 @@ qq rubocop standardrb \ --annotate-github-stdout ``` -Note the use of `--no-config`, to cause it to _not_ automatically load the `.quiet_quality.yml` -config included in the repository. +Note the use of `--no-config`, to cause it to _not_ automatically load the +`.quiet_quality.yml` config included in the repository. -Alternatively, we could have put all of that configuration into a config file like this: +Alternatively, we could have put all of that configuration into a config file +like this: -``` +```yaml # config/quiet_quality/linters_workflow.yml --- default_tools: ["standardrb", "rubocop"] @@ -109,26 +122,34 @@ rubocop: And then run `qq -C config/quiet_quality/linters_workflow.yml` -# Available Options +## Available Options + The configuration file supports the following _global_ options (top-level keys): + * `executor`: 'serial' or 'concurrent' (the latter is the default) -* `annotator`: none set by default, and `github_stdout` is the only supported value so far. -* `comparison_branch`: by default, this will be _fetched_ from git, but that does require a remote - request. You should set this, it saves about half a second. This is normally 'main' or 'master', - but it could be 'trunk', or 'develop' - it is the branch that PR diffs are _against_. -* `changed_files`: defaults to false - should tools be run against only the files that have changed, - or against the entire repository? This is the global setting, but it is also settable per tool. -* `filter_messages`: defaults to false - should the resulting messages that do not refer to lines - that were changed or added relative to the comparison branch be skipped? Also possible to set - for each tool. - -And then each tool can have an entry, within which `changed_files` and `filter_messages` can be -specified - the tool-specific settings override the global ones. +* `annotator`: none set by default, and `github_stdout` is the only supported + value so far. +* `comparison_branch`: by default, this will be _fetched_ from git, but that + does require a remote request. You should set this, it saves about half a + second. This is normally 'main' or 'master', but it could be 'trunk', or + 'develop' - it is the branch that PR diffs are _against_. +* `changed_files`: defaults to false - should tools be run against only the + files that have changed, or against the entire repository? This is the global + setting, but it is also settable per tool. +* `filter_messages`: defaults to false - should the resulting messages that do + not refer to lines that were changed or added relative to the comparison + branch be skipped? Also possible to set for each tool. + +And then each tool can have an entry, within which `changed_files` and +`filter_messages` can be specified - the tool-specific settings override the +global ones. ### CLI Options -The same options are all available on the CLI, plus some additional ones - run `qq --help` for a -detailed list of the options, but the notable additions are: + +The same options are all available on the CLI, plus some additional ones - run +`qq --help` for a detailed list of the options, but the notable additions are: * `--help/-H`: See a list of the options * `--no-config/-N`: Do _not_ load a config file, even if present. -* `--config/-C` load the supplied config file (instead of the detected one, if found) +* `--config/-C` load the supplied config file (instead of the detected one, if + found) diff --git a/docs/example-config.yml b/docs/example-config.yml new file mode 100644 index 0000000..1041227 --- /dev/null +++ b/docs/example-config.yml @@ -0,0 +1,9 @@ +--- +default_tools: ["standardrb", "rubocop", "rspec"] +executor: concurrent +comparison_branch: main +changed_files: true +filter_messages: true +brakeman: + changed_files: false + filter_messages: true From b94399d51d0338cadc1e732293956e8ff01e627d Mon Sep 17 00:00:00 2001 From: Eric Mueller Date: Wed, 24 May 2023 12:03:30 -0400 Subject: [PATCH 5/7] use italics to set off option-referencing text --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 1a9d95b..e9f81bc 100644 --- a/README.md +++ b/README.md @@ -31,9 +31,9 @@ tool's support is built orthogonally to the others, in a Working locally, you'll generally want to commit a `.quiet_quality.yml` configuration file into the root of your repository - it'll specify which tools to run by default, and how to run them (whether you want to only run each tool -against the "changed files", whether to filter the resulting messages down to -only those targeting lines that have been changed), and allows you to specify -the 'comparison branch', so you don't have to make a request to your origin +against the _changed files_, whether to _filter_ the resulting _messages_ down +to only those targeting lines that have been changed), and allows you to specify +the _comparison branch_, so you don't have to make a request to your origin server every time you run the tool to see whether you're comparing against `master` or `main` in this project. From 3b8bf530d04559ec5ada63da1b1667744894c908 Mon Sep 17 00:00:00 2001 From: Eric Mueller Date: Wed, 24 May 2023 12:05:42 -0400 Subject: [PATCH 6/7] run mdl in the linter github action --- .github/workflows/linters.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/linters.yml b/.github/workflows/linters.yml index 32e7789..0d52b9d 100644 --- a/.github/workflows/linters.yml +++ b/.github/workflows/linters.yml @@ -29,3 +29,6 @@ jobs: - name: Run rubocop (complexity checks) run: bundle exec rubocop --parallel + + - name: Run markdownlint + run: bundle exec mdl . From 0d13191f7970c2b4322d505096296281bcb30f30 Mon Sep 17 00:00:00 2001 From: Eric Mueller Date: Wed, 24 May 2023 12:06:50 -0400 Subject: [PATCH 7/7] fix punctuation --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index e9f81bc..b5e03de 100644 --- a/README.md +++ b/README.md @@ -40,7 +40,7 @@ server every time you run the tool to see whether you're comparing against If you have a configuration set up like that, you might have details specified for `rubocop`, `rspec`, `standardrb`, and `brakeman`, but have only `rubocop`, `standardrb`, and `rspec` set to run by default. That configuration file would -look like this (you can copy it from [here](docs/example-config.yml) +look like this (you can copy it from [here](docs/example-config.yml)): ```yaml ---