torque 0.3.1 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 4bbf96a5e564ef44f742123c47a9509abe4c18ea
4
- data.tar.gz: e20c283836eee7bf65a5b3bac666a40e389ecd96
3
+ metadata.gz: 4b758a1a40b981493fc10c574974eddb9d65aa6c
4
+ data.tar.gz: 9e937f2bbeb8e3af7b6b1939d61014c8b5f96d29
5
5
  SHA512:
6
- metadata.gz: df9a49f19e231ba96215dbfc1082e790502c82c0d7e3fd06410f1ca8f96e0f568c6c76e64a79fe9cbe96081715a5dbb332303033f394cfe3177756eda6cb1236
7
- data.tar.gz: 490ca79fbe959b5f6232bf9a9825c791213ac1f51c60a72bcb69f779fd1d4644f50d054b16c97eec314e20765f71b3a951cf0c5f6d25bedb57145fae3fe3945e
6
+ metadata.gz: 74e771fe69f47007a1badc7cd1b33e24dc1f077ef1025a433549abe4e8f42ab6b1876196d1f8fcfd0380138fbbb06b6f30b29a40730f6ba57e8ab3d4731860db
7
+ data.tar.gz: 16205617e5a71c342f41611cb74b103ff966111970098c59f7121ba29d6ce1448fa11503f6b82be0f3260e201f99660bd40ba8c9fafc2525a69860084d2ccbc2
data/README.md CHANGED
@@ -91,17 +91,22 @@ To filter your results by story label, owner or type:
91
91
  # torque --owner "list + of , owners"
92
92
  # torque --type "list, of + story types"
93
93
 
94
- When using filters, "," is used to signify OR, "+" is used to signify AND, and "+" has a higher precedence than ",". For example, "ios + android, ios + web" becomes
94
+ When using filters:
95
+ * "," => OR
96
+ * "+" => AND
97
+ * "+" is evaluated before ","
98
+
99
+ For example, "ios + android, ios + web" becomes
95
100
 
96
101
  ("ios" AND "android") OR ("ios" AND "web")
97
102
 
98
- Additionally, the "owner" filter will try to match against first/middle/last names as well as full names. For instance, '--owner Lee' will match stories owned by "Lee Grant", "Jake Lee", or "Kate Lee Swanson".
103
+ The "owner" filter will try to match against first/middle/last names as well as full names. For instance, '--owner Lee' will match stories owned by (eg) "Lee Grant", "Jake Lee", or "John Lee Jones".
99
104
 
100
105
  To email the release notes from a personal email to Torque's mailing list:
101
106
 
102
107
  # torque --email
103
108
 
104
- 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.
109
+ Running with '-v/--verbose' will print a running list of stories as they are added. Running with '-s/--silent' will silence all output.
105
110
 
106
111
  To display all available Pivotal Tracker projects or change your current project:
107
112
 
@@ -111,6 +116,77 @@ To set up automatic emailing of the notes and add/remove from the mailing list:
111
116
 
112
117
  # torque email
113
118
 
119
+ To view/change the format of the notes that Torque generates:
120
+
121
+ # torque format
122
+
123
+ Formatting
124
+ ----------
125
+
126
+ By default, stories are formatted like this:
127
+
128
+ 12345678
129
+ Story Name
130
+ Accepted on 2012/12/21
131
+ https://www.pivotaltracker.com/story/show/12345678
132
+ Short description of story goes here
133
+ - This is a side note
134
+ - This is another side note
135
+
136
+ To change the way that stories are formatted, use 'torque format -s/--set'. Alternately, use 'torque format -e/--example' to see some sample output from a new format.
137
+
138
+ The format is set by way of a "formatting string", a mix of plain text and parameters (eg "%a") that act as placeholders for elements of a story.
139
+
140
+ Parameters:
141
+ * %a => Date accepted (MM/DD)
142
+ * %A => Date accepted (YYYY/MM/DD)
143
+ * %d => Description
144
+ * %D => Description (tabbed once on each newline)
145
+ * %e => Estimate
146
+ * %i => ID
147
+ * %l => Labels (separated by ", ")
148
+ * %n => Newline character
149
+ * %N => Name
150
+ * %o => Owner of the story
151
+ * %p => ID of the story's project
152
+ * %u => URL pointing to the story
153
+ * %t => Tab character
154
+ * %T => Type (feature, bug, etc)
155
+
156
+ Exit Codes
157
+ ----------
158
+
159
+ The following is a list of exit codes that are thrown on various errors for each of the Torque scripts.
160
+
161
+ (general)
162
+ 3 Invalid arguments
163
+ 4 Cannot connect to Pivotal Tracker API
164
+
165
+ torque
166
+ 5 Missing torque info file
167
+ 6 Missing output directory
168
+ 7 Missing token
169
+ 8 Invalid token
170
+ 9 Missing project
171
+ 10 Invalid project
172
+ 11 Misc. Pivotal Tracker API request error
173
+ 12 Misc argument error
174
+
175
+ torque config
176
+ 5 Pre-existing output directory
177
+ 6 Pre-existing torque info file
178
+ 7 Invalid output directory
179
+
180
+ torque email
181
+ 5 Missing torque info file
182
+
183
+ torque format
184
+ 5 Missing torque info file
185
+
186
+ torque project
187
+ 5 Missing torque info file
188
+ 6 Project not found
189
+
114
190
  License
