#!/usr/bin/env ruby # vim: syntax=ruby ts=4 sw=4 et nolist: require 'minedig' require 'yaml' require 'rspreadsheet' require 'pry' require 'thor' require 'semantic' class Aoidos < Thor def initialize *args super credential_file = ENV['HOME'] + '/.aoidos/redmine.yml' unless File.exist? credential_file sample_content = "home: 'http://redmine.example.com'\nkey: REDMINE_API_KEY" raise Errno::ENOENT, "Please create %s file with:\n%s" % [ credential_file, sample_content ] end credential = YAML.load_file(credential_file) @redmine = Minedig::Redmine.new do |config| config.home = credential['home'] # ex: 'http://project.gnuside.com' config.api_key = credential['key'] # ex: ... end end option :output, aliases: "-o", desc: "Set ODS output file name" desc "export PROJECT", "Export project user stories" def export(project) target_version = make_version '2.0.0' book_filename = options[:output] || (project + '.ods') book = Rspreadsheet::Workbook.new tickets = @redmine.project(project).tickets(count: :all) tickets.each do |ticket| type = case ticket.tracker_id when 2 then :feature # feature when 4 then :user_story # user story else :bug end next if type != :user_story prefix = nil title = nil sheet = nil if ticket.subject.strip =~ /^(\s*As\s+.*?)\s*,\s+i\s+want\s+to\s+(.*)$/i then prefix = $1.strip title = $2.strip else raise "Invalid ticket #{ticket.id} - #{ticket.subject}" end sheet = book.sheet(prefix) || book.create_worksheet(prefix) if sheet.rows.size == 0 then [prefix + ', i want to...', 'Description', 'Version', 'ID'] .each_with_index do |txt,idx| cell = sheet.cell(1,idx+1) cell.value = txt cell.format.bold = true cell.format.color = '#FFFFFF' cell.format.background_color = '#662D91' end # sheet.columns(0).format.width = 20 # sheet.columns(1).format.width = 20 # sheet.columns(2).format.width = 8 # sheet.columns(3).format.width = 4 end nextline = sheet.rows.size + 1 ticket_title = "%s%s" % [title[0].upcase, title[1..-1]] ticket_version = (ticket.ticket['fixed_version'] || {'name' => ''})['name'] .split(/\s+-\s+/)[0] ticket_version_obj = make_version ticket_version.gsub(/^v/,'') puts "[ %- 8d | %- 30.30s | %- 50.50s ]" % [ticket.id, prefix, ticket_title] [ticket_title, '', ticket_version, ticket.id].each_with_index do |txt,idx| cell = sheet.cell(nextline,idx+1) cell.value = txt if ticket_version_obj <= target_version then cell.format.bold = true cell.format.color = '#000000' else cell.format.color = '#888888' end end end book.save(book_filename) end private def make_version str return Semantic::Version.new str rescue ArgumentError make_version str + '.0' end end Aoidos.start(ARGV)