class Torque

The central class for Torque. Takes in a hash of options, generates release notes from online data, writes them to file and emails them

Public Class Methods

new(options, settings=nil, fs=nil) click to toggle source

@param options A hash of the settings to use for @param settings An instance of Torque::Settings (default: Torque::Settings.new) @param settings An instance of Torque::FileSystem (default: Torque::FileSystem.new)

# File lib/torque.rb, line 20
def initialize(options, settings=nil, fs=nil)
  @fs = fs || FileSystem.new
  @settings = settings || Settings.new(options, @fs)

  @date_format = "%Y/%m/%d"
end

Public Instance Methods

email_notes(notes_string, project_name, mailer=nil) click to toggle source

@param notes_string A string representation of the generated release notes @param project_name The name of the current project @param mailer An instance of Torque::Mailer (default: Torque::Mailer.new(@settings.email_address, @settings.email_password) )

Emails notes_string to the email list specified in the torque info file

# File lib/torque.rb, line 129
def email_notes(notes_string, project_name, mailer=nil)
  print_if_not_silent "Emailing notes..."

  mailer ||= Mailer.new(@settings.email_address, @settings.email_password)

  if @settings.email_address.blank?
    print_if_not_silent "Emailing notes failed: No sender email address found. (Set this with 'torque email')"
  elsif @settings.email_password.blank?
    print_if_not_silent "Emailing notes failed: No sender email password found. (Set this with 'torque email')"
  elsif(@settings.email_to.length == 0)
    print_if_not_silent "No email addresses found. (Add them with 'torque email')"
  else
  
    address_list = ""
    @settings.email_to.each_with_index {
      |address, i|

      if i!=0
        address_list << ", "
      end
      address_list << address
    }

    subject_line = \
      "Release Notes: Project #{@settings.project} - '#{project_name}' (" \
      + (@settings.custom_date_range ? "Custom " : "") \
      + "#{@settings.accept_from.strftime('%Y/%m/%d')} - " \
      + "#{@settings.accept_to.strftime('%Y/%m/%d')}" \
      + ")"

    mailer.send_notes(notes_string, subject_line, address_list)

    print_if_not_silent "Emailed notes to #{address_list}"
  end
end
execute() click to toggle source

@return The generated notes

The method run by Torque on the command line. Generates the notes, writes them to file, optionally emails them

# File lib/torque.rb, line 169
def execute

  # Determines the current project

  torque_info = TorqueInfoParser.new(@settings.torque_info_path)
  project_manager = ProjectManager.new(torque_info)
  
  project_manager.load_project_list
  project_name = project_manager.current_project.name

  # Generates the notes

  print_if_not_silent "Current project: #{@settings.project} - '#{project_name}'"

  print_if_not_silent "Filter: \"#{@settings.filter_string}\"" if @settings.filters_on

  if @settings.iterations
    print_if_not_silent "Generating release notes: Last #{@settings.iterations} iterations..."

  else
    print_if_not_silent "Generating release notes: " \
      + (@settings.custom_date_range ? "Custom " : "") \
      + @settings.accept_from.strftime(@date_format) + " - " \
      + @settings.accept_to.strftime(@date_format) \
      + "..."
  end

  pivotal = Pivotal.new(@settings.token)
  if @settings.iterations
    project_html = pivotal.get_project_iterations(@settings.project, @settings.iterations)
  else
    project_html = pivotal.get_project_stories(@settings.project)
  end
  
  iterations_on = (!@settings.iterations.nil?)
  notes_string = generate_notes(project_html, project_name, iterations_on)

  # Writes the notes to file

  root_dir_path = Pathname.new(@settings.root_dir)
  rel_notes_path = Pathname.new(@settings.current_notes_path).relative_path_from(root_dir_path)
  print_if_not_silent "- Writing notes > #{rel_notes_path}"

  @fs.file_write("#{@settings.current_notes_path}", notes_string)

  # Creates a record of the notes file

  rel_record_path = Pathname.new(@settings.record_path).relative_path_from(root_dir_path)
  print_if_not_silent "- Copying notes > #{rel_record_path}"

  begin
    @fs.file_write("#{@settings.record_path}", notes_string)
  rescue => e
    err_str = "WARNING: Unable to make a record of the release notes file. Could not locate records "
    err_str += "directory \"#{File.expand_path(@settings.record_path)}\""
    print_if_not_silent err_str
  end

  print_if_not_silent "Notes generated!"

  # Emails the release notes to the mailing list
  
  email_notes(notes_string, project_name) if(@settings.email)

