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 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