refactor: use generator methods, and class instance variables to separate duties between classes#143
refactor: use generator methods, and class instance variables to separate duties between classes#143
Conversation
…rate duties between classes
| Style/ClassVars: | ||
| Enabled: false | ||
|
|
||
| Style/GlobalVars: |
There was a problem hiding this comment.
The proscription against class and global variables is in general pretty sensible. I haven't yet digested enough of this PR to know whether they can be done without, but if not, I think the Rubocop checks should be disabled on a linewise basis rather than disabling them globally. For example, one a line with a global variable like $options, you can append a comment:
# rubocop:disable Style/GlobalVars
...to turn off the warning for that line only. It's a bit noisy, but I think it's better to draw attention to places where the usual style rules are being overridden by necessity.
...Also, when I check out your branch and search the codebase for the string @@, I don't find any instances. I would expect to find some if Ruby class variables are being employed somewhere. Is it actually necessary to disable the Style/ClassVars rule at all?
| def any_resource_instance | ||
| resource_instances.first | ||
| def initialize(options) | ||
| $options = options |
There was a problem hiding this comment.
The original code stored the options in an instance variable rather than a global variable, which would be the more normal practice. This PR is a little large for me to take in all at once, so I'll just ask here: What other code needs to access the options passed in here via the global variable $options?
...Coming back to this comment a bit later, I have some ideas for how to minimize the drawbacks of the use of a global variable. (That is, if its use can't be easily eliminated.)
First, it would be cleaner if the code that instantiates the DatadogBackup::Cli object assigns the options to the global variable rather than leaving it up to the class to do it. I see the code that does the instantiation in bin/datadog_backup:
DatadogBackup::Cli.new(prereqs(defaults)).run!
I'd suggest instead something like:
$options = prereqs(defaults).freeze
DatadogBackup::Cli.new($options).run!
I see also that the Cli class only cares about the resources, force_restore, and action option values. The class could be constructed in a more standard style be storing these as instance variables in the class.
def initialize(resources:, force_restore:, action:, **)
@resources = resources
@force_restore = force_restore
@action = action
end
(The ** will cause any unknown keys in the hash to be ignored.)
Then in the rest of the class you can write just @resources instead of $options[:resources], and likewise for the other keys.
The above only applies if no other code is going to update the options on the fly, which appears to be the case.
| def diffs | ||
| $options[:resources].each do |resource| | ||
| resource.all.each do |resource_instance| | ||
| next if resource_instance.diff.nil? || resource_instance.diff.empty? |
There was a problem hiding this comment.
It doesn't seem like ActiveSupport is available in this repo...? If it is, you can combine these two tests into just:
next if resource_instance.diff.blank?
| outhash.delete(key) # delete returns the value at the deleted key, hence the tap wrapper | ||
| end | ||
| outhash | ||
| end |
There was a problem hiding this comment.
This method could be more concisely implemented as:
@banlist.each_with_object(hash.dup) do |key, outhash|
outhash.delete(key)
end
| file.write(data) | ||
| ensure | ||
| file.close | ||
| end |
There was a problem hiding this comment.
The File.open method can be given a block, and will take care of closing the file afterwards:
::File.open(filename, 'w') do |file|
file.write(data)
end
|
|
||
| def initialize | ||
| @client = Faraday.new( | ||
| url: ENV.fetch('DD_SITE_URL', 'https://api.datadoghq.com/'), |
There was a problem hiding this comment.
The default url might be better stored as a class constant, eg:
DEFAULT_DD_SITE_URL = 'https://api.datadoghq.com/'
And later:
url: ENV.fetch('DD_SITE_URL', DEFAULT_DD_SITE_URL)
| @all ||= get_all.map do |resource| | ||
| new_resource(id: resource.fetch(@id_keyname), body: resource) | ||
| end | ||
| LOGGER.info "Found #{@all.length} #{@api_resource_name}s in Datadog" |
There was a problem hiding this comment.
This logging will happen even if the get_all response has already been cached in the @all instance variable. Is that intended?
| @get_all = @dig_in_list_body ? body.fetch(*@dig_in_list_body) : body | ||
| end | ||
|
|
||
| # Fetch the specified resource from Datadog and remove the @banlist elements |
There was a problem hiding this comment.
Is this comment accurate? The method is very short and doesn't seem to affect @banlist at all.
| end | ||
|
|
||
| def backup_all | ||
| all.map(&:backup) |
There was a problem hiding this comment.
I see only one place backup_all is called, and the result is discarded. If the result of calling backup is not needed, you can signal that more explicitly by saying all.each(&:backup) here.
| class Resources | ||
| ## | ||
| # Meant to be mixed into DatadogBackup::Resources | ||
| # Relies on $options[:backup_dir] and $options[:output_format] |
There was a problem hiding this comment.
I don't see $options[:backup_dir] mentioned in this file; is this comment accurate?
| @@ -3,142 +3,4 @@ | |||
| require 'spec_helper' | |||
|
|
|||
| describe DatadogBackup::Cli do | |||
There was a problem hiding this comment.
This file is now nearly empty and does no testing; can it be removed?
| @@ -0,0 +1,4 @@ | |||
| # frozen_string_literal: true | |||
|
|
|||
| describe DatadogBackup::Client do | |||
There was a problem hiding this comment.
Is this file necessary? It doesn't seem to do anything.
| @strategy = FactoryBot.strategy_by_name(:create).new | ||
| end | ||
|
|
||
| #delegate :association, to: :@strategy |
There was a problem hiding this comment.
Better to just delete this line probably.
|
To keep it open, please leave a comment or push an update. You can also label it as 'pinned' to prevent auto-closure. |
Uses the factory method to manage the differences and commonalities in the DataDog API.
The major features of this refactor are:
TODO: