story_branch 0.2.5 → 0.2.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (4) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +15 -7
  3. data/lib/story_branch.rb +61 -81
  4. metadata +14 -14
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 71eaa77737e5c7d0b0f33de5bd0f2bddea608b37
4
- data.tar.gz: dd9ffd60e2981b7b29f9cc874100407f31d099f4
3
+ metadata.gz: 27b478138908ff36d93a8c9c641136de6b789f1d
4
+ data.tar.gz: b7435c40b8257bb544f1379436a7559115100f2c
5
5
  SHA512:
6
- metadata.gz: 18501105780a33a97970652d34d906722362b7f60b791bee54c26da8cf511d5e28525f2022874fe9c450c4d55b33e45b575910d3da27a6e803987994aed817d0
7
- data.tar.gz: ae49ac7b0c07187ab62aa622aa0c416d17e36f89a0ffb0989d778e44b1fa8a615238b9078304414c48f94f3b0af6e8562ea799f032595b9fd6c178bbdc720b0d
6
+ metadata.gz: aa08dfe184feb00523a32995ea457952ef7881d34473d2aaf3423c4dbf2aedfa83050786090d1f84b2651bcf64061c2809ea0ef01eed3f052d53947f629af4e3
7
+ data.tar.gz: acec4e4033a5b0a6deff313be9b34253e89c379b614a0374c4e0b9a91d424e6377fb03644ecaf9867c14b964721a13d7314ab736509308bd6f44745bd8f6409f
data/README.md CHANGED
@@ -12,12 +12,17 @@ Pivotal Tracker Story. It will get started stories from your active
12
12
  project. You can enter text and press TAB to search for a story
13
13
  name, or TAB to show the full list. It will then suggest an editable
14
14
  branch name. When the branch is created the `story_id` will
15
- be appended to it.
15
+ be appended to it. Enter a blank to exit.
16
16
 
17
17
  `git start`: Start a story in Pivotal Tracker from the terminal.
18
18
  It'll get all unstarted stories in your current project. You can
19
19
  enter text and press TAB to search for a story name, or TAB to show
20
- the full list.
20
+ the full list. Enter blank to exit.
21
+
22
+ `git unstart`: Unstart a started story in Pivotal Tracker from the terminal.
23
+ It'll get all started stories in your current project. You can
24
+ enter text and press TAB to search for a story name, or TAB to show
25
+ the full list. Enter blank to exit.
21
26
 
22
27
  `git finish`: Create commit/message for the staged changes, e.g:
23
28
  "[Finishes #1234567] My Story Title" - optionally Finishes the story
@@ -48,7 +53,7 @@ Can be saved to `~/` or `./`
48
53
 
49
54
  You run story_branch from the git/project root folder.
50
55
 
51
- `start`, `branch`, are run interactively and will display a
56
+ `start`, `unstart` and `story`, are run interactively and will display a
52
57
  list of stories to work with.
53
58
 
54
59
  `finish` will scan the current branch name for a story id (as its
@@ -56,6 +61,8 @@ suffix) and if a valid, active story is found on pivotal tracker it
56
61
  will create a commit with a message to trigger pivotal's git
57
62
  integraton features.
58
63
 
64
+ All text entry supports Readline keyboard shortcuts / bindings, (word fwd/back, undo etc.)
65
+
59
66
  ### Command names
60
67
 
61
68
  It's possible to the commands in a few ways, we have deprecated the
@@ -63,10 +70,11 @@ old commmand names, and now encourage only the use of the `git`
63
70
  style usage.
64
71
 
65
72
  git style | deprecated
66
- ------------+--------------+--------------
67
- git story | story_branch | story-branch
68
- git start | story_start | story-start
69
- git finish | story_finish | story-finish
73
+ ------------+---------------+--------------
74
+ git story | story_branch | story-branch
75
+ git start | story_start | story-start
76
+ git unstart| story_unstart | story-unstart
77
+ git finish | story_finish | story-finish
70
78
 
71
79
  ## Contributing
72
80
 
data/lib/story_branch.rb CHANGED
@@ -5,7 +5,7 @@
5
5
  # Dominic Wong <dominic.wong.617@gmail.com>
6
6
  # Gabe Hollombe <gabe@neo.com>
7
7
  #
