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.
@@ -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
@@ -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
@@ -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
@@ -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
- FileUtils.rm_rf(credentials_file, fileutils_opts)
23
+ file = credentials_file
24
+ FileUtils.rm_rf(file, fileutils_opts)
24
25
 
25
- puts "Credentials removed for #{username}"
26
+ puts "Credentials removed from #{file}"
26
27
 
27
28
  end
28
29
  end
@@ -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
- puts current_project_name
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", opts[:dry] ? { :noop => true, :verbose => true } : {}
43
+ FileUtils.mkdir_p ".crab", is_dry_run
37
44
  file = ".crab/project"
38
45
  output = project.name
39
46
 
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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 a Project
11
- Given no project is selected
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
- if File.exists? ".crab/tests/project"
25
- File.read(".crab/tests/project").strip
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 %Q{I run `crab project "#{get_test_project}"`}
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 %Q{I run `crab project "#{get_test_project}"`}
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 "#{get_test_project}"}
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] |
@@ -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
@@ -15,7 +15,13 @@ module Crab
15
15
  def connect
16
16
  get_credentials
17
17
  logger.info "Connecting to Rally as #{@username}..."
18
- @rally = ::RallyRestAPI.new :username => @username, :password => @password
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?
@@ -4,8 +4,7 @@ module Crab
4
4
  include Logging
5
5
 
6
6
  def credentials_file
7
- FileUtils.mkdir_p File.expand_path("~/.crab")
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
- if File.exists? ".crab/project"
24
- File.read(".crab/project").strip
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
@@ -1,3 +1,3 @@
1
1
  module Crab
2
- VERSION = "0.2.12"
2
+ VERSION = "0.2.13"
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: 15
4
+ hash: 13
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 2
9
- - 12
10
- version: 0.2.12
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-05 00:00:00 -03:00
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