From 076800e304fd183809ba7b3e559553c7deac0b09 Mon Sep 17 00:00:00 2001 From: "Glenn Y. Rolland" Date: Tue, 28 Jun 2016 19:02:07 +0200 Subject: [PATCH] Initial import. --- .gitignore | 1 + Gemfile | 7 ++++++ README.md | 6 +++++ bin/aoidos | 68 +++++++++++++++++++++++++++++++++++++++++++++++++++++ report.ods | Bin 0 -> 4320 bytes 5 files changed, 82 insertions(+) create mode 100644 .gitignore create mode 100644 Gemfile create mode 100644 README.md create mode 100755 bin/aoidos create mode 100644 report.ods diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..b844b14 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +Gemfile.lock diff --git a/Gemfile b/Gemfile new file mode 100644 index 0000000..bbbfd0d --- /dev/null +++ b/Gemfile @@ -0,0 +1,7 @@ +# A sample Gemfile +source "https://rubygems.org" + +gem 'thor' +gem 'minedig', git: "https://github.com/siman-man/minedig" +gem 'rspreadsheet' +gem 'pry' diff --git a/README.md b/README.md new file mode 100644 index 0000000..a80204d --- /dev/null +++ b/README.md @@ -0,0 +1,6 @@ +Aoidos (ἀοιδός) +============== + +Export _users stories_ from your redmine into an OpenDocument Spreadsheet (ods) report. + + diff --git a/bin/aoidos b/bin/aoidos new file mode 100755 index 0000000..a9300ea --- /dev/null +++ b/bin/aoidos @@ -0,0 +1,68 @@ +#!/usr/bin/env ruby +# vim: syntax=ruby ts=4 sw=4 et nolist: + +require 'minedig' +require 'yaml' +require 'rspreadsheet' +require 'pry' + +credential_file = ENV['HOME'] + '/.sansa-report/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 + +book = Rspreadsheet::Workbook.new +tickets = redmine.project('catone-smb-device').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, '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 + end + + nextline = sheet.rows.size + 1 + ticket_title = "%s%s" % [title[0].upcase, title[1..-1]] + ticket_version = (ticket.ticket['fixed_version'] || {'name' => ''})['name'] + puts "[ %- 8d | %- 30.30s | %- 50.50s ]" % [ticket.id, prefix, ticket_title] + + [title, '', ticket_version, ticket.id].each_with_index do |txt,idx| + cell = sheet.cell(nextline,idx+1) + cell.value = txt + end + +end +book.save('report.ods') diff --git a/report.ods b/report.ods new file mode 100644 index 0000000000000000000000000000000000000000..249b10c42bcecc72955a0b066fd796e56b5a4ce9 GIT binary patch literal 4320 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