8
- # Version: 0.2.5
8
+ # Version: 0.2.6
9
9
  #
10
10
  # ## Description
11
11
  #
@@ -86,50 +86,45 @@ require 'pivotal-tracker'
86
86
  require 'rb-readline'
87
87
  require 'readline'
88
88
  require 'git'
89
- require 'active_support/core_ext/string/inflections'
90
89
  require 'levenshtein'
91
90
 
92
91
  trap('INT') {exit}
93
92
 
94
93
  module StoryBranch
95
-
96
94
  class Main
97
-
98
95
  ERRORS = {
99
- "Stories in the started state must be estimated." =>
96
+ 'Stories in the started state must be estimated.' =>
100
97
  "Error: Pivotal won't allow you to start an unestimated story"
101
98
  }
102
99
 
103
- PIVOTAL_CONFIG_FILES = ['.story_branch',"#{ENV['HOME']}/.story_branch"]
100
+ PIVOTAL_CONFIG_FILES = ['.story_branch', "#{ENV['HOME']}/.story_branch"]
101
+ PIVOTAL_API_CONFIG_FILES = ['.pivotal_api_key', "#{ENV['HOME']}/.pivotal_api_key"]
104
102
 
105
103
  attr_accessor :p
106
104
 
107
105
  def initialize
108
- if config_file
109
- @pivotal_info = YAML.load_file config_file
110
- end
111
- @p = PivotalUtils.new
112
- @p.api_key = config_value "api", 'PIVOTAL_API_KEY'
113
- @p.project_id = config_value "project", 'PIVOTAL_PROJECT_ID'
106
+ @pivotal_info = YAML.load_file config_file(PIVOTAL_CONFIG_FILES) if config_file(PIVOTAL_CONFIG_FILES)
107
+ @pivotal_api_info = YAML.load_file config_file(PIVOTAL_API_CONFIG_FILES) if config_file(PIVOTAL_API_CONFIG_FILES)
108
+ @p = PivotalUtils.new
109
+ @p.api_key = api_config_value
110
+ @p.project_id = config_value 'project', 'PIVOTAL_PROJECT_ID'
114
111
  exit unless @p.valid?
115
112
  end
116
113
 
117
114
  def create_story_branch
118
115
  begin
119
- puts "Connecting with Pivotal Tracker"
116
+ puts 'Connecting with Pivotal Tracker'
120
117
  @p.get_project
121
- puts "Getting stories..."
118
+ puts 'Getting stories...'
122
119
  stories = @p.display_stories :started, false
123
120
  if stories.length < 1
124
- puts "No stories started, exiting"
121
+ puts 'No stories started, exiting'
125
122
  exit
126
123
  end
127
124
  story = @p.select_story stories
128
- if story
129
- @p.create_feature_branch story
130
- end
125
+ @p.create_feature_branch story if story
131
126
  rescue RestClient::Unauthorized
132
- $stderr.puts "Pivotal API key or Project ID invalid"
127
+ $stderr.puts 'Pivotal API key or Project ID invalid'
133
128
  return nil
134
129
  end
135
130
  end
@@ -178,39 +173,44 @@ module StoryBranch
178
173
  end
179
174
 
180
175
  if GitUtils.has_status? :untracked or GitUtils.has_status? :modified
181
- puts "There are unstaged changes"
182
- puts "Use git add to stage changes before running git finish"
183
- puts "Use git stash if you want to hide changes for this commit"
176
+ puts 'There are unstaged changes'
177
+ puts 'Use git add to stage changes before running git finish'
178
+ puts 'Use git stash if you want to hide changes for this commit'
184
179
  return
185
180
  end
186
181
 
187
182
  unless GitUtils.has_status? :added or GitUtils.has_status? :staged
188
- puts "There are no staged changes."
189
- puts "Nothing to do"
183
+ puts 'There are no staged changes.'
184
+ puts 'Nothing to do'
190
185
  return
191
186
  end
192
187
 
193
- puts "Use standard finishing commit message: [y/N]?"
188
+ puts 'Use standard finishing commit message: [y/N]?'
194
189
  commit_message = "[Finishes ##{GitUtils.current_branch_story_parts[:id]}] #{StringUtils.undashed GitUtils.current_branch_story_parts[:title]}"
195
190
  puts commit_message
196
191
 
