Skip to content

Instantly share code, notes, and snippets.

@wteuber
Created January 23, 2025 17:37
Show Gist options
  • Save wteuber/9dd0502601f8dd7cbd6add10cf5aa6d2 to your computer and use it in GitHub Desktop.
Save wteuber/9dd0502601f8dd7cbd6add10cf5aa6d2 to your computer and use it in GitHub Desktop.
Ruby namespace checker
#!/usr/bin/env ruby
# frozen_string_literal: true
# Example usage:
# ./check_namespaces.rb
# for dir in */; do (cd "$dir" && ../check_namespaces.rb); done
require "parser/current"
require "pathname"
def namespaces(file_path)
content = File.read(file_path)
buffer = Parser::Source::Buffer.new(file_path)
buffer.source = content
parser = Parser::CurrentRuby.new
ast = parser.parse(buffer)
namespaces = []
find_namespaces = lambda do |node, current_namespace = []|
return unless node.is_a?(Parser::AST::Node)
case node.type
when :module, :class
name = extract_const_name(node.children[0])
current_namespace.push(name)
namespaces << current_namespace.join("::")
end
node.children.each { |child| find_namespaces.call(child, current_namespace.dup) }
end
find_namespaces.call(ast)
namespaces
end
def extract_const_name(node)
return unless node.is_a?(Parser::AST::Node)
names = []
while node && node.type == :const
names.unshift(node.children[1].to_s)
node = node.children[0]
end
names.join("::")
end
def check_compatibility(file_path)
path_parts = Pathname(file_path).dirname.to_s.split(File::SEPARATOR).reject { |part| ["."].include?(part) }
expected_modules = path_parts.map { |part| part.split("_").map(&:capitalize).join }
expected_class = File.basename(file_path, ".rb").split("_").map(&:capitalize).join
expected_namespace = (expected_modules + [expected_class]).join("::")
namespaces = namespaces(file_path)
if !namespaces.include?(expected_namespace)
puts "❌ #{file_path}"
puts " Expected: #{expected_namespace}"
puts " Found: #{namespaces.join(", ")}"
else
puts "✅ #{file_path}"
end
end
def find_ruby_files(dir)
Dir.glob("#{dir}/**/*.rb")
end
root_dir = "."
files = find_ruby_files(root_dir)
files.each do |file|
check_compatibility(file)
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment