pivotal-slacker 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/bin/pivotal-slacker +199 -0
 - data/lib/app_config.rb +40 -0
 - data/lib/formatter.rb +65 -0
 - metadata +49 -0
 
    
        data/bin/pivotal-slacker
    ADDED
    
    | 
         @@ -0,0 +1,199 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            #!/usr/bin/env ruby
         
     | 
| 
      
 2 
     | 
    
         
            +
            # encoding: utf-8
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
            require "rubygems"
         
     | 
| 
      
 5 
     | 
    
         
            +
            require "pivotal-tracker"
         
     | 
| 
      
 6 
     | 
    
         
            +
            require "rainbow"
         
     | 
| 
      
 7 
     | 
    
         
            +
            require "action_view"
         
     | 
| 
      
 8 
     | 
    
         
            +
            require "launchy"
         
     | 
| 
      
 9 
     | 
    
         
            +
            require "pp"
         
     | 
| 
      
 10 
     | 
    
         
            +
            require "app_config"
         
     | 
| 
      
 11 
     | 
    
         
            +
            require "formatter"
         
     | 
| 
      
 12 
     | 
    
         
            +
            include ActionView::Helpers::DateHelper
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
            # ----------------------------------------------------------
         
     | 
| 
      
 15 
     | 
    
         
            +
            # Load config
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
            config = nil
         
     | 
| 
      
 18 
     | 
    
         
            +
            begin
         
     | 
| 
      
 19 
     | 
    
         
            +
              config = AppConfig.load
         
     | 
| 
      
 20 
     | 
    
         
            +
            rescue Exception => e
         
     | 
| 
      
 21 
     | 
    
         
            +
              puts e
         
     | 
| 
      
 22 
     | 
    
         
            +
              exit 1
         
     | 
| 
      
 23 
     | 
    
         
            +
            end
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
            # ----------------------------------------------------------
         
     | 
| 
      
 26 
     | 
    
         
            +
            # Init
         
     | 
| 
      
 27 
     | 
    
         
            +
             
     | 
| 
      
 28 
     | 
    
         
            +
            PivotalTracker::Client.token = config.api_key
         
     | 
| 
      
 29 
     | 
    
         
            +
            project = PivotalTracker::Project.find config.project
         
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
      
 31 
     | 
    
         
            +
            # ----------------------------------------------------------
         
     | 
| 
      
 32 
     | 
    
         
            +
            # Main app code
         
     | 
| 
      
 33 
     | 
    
         
            +
             
     | 
| 
      
 34 
     | 
    
         
            +
            require "commander/import"
         
     | 
| 
      
 35 
     | 
    
         
            +
            require "pivotal-tracker"
         
     | 
| 
      
 36 
     | 
    
         
            +
             
     | 
| 
      
 37 
     | 
    
         
            +
            program :version, "1.0"
         
     | 
| 
      
 38 
     | 
    
         
            +
            program :description, "Pivotal Tracker command line client."
         
     | 
| 
      
 39 
     | 
    
         
            +
             
     | 
| 
      
 40 
     | 
    
         
            +
            command :mine do |c|
         
     | 
| 
      
 41 
     | 
    
         
            +
              c.syntax = "pivotal-slacker mine [options]"
         
     | 
| 
      
 42 
     | 
    
         
            +
              c.description = "List your stories in pivotal tracker."
         
     | 
| 
      
 43 
     | 
    
         
            +
              c.example "description", "command example"
         
     | 
| 
      
 44 
     | 
    
         
            +
              c.option "--some-switch", "Some switch that does something"
         
     | 
| 
      
 45 
     | 
    
         
            +
              c.action do |args, options|
         
     | 
| 
      
 46 
     | 
    
         
            +
                # Do something or c.when_called Pivotal-slacker::Commands::Mine
         
     | 
| 
      
 47 
     | 
    
         
            +
                
         
     | 
| 
      
 48 
     | 
    
         
            +
                states = %w{unstarted started finished accepted rejected}
         
     | 
| 
      
 49 
     | 
    
         
            +
                owned_by = config.user
         
     | 
| 
      
 50 
     | 
    
         
            +
                
         
     | 
| 
      
 51 
     | 
    
         
            +
                puts "Looking for stories owned by #{owned_by} in states: #{states}".color("#444444")
         
     | 
| 
      
 52 
     | 
    
         
            +
             
     | 
| 
      
 53 
     | 
    
         
            +
                stories = project.stories.all(:owned_by => owned_by, :current_state => states)
         
     | 
| 
      
 54 
     | 
    
         
            +
                stories.sort! { |a, b| a.created_at <=> b.created_at }
         
     | 
| 
      
 55 
     | 
    
         
            +
                stories.each do |story|
         
     | 
| 
      
 56 
     | 
    
         
            +
                  id = Formatter.story_id(story.id)
         
     | 
| 
      
 57 
     | 
    
         
            +
                  name = Formatter.story_name(story.name)
         
     | 
| 
      
 58 
     | 
    
         
            +
                  state = Formatter.state(story.current_state)
         
     | 
| 
      
 59 
     | 
    
         
            +
                  requested_by = Formatter.requested_by(story.requested_by)
         
     | 
| 
      
 60 
     | 
    
         
            +
                  created_at = Formatter.time_ago(story.created_at)
         
     | 
| 
      
 61 
     | 
    
         
            +
                  
         
     | 
| 
      
 62 
     | 
    
         
            +
                  puts "[#{id}] #{name}  ~  #{state}, from #{requested_by}, created #{created_at}"
         
     | 
| 
      
 63 
     | 
    
         
            +
                end
         
     | 
| 
      
 64 
     | 
    
         
            +
              end
         
     | 
| 
      
 65 
     | 
    
         
            +
            end
         
     | 
| 
      
 66 
     | 
    
         
            +
             
     | 
| 
      
 67 
     | 
    
         
            +
            command :open do |c|
         
     | 
| 
      
 68 
     | 
    
         
            +
              c.syntax = "pivotal-slacker open story_id"
         
     | 
| 
      
 69 
     | 
    
         
            +
              c.description = "Open a specific Pivotal Tracker story in the browser."
         
     | 
| 
      
 70 
     | 
    
         
            +
              c.example "Open a story with ID 123", "pivotal-slacker open 123"
         
     | 
| 
      
 71 
     | 
    
         
            +
              c.action do |args, options|
         
     | 
| 
      
 72 
     | 
    
         
            +
                story = project.stories.find(args[0].to_i)
         
     | 
| 
      
 73 
     | 
    
         
            +
                Launchy.open story.url
         
     | 
| 
      
 74 
     | 
    
         
            +
              end
         
     | 
| 
      
 75 
     | 
    
         
            +
            end
         
     | 
| 
      
 76 
     | 
    
         
            +
             
     | 
| 
      
 77 
     | 
    
         
            +
            command :show do |c|
         
     | 
| 
      
 78 
     | 
    
         
            +
              c.syntax = "pivotal-slacker show story_id"  
         
     | 
| 
      
 79 
     | 
    
         
            +
              c.description = "Show the details of a given Pivotal Tracker story."
         
     | 
| 
      
 80 
     | 
    
         
            +
              c.example "Show a story with ID 123", "pivotal-slacker show 123"
         
     | 
| 
      
 81 
     | 
    
         
            +
              c.action do |args, options|
         
     | 
| 
      
 82 
     | 
    
         
            +
                story = project.stories.find(args[0].to_i)
         
     | 
| 
      
 83 
     | 
    
         
            +
                id = Formatter.story_id(story.id)
         
     | 
| 
      
 84 
     | 
    
         
            +
                state = Formatter.state(story.current_state)
         
     | 
| 
      
 85 
     | 
    
         
            +
                requested_by = Formatter.requested_by(story.requested_by)
         
     | 
| 
      
 86 
     | 
    
         
            +
                created_at = Formatter.time_ago(story.created_at)
         
     | 
| 
      
 87 
     | 
    
         
            +
             
     | 
| 
      
 88 
     | 
    
         
            +
                puts ""
         
     | 
| 
      
 89 
     | 
    
         
            +
                puts "[#{id}] #{Formatter.story_name(story.name, :heading => true)}"
         
     | 
