-
Notifications
You must be signed in to change notification settings - Fork 2
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
Extract ExternalCommand and CleanedOutput classes #63
Extract ExternalCommand and CleanedOutput classes #63
Conversation
README.md
Outdated
|
||
The main task this app performs is running the EveryPolitician build process as an external command and then creating a pull request with the output from the command. As such, one of the main classes in the system is the `ExternalCommand` class. This encapsulates running an external command, checking for errors and returning the output. | ||
|
||
To use this class create an instance of `ExternalCommand` and pass `command` and `end` keyword arguments to the constructor. The `command` should be a string representing the external command to execute, and `env` is an optional hash containing environment variables that should be set, or if they are `nil`, unset. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
typo: end → env
72ef3fe
to
f6ba631
Compare
This outlines the expected usage for the ExternalCommand class.
This class encapsulates running an external command and gathering up the output.
This class is responsible for taking the output from an external command and cleaning it up ready to be included in a GitHub comment.
3e309c4
to
c28d349
Compare
This simplifies the `RebuilderJob#perform` method quite a bit, and means that we're using tested classes, rather than just having a big ball of code.
c28d349
to
8e7e5cf
Compare
Rather than needing to override ENV we instead allow passing in a Morph API key, and then defaulting that to an environment variable.
Previously this was accidentally replacing every character with REDACTED when the API key was "".
Oops, requested a review before I'd updated the title and body. Fixed now. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yay! This is definitely a lot better. A few interface/implementation notes in-place
@@ -49,36 +50,28 @@ def perform(country_slug, legislature_slug, source = nil) | |||
branch_parts = [country_slug, legislature_slug, Time.now.to_i] | |||
branch = branch_parts.join('-').parameterize | |||
message = "#{country.name}: Refresh from upstream changes" | |||
output = '' | |||
child_status = nil | |||
command = nil |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This raises a few warning signs to me. In general, assigning a placeholder that you're going to re-assign later is quite suspicious, and here's not really obvious why it's needed.
I think it's also a little badly named, as it's named for what it is (which is obvious as it's going be an ExternalCommand object), rather than what it's doing (i.e. it's like naming your variables integer
or string
), and leads to some confusion when it's later used again at line 68, even though there's been several other commands executed in the meantime.
Perhaps it would be clearer and simpler to hoist the declaration of this command (if not others) out of within the with_git_repo
blocks, and then only trigger the .run
inside?
require 'colorize' | ||
|
||
class CleanedOutput | ||
def initialize(output:, morph_api_key: ENV['MORPH_API_KEY']) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it feels a little odd to me to have this class so tightly coupled to Morph-specific concepts like this, or for a class like this to be peering into ENV. This seems like it would be a lot more extensible if the argument here was something like redact: *strings
, for a list of things you want redacted in the output.
|
||
attr_reader :output, :morph_api_key | ||
|
||
def cleaned_output |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is overloading what 'cleaned' means in a slightly odd way, where cleaned_output
here is something different to the CleanedOutput
of the class. This is really just the original output with redactions applied.
end | ||
|
||
def to_s | ||
(cleaned_output[-64_000..-1] || cleaned_output).uncolorize |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suspect this would be a little clearer if the truncation code were pulled out into its own method.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The magic number here should probably be hoisted out. (We'd probably want to take the size as an optional constructor argument too, but I'm OK with leaving that part to a later enhancement if it's not as trivial as it seems it should be)
This pull request has got a bit large for my liking. I've broken off the |
#64 has now been merge into |
This adds two new classes,
ExternalCommand
, which runs external commands and captures their output, andCleanedOutput
, which cleans up the output from external commands ready for inclusion in a pull request.Fixes #43
Fixes #45
Part of #62