class TimeCost::CLI

Public Class Methods

new() click to toggle source
# File lib/timecost/cli.rb, line 3
def initialize
        # FIXME: accept multiple authors
        @config = {
                :author_filter_enable => false,
                :author_filter => ".*?",

                :date_filter_enable => false,
                :date_filter => [],

                :branches_filter_enable => true,

                :input_dump => [],
                :output_dump => nil,

                :range_granularity => 0.5, # in decimal hours

                :verbose => false
        }
        @rangelist = {}
        @authorlist = nil
end

Public Instance Methods

analyze() click to toggle source
# File lib/timecost/cli.rb, line 193
def analyze
        if @config[:input_dump].empty? then
                analyze_git
        else
                analyze_dumps
        end
end
analyze_dumps() click to toggle source
# File lib/timecost/cli.rb, line 175
def analyze_dumps
        #read ranges

        @config[:input_dump].each do |filename|
          filelists = YAML::load(File.open(filename,"r"))
                # require 'pry'
                # binding.pry
                filelists.each do |author, rangelist|
                  # create list if author is new
            @rangelist[author] ||= RangeList.new

                  rangelist.each do |range|
                          @rangelist[author].add range
                        end
                end
        end
end
analyze_git() click to toggle source
# File lib/timecost/cli.rb, line 92
def analyze_git
        # git log
        # foreach, create time range (before) + logs

        cmd = [
                "git", "log",
              "--date=iso", 
              "--no-patch"
        ]
        if not @config[:branches_filter_enable] then  
                cmd << "--all"
        end
        cmd.concat ["--", "."]
        process = IO.popen cmd

        @rangelist = {}
        commit = nil
        loop do
                line = process.gets
                break if line.nil?
                # utf-8 fix ?
                # line.encode!( line.encoding, "binary", :invalid => :replace, :undef => :replace)
                line.strip!

                case line
                when /^commit (.*)$/ then
                        id = $1
                        # merge ranges & push
                        unless commit.nil? then
                                range = Range.new commit, granularity: @config[:range_granularity]

                                if not @rangelist.include? commit.author then
                                        @rangelist[commit.author] = RangeList.new
                                end
                                @rangelist[commit.author].add range
                        end
                        commit = Commit.new id
                        # puts "commit #{id}"

                when /^Author:\s*(.*?)\s*$/ then
                        unless commit.nil? then
                                commit.author = $1 

                                if @config[:author_filter_enable] and 
                                        (not commit.author =~ /#{@config[:author_filter]}/) then
                                        commit = nil
                                        # reject
                                end

                        end

                when /^Date:\s*(.*?)\s*$/ then
                        unless commit.nil? then
                                commit.date = $1

                                # reject if a some filter does not validate date
                                filter_keep = true
                                filters = @config[:date_filter]
                                filters.each do |f|
                                        filter_keep &= f.call(DateTime.parse(commit.date))
                                end

                                if not filter_keep then
                                        commit = nil
                                end
                        end

                when /^\s*$/ then
                        # skip

                else 
                        # add as note
                        unless commit.nil? then
                                commit.note = if commit.note.nil? then line
                                                          else commit.note + "\n" + line
                                                          end
                        end
                end

        end

end
export() click to toggle source
# File lib/timecost/cli.rb, line 201
def export
        return if @config[:output_dump].nil?
        puts "Exporting to %s" % @config[:output_dump]
        File.open(@config[:output_dump], "w") do |file|
                file.puts YAML::dump(@rangelist)
        end
end
parse_cmdline(args) click to toggle source
# File lib/timecost/cli.rb, line 25
def parse_cmdline args
        options = OptionParser.new do |opts|
                opts.banner = "Usage: #{File.basename $0} [options]"

                opts.on_tail("-v","--verbose", "Run verbosely") do |v|
                        @config[:verbose] = true
                end

                opts.on_tail("-h","--help", "Show this help") do
                        puts opts
                        exit 0
                end


                opts.on("-i","--input FILE", "Set input dump file") do |file|
                        @config[:input_dump] << file
                end

                opts.on("-o","--output FILE", "Set output dump file") do |file|
                        @config[:output_dump] = file
                end

                opts.on("--before DATE", "Keep only commits before DATE") do |date|
                        puts "set date filter to <= #{date}"
                        @config[:date_filter] << lambda { |other|
                                return (other <= DateTime.parse(date))
                        }
                        @config[:date_filter_enable] = true
                end

                opts.on("--after DATE", "Keep only commits after DATE") do |date|
                        puts "set date filter to >= #{date}"
                        @config[:date_filter] << lambda { |other|
                                return (other >= DateTime.parse(date))
                        }
                        @config[:date_filter_enable] = true
                end

                opts.on("-t","--time TIME", "Keep only commits on last TIME days") do |time|
                        puts "set time filter to latest #{time} days"
                        @config[:date_filter] = DateTime.now - time.to_f;
                        puts "set date filter to date = #{@config[:date_filter]}"
                        @config[:date_filter_enable] = true
                end

                opts.on("-a","--author AUTHOR", "Keep only commits by AUTHOR") do |author|
                        puts "set author filter to #{author}"
                        @config[:author_filter] = author
                        @config[:author_filter_enable] = true
                end

                opts.on_tail("--all", "Collect from all branches and refs") do
                        @config[:branches_filter_enable] = false
                end

                # overlap :
                #
                opts.on("-s","--scotch GRANULARITY", "Use GRANULARITY (decimal hours) to merge ranges") do |granularity|
                        puts "set scotch to #{granularity}"
                        @config[:range_granularity] = granularity.to_f
                end
        end
        options.parse! args

end
report() click to toggle source
# File lib/timecost/cli.rb, line 209
def report
        return if not @config[:output_dump].nil?

        @rangelist.each do |author,rangelist|
                rangelist.each do |range|
                        puts range.to_s(!@config[:author_filter_enable]) + "\n"
                end
        end
        total = 0
        @rangelist.each do |author,rangelist|
                puts "SUB-TOTAL for %s: %.2f hours\n" % [author, rangelist.sum]
                total += rangelist.sum
        end
        puts "TOTAL: %.2f hours" % total
end