OpenC3/cosmos

View on GitHub
openc3/bin/rubysloc

Summary

Maintainability
Test Coverage
#!/usr/bin/env ruby
# encoding: ascii-8bit

# Copyright 2022 Ball Aerospace & Technologies Corp.
# All Rights Reserved.
#
# This program is free software; you can modify and/or redistribute it
# under the terms of the GNU Affero General Public License
# as published by the Free Software Foundation; version 3 with
# attribution addendums as found in the LICENSE.txt
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Affero General Public License for more details.

# Modified by OpenC3, Inc.
# All changes Copyright 2022, OpenC3, Inc.
# All Rights Reserved
#
# This file may also be used under the terms of a commercial license 
# if purchased from OpenC3, Inc.

# This file provides a simple ruby sloc counter.
# Blank lines and comment lines are ignored.  All other
# lines count as one line.

require 'ostruct'
require 'optparse'

options = OpenStruct.new
options.filename = nil
options.sort_column = nil

opts = OptionParser.new do |opts|
  opts.banner = "Usage: rubysloc"
  opts.separator ""
  opts.separator "Recursively calculate SLOC for all ruby files (*.rb) sorted by filename"
  opts.separator ""
  opts.on("-h", "--help", "Show this message") do
    puts opts
    exit
  end
  opts.on("-i DIRECTORY/FILENAME", "--input DIRECTORY/FILENAME",
          "Parse only the specified directory/filename (relative or absolute path)") do |arg|
    options.filename = arg
  end
  opts.on("-s SORT", "--sort SORT", "Sort by the specified column. Must be one of LINES, COMMENTS, SLOC, or RATIO.") do |arg|
    case arg
    when 'LINES'
      options.sort_column = 1
    when 'COMMENTS'
      options.sort_column = 2
    when 'SLOC'
      options.sort_column = 3
    when 'RATIO'
      options.sort_column = 4
    else
      puts opts
      exit
    end
  end
end

begin
  opts.parse!(ARGV)
rescue => err
  puts err
  puts opts
  exit
end

files = []
if options.filename
  options.filename = File.join(Dir.pwd, options.filename) unless File.exist?(options.filename)
  if File.exist?(options.filename)
    if File.directory?(options.filename)
      # Dir only works with unix paths so swap backslashes
      files = Dir[File.join(options.filename.gsub('\\', '/'), '**', '*.rb')]
    else
      files << options.filename
    end
  else
    puts "File #{options.filename} not found."
    puts opts
    exit
  end
else
  files = Dir['**/*.rb']
end

# Build results over all found ruby files
longest_path = 1
results = []
files.each do |full_filename|
  filename = File.basename(full_filename)
  File.open(full_filename, 'r') do |file|
    lines    = 0
    slocs    = 0
    comments = 0
    file.each_line do |line|
      lines += 1
      split_line = line.split
      if split_line[0].nil?
        # Blank Line - Do Nothing
      elsif split_line[0].to_s[0..0] == '#'
        comments += 1
      else
        slocs += 1
      end
    end
    results << [full_filename, lines, comments, slocs, comments.to_f / slocs.to_f]
    longest_path = full_filename.length if full_filename.length > longest_path
  end
end

results.sort_by! { |col| col[options.sort_column].finite? ? col[options.sort_column] : -1 } if options.sort_column

# Print results to STDOUT
total_files    = 0
total_lines    = 0
total_comments = 0
total_slocs    = 0
total_ratio    = 0

puts sprintf("|-%-#{longest_path}s-|----------|----------|----------|--------|", "-" * longest_path)
puts sprintf("| %-#{longest_path}s |  Lines   | Comments |  SLOCs   |  Ratio |", "Filename")
puts sprintf("|-%-#{longest_path}s-|----------|----------|----------|--------|", "-" * longest_path)
results.each do |filename, lines, comments, slocs, ratio|
  # filename = filename[0..32] if filename.length > 33
  puts sprintf("| %-#{longest_path}s | %8d | %8d | %8d | %6.2f |",
               filename, lines, comments, slocs, ratio)
  total_files    += 1
  total_lines    += lines
  total_comments += comments
  total_slocs    += slocs
end
total_ratio = total_comments.to_f / total_slocs.to_f if total_slocs != 0
puts sprintf("|-%-#{longest_path}s-|----------|----------|----------|--------|", "-" * longest_path)
puts sprintf("| %-#{longest_path}s | %8d | %8d | %8d | %6.2f |",
             "Totals - #{total_files} Files", total_lines, total_comments, total_slocs, total_ratio)
puts sprintf("|-%-#{longest_path}s-|----------|----------|----------|--------|", "-" * longest_path)