197
- if gets.chomp!.downcase == "y"
192
+ if gets.chomp!.downcase == 'y'
198
193
  GitUtils.commit commit_message
199
194
  else
200
195
  puts "Aborted"
201
196
  end
202
197
  rescue RestClient::Unauthorized
203
- $stderr.puts "Pivotal API key or Project ID invalid"
198
+ $stderr.puts 'Pivotal API key or Project ID invalid'
204
199
  return nil
205
200
  end
206
201
  end
207
202
 
208
- def config_file
209
- PIVOTAL_CONFIG_FILES.select{|conf| File.exists? conf}.first
203
+ def config_file file_set
204
+ file_set.select{|conf| File.exists? conf}.first
205
+ end
206
+
207
+ def api_config_value
208
+ return @pivotal_api_info['api'] if @pivotal_api_info && @pivotal_api_info['api']
209
+ config_value 'api', 'PIVOTAL_API_KEY'
210
210
  end
211
211
 
212
212
  def config_value key, env
213
- value = @pivotal_info[key] if @pivotal_info and @pivotal_info[key]
213
+ value = @pivotal_info[key] if @pivotal_info && @pivotal_info[key]
214
214
  value ||= env_required env
215
215
  value
216
216
  end
@@ -222,62 +222,52 @@ module StoryBranch
222
222
  end
223
223
  ENV[var_name]
224
224
  end
225
-
226
225
  end
227
226
 
228
227
  class StringUtils
229
-
230
228
  def self.dashed s
231
229
  s.tr(' _,./:;+&', '-')
232
230
  end
233
231
 
234
232
  def self.simple_sanitize s
235
- strip_newlines (s.tr '\'"%!@#$(){}[]*\\?', '')
233
+ strip_newlines s.tr '\'"%!@#$(){}[]*\\?', ''
236
234
  end
237
235
 
238
236
  def self.normalised_branch_name s
239
- StringUtils.simple_sanitize((StringUtils.dashed s).downcase).squeeze("-")
237
+ StringUtils.simple_sanitize StringUtils.dashed(s).downcase.squeeze('-')
240
238
  end
241
239
 
242
240
  def self.strip_newlines s
243
- s.tr "\n", "-"
241
+ s.tr "\n", '-'
244
242
  end
245
243
 
246
244
  def self.undashed s
247
245
  s.underscore.humanize
248
246
  end
249
-
250
247
  end
251
248
 
252
249
  class GitUtils
253
-
254
250
  def self.g
255
- Git.open "."
251
+ Git.open '.'
256
252
  end
257
253
 
258
254
  def self.is_existing_branch? name
259
255
  branch_names.each do |n|
260
- if Levenshtein.distance(n, name) < 3
261
- return true
262
- end
256
+ return true if Levenshtein.distance(n, name) < 3
263
257
  existing_branch_name = n.match(/(.*)(-[1-9][0-9]+$)/)
264
258
  if existing_branch_name
265
259
  levenshtein_distance = Levenshtein.distance existing_branch_name[1], name
266
- if levenshtein_distance < 3
267
- return true
268
- end
260
+ return true if levenshtein_distance < 3
269
261
  end
270
262
  end
271
- return false
263
+ false
272
264
  end
273
265
 
274
266
  def self.is_existing_story? id
275
267
  branch_names.each do |n|
276
268
  branch_id = n.match(/-[1-9][0-9]+$/)
277
269
  if branch_id
278
- if branch_id.to_s == "-#{id}"
279
- return true
280
- end
270
+ return true if branch_id.to_s == "-#{id}"
281
271
  end
282
272
  end
283
273
  false
@@ -297,11 +287,7 @@ module StoryBranch
297
287
 
298
288
  def self.current_branch_story_parts
299
289
  matches = current_branch.match(/(.*)-(\d+$)/)
300
- if matches.length == 3
301
- { title: matches[1], id: matches[2] }
302
- else
303
- nil
304
- end
290
+ { title: matches[1], id: matches[2] } if matches.length == 3
305
291
  end
306
292
 
307
293
  def self.create_branch name
@@ -310,11 +296,7 @@ module StoryBranch
310
296
  end
311
297
 
312
298
  def self.status_collect status, regex
