Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fail Rubocop on warn logging #11458

Merged
merged 9 commits into from
Nov 8, 2024
Merged

Fail Rubocop on warn logging #11458

merged 9 commits into from
Nov 8, 2024

Conversation

aduth
Copy link
Member

@aduth aduth commented Nov 5, 2024

🛠 Summary of changes

Updates Rubocop to fail the build if there are any warning messages emitted.

Rubocop may warn when there's incorrect usage, but it doesn't trigger a failure. The changes here override Kernel#warn in the context of Rubocop linting to exit with a non-zero exit code.

📜 Testing Plan

Prior to fix, verify that the build fails, including an error message. (Edit: See https://gitlab.login.gov/lg/identity-idp/-/jobs/1513614)

Example:

Error: Unexpected warn logging occurred:

lib/identity_config.rb: Metrics/LineLength has the wrong namespace - replace it with Layout/LineLength

aduth added 2 commits November 5, 2024 16:51
changelog: Internal, Automated Testing, Fail static analysis linting when warning messages emitted
@aduth
Copy link
Member Author

aduth commented Nov 6, 2024

I think this is failing as expected: https://gitlab.login.gov/lg/identity-idp/-/jobs/1513614

Though it also includes an additional warning I wasn't expecting about Parallel::DeadWorker

Error: Unexpected warn logging occurred:
lib/identity_config.rb: Metrics/LineLength has the wrong namespace - replace it with Layout/LineLength
Error: Unexpected warn logging occurred:
Parallel::DeadWorker

It might be a result of calling exit. Could be okay? A little distracting to have that included as well though.

Alternatively, could look at raising an exception, or curious if there's some equivalent of Node.js's process.exitCode assignment for Ruby (i.e. set the exit code, but don't end the process immediately). I wasn't able to find one. I experimented with raising an exception and it does work, but the output is much noisier since it includes a full stack trace, and the actual warning message is hard to find in the output.

@aduth aduth marked this pull request as ready for review November 6, 2024 16:09
@@ -0,0 +1,12 @@
# frozen_string_literal: true

module Kernel
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. I might document this with a comment? Big change in behavior from typical Ruby
  2. This seems like a lib/core_ext kinda file to me, I would move it there? Since lib is not autoloaded it should be safe
Suggested change
module Kernel
# Module that overrides Kernel#warn to immediately exit
# Should NOT be included in normal web server mode, is only used in specific scripts
module Kernel

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, good point on both counts. I'll make those updates.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would rather we not do this. This is an extreme change to Ruby's default behavior.

Instead, can we:

  1. Disable cache so that we always get the warning output and consume that output to change the exit code OR
  2. Write a cop to detect this specific issue.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@lmgeorge What do you think of the updated approach? I think it's an improvement. I hadn't realized that these warnings were being emitted to stderr, so it becomes a test of "fail if there's any stderr".

Example build failure: https://gitlab.login.gov/lg/identity-idp/-/jobs/1515745

Example output:

--- rubocop ---
mkdir -p tmp
bundle exec rubocop --parallel --format progress --format junit --out rubocop.xml --display-only-failed --color 2> tmp/rubocop.txt
Inspecting 2259 files
.......
2259 files inspected, no offenses detected
[ -s tmp/rubocop.txt ] && (printf "Error: Unexpected stderr output from Rubocop\n"; cat tmp/rubocop.txt; exit 1)
Error: Unexpected stderr output from Rubocop
lib/identity_config.rb: Metrics/LineLength has the wrong namespace - replace it with Layout/LineLength
lib/identity_config.rb: Metrics/LineLength has the wrong namespace - replace it with Layout/LineLength
make: *** [Makefile:71: lint] Error 1

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I sort of lean towards @lmgeorge's concerns on this in that the change feels pretty heavy (though limited in scope) for the upside. The only alternative I have is to grep the output for the message we don't expect to see. It's not quite the same though. I don't intend for this to be a blocking suggestion since anything going sideways on this will hopefully be pretty apparent.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mitchellhenke I've since changed from the initial approach in recent commits.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@aduth I can agree with this approach of grepping the stderr output.

My main concern is that it can be easy to see an existing pattern and replicate it elsewhere even when strong language in the form of doc comments warn (heh) against it. I think this new approach addresses that concern. Thank you for being willing to flex on this!

@@ -0,0 +1,12 @@
# frozen_string_literal: true

module Kernel
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would rather we not do this. This is an extreme change to Ruby's default behavior.

Instead, can we:

  1. Disable cache so that we always get the warning output and consume that output to change the exit code OR
  2. Write a cop to detect this specific issue.

@aduth aduth marked this pull request as draft November 6, 2024 21:36
@aduth aduth marked this pull request as ready for review November 6, 2024 22:00
@aduth aduth requested a review from lmgeorge November 6, 2024 22:00
Previous didn't seem to work in CI, always exited even with empty file?
@aduth aduth merged commit 22e2ab2 into main Nov 8, 2024
2 checks passed
@aduth aduth deleted the aduth-rubocop-strict-warning branch November 8, 2024 16:09
@aduth aduth mentioned this pull request Nov 12, 2024
@matthinz
Copy link
Member

matthinz commented Dec 6, 2024

I think I'm seeing a difference in how this behaves in CI. Basically, I have a job that is failing the lint phase, but the CI logs don't include the output from tmp/rubocop.txt.

I added the rubocop.txt file to the gitlab artifacts and downloaded it to verify that it is present. I think there might be a difference in how the make running inside the CI docker container behaves compared to the one installed on my laptop.

@aduth
Copy link
Member Author

aduth commented Dec 6, 2024

@matthinz Interesting, yeah. I think the tmp/rubocop.txt artifact points to the problem, but I would expect that to be output in the build log, which doesn't appear to be working as expected there.

Maybe it's because it doesn't actually get far enough to the awk command: a combination of the rubocop command exits with non-0 status code, but the stderr is being put into tmp/rubocop.txt instead.

Maybe we can tolerate the non-0 status code result , like throwing a || true somewhere in there? Then it'll still fail once it reaches the awk line, but at least output the failure reason.

@aduth
Copy link
Member Author

aduth commented Dec 13, 2024

Continuing issue with tmp/rubocop.txt output here: #11642

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants