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

Extract ExternalCommand and CleanedOutput classes #63

Closed

Conversation

chrismytton
Copy link
Contributor

@chrismytton chrismytton commented Feb 7, 2017

This adds two new classes, ExternalCommand, which runs external commands and captures their output, and CleanedOutput, which cleans up the output from external commands ready for inclusion in a pull request.

Fixes #43
Fixes #45
Part of #62

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.
Copy link
Contributor

Choose a reason for hiding this comment

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

typo: end → env

@chrismytton chrismytton force-pushed the 45-extract-class-for-running-external-commands branch from 72ef3fe to f6ba631 Compare February 8, 2017 09:29
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.
@chrismytton chrismytton force-pushed the 45-extract-class-for-running-external-commands branch from 3e309c4 to c28d349 Compare February 8, 2017 10:57
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.
@chrismytton chrismytton force-pushed the 45-extract-class-for-running-external-commands branch from c28d349 to 8e7e5cf Compare February 8, 2017 11:50
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 "".
@chrismytton chrismytton requested a review from tmtmtmtm February 8, 2017 12:29
@chrismytton chrismytton changed the title [WIP] Extract ExternalCommand class Extract ExternalCommand and CleanedOutput classes Feb 8, 2017
@chrismytton
Copy link
Contributor Author

Oops, requested a review before I'd updated the title and body. Fixed now.

Copy link
Contributor

@tmtmtmtm tmtmtmtm left a 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
Copy link
Contributor

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'])
Copy link
Contributor

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
Copy link
Contributor

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
Copy link
Contributor

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.

Copy link
Contributor

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)

@chrismytton
Copy link
Contributor Author

This pull request has got a bit large for my liking. I've broken off the CleanedOutput change into #64 so that can be reviewed separately. That pull request addresses the feedback on the CleanedOutput class from above.

@chrismytton
Copy link
Contributor Author

#64 has now been merge into master, that contains the output cleaner part of this PR. So the next step is to pull the external command bits into another branch off master.

@chrismytton
Copy link
Contributor Author

CleanedOutput work was done in #64 and #65. The ExternalCommand work is being done in #72. So this PR is now redundant.

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.

2 participants