115
191
  -------
116
192
 
data/VERSION CHANGED
@@ -1,3 +1,3 @@
1
1
  major:0
2
- minor:3
3
- patch:1
2
+ minor:4
3
+ patch:0
data/bin/config CHANGED
@@ -11,6 +11,7 @@ require 'highline/import'
11
11
  require 'net/http'
12
12
  require 'optparse'
13
13
  require 'pathname'
14
+ require "#{lib_dir}/torque/format_string"
14
15
  require "#{lib_dir}/torque/pivotal"
15
16
  require "#{lib_dir}/torque/torque_info_parser"
16
17
  require "#{lib_dir}/torque/project/project"
@@ -62,7 +63,7 @@ begin
62
63
  rescue OptionParser::InvalidOption, OptionParser::MissingArgument
63
64
  puts $!.to_s
64
65
  puts option_parser
65
- exit
66
+ exit 3
66
67
  end
67
68
 
68
69
  # Handles special cases and exceptions
@@ -74,7 +75,7 @@ if ((ARGV.member? "help") || options[:help])
74
75
  elsif !ARGV.empty?
75
76
  puts "Unknown arguments: #{ARGV.join(", ")}"
76
77
  puts option_parser.help
77
- exit
78
+ exit 3
78
79
  end
79
80
 
80
81
  # Checks for a connection to Pivotal Tracker
@@ -82,7 +83,7 @@ end
82
83
  if !Torque::Pivotal.connection?
83
84
  puts "ABORTING"
84
85
  puts "Cannot connect to www.pivotaltracker.com. A connection is required to configure Torque"
85
- exit 1
86
+ exit 4
86
87
  end
87
88
 
88
89
  # Configures the directory
@@ -102,7 +103,7 @@ if !options[:token]
102
103
  puts "The default output directory, #{default_output_dir}, already exists."
103
104
  puts "(Use -o to manually choose an existing output directory or create a new one)"
104
105
  puts "(Use -f to overwrite an existing directory)"
105
- exit
106
+ exit 5
106
107
  end
107
108
 
108
109
 
@@ -113,7 +114,7 @@ if !options[:token]
113
114
  puts "A .torqueinfo.yaml file already exists in this directory."
114
115
  puts "(Use -o to ignore this file and change only the output directory)"
115
116
  puts "(Use -f to overwrite this file)"
116
- exit
117
+ exit 6
117
118
  end
118
119
 
119
120
 
@@ -132,7 +133,13 @@ if !options[:token]
132
133
  puts "- Creating directory #{output_dir}"
133
134
  end
134
135
 
135
- FileUtils.mkdir_p("#{output_dir}/previous")
136
+ begin
137
+ FileUtils.mkdir_p("#{output_dir}/previous")
138
+ rescue Errno::EACCES => e
139
+ puts "ABORTING"
140
+ puts "Cannot use output directory \"#{output_dir}\""
141
+ exit 7
142
+ end
136
143
 
137
144
  if options[:force] && torque_info_path.exist?
138
145
  puts "- Overwriting file .torqueinfo.yaml"
@@ -157,7 +164,7 @@ end
157
164
 
158
165
  # Determines whether to set up a new API token and project ID
159
166
 
160
- should_setup_info = true
167
+ should_setup_torque_info = true
161
168
  if retained_torque_info_file
162
169
  valid = /^\s*(y|Y|n|N)\s*$/
163
170
  setup_info_prompt = ask("Existing Torque info file found. Would you like to set up a new API token? [y/n]") {
@@ -165,11 +172,11 @@ if retained_torque_info_file
165
172
  q.validate = valid
166
173
  }
167
174
  setup_info_prompt.strip!
168
- should_setup_info = (setup_info_prompt =~ /y|Y/)
175
+ should_setup_torque_info = (setup_info_prompt =~ /y|Y/)
169
176
  end
170
177
 
171
178
 
172
- if should_setup_info
179
+ if should_setup_torque_info
173
180
 
174
181
  # Adds the API token to the torque info file
175
182
 
@@ -247,12 +254,16 @@ if should_setup_info
247
254
  end