| 
      
 90 
     | 
    
         
            +
                puts "#{state}, from #{requested_by}, created #{created_at}"
         
     | 
| 
      
 91 
     | 
    
         
            +
                puts ""
         
     | 
| 
      
 92 
     | 
    
         
            +
                puts Formatter.description(story.description)
         
     | 
| 
      
 93 
     | 
    
         
            +
                puts ""
         
     | 
| 
      
 94 
     | 
    
         
            +
                
         
     | 
| 
      
 95 
     | 
    
         
            +
                notes = story.notes.all.sort { |a, b| a.noted_at <=> b.noted_at }
         
     | 
| 
      
 96 
     | 
    
         
            +
                notes.each do |note|
         
     | 
| 
      
 97 
     | 
    
         
            +
                  author = Formatter.note_author(note.author)
         
     | 
| 
      
 98 
     | 
    
         
            +
                  noted_at = Formatter.time_ago(note.noted_at)
         
     | 
| 
      
 99 
     | 
    
         
            +
                  note_text = Formatter.note_text(note.text)
         
     | 
| 
      
 100 
     | 
    
         
            +
                  puts "#{author} (#{noted_at}): #{note_text}"
         
     | 
| 
      
 101 
     | 
    
         
            +
                end
         
     | 
| 
      
 102 
     | 
    
         
            +
                
         
     | 
| 
      
 103 
     | 
    
         
            +
                # Extra padding line after notes.
         
     | 
| 
      
 104 
     | 
    
         
            +
                if notes != nil and notes.size > 0
         
     | 
| 
      
 105 
     | 
    
         
            +
                  puts ""
         
     | 
| 
      
 106 
     | 
    
         
            +
                end
         
     | 
| 
      
 107 
     | 
    
         
            +
              end
         
     | 
| 
      
 108 
     | 
    
         
            +
            end
         
     | 
| 
      
 109 
     | 
    
         
            +
             
     | 
| 
      
 110 
     | 
    
         
            +
            command :start do |c|
         
     | 
| 
      
 111 
     | 
    
         
            +
              c.syntax = "pivotal-slacker start story_id"
         
     | 
| 
      
 112 
     | 
    
         
            +
              c.description = "Mark a given Pivotal Tracker story as \"started\"."
         
     | 
| 
      
 113 
     | 
    
         
            +
              c.example "Start a story with ID 123", "pivotal-slacker start 123"
         
     | 
| 
      
 114 
     | 
    
         
            +
              c.action do |args, options|
         
     | 
| 
      
 115 
     | 
    
         
            +
                story_id = args[0].to_i
         
     | 
| 
      
 116 
     | 
    
         
            +
                
         
     | 
| 
      
 117 
     | 
    
         
            +
                story = project.stories.find(story_id)
         
     | 
| 
      
 118 
     | 
    
         
            +
                story.update :current_state => "started"
         
     | 
| 
      
 119 
     | 
    
         
            +
                
         
     | 
| 
      
 120 
     | 
    
         
            +
                puts Formatter.story_action(Formatter.state("started"), story_id, story.name) + "."
         
     | 
| 
      
 121 
     | 
    
         
            +
              end
         
     | 
| 
      
 122 
     | 
    
         
            +
            end
         
     | 
| 
      
 123 
     | 
    
         
            +
             
     | 
| 
      
 124 
     | 
    
         
            +
            command :comment do |c|
         
     | 
| 
      
 125 
     | 
    
         
            +
              c.syntax = "pivotal-slacker comment story_id comment"
         
     | 
| 
      
 126 
     | 
    
         
            +
              c.description = "Comment on a given Pivotal Tracker story."
         
     | 
| 
      
 127 
     | 
    
         
            +
              c.example "Comment on story 123", "pivotal-slacker comment 123 \"Due to my skills I will destroy this task.\""
         
     | 
| 
      
 128 
     | 
    
         
            +
              c.action do |args, options|
         
     | 
| 
      
 129 
     | 
    
         
            +
                story_id = args[0].to_i
         
     | 
| 
      
 130 
     | 
    
         
            +
                comment = args[1]
         
     | 
| 
      
 131 
     | 
    
         
            +
                
         
     | 
| 
      
 132 
     | 
    
         
            +
                story = project.stories.find(story_id)
         
     | 
| 
      
 133 
     | 
    
         
            +
                story.notes.create :text => comment
         
     | 
| 
      
 134 
     | 
    
         
            +
                
         
     | 
| 
      
 135 
     | 
    
         
            +
                comment = Formatter.note_text(comment)
         
     | 
| 
      
 136 
     | 
    
         
            +
                puts "#{Formatter.story_action "Commented on", story_id, story.name}:"
         
     | 
| 
      
 137 
     | 
    
         
            +
                puts "#{Formatter.note_author(config.user)}: #{comment}"
         
     | 
| 
      
 138 
     | 
    
         
            +
              end
         
     | 
| 
      
 139 
     | 
    
         
            +
            end
         
     | 
| 
      
 140 
     | 
    
         
            +
             
     | 
| 
      
 141 
     | 
    
         
            +
            command :finish do |c|
         
     | 
| 
      
 142 
     | 
    
         
            +
              c.syntax = "pivotal-slacker finish story_id"
         
     | 
| 
      
 143 
     | 
    
         
            +
              c.description = "Mark a given Pivotal Tracker story as \"finished\"."
         
     | 
| 
      
 144 
     | 
    
         
            +
              c.example "Finish a story with ID 123", "pivotal-slacker finish 123"
         
     | 
| 
      
 145 
     | 
    
         
            +
              c.action do |args, options|
         
     | 
| 
      
 146 
     | 
    
         
            +
                story_id = args[0].to_i
         
     | 
| 
      
 147 
     | 
    
         
            +
                
         
     | 
| 
      
 148 
     | 
    
         
            +
                story = project.stories.find(story_id)
         
     | 
| 
      
 149 
     | 
    
         
            +
                story.update :current_state => "finished"
         
     | 
| 
      
 150 
     | 
    
         
            +
                
         
     | 
| 
      
 151 
     | 
    
         
            +
                puts Formatter.story_action(Formatter.state("finished"), story_id, story.name) + "."
         
     | 
| 
      
 152 
     | 
    
         
            +
              end
         
     | 
| 
      
 153 
     | 
    
         
            +
            end
         
     | 
| 
      
 154 
     | 
    
         
            +
             
     | 
| 
      
 155 
     | 
    
         
            +
            command :create do |c|
         
     | 
| 
      
 156 
     | 
    
         
            +
              c.syntax = "pivotal-slacker create [options]"
         
     | 
| 
      
 157 
     | 
    
         
            +
              c.description = "Create a new task in Pivotal Tracker."
         
     | 
| 
      
 158 
     | 
    
         
            +
              c.example "Create a new task", "pivotal-slacker create --chore --owner \"Jimmy Winkerbean\""
         
     | 
| 
      
 159 
     | 
    
         
            +
              c.option "--feature", "Designate the story as a feature"
         
     | 
| 
      
 160 
     | 
    
         
            +
              c.option "--bug", "Designate the story as a bug"
         
     | 
| 
      
 161 
     | 
    
         
            +
              c.option "--chore", "Designate the story as a chore"
         
     | 
| 
      
 162 
     | 
    
         
            +
              c.option "--release", "Designate the story as a release"
         
     | 
| 
      
 163 
     | 
    
         
            +
              c.option "--owner STRING", String, "Assigns the story to a user"
         
     | 
| 
      
 164 
     | 
    
         
            +
              c.option "--name STRING", String, "Name of story"
         
     | 
| 
      
 165 
     | 
    
         
            +
              c.option "--description STRING", String, "Description of story"
         
     | 
| 
      
 166 
     | 
    
         
            +
              c.action do |args, options|
         
     | 
| 
      
 167 
     | 
    
         
            +
                options.default :chore => false, :owner => config.user, :name => nil, :description => nil
         
     | 
| 
      
 168 
     | 
    
         
            +
                
         
     | 
| 
      
 169 
     | 
    
         
            +
                raise "--name is required" if options.name == nil
         
     | 
