yapt 0.0.1 → 0.0.2
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.
- checksums.yaml +4 -4
- data/.gitignore +1 -1
- data/Gemfile +0 -1
- data/README.md +23 -1
- data/lib/yapt/config.rb +36 -0
- data/lib/yapt/filter.rb +0 -2
- data/lib/yapt/move.rb +28 -0
- data/lib/yapt/request.rb +26 -9
- data/lib/yapt/story.rb +90 -3
- data/lib/yapt/templates/detail.erb +12 -0
- data/lib/yapt/templates/simple.erb +3 -0
- data/lib/yapt/version.rb +1 -1
- data/lib/yapt/view.rb +15 -61
- data/lib/yapt.rb +58 -12
- metadata +6 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 23de5c03a7ac130c7f824eb67fb29f3e16f33a52
|
4
|
+
data.tar.gz: 1cc941043e57e0e3557d506bb2f176d0dddf7d1f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a700985a6d0e2e93665ffa341acec9b17c01cdc498c2f2e2d0274411f8918ef897f1b9689766d8f64076f5b6923fc4c41e944f540fc57298a01e15f2d89df9fb
|
7
|
+
data.tar.gz: db5d1a4cfb1d4d4e237838dc490532375ae6dfe1bb64f2ce29718e87220dbd58c6ef772531ac11898b8da0e785a5312ac0896fb67092e53b56b0a2798c3f85a9
|
data/.gitignore
CHANGED
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -8,13 +8,35 @@ A command line Pivotal Tracker client. In early days.
|
|
8
8
|
|
9
9
|
## Usage
|
10
10
|
|
11
|
-
|
11
|
+
Put these in a yaml .yapt file in your project or ~ directory:
|
12
12
|
|
13
13
|
* api_token
|
14
14
|
* project_id
|
15
15
|
|
16
16
|
yapt list "created_since=last friday" limit=5 keyword
|
17
17
|
|
18
|
+
Use a different template with v(iew)=
|
19
|
+
|
20
|
+
```
|
21
|
+
yapt list v=detail
|
22
|
+
yapt list view=simple
|
23
|
+
```
|
24
|
+
|
25
|
+
Check out an individual story...
|
26
|
+
|
27
|
+
```
|
28
|
+
yapt show 12345
|
29
|
+
```
|
30
|
+
|
31
|
+
Move it ...
|
32
|
+
|
33
|
+
```
|
34
|
+
yapt move 12345 54321 # move 12345 just above 54321
|
35
|
+
yapt move 12345 tback # move 12345 to top of backlog
|
36
|
+
```
|
37
|
+
|
38
|
+
Other keywords: ticebox, tice, bback, tbacklog, bice, bicebox
|
39
|
+
|
18
40
|
## Contributing
|
19
41
|
|
20
42
|
1. Fork it
|
data/lib/yapt/config.rb
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
|
3
|
+
module Yapt
|
4
|
+
class Config
|
5
|
+
attr_reader :project_path
|
6
|
+
def initialize(project_path)
|
7
|
+
@project_path = project_path
|
8
|
+
end
|
9
|
+
|
10
|
+
def project_id
|
11
|
+
config.fetch('project_id')
|
12
|
+
end
|
13
|
+
|
14
|
+
def api_token
|
15
|
+
config.fetch('api_token')
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def load_or_hash(path)
|
21
|
+
YAML.load_file(path) rescue Hash.new
|
22
|
+
end
|
23
|
+
|
24
|
+
def config
|
25
|
+
@config ||= user_config.merge(project_config)
|
26
|
+
end
|
27
|
+
|
28
|
+
def project_config
|
29
|
+
load_or_hash("#{project_path}/.yapt")
|
30
|
+
end
|
31
|
+
|
32
|
+
def user_config
|
33
|
+
load_or_hash("#{Dir.home}/.yapt")
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
data/lib/yapt/filter.rb
CHANGED
data/lib/yapt/move.rb
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
module Yapt
|
2
|
+
class Move
|
3
|
+
def self.setup(id, target_id)
|
4
|
+
to_move = Story.find(id)
|
5
|
+
target = Story.find(target_id)
|
6
|
+
new(to_move, target)
|
7
|
+
end
|
8
|
+
|
9
|
+
attr_reader :to_move, :target
|
10
|
+
def initialize(to_move, target)
|
11
|
+
@to_move, @target = to_move, target
|
12
|
+
end
|
13
|
+
|
14
|
+
def description
|
15
|
+
"Move #{to_move.id} just above #{target.id}"
|
16
|
+
end
|
17
|
+
|
18
|
+
def params
|
19
|
+
{
|
20
|
+
before_id: target.id
|
21
|
+
}
|
22
|
+
end
|
23
|
+
|
24
|
+
def execute!
|
25
|
+
Request.new("stories/#{to_move.id}", params, :put).result
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
data/lib/yapt/request.rb
CHANGED
@@ -2,24 +2,41 @@ require "rest-client"
|
|
2
2
|
|
3
3
|
module Yapt
|
4
4
|
class Request
|
5
|
+
attr_reader :method, :path, :params
|
5
6
|
def initialize(path, params = {}, method = :get)
|
6
|
-
@
|
7
|
+
@method, @path, @params = method, path, params
|
7
8
|
end
|
8
9
|
|
9
10
|
def result
|
10
|
-
|
11
|
+
request(method, params)
|
11
12
|
end
|
12
13
|
|
13
|
-
def
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
params: params,
|
18
|
-
"X-TrackerToken" => Yapt.api_token
|
14
|
+
def request(method, payload)
|
15
|
+
options = {
|
16
|
+
"X-TrackerToken" => Yapt.api_token,
|
17
|
+
"Content-Type" => "application/json"
|
19
18
|
}
|
19
|
+
response_handling = ->(response, request, result, &block) {
|
20
|
+
case response.code
|
21
|
+
when 200
|
22
|
+
JSON.parse(response.to_s)
|
23
|
+
else
|
24
|
+
puts "Non-200 response!"
|
25
|
+
puts response.to_s
|
26
|
+
end
|
27
|
+
}
|
28
|
+
if method == :get
|
29
|
+
RestClient.get(url, options.merge(params: payload), &response_handling)
|
30
|
+
else
|
31
|
+
RestClient.send(method, url, payload, options, &response_handling)
|
32
|
+
end
|
20
33
|
end
|
21
34
|
|
22
|
-
def
|
35
|
+
def url
|
36
|
+
"#{self.class.base_url}/#{path}"
|
37
|
+
end
|
38
|
+
|
39
|
+
def self.base_url
|
23
40
|
"https://www.pivotaltracker.com/
|
24
41
|
services/v5/projects/#{Yapt.project_id}".gsub(/\s+/,'')
|
25
42
|
end
|
data/lib/yapt/story.rb
CHANGED
@@ -1,11 +1,98 @@
|
|
1
1
|
module Yapt
|
2
2
|
class Story
|
3
3
|
def self.find(options = ["limit=5"])
|
4
|
+
return find_one(options) if options.kind_of?(String)
|
4
5
|
params = Filter.parse(options)
|
5
|
-
puts View.headline(params[:filter])
|
6
|
-
puts
|
7
6
|
results = Request.new("stories", params, :get).result
|
8
|
-
|
7
|
+
results.collect {|r| new(r) }
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.find_one(id)
|
11
|
+
case id
|
12
|
+
when /\A\d+\Z/ then find_by_id(id)
|
13
|
+
when 'tback' then top_of_backlog
|
14
|
+
when 'tbacklog' then top_of_backlog
|
15
|
+
when 'tice' then top_of_icebox
|
16
|
+
when 'ticebox' then top_of_icebox
|
17
|
+
|
18
|
+
when 'bback' then bottom_of_backlog
|
19
|
+
when 'bbacklog' then bottom_of_backlog
|
20
|
+
when 'bice' then bottom_of_icebox
|
21
|
+
when 'bicebox' then bottom_of_icebox
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.find_by_id(id)
|
26
|
+
new(Request.new("stories/#{id}", {}, :get).result)
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.top_of_backlog
|
30
|
+
find(["state:unstarted", "limit:1"]).first
|
31
|
+
end
|
32
|
+
|
33
|
+
def self.top_of_icebox
|
34
|
+
find(["state:unscheduled", "limit:1"]).first
|
35
|
+
end
|
36
|
+
|
37
|
+
def self.bottom_of_backlog
|
38
|
+
find(["state:unstarted"]).last
|
39
|
+
end
|
40
|
+
|
41
|
+
def self.bottom_of_icebox
|
42
|
+
find(["state:unscheduled"]).last
|
43
|
+
end
|
44
|
+
|
45
|
+
def self.just_url(id)
|
46
|
+
if id
|
47
|
+
"#{base_site_url}/stories/#{id}"
|
48
|
+
else
|
49
|
+
base_site_url
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def self.images_url(id)
|
54
|
+
"#{just_url(id)}/images"
|
55
|
+
end
|
56
|
+
|
57
|
+
def self.base_site_url
|
58
|
+
"https://www.pivotaltracker.com/s/projects/#{Yapt.project_id}"
|
59
|
+
end
|
60
|
+
|
61
|
+
attr_reader :raw_story
|
62
|
+
def initialize(raw_story)
|
63
|
+
@raw_story = raw_story
|
64
|
+
end
|
65
|
+
|
66
|
+
[:url, :story_type, :description, :id,
|
67
|
+
:current_state, :labels, :owned_by_id, :created_at, :kind,
|
68
|
+
:project_id, :requested_by_id, :updated_at, :name].each do |attr|
|
69
|
+
define_method attr do
|
70
|
+
raw_story[attr.to_s]
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def owner_initials
|
75
|
+
if owned_by_id
|
76
|
+
"Owner: #{Member.find(owned_by_id).initials}"
|
77
|
+
else
|
78
|
+
"No owner"
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
def requester_initials
|
83
|
+
"Requester: #{Member.find(requested_by_id).initials}"
|
84
|
+
end
|
85
|
+
|
86
|
+
def created_at_display
|
87
|
+
"Created: #{time_display(created_at)}"
|
88
|
+
end
|
89
|
+
|
90
|
+
def updated_at_display
|
91
|
+
"Updated: #{time_display(updated_at)}"
|
92
|
+
end
|
93
|
+
|
94
|
+
def time_display(time)
|
95
|
+
Time.parse(time).strftime("%a %d%b %I:%M")
|
9
96
|
end
|
10
97
|
end
|
11
98
|
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
<% @stories.each do |story| -%>
|
2
|
+
<%= story.id %> | <%= story.name %>
|
3
|
+
<%= story.description %>
|
4
|
+
<%= '-' * 100 %>
|
5
|
+
<%= story.created_at_display %> | <%= story.updated_at_display %> | <%= story.current_state %> | <%= story.requester_initials %> | <%= story.owner_initials %>
|
6
|
+
<%= '=' * 100 %>
|
7
|
+
<% end %>
|
8
|
+
<% if false %>
|
9
|
+
[:url, :story_type, :description, :id,
|
10
|
+
:current_state, :labels, :owned_by_id, :created_at, :kind,
|
11
|
+
:project_id, :requested_by_id, :updated_at, :name].each do |attr|
|
12
|
+
<% end %>
|
data/lib/yapt/version.rb
CHANGED
data/lib/yapt/view.rb
CHANGED
@@ -1,75 +1,29 @@
|
|
1
|
-
require
|
1
|
+
require 'erb'
|
2
2
|
|
3
3
|
module Yapt
|
4
4
|
class View
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
:project_id, :requested_by_id, :updated_at, :name
|
10
|
-
|
11
|
-
def self.headline(str)
|
12
|
-
"About to display: #{str}"
|
13
|
-
end
|
14
|
-
|
15
|
-
def self.display(stories)
|
16
|
-
stories.inject("") do |str, story|
|
17
|
-
str + new(story).to_s
|
18
|
-
end
|
5
|
+
def self.extract_display_config(args)
|
6
|
+
display = args.detect {|a| a =~ /\Av(iew)?[=:]/ }
|
7
|
+
args.delete(display)
|
8
|
+
display ? display.split(/[=:]/).last : nil
|
19
9
|
end
|
20
10
|
|
21
|
-
|
22
|
-
|
23
|
-
@story = OpenStruct.new(story)
|
11
|
+
def initialize(stories)
|
12
|
+
@stories = stories
|
24
13
|
end
|
25
14
|
|
26
|
-
def
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
].inject("") do |str, element|
|
32
|
-
str += "#{send(element)}"
|
33
|
-
element == :nl ? str : "#{str} | "
|
34
|
-
end.gsub(/\| $/, '')
|
35
|
-
end
|
36
|
-
|
37
|
-
private
|
38
|
-
|
39
|
-
def owner_initials
|
40
|
-
if owned_by_id
|
41
|
-
"Owner: #{Member.find(owned_by_id).initials}"
|
15
|
+
def display(template_name)
|
16
|
+
template_path = "#{template_dir}/#{template_name}.erb"
|
17
|
+
if File.exists?(template_path)
|
18
|
+
template = IO.read template_path
|
19
|
+
ERB.new(template, 0, '-').result(binding)
|
42
20
|
else
|
43
|
-
"
|
21
|
+
raise "#{template_path} missing!"
|
44
22
|
end
|
45
23
|
end
|
46
24
|
|
47
|
-
def
|
48
|
-
"
|
49
|
-
end
|
50
|
-
|
51
|
-
def created_at_display
|
52
|
-
"Created: #{time_display(created_at)}"
|
53
|
-
end
|
54
|
-
|
55
|
-
def updated_at_display
|
56
|
-
"Updated: #{time_display(updated_at)}"
|
57
|
-
end
|
58
|
-
|
59
|
-
def time_display(time)
|
60
|
-
Time.parse(time).strftime("%a %d%b %I:%M")
|
61
|
-
end
|
62
|
-
|
63
|
-
def id_name
|
64
|
-
"#{story.id} | #{story.name}\n"
|
65
|
-
end
|
66
|
-
|
67
|
-
def nl
|
68
|
-
"\n"
|
25
|
+
def template_dir
|
26
|
+
"#{File.dirname(__FILE__)}/templates"
|
69
27
|
end
|
70
28
|
end
|
71
29
|
end
|
72
|
-
# ["url", "story_type", "description", "id", "current_state",
|
73
|
-
# "labels", "owned_by_id", "created_at", "kind", "project_id",
|
74
|
-
# "requested_by_id", "updated_at", "name"]
|
75
|
-
|
data/lib/yapt.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
|
-
require '
|
2
|
-
|
1
|
+
require 'pry'
|
2
|
+
require 'highline/import'
|
3
3
|
|
4
4
|
module Yapt
|
5
5
|
autoload :VERSION, "yapt/version"
|
@@ -8,13 +8,19 @@ module Yapt
|
|
8
8
|
autoload :View, "yapt/view"
|
9
9
|
autoload :Member, "yapt/member"
|
10
10
|
autoload :Request, "yapt/request"
|
11
|
+
autoload :Config, "yapt/config"
|
12
|
+
autoload :Move, "yapt/move"
|
13
|
+
|
14
|
+
def self.config
|
15
|
+
@config ||= Config.new(Dir.pwd)
|
16
|
+
end
|
11
17
|
|
12
18
|
def self.project_id
|
13
|
-
|
19
|
+
config.project_id
|
14
20
|
end
|
15
21
|
|
16
22
|
def self.api_token
|
17
|
-
|
23
|
+
config.api_token
|
18
24
|
end
|
19
25
|
|
20
26
|
def self.cache_duration
|
@@ -30,20 +36,60 @@ module Yapt
|
|
30
36
|
end
|
31
37
|
|
32
38
|
class Runner < Boson::Runner
|
33
|
-
|
39
|
+
attr_reader :start_time
|
40
|
+
def initialize
|
41
|
+
@start_time = Time.now
|
42
|
+
super
|
43
|
+
end
|
44
|
+
|
34
45
|
def list(*args)
|
46
|
+
display_config = View.extract_display_config(args)
|
47
|
+
@stories = Story.find(args)
|
48
|
+
display_config ||= (@stories.length > 1) ? "simple" : "detail"
|
49
|
+
output View.new(@stories).display(display_config)
|
50
|
+
end
|
51
|
+
|
52
|
+
def show(id)
|
53
|
+
@story = Story.find(id)
|
54
|
+
output View.new([@story]).display("detail")
|
55
|
+
end
|
56
|
+
|
57
|
+
def open(id = nil)
|
58
|
+
system_open Story.just_url(id)
|
59
|
+
end
|
60
|
+
|
61
|
+
def images(id)
|
62
|
+
system_open Story.images_url(id)
|
63
|
+
end
|
64
|
+
|
65
|
+
def move(id, destination)
|
66
|
+
mover = Move.setup(id, destination)
|
35
67
|
puts
|
36
|
-
puts
|
37
|
-
puts
|
38
|
-
|
68
|
+
puts mover.description
|
69
|
+
puts View.new([mover.to_move, mover.target]).display("simple")
|
70
|
+
|
71
|
+
permission = ask("Make this move? ").downcase
|
72
|
+
if %w(y yes).include?(permission)
|
73
|
+
mover.execute!
|
74
|
+
puts "Moved!"
|
75
|
+
else
|
76
|
+
puts "Aborted. Oh well."
|
77
|
+
end
|
39
78
|
end
|
40
79
|
|
41
|
-
|
42
|
-
|
80
|
+
private
|
81
|
+
|
82
|
+
def system_open(whatever)
|
83
|
+
puts "Opening: #{whatever}"
|
84
|
+
system "open #{whatever}"
|
43
85
|
end
|
44
86
|
|
45
|
-
def
|
46
|
-
puts
|
87
|
+
def output(str)
|
88
|
+
puts
|
89
|
+
puts str
|
90
|
+
puts
|
91
|
+
puts "Took #{Time.now - start_time} seconds."
|
92
|
+
puts
|
47
93
|
end
|
48
94
|
end
|
49
95
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: yapt
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sam Schenkman-Moore
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2014-01-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: boson
|
@@ -109,10 +109,14 @@ files:
|
|
109
109
|
- Rakefile
|
110
110
|
- bin/yapt
|
111
111
|
- lib/yapt.rb
|
112
|
+
- lib/yapt/config.rb
|
112
113
|
- lib/yapt/filter.rb
|
113
114
|
- lib/yapt/member.rb
|
115
|
+
- lib/yapt/move.rb
|
114
116
|
- lib/yapt/request.rb
|
115
117
|
- lib/yapt/story.rb
|
118
|
+
- lib/yapt/templates/detail.erb
|
119
|
+
- lib/yapt/templates/simple.erb
|
116
120
|
- lib/yapt/version.rb
|
117
121
|
- lib/yapt/view.rb
|
118
122
|
- yapt.gemspec
|