#!/usr/bin/env ruby begin # First, try to load our files from the source tree $: << "#{File.dirname(__FILE__)}/../lib" require 'ohcount' rescue LoadError # Failing that, try to load from a gem require 'rubygems' require 'ohcount' end class OhcountCommandLine attr_accessor :paths def initialize(args=[]) args = args.clone # Because shift is destructive set_option(args.shift) while args.first =~ /^-/ assign_paths_and_files(args) end def assign_paths_and_files(args) @files = [] @paths = [] args.each do |file_or_path| if File.directory?(file_or_path) @paths << file_or_path else @files << file_or_path end end @paths = ['.'] if @files.empty? && @paths.empty? end def source_file_list @source_file_list ||= Ohcount::SourceFileList.new(:paths => @paths, :files => @files) end def annotate source_file_list.each_source_file do |s| s.parse do |language, semantic, line| puts "#{language}\t#{semantic}\t#{line}" end end end # Find all source code files def detect source_file_list.each_source_file do |s| puts "#{s.polyglot}\t#{s.filename}" end end # Licenses def licenses source_file_list.each_source_file do |s| next unless s.licenses.any? symbols = s.licenses.collect { |l| Ohcount::LicenseSniffer::LicenseMap.instance.map[l].symbol }.join(",") puts "#{symbols}\t#{s.filename}" end end def analyze_with_progress(what) count = 0 source_file_list.analyze(what) do |s| if count % 100 == 0 STDOUT.write('.') STDOUT.flush end count+=1 end puts "\n" end def write_gestalt platforms = source_file_list.gestalt_facts.platforms platforms = platforms.any? ? platforms.collect { |p| p.to_s.split('::').last }.join(", ") : 'None' puts "Platforms detected: #{ platforms }" tools = source_file_list.gestalt_facts.tools tools = tools.any? ? tools.collect { |p| p.to_s.split('::').last }.join(", ") : 'None' puts "Tools detected: #{ tools }" end # Gestalt def gestalt analyze_with_progress(:gestalt) write_gestalt end def raw_entities source_file_list.each_source_file do |s| s.raw_entities do |language, entity, s, e| puts "#{language}\t#{entity}\t#{s}\t#{e}" end end end def help puts < l1.name}.each do |lb| write_individual_row(s.filename, lb.name, lb.code_count, lb.comment_count, lb.blanks) end end end def write_individual_row(file, name, code, comment, blank) printf("%-16s",name) printf(" %10d",code) printf(" %10d",comment) if comment+code > 0 printf(" %9.1f%%", comment.to_f / (comment+code).to_f * 100.0) else printf(" ") end printf(" %10d",blank) printf(" %10d",code+comment+blank) printf(" %s\n", file) end def memoryleak puts "Parsing one file repeatedly. Watch your RAM vanish...." s = Ohcount::SourceCode.new(files.first, :filenames => files) while true s.parse {} end end def summary STDOUT.write "Examining #{source_file_list.size} file(s)" analyze_with_progress(:*) puts puts "Ohloh Line Count Summary".center(76) puts puts "Language Files Code Comment Comment % Blank Total" puts "---------------- ----- --------- --------- --------- --------- ---------" source_file_list.loc_list.locs.sort { |a,b| b.code <=> a.code}.each do |loc| write_summary_row(loc.language, loc.filecount, loc.code, loc.comments, loc.blanks) end puts "---------------- ----- --------- --------- --------- --------- ---------" write_summary_row('Total', source_file_list.loc_list.filecount, source_file_list.loc_list.code, source_file_list.loc_list.comments, source_file_list.loc_list.blanks) puts write_gestalt end def write_summary_row(name, file_count, code, comment, blank) printf("%-16s", name) printf(" %6d", file_count) printf(" %10d", code) printf(" %10d", comment) if comment+code > 0 printf(" %9.1f%%", comment.to_f / (comment+code).to_f * 100.0) else printf(" 0.0%"); end printf(" %10d", blank) printf(" %10d\n", code+comment+blank) end def subcommand=(s) if @subcommand STDERR.puts "Error: Multiple commands specified." exit 1 else @subcommand=s end end def subcommand @subcommand end def set_option(option) case option when '-s', '--summary' self.subcommand = :summary when '-d', '--detect' self.subcommand = :detect when '-a', '--annotate' self.subcommand = :annotate when '-g', '--gestalt' self.subcommand = :gestalt when '-i', '--individual' self.subcommand = :individual when '-l', '--licenses' self.subcommand = :licenses when '-m', '--memoryleak' self.subcommand = :memoryleak when '-e', '--entities' self.subcommand = :entities when '-re' self.subcommand = :raw_entities #when /-n([\w_]+)/ # @entities ||= [] # @entities << $1.to_sym # self.subcommand = :entities unless @subcommand when '-?', '-h', '--help' self.subcommand = :help else STDERR.puts "Type 'ohcount -?' for usage." exit 1 end end def run! self.subcommand ||= :summary if self.respond_to?(self.subcommand) self.send(self.subcommand) else STDERR.puts "Type 'ohcount -?' for usage." exit 1 end end end OhcountCommandLine.new(ARGV).run!