-
-
Save jbrains/9451941 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# SMELL I don't like the name gemfile_lock_file, but I don't know | |
# what else to call it. I want to distinguish it from Gemfile. | |
def extract_gems_from_gemfile_lock_file(contents) | |
gems = [] | |
# Extract all the non-empty lines between and excluding 'specs:' and 'PLATFORMS' | |
contents.each_line do |line| | |
line = line.strip | |
# It takes a few seconds to understand this algorithm, | |
# but I can't yet justify replacing it with a functional | |
# approach. Again, it depends what the reader understands | |
# better. | |
# If we're going to let iterating and filtering stay | |
# intertwined like this, I'm glad we've separated it from | |
# the rest of the code. | |
break if line.include?("PLATFORMS") | |
next if line.include?("GEM") | |
next if line.include?("remote:") | |
next if line.include?("specs:") | |
next if line.empty? | |
gems.push(line.split(' ').first) | |
end | |
return gems | |
end | |
# Guess what? Now independent of "gem" concept. More reusable. MAGIC! | |
# Guess what? Almost dead-simple wrapper around command line tool. Cohesive. SRP. Nice. | |
def count_lines_in_file(file) | |
output = `wc -l #{file}` | |
# ASSERT: output is of the form <whitespace><line count><whitespace><filename> | |
# We could turn this comment into code by matching with a regex, which some | |
# would find clearer and others less clear. I could do either. | |
line_count_text = output.strip.split(' ').first | |
return line_count_text.to_i | |
end | |
# SMELL Depends on globals like 'puts' and `` (execute process). | |
def count_lines_for_gem(gem) | |
puts "Processing #{gem}" | |
gem_filenames = `gem contents #{gem}`.split | |
# If you prefer to 'inject', then feel free to 'inject'. | |
# Either way, the name duplication disappears. | |
line_count_for_this_gem = gem_filenames.map { |each| count_lines_in_file(each) }.reduce(:+) | |
puts " LOC: #{line_count_for_this_gem}" | |
return line_count_for_this_gem | |
end | |
total = extract_gems_from_gemfile_lock_file(File.read("Gemfile.lock")) | |
.map { |each| count_lines_for_gem(each) }.reduce(:+) | |
puts "Total Lines: #{total}" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
If you don't care about the interim line count in each gem, then we can remove the duplicate
count_lines
concept, replacing the whole thing with this, in approximate Haskell, of course: