crab 0.2.12 → 0.2.13
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.
- 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
|