crab 0.1.8 → 0.1.9

Sign up to get free protection for your applications and to get access to all the features.
data/bin/crab CHANGED
@@ -1,5 +1,21 @@
1
1
  #!/usr/bin/env ruby
2
- require 'rubygems'
3
- require 'crab'
2
+ # vim: set ft=ruby:
4
3
 
5
- Crab::CLI.start
4
+ cmd = ARGV.shift # get the subcommand
5
+
6
+ case cmd
7
+ when "-h", "--help", NilClass
8
+ system "crab-help"
9
+ exit 0
10
+ when "-v", "--version"
11
+ system "crab-version"
12
+ exit 0
13
+ end
14
+
15
+ unless system("crab-#{cmd}", *ARGV)
16
+ if $?.exitstatus == 127 # bash 'command not found'
17
+ $stderr.puts "Unknown subcommand #{cmd.inspect}"
18
+ system "crab-help"
19
+ exit 127
20
+ end
21
+ end
@@ -9,11 +9,10 @@ Usage: crab create name [options]
9
9
  BANNER
10
10
  end
11
11
 
12
- rally = Crab::Rally.new
13
12
  name = ARGV.join(" ")
14
13
  Trollop::die "Please specify a name for the story" if name.blank?
15
14
 
16
- rally.connect
17
- story = rally.create_story :name => name
18
-
19
- puts "#{story.formatted_id}: #{story.name} (#{story.state})"
15
+ Crab::Rally.new do |rally|
16
+ story = rally.create_story :name => name
17
+ puts "#{story.formatted_id}: #{story.name} (#{story.state})"
18
+ end
@@ -19,8 +19,6 @@ Usage: crab update story [options]
19
19
  opt :parent, "Parent", :type => String, :short => "-p"
20
20
  end
21
21
 
22
- rally = Crab::Rally.new
23
-
24
22
  Trollop::die "No story given" if ARGV.empty?
25
23
  Trollop::die "Nothing to update. Please provide some options" unless cmd_opts.any? {|k, v| k.to_s =~ /_given$/ }
26
24
 
@@ -35,27 +33,29 @@ end
35
33
  opts[:blocked] = cmd_opts[:blocked] if cmd_opts[:blocked_given]
36
34
  opts[:blocked] = !cmd_opts[:unblocked] if cmd_opts[:unblocked_given]
37
35
 
38
- rally.connect
36
+ Crab::Rally.new do |rally|
37
+ rally.connect
39
38
 
40
- story = rally.find_story_with_id ARGV.first
39
+ story = rally.find_story_with_id ARGV.first
41
40
 
42
- if cmd_opts[:iteration_given]
43
- opts[:iteration] = rally.find_iteration_by_name cmd_opts[:iteration]
44
- Trollop::die "Unknown iteration \"#{cmd_opts[:iteration]}\"" if opts[:iteration].nil?
45
- end
41
+ if cmd_opts[:iteration_given]
42
+ opts[:iteration] = rally.find_iteration_by_name cmd_opts[:iteration]
43
+ Trollop::die "Unknown iteration \"#{cmd_opts[:iteration]}\"" if opts[:iteration].nil?
44
+ end
46
45
 
47
- if cmd_opts[:release_given]
48
- opts[:release] = rally.find_release_by_name cmd_opts[:release]
49
- Trollop::die "Unknown release \"#{cmd_opts[:release]}\"" if opts[:release].nil?
50
- end
46
+ if cmd_opts[:release_given]
47
+ opts[:release] = rally.find_release_by_name cmd_opts[:release]
48
+ Trollop::die "Unknown release \"#{cmd_opts[:release]}\"" if opts[:release].nil?
49
+ end
51
50
 
52
- if cmd_opts[:parent_given]
53
- opts[:parent] = rally.find_story_with_id(cmd_opts[:parent]).rally_object
54
- Trollop::die "Unknown story \"#{cmd_opts[:parent]}\"" if opts[:parent].nil?
55
- end
51
+ if cmd_opts[:parent_given]
52
+ opts[:parent] = rally.find_story_with_id(cmd_opts[:parent]).rally_object
53
+ Trollop::die "Unknown story \"#{cmd_opts[:parent]}\"" if opts[:parent].nil?
54
+ end
56
55
 
57
- opts[:name] = story.name if opts[:name].blank?
56
+ opts[:name] = story.name if opts[:name].blank?
58
57
 
59
- story.update opts
58
+ story.update opts
60
59
 
61
- puts "#{story.formatted_id}: #{story.name} (#{story.state})"
60
+ puts "#{story.formatted_id}: #{story.name} (#{story.state})"
61
+ end
@@ -9,11 +9,10 @@ Usage: crab create name [options]
9
9
  BANNER
10
10
  end
11
11
 
12
- rally = Crab::Rally.new
13
12
  name = ARGV.join(" ")
14
13
  Trollop::die "Please specify a name for the story" if name.blank?
15
14
 
16
- rally.connect
17
- story = rally.create_story :name => name
18
-
19
- puts "#{story.formatted_id}: #{story.name} (#{story.state})"
15
+ Crab::Rally.new do |rally|
16
+ story = rally.create_story :name => name
17
+ puts "#{story.formatted_id}: #{story.name} (#{story.state})"
18
+ end
@@ -9,14 +9,12 @@ Usage: crab delete story [options]
9
9
  BANNER
10
10
  end
11
11
 
12
- rally = Crab::Rally.new
13
-
14
- story_id = ARGV.join(" ")
12
+ id = ARGV.join(" ")
15
13
  Trollop::die "Story ID must be specified" if story_id.blank?
16
14
 
17
- rally.connect
18
- story = rally.find_story_with_id story_id
19
-
20
- story.delete
15
+ Crab::Rally.new do |rally|
16
+ story = rally.find_story_with_id id
17
+ story.delete
21
18
 
22
- puts "Story #{story_id} deleted."
19
+ puts "Story #{id} deleted."
20
+ end
@@ -9,14 +9,12 @@ Usage: crab delete story [options]
9
9
  BANNER
10
10
  end
11
11
 
12
- rally = Crab::Rally.new
13
-
14
- story_id = ARGV.join(" ")
12
+ id = ARGV.join(" ")
15
13
  Trollop::die "Story ID must be specified" if story_id.blank?
16
14
 
17
- rally.connect
18
- story = rally.find_story_with_id story_id
19
-
20
- story.delete
15
+ Crab::Rally.new do |rally|
16
+ story = rally.find_story_with_id id
17
+ story.delete
21
18
 
22
- puts "Story #{story_id} deleted."
19
+ puts "Story #{id} deleted."
20
+ end
@@ -12,16 +12,14 @@ Usage: crab find [options] [text]
12
12
  opt :project, "Project to use (required unless set by 'crab project')", :short => "-p", :type => String
13
13
  end
14
14
 
15
- rally = Crab::Rally.new
16
15
  pattern = ARGV.map(&:strip).reject(&:empty?)
17
16
  project_name = valid_project_name(cmd_opts)
18
17
 
19
- rally.connect
18
+ Crab::Rally.new do |rally|
19
+ project = rally.find_project(project_name)
20
+ Trollop::die "Project #{cmd_opts[:project].inspect} not found" if project.nil?
20
21
 
21
- project = rally.find_project(project_name)
22
-
23
- Trollop::die "Project #{cmd_opts[:project].inspect} not found" if project.nil?
24
-
25
- rally.find_stories(project, pattern).each do |story|
26
- puts "#{story.formatted_id}: #{story.name} (#{story.state})"
22
+ rally.find_stories(project, pattern).each do |story|
23
+ puts "#{story.formatted_id}: #{story.name} (#{story.state})"
24
+ end
27
25
  end
@@ -0,0 +1,26 @@
1
+ # vim: set ft=ruby :
2
+ require 'crab'
3
+
4
+ puts <<-HELP
5
+ Usage: crab <command> [options*]
6
+
7
+ crab version #{Crab::VERSION}: A Cucumber-Rally bridge
8
+
9
+ Available commands:
10
+
11
+ create Create a new story in Rally
12
+ delete Delete an existing story in Rally
13
+ find Find stories by text in name, description or notes
14
+ login Persistently authenticate user with Rally
15
+ move Move a story from one status to the next (or previous)
16
+ project Persistently select project to work with in Rally
17
+ pull Downloads stories (and its test cases) as Cucumber feature files
18
+ show Show a story (and its test cases) as a Cucumber feature
19
+ testcase Manage test cases in a story (add, update, delete)
20
+ truncate Make sphor happy!
21
+ update Update a story (name, estimate, etc)
22
+
23
+
24
+ --version, -v: Print version and exit
25
+ --help, -h: Show this message
26
+ HELP
@@ -12,15 +12,14 @@ Usage: crab move story [options]
12
12
  opt :back, "Move story backwards (from accepted to completed, for example)"