313
- status.select{|e|
314
- e.match(regex)
315
- }.map{|e|
316
- e.match(regex)[1]
317
- }
299
+ status.select { |s| s.match(regex) }.map { |e| e.match(regex)[1] }
318
300
  end
319
301
 
320
302
  def self.status
@@ -340,11 +322,9 @@ module StoryBranch
340
322
  def self.commit message
341
323
  g.commit(message)
342
324
  end
343
-
344
325
  end
345
326
 
346
327
  class PivotalUtils
347
-
348
328
  attr_accessor :api_key, :project_id, :project
349
329
 
350
330
  def valid?
@@ -357,11 +337,10 @@ module StoryBranch
357
337
  end
358
338
 
359
339
  def is_current_branch_a_story?
360
- GitUtils.current_story and
361
- GitUtils.current_story.length == 3 and
362
- filtered_stories_list(:started, true).
363
- map(&:id).
364
- include? GitUtils.current_story[2].to_i
340
+ GitUtils.current_story && GitUtils.current_story.length == 3 &&
341
+ filtered_stories_list(:started, true)
342
+ .map(&:id)
343
+ .include?(GitUtils.current_story[2].to_i)
365
344
  end
366
345
 
367
346
  def story_from_current_branch
@@ -377,9 +356,9 @@ module StoryBranch
377
356
  stories = project.stories.all({current_state: state})
378
357
  if estimated
379
358
  stories.select{|s|
380
- s.story_type == "bug" or
381
- s.story_type == "chore" or
382
- (s.story_type == "feature" and s.estimate and s.estimate >= 0)}
359
+ s.story_type == 'bug' ||
360
+ s.story_type == 'chore' ||
361
+ (s.story_type == 'feature' && s.estimate && s.estimate >= 0)}
383
362
  else
384
363
  stories
385
364
  end
@@ -421,16 +400,17 @@ module StoryBranch
421
400
  dashed_story_name = StringUtils.normalised_branch_name story.name
422
401
  feature_branch_name = nil
423
402
  puts "You are checked out at: #{GitUtils.current_branch}"
424
- while feature_branch_name == nil or feature_branch_name == ""
425
- puts "Provide a new branch name... (TAB for suggested name)" if [nil, ""].include? feature_branch_name
426
- feature_branch_name = readline("Name of feature branch: ", [dashed_story_name])
403
+ while feature_branch_name == nil || feature_branch_name == ""
404
+ puts 'Provide a new branch name... (TAB for suggested name)' if [nil, ''].include? feature_branch_name
405
+ feature_branch_name = readline('Name of feature branch: ', [dashed_story_name])
427
406
  end
428
407
  feature_branch_name.chomp!
429
- if validate_branch_name feature_branch_name, story.id
430
- feature_branch_name_with_story_id = "#{feature_branch_name}-#{story.id}"
431
- puts "Creating: #{feature_branch_name_with_story_id} with #{GitUtils.current_branch} as parent"
432
- GitUtils.create_branch feature_branch_name_with_story_id
433
- end
408
+
409
+ return unless validate_branch_name feature_branch_name, story.id
410
+
411
+ feature_branch_name_with_story_id = "#{feature_branch_name}-#{story.id}"
412
+ puts "Creating: #{feature_branch_name_with_story_id} with #{GitUtils.current_branch} as parent"
413
+ GitUtils.create_branch feature_branch_name_with_story_id
434
414
  end
435
415
 
436
416
  # Branch name validation
@@ -440,7 +420,7 @@ module StoryBranch
440
420
  return false
441
421
  end
442
422
  if GitUtils.is_existing_branch? name
443
- puts "Error: This name is very similar to an existing branch. Avoid confusion and use a more unique name."
423
+ puts "Error: The name: #{name}, is very similar to an existing branch. To avoid confusion use a more unique name."
444
424
  return false
445
425
  end
446
426
  unless valid_branch_name? name
@@ -461,10 +441,10 @@ module StoryBranch
461
441
  # Store the state of the terminal
462
442
  RbReadline.clear_history
463
443
  if completions.length > 0