248
255
  end
249
256
 
250
- # Finishes
251
257
 
258
+ # Sets the default format string
259
+
260
+ Torque::TorqueInfoParser.new.set("format", Torque::FormatString.default)
261
+
262
+ # Finishes
252
263
 
253
264
  puts
254
265
  puts "Configuration complete!"
255
- if !options[:token] && !(options[:output_dir] && !should_setup_info)
266
+ unless options[:token] || (options[:output_dir] && !should_setup_torque_info)
256
267
  puts "WARNING: Do not check .torqueinfo.yaml into your version control system! (Contains sensitive information)"
257
- end
258
- puts
268
+ puts
269
+ end
data/bin/email CHANGED
@@ -10,8 +10,8 @@ working_dir = "."
10
10
  require 'highline/import'
11
11
  require 'mail'
12
12
  require 'optparse'
13
- require "#{lib_dir}/torque/torque_info_parser"
14
13
  require "#{lib_dir}/torque/pivotal"
14
+ require "#{lib_dir}/torque/torque_info_parser"
15
15
 
16
16
  # Parses the options
17
17
  options = {}
@@ -60,7 +60,7 @@ begin
60
60
  rescue OptionParser::InvalidOption, OptionParser::MissingArgument
61
61
  puts $!.to_s
62
62
  puts option_parser
63
- exit
63
+ exit 3
64
64
  end
65
65
 
66
66
  # Handles special cases and exceptions
@@ -72,15 +72,7 @@ if ((ARGV.member? "help") || options[:help])
72
72
  elsif !ARGV.empty?
73
73
  puts "Unknown arguments: #{ARGV.join(", ")}"
74
74
  puts option_parser.help
75
- exit
76
- end
77
-
78
- # Checks for a connection to Pivotal Tracker
79
-
80
- if !Torque::Pivotal.connection?
81
- puts "ABORTING"
82
- puts "Cannot connect to www.pivotaltracker.com. A connection is required to use Torque"
83
- exit 1
75
+ exit 3
84
76
  end
85
77
 
86
78
  # Parses the torque info file
@@ -92,7 +84,7 @@ rescue Torque::MissingTorqueInfoFileError => e
92
84
  puts "ABORTING"
93
85
  puts e.message
94
86
  puts "Run 'torque config' in this directory, or change your working directory"
95
- exit 2
87
+ exit 5
96
88
  end
97
89
 
98
90
  # Util method to display the current email settings
@@ -137,12 +129,6 @@ if options[:setup]
137
129
 
138
130
  end
139
131
 
140
- # Validates all emails to be added
141
-
142
- options[:add].each do |email|
143
-
144
- end
145
-
146
132
  # Adds and removes emails from the email list
147
133
 
148
134
  unless (options[:add].empty? && options[:rm].empty?)
@@ -169,9 +155,13 @@ unless (options[:add].empty? && options[:rm].empty?)
169
155
 
170
156
  end
171
157
 
172
- # Finishes
158
+ # Displays the current email settings
159
+
160
+ options_empty = options.size == 2 && options[:add].empty? && options[:rm].empty?
173
161
 
174
162
  torque_info.parse
163
+ puts "(When torque is run with the '--email' option, these addresses will receive a copy of the notes)" \
164
+ if options_empty
175
165
  puts
176
166
  disp_email(torque_info)