13
13
  end
14
14
 
15
- rally = Crab::Rally.new
16
- story_id = ARGV.join(" ")
17
- Trollop::die "No story given" if story_id.empty?
15
+ id = ARGV.join(" ")
16
+ Trollop::die "No story given" if id.empty?
18
17
 
19
- rally.connect
18
+ Crab::Rally.new do |rally|
19
+ story = rally.find_story_with_id id
20
+ state = state_from(story.state)
20
21
 
21
- story = rally.find_story_with_id story_id
22
- state = state_from(story.state)
22
+ story.update :schedule_state => (cmd_opts[:back] ? state_before(state) : state_after(state))
23
23
 
24
- story.update :schedule_state => (cmd_opts[:back] ? state_before(state) : state_after(state))
25
-
26
- puts "#{story.formatted_id}: #{story.name} (#{story.state})"
24
+ puts "#{story.formatted_id}: #{story.name} (#{story.state})"
25
+ end
@@ -12,15 +12,14 @@ Usage: crab move story [options]
12
12
  opt :back, "Move story backwards (from accepted to completed, for example)"
13
13
  end
14
14
 
15
- rally = Crab::Rally.new
16
- story_id = ARGV.join(" ")
17
- Trollop::die "No story given" if story_id.empty?
15
+ id = ARGV.join(" ")
16
+ Trollop::die "No story given" if id.empty?
18
17
 
19
- rally.connect
18
+ Crab::Rally.new do |rally|
19
+ story = rally.find_story_with_id id
20
+ state = state_from(story.state)
20
21
 
21
- story = rally.find_story_with_id story_id
22
- state = state_from(story.state)
22
+ story.update :schedule_state => (cmd_opts[:back] ? state_before(state) : state_after(state))
23
23
 
24
- story.update :schedule_state => (cmd_opts[:back] ? state_before(state) : state_after(state))
25
-
26
- puts "#{story.formatted_id}: #{story.name} (#{story.state})"
24
+ puts "#{story.formatted_id}: #{story.name} (#{story.state})"
25
+ end
@@ -11,20 +11,19 @@ Usage: crab project [name]
11
11
  BANNER
12
12
  end
13
13
 
14
- rally = Crab::Rally.new
15
-
16
14
  current_project_name = self.class.current_project_name
17
15
  if current_project_name.present?
18
16
  puts current_project_name
17
+ exit 0
19
18
 
20
19
  elsif ARGV.reject {|arg| arg.blank? }.empty?
21
20
  puts "No project currently selected."
21
+ exit 1
22
+ end
22
23
 
23
- else
24
- name = ARGV.join(" ").strip
25
-
26
- rally.connect
24
+ name = ARGV.join(" ").strip
27
25
 
26
+ Crab::Rally.new do |rally|
28
27
  project = rally.find_project name
29
28
  Trollop::die "#{name.inspect} is not a valid project" if project.nil?
30
29
 
@@ -10,19 +10,20 @@ Usage: crab pull [options] story1 [story2 ...]
10
10
  opt :language, "Language to generate Cucumber features in (ISO code)", :default => "en", :short => "-l"
11
11
  end
12
12
 
13
- rally = Crab::Rally.new
14
- rally.connect
13
+ Crab::Rally.new do |rally|
15
14
 
16
- ARGV.each do |story_number|
17
- story = rally.find_story_with_id story_number
18
- Trollop::die "Could not find story with ID #{story_number}" if story.nil?
15
+ ARGV.each do |story_number|
16
+ story = rally.find_story_with_id story_number
17
+ Trollop::die "Could not find story with ID #{story_number}" if story.nil?
19
18
 
