torque 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/Gemfile +3 -0
- data/LICENSE +18 -0
- data/README.md +116 -0
- data/VERSION +3 -0
- data/bin/config +257 -0
- data/bin/email +172 -0
- data/bin/project +136 -0
- data/bin/torque +150 -0
- data/lib/torque.rb +190 -0
- data/lib/torque/date_settings.rb +166 -0
- data/lib/torque/error/invalid_project_error.rb +10 -0
- data/lib/torque/error/invalid_token_error.rb +10 -0
- data/lib/torque/error/missing_output_directory_error.rb +7 -0
- data/lib/torque/error/missing_project_error.rb +8 -0
- data/lib/torque/error/missing_token_error.rb +8 -0
- data/lib/torque/error/missing_torque_info_file_error.rb +8 -0
- data/lib/torque/error/pivotal_api_error.rb +8 -0
- data/lib/torque/file_system.rb +70 -0
- data/lib/torque/mailer.rb +62 -0
- data/lib/torque/pivotal.rb +98 -0
- data/lib/torque/pivotal_html_parser.rb +67 -0
- data/lib/torque/project/project.rb +25 -0
- data/lib/torque/project/project_manager.rb +140 -0
- data/lib/torque/record_pathname_settings.rb +80 -0
- data/lib/torque/settings.rb +164 -0
- data/lib/torque/story.rb +108 -0
- data/lib/torque/torque_info_parser.rb +230 -0
- data/lib/torque/version.rb +24 -0
- metadata +145 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: abb92afe8ffbc8574c523dc0edc68438b75ccdeb
|
4
|
+
data.tar.gz: 5e0715da5458863001a6c9ff66cfa591704ff830
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 63143235c62b8ddd4b95d6a8b6a654f78b17e4b2e4e9592009a51679eaa7f971cc0542246029938df55b473124bd9d91e49f370ca64cd26cb3a2ce73668c9435
|
7
|
+
data.tar.gz: f0ebb0b09dda8ae970bcd116eeb78ece99d183a21e625074de6638557efa65b0fd9adab1520ef9afeeeddfe22f8515377e4a38256dbe49cc2e47f9c493f912fd
|
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
Copyright (c) 2013 Scrimmage
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
4
|
+
this software and associated documentation files (the "Software"), to deal in
|
5
|
+
the Software without restriction, including without limitation the rights to
|
6
|
+
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
7
|
+
the Software, and to permit persons to whom the Software is furnished to do so,
|
8
|
+
subject to the following conditions:
|
9
|
+
|
10
|
+
The above copyright notice and this permission notice shall be included in all
|
11
|
+
copies or substantial portions of the Software.
|
12
|
+
|
13
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
15
|
+
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
16
|
+
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
17
|
+
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
18
|
+
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,116 @@
|
|
1
|
+
Torque
|
2
|
+
======
|
3
|
+
|
4
|
+
Introduction
|
5
|
+
------------
|
6
|
+
|
7
|
+
Torque is a command line utility packaged as a Ruby gem. It compiles online data from a Pivotal Tracker project into a set of release notes for that project.
|
8
|
+
|
9
|
+
At start, Torque requests a Pivotal Tracker API token, which gives Torque access to information from your Pivotal Tracker projects. Torque then asks the user to choose one of their projects to begin to generate notes from.
|
10
|
+
|
11
|
+
Once configured, Torque requests data on the accepted stories from the current Pivotal project. It then compiles these stories into a first-draft release notes document. Depending on how consistently your team uses Pivotal Tracker, this document will contain:
|
12
|
+
|
13
|
+
* A record of each feature that was added to the project since the last time Torque was run
|
14
|
+
* A description of the feature
|
15
|
+
* The date that this feature was accepted
|
16
|
+
* A link to the Pivotal Tracker story that tracks this feature
|
17
|
+
|
18
|
+
Torque's default behavior is to document all the stories that were accepted since the last time Torque was run. For instance, if Torque was run on June 1st and then on June 10th, it would generate release notes from the stories that were accepted between June 1st and June 10th (inclusive). This is designed to make it easy to generate release notes each time new features are pushed to production: If Torque is run at the time of each new release, then it will generate notes for all the features that were added since the previous release. If needed, Torque can also generate notes for a custom date range.
|
19
|
+
|
20
|
+
Torque was designed and tested in a Ruby 2.0 environment.
|
21
|
+
|
22
|
+
Current Features
|
23
|
+
----------------
|
24
|
+
|
25
|
+
* Automatically compiles all Pivotal Tracker stories accepted between the current date and the last time Torque was run
|
26
|
+
* Compile stories accepted within a custom date range
|
27
|
+
* Stores a record of each document as it's generated
|
28
|
+
* Configuration script that automatically sets up a directory to use Torque
|
29
|
+
* Project script that automatically displays/switches between your Pivotal Tracker projects
|
30
|
+
* Ability to email the finished release notes from a personal email account to a pre-specified mailing list. (Currently can only send from accounts hosted by Gmail)
|
31
|
+
|
32
|
+
Note on Confidentiality
|
33
|
+
-----------------------
|
34
|
+
|
35
|
+
During usage, Torque will request some confidential information -- namely, your Pivotal Tracker API token and your email username/password. This information is stored in a local config file on your computer and is only used to access (respectively) Pivotal Tracker and your email server. It is never collected, sent to a 3rd party, or used for any other purpose.
|
36
|
+
|
37
|
+
Torque stores this data in a file called '.torqueinfo.yaml': Do not commit this file to your version control system!
|
38
|
+
|
39
|
+
Installation
|
40
|
+
------------
|
41
|
+
|
42
|
+
# gem install torque
|
43
|
+
|
44
|
+
Configuration
|
45
|
+
-------------
|
46
|
+
|
47
|
+
To configure Torque, run in your project's root directory
|
48
|
+
|
49
|
+
# torque config
|
50
|
+
|
51
|
+
The configuration script will request a Pivotal Tracker API token, which can be found at https://www.pivotaltracker.com/profile#api. The token can be reset at any time by running:
|
52
|
+
|
53
|
+
# 'torque config -t/--token'
|
54
|
+
|
55
|
+
To change the output directory Torque writes its release notes to:
|
56
|
+
|
57
|
+
# 'torque config -o/--output [directory]'
|
58
|
+
|
59
|
+
To overwrite the Torque settings and/or output directory:
|
60
|
+
|
61
|
+
# 'torque config -f/--force'
|
62
|
+
|
63
|
+
Usage
|
64
|
+
-----
|
65
|
+
|
66
|
+
In a directory that has been configured, run
|
67
|
+
|
68
|
+
# torque
|
69
|
+
|
70
|
+
Alternately, run Torque from a different directory by using the --root option:
|
71
|
+
|
72
|
+
# torque --root [configured/torque/directory]
|
73
|
+
|
74
|
+
This will compile release notes for all stories accepted since the last time you ran Torque in this directory.
|
75
|
+
|
76
|
+
To compile release notes for stories within a custom date range:
|
77
|
+
|
78
|
+
# torque -f [from] -t [to]
|
79
|
+
|
80
|
+
If [from] is set, [to] will default to today. If [to] is set, [from] will default to 1/1/1900.
|
81
|
+
|
82
|
+
To email the release notes from a personal email to Torque's mailing list:
|
83
|
+
|
84
|
+
# torque --email
|
85
|
+
|
86
|
+
Running with the 'verbose' option will print a running list of stories as they are added. Running with the 'silent' option will silence all output.
|
87
|
+
|
88
|
+
To display all available Pivotal Tracker projects or change your current project:
|
89
|
+
|
90
|
+
# torque project
|
91
|
+
|
92
|
+
To set up automatic emailing when the notes and add/remove from the mailing list:
|
93
|
+
|
94
|
+
# torque email
|
95
|
+
|
96
|
+
License
|
97
|
+
-------
|
98
|
+
|
99
|
+
Copyright (c) 2013 Scrimmage
|
100
|
+
|
101
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
102
|
+
this software and associated documentation files (the "Software"), to deal in
|
103
|
+
the Software without restriction, including without limitation the rights to
|
104
|
+
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
105
|
+
the Software, and to permit persons to whom the Software is furnished to do so,
|
106
|
+
subject to the following conditions:
|
107
|
+
|
108
|
+
The above copyright notice and this permission notice shall be included in all
|
109
|
+
copies or substantial portions of the Software.
|
110
|
+
|
111
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
112
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
113
|
+
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
114
|
+
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
115
|
+
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
116
|
+
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/VERSION
ADDED
data/bin/config
ADDED
@@ -0,0 +1,257 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
# Configuration script for Torque. Sets up an output directory and settings file
|
4
|
+
|
5
|
+
lib_dir = File.expand_path("../lib", File.dirname(__FILE__))
|
6
|
+
template_dir = File.expand_path("../template", File.dirname(__FILE__))
|
7
|
+
working_dir = "."
|
8
|
+
|
9
|
+
require 'fileutils'
|
10
|
+
require 'highline/import'
|
11
|
+
require 'net/http'
|
12
|
+
require 'optparse'
|
13
|
+
require 'pathname'
|
14
|
+
require "#{lib_dir}/torque/pivotal"
|
15
|
+
require "#{lib_dir}/torque/torque_info_parser"
|
16
|
+
require "#{lib_dir}/torque/project/project"
|
17
|
+
require "#{lib_dir}/torque/project/project_manager"
|
18
|
+
|
19
|
+
# Parses the options
|
20
|
+
options = {}
|
21
|
+
option_parser = OptionParser.new do |opts|
|
22
|
+
|
23
|
+
help_message = "Configures a directory to use Torque."
|
24
|
+
help_message += "\n"
|
25
|
+
help_message += "\nThis script will create a template for .torqueinfo.yaml and set up an output directory. It " \
|
26
|
+
"will also set up access to the Pivotal Tracker API"
|
27
|
+
|
28
|
+
opts.banner = "\nUsage:"
|
29
|
+
opts.banner += "\n torque config [options]"
|
30
|
+
opts.banner += "\n"
|
31
|
+
opts.banner += "\n#{help_message}"
|
32
|
+
opts.banner += "\n"
|
33
|
+
opts.banner += "\n"
|
34
|
+
|
35
|
+
opts.on("-f", "--force", "Force a configuration, overwriting any existing .torqueinfo file or output directory") do
|
36
|
+
|arg|
|
37
|
+
options[:force] = arg
|
38
|
+
end
|
39
|
+
|
40
|
+
opts.on("-h", "--help", "Display this help screen") do
|
41
|
+
|arg|
|
42
|
+
options[:help] = arg
|
43
|
+
end
|
44
|
+
|
45
|
+
opts.on("-o", "--output OUTPUT", "Set the output directory to the directory specified (default: release_notes)") do
|
46
|
+
|arg|
|
47
|
+
options[:output_dir] = arg
|
48
|
+
end
|
49
|
+
|
50
|
+
opts.on("-t", "--token", "Set the API token and Pivotal project only (do not change the filesystem)") do
|
51
|
+
|arg|
|
52
|
+
options[:token] = arg
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
56
|
+
|
57
|
+
# Parses options and handles exceptions
|
58
|
+
|
59
|
+
begin
|
60
|
+
option_parser.parse!
|
61
|
+
|
62
|
+
rescue OptionParser::InvalidOption, OptionParser::MissingArgument
|
63
|
+
puts $!.to_s
|
64
|
+
puts option_parser
|
65
|
+
exit
|
66
|
+
end
|
67
|
+
|
68
|
+
# Handles special cases and exceptions
|
69
|
+
|
70
|
+
if ARGV.member? "help" || options[:help]
|
71
|
+
puts "(Ran with 'help' option; other options ignored)"
|
72
|
+
puts option_parser
|
73
|
+
exit
|
74
|
+
elsif !ARGV.empty?
|
75
|
+
puts "Unknown arguments: #{ARGV.join(", ")}"
|
76
|
+
puts option_parser.help
|
77
|
+
exit
|
78
|
+
end
|
79
|
+
|
80
|
+
# Checks for a connection to Pivotal Tracker
|
81
|
+
|
82
|
+
if !Torque::Pivotal.connection?
|
83
|
+
puts "ABORTING"
|
84
|
+
puts "Cannot connect to www.pivotaltracker.com. A connection is required to configure Torque"
|
85
|
+
exit 1
|
86
|
+
end
|
87
|
+
|
88
|
+
# Configures the directory
|
89
|
+
|
90
|
+
if !options[:token]
|
91
|
+
|
92
|
+
puts "Configuring directory for Torque..."
|
93
|
+
|
94
|
+
# Checks that configuration is possible
|
95
|
+
|
96
|
+
default_output_dir = "release_notes"
|
97
|
+
output_dir = options[:output_dir] || default_output_dir
|
98
|
+
output_path = Pathname.new(output_dir)
|
99
|
+
|
100
|
+
if !options[:force] && !options[:output_dir] && output_path.exist?
|
101
|
+
puts "ABORTING"
|
102
|
+
puts "The default output directory, #{default_output_dir}, already exists."
|
103
|
+
puts "(Use -o to choose an existing output directory or create a new one)"
|
104
|
+
puts "(Use -f to overwrite an existing directory)"
|
105
|
+
exit
|
106
|
+
end
|
107
|
+
|
108
|
+
|
109
|
+
torque_info_path = Pathname.new(".torqueinfo.yaml")
|
110
|
+
|
111
|
+
if !options[:force] && !options[:output_dir] && torque_info_path.exist?
|
112
|
+
puts "ABORTING"
|
113
|
+
puts "A .torqueinfo.yaml file already exists in this directory."
|
114
|
+
puts "(Use -o to ignore this file and change only the output directory)"
|
115
|
+
puts "(Use -f to overwrite this file)"
|
116
|
+
exit
|
117
|
+
end
|
118
|
+
|
119
|
+
|
120
|
+
# Configures the directory
|
121
|
+
|
122
|
+
retained_torque_info_file = false # True if the torque info file is the same after configuration
|
123
|
+
|
124
|
+
if options[:force] && output_path.exist?
|
125
|
+
puts "- Overwriting directory #{output_dir}"
|
126
|
+
FileUtils.rm_r(output_dir)
|
127
|
+
|
128
|
+
elsif options[:output_dir] && output_path.exist?
|
129
|
+
puts "- Setting output directory to #{output_dir}"
|
130
|
+
|
131
|
+
else
|
132
|
+
puts "- Creating directory #{output_dir}"
|
133
|
+
end
|
134
|
+
|
135
|
+
FileUtils.mkdir_p("#{output_dir}/previous")
|
136
|
+
|
137
|
+
if options[:force] && torque_info_path.exist?
|
138
|
+
puts "- Overwriting file .torqueinfo.yaml"
|
139
|
+
FileUtils.rm(".torqueinfo.yaml")
|
140
|
+
|
141
|
+
elsif options[:output_dir] && torque_info_path.exist?
|
142
|
+
retained_torque_info_file = true
|
143
|
+
|
144
|
+
else
|
145
|
+
puts "- Creating file .torqueinfo.yaml"
|
146
|
+
end
|
147
|
+
|
148
|
+
FileUtils.touch("./.torqueinfo.yaml")
|
149
|
+
|
150
|
+
File.open(".torqueinfo.yaml", "a+") do |file|
|
151
|
+
file.write("\n\n")
|
152
|
+
end
|
153
|
+
Torque::TorqueInfoParser.new.set("output_dir", output_dir)
|
154
|
+
|
155
|
+
end
|
156
|
+
|
157
|
+
|
158
|
+
# Determines whether to set up a new API token and project ID
|
159
|
+
|
160
|
+
should_setup_info = true
|
161
|
+
if retained_torque_info_file
|
162
|
+
valid = /^\s*(y|Y|n|N)\s*$/
|
163
|
+
setup_info_prompt = ask("Existing Torque info file found. Would you like to set up a new API token? [y/n]") {
|
164
|
+
|q|
|
165
|
+
q.validate = valid
|
166
|
+
}
|
167
|
+
setup_info_prompt.strip!
|
168
|
+
should_setup_info = (setup_info_prompt =~ /y|Y/)
|
169
|
+
end
|
170
|
+
|
171
|
+
|
172
|
+
if should_setup_info
|
173
|
+
|
174
|
+
# Adds the API token to the torque info file
|
175
|
+
|
176
|
+
project_manager = Torque::ProjectManager.new
|
177
|
+
|
178
|
+
puts
|
179
|
+
puts "In order to generate release notes, Torque needs your account's Pivotal Tracker API token"
|
180
|
+
|
181
|
+
# Input loop
|
182
|
+
while true
|
183
|
+
token_input = ask("Please paste your Pivotal Tracker API token below: https://www.pivotaltracker.com/profile#api") {
|
184
|
+
|q| q.echo = "*"
|
185
|
+
}
|
186
|
+
token = token_input.to_s
|
187
|
+
|
188
|
+
Torque::Pivotal.new(token).check_token ? break : (puts "Token was invalid. Try again")
|
189
|
+
end
|
190
|
+
|
191
|
+
File.open(".torqueinfo.yaml", "a+") do |file|
|
192
|
+
Torque::TorqueInfoParser.new.set("token", token)
|
193
|
+
end
|
194
|
+
|
195
|
+
# Adds the project ID to the torque info file
|
196
|
+
|
197
|
+
project_manager.load_project_list(token)
|
198
|
+
project_list = project_manager.project_list
|
199
|
+
|
200
|
+
if project_list.empty?
|
201
|
+
puts "No projects found for your Pivotal Tracker account. Add a project to your account, then use 'torque " \
|
202
|
+
"project' to set your Torque project"
|
203
|
+
|
204
|
+
else
|
205
|
+
|
206
|
+
# If only one project exists, defaults to it
|
207
|
+
if project_list.length == 1
|
208
|
+
project_index = 0
|
209
|
+
puts
|
210
|
+
|
211
|
+
# Allows user to choose between multiple projects
|
212
|
+
else
|
213
|
+
choice_str = "Please select one of the following projects. Torque will use the stories from this project to " \
|
214
|
+
"generate release notes"
|
215
|
+
choice_str += "\n(Enter a number)"
|
216
|
+
project_list.each_with_index do
|
217
|
+
|project, index|
|
218
|
+
choice_str += "\n#{index} : #{project.id} #{project.name}"
|
219
|
+
end
|
220
|
+
|
221
|
+
# Short util method for parsing numbers from strings
|
222
|
+
# Returns nil if no number can be parsed from string or if the number parsed is >= max
|
223
|
+
def parse_index(string, max)
|
224
|
+
index = nil
|
225
|
+
begin; index = Integer(string)
|
226
|
+
rescue ArgumentError; return nil
|
227
|
+
end
|
228
|
+
(index >= max || index < 0) ? nil : index
|
229
|
+
end
|
230
|
+
|
231
|
+
# Input loop
|
232
|
+
puts
|
233
|
+
while true
|
234
|
+
puts choice_str
|
235
|
+
num_str = ask("")
|
236
|
+
project_index = parse_index(num_str, project_list.length)
|
237
|
+
project_index ? break : (puts "Choice was invalid. Try again")
|
238
|
+
end
|
239
|
+
|
240
|
+
end
|
241
|
+
|
242
|
+
project = project_list[project_index]
|
243
|
+
Torque::TorqueInfoParser.new.set("project", Integer(project.id))
|
244
|
+
puts "Set project to #{project.id} - '#{project.name}'"
|
245
|
+
puts "Use 'torque project' to change this project"
|
246
|
+
|
247
|
+
end
|
248
|
+
end
|
249
|
+
|
250
|
+
# Finishes
|
251
|
+
|
252
|
+
unless options[:token]
|
253
|
+
puts
|
254
|
+
puts "Configuration complete!"
|
255
|
+
puts "WARNING: Do not check .torqueinfo.yaml into your version control system! (Contains sensitive information)"
|
256
|
+
puts
|
257
|
+
end
|
data/bin/email
ADDED
@@ -0,0 +1,172 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
# Manages email settings for Torque.
|
4
|
+
# Prompts for and stores a user's email and password, adds to/removes from the email_to list
|
5
|
+
|
6
|
+
lib_dir = File.expand_path("../lib", File.dirname(__FILE__))
|
7
|
+
template_dir = File.expand_path("../template", File.dirname(__FILE__))
|
8
|
+
working_dir = "."
|
9
|
+
|
10
|
+
require 'highline/import'
|
11
|
+
require 'mail'
|
12
|
+
require 'optparse'
|
13
|
+
require "#{lib_dir}/torque/torque_info_parser"
|
14
|
+
require "#{lib_dir}/torque/pivotal"
|
15
|
+
|
16
|
+
# Parses the options
|
17
|
+
options = {}
|
18
|
+
option_parser = OptionParser.new do |opts|
|
19
|
+
|
20
|
+
help_message = "Handles email settings for Torque. Allows users to set up their own email address, add or remove " \
|
21
|
+
"emails from the email_to list, and display the current email settings"
|
22
|
+
|
23
|
+
opts.banner = "\nUsage:"
|
24
|
+
opts.banner += "\n torque email [options]"
|
25
|
+
opts.banner += "\n"
|
26
|
+
opts.banner += "\n#{help_message}"
|
27
|
+
opts.banner += "\n"
|
28
|
+
opts.banner += "\n"
|
29
|
+
|
30
|
+
options[:add] = []
|
31
|
+
options[:rm] = []
|
32
|
+
|
33
|
+
opts.on("-a", "--add ADDRESS", "Add an email address to the list") do
|
34
|
+
|arg|
|
35
|
+
options[:add] << arg
|
36
|
+
end
|
37
|
+
|
38
|
+
opts.on("-r", "--rm ADDRESS", "Remove an email address from the list") do
|
39
|
+
|arg|
|
40
|
+
options[:rm] << arg
|
41
|
+
end
|
42
|
+
|
43
|
+
opts.on("-s", "--setup", "Sets up a personal email address (Gmail only)") do
|
44
|
+
|arg|
|
45
|
+
options[:setup] = arg
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
49
|
+
|
50
|
+
# Parses options and handles exceptions
|
51
|
+
|
52
|
+
begin
|
53
|
+
option_parser.parse!
|
54
|
+
|
55
|
+
rescue OptionParser::InvalidOption, OptionParser::MissingArgument
|
56
|
+
puts $!.to_s
|
57
|
+
puts option_parser
|
58
|
+
exit
|
59
|
+
end
|
60
|
+
|
61
|
+
# Handles special cases and exceptions
|
62
|
+
|
63
|
+
if ARGV.member? "help" || options[:help]
|
64
|
+
puts "(Ran with 'help' option; other options ignored)"
|
65
|
+
puts option_parser
|
66
|
+
exit
|
67
|
+
elsif !ARGV.empty?
|
68
|
+
puts "Unknown arguments: #{ARGV.join(", ")}"
|
69
|
+
puts option_parser.help
|
70
|
+
exit
|
71
|
+
end
|
72
|
+
|
73
|
+
# Checks for a connection to Pivotal Tracker
|
74
|
+
|
75
|
+
if !Torque::Pivotal.connection?
|
76
|
+
puts "ABORTING"
|
77
|
+
puts "Cannot connect to www.pivotaltracker.com. A connection is required to use Torque"
|
78
|
+
exit 1
|
79
|
+
end
|
80
|
+
|
81
|
+
# Parses the torque info file
|
82
|
+
|
83
|
+
torque_info = Torque::TorqueInfoParser.new
|
84
|
+
begin
|
85
|
+
torque_info.parse
|
86
|
+
rescue Torque::MissingTorqueInfoFileError => e
|
87
|
+
puts "ABORTING"
|
88
|
+
puts e.message
|
89
|
+
puts "Run 'torque config' in this directory, or change your working directory"
|
90
|
+
exit 2
|
91
|
+
end
|
92
|
+
|
93
|
+
# Util method to display the current email settings
|
94
|
+
# Passes in the current TorqueInfoParser
|
95
|
+
def disp_email(torque_info)
|
96
|
+
|
97
|
+
if !torque_info.email_address
|
98
|
+
puts "No user email found. (Set up your email address with 'torque email -s/--setup')"
|
99
|
+
elsif !torque_info.email_password
|
100
|
+
puts "No password found for current user email, '#{torque_info.email_address}'. (Set this with 'torque email " \
|
101
|
+
"--setup')"
|
102
|
+
else
|
103
|
+
puts "Email: #{torque_info.email_address}"
|
104
|
+
end
|
105
|
+
|
106
|
+
if torque_info.email_to.nil? || torque_info.email_to.empty?
|
107
|
+
puts "Mailing list: <empty>"
|
108
|
+
else
|
109
|
+
puts "Mailing list:"
|
110
|
+
torque_info.email_to.each do |email|
|
111
|
+
puts " #{email}"
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
end
|
116
|
+
|
117
|
+
# Sets up the user's email and password
|
118
|
+
|
119
|
+
if options[:setup]
|
120
|
+
|
121
|
+
puts "Enter the email address and password for the account you wish to send emails from. (Only Gmail accounts are " \
|
122
|
+
"currently supported)"
|
123
|
+
email_address = ( ask("Address:") ).to_s
|
124
|
+
email_password = ( ask("Password:") {|p| p.echo = "*"} ).to_s
|
125
|
+
|
126
|
+
torque_info.set("email_address", email_address)
|
127
|
+
torque_info.set("email_password", email_password)
|
128
|
+
|
129
|
+
puts "Ready to email!"
|
130
|
+
|
131
|
+
puts "---" unless (options[:add].empty? && options[:rm].empty?)
|
132
|
+
|
133
|
+
end
|
134
|
+
|
135
|
+
# Validates all emails to be added
|
136
|
+
|
137
|
+
options[:add].each do |email|
|
138
|
+
|
139
|
+
end
|
140
|
+
|
141
|
+
# Adds and removes emails from the email list
|
142
|
+
|
143
|
+
unless (options[:add].empty? && options[:rm].empty?)
|
144
|
+
|
145
|
+
emails_added = torque_info.add_no_duplicates("email_to", options[:add])
|
146
|
+
options[:add].each do |email|
|
147
|
+
if emails_added.member? email
|
148
|
+
puts "'#{email}' added"
|
149
|
+
emails_added.delete(email)
|
150
|
+
else
|
151
|
+
puts "(add: '#{email}' is already on the list)"
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
emails_removed = torque_info.rm("email_to", options[:rm])
|
156
|
+
options[:rm].each do |email|
|
157
|
+
if emails_removed.member? email
|
158
|
+
puts "'#{email}' removed"
|
159
|
+
emails_removed.delete("#{email}")
|
160
|
+
else
|
161
|
+
puts "(rm: '#{email}' is not on the list)"
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
end
|
166
|
+
|
167
|
+
# Finishes
|
168
|
+
|
169
|
+
torque_info.parse
|
170
|
+
puts
|
171
|
+
disp_email(torque_info)
|
172
|
+
puts
|