ptlog 0.1.1 → 0.2.0
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/Gemfile +2 -1
- data/lib/ptlog/capistrno.rb +2 -1
- data/lib/ptlog/change_log.rb +103 -0
- data/lib/ptlog/pivotal/api.rb +44 -0
- data/lib/ptlog/pivotal/story.rb +34 -0
- data/lib/ptlog/version.rb +1 -1
- data/lib/ptlog.rb +9 -0
- data/ptlog.gemspec +2 -1
- metadata +29 -11
data/Gemfile
CHANGED
data/lib/ptlog/capistrno.rb
CHANGED
@@ -4,7 +4,8 @@ Capistrano::Configuration.instance(:must_exist).load do
|
|
4
4
|
namespace :ptlog do
|
5
5
|
desc "Generates changelog"
|
6
6
|
task :changes do
|
7
|
-
|
7
|
+
# put PTLog::ChangeLog.generate, "#{release_path}/public/changelog.html"
|
8
|
+
puts PTLog::ChangeLog.generate
|
8
9
|
end
|
9
10
|
|
10
11
|
desc "Generates release file. RESTART=(true|false) option could be specified (by default is true)"
|
data/lib/ptlog/change_log.rb
CHANGED
@@ -1,4 +1,107 @@
|
|
1
|
+
require 'git'
|
2
|
+
require 'nokogiri'
|
3
|
+
|
4
|
+
module Git
|
5
|
+
class Lib
|
6
|
+
def ordered_tags
|
7
|
+
command_lines("for-each-ref --sort='*authordate' --format='%(tag)' refs/tags")
|
8
|
+
end
|
9
|
+
def first_commit
|
10
|
+
command("rev-list --max-parents=0 HEAD")
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
|
16
|
+
|
1
17
|
module PTLog
|
18
|
+
class TagList
|
19
|
+
include Enumerable
|
20
|
+
|
21
|
+
def initialize(git, since)
|
22
|
+
@list = git.lib.ordered_tags
|
23
|
+
@since = since
|
24
|
+
@first_commit = git.lib.first_commit
|
25
|
+
end
|
26
|
+
|
27
|
+
def each(options = {})
|
28
|
+
list_after_item = @list[@list.index(@since), @list.size]
|
29
|
+
|
30
|
+
if block_given?
|
31
|
+
list_after_item.reverse.each { |e| yield(e) }
|
32
|
+
else
|
33
|
+
Enumerator.new(list_after_item.reverse, :each)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def next_to(name)
|
38
|
+
@list[@list.index(name) + 1] || 'HEAD'
|
39
|
+
end
|
40
|
+
|
41
|
+
def prev_to(name)
|
42
|
+
0 < @list.index(name) && @list[@list.index(name) - 1] or @first_commit
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
2
46
|
class ChangeLog
|
47
|
+
attr_reader :git, :tags
|
48
|
+
|
49
|
+
def initialize
|
50
|
+
@git ||= Git.open(Dir.getwd)
|
51
|
+
@start = ENV['PTLOG_SINCE'] || git.lib.ordered_tags[-2]
|
52
|
+
@tags = PTLog::TagList.new(@git, @start)
|
53
|
+
end
|
54
|
+
|
55
|
+
def log(from, to)
|
56
|
+
git.log.between(from, to)
|
57
|
+
end
|
58
|
+
|
59
|
+
def stories(from, to)
|
60
|
+
output = {}
|
61
|
+
log(from, to).each do |commit|
|
62
|
+
commit.message.scan(/\#(\d+)/).flatten.each do |num|
|
63
|
+
output[num] ||= []
|
64
|
+
output[num] << commit.message
|
65
|
+
end
|
66
|
+
end
|
67
|
+
output
|
68
|
+
end
|
69
|
+
|
70
|
+
def self.generate
|
71
|
+
raise GeneralError, "You have to specify Pivotal token with export PIVOTAL_TOKEN=xyz" unless ENV.has_key?('PIVOTAL_TOKEN')
|
72
|
+
|
73
|
+
changelog = new
|
74
|
+
|
75
|
+
@builder = Nokogiri::HTML::Builder.new(:encoding => 'UTF-8') do |doc|
|
76
|
+
doc.body do
|
77
|
+
doc.h1 "ChangeLog"
|
78
|
+
changelog.tags.each do |tag|
|
79
|
+
doc.h2 "Release #{tag}"
|
80
|
+
changelog.stories(changelog.tags.prev_to(tag), tag).each do |num, messages|
|
81
|
+
doc.div(class: 'story') do
|
82
|
+
story = Pivotal::Story.get(num)
|
83
|
+
doc.h3 do
|
84
|
+
if story.valid?
|
85
|
+
doc.a(href: story.url) do
|
86
|
+
doc.text "##{num}"
|
87
|
+
end
|
88
|
+
doc.text " - #{story.name}"
|
89
|
+
else
|
90
|
+
doc.text "##{num} - #{story.error}"
|
91
|
+
end
|
92
|
+
end
|
93
|
+
doc.ul(class: 'commits') do
|
94
|
+
messages.each do |message|
|
95
|
+
doc.li message
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
@builder.to_html
|
105
|
+
end
|
3
106
|
end
|
4
107
|
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require 'faraday'
|
2
|
+
require 'faraday_middleware'
|
3
|
+
|
4
|
+
module PTLog
|
5
|
+
module Pivotal
|
6
|
+
class API
|
7
|
+
class << self
|
8
|
+
def connection
|
9
|
+
@connection ||= Faraday.new 'https://www.pivotaltracker.com/services/v5' do |faraday|
|
10
|
+
faraday.request :json
|
11
|
+
faraday.response :json, :content_type => /\bjson$/
|
12
|
+
faraday.adapter Faraday.default_adapter
|
13
|
+
faraday.headers['X-TrackerToken'] = ENV['PIVOTAL_TOKEN']
|
14
|
+
faraday.options[:timeout] = 30
|
15
|
+
faraday.options[:open_timeout] = 30
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def get(uri)
|
20
|
+
begin
|
21
|
+
response = connection.get(uri)
|
22
|
+
|
23
|
+
raise Pivotal::NetworkError unless response.status == 200
|
24
|
+
|
25
|
+
response.body
|
26
|
+
rescue Pivotal::NetworkError, Faraday::Error::TimeoutError => e
|
27
|
+
{
|
28
|
+
'kind' => 'error',
|
29
|
+
'error' => 'Unable to fetch data'
|
30
|
+
}
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def story(id)
|
35
|
+
get("stories/#{id}")
|
36
|
+
end
|
37
|
+
|
38
|
+
def epic(id)
|
39
|
+
get("epics/#{id}")
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'faraday'
|
2
|
+
|
3
|
+
module PTLog
|
4
|
+
module Pivotal
|
5
|
+
class Story
|
6
|
+
def initialize(story_id)
|
7
|
+
@story = Pivotal::API.story(story_id)
|
8
|
+
@labels = @story['labels'].map { |label| label['name'] } if @story['labels'].is_a?(Array)
|
9
|
+
end
|
10
|
+
|
11
|
+
def invalid?
|
12
|
+
@story['kind'] == 'error'
|
13
|
+
end
|
14
|
+
|
15
|
+
def valid?
|
16
|
+
!invalid?
|
17
|
+
end
|
18
|
+
|
19
|
+
def method_missing(meth)
|
20
|
+
if @story.has_key?(meth.to_s)
|
21
|
+
@story[meth.to_s]
|
22
|
+
else
|
23
|
+
super
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.get(id)
|
28
|
+
return @stories[id] if defined?(@stories) and @stories[id]
|
29
|
+
@stories ||= {}
|
30
|
+
@stories[id] = new(id)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
data/lib/ptlog/version.rb
CHANGED
data/lib/ptlog.rb
CHANGED
@@ -1,6 +1,15 @@
|
|
1
1
|
require "ptlog/version"
|
2
2
|
|
3
3
|
module PTLog
|
4
|
+
class GeneralError < StandardError; end
|
5
|
+
|
6
|
+
module Pivotal
|
7
|
+
class NetworkError < StandardError; end
|
8
|
+
|
9
|
+
autoload :Story, "ptlog/pivotal/story"
|
10
|
+
autoload :API, "ptlog/pivotal/api"
|
11
|
+
end
|
12
|
+
|
4
13
|
autoload :Release, "ptlog/release"
|
5
14
|
autoload :ChangeLog, "ptlog/change_log"
|
6
15
|
end
|
data/ptlog.gemspec
CHANGED
@@ -21,7 +21,8 @@ Gem::Specification.new do |spec|
|
|
21
21
|
spec.add_development_dependency "bundler", "~> 1.3"
|
22
22
|
spec.add_development_dependency "rake"
|
23
23
|
|
24
|
-
spec.add_runtime_dependency "pivotal-tracker", "~> 0.5.12"
|
25
24
|
spec.add_runtime_dependency "git", "~> 1.2.6"
|
26
25
|
spec.add_runtime_dependency "capistrano", "~> 2.0"
|
26
|
+
spec.add_runtime_dependency "faraday", "~> 0.8"
|
27
|
+
spec.add_runtime_dependency "faraday_middleware", "~> 0.9"
|
27
28
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ptlog
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-11-
|
12
|
+
date: 2013-11-21 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: bundler
|
@@ -44,13 +44,13 @@ dependencies:
|
|
44
44
|
- !ruby/object:Gem::Version
|
45
45
|
version: '0'
|
46
46
|
- !ruby/object:Gem::Dependency
|
47
|
-
name:
|
47
|
+
name: git
|
48
48
|
requirement: !ruby/object:Gem::Requirement
|
49
49
|
none: false
|
50
50
|
requirements:
|
51
51
|
- - ~>
|
52
52
|
- !ruby/object:Gem::Version
|
53
|
-
version:
|
53
|
+
version: 1.2.6
|
54
54
|
type: :runtime
|
55
55
|
prerelease: false
|
56
56
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -58,15 +58,15 @@ dependencies:
|
|
58
58
|
requirements:
|
59
59
|
- - ~>
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version:
|
61
|
+
version: 1.2.6
|
62
62
|
- !ruby/object:Gem::Dependency
|
63
|
-
name:
|
63
|
+
name: capistrano
|
64
64
|
requirement: !ruby/object:Gem::Requirement
|
65
65
|
none: false
|
66
66
|
requirements:
|
67
67
|
- - ~>
|
68
68
|
- !ruby/object:Gem::Version
|
69
|
-
version:
|
69
|
+
version: '2.0'
|
70
70
|
type: :runtime
|
71
71
|
prerelease: false
|
72
72
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -74,15 +74,15 @@ dependencies:
|
|
74
74
|
requirements:
|
75
75
|
- - ~>
|
76
76
|
- !ruby/object:Gem::Version
|
77
|
-
version:
|
77
|
+
version: '2.0'
|
78
78
|
- !ruby/object:Gem::Dependency
|
79
|
-
name:
|
79
|
+
name: faraday
|
80
80
|
requirement: !ruby/object:Gem::Requirement
|
81
81
|
none: false
|
82
82
|
requirements:
|
83
83
|
- - ~>
|
84
84
|
- !ruby/object:Gem::Version
|
85
|
-
version: '
|
85
|
+
version: '0.8'
|
86
86
|
type: :runtime
|
87
87
|
prerelease: false
|
88
88
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -90,7 +90,23 @@ dependencies:
|
|
90
90
|
requirements:
|
91
91
|
- - ~>
|
92
92
|
- !ruby/object:Gem::Version
|
93
|
-
version: '
|
93
|
+
version: '0.8'
|
94
|
+
- !ruby/object:Gem::Dependency
|
95
|
+
name: faraday_middleware
|
96
|
+
requirement: !ruby/object:Gem::Requirement
|
97
|
+
none: false
|
98
|
+
requirements:
|
99
|
+
- - ~>
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
version: '0.9'
|
102
|
+
type: :runtime
|
103
|
+
prerelease: false
|
104
|
+
version_requirements: !ruby/object:Gem::Requirement
|
105
|
+
none: false
|
106
|
+
requirements:
|
107
|
+
- - ~>
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: '0.9'
|
94
110
|
description: Generages changelog based on PivotalTracker stories and Git commits
|
95
111
|
email:
|
96
112
|
- dmitry.larkin@gmail.com
|
@@ -107,6 +123,8 @@ files:
|
|
107
123
|
- lib/ptlog.rb
|
108
124
|
- lib/ptlog/capistrno.rb
|
109
125
|
- lib/ptlog/change_log.rb
|
126
|
+
- lib/ptlog/pivotal/api.rb
|
127
|
+
- lib/ptlog/pivotal/story.rb
|
110
128
|
- lib/ptlog/release.rb
|
111
129
|
- lib/ptlog/version.rb
|
112
130
|
- ptlog.gemspec
|