| 
      
 170 
     | 
    
         
            +
                raise "--description is required" if options.description == nil
         
     | 
| 
      
 171 
     | 
    
         
            +
             
     | 
| 
      
 172 
     | 
    
         
            +
                story_type = "feature" if options.feature
         
     | 
| 
      
 173 
     | 
    
         
            +
                story_type = "bug" if options.bug
         
     | 
| 
      
 174 
     | 
    
         
            +
                story_type = "chore" if options.chore
         
     | 
| 
      
 175 
     | 
    
         
            +
                story_type = "release" if options.release
         
     | 
| 
      
 176 
     | 
    
         
            +
             
     | 
| 
      
 177 
     | 
    
         
            +
                puts ""
         
     | 
| 
      
 178 
     | 
    
         
            +
                puts Formatter.story_name(options.name, :heading => true)
         
     | 
| 
      
 179 
     | 
    
         
            +
                puts "#{Formatter.attr_descriptor('type is', Formatter.story_type(story_type))}"
         
     | 
| 
      
 180 
     | 
    
         
            +
                puts "#{Formatter.attr_descriptor('requested by', Formatter.owner(config.user))}"
         
     | 
| 
      
 181 
     | 
    
         
            +
                puts "#{Formatter.attr_descriptor('owned by', Formatter.owner(options.owner))}"
         
     | 
| 
      
 182 
     | 
    
         
            +
                puts "#{Formatter.attr_descriptor('description is', Formatter.description(options.description))}"
         
     | 
| 
      
 183 
     | 
    
         
            +
                puts ""
         
     | 
| 
      
 184 
     | 
    
         
            +
                
         
     | 
| 
      
 185 
     | 
    
         
            +
                if agree "Really create? (y/n)"
         
     | 
| 
      
 186 
     | 
    
         
            +
                  story = project.stories.create(
         
     | 
| 
      
 187 
     | 
    
         
            +
                    :name => options.name,
         
     | 
| 
      
 188 
     | 
    
         
            +
                    :story_type => story_type,
         
     | 
| 
      
 189 
     | 
    
         
            +
                    :description => options.description,
         
     | 
| 
      
 190 
     | 
    
         
            +
                    :requested_by => config.user,
         
     | 
| 
      
 191 
     | 
    
         
            +
                    :owned_by => options.owner
         
     | 
| 
      
 192 
     | 
    
         
            +
                  )
         
     | 
| 
      
 193 
     | 
    
         
            +
                  puts Formatter.story_action("Created", story.id, story.name)
         
     | 
| 
      
 194 
     | 
    
         
            +
                else
         
     | 
| 
      
 195 
     | 
    
         
            +
                  puts "Didn't create story."
         
     | 
| 
      
 196 
     | 
    
         
            +
                end
         
     | 
| 
      
 197 
     | 
    
         
            +
              end
         
     | 
| 
      
 198 
     | 
    
         
            +
            end
         
     | 
| 
      
 199 
     | 
    
         
            +
             
     | 
    
        data/lib/app_config.rb
    ADDED
    
    | 
         @@ -0,0 +1,40 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require "rubygems"
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            class AppConfig
         
     | 
| 
      
 4 
     | 
    
         
            +
              FILENAME = ".pt.yaml"
         
     | 
| 
      
 5 
     | 
    
         
            +
              
         
     | 
| 
      
 6 
     | 
    
         
            +
              def self.load
         
     | 
| 
      
 7 
     | 
    
         
            +
                require "yaml"
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
                # Read YAML config or quit.
         
     | 
| 
      
 10 
     | 
    
         
            +
                config = nil
         
     | 
| 
      
 11 
     | 
    
         
            +
                begin
         
     | 
| 
      
 12 
     | 
    
         
            +
                  config = YAML.load_file FILENAME
         
     | 
| 
      
 13 
     | 
    
         
            +
                rescue Exception => e
         
     | 
| 
      
 14 
     | 
    
         
            +
                  raise "No #{FILENAME} file found in current directory; please create one."
         
     | 
| 
      
 15 
     | 
    
         
            +
                end
         
     | 
| 
      
 16 
     | 
    
         
            +
                
         
     | 
