diff --git a/History.rdoc b/History.rdoc index 8c3bdf6..1842107 100644 --- a/History.rdoc +++ b/History.rdoc @@ -1,3 +1,15 @@ +=== 4.7.0 / 2019-04-23 + +* 7 minor enhancements: + + * Modified Flog#flog to expand directories in its arguments into files + * Modified FlogCLI::run to use Flog#flog to expand directories into files + * Modified test_flog.rb to test expansion of dirs to files. + * Modified usage message of FlogCli to show standard input case. + * flog_cli.rb uses require_relative such that tests don't used an installed gem file. + * bin/flog uses require_relative such that tests don't used an installed gem file. + * Modified bin/flog to use /usr/bin/env to select the ruby interpreter. + === 4.6.2 / 2018-02-14 * 1 bug fix: diff --git a/bin/flog b/bin/flog index 8f10030..50b1feb 100755 --- a/bin/flog +++ b/bin/flog @@ -1,6 +1,6 @@ -#!/usr/local/bin/ruby -w +#!/usr/bin/env ruby -w -require "flog_cli" +require_relative File.join("..", "lib", "flog_cli") FlogCLI.run diff --git a/lib/flog.rb b/lib/flog.rb index 1ae537b..16b3a7a 100644 --- a/lib/flog.rb +++ b/lib/flog.rb @@ -1,6 +1,7 @@ require "sexp_processor" require "ruby_parser" require "timeout" +require 'path_expander' class File RUBY19 = "<3".respond_to? :encoding unless defined? RUBY19 # :nodoc: @@ -11,7 +12,7 @@ class << self end class Flog < MethodBasedSexpProcessor - VERSION = "4.6.2" # :nodoc: + VERSION = "4.7.0" # :nodoc: ## # Cut off point where the report should stop unless --all given. @@ -167,22 +168,33 @@ def each_by_score max = nil end end - ## + # # Flog the given files. Deals with "-", and syntax errors. # - # Not as smart as FlogCLI's #flog method as it doesn't traverse - # dirs. Use PathExpander to expand dirs into files. + def expand_file(file) + expander = PathExpander.new [file], "**/*.{rb,rake}" + expander.process + end + # NOW as smart as FlogCLI's #flog method as it traverses + # dirs using PathExpander. def flog(*files) + flogged = false files.each do |file| - next unless file == '-' or File.readable? file - - ruby = file == '-' ? $stdin.read : File.binread(file) - - flog_ruby ruby, file + if file == '-' + flog_ruby $stdin.read, file + flogged = true + else + expand_file(file).each do |elem| + next unless File.readable? elem + flogged = true + flog_ruby File.binread(elem), elem + end + end end calculate_total_scores + flogged end ## diff --git a/lib/flog_cli.rb b/lib/flog_cli.rb index 3853635..56024ef 100644 --- a/lib/flog_cli.rb +++ b/lib/flog_cli.rb @@ -2,8 +2,7 @@ require "optparse" require "forwardable" -require "path_expander" -require "flog" +require_relative "flog" class FlogCLI extend Forwardable @@ -16,16 +15,14 @@ class FlogCLI def self.run args = ARGV load_plugins - expander = PathExpander.new args, "**/*.{rb,rake}" - files = expander.process - options = parse_options args - abort "no files or stdin (-) to process, aborting." if - files.empty? and args.empty? + abort "no files or stdin (-) to process, aborting." if args.empty? flogger = new options - flogger.flog(*files) + unless flogger.flog(*args) + abort "no readable source files to process, aborting." + end flogger.report end @@ -74,6 +71,12 @@ def self.parse_options args = ARGV } OptionParser.new do |opts| + opts.banner = + "\nUsage:" \ + "\n flog [options] - # to read stdin." \ + "\nor," \ + "\n flog [options] dir_or_file(s)\n\n" + opts.separator "Standard options:" opts.on("-a", "--all", "Display all flog results, not top 60%.") do @@ -154,8 +157,8 @@ def self.plugins ## # Flog the given files. Deals with "-", syntax errors, and - # traversing subdirectories intelligently. Use PathExpander to - # process dirs into files. + # traversing subdirectories intelligently. PathExpander is used + # by Flog#flog to process dirs into files. def flog(*files) files << "-" if files.empty? diff --git a/test/test_flog.rb b/test/test_flog.rb index e947580..75794b0 100644 --- a/test/test_flog.rb +++ b/test/test_flog.rb @@ -1,5 +1,8 @@ require "minitest/autorun" require "flog" +require 'tempfile' +require 'tmpdir' + class Flog attr_writer :calls @@ -625,6 +628,56 @@ def bleh n assert_equal(expected, @flog.method_scores) end + def test_flog_with_path_expander + account = %( + module User + class Account + def blah n + puts "blah" * n + end + end + end + ) + profile = %( + module User + class Profile + def bleh n + puts "bleh" * n + end + end + end + ) + + # Lambda to make a temporary data file called 'name' in directory named 'where' + # with contents of 'data' + temp_data = -> (name, where, data) { + file = Tempfile.new([name, '.rb'], where) + file << data + file.close + file.open + } + + # Make a temporary dir with account data + Dir.mktmpdir() { |dir| + temp_data.call('dir', dir.to_s, account) + # Make a a temporary subdirectory of dir with profile data + Dir.mktmpdir(nil, dir) { |sub_dir| + temp_data.call('sub_dir', sub_dir.to_s, profile) + Dir.chdir(dir) { + # tell flog to process from the temporary dir downward + @flog.flog dir.to_s + } + } + } + @flog.calculate + + expected = { + "User::Account"=>[["User::Account#blah", 2.2]], + "User::Profile"=>[["User::Profile#bleh", 2.2]] + } + assert_equal(expected, @flog.method_scores) + end + def setup_my_klass @flog.class_stack << "Base" << "MyKlass" @flog.method_stack << "mymethod"