torque 0.3.1 → 0.4.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.
- checksums.yaml +4 -4
- data/README.md +79 -3
- data/VERSION +2 -2
- data/bin/config +24 -13
- data/bin/email +10 -20
- data/bin/format +170 -0
- data/bin/project +14 -23
- data/bin/torque +27 -21
- data/lib/torque.rb +20 -34
- data/lib/torque/date_settings.rb +2 -2
- data/lib/torque/field_filter.rb +8 -9
- data/lib/torque/file_system.rb +6 -6
- data/lib/torque/format_string.rb +107 -0
- data/lib/torque/iteration.rb +1 -1
- data/lib/torque/mailer.rb +0 -5
- data/lib/torque/pivotal.rb +8 -8
- data/lib/torque/pivotal_html_parser.rb +2 -2
- data/lib/torque/project/project.rb +4 -0
- data/lib/torque/project/project_manager.rb +4 -5
- data/lib/torque/record_pathname_settings.rb +1 -1
- data/lib/torque/settings.rb +19 -11
- data/lib/torque/story.rb +32 -21
- data/lib/torque/torque_info_parser.rb +20 -8
- data/lib/torque/version.rb +1 -1
- metadata +4 -2
data/lib/torque/iteration.rb
CHANGED
@@ -38,7 +38,7 @@ class Torque
|
|
38
38
|
##
|
39
39
|
# @param iterations A list of iterations
|
40
40
|
#
|
41
|
-
#
|
41
|
+
# @return A list of iterations sorted from most to least recent
|
42
42
|
def self.sort_list(iterations)
|
43
43
|
sorted = iterations.sort {|i1, i2| Integer(i2.number) - Integer(i1.number) }
|
44
44
|
sorted
|
data/lib/torque/mailer.rb
CHANGED
@@ -28,11 +28,6 @@ class Torque
|
|
28
28
|
end
|
29
29
|
end
|
30
30
|
|
31
|
-
# ##
|
32
|
-
# # Returns true if the email and password combination is valid, else false
|
33
|
-
# def verify
|
34
|
-
# end
|
35
|
-
|
36
31
|
# @param notes_string The release notes file in string form
|
37
32
|
# @param subject_line The subject line to use in the email
|
38
33
|
# @param address_list A comma-separated list of email addresses to which to send the notes
|
data/lib/torque/pivotal.rb
CHANGED
@@ -13,7 +13,7 @@ class Torque
|
|
13
13
|
end
|
14
14
|
|
15
15
|
##
|
16
|
-
#
|
16
|
+
# @return True if a connection to www.pivotaltracker.com exists, else false
|
17
17
|
def self.connection?
|
18
18
|
begin
|
19
19
|
TCPSocket.new "www.pivotaltracker.com", 80
|
@@ -24,7 +24,7 @@ class Torque
|
|
24
24
|
end
|
25
25
|
|
26
26
|
##
|
27
|
-
#
|
27
|
+
# @return True if the token supplied is a valid token, else false
|
28
28
|
def check_token
|
29
29
|
begin
|
30
30
|
get_project_data
|
@@ -35,9 +35,9 @@ class Torque
|
|
35
35
|
end
|
36
36
|
|
37
37
|
##
|
38
|
-
#
|
38
|
+
# @return A string of html data from Pivotal Tracker with data on each of a user's projects
|
39
39
|
#
|
40
|
-
#
|
40
|
+
# Sends a request through the Pivotal Tracker API
|
41
41
|
def get_project_data
|
42
42
|
|
43
43
|
host="pivotaltracker.com"
|
@@ -66,9 +66,9 @@ class Torque
|
|
66
66
|
##
|
67
67
|
# @param project The ID of the Pivotal Tracker project from which to get data
|
68
68
|
#
|
69
|
-
#
|
69
|
+
# @return A string of html data from Pivotal Tracker with data on the stories for the given project
|
70
70
|
#
|
71
|
-
#
|
71
|
+
# Sends a request through the Pivotal Tracker API
|
72
72
|
def get_project_stories(project)
|
73
73
|
|
74
74
|
# Polls story data from pivotal tracker
|
@@ -103,9 +103,9 @@ class Torque
|
|
103
103
|
# @param project The ID of the Pivotal Tracker project from which to get data
|
104
104
|
# @param number The number of project iterations to fetch
|
105
105
|
#
|
106
|
-
#
|
106
|
+
# @return A string of html data from Pivotal Tracker with data on finished iterations of a project
|
107
107
|
#
|
108
|
-
#
|
108
|
+
# Sends a request throgh the Pivotal Tracker API
|
109
109
|
def get_project_iterations(project, number=1)
|
110
110
|
|
111
111
|
# Polls story data from pivotal tracker
|
@@ -38,7 +38,7 @@ class Torque
|
|
38
38
|
##
|
39
39
|
# @param project_html_string An html string containing the story data for a Pivotal Tracker project
|
40
40
|
#
|
41
|
-
#
|
41
|
+
# @return A list of all Story objects parsed from project_html_string (least recent to most recent date accepted)
|
42
42
|
#
|
43
43
|
# Applies during processing any filters that have been added
|
44
44
|
def process_project(project_html_string)
|
@@ -51,7 +51,7 @@ class Torque
|
|
51
51
|
##
|
52
52
|
# @param project_html_string An html string containing iteration data for a Pivotal Tracker project
|
53
53
|
#
|
54
|
-
#
|
54
|
+
# @return A list of Iteration objects parsed from project_html_string (least recent to most recent iteration)
|
55
55
|
def process_project_iterations(project_html_string)
|
56
56
|
|
57
57
|
project_html = Nokogiri::HTML(project_html_string)
|
@@ -16,6 +16,10 @@ class Torque
|
|
16
16
|
# The project name
|
17
17
|
attr_reader :name
|
18
18
|
|
19
|
+
##
|
20
|
+
# @param id The project's ID
|
21
|
+
# @param name The project's name
|
22
|
+
# @param current True if this is the current project, else false
|
19
23
|
def initialize(id, name, current=false)
|
20
24
|
@current = current
|
21
25
|
@id = id
|
@@ -27,17 +27,16 @@ class Torque
|
|
27
27
|
|
28
28
|
##
|
29
29
|
# @param token A Pivotal Tracker API token (default: Loads token from .torqueinfo.yaml)
|
30
|
+
# @return the project list
|
30
31
|
#
|
31
32
|
# Requests and processes the project list from the Pivotal Tracker API
|
32
|
-
#
|
33
|
-
# Returns the project list
|
34
33
|
def load_project_list(token=nil)
|
35
34
|
get_project_list(token)
|
36
35
|
@project_list
|
37
36
|
end
|
38
37
|
|
39
38
|
##
|
40
|
-
#
|
39
|
+
# @return The project list if 'load_project_list' has been called, else returns nil
|
41
40
|
#
|
42
41
|
# Does not do any processing
|
43
42
|
def project_list
|
@@ -45,7 +44,7 @@ class Torque
|
|
45
44
|
end
|
46
45
|
|
47
46
|
##
|
48
|
-
#
|
47
|
+
# @return The current project if 'load_project_list' has been called and one exists, else returns nil
|
49
48
|
def current_project
|
50
49
|
@project_list.nil? \
|
51
50
|
? nil
|
@@ -53,7 +52,7 @@ class Torque
|
|
53
52
|
end
|
54
53
|
|
55
54
|
##
|
56
|
-
#
|
55
|
+
# @return The project list formatted as a printable string
|
57
56
|
#
|
58
57
|
# Prepends an asterisk to the current project
|
59
58
|
def format_project_list
|
data/lib/torque/settings.rb
CHANGED
@@ -2,6 +2,7 @@ require 'date'
|
|
2
2
|
require_relative 'date_settings'
|
3
3
|
require_relative 'field_filter'
|
4
4
|
require_relative 'file_system'
|
5
|
+
require_relative 'format_string'
|
5
6
|
require_relative 'record_pathname_settings'
|
6
7
|
require_relative 'torque_info_parser'
|
7
8
|
require_relative 'error/missing_project_error'
|
@@ -62,6 +63,10 @@ class Torque
|
|
62
63
|
# True if field filters are being used for stories, else false
|
63
64
|
attr_reader :filters_on
|
64
65
|
|
66
|
+
##
|
67
|
+
# The FormatString object to use to generate notes
|
68
|
+
attr_reader :format_string
|
69
|
+
|
65
70
|
##
|
66
71
|
# The number of iterations of the project to generate notes for, or nil if not using iterations
|
67
72
|
attr_reader :iterations
|
@@ -141,11 +146,23 @@ class Torque
|
|
141
146
|
|
142
147
|
@email_address = torque_info.email_address
|
143
148
|
@email_password = torque_info.email_password
|
144
|
-
|
145
|
-
|
149
|
+
email_to_raw = torque_info.email_to
|
150
|
+
format_string_raw = torque_info.format
|
151
|
+
output_dir_raw = torque_info.output_dir
|
146
152
|
@project = torque_info.project
|
147
153
|
@token = torque_info.token
|
148
154
|
|
155
|
+
if email_to_raw.class == NilClass; @email_to = []
|
156
|
+
elsif email_to_raw.class == String; @email_to = [email_to_raw]
|
157
|
+
elsif email_to_raw.class == Array; @email_to = email_to_raw
|
158
|
+
else; raise "Unknown parsing error on .torqueinfo.yaml's 'email_to' field: #{@email_to}"
|
159
|
+
end
|
160
|
+
|
161
|
+
@format_string = Torque::FormatString.new(format_string_raw)
|
162
|
+
|
163
|
+
output_dir_raw = "release_notes" if output_dir_raw.blank?
|
164
|
+
@output_dir = "#{@root_dir}/#{output_dir_raw}"
|
165
|
+
|
149
166
|
raise MissingTokenError.new(
|
150
167
|
"API token for Pivotal Tracker has not been set"
|
151
168
|
) if @token.blank?
|
@@ -153,15 +170,6 @@ class Torque
|
|
153
170
|
"Project ID for Pivotal Tracker has not been set"
|
154
171
|
) if @project.blank?
|
155
172
|
|
156
|
-
@output_dir = "release_notes" if @output_dir.blank?
|
157
|
-
@output_dir = "#{@root_dir}/#{@output_dir}"
|
158
|
-
|
159
|
-
if @email_to.class == NilClass; @email_to = []
|
160
|
-
elsif @email_to.class == String; @email_to = [@email_to]
|
161
|
-
elsif @email_to.class == Array; @email_to = @email_to
|
162
|
-
else; raise "Unknown parsing error on .torqueinfo.yaml's 'email_to' field: #{@email_to}"
|
163
|
-
end
|
164
|
-
|
165
173
|
# Sets up the output directory, throwing an error if it cannot be found
|
166
174
|
|
167
175
|
if !@fs.path_exist? @output_dir
|
data/lib/torque/story.rb
CHANGED
@@ -6,48 +6,48 @@ class Torque
|
|
6
6
|
|
7
7
|
##
|
8
8
|
# The current state of the story (finished, accepted, etc)
|
9
|
-
|
9
|
+
attr_accessor :current_state
|
10
10
|
|
11
11
|
##
|
12
12
|
# The date that the story was accepted, or nil if it has not been accepted yet
|
13
|
-
|
13
|
+
attr_accessor :date_accepted
|
14
14
|
|
15
15
|
##
|
16
16
|
# The story description
|
17
|
-
|
17
|
+
attr_accessor :description
|
18
18
|
|
19
19
|
##
|
20
20
|
# The estimate for the story
|
21
|
-
|
21
|
+
attr_accessor :estimate
|
22
|
+
|
23
|
+
##
|
24
|
+
# The story's ID
|
25
|
+
attr_accessor :id
|
22
26
|
|
23
27
|
##
|
24
28
|
# The labels for the story
|
25
|
-
|
29
|
+
attr_accessor :labels
|
26
30
|
|
27
31
|
##
|
28
32
|
# The name of the story
|
29
|
-
|
33
|
+
attr_accessor :name
|
30
34
|
|
31
35
|
##
|
32
36
|
# The owner of the story
|
33
|
-
|
37
|
+
attr_accessor :owner
|
34
38
|
|
35
39
|
##
|
36
40
|
# The ID of the story's project
|
37
|
-
|
38
|
-
|
39
|
-
##
|
40
|
-
# The story's ID
|
41
|
-
attr_reader :story_id
|
41
|
+
attr_accessor :project_id
|
42
42
|
|
43
43
|
##
|
44
44
|
# The story's type (feature, chore, etc)
|
45
|
-
|
45
|
+
attr_accessor :type
|
46
46
|
|
47
47
|
##
|
48
48
|
# @param html_hash A hash (of html elements keyed by their tags) generated from Pivotal Tracker story html
|
49
49
|
#
|
50
|
-
#
|
50
|
+
# @return A new story whose fields were parsed from the html_hash provided
|
51
51
|
def self.create(html_hash)
|
52
52
|
Story.new(html_hash).parse
|
53
53
|
end
|
@@ -67,25 +67,34 @@ class Torque
|
|
67
67
|
end
|
68
68
|
private :handle_nil
|
69
69
|
|
70
|
-
|
70
|
+
##
|
71
|
+
# @return The url pointing to the story
|
72
|
+
def url
|
73
|
+
"https://www.pivotaltracker.com/story/show/#{id}"
|
74
|
+
end
|
71
75
|
|
72
76
|
##
|
73
77
|
# Parses the story's fields from its html hash
|
78
|
+
#
|
79
|
+
# @return The story (self)
|
74
80
|
def parse
|
75
81
|
html_hash = @html_hash
|
76
82
|
|
77
83
|
# Default values
|
84
|
+
|
78
85
|
@current_state = ""
|
79
|
-
@date_accepted = nil #
|
86
|
+
@date_accepted = nil # [Date]
|
80
87
|
@description = ""
|
81
88
|
@estimate = -1
|
82
|
-
@
|
89
|
+
@id = -1
|
90
|
+
@labels = "" # [Array]
|
83
91
|
@name = ""
|
84
92
|
@owner = ""
|
85
93
|
@project_id = -1
|
86
|
-
@story_id = -1
|
87
94
|
@type = ""
|
88
95
|
|
96
|
+
# Processes each field
|
97
|
+
|
89
98
|
@current_state = handle_nil(@current_state, html_hash["current_state"])
|
90
99
|
@description = handle_nil(@description, html_hash["description"])
|
91
100
|
@name = handle_nil(@name, html_hash["name"])
|
@@ -94,7 +103,7 @@ class Torque
|
|
94
103
|
|
95
104
|
@estimate = Integer(handle_nil(@estimate, html_hash["estimate"]))
|
96
105
|
@project_id = Integer(handle_nil(@project_id, html_hash["project_id"]))
|
97
|
-
@
|
106
|
+
@id = Integer(handle_nil(@id, html_hash["id"]))
|
98
107
|
|
99
108
|
@labels = handle_nil(@labels, html_hash["labels"])
|
100
109
|
@labels = @labels.split(",")
|
@@ -104,12 +113,14 @@ class Torque
|
|
104
113
|
@date_accepted = Date.strptime(date_acceptedString, "%Y/%m/%d")
|
105
114
|
end
|
106
115
|
|
107
|
-
# Returns the
|
116
|
+
# Returns the parsed story
|
117
|
+
|
108
118
|
self
|
109
119
|
end
|
110
120
|
|
111
121
|
##
|
112
|
-
#
|
122
|
+
# @param stories A list of stories
|
123
|
+
# @return The list of stories sorted from most to least recently accepted
|
113
124
|
def self.sort_list(stories)
|
114
125
|
sorted = stories.sort { |s1, s2| -(s1.date_accepted <=> s2.date_accepted) }
|
115
126
|
sorted
|
@@ -21,6 +21,10 @@ class Torque
|
|
21
21
|
# The email_to field (String or Array)
|
22
22
|
attr_reader :email_to
|
23
23
|
|
24
|
+
##
|
25
|
+
# The format string to use for the project
|
26
|
+
attr_reader :format
|
27
|
+
|
24
28
|
##
|
25
29
|
# The project field (Fixnum)
|
26
30
|
attr_reader :project
|
@@ -45,9 +49,10 @@ class Torque
|
|
45
49
|
end
|
46
50
|
|
47
51
|
##
|
52
|
+
# @return The TorqueInfoParser (self)
|
53
|
+
#
|
48
54
|
# Parses the file, storing the results as public instnance fields
|
49
55
|
# Stores each field with no corresponding value in the file as 'nil'
|
50
|
-
# Returns self
|
51
56
|
def parse
|
52
57
|
|
53
58
|
if !@fs.path_exist?(@file_path)
|
@@ -59,12 +64,13 @@ class Torque
|
|
59
64
|
begin
|
60
65
|
torque_info_hash = YAML::load(@fs.file_read(@file_path)) || {}
|
61
66
|
rescue Psych::SyntaxError
|
62
|
-
#
|
67
|
+
# TODO Implement custom error, raise/rescue paths to catch this problem
|
63
68
|
end
|
64
69
|
|
65
70
|
@email_address = torque_info_hash["email_address"]
|
66
71
|
@email_password = torque_info_hash["email_password"]
|
67
72
|
@email_to = torque_info_hash["email_to"]
|
73
|
+
@format = torque_info_hash["format"]
|
68
74
|
@project = torque_info_hash["project"]
|
69
75
|
@output_dir = torque_info_hash["output_dir"]
|
70
76
|
@token = torque_info_hash["token"]
|
@@ -73,7 +79,8 @@ class Torque
|
|
73
79
|
end
|
74
80
|
|
75
81
|
##
|
76
|
-
#
|
82
|
+
# @param field The field to set
|
83
|
+
# @param value The value to set the field to
|
77
84
|
def set(field, value)
|
78
85
|
file_string = @fs.file_read(@file_path)
|
79
86
|
new_file_string = set_string(field, value, file_string)
|
@@ -81,7 +88,8 @@ class Torque
|
|
81
88
|
end
|
82
89
|
|
83
90
|
##
|
84
|
-
#
|
91
|
+
# @param field The field to add to
|
92
|
+
# @param values A list of values to add to the field
|
85
93
|
def add(field, values)
|
86
94
|
file_string = @fs.file_read(@file_path)
|
87
95
|
new_file_string = add_string(field, values, file_string)
|
@@ -89,8 +97,10 @@ class Torque
|
|
89
97
|
end
|
90
98
|
|
91
99
|
##
|
92
|
-
#
|
93
|
-
#
|
100
|
+
# @param field The field to add to
|
101
|
+
# @param values A list of values to add to the field
|
102
|
+
#
|
103
|
+
# @return A list of all values that were added (ie that were not duplicates)
|
94
104
|
def add_no_duplicates(field, values)
|
95
105
|
file_string = @fs.file_read(@file_path)
|
96
106
|
values_copy = values.clone
|
@@ -101,8 +111,10 @@ class Torque
|
|
101
111
|
end
|
102
112
|
|
103
113
|
##
|
104
|
-
#
|
105
|
-
#
|
114
|
+
# @param field The field to remove from
|
115
|
+
# @param values A list of values to remove from the field
|
116
|
+
#
|
117
|
+
# @return A list of the values that were removed (ie that could be found)
|
106
118
|
def rm(field, values)
|
107
119
|
file_string = @fs.file_read(@file_path)
|
108
120
|
values_copy = values.clone
|
data/lib/torque/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: torque
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nico Adams, Scrimmage
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-08-
|
11
|
+
date: 2013-08-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: highline
|
@@ -92,6 +92,7 @@ extra_rdoc_files:
|
|
92
92
|
files:
|
93
93
|
- bin/config
|
94
94
|
- bin/email
|
95
|
+
- bin/format
|
95
96
|
- bin/project
|
96
97
|
- bin/torque
|
97
98
|
- lib/torque/date_settings.rb
|
@@ -104,6 +105,7 @@ files:
|
|
104
105
|
- lib/torque/error/pivotal_api_error.rb
|
105
106
|
- lib/torque/field_filter.rb
|
106
107
|
- lib/torque/file_system.rb
|
108
|
+
- lib/torque/format_string.rb
|
107
109
|
- lib/torque/iteration.rb
|
108
110
|
- lib/torque/mailer.rb
|
109
111
|
- lib/torque/pivotal.rb
|