class RuboCop::Cop::Rails::RootPathnameMethods
rubocop:disable Metrics/ClassLength
Rails.root.glob(“db/schema.rb”)
Rails.root.join(‘db’, ‘schema.rb’).binwrite(content)
Rails.root.join(‘db’, ‘schema.rb’).write(content)
Rails.root.join(‘db’, ‘schema.rb’).binread
Rails.root.join(‘db’, ‘schema.rb’).read
Rails.root.join(‘db’, ‘schema.rb’).open(‘w’)
Rails.root.join(‘db’, ‘schema.rb’).open
# good
Dir[Rails.root.join(‘db’, ‘schema.rb’)]
Dir.glob(Rails.root.join(‘db’, ‘schema.rb’))
File.binwrite(Rails.root.join(‘db’, ‘schema.rb’), content)
File.write(Rails.root.join(‘db’, ‘schema.rb’), content)
File.binread(Rails.root.join(‘db’, ‘schema.rb’))
File.read(Rails.root.join(‘db’, ‘schema.rb’))
File.open(Rails.root.join(‘db’, ‘schema.rb’), ‘w’)
File.open(Rails.root.join(‘db’, ‘schema.rb’))
# bad
@example
methods return string element, but these methods of ‘Pathname` return `Pathname` element.
This cop is unsafe for autocorrection because “Dir“’s ‘children`, `each_child`, `entries`, and `glob`
@safety
`Style/FileRead`, `Style/FileWrite` and `Rails/RootJoinChain`.
This cop works best when used together with
so we can apply many IO methods directly.
`Rails.root` is an instance of `Pathname`
Use `Rails.root` IO methods instead of passing it to `File`.
def build_path_glob_replacement(path)
def build_path_glob_replacement(path) receiver = range_between(path.source_range.begin_pos, path.children.first.loc.selector.end_pos).source argument = path.arguments.one? ? path.first_argument.source : join_arguments(path.arguments) "#{receiver}.glob(#{argument})" end
def build_path_replacement(path, method, args)
def build_path_replacement(path, method, args) path_replacement = path.source if path.arguments? && !path.parenthesized_call? path_replacement[' '] = '(' path_replacement << ')' end replacement = "#{path_replacement}.#{method}" if args.any? formatted_args = args.map { |arg| arg.array_type? ? "*#{arg.source}" : arg.source } replacement += "(#{formatted_args.join(', ')})" end replacement end
def enforce_double_quotes?
def enforce_double_quotes? string_literals_config['EnforcedStyle'] == 'double_quotes' end
def evidence(node)
def evidence(node) return if node.method?(:open) && node.parent&.send_type? return unless (method, path, args = pathname_method(node)) && (rails_root = rails_root_pathname?(path)) yield(method, path, args, rails_root) end
def include_interpolation?(arguments)
def include_interpolation?(arguments) arguments.any? do |argument| argument.children.any? { |child| child.respond_to?(:begin_type?) && child.begin_type? } end end
def join_arguments(arguments)
def join_arguments(arguments) use_interpolation = false joined_arguments = arguments.map do |arg| if arg.respond_to?(:value) arg.value else use_interpolation = true "\#{#{arg.source}}" end end.join('/') quote = enforce_double_quotes? || include_interpolation?(arguments) || use_interpolation ? '"' : "'" "#{quote}#{joined_arguments}#{quote}" end
def on_send(node)
def on_send(node) evidence(node) do |method, path, args, rails_root| replacement = if dir_glob?(node) build_path_glob_replacement(path) else build_path_replacement(path, method, args) end message = format(MSG, rails_root: rails_root.source, replacement: replacement) add_offense(node, message: message) do |corrector| corrector.replace(node, replacement) end end end
def pathname_method(node)
def pathname_method(node) if target_ruby_version >= 2.5 pathname_method_for_ruby_2_5_or_higher(node) else pathname_method_for_ruby_2_4_or_lower(node) end end
def string_literals_config
def string_literals_config config.for_cop('Style/StringLiterals') end