20
- puts "#{story.formatted_id}: #{story.full_file_name}"
19
+ puts "#{story.formatted_id}: #{story.full_file_name}"
21
20
 
22
- FileUtils.mkdir_p File.dirname(story.full_file_name)
23
- FileUtils.touch story.full_file_name
21
+ FileUtils.mkdir_p File.dirname(story.full_file_name)
22
+ FileUtils.touch story.full_file_name
24
23
 
25
- File.open(story.full_file_name, "w") do |file|
26
- file.write Crab::CucumberFeature.new(cmd_opts[:language]).generate_from story
24
+ File.open(story.full_file_name, "w") do |file|
25
+ file.write Crab::CucumberFeature.new(cmd_opts[:language]).generate_from story
26
+ end
27
27
  end
28
+
28
29
  end
@@ -9,14 +9,12 @@ Usage: crab delete story [options]
9
9
  BANNER
10
10
  end
11
11
 
12
- rally = Crab::Rally.new
13
-
14
- story_id = ARGV.join(" ")
12
+ id = ARGV.join(" ")
15
13
  Trollop::die "Story ID must be specified" if story_id.blank?
16
14
 
17
- rally.connect
18
- story = rally.find_story_with_id story_id
19
-
20
- story.delete
15
+ Crab::Rally.new do |rally|
16
+ story = rally.find_story_with_id id
17
+ story.delete
21
18
 
22
- puts "Story #{story_id} deleted."
19
+ puts "Story #{id} deleted."
20
+ end
@@ -9,14 +9,12 @@ Usage: crab delete story [options]
9
9
  BANNER
10
10
  end
11
11
 
12
- rally = Crab::Rally.new
13
-
14
- story_id = ARGV.join(" ")
12
+ id = ARGV.join(" ")
15
13
  Trollop::die "Story ID must be specified" if story_id.blank?
16
14
 
17
- rally.connect
18
- story = rally.find_story_with_id story_id
19
-
20
- story.delete
15
+ Crab::Rally.new do |rally|
16
+ story = rally.find_story_with_id id
17
+ story.delete
21
18
 
22
- puts "Story #{story_id} deleted."
19
+ puts "Story #{id} deleted."
20
+ end
@@ -1,7 +1,7 @@
1
1
  # vim: set ft=ruby :
2
2
  require 'crab'
3
3
 
4
- cmd_opts = Trollop::options do
4
+ opts = Trollop::options do
5
5
  banner <<-BANNER
6
6
  crab show: displays a story in Rally as a Cucumber feature
7
7
 
@@ -10,11 +10,9 @@ Usage: crab show story"
10
10
  opt :language, "Language to display Cucumber features in (ISO code)", :default => "en", :short => "-l"
11
11
  end
12
12
 
13
- story_id = ARGV.first
14
- rally = Crab::Rally.new
13
+ id = ARGV.first
14
+ Crab::Rally.new do |rally|
15
+ story = rally.find_story_with_id(id)
15
16
 
16
- rally.connect
17
-
18
- story = rally.find_story_with_id story_id
19
-
20
- puts Crab::CucumberFeature.new(cmd_opts[:language]).generate_from story
17
+ puts Crab::CucumberFeature.new(opts[:language]).generate_from story
18
+ end
@@ -26,8 +26,6 @@ def sanitize_options(opts, creating=true)
26
26
  result
27
27
  end
28
28
 
29
- rally = Crab::Rally.new
30
-
31
29
  Trollop::options do
32
30
  banner <<-BANNER
33
31
  crab testcase: manage test cases in a story (add, update, delete)
@@ -46,22 +44,22 @@ when "add"
46
44
 
47
45
  story_id = ARGV.shift
48
46
  name = ARGV.join(" ")
49
- add(story_id, name, opts)
50
-
51
- rally.connect
52
- tc = rally.create_test_case(story_id, name, sanitize_options(opts))
53
47
 
54
- puts "#{tc.story.formatted_id}/#{tc.formatted_id}: #{tc.name} (#{tc.tags.join(" ")})"
48
+ Crab::Rally.new do |rally|
49
+ tc = rally.create_test_case(story_id, name, sanitize_options(opts))
50
+ puts "#{tc.story.formatted_id}/#{tc.formatted_id}: #{tc.name} (#{tc.tags.join(" ")})"
51
+ end
55
52
 