| 
      
 17 
     | 
    
         
            +
                AppConfig.new :config => config
         
     | 
| 
      
 18 
     | 
    
         
            +
              end
         
     | 
| 
      
 19 
     | 
    
         
            +
              
         
     | 
| 
      
 20 
     | 
    
         
            +
              def initialize opts={:config => Hash.new}
         
     | 
| 
      
 21 
     | 
    
         
            +
                @config = opts[:config]
         
     | 
| 
      
 22 
     | 
    
         
            +
                
         
     | 
| 
      
 23 
     | 
    
         
            +
                raise "Config must include \"project\" key" if not @config.has_key? "project"
         
     | 
| 
      
 24 
     | 
    
         
            +
                raise "Config must include \"api_key\" key" if not @config.has_key? "api_key"
         
     | 
| 
      
 25 
     | 
    
         
            +
                raise "Config must include \"user\" key" if not @config.has_key? "user"
         
     | 
| 
      
 26 
     | 
    
         
            +
              end
         
     | 
| 
      
 27 
     | 
    
         
            +
              
         
     | 
| 
      
 28 
     | 
    
         
            +
              def project
         
     | 
| 
      
 29 
     | 
    
         
            +
                @config["project"]
         
     | 
| 
      
 30 
     | 
    
         
            +
              end
         
     | 
| 
      
 31 
     | 
    
         
            +
              
         
     | 
| 
      
 32 
     | 
    
         
            +
              def api_key
         
     | 
| 
      
 33 
     | 
    
         
            +
                @config["api_key"]
         
     | 
| 
      
 34 
     | 
    
         
            +
              end
         
     | 
| 
      
 35 
     | 
    
         
            +
              
         
     | 
| 
      
 36 
     | 
    
         
            +
              def user
         
     | 
| 
      
 37 
     | 
    
         
            +
                @config["user"]
         
     | 
| 
      
 38 
     | 
    
         
            +
              end
         
     | 
| 
      
 39 
     | 
    
         
            +
              
         
     | 
| 
      
 40 
     | 
    
         
            +
            end
         
     | 
    
        data/lib/formatter.rb
    ADDED
    
    | 
         @@ -0,0 +1,65 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # encoding: utf-8
         
     | 
| 
      
 2 
     | 
    
         
            +
            require "rubygems"
         
     | 
| 
      
 3 
     | 
    
         
            +
            require "rainbow"
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            class Formatter
         
     | 
| 
      
 6 
     | 
    
         
            +
              def self.story_id id
         
     | 
| 
      
 7 
     | 
    
         
            +
                id.to_s.color("#404040")
         
     | 
| 
      
 8 
     | 
    
         
            +
              end
         
     | 
| 
      
 9 
     | 
    
         
            +
              
         
     | 
| 
      
 10 
     | 
    
         
            +
              def self.state state
         
     | 
| 
      
 11 
     | 
    
         
            +
                if state == "finished"
         
     | 
| 
      
 12 
     | 
    
         
            +
                  # state = state.color('009900').bright #background('009900').color('ffffff')
         
     | 
| 
      
 13 
     | 
    
         
            +
                  " ✓ #{state} ".background('#4C9900').bright.underline
         
     | 
| 
      
 14 
     | 
    
         
            +
                elsif state == "accepted"
         
     | 
| 
      
 15 
     | 
    
         
            +
                  " ✓ #{state} ".background('#0080ff').color(:black).underline
         
     | 
| 
      
 16 
     | 
    
         
            +
                else
         
     | 
| 
      
 17 
     | 
    
         
            +
                  state = state.bright # .background(:green).underline
         
     | 
| 
      
 18 
     | 
    
         
            +
                end
         
     | 
| 
      
 19 
     | 
    
         
            +
              end
         
     | 
| 
      
 20 
     | 
    
         
            +
              
         
     | 
| 
      
 21 
     | 
    
         
            +
              def self.requested_by requested_by
         
     | 
| 
      
 22 
     | 
    
         
            +
                requested_by.color("#3399ff")
         
     | 
| 
      
 23 
     | 
    
         
            +
              end
         
     | 
