crab 0.2.12 → 0.2.13
Sign up to get free protection for your applications and to get access to all the features.
- data/bin/crab-defect +31 -0
- data/bin/crab-defect-delete +29 -0
- data/bin/crab-defect-find +45 -0
- data/bin/crab-defect-help +26 -0
- data/bin/crab-help +3 -1
- data/bin/crab-login +11 -1
- data/bin/crab-logout +4 -3
- data/bin/crab-project +9 -2
- data/bin/crab-tc-add +1 -3
- data/bin/crab-tc-create +1 -3
- data/bin/crab-tc-new +1 -3
- data/bin/crab-testcase-add +1 -3
- data/bin/crab-testcase-create +1 -3
- data/bin/crab-testcase-new +1 -3
- data/features/login-and-out-of-rally.feature +8 -0
- data/features/project-selection.feature +10 -4
- data/features/recursively-look-for-dotcrab-folder.feature +31 -0
- data/features/steps/rally_steps.rb +12 -14
- data/features/subcommand-help.feature +1 -1
- data/lib/crab/defect.rb +51 -0
- data/lib/crab/rally.rb +33 -1
- data/lib/crab/utilities.rb +19 -5
- data/lib/crab/version.rb +1 -1
- metadata +14 -4
data/bin/crab-defect
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# vim: set ft=ruby:
|
3
|
+
require 'crab'
|
4
|
+
|
5
|
+
class Crab::DefectMain
|
6
|
+
|
7
|
+
class << self
|
8
|
+
|
9
|
+
include Crab::Utilities
|
10
|
+
|
11
|
+
def run(args=ARGV)
|
12
|
+
cmd = args.shift # get the subcommand
|
13
|
+
|
14
|
+
case cmd
|
15
|
+
when "-h", "--help", NilClass
|
16
|
+
system "crab-defect-help"
|
17
|
+
exit 0
|
18
|
+
end
|
19
|
+
|
20
|
+
unless system("crab-defect-#{cmd}", *args)
|
21
|
+
if $?.exitstatus == 127 # bash 'command not found'
|
22
|
+
logger.error "Unknown subcommand \"defect #{cmd}\""
|
23
|
+
system "crab-defect-help"
|
24
|
+
exit 1
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
Crab::DefectMain.run
|
@@ -0,0 +1,29 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# vim: set ft=ruby :
|
3
|
+
require 'crab'
|
4
|
+
|
5
|
+
class Crab::DefectDelete
|
6
|
+
|
7
|
+
def self.run(args=ARGV)
|
8
|
+
opts = Trollop::options(args) do
|
9
|
+
banner <<-BANNER
|
10
|
+
crab defect delete: delete an existing defect in Rally
|
11
|
+
|
12
|
+
Usage: crab defect delete <id> [options*]
|
13
|
+
BANNER
|
14
|
+
opt :dry, "Dry-run (don't change anything)", :short => "-D", :default => false
|
15
|
+
end
|
16
|
+
|
17
|
+
id = args.join(" ")
|
18
|
+
Trollop::die "Defect ID must be specified" if id.blank?
|
19
|
+
|
20
|
+
Crab::Rally.new(opts[:dry]) do |rally|
|
21
|
+
defect = rally.find_defect_with_id id
|
22
|
+
defect.delete
|
23
|
+
|
24
|
+
puts "Defect #{id} deleted."
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
Crab::DefectDelete.run
|
@@ -0,0 +1,45 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# vim: set ft=ruby :
|
3
|
+
require 'crab'
|
4
|
+
|
5
|
+
class Crab::DefectFind
|
6
|
+
|
7
|
+
class << self
|
8
|
+
|
9
|
+
include Crab::Utilities
|
10
|
+
|
11
|
+
def run(args=ARGV)
|
12
|
+
opts = Trollop::options(args) do
|
13
|
+
banner <<-BANNER
|
14
|
+
crab defect find: find a defect in Rally
|
15
|
+
|
16
|
+
Usage: crab defect find [options*] [text]
|
17
|
+
BANNER
|
18
|
+
opt :project, "Project to use (required unless set by 'crab project')", :short => "-p", :type => String
|
19
|
+
opt :iteration, "Limit search to this iteration", :short => "-i", :type => String
|
20
|
+
opt :release, "Limit search to this release", :short => "-r", :type => String
|
21
|
+
opt :parent, "Limit search to children of this defect", :short => "-P", :type => String
|
22
|
+
opt :dry, "Dry-run (don't change anything)", :short => "-D", :default => false
|
23
|
+
end
|
24
|
+
|
25
|
+
pattern = args.map(&:strip).reject(&:empty?)
|
26
|
+
project_name = valid_project_name(opts)
|
27
|
+
|
28
|
+
Crab::Rally.new(opts[:dry]) do |rally|
|
29
|
+
project = rally.find_project(project_name)
|
30
|
+
Trollop::die "Project #{opts[:project].inspect} not found" if project.nil?
|
31
|
+
|
32
|
+
find_opts = {}
|
33
|
+
find_opts[:iteration] = rally.find_iteration_by_name opts[:iteration], project if opts[:iteration_given]
|
34
|
+
find_opts[:release] = rally.find_release_by_name opts[:release], project if opts[:release_given]
|
35
|
+
find_opts[:parent] = rally.find_defect_with_id opts[:parent] if opts[:parent_given]
|
36
|
+
|
37
|
+
rally.find_defects(project, pattern, find_opts).each do |defect|
|
38
|
+
puts "#{defect.formatted_id}: #{defect.name} (#{defect.state})"
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
Crab::DefectFind.run
|
@@ -0,0 +1,26 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# vim: set ft=ruby :
|
3
|
+
require 'crab'
|
4
|
+
|
5
|
+
class Crab::DefectHelp
|
6
|
+
|
7
|
+
def self.run
|
8
|
+
puts <<-HELP
|
9
|
+
Usage: crab defect <command> [options*]
|
10
|
+
|
11
|
+
Available commands:
|
12
|
+
|
13
|
+
create Create a new defect in a story
|
14
|
+
delete Delete an existing defect
|
15
|
+
find Find defects
|
16
|
+
help Show this help text
|
17
|
+
list List defects
|
18
|
+
show Show a defect (and its steps) as a Cucumber scenario
|
19
|
+
update Update a defect
|
20
|
+
|
21
|
+
--help, -h: Show this message
|
22
|
+
HELP
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
Crab::DefectHelp.run
|
data/bin/crab-help
CHANGED
@@ -13,10 +13,12 @@ crab version #{Crab::VERSION}: A Cucumber-Rally bridge
|
|
13
13
|
Available commands:
|
14
14
|
|
15
15
|
help Show this help text
|
16
|
-
iteration Manipulate iterations
|
17
16
|
login Persistently authenticate user with Rally
|
18
17
|
logout Remove stored Rally credentials
|
19
18
|
project Persistently select project to work with in Rally
|
19
|
+
|
20
|
+
defect Manipulate defects
|
21
|
+
iteration Manipulate iterations
|
20
22
|
release Manipulate releases
|
21
23
|
story Manipulate stories
|
22
24
|
testcase Manipulate test cases
|
data/bin/crab-login
CHANGED
@@ -13,16 +13,26 @@ class Crab::Login
|
|
13
13
|
banner <<-BANNER
|
14
14
|
Usage: crab login [options*]
|
15
15
|
|
16
|
-
Log into Rally. Your credentials will be written to ~/.crab/credentials.
|
16
|
+
Log into Rally. Your credentials will be written to ~/.crab/credentials unless --project is specified.
|
17
17
|
BANNER
|
18
18
|
|
19
19
|
opt :username, "Username", :type => String, :short => "-u"
|
20
20
|
opt :password, "Password", :type => String, :short => "-p"
|
21
|
+
opt :project, "Store credentials into current folder", :short => "-P", :default => false
|
21
22
|
end
|
22
23
|
|
23
24
|
username = opts[:username_given] ? opts[:username] : ask("Username: ")
|
24
25
|
password = opts[:password_given] ? opts[:password] : ask("Password: ") {|q| q.echo = false }
|
25
26
|
|
27
|
+
crab_dir = if opts[:project]
|
28
|
+
File.expand_path "./.crab"
|
29
|
+
else
|
30
|
+
File.expand_path "~/.crab"
|
31
|
+
end
|
32
|
+
|
33
|
+
FileUtils.mkdir_p crab_dir
|
34
|
+
credentials_file = "#{crab_dir}/credentials"
|
35
|
+
|
26
36
|
File.open(credentials_file, 'w') do |file|
|
27
37
|
file.puts username
|
28
38
|
file.puts password
|
data/bin/crab-logout
CHANGED
@@ -14,15 +14,16 @@ class Crab::Logout
|
|
14
14
|
banner <<-BANNER
|
15
15
|
Usage: crab logout [options*]
|
16
16
|
|
17
|
-
Log out of Rally. Your credentials will be removed from ~/.crab/credentials.
|
17
|
+
Log out of Rally. Your credentials will be removed from current project directory or home folder (~/.crab/credentials).
|
18
18
|
BANNER
|
19
19
|
opt :dry, "Dry-run (don't change anything)", :short => "-D", :default => false
|
20
20
|
end
|
21
21
|
|
22
22
|
fileutils_opts = opts[:dry] ? {:noop => true, :verbose => true} : {}
|
23
|
-
|
23
|
+
file = credentials_file
|
24
|
+
FileUtils.rm_rf(file, fileutils_opts)
|
24
25
|
|
25
|
-
puts "Credentials removed
|
26
|
+
puts "Credentials removed from #{file}"
|
26
27
|
|
27
28
|
end
|
28
29
|
end
|
data/bin/crab-project
CHANGED
@@ -15,14 +15,21 @@ crab project: show or persistently select project to work with in Rally
|
|
15
15
|
|
16
16
|
Usage: crab project [name] [options*]
|
17
17
|
BANNER
|
18
|
+
opt :clear, "Remove a previous project selection", :short => "-c", :default => false
|
18
19
|
opt :dry, "Dry-run (don't change anything)", :short => "-D", :default => false
|
19
20
|
end
|
20
21
|
|
21
22
|
name = args.join(" ").strip
|
23
|
+
is_dry_run = opts[:dry] ? { :noop => true, :verbose => true } : {}
|
22
24
|
|
23
25
|
if name.empty?
|
24
26
|
if current_project_name.present?
|
25
|
-
|
27
|
+
if opts[:clear]
|
28
|
+
FileUtils.rm_rf dotcrab_file("project"), is_dry_run
|
29
|
+
puts "Project selection removed."
|
30
|
+
else
|
31
|
+
puts current_project_name
|
32
|
+
end
|
26
33
|
else
|
27
34
|
puts "No project currently selected."
|
28
35
|
end
|
@@ -33,7 +40,7 @@ Usage: crab project [name] [options*]
|
|
33
40
|
project = rally.find_project name
|
34
41
|
Trollop::die "#{name.inspect} is not a valid project" if project.nil?
|
35
42
|
|
36
|
-
FileUtils.mkdir_p ".crab",
|
43
|
+
FileUtils.mkdir_p ".crab", is_dry_run
|
37
44
|
file = ".crab/project"
|
38
45
|
output = project.name
|
39
46
|
|
data/bin/crab-tc-add
CHANGED
@@ -12,7 +12,7 @@ class Crab::TestCaseCreate
|
|
12
12
|
opts = add_or_update_options <<-BANNER, args
|
13
13
|
crab testcase create: add a test case to a story in Rally
|
14
14
|
|
15
|
-
Usage: crab testcase create <story> <name> [options*]
|
15
|
+
Usage: crab testcase create <story> --name <name> [options*]
|
16
16
|
BANNER
|
17
17
|
|
18
18
|
story_id = args.shift
|
@@ -24,7 +24,6 @@ Usage: crab testcase create <story> <name> [options*]
|
|
24
24
|
|
25
25
|
unless opts[:name_given]
|
26
26
|
logger.error "Error: Test case name not provided."
|
27
|
-
system "crab-testcase-help"
|
28
27
|
exit 1
|
29
28
|
end
|
30
29
|
|
@@ -32,7 +31,6 @@ Usage: crab testcase create <story> <name> [options*]
|
|
32
31
|
tc = rally.create_test_case(story_id, name, sanitize_options(opts))
|
33
32
|
puts "#{tc.story.formatted_id}/#{tc.formatted_id}: #{tc.name} (#{tc.tags.join(" ")})"
|
34
33
|
end
|
35
|
-
|
36
34
|
end
|
37
35
|
end
|
38
36
|
end
|
data/bin/crab-tc-create
CHANGED
@@ -12,7 +12,7 @@ class Crab::TestCaseCreate
|
|
12
12
|
opts = add_or_update_options <<-BANNER, args
|
13
13
|
crab testcase create: add a test case to a story in Rally
|
14
14
|
|
15
|
-
Usage: crab testcase create <story> <name> [options*]
|
15
|
+
Usage: crab testcase create <story> --name <name> [options*]
|
16
16
|
BANNER
|
17
17
|
|
18
18
|
story_id = args.shift
|
@@ -24,7 +24,6 @@ Usage: crab testcase create <story> <name> [options*]
|
|
24
24
|
|
25
25
|
unless opts[:name_given]
|
26
26
|
logger.error "Error: Test case name not provided."
|
27
|
-
system "crab-testcase-help"
|
28
27
|
exit 1
|
29
28
|
end
|
30
29
|
|
@@ -32,7 +31,6 @@ Usage: crab testcase create <story> <name> [options*]
|
|
32
31
|
tc = rally.create_test_case(story_id, name, sanitize_options(opts))
|
33
32
|
puts "#{tc.story.formatted_id}/#{tc.formatted_id}: #{tc.name} (#{tc.tags.join(" ")})"
|
34
33
|
end
|
35
|
-
|
36
34
|
end
|
37
35
|
end
|
38
36
|
end
|
data/bin/crab-tc-new
CHANGED
@@ -12,7 +12,7 @@ class Crab::TestCaseCreate
|
|
12
12
|
opts = add_or_update_options <<-BANNER, args
|
13
13
|
crab testcase create: add a test case to a story in Rally
|
14
14
|
|
15
|
-
Usage: crab testcase create <story> <name> [options*]
|
15
|
+
Usage: crab testcase create <story> --name <name> [options*]
|
16
16
|
BANNER
|
17
17
|
|
18
18
|
story_id = args.shift
|
@@ -24,7 +24,6 @@ Usage: crab testcase create <story> <name> [options*]
|
|
24
24
|
|
25
25
|
unless opts[:name_given]
|
26
26
|
logger.error "Error: Test case name not provided."
|
27
|
-
system "crab-testcase-help"
|
28
27
|
exit 1
|
29
28
|
end
|
30
29
|
|
@@ -32,7 +31,6 @@ Usage: crab testcase create <story> <name> [options*]
|
|
32
31
|
tc = rally.create_test_case(story_id, name, sanitize_options(opts))
|
33
32
|
puts "#{tc.story.formatted_id}/#{tc.formatted_id}: #{tc.name} (#{tc.tags.join(" ")})"
|
34
33
|
end
|
35
|
-
|
36
34
|
end
|
37
35
|
end
|
38
36
|
end
|
data/bin/crab-testcase-add
CHANGED
@@ -12,7 +12,7 @@ class Crab::TestCaseCreate
|
|
12
12
|
opts = add_or_update_options <<-BANNER, args
|
13
13
|
crab testcase create: add a test case to a story in Rally
|
14
14
|
|
15
|
-
Usage: crab testcase create <story> <name> [options*]
|
15
|
+
Usage: crab testcase create <story> --name <name> [options*]
|
16
16
|
BANNER
|
17
17
|
|
18
18
|
story_id = args.shift
|
@@ -24,7 +24,6 @@ Usage: crab testcase create <story> <name> [options*]
|
|
24
24
|
|
25
25
|
unless opts[:name_given]
|
26
26
|
logger.error "Error: Test case name not provided."
|
27
|
-
system "crab-testcase-help"
|
28
27
|
exit 1
|
29
28
|
end
|
30
29
|
|
@@ -32,7 +31,6 @@ Usage: crab testcase create <story> <name> [options*]
|
|
32
31
|
tc = rally.create_test_case(story_id, name, sanitize_options(opts))
|
33
32
|
puts "#{tc.story.formatted_id}/#{tc.formatted_id}: #{tc.name} (#{tc.tags.join(" ")})"
|
34
33
|
end
|
35
|
-
|
36
34
|
end
|
37
35
|
end
|
38
36
|
end
|
data/bin/crab-testcase-create
CHANGED
@@ -12,7 +12,7 @@ class Crab::TestCaseCreate
|
|
12
12
|
opts = add_or_update_options <<-BANNER, args
|
13
13
|
crab testcase create: add a test case to a story in Rally
|
14
14
|
|
15
|
-
Usage: crab testcase create <story> <name> [options*]
|
15
|
+
Usage: crab testcase create <story> --name <name> [options*]
|
16
16
|
BANNER
|
17
17
|
|
18
18
|
story_id = args.shift
|
@@ -24,7 +24,6 @@ Usage: crab testcase create <story> <name> [options*]
|
|
24
24
|
|
25
25
|
unless opts[:name_given]
|
26
26
|
logger.error "Error: Test case name not provided."
|
27
|
-
system "crab-testcase-help"
|
28
27
|
exit 1
|
29
28
|
end
|
30
29
|
|
@@ -32,7 +31,6 @@ Usage: crab testcase create <story> <name> [options*]
|
|
32
31
|
tc = rally.create_test_case(story_id, name, sanitize_options(opts))
|
33
32
|
puts "#{tc.story.formatted_id}/#{tc.formatted_id}: #{tc.name} (#{tc.tags.join(" ")})"
|
34
33
|
end
|
35
|
-
|
36
34
|
end
|
37
35
|
end
|
38
36
|
end
|
data/bin/crab-testcase-new
CHANGED
@@ -12,7 +12,7 @@ class Crab::TestCaseCreate
|
|
12
12
|
opts = add_or_update_options <<-BANNER, args
|
13
13
|
crab testcase create: add a test case to a story in Rally
|
14
14
|
|
15
|
-
Usage: crab testcase create <story> <name> [options*]
|
15
|
+
Usage: crab testcase create <story> --name <name> [options*]
|
16
16
|
BANNER
|
17
17
|
|
18
18
|
story_id = args.shift
|
@@ -24,7 +24,6 @@ Usage: crab testcase create <story> <name> [options*]
|
|
24
24
|
|
25
25
|
unless opts[:name_given]
|
26
26
|
logger.error "Error: Test case name not provided."
|
27
|
-
system "crab-testcase-help"
|
28
27
|
exit 1
|
29
28
|
end
|
30
29
|
|
@@ -32,7 +31,6 @@ Usage: crab testcase create <story> <name> [options*]
|
|
32
31
|
tc = rally.create_test_case(story_id, name, sanitize_options(opts))
|
33
32
|
puts "#{tc.story.formatted_id}/#{tc.formatted_id}: #{tc.name} (#{tc.tags.join(" ")})"
|
34
33
|
end
|
35
|
-
|
36
34
|
end
|
37
35
|
end
|
38
36
|
end
|
@@ -11,3 +11,11 @@ Feature: Log In and Out of Rally
|
|
11
11
|
Then the exit status should be 0
|
12
12
|
And the user's home directory should have a file named ".crab/credentials"
|
13
13
|
|
14
|
+
Scenario: Logged Out, Logging In project specific
|
15
|
+
Given a directory named "my-project"
|
16
|
+
And I cd to "my-project"
|
17
|
+
When I run `crab login -P` interactively
|
18
|
+
And I type my username
|
19
|
+
And I type my password
|
20
|
+
Then the exit status should be 0
|
21
|
+
And a file named ".crab/credentials" should exist
|
@@ -1,18 +1,24 @@
|
|
1
1
|
Feature: Project Selection
|
2
|
-
|
2
|
+
|
3
3
|
In order to work with the find, list etc commands more effectively
|
4
4
|
A lazy developer
|
5
5
|
Wants to set the project persistently across all commands
|
6
6
|
|
7
|
-
Background:
|
7
|
+
Background:
|
8
8
|
Given I am logged in
|
9
9
|
|
10
|
-
Scenario: Selecting
|
11
|
-
Given
|
10
|
+
Scenario: Selecting and Clearing Projects
|
11
|
+
Given I select my test project
|
12
|
+
|
13
|
+
When I run `crab project --clear`
|
14
|
+
Then the output should contain "Project selection removed."
|
15
|
+
|
12
16
|
When I run `crab project`
|
13
17
|
Then the output should contain "No project currently selected."
|
18
|
+
|
14
19
|
When I select my test project
|
15
20
|
Then the exit status should be 0
|
21
|
+
|
16
22
|
When I run `crab project`
|
17
23
|
Then the output should be the name of my test project
|
18
24
|
|
@@ -0,0 +1,31 @@
|
|
1
|
+
Feature: Recursively looks for .crab folder
|
2
|
+
|
3
|
+
In order to easily work with multiple projects and avoid having to cd back into project's root
|
4
|
+
A lazy developer
|
5
|
+
Wants to run crab from any project's subfolder
|
6
|
+
|
7
|
+
Background:
|
8
|
+
Given a directory named "crab-project/subfolder/othersubfolder"
|
9
|
+
|
10
|
+
Scenario: Uses Parent Folder Project Settings From Any Subfolder
|
11
|
+
Given I am logged in
|
12
|
+
And no project is selected
|
13
|
+
And I cd to "crab-project"
|
14
|
+
And I have selected my test project
|
15
|
+
When I cd to "subfolder"
|
16
|
+
And I run `crab project`
|
17
|
+
Then the output should be the name of my test project
|
18
|
+
When I cd to "othersubfolder"
|
19
|
+
And I run `crab project`
|
20
|
+
Then the output should be the name of my test project
|
21
|
+
|
22
|
+
Scenario: Uses Parent Folder Credentials From Subfolder
|
23
|
+
Given I run `crab logout`
|
24
|
+
And I cd to "crab-project"
|
25
|
+
When I run `crab login -P` interactively
|
26
|
+
And I type my username
|
27
|
+
And I type my password
|
28
|
+
Then a file named ".crab/credentials" should exist
|
29
|
+
When I cd to "subfolder"
|
30
|
+
And I run `crab logout`
|
31
|
+
Then a file named "../.crab/credentials" should not exist
|
@@ -21,17 +21,10 @@ def get_story(story_id)
|
|
21
21
|
end
|
22
22
|
|
23
23
|
def get_project
|
24
|
-
|
25
|
-
|
24
|
+
project_file = File.expand_path("~/.crab/tests/project")
|
25
|
+
if File.exists? project_file
|
26
|
+
File.read(project_file).strip
|
26
27
|
else
|
27
|
-
raise "Please run rake cucumber:setup first"
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
def get_test_project
|
32
|
-
begin
|
33
|
-
test_project = File.read(File.expand_path("~/.crab/tests/project"))
|
34
|
-
rescue
|
35
28
|
raise "Looks like your test project isn't set up. Please run 'rake cucumber:setup'"
|
36
29
|
end
|
37
30
|
end
|
@@ -45,10 +38,12 @@ crab version #{Crab::VERSION}: A Cucumber-Rally bridge
|
|
45
38
|
Available commands:
|
46
39
|
|
47
40
|
help Show this help text
|
48
|
-
iteration Manipulate iterations
|
49
41
|
login Persistently authenticate user with Rally
|
50
42
|
logout Remove stored Rally credentials
|
51
43
|
project Persistently select project to work with in Rally
|
44
|
+
|
45
|
+
defect Manipulate defects
|
46
|
+
iteration Manipulate iterations
|
52
47
|
release Manipulate releases
|
53
48
|
story Manipulate stories
|
54
49
|
testcase Manipulate test cases
|
@@ -110,6 +105,7 @@ end
|
|
110
105
|
|
111
106
|
Given /^no project is selected$/ do
|
112
107
|
Given 'I run `rm -rf ".crab/project"`'
|
108
|
+
Then 'the exit status should be 0'
|
113
109
|
end
|
114
110
|
|
115
111
|
Given /^I have selected the project "([^"]*)"$/ do |project|
|
@@ -122,13 +118,15 @@ Given /^I have selected the project "([^"]*)"$/ do |project|
|
|
122
118
|
end
|
123
119
|
|
124
120
|
Given /^I have selected my test project$/ do
|
125
|
-
When %
|
121
|
+
When %{I run `crab project "#{get_project}"`}
|
122
|
+
Then %{the exit status should be 0}
|
126
123
|
end
|
127
124
|
|
128
125
|
When /^I select my test project$/ do
|
129
|
-
When %
|
126
|
+
When %{I run `crab project "#{get_project}"`}
|
127
|
+
Then %{the exit status should be 0}
|
130
128
|
end
|
131
129
|
|
132
130
|
Then /^the output should be the name of my test project$/ do
|
133
|
-
Then %Q{the output should contain "#{
|
131
|
+
Then %Q{the output should contain "#{get_project}"}
|
134
132
|
end
|
@@ -38,7 +38,7 @@ Feature: Subcommand Help
|
|
38
38
|
| story show | Usage: crab story show <id> [options*] |
|
39
39
|
| story help | Usage: crab story <command> [options*] |
|
40
40
|
|
41
|
-
| testcase create | Usage: crab testcase create <story> <name> [options*] |
|
41
|
+
| testcase create | Usage: crab testcase create <story> --name <name> [options*] |
|
42
42
|
| testcase update | Usage: crab testcase update <id> [options*] |
|
43
43
|
| testcase delete | Usage: crab testcase delete <id> [options*] |
|
44
44
|
| testcase find | Usage: crab testcase find [options*] [text] |
|
data/lib/crab/defect.rb
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
class Crab::Defect
|
2
|
+
|
3
|
+
def initialize(rally_defect)
|
4
|
+
@rally_defect = rally_defect
|
5
|
+
end
|
6
|
+
|
7
|
+
def formatted_id
|
8
|
+
@rally_defect.formatted_i_d
|
9
|
+
end
|
10
|
+
|
11
|
+
def name
|
12
|
+
@rally_defect.name
|
13
|
+
end
|
14
|
+
|
15
|
+
def description
|
16
|
+
@rally_defect.description
|
17
|
+
end
|
18
|
+
|
19
|
+
def environment
|
20
|
+
@rally_defect.environment
|
21
|
+
end
|
22
|
+
|
23
|
+
def browser
|
24
|
+
@rally_defect.navegador
|
25
|
+
end
|
26
|
+
|
27
|
+
def statte
|
28
|
+
@rally_defect.schedule_state
|
29
|
+
end
|
30
|
+
|
31
|
+
def severity
|
32
|
+
@rally_defect.severity
|
33
|
+
end
|
34
|
+
|
35
|
+
def target_date
|
36
|
+
@rally_defect.target_date
|
37
|
+
end
|
38
|
+
|
39
|
+
def task_status
|
40
|
+
@rally_defect.task_status
|
41
|
+
end
|
42
|
+
|
43
|
+
def test_case_status
|
44
|
+
@rally_defect.test_case_status
|
45
|
+
end
|
46
|
+
|
47
|
+
def delete
|
48
|
+
@rally_defect.delete
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
data/lib/crab/rally.rb
CHANGED
@@ -15,7 +15,13 @@ module Crab
|
|
15
15
|
def connect
|
16
16
|
get_credentials
|
17
17
|
logger.info "Connecting to Rally as #{@username}..."
|
18
|
-
|
18
|
+
|
19
|
+
rally_logger = Logger.new(STDERR)
|
20
|
+
rally_logger.formatter = Logger::Formatter.new
|
21
|
+
rally_logger.progname = 'rally'
|
22
|
+
rally_logger.level = ENV['CRAB_LOG_LEVEL'].present? ? ENV['CRAB_LOG_LEVEL'].to_i : Logger::WARN
|
23
|
+
|
24
|
+
@rally = ::RallyRestAPI.new :username => @username, :password => @password, :logger => rally_logger
|
19
25
|
end
|
20
26
|
|
21
27
|
def get_credentials
|
@@ -30,6 +36,13 @@ module Crab
|
|
30
36
|
Crab::Story.new(story, @dry_run)
|
31
37
|
end
|
32
38
|
|
39
|
+
def find_defect_with_id defect_id
|
40
|
+
logger.info "Looking up defect with ID #{defect_id}"
|
41
|
+
defect = @rally.find(:defect) { equal :formatted_i_d, defect_id }.first
|
42
|
+
Trollop::die "Defect with ID #{defect_id.inspect} not found" if defect.nil?
|
43
|
+
Crab::Defect.new(defect, @dry_run)
|
44
|
+
end
|
45
|
+
|
33
46
|
def find_testcases(project, pattern, opts)
|
34
47
|
logger.info "Looking for testcases matching #{pattern.inspect} with options #{opts.keys.inspect} in #{project.name.inspect}"
|
35
48
|
|
@@ -52,6 +65,25 @@ module Crab
|
|
52
65
|
end
|
53
66
|
end
|
54
67
|
|
68
|
+
def find_defects(project, pattern, opts)
|
69
|
+
logger.info "Looking for defects matching #{pattern.inspect} with options #{opts.keys.inspect} in #{project.name.inspect}"
|
70
|
+
if pattern.join.empty? && opts.empty?
|
71
|
+
return @rally.find_all(:defect, :fetch => true, :project => project).map {|s| Crab::Defect.new(s, @dry_run) }
|
72
|
+
end
|
73
|
+
|
74
|
+
rally_stories = @rally.find(:defect, :fetch => true, :project => project) do
|
75
|
+
Crab::Rally.search_for_words_in pattern, self
|
76
|
+
|
77
|
+
equal :iteration, opts[:iteration] if opts[:iteration]
|
78
|
+
equal :release, opts[:release] if opts[:release]
|
79
|
+
equal :parent, opts[:parent].rally_object if opts[:parent]
|
80
|
+
end
|
81
|
+
|
82
|
+
rally_stories.map {|defect| Crab::Defect.new(defect, @dry_run) }.tap do |defects|
|
83
|
+
logger.info "Found #{defects.size} defects"
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
55
87
|
def find_stories(project, pattern, opts)
|
56
88
|
logger.info "Looking for stories matching #{pattern.inspect} with options #{opts.keys.inspect} in #{project.name.inspect}"
|
57
89
|
if pattern.join.empty? && opts.empty?
|
data/lib/crab/utilities.rb
CHANGED
@@ -4,8 +4,7 @@ module Crab
|
|
4
4
|
include Logging
|
5
5
|
|
6
6
|
def credentials_file
|
7
|
-
|
8
|
-
File.expand_path("~/.crab/credentials")
|
7
|
+
dotcrab_file 'credentials'
|
9
8
|
end
|
10
9
|
|
11
10
|
def valid_credentials_file
|
@@ -20,9 +19,8 @@ module Crab
|
|
20
19
|
end
|
21
20
|
|
22
21
|
def current_project_name
|
23
|
-
|
24
|
-
|
25
|
-
end
|
22
|
+
project_file = dotcrab_file('project')
|
23
|
+
File.read(project_file).strip if File.exists?(project_file)
|
26
24
|
end
|
27
25
|
|
28
26
|
def state_from(option)
|
@@ -77,5 +75,21 @@ module Crab
|
|
77
75
|
def sanitize(source)
|
78
76
|
Sanitize.clean source, :remove_contents => %w{style}
|
79
77
|
end
|
78
|
+
|
79
|
+
def dotcrab_file(file)
|
80
|
+
current_folder = File.expand_path '.'
|
81
|
+
|
82
|
+
while current_folder != '/'
|
83
|
+
|
84
|
+
dotcrab = "#{current_folder}/.crab"
|
85
|
+
if File.exists? "#{dotcrab}/#{file}"
|
86
|
+
return "#{dotcrab}/#{file}"
|
87
|
+
end
|
88
|
+
current_folder = File.expand_path "#{current_folder}/.."
|
89
|
+
|
90
|
+
end
|
91
|
+
|
92
|
+
File.expand_path "~/.crab/#{file}"
|
93
|
+
end
|
80
94
|
end
|
81
95
|
end
|
data/lib/crab/version.rb
CHANGED
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:
|
4
|
+
hash: 13
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 2
|
9
|
-
-
|
10
|
-
version: 0.2.
|
9
|
+
- 13
|
10
|
+
version: 0.2.13
|
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-10-
|
18
|
+
date: 2011-10-06 00:00:00 -03:00
|
19
19
|
default_executable: crab
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
@@ -149,6 +149,10 @@ email:
|
|
149
149
|
- cvillela@thoughtworks.com
|
150
150
|
executables:
|
151
151
|
- crab
|
152
|
+
- crab-defect
|
153
|
+
- crab-defect-delete
|
154
|
+
- crab-defect-find
|
155
|
+
- crab-defect-help
|
152
156
|
- crab-help
|
153
157
|
- crab-it
|
154
158
|
- crab-it-help
|
@@ -249,6 +253,10 @@ files:
|
|
249
253
|
- README.md
|
250
254
|
- Rakefile
|
251
255
|
- bin/crab
|
256
|
+
- bin/crab-defect
|
257
|
+
- bin/crab-defect-delete
|
258
|
+
- bin/crab-defect-find
|
259
|
+
- bin/crab-defect-help
|
252
260
|
- bin/crab-help
|
253
261
|
- bin/crab-it
|
254
262
|
- bin/crab-it-help
|
@@ -345,6 +353,7 @@ files:
|
|
345
353
|
- features/move-in-rally.feature
|
346
354
|
- features/project-selection.feature
|
347
355
|
- features/pull-from-rally-into-cucumber.feature
|
356
|
+
- features/recursively-look-for-dotcrab-folder.feature
|
348
357
|
- features/show-from-rally.feature
|
349
358
|
- features/steps/rally_steps.rb
|
350
359
|
- features/subcommand-help.feature
|
@@ -354,6 +363,7 @@ files:
|
|
354
363
|
- lib/crab/cucumber_feature.rb
|
355
364
|
- lib/crab/cucumber_scenario.rb
|
356
365
|
- lib/crab/cucumber_to_rally_adapter.rb
|
366
|
+
- lib/crab/defect.rb
|
357
367
|
- lib/crab/logging.rb
|
358
368
|
- lib/crab/rally.rb
|
359
369
|
- lib/crab/rally_to_cucumber_adapter.rb
|