56
53
  when "update"
57
54
  opts = add_or_update_options "crab testcase update: update a test case in Rally"
58
55
 
59
56
  tc_id = ARGV.shift
60
57
 
61
- rally.connect
62
- tc = rally.find_test_case(tc_id)
63
- tc.update(sanitize_options(opts))
64
- puts "#{tc.story.formatted_id}/#{tc.formatted_id}: #{tc.name} (#{tc.tags.join(" ")})"
58
+ Crab::Rally.new do |rally|
59
+ tc = rally.find_test_case(tc_id)
60
+ tc.update(sanitize_options(opts))
61
+ puts "#{tc.story.formatted_id}/#{tc.formatted_id}: #{tc.name} (#{tc.tags.join(" ")})"
62
+ end
65
63
 
66
64
  when "delete"
67
65
  Trollop::options do
@@ -69,10 +67,11 @@ when "delete"
69
67
  end
70
68
 
71
69
  tc_id = ARGV.shift
72
- rally.connect
73
- tc = rally.find_test_case(tc_id)
74
- tc.delete
75
- puts "Test case #{tc_id} deleted."
70
+ Crab::Rally.new do |rally|
71
+ tc = rally.find_test_case(tc_id)
72
+ tc.delete
73
+ puts "Test case #{tc_id} deleted."
74
+ end
76
75
 
77
76
  else
78
77
  Trollop::die "Unknown subcommand#{' ' + sub.inspect if sub}"
@@ -26,8 +26,6 @@ def sanitize_options(opts, creating=true)
26
26
  result
27
27
  end
28
28
 
29
- rally = Crab::Rally.new
30
-
31
29
  Trollop::options do
32
30
  banner <<-BANNER
33
31
  crab testcase: manage test cases in a story (add, update, delete)
@@ -46,22 +44,22 @@ when "add"
46
44
 
47
45
  story_id = ARGV.shift
48
46
  name = ARGV.join(" ")
49
- add(story_id, name, opts)
50
-
51
- rally.connect
52
- tc = rally.create_test_case(story_id, name, sanitize_options(opts))
53
47
 
54
- puts "#{tc.story.formatted_id}/#{tc.formatted_id}: #{tc.name} (#{tc.tags.join(" ")})"
48
+ Crab::Rally.new do |rally|
49
+ tc = rally.create_test_case(story_id, name, sanitize_options(opts))
50
+ puts "#{tc.story.formatted_id}/#{tc.formatted_id}: #{tc.name} (#{tc.tags.join(" ")})"
51
+ end
55
52
 
56
53
  when "update"
57
54
  opts = add_or_update_options "crab testcase update: update a test case in Rally"
58
55
 
59
56
  tc_id = ARGV.shift
60
57
 
61
- rally.connect
62
- tc = rally.find_test_case(tc_id)
63
- tc.update(sanitize_options(opts))
64
- puts "#{tc.story.formatted_id}/#{tc.formatted_id}: #{tc.name} (#{tc.tags.join(" ")})"
58
+ Crab::Rally.new do |rally|
59
+ tc = rally.find_test_case(tc_id)
60
+ tc.update(sanitize_options(opts))
61
+ puts "#{tc.story.formatted_id}/#{tc.formatted_id}: #{tc.name} (#{tc.tags.join(" ")})"
62
+ end
65
63
 
66
64
  when "delete"
67
65
  Trollop::options do
@@ -69,10 +67,11 @@ when "delete"
69
67
  end
70
68
 
71
69
  tc_id = ARGV.shift
72
- rally.connect
73
- tc = rally.find_test_case(tc_id)
74
- tc.delete
75
- puts "Test case #{tc_id} deleted."
70
+ Crab::Rally.new do |rally|
71
+ tc = rally.find_test_case(tc_id)
72
+ tc.delete
73
+ puts "Test case #{tc_id} deleted."
74
+ end
76
75
 
77
76
  else
78
77
  Trollop::die "Unknown subcommand#{' ' + sub.inspect if sub}"