| 
      
 24 
     | 
    
         
            +
              
         
     | 
| 
      
 25 
     | 
    
         
            +
              def self.owner owner
         
     | 
| 
      
 26 
     | 
    
         
            +
                self.requested_by owner
         
     | 
| 
      
 27 
     | 
    
         
            +
              end
         
     | 
| 
      
 28 
     | 
    
         
            +
              
         
     | 
| 
      
 29 
     | 
    
         
            +
              def self.story_name story_name, opts={:heading => false}
         
     | 
| 
      
 30 
     | 
    
         
            +
                if opts[:heading] == true
         
     | 
| 
      
 31 
     | 
    
         
            +
                  story_name.bright.underline
         
     | 
| 
      
 32 
     | 
    
         
            +
                else
         
     | 
| 
      
 33 
     | 
    
         
            +
                  story_name
         
     | 
| 
      
 34 
     | 
    
         
            +
                end
         
     | 
| 
      
 35 
     | 
    
         
            +
              end
         
     | 
| 
      
 36 
     | 
    
         
            +
              
         
     | 
| 
      
 37 
     | 
    
         
            +
              def self.time_ago time
         
     | 
| 
      
 38 
     | 
    
         
            +
                (distance_of_time_in_words(Time.now, time) + " ago").color('#404040')
         
     | 
| 
      
 39 
     | 
    
         
            +
              end
         
     | 
| 
      
 40 
     | 
    
         
            +
              
         
     | 
| 
      
 41 
     | 
    
         
            +
              def self.note_author author
         
     | 
| 
      
 42 
     | 
    
         
            +
                self.requested_by(author)
         
     | 
| 
      
 43 
     | 
    
         
            +
              end
         
     | 
| 
      
 44 
     | 
    
         
            +
              
         
     | 
| 
      
 45 
     | 
    
         
            +
              def self.note_text text
         
     | 
| 
      
 46 
     | 
    
         
            +
                text.bright
         
     | 
| 
      
 47 
     | 
    
         
            +
              end
         
     | 
| 
      
 48 
     | 
    
         
            +
              
         
     | 
| 
      
 49 
     | 
    
         
            +
              def self.story_action comment, story_id, story_name
         
     | 
| 
      
 50 
     | 
    
         
            +
                story_name = Formatter.story_name(story_name, :heading => true)
         
     | 
| 
      
 51 
     | 
    
         
            +
                "#{comment} #{Formatter.story_id(story_id)}, #{story_name}"
         
     | 
| 
      
 52 
     | 
    
         
            +
              end
         
     | 
| 
      
 53 
     | 
    
         
            +
              
         
     | 
| 
      
 54 
     | 
    
         
            +
              def self.story_type type
         
     | 
| 
      
 55 
     | 
    
         
            +
                type.color '#99004C'
         
     | 
| 
      
 56 
     | 
    
         
            +
              end
         
     | 
| 
      
 57 
     | 
    
         
            +
              
         
     | 
| 
      
 58 
     | 
    
         
            +
              def self.attr_descriptor descriptor, attr
         
     | 
| 
      
 59 
     | 
    
         
            +
                "#{descriptor} → ".color('#333333') + attr
         
     | 
| 
      
 60 
     | 
    
         
            +
              end
         
     | 
| 
      
 61 
     | 
    
         
            +
              
         
     | 
| 
      
 62 
     | 
    
         
            +
              def self.description description
         
     | 
| 
      
 63 
     | 
    
         
            +
                description
         
     | 
| 
      
 64 
     | 
    
         
            +
              end
         
     | 
| 
      
 65 
     | 
    
         
            +
            end
         
     | 
    
        metadata
    ADDED
    
    | 
         @@ -0,0 +1,49 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            --- !ruby/object:Gem::Specification
         
     | 
| 
      
 2 
     | 
    
         
            +
            name: pivotal-slacker
         
     | 
| 
      
 3 
     | 
    
         
            +
            version: !ruby/object:Gem::Version
         
     | 
| 
      
 4 
     | 
    
         
            +
              version: 1.0.1
         
     | 
| 
      
 5 
     | 
    
         
            +
              prerelease: 
         
     | 
