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

Add settings checks #41

Merged

Conversation

gingermusketeer
Copy link
Member

@gingermusketeer gingermusketeer commented Oct 21, 2017

Let me know what you think of this fix for #32.

Note: This removes the eval of the dot file in favor of manually parsing the config file.

Remaining changes:

  • Tests

@gingermusketeer
Copy link
Member Author

When config value is invalid:
screen shot 2017-10-20 at 10 49 29 pm
When config is unknown:
screen shot 2017-10-20 at 10 49 15 pm

@mjago
Copy link
Member

mjago commented Oct 21, 2017

@gingermusketeer 👍 Looks good in principle. It would be good to see a benchmark as a speed increase would be great 😃 . I guess config versioning could be implemented also ref: #32.

@gingermusketeer
Copy link
Member Author

@mjago How do you normally go about benchmarking rufo? Would it make sense to have some tools for this in the codebase?

Copy link
Member

@splattael splattael left a comment

Choose a reason for hiding this comment

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

Overall, I like it 👍 Thank you 💛

I've left some comments though.

default = valid_options.first
value = options.fetch(name, default)
unless valid_options.include?(value)
STDERR.puts "invalid value for #{name}: #{value}. Valid values are: " \
Copy link
Member

Choose a reason for hiding this comment

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

Inspect value like in

STDERR.puts "invalid value for #{name}: #{value.inspect}

value = options.fetch(name, default)
unless valid_options.include?(value)
STDERR.puts "invalid value for #{name}: #{value}. Valid values are: " \
"#{valid_options.join(', ')}"
Copy link
Member

Choose a reason for hiding this comment

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

Inspect valid options:

"#{valid_options.map(&:inspect).join(', ')}"

Before: Valid values are: dynamic, one
After: Valid values are: :dynamic, :one

def double_newline_inside_type(value)
@double_newline_inside_type = no_dynamic("double_newline_inside_type", value)
end
attr_accessor *OPTIONS.keys
Copy link
Member

Choose a reason for hiding this comment

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

Do we need real setters and getters?

Currently, these are just instance variables.

"#{valid_options.join(', ')}"
value = default
end
self.send("#{name}=", value)
Copy link
Member

Choose a reason for hiding this comment

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

This should change to instance_variable_set if we want to avoid attr_accessor above.

end

formatter.format
formatter.result
end

def parse_dot_file(file_contents)
file_contents.lines
Copy link
Member

Choose a reason for hiding this comment

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

How about using each_with_object and split config line in exact 2 parts?

    file_contents.lines
                 .map { |s| s.strip.split(/\s+/, 2) }
                 .each_with_object({}) do |(name, value), acc|
      if value.start_with?(':')
        value = value[1..-1].to_sym
      elsif value == 'true'
        value = true
      elsif value == 'false'
        value = false
      else
        STDERR.puts "Unknown config value=#{value.inspect} for #{name.inspect}"
        next
      end
      acc[name.to_sym] = value
    end

@mjago
Copy link
Member

mjago commented Oct 24, 2017

@gingermusketeer re. benchmarking I usually use a project with a large number of ruby files as the test to magnify the parsing speed value. Then in git I reset any changes made to the project by Rufo to reset the start position. One such large project is ruby/spec (5000 or so files).

@gingermusketeer
Copy link
Member Author

I did a little benchmarking on this looks to be a slight improvement of 2-4 seconds for a set of 10 runs against the ruby/spec code base.

Copy link
Member

@bessey bessey left a comment

Choose a reason for hiding this comment

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

Reading this PR called to my attention some existing issues that kinda fall in the scope of it, so I made some suggestions, however I don't consider any of them blockers to merge. If you disagree or don't want to expand the scope of the PR, do ignore me 😄

"values are: #{valid_options.map(&:inspect).join(', ')}"
value = default
end
self.instance_variable_set("@#{name}", value)
Copy link
Member

Choose a reason for hiding this comment

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

Relying on instance variables seems error prone to me, leaves us open to typoing the setting entirely in the formatter and not realising it. What about adding

attr_accessor *OPTIONS.keys

... to the class, and replacing this with

public_send(name, value)

and then referring to these settings by their methods rather than instance variables in the formatter?

Copy link
Member

Choose a reason for hiding this comment

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

Side note, this isn't you, but having rufo/formatter/settings.rb reopen an existing class and add methods to it had me very confused. How about this is instead a Rufo::Settings module that is mixed into Rufo::Formatter explicitly?

Why: So that accessing non existent settings raises a no method error.
@gingermusketeer
Copy link
Member Author

@bessey Thanks for the feedback. I think that makes sense so I have gone a head and changed it.

Your first bit of feedback is counter to something that was touched on in some earlier feedback. I think you do have a good point about relying on instance variables and I have changed the formatter code so that we get the benefit. @splattael Be good to get your input on the last few commits.

Copy link
Member

@splattael splattael left a comment

Choose a reason for hiding this comment

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

Looks very good 👍

Thank you 💜

@bessey
Copy link
Member

bessey commented Nov 1, 2017

Oops, sorry to have introduced conflict. I tend to avoid @instance_vars since a typo can creep in silently, but admittedly in a code base as well tested as rufo, that may be less of a concern than it usually is to me.

Thank you for making the changes nonetheless!

Copy link
Member

@bessey bessey left a comment

Choose a reason for hiding this comment

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

I'd love to merge this but will wait for 1 more approval perhaps

Copy link
Member

@mjago mjago left a comment

Choose a reason for hiding this comment

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

Looks good to me 👍

@gingermusketeer
Copy link
Member Author

Going to merge this. Let me know if anything else needs addressing and I will do that in a subsequent PR.

@gingermusketeer gingermusketeer merged commit e333d0f into ruby-formatter:master Nov 4, 2017
@gingermusketeer gingermusketeer deleted the add-settings-checks branch November 4, 2017 12:54
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.

4 participants