@@ -19,8 +19,6 @@ Usage: crab update story [options]
19
19
  opt :parent, "Parent", :type => String, :short => "-p"
20
20
  end
21
21
 
22
- rally = Crab::Rally.new
23
-
24
22
  Trollop::die "No story given" if ARGV.empty?
25
23
  Trollop::die "Nothing to update. Please provide some options" unless cmd_opts.any? {|k, v| k.to_s =~ /_given$/ }
26
24
 
@@ -35,27 +33,29 @@ end
35
33
  opts[:blocked] = cmd_opts[:blocked] if cmd_opts[:blocked_given]
36
34
  opts[:blocked] = !cmd_opts[:unblocked] if cmd_opts[:unblocked_given]
37
35
 
38
- rally.connect
36
+ Crab::Rally.new do |rally|
37
+ rally.connect
39
38
 
40
- story = rally.find_story_with_id ARGV.first
39
+ story = rally.find_story_with_id ARGV.first
41
40
 
42
- if cmd_opts[:iteration_given]
43
- opts[:iteration] = rally.find_iteration_by_name cmd_opts[:iteration]
44
- Trollop::die "Unknown iteration \"#{cmd_opts[:iteration]}\"" if opts[:iteration].nil?
45
- end
41
+ if cmd_opts[:iteration_given]
42
+ opts[:iteration] = rally.find_iteration_by_name cmd_opts[:iteration]
43
+ Trollop::die "Unknown iteration \"#{cmd_opts[:iteration]}\"" if opts[:iteration].nil?
44
+ end
46
45
 
47
- if cmd_opts[:release_given]
48
- opts[:release] = rally.find_release_by_name cmd_opts[:release]
49
- Trollop::die "Unknown release \"#{cmd_opts[:release]}\"" if opts[:release].nil?
50
- end
46
+ if cmd_opts[:release_given]
47
+ opts[:release] = rally.find_release_by_name cmd_opts[:release]
48
+ Trollop::die "Unknown release \"#{cmd_opts[:release]}\"" if opts[:release].nil?
49
+ end
51
50
 
52
- if cmd_opts[:parent_given]
53
- opts[:parent] = rally.find_story_with_id(cmd_opts[:parent]).rally_object
54
- Trollop::die "Unknown story \"#{cmd_opts[:parent]}\"" if opts[:parent].nil?
55
- end
51
+ if cmd_opts[:parent_given]
52
+ opts[:parent] = rally.find_story_with_id(cmd_opts[:parent]).rally_object
53
+ Trollop::die "Unknown story \"#{cmd_opts[:parent]}\"" if opts[:parent].nil?
54
+ end
56
55
 
57
- opts[:name] = story.name if opts[:name].blank?
56
+ opts[:name] = story.name if opts[:name].blank?
58
57
 
59
- story.update opts
58
+ story.update opts
60
59
 
61
- puts "#{story.formatted_id}: #{story.name} (#{story.state})"
60
+ puts "#{story.formatted_id}: #{story.name} (#{story.state})"
61
+ end
@@ -19,8 +19,6 @@ Usage: crab update story [options]
19
19
  opt :parent, "Parent", :type => String, :short => "-p"
20
20
  end
21
21
 
22
- rally = Crab::Rally.new
23
-
24
22
  Trollop::die "No story given" if ARGV.empty?
25
23
  Trollop::die "Nothing to update. Please provide some options" unless cmd_opts.any? {|k, v| k.to_s =~ /_given$/ }
26
24
 
@@ -35,27 +33,29 @@ end
35
33
  opts[:blocked] = cmd_opts[:blocked] if cmd_opts[:blocked_given]
36
34
  opts[:blocked] = !cmd_opts[:unblocked] if cmd_opts[:unblocked_given]
37
35
 
38
- rally.connect
36
+ Crab::Rally.new do |rally|
37
+ rally.connect
39
38
 
40
- story = rally.find_story_with_id ARGV.first
39
+ story = rally.find_story_with_id ARGV.first
41
40
 