end
generate_notes(project_html, project_name, iterations_on=false) click to toggle source

@param project_html An html string containing all the project's stories @param project_name The name of the current project @param iterations_on True if the stories are organized into iterations, else false

@return A string comprising the release notes document

# File lib/torque.rb, line 33
def generate_notes(project_html, project_name, iterations_on=false)

  notes_string = ""

  # Adds the header
  notes_string += Date.today.strftime(@date_format)+"\n"
  notes_string += "Release Notes\n"
  notes_string += "Project #{@settings.project} - '#{project_name}'\n"

  if iterations_on
    # Past iterations header
    notes_string += "Last "
    notes_string += (@settings.iterations == 1 \
                    ? "iteration"
                    : "#{@settings.iterations} iterations"
                    )
    notes_string += "\n"

  elsif @settings.custom_date_range
    # Custom date range header
    notes_string += "(custom "+@settings.accept_from.strftime(@date_format)+" - "+@settings.accept_to.strftime(@date_format)+")\n"
  
  else
    # Default date range header
    notes_string += "("+@settings.accept_from.strftime(@date_format)+" - "+@settings.accept_to.strftime(@date_format)+")\n"
  end
  
  if @settings.filters_on
    # Filters header
    notes_string += "Filter '#{@settings.filter_string}'\n"
  end

  notes_string += "\n"
  notes_string += "These notes were generated with Torque, a Pivotal Tracker command line utility\n"
  notes_string += "\n"

  html_parser = PivotalHTMLParser.new
  html_parser.add_date_filter(@settings.accept_from, @settings.accept_to) unless @settings.iterations
  html_parser.add_field_filters(@settings.filters) if @settings.filters_on

  if iterations_on
    # Adds each iteration
    
    iteration_list = html_parser.process_project_iterations(project_html)

    iteration_list = Iteration.sort_list(iteration_list)
    iteration_list.each do |iteration|
      notes_string += "-- Iteration #{iteration.number} --\n"
      notes_string += "\n"

      print_if_verbose "[Torque]"
      print_if_verbose "[Torque] -- Iteration #{iteration.number} --"

      iteration.sort_stories
      iteration.stories.each do |story|
        notes_string += @settings.format_string.apply(story)
        notes_string += "\n"
        notes_string += "\n"

        print_if_verbose "[Torque] (#{story.date_accepted.strftime(@date_format)}) #{story.name}"
      end
    end

    num_stories = 0
    iteration_list.each {|iteration| num_stories += iteration.stories.length}

    print_if_verbose "[Torque]"
    print_if_verbose "[Torque] Added #{num_stories} stories"

  else
    # Adds each story
    
    stories = html_parser.process_project(project_html)

    stories = Story.sort_list(stories)
    stories.each do |story|
      notes_string += @settings.format_string.apply(story)
      notes_string += "\n"
      notes_string += "\n"

      print_if_verbose "[Torque] (#{story.date_accepted.strftime(@date_format)}) #{story.name}"
    end

    print_if_verbose "[Torque]"
    print_if_verbose "[Torque] Added #{stories.length} stories"
  end

  notes_string
end

Private Instance Methods

print_if_not_silent(msg) click to toggle source

Prints a message if silent is not on

print_if_verbose(msg) click to toggle source

Prints a message if verbose is on and silent is not