464
- completions.each {|i| Readline::HISTORY.push i}
465
- RbReadline.rl_completer_word_break_characters = ""
466
- Readline.completion_proc = proc {|s| completions.grep(/#{Regexp.escape(s)}/) }
467
- Readline.completion_append_character = ""
444
+ completions.each { |i| Readline::HISTORY.push i}
445
+ RbReadline.rl_completer_word_break_characters = ''
446
+ Readline.completion_proc = proc { |s| completions.grep(/#{Regexp.escape(s)}/) }
447
+ Readline.completion_append_character = ''
468
448
  end
469
449
  Readline.readline(prompt, false)
470
450
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: story_branch
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.5
4
+ version: 0.2.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jason Milkins
@@ -17,70 +17,70 @@ dependencies:
17
17
  name: pivotal-tracker
18
18
  requirement: !ruby/object:Gem::Requirement
19
19
  requirements:
20
- - - ~>
20
+ - - "~>"
21
21
  - !ruby/object:Gem::Version
22
22
  version: '0.5'
23
23
  type: :runtime
24
24
  prerelease: false
25
25
  version_requirements: !ruby/object:Gem::Requirement
26
26
  requirements:
27
- - - ~>
27
+ - - "~>"
28
28
  - !ruby/object:Gem::Version
29
29
  version: '0.5'
30
30
  - !ruby/object:Gem::Dependency
31
31
  name: git
32
32
  requirement: !ruby/object:Gem::Requirement
33
33
  requirements:
34
- - - ~>
34
+ - - "~>"
35
35
  - !ruby/object:Gem::Version
36
36
  version: '1.2'
37
37
  type: :runtime
38
38
  prerelease: false
39
39
  version_requirements: !ruby/object:Gem::Requirement
40
40
  requirements:
41
- - - ~>
41
+ - - "~>"
42
42
  - !ruby/object:Gem::Version
43
43
  version: '1.2'
44
44
  - !ruby/object:Gem::Dependency
45
45
  name: levenshtein-ffi
46
46
  requirement: !ruby/object:Gem::Requirement
47
47
  requirements:
48
- - - ~>
48
+ - - "~>"
49
49
  - !ruby/object:Gem::Version
50
50
  version: '1.0'
51
51
  type: :runtime
52
52
  prerelease: false
53
53
  version_requirements: !ruby/object:Gem::Requirement
54
54
  requirements:
55
- - - ~>
55
+ - - "~>"
56
56
  - !ruby/object:Gem::Version
57
57
  version: '1.0'
58
58
  - !ruby/object:Gem::Dependency
59
59
  name: rb-readline
60
60
  requirement: !ruby/object:Gem::Requirement
61
61
  requirements:
62
- - - ~>
62
+ - - "~>"
63
63
  - !ruby/object:Gem::Version
64
64
  version: '0.5'
65
65
  type: :runtime
66
66
  prerelease: false
67
67
  version_requirements: !ruby/object:Gem::Requirement
68
68
  requirements:
69
- - - ~>
69
+ - - "~>"
70
70
  - !ruby/object:Gem::Version
71
71
  version: '0.5'
72
72
  - !ruby/object:Gem::Dependency
73
73
  name: rspec
74
74
  requirement: !ruby/object:Gem::Requirement
75
75
  requirements:
76
- - - ~>
76
+ - - "~>"
77
77
  - !ruby/object:Gem::Version
78
78
  version: '3.0'
79
79
  type: :development
80
80
  prerelease: false
81
81
  version_requirements: !ruby/object:Gem::Requirement
82
82
  requirements:
83
- - - ~>
83
+ - - "~>"
84
84
  - !ruby/object:Gem::Version
85
85
  version: '3.0'
86
86
  description: Simple gem that fetches the available stories in your pivotaltracker
@@ -142,17 +142,17 @@ require_paths:
142
142
  - lib
143
143
  required_ruby_version: !ruby/object:Gem::Requirement
144
144
  requirements:
145
- - - '>='
145
+ - - ">="
146
146
  - !ruby/object:Gem::Version
147
147
  version: 1.9.3
148
148
  required_rubygems_version: !ruby/object:Gem::Requirement
149
149
  requirements:
150
- - - '>='
150
+ - - ">="
151
151
  - !ruby/object:Gem::Version
152
152
  version: '0'
153
153
  requirements: []
154
154
  rubyforge_project:
155
- rubygems_version: 2.2.2
155
+ rubygems_version: 2.4.3
156
156
  signing_key:
157
157
  specification_version: 4
158
158
  summary: Story Branch - create git branches based on pivotal tracker stories