Sha256: 2e1550e40082e89a6a40f28a646af5c4d8c04bdc4836d42e561f1f3da8132938

Contents?: true

Size: 1.64 KB

Versions: 1

Compression:

Stored size: 1.64 KB

Contents

require 'nokogiri'

module Rallycat
  class Cat
    class StoryNotFound < StandardError; end

    def initialize(rally_api)
      @rally_api = rally_api
    end

    def story(story_number)
      story_type = story_number.start_with?('US') ? :hierarchical_requirement : :defect

      results = @rally_api.find(story_type, fetch: true) do
        equal :formatted_id, story_number
      end

      if results.total_result_count == 0
        raise StoryNotFound, "Story (#{ story_number }) does not exist."
      end

      consolidate_newlines parse_story(results.first)
    end

    private

    # NOTE: story.elements.keys => all properties exposed by rally
    def parse_story(story)
      <<-TEXT

# [#{story.formatted_i_d}] - #{story.name}

  Plan Estimate:   #{story.plan_estimate}
  State:           #{story.schedule_state}
  Task Actual:     #{story.task_actual_total}
  Task Estimate:   #{story.task_estimate_total}
  Task Remaining:  #{story.task_remaining_total}
  Owner:           #{story.owner}

## DESCRIPTION

#{HtmlToTextConverter.new(story.description).parse}

## TASKS

#{parse_tasks(story)}

TEXT
    end

    def parse_tasks(story)
      return '' unless story.tasks

      tasks        = story.tasks
      sorted_tasks = tasks.sort_by{ |t| t.task_index }

      # This is an example of a task formatted in plain text:
      #
      # [TA12345] [C] The name of the task.
      #
      sorted_tasks.map do |task|
        state =  task.state == 'In-Progress' ? 'P' : task.state[0]
        "[#{task.formatted_i_d}] [#{state}] #{task.name}"
      end.join("\n")
    end

    def consolidate_newlines(story)
      story.gsub(/\n{3,}/, "\n\n")
    end
  end
end

Version data entries

1 entries across 1 versions & 1 rubygems

Version Path
rallycat-0.3.0 lib/rallycat/cat.rb