| 
      
 6 
     | 
    
         
            +
            platform: ruby
         
     | 
| 
      
 7 
     | 
    
         
            +
            authors:
         
     | 
| 
      
 8 
     | 
    
         
            +
            - Sean Gilbertson
         
     | 
| 
      
 9 
     | 
    
         
            +
            autorequire: 
         
     | 
| 
      
 10 
     | 
    
         
            +
            bindir: bin
         
     | 
| 
      
 11 
     | 
    
         
            +
            cert_chain: []
         
     | 
| 
      
 12 
     | 
    
         
            +
            date: 2013-02-04 00:00:00.000000000 Z
         
     | 
| 
      
 13 
     | 
    
         
            +
            dependencies: []
         
     | 
| 
      
 14 
     | 
    
         
            +
            description: If you're overwhelmed with or tired of using the Pivotal Tracker web
         
     | 
| 
      
 15 
     | 
    
         
            +
              UI, use this!
         
     | 
| 
      
 16 
     | 
    
         
            +
            email: sean.gilbertson@gmail.com
         
     | 
| 
      
 17 
     | 
    
         
            +
            executables:
         
     | 
| 
      
 18 
     | 
    
         
            +
            - pivotal-slacker
         
     | 
| 
      
 19 
     | 
    
         
            +
            extensions: []
         
     | 
| 
      
 20 
     | 
    
         
            +
            extra_rdoc_files: []
         
     | 
| 
      
 21 
     | 
    
         
            +
            files:
         
     | 
| 
      
 22 
     | 
    
         
            +
            - lib/formatter.rb
         
     | 
| 
      
 23 
     | 
    
         
            +
            - lib/app_config.rb
         
     | 
| 
      
 24 
     | 
    
         
            +
            - bin/pivotal-slacker
         
     | 
| 
      
 25 
     | 
    
         
            +
            homepage: https://github.com/dreki/pivotal-slacker
         
     | 
| 
      
 26 
     | 
    
         
            +
            licenses: []
         
     | 
| 
      
 27 
     | 
    
         
            +
            post_install_message: 
         
     | 
| 
      
 28 
     | 
    
         
            +
            rdoc_options: []
         
     | 
| 
      
 29 
     | 
    
         
            +
            require_paths:
         
     | 
| 
      
 30 
     | 
    
         
            +
            - lib
         
     | 
| 
      
 31 
     | 
    
         
            +
            required_ruby_version: !ruby/object:Gem::Requirement
         
     | 
| 
      
 32 
     | 
    
         
            +
              none: false
         
     | 
| 
      
 33 
     | 
    
         
            +
              requirements:
         
     | 
| 
      
 34 
     | 
    
         
            +
              - - ! '>='
         
     | 
| 
      
 35 
     | 
    
         
            +
                - !ruby/object:Gem::Version
         
     | 
| 
      
 36 
     | 
    
         
            +
                  version: '0'
         
     | 
| 
      
 37 
     | 
    
         
            +
            required_rubygems_version: !ruby/object:Gem::Requirement
         
     | 
| 
      
 38 
     | 
    
         
            +
              none: false
         
     | 
| 
      
 39 
     | 
    
         
            +
              requirements:
         
     | 
| 
      
 40 
     | 
    
         
            +
              - - ! '>='
         
     | 
| 
      
 41 
     | 
    
         
            +
                - !ruby/object:Gem::Version
         
     | 
| 
      
 42 
     | 
    
         
            +
                  version: '0'
         
     | 
| 
      
 43 
     | 
    
         
            +
            requirements: []
         
     | 
| 
      
 44 
     | 
    
         
            +
            rubyforge_project: 
         
     | 
| 
      
 45 
     | 
    
         
            +
            rubygems_version: 1.8.25
         
     | 
| 
      
 46 
     | 
    
         
            +
            signing_key: 
         
     | 
| 
      
 47 
     | 
    
         
            +
            specification_version: 3
         
     | 
| 
      
 48 
     | 
    
         
            +
            summary: A command-line client for Pivotal Tracker.
         
     | 
| 
      
 49 
     | 
    
         
            +
            test_files: []
         
     |