177
- puts
167
+ puts
data/bin/format ADDED
@@ -0,0 +1,170 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # Controls the format of the release notes that Torque generates.
4
+ # Prompts for/sets the format string, and/or prints an example of the current format settings
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 'optparse'
12
+ require "#{lib_dir}/torque/format_string"
13
+ require "#{lib_dir}/torque/story"
14
+ require "#{lib_dir}/torque/torque_info_parser"
15
+ require "#{lib_dir}/torque/error/missing_torque_info_file_error"
16
+
17
+ # Parses the options
18
+ options = {}
19
+ option_parser = OptionParser.new do |opts|
20
+
21
+ help_message = "Sets the format string that Torque uses to generate release notes, or prints the current format " \
22
+ "string settings if run with no arguments"
23
+ help_message += "\nThe format string consists of plain text as well as a series of parameters (eg. \"%a\") that " \
24
+ "act as placeholders for elements of a story"
25
+ help_message += "\n"
26
+ help_message += "\nA format string of \"default\" will return the format string to its default value " \
27
+ "(\"#{Torque::FormatString.default}\")"
28
+ help_message += "\n"
29
+ help_message += "\n"
30
+ help_message +=
31
+ <<-END_STR
32
+ Parameters:
33
+ %a => Date accepted (MM/DD)
34
+ %A => Date accepted (YYYY/MM/DD)
35
+ %d => Description
36
+ %D => Description (tabbed once on each newline)
37
+ %e => Estimate
38
+ %i => ID
39
+ %l => Labels (separated by ", ")
40
+ %n => Newline character
41
+ %N => Name
42
+ %o => Owner of the story
43
+ %p => ID of the story's project
44
+ %u => URL pointing to the story
45
+ %t => Tab character
46
+ %T => Type (feature, bug, etc)
47
+ END_STR
48
+
49
+ opts.banner = "\nUsage:"
50
+ opts.banner += "\n torque format [options]"
51
+ opts.banner += "\n"
52
+ opts.banner += "\n#{help_message}"
53
+ opts.banner += "\n"
54
+
55
+ opts.on("-e", "--example", "Optionally sets your format string after printing an example story") do
56
+ |arg|
57
+ options[:example] = arg
58
+ end
59
+
60
+ opts.on("-h", "--help", "Displays this help screen") do
61
+ |arg|
62
+ options[:help] = arg
63
+ end
64
+
65
+ opts.on("-s", "--set", "Sets your format string") do
66
+ |arg|
67
+ options[:set] = arg
68
+ end
69
+
70
+ end
71
+
72
+ # Parses options and handles exceptions
73
+
74
+ begin
75
+ option_parser.parse!
76
+
77
+ rescue OptionParser::InvalidOption, OptionParser::MissingArgument
78
+ puts $!.to_s
79
+ puts option_parser
80
+ exit 3
81
+ end
82
+
83
+ # Handles special cases and exceptions
84
+
85
+ if ((ARGV.member? "help") || options[:help])
86
+ puts "(Ran with 'help' option; other options ignored)"
87
+ puts option_parser
88
+ exit
89
+ elsif !ARGV.empty?
90
+ puts "Unknown arguments: #{ARGV.join(", ")}"
91
+ puts option_parser.help
92
+ exit 3
93
+ elsif (options.has_key? :example) && (options.has_key? :set)
94
+ puts "Conflicting options: -e/--example and -s/--set. Choose either 'example' or 'set'."
95
+ exit 3
96
+ end
97
+
98
+ # An example story for display purposes
99
+
100
+ sample_story = Torque::Story.new({})
101
+
102
+ sample_story.current_state = "accepted"
103
+ sample_story.date_accepted = Date.new(2012, 12, 21)
104
+ sample_story.description = "Short description of story goes here\n- This is a side note\n- This is another side note"
105
+ sample_story.estimate = 3
106
+ sample_story.id = 12345678
107
+ sample_story.labels = ["label-1", "label-2"]
108
+ sample_story.name = "Story Name"
109
+ sample_story.owner = "Owner Smith"
110
+ sample_story.project_id = 123456
111
+ sample_story.type = "feature"
112
+
113
+ # Instantiates a TorqueInfoParser
114
+
115
+ begin
116
+ torque_info = Torque::TorqueInfoParser.new.parse
117
+ rescue Torque::MissingTorqueInfoFileError => e
118
+ puts "ABORTING"
119
+ puts e.message
120
+ puts "Run 'torque config' in this directory, or change your working directory"
121
+ exit 5
122
+ end
123
+
124
+ # If run with -e/--example or -s/--setup: Takes in a string, optionally verifies format settings, sets format string
125
+
126
+ if options[:example] || options[:set]
127
+
128
+ default = false # True if the default format string should be used
129
+ should_set = true # True if the format string should be changed on file
130
+
131
+ format = (ask("Enter a format string below:") {|q| q.readline = true}).to_s
132
+
133
+ if format == 'default'
134
+ default = true
135
+ format = Torque::FormatString.default
136
+ end
137
+
138
+ # If -e/--example, prints and validates the new settings
139
+
140
+ if options[:example]
141
+ puts "---"
142
+ puts Torque::FormatString.new(format).apply(sample_story)
143
+ puts "---"
144
+
145
+ valid = /^\s*(y|Y|n|N)\s*$/
146
+ should_set_prompt = ask("Would you like to set this as your format? [y/n]") {
147
+ |q|
148
+ q.validate = valid
149
+ }
150
+ should_set_prompt.strip!
151
+ should_set = (should_set_prompt =~ /y|Y/)
152
+ end
153
+
154
+ if should_set
155
+ torque_info.set("format", format)
156
+
157
+ to_print = "Set format string to "
158
+ to_print += (default ? "default" : "\"#{format}\"")
159
+ puts to_print
160
+ end
161
+
162
+ # If run with no arguments, displays the current format settings
163
+
164
+ else
165
+ puts
166
+ puts "Current format string: \"#{torque_info.format}\""
167
+ puts "---"
168
+ puts Torque::FormatString.new(torque_info.format).apply(sample_story)
169
+ puts "---"
170
+ end