152 lines
4.2 KiB
Crystal
152 lines
4.2 KiB
Crystal
module TimeCost
|
|
class CLI
|
|
property authorlist : String?
|
|
property rangelist : Hash(Range, Array(Range))
|
|
|
|
def initialize
|
|
# FIXME: accept multiple authors
|
|
@config = {
|
|
:author_filter_enable => false,
|
|
:author_filter => ".*?",
|
|
|
|
:date_filter_enable => false,
|
|
:date_filter => [] of Time,
|
|
|
|
:branches_filter_enable => true,
|
|
|
|
:input_dump => [] of String,
|
|
:output_dump => nil,
|
|
|
|
:range_granularity => 0.5, # in decimal hours
|
|
|
|
:verbose => false,
|
|
}
|
|
@authorlist = nil
|
|
@rangelist = {} of Range => Array(Range)
|
|
end
|
|
|
|
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
|
|
|
|
def analyze_git
|
|
reader = GitReader.new
|
|
@rangelist = reader.parse
|
|
|
|
# git log
|
|
# foreach, create time range (before) + logs
|
|
|
|
end
|
|
|
|
# CR: def analyze_dumps
|
|
# CR: #read ranges
|
|
|
|
# CR: @config[:input_dump].each do |filename|
|
|
# CR: filelists = YAML::load(File.open(filename,"r"))
|
|
# CR: # require 'pry'
|
|
# CR: # binding.pry
|
|
# CR: filelists.each do |author, rangelist|
|
|
# CR: # create list if author is new
|
|
# CR: @rangelist[author] ||= RangeList.new
|
|
|
|
# CR: rangelist.each do |range|
|
|
# CR: @rangelist[author].add range
|
|
# CR: end
|
|
# CR: end
|
|
# CR: end
|
|
# CR: end
|
|
|
|
def analyze
|
|
if @config[:input_dump].empty?
|
|
analyze_git
|
|
else
|
|
analyze_dumps
|
|
end
|
|
end
|
|
|
|
# CR: def export
|
|
# CR: return if @config[:output_dump].nil?
|
|
# CR: puts "Exporting to %s" % @config[:output_dump]
|
|
# CR: File.open(@config[:output_dump], "w") do |file|
|
|
# CR: file.puts YAML::dump(@rangelist)
|
|
# CR: end
|
|
# CR: end
|
|
|
|
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
|
|
end
|
|
end
|