42
- if cmd_opts[:iteration_given]
43
- opts[:iteration] = rally.find_iteration_by_name cmd_opts[:iteration]
44
- Trollop::die "Unknown iteration \"#{cmd_opts[:iteration]}\"" if opts[:iteration].nil?
45
- end
41
+ if cmd_opts[:iteration_given]
42
+ opts[:iteration] = rally.find_iteration_by_name cmd_opts[:iteration]
43
+ Trollop::die "Unknown iteration \"#{cmd_opts[:iteration]}\"" if opts[:iteration].nil?
44
+ end
46
45
 
47
- if cmd_opts[:release_given]
48
- opts[:release] = rally.find_release_by_name cmd_opts[:release]
49
- Trollop::die "Unknown release \"#{cmd_opts[:release]}\"" if opts[:release].nil?
50
- end
46
+ if cmd_opts[:release_given]
47
+ opts[:release] = rally.find_release_by_name cmd_opts[:release]
48
+ Trollop::die "Unknown release \"#{cmd_opts[:release]}\"" if opts[:release].nil?
49
+ end
51
50
 
52
- if cmd_opts[:parent_given]
53
- opts[:parent] = rally.find_story_with_id(cmd_opts[:parent]).rally_object
54
- Trollop::die "Unknown story \"#{cmd_opts[:parent]}\"" if opts[:parent].nil?
55
- end
51
+ if cmd_opts[:parent_given]
52
+ opts[:parent] = rally.find_story_with_id(cmd_opts[:parent]).rally_object
53
+ Trollop::die "Unknown story \"#{cmd_opts[:parent]}\"" if opts[:parent].nil?
54
+ end
56
55
 
57
- opts[:name] = story.name if opts[:name].blank?
56
+ opts[:name] = story.name if opts[:name].blank?
58
57
 
59
- story.update opts
58
+ story.update opts
60
59
 
61
- puts "#{story.formatted_id}: #{story.name} (#{story.state})"
60
+ puts "#{story.formatted_id}: #{story.name} (#{story.state})"
61
+ end
@@ -0,0 +1,4 @@
1
+ # vim: set ft=ruby :
2
+
3
+ require 'crab'
4
+ puts "crab version #{Crab::VERSION}"
@@ -1,5 +1,31 @@
1
1
  require 'rally_rest_api'
2
2
 
3
+ Then /^I should see a usage screen$/ do
4
+ Then "the output should contain:", <<-TEXT
5
+ Usage: crab <command> [options*]
6
+
7
+ crab version #{Crab::VERSION}: A Cucumber-Rally bridge
8
+
9
+ Available commands:
10
+
11
+ create Create a new story in Rally
12
+ delete Delete an existing story in Rally
13
+ find Find stories by text in name, description or notes
14
+ login Persistently authenticate user with Rally
15
+ move Move a story from one status to the next (or previous)
16
+ project Persistently select project to work with in Rally
17
+ pull Downloads stories (and its test cases) as Cucumber feature files
18
+ show Show a story (and its test cases) as a Cucumber feature
19
+ testcase Manage test cases in a story (add, update, delete)
20
+ truncate Make sphor happy!
21
+ update Update a story (name, estimate, etc)
22
+
23
+
24
+ --version, -v: Print version and exit
25
+ --help, -h: Show this message
26
+ TEXT
27
+ end
28
+
3
29
  Given /^I am logged out$/ do
4
30
  end
5
31
 
@@ -7,7 +7,7 @@ Feature: Subcommand Help
7
7
 
8
8
  Scenario: No Arguments
9
9
  When I run `crab`
10
- Then the output should contain "Error: Unknown subcommand."
10
+ Then I should see a usage screen
11
11
 
12
12
  Scenario: Help
13
13
  When I run `crab -h`
@@ -24,10 +24,7 @@ Feature: Subcommand Help
24
24
 
25
25
  Scenario: Bogus Subcommand
26
26
  When I run `crab bogus`
27
- Then the output should contain:
28
- """
29
- Error: Unknown subcommand "bogus".
30
- """
27
+ Then I should see a usage screen
31
28
 
32
29
  Scenario: Pull Subcommand
33
30
  When I run `crab pull --help`
@@ -11,7 +11,6 @@ require 'trollop'
11
11
 
12
12
  # internals
13
13
  require "crab/utilities"
14
- require "crab/cli"
15
14
  require "crab/rally"
16
15
  require "crab/story"
17
16
  require "crab/testcase"
@@ -3,6 +3,13 @@ module Crab
3
3
 
4
4
  include Crab::Utilities
5
5
 
6
+ def initialize
7
+ if block_given?
8
+ connect
9
+ yield self
10
+ end
11
+ end
12
+
6
13
  def connect
7
14
  get_credentials
8
15
  @rally = ::RallyRestAPI.new :username => @username, :password => @password
@@ -1,3 +1,3 @@
1
1
  module Crab
2
- VERSION = "0.1.8"
2
+ VERSION = "0.1.9"
3
3
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: crab
3
3
  version: !ruby/object:Gem::Version
4
- hash: 11
4
+ hash: 9
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 1
9
- - 8
10
- version: 0.1.8
9
+ - 9
10
+ version: 0.1.9
11
11
  platform: ruby
12
12
  authors:
13
13
  - Carlos Villela
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-09-28 00:00:00 -03:00
18
+ date: 2011-09-29 00:00:00 -03:00
19
19
  default_executable: crab
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
@@ -155,6 +155,7 @@ executables:
155
155
  - crab-del
156
156
  - crab-delete
157
157
  - crab-find
158
+ - crab-help
158
159
  - crab-login
159
160
  - crab-move
160
161
  - crab-mv
@@ -168,6 +169,7 @@ executables:
168
169
  - crab-truncate
169
170
  - crab-up
170
171
  - crab-update
172
+ - crab-version
171
173
  extensions: []
172
174
 
173
175
  extra_rdoc_files: []
@@ -185,6 +187,7 @@ files:
185
187
  - bin/crab-del
186
188
  - bin/crab-delete
187
189
  - bin/crab-find
190
+ - bin/crab-help
188
191
  - bin/crab-login
189
192
  - bin/crab-move
190
193
  - bin/crab-mv
@@ -198,6 +201,7 @@ files:
198
201
  - bin/crab-truncate
199
202
  - bin/crab-up
200
203
  - bin/crab-update
204
+ - bin/crab-version
201
205
  - crab.gemspec
202
206
  - features/create-and-delete-story.feature
203
207
  - features/find-text-in-stories.feature
@@ -211,7 +215,6 @@ files:
211
215
  - features/support/aruba.rb
212
216
  - features/update-story-in-rally.feature
213
217
  - lib/crab.rb
214
- - lib/crab/cli.rb
215
218
  - lib/crab/cucumber_feature.rb
216
219
  - lib/crab/cucumber_scenario.rb
217
220
  - lib/crab/rally.rb
@@ -1,39 +0,0 @@
1
- module Crab
2
-
3
- SUB_COMMANDS = {
4
- "create" => "Create a new story in Rally",
5
- "delete" => "Delete an existing story in Rally",
6
- "find" => "Find stories by text in name, description or notes",
7
- "login" => "Persistently authenticate user with Rally",
8
- "project" => "Persistently select project to work with in Rally",
9
- "pull" => "Downloads stories (and its test cases) as Cucumber feature files",
10
- "show" => "Show a story (and its test cases) as a Cucumber feature",
11
- "testcase" => "Manage test cases in a story (add, update, delete)",
12
- "update" => "Update a story (name, estimate, etc)",
13
- "move" => "Move a story from one status to the next (or previous)",
14
- "truncate" => "Make sphor happy!",
15
- }
16
-
17
- class CLI
18
- def self.start
19
- Trollop::options do
20
- version "crab version #{Crab::VERSION}"
21
- banner """
22
- crab version #{Crab::VERSION}: A Cucumber-Rally bridge
23
-
24
- #{SUB_COMMANDS.keys.sort.map {|k| sprintf "%10s %s\n", k, SUB_COMMANDS[k] }.join}
25
- """
26
- stop_on SUB_COMMANDS.keys
27
- end
28
-
29
- cmd = ARGV.shift # get the subcommand
30
- Trollop::die "Unknown subcommand" unless cmd
31
-
32
- unless system("crab-#{cmd}", *ARGV)
33
- if $?.exitstatus == 127 # bash 'command not found error'
34
- Trollop::die "Unknown subcommand #{cmd.inspect}"
35
- end
36
- end
37
- end
38
- end
39
- end