gitmine 0.1.5 → 0.1.6

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/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.5
1
+ 0.1.6
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{gitmine}
8
- s.version = "0.1.5"
8
+ s.version = "0.1.6"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Philippe Creux"]
12
- s.date = %q{2010-11-24}
12
+ s.date = %q{2010-12-10}
13
13
  s.default_executable = %q{gitmine}
14
14
  s.description = %q{Git log with status of associated redmine tickets}
15
15
  s.email = %q{pcreux@gmail.com}
@@ -32,15 +32,21 @@ Gem::Specification.new do |s|
32
32
  "bin/gitmine",
33
33
  "gitmine.gemspec",
34
34
  "lib/gitmine.rb",
35
+ "lib/gitmine/branch.rb",
35
36
  "lib/gitmine/cli.rb",
37
+ "lib/gitmine/colors.rb",
36
38
  "lib/gitmine/commit.rb",
37
- "lib/gitmine/gitmine.rb",
39
+ "lib/gitmine/config.rb",
40
+ "lib/gitmine/git.rb",
41
+ "lib/gitmine/hudson_job.rb",
38
42
  "lib/gitmine/issue.rb",
39
43
  "spec/commit_msg_to_issue_id_spec.rb",
40
44
  "spec/commit_spec.rb",
41
45
  "spec/config.yml",
42
46
  "spec/gitmine_spec.rb",
43
47
  "spec/issue_spec.rb",
48
+ "spec/lib/branch_spec.rb",
49
+ "spec/lib/config_spec.rb",
44
50
  "spec/spec_helper.rb"
45
51
  ]
46
52
  s.homepage = %q{http://github.com/pcreux/gitmine}
@@ -53,6 +59,8 @@ Gem::Specification.new do |s|
53
59
  "spec/commit_spec.rb",
54
60
  "spec/gitmine_spec.rb",
55
61
  "spec/issue_spec.rb",
62
+ "spec/lib/branch_spec.rb",
63
+ "spec/lib/config_spec.rb",
56
64
  "spec/spec_helper.rb"
57
65
  ]
58
66
 
@@ -4,6 +4,97 @@ require 'grit'
4
4
  require 'yaml'
5
5
  require 'httparty'
6
6
 
7
- %w(gitmine issue commit cli).each do |filename|
7
+ class Gitmine
8
+
9
+ def self.list
10
+ gm = Gitmine.new
11
+ gm.commits.each do |commit|
12
+ status = commit.issue ? commit.issue.status : 'N/A'
13
+ puts "#{commit.id[0..6]} #{status.ljust(12)} #{commit.committer.name.ljust(15)} #{commit.message[0..50].gsub("\n", '')}"
14
+ end
15
+ end
16
+
17
+ def initialize
18
+ @repo = Grit::Repo.new(ENV['PWD'])
19
+ @branch = File.read('./.git/HEAD').match(/^ref: refs\/heads\/(.+)/)[1]
20
+ end
21
+
22
+ def commits
23
+ @repo.commits(@branch).map do |c|
24
+ Commit.new(c)
25
+ end
26
+ end
27
+
28
+
29
+ # TODO specs
30
+ def self.branch(branch_name)
31
+ issue_id = branch_name[/^\d+/]
32
+ original_branch = File.read('./.git/HEAD').match(/^ref: refs\/heads\/(.+)/)[1]
33
+
34
+ raise "Invalid branch name. It should look like 123-my-branch" unless branch_name[/^\d+-/]
35
+
36
+ issue = Issue.find(issue_id)
37
+
38
+ raise "Issue ##{issue_id} does not exists" if issue.nil?
39
+
40
+ puts yellow("Create the branch #{branch_name}")
41
+ run_cmd("git checkout -b #{branch_name}")
42
+
43
+ puts yellow("Push it to origin")
44
+ run_cmd("git push origin #{branch_name}")
45
+
46
+ puts yellow("Make the local branch tracking the remote")
47
+ run_cmd("git branch --set-upstream #{branch_name} origin/#{branch_name}")
48
+
49
+ puts yellow("Adding a note to the Issue ##{issue_id}")
50
+ note = "Branch *#{branch_name}* created from #{original_branch}"
51
+ if Config.github
52
+ note << %{ - "See on Github":https://github.com/#{Config.github}/tree/#{branch_name}}
53
+ note << %{ - "Compare on Github":https://github.com/#{Config.github}/compare/#{original_branch}...#{branch_name}}
54
+ end
55
+ end
56
+
57
+ # TODO specs
58
+ def self.checkout(issue_id)
59
+ local_branch = LocalBranch.find(issue_id).name
60
+ if local_branch
61
+ run_cmd("git checkout #{local_branch}")
62
+ return
63
+ end
64
+
65
+ remote_branch = RemoteBranch.find(issue_id).name
66
+ if remote_branch
67
+ run_cmd("git checkout -b #{remote_branch} origin/#{remote_branch}")
68
+ return
69
+ end
70
+
71
+ raise "Can't find branch starting with #{issue_id}"
72
+ end
73
+
74
+ # TODO specs
75
+ def self.delete(issue_id)
76
+ RemoteBranch.find(issue_id).delete
77
+ end
78
+
79
+ # TODO specs
80
+ def self.reviewed(issue_id)
81
+ issue = Issue.find(issue_id)
82
+
83
+ puts yellow("Merge #{issue_id} to master and push")
84
+ issue.local_branch.merge_to_master
85
+
86
+ puts yellow("Delete remote branch")
87
+ issue.remote_branch.delete
88
+
89
+ puts yellow("Delete hudson jobs")
90
+ issue.delete_hudson_jobs
91
+
92
+ puts yellow("Set Ticket status to 'reviewed'")
93
+ issue.update_status("reviewed")
94
+ end
95
+ end
96
+
97
+
98
+ %w(config issue commit cli colors branch git hudson_job).each do |filename|
8
99
  require File.dirname(__FILE__) + "/gitmine/#{filename}.rb"
9
100
  end
@@ -0,0 +1,102 @@
1
+ class Gitmine
2
+ class Branch
3
+ class << self
4
+ def find(issue_id)
5
+ new(issue_id)
6
+ end
7
+
8
+ # TODO: specs
9
+ # Return local branch name for issue_id
10
+ def find_local(issue_id)
11
+ local_branches.select { |branch| branch[/^#{issue_id}-/] }.first
12
+ end
13
+
14
+ # TODO: specs
15
+ # Return remote branch name for issue_id
16
+ def find_remote(issue_id)
17
+ remote_branch = remote_branches.select { |branch| branch[/^#{issue_id}-/] }.first
18
+ unless remote_branch
19
+ # Fetch and retry
20
+ Git.fetch
21
+ clear_memoized_remote_branches!
22
+ remote_branch = remote_branches.select { |branch| branch[/^#{issue_id}-/] }.first
23
+ end
24
+
25
+ remote_branch
26
+ end
27
+
28
+
29
+ # Return an array of local branches starting with digits
30
+ # Example
31
+ # ['123-my-branch', '1234-your-branch']
32
+ # TODO specs
33
+ def local_branches
34
+ return @@local_branches if defined?(@@local_branches) && @@local_branches
35
+ branches = []
36
+ Git.local_branches.each_line do |line|
37
+ if match = line[/\d+.*$/]
38
+ branches << match
39
+ end
40
+ end
41
+
42
+ @@local_branches = branches
43
+ end
44
+
45
+ # Return an array of remote branches
46
+ # TODO specs
47
+ def remote_branches
48
+ return @@remote_branches if defined?(@@remote_branches) && @@remote_branches
49
+ branches = []
50
+ Git.remote_branches.each_line do |line|
51
+ if match = line.match(/origin\/(\d+.*)/)
52
+ branches << match[1]
53
+ end
54
+ end
55
+
56
+ @@remote_branches = branches
57
+ end
58
+
59
+ protected
60
+
61
+ def clear_memoized_remote_branches!
62
+ @@remote_branches = nil
63
+ end
64
+ end # class methods
65
+
66
+ attr_accessor :issue_id
67
+
68
+ def initialize(issue_id)
69
+ @issue_id = issue_id
70
+ end
71
+
72
+ def local
73
+ LocalBranch.new(issue_id)
74
+ end
75
+
76
+ def remote
77
+ RemoteBranch.new(issue_id)
78
+ end
79
+ end
80
+
81
+ class LocalBranch < Branch
82
+ def name
83
+ @name ||= Branch.find_local(issue_id)
84
+ end
85
+
86
+ def merge_to_master
87
+ Git.checkout("master")
88
+ Git.merge(self.name)
89
+ Git.push
90
+ end
91
+ end
92
+
93
+ class RemoteBranch < Branch
94
+ def name
95
+ @name ||= Branch.find_remote(issue_id)
96
+ end
97
+
98
+ def delete
99
+ Git.delete_remote_branch(self.name)
100
+ end
101
+ end
102
+ end
@@ -1,50 +1,54 @@
1
- module Gitmine
2
- class CLI
3
- def self.run
4
- case ARGV[0]
5
- when "log"
6
- list
7
- when "branch", "br"
8
- branch
9
- when "checkout", "co"
10
- checkout
11
- when "delete", "del"
12
- delete
13
- else
14
- puts <<-EOS
15
- Usage:
16
- gitmine branch BRANCH_NAME
17
- Create a new branch, push to origin, add github links to gitmine ticket
18
- Example: gitmine branch 1234-my-branch
19
-
20
- gitmine checkout ISSUE_ID
21
- Checkout remote/local branch starting with ISSUE_ID
22
- Example: gitmine checkout 1234
23
-
24
- gitmine delete ISSUE_ID
25
- Delete remote branch starting with ISSUE_ID
26
- Example: gitmine delete 1234
27
-
28
- gitmine log
29
- Displays latest 10 commits and the status of their associated Redmine tickets
30
- EOS
31
- end
32
- end
1
+ class Gitmine::CLI
2
+ def self.run
3
+ case ARGV[0]
4
+ when "log"
5
+ list
6
+ when "branch", "br"
7
+ branch
8
+ when "checkout", "co"
9
+ checkout
10
+ when "delete", "del"
11
+ delete
12
+ when "for_deploy", "reviewed"
13
+ reviewed
14
+ else
15
+ puts <<-EOS
16
+ Usage:
17
+ gitmine branch BRANCH_NAME
18
+ Create a new branch, push to origin, add github links to gitmine ticket
19
+ Example: gitmine branch 1234-my-branch
33
20
 
34
- def self.list
35
- Gitmine.list
36
- end
21
+ gitmine checkout ISSUE_ID
22
+ Checkout remote/local branch starting with ISSUE_ID
23
+ Example: gitmine checkout 1234
37
24
 
38
- def self.branch
39
- Gitmine.branch(ARGV[1])
40
- end
25
+ gitmine delete ISSUE_ID
26
+ Delete remote branch starting with ISSUE_ID
27
+ Example: gitmine delete 1234
41
28
 
42
- def self.checkout
43
- Gitmine.checkout(ARGV[1])
29
+ gitmine log
30
+ Displays latest 10 commits and the status of their associated Redmine tickets
31
+ EOS
44
32
  end
33
+ end
45
34
 
46
- def self.delete
47
- Gitmine.delete(ARGV[1])
48
- end
35
+ def self.list
36
+ Gitmine.list
37
+ end
38
+
39
+ def self.branch
40
+ Gitmine.branch(ARGV[1])
41
+ end
42
+
43
+ def self.checkout
44
+ Gitmine.checkout(ARGV[1])
45
+ end
46
+
47
+ def self.delete
48
+ Gitmine.delete(ARGV[1])
49
+ end
50
+
51
+ def self.reviewed
52
+ Gitmine.reviewed(ARGV[1])
49
53
  end
50
54
  end
@@ -0,0 +1,45 @@
1
+ #module Gitmine::Colors
2
+ # Display the command, run it and raise if it fails.
3
+ def run_cmd(cmd)
4
+ puts blue(cmd)
5
+ raise unless system cmd
6
+ end
7
+
8
+ # ### COLORS ###
9
+ # Display colored text in console
10
+ def color(text, color_code)
11
+ "#{color_code}#{text}\e[0m"
12
+ end
13
+
14
+ def bold(text)
15
+ color(text, "\e[1m")
16
+ end
17
+
18
+ def white(text)
19
+ color(text, "\e[37m")
20
+ end
21
+
22
+ def green(text)
23
+ color(text, "\e[32m")
24
+ end
25
+
26
+ def red(text)
27
+ color(text, "\e[31m")
28
+ end
29
+
30
+ def magenta(text)
31
+ color(text, "\e[35m")
32
+ end
33
+
34
+ def yellow(text)
35
+ color(text, "\e[33m")
36
+ end
37
+
38
+ def blue(text)
39
+ color(text, "\e[34m")
40
+ end
41
+
42
+ def grey(text)
43
+ color(text, "\e[90m")
44
+ end
45
+ #end
@@ -1,28 +1,26 @@
1
- module Gitmine
2
- class Commit
3
- attr_reader :grit_commit
1
+ class Gitmine::Commit
2
+ attr_reader :grit_commit
4
3
 
5
- # Initialize a new Commit objects that delegates methods to the Grit::Commit object passed in
6
- def initialize(grit_commit)
7
- @grit_commit = grit_commit
8
- end
9
-
10
- # Issue associated with this commit
11
- # Return nil if their is no associated issue
12
- def issue
13
- @issue ||= Issue.get_for_commit(message)
14
- end
4
+ # Initialize a new Commit objects that delegates methods to the Grit::Commit object passed in
5
+ def initialize(grit_commit)
6
+ @grit_commit = grit_commit
7
+ end
15
8
 
16
- # Delegate #id to Grit::Commit
17
- def id
18
- @grit_commit.id
19
- end
9
+ # Issue associated with this commit
10
+ # Return nil if their is no associated issue
11
+ def issue
12
+ @issue ||= Gitmine::Issue.get_for_commit(message)
13
+ end
20
14
 
21
- protected
22
- # Delegate methods to Grit::Commit
23
- def method_missing(m, *args, &block)
24
- return @grit_commit.send(m, args, block) if @grit_commit.respond_to? m
25
- super
26
- end
15
+ # Delegate #id to Grit::Commit
16
+ def id
17
+ @grit_commit.id
27
18
  end
19
+
20
+ protected
21
+ # Delegate methods to Grit::Commit
22
+ def method_missing(m, *args, &block)
23
+ return @grit_commit.send(m, args, block) if @grit_commit.respond_to? m
24
+ super
25
+ end
28
26
  end
@@ -0,0 +1,53 @@
1
+ class Gitmine
2
+ class Config
3
+ CONFIG_FILE = './.gitmine.yml'
4
+
5
+ class << self
6
+ def config
7
+ @@config ||= new
8
+ end
9
+
10
+ def redmine_host
11
+ config['host']
12
+ end
13
+
14
+ def redmine_api_key
15
+ config['api_key']
16
+ end
17
+
18
+ def github
19
+ config['github']
20
+ end
21
+
22
+ def hudson_host
23
+ config['hudson']['host']
24
+ end
25
+
26
+ def hudson_username
27
+ config['hudson']['username']
28
+ end
29
+
30
+ def hudson_password
31
+ config['hudson']['password']
32
+ end
33
+
34
+ def statuses
35
+ config['statuses']
36
+ end
37
+
38
+ def status_reviewed
39
+ config['statuses']['reviewed']
40
+ end
41
+ end
42
+
43
+ def initialize
44
+ path = CONFIG_FILE
45
+ @config = YAML.load_file(path)
46
+ end
47
+
48
+ def [](key)
49
+ @config[key]
50
+ end
51
+
52
+ end # Class Config
53
+ end
@@ -0,0 +1,34 @@
1
+ class Gitmine::Git
2
+ class << self
3
+ # Return output of 'git branch'
4
+ def local_branches
5
+ `git branch`
6
+ end
7
+
8
+ # Return output of 'git branch -r'
9
+ def remote_branches
10
+ `git branch -r`
11
+ end
12
+
13
+ # Run 'git fetch'
14
+ def fetch
15
+ run_cmd("git fetch")
16
+ end
17
+
18
+ def checkout(branch)
19
+ run_cmd("git checkout #{branch}")
20
+ end
21
+
22
+ def merge(branch)
23
+ run_cmd("git merge #{branch}")
24
+ end
25
+
26
+ def push
27
+ run_cmd("git push")
28
+ end
29
+
30
+ def delete_remote_branch(branch)
31
+ run_cmd("git push origin :#{branch}")
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,41 @@
1
+ class Gitmine
2
+ class HudsonJob
3
+ class Http
4
+ include HTTParty
5
+
6
+ base_uri Config.hudson_host
7
+ basic_auth(Config.hudson_username, Config.hudson_password) if Config.hudson_username
8
+ headers 'Content-type' => 'text/xml'
9
+ # I get timeout errors on heroku but not on local env. Is that because of REE-1.8.7 ?
10
+ # Workaround: Set the timeout to 10 seconds and rescue timeout errors.
11
+ default_timeout 8
12
+ end
13
+
14
+ def self.all_by_name_including(pattern)
15
+ HudsonJob.all.select { |projects| projects.name[pattern] }
16
+ end
17
+
18
+ def self.all
19
+ r = Http.get('/api/xml')
20
+ return [] unless r.code == 200
21
+ r.parsed_response["hudson"]["job"].map do |jobs_data|
22
+ new(jobs_data["name"])
23
+ end
24
+ end
25
+
26
+ attr_accessor :name
27
+
28
+ def initialize(name)
29
+ @name = name
30
+ end
31
+
32
+ def delete!
33
+ r = Http.post("/job/#{name}/doDelete")
34
+ raise "Failed to delete job #{name}" unless r.code == 200
35
+ puts green(" - #{name} deleted!")
36
+
37
+ true
38
+ end
39
+
40
+ end
41
+ end
@@ -1,14 +1,7 @@
1
- module Gitmine
1
+ class Gitmine
2
2
  class Issue
3
- CONFIG_FILE = './.gitmine.yml'
4
-
5
3
  attr_reader :id, :subject, :status
6
4
 
7
- # Config from .gitmine.yml
8
- def self.config
9
- @@config ||= YAML.load_file(CONFIG_FILE)
10
- end
11
-
12
5
  # Extract the issue_id from a commit message.
13
6
  # Examples:
14
7
  # CommitMsgToIssueId.parse("Message for Issue #123.")
@@ -34,28 +27,49 @@ module Gitmine
34
27
  }
35
28
  end
36
29
 
30
+ def local_branch
31
+ LocalBranch.find(self.id)
32
+ end
33
+
34
+ def remote_branch
35
+ RemoteBranch.find(self.id)
36
+ end
37
+
38
+ def delete_hudson_jobs
39
+ hudson_jobs.map(&:delete!)
40
+ end
41
+
37
42
  # Get attributes from redmine and set them all
38
43
  def build_via_issue_id(issue_id)
39
44
  @id = issue_id
40
45
  data = http_get(issue_id).parsed_response['issue']
41
- @subject = data['subject']
42
- @status = data['status']['name']
46
+ if data
47
+ @subject = data['subject']
48
+ @status = data['status']['name']
49
+ end
43
50
  end
44
51
 
45
52
  # Add a note to the Issue
46
53
  def add_note(note)
47
54
  response = self.class.put(url(self.id), :query => {:notes => note}, :body => "") # nginx reject requests without body
55
+ raise response.response.to_s unless response.code == 200
48
56
 
49
- if response.code == 200
50
- return true
51
- else
52
- raise response.response
53
- end
57
+ puts green("Note added to Issue ##{self.id}: #{note}")
58
+ end
59
+
60
+ def update_status(st)
61
+ status_id = Gitmine::Config.statuses[st]
62
+ raise "Please specify status_id in .gitmine.yml for #{st}" unless status_id
63
+
64
+ response = self.class.put(url(self.id), :query => {:issue => {:status_id => status_id }}, :body => "")
65
+ raise response.response.to_s unless response.code == 200
66
+
67
+ puts green("Issue ##{self.id} -> #{st}")
54
68
  end
55
69
 
56
70
  include HTTParty
57
- base_uri "#{config['host']}/issues/"
58
- basic_auth config['api_key'], '' # username is api_key, password is empty
71
+ base_uri "#{Gitmine::Config.redmine_host}/issues/"
72
+ basic_auth Gitmine::Config.redmine_api_key, '' # username is api_key, password is empty
59
73
  headers 'Content-type' => 'text/xml' # by-pass rails authenticity token mechanism
60
74
 
61
75
  protected
@@ -68,5 +82,10 @@ module Gitmine
68
82
  def http_get(issue_id)
69
83
  self.class.get(url(issue_id))
70
84
  end
85
+
86
+ def hudson_jobs
87
+ HudsonJob.all_by_name_including(self.id)
88
+ end
89
+
71
90
  end
72
91
  end
@@ -1,11 +1,11 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe Gitmine::Gitmine do
3
+ describe Gitmine do
4
4
  before do
5
5
  File.stub!(:read) { "ref: refs/heads/wip" }
6
6
  end
7
7
 
8
- let(:gitmine) { Gitmine::Gitmine.new }
8
+ let(:gitmine) { Gitmine.new }
9
9
 
10
10
  let(:commit_1) do
11
11
  mock(
@@ -41,7 +41,7 @@ describe Gitmine::Gitmine do
41
41
 
42
42
  it "should check out to the current branch" do
43
43
  Grit::Repo.should_receive(:new).with(ENV['PWD']) { grit_repo }
44
- Gitmine::Gitmine.new
44
+ Gitmine.new
45
45
  end
46
46
  end
47
47
  end
@@ -8,12 +8,6 @@ describe Gitmine::Issue do
8
8
  end
9
9
  end
10
10
 
11
- describe "#config" do
12
- it "should load the config from config.yml" do
13
- Gitmine::Issue.config.should == {"host"=>"http://redmine-gitmine.heroku.com", "github" => "pcreux/gitmine"}
14
- end
15
- end
16
-
17
11
  describe "#get_for_commit" do
18
12
  it "should parse the commit message to find a commit_id and call #get" do
19
13
  commit_msg = 'A commit msg Issue #123'
@@ -0,0 +1,78 @@
1
+ require 'spec_helper'
2
+
3
+ describe Gitmine::Branch do
4
+ before do
5
+ Gitmine::Git.stub!(:local_branches) { <<-GIT_OUTPUT
6
+ 2632-invoice-should-accept-date
7
+ 2675
8
+ * 2869-BUG-accepted-by-not-set
9
+ master
10
+ production
11
+ GIT_OUTPUT
12
+ }
13
+
14
+ Gitmine::Git.stub!(:remote_branches) { <<-GIT_OUTPUT
15
+ origin/2890-email-aliases
16
+ origin/2915-sanitize-eft-fields
17
+ origin/HEAD -> origin/master
18
+ origin/master
19
+ origin/production
20
+ GIT_OUTPUT
21
+ }
22
+
23
+ Gitmine::Git.stub!(:fetch)
24
+ end
25
+
26
+ describe "#local_branches" do
27
+ it "should return an array of branches starting with digits only" do
28
+ Gitmine::Branch.local_branches.
29
+ should == %w(2632-invoice-should-accept-date 2675 2869-BUG-accepted-by-not-set)
30
+ end
31
+ end
32
+
33
+ describe "#remote_branches" do
34
+ it "should return an array of branches starting with digits only" do
35
+ Gitmine::Branch.remote_branches.
36
+ should == %w( 2890-email-aliases 2915-sanitize-eft-fields )
37
+ end
38
+ end
39
+
40
+ describe "find_local(issue_id)" do
41
+ context "when the branch exists" do
42
+ it "should return the branch name" do
43
+ Gitmine::Branch.find_local('2632').
44
+ should == '2632-invoice-should-accept-date'
45
+ end
46
+ end
47
+
48
+ context "when the does not exists" do
49
+ it "should return nil" do
50
+ Gitmine::Branch.find_local('9999').
51
+ should == nil
52
+ end
53
+ end
54
+ end
55
+
56
+ describe "find_remote(issue_id)" do
57
+ context "when the branch exists" do
58
+ it "should return the branch name" do
59
+ Gitmine::Branch.find_remote('2890').
60
+ should == '2890-email-aliases'
61
+ end
62
+ end
63
+
64
+ context "when the does not exists" do
65
+ it "should return nil" do
66
+ Gitmine::Branch.find_remote('9999').
67
+ should == nil
68
+ end
69
+ it "should fetch and retry" do
70
+ Gitmine::Git.should_receive(:fetch)
71
+ Gitmine::Branch.should_receive(:clear_memoized_remote_branches!)
72
+ # can't test the recursive call
73
+ Gitmine::Branch.find_remote('9999')
74
+ end
75
+ end
76
+ end
77
+
78
+ end
@@ -0,0 +1,8 @@
1
+ describe Gitmine::Config do
2
+ describe "#config" do
3
+ it "should load the config from config.yml" do
4
+ Gitmine::Config.redmine_host.should == "http://redmine-gitmine.heroku.com"
5
+ Gitmine::Config.github.should == "pcreux/gitmine"
6
+ end
7
+ end
8
+ end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gitmine
3
3
  version: !ruby/object:Gem::Version
4
- hash: 17
4
+ hash: 23
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
8
  - 1
9
- - 5
10
- version: 0.1.5
9
+ - 6
10
+ version: 0.1.6
11
11
  platform: ruby
12
12
  authors:
13
13
  - Philippe Creux
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2010-11-24 00:00:00 -08:00
18
+ date: 2010-12-10 00:00:00 -08:00
19
19
  default_executable: gitmine
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
@@ -85,15 +85,21 @@ files:
85
85
  - bin/gitmine
86
86
  - gitmine.gemspec
87
87
  - lib/gitmine.rb
88
+ - lib/gitmine/branch.rb
88
89
  - lib/gitmine/cli.rb
90
+ - lib/gitmine/colors.rb
89
91
  - lib/gitmine/commit.rb
90
- - lib/gitmine/gitmine.rb
92
+ - lib/gitmine/config.rb
93
+ - lib/gitmine/git.rb
94
+ - lib/gitmine/hudson_job.rb
91
95
  - lib/gitmine/issue.rb
92
96
  - spec/commit_msg_to_issue_id_spec.rb
93
97
  - spec/commit_spec.rb
94
98
  - spec/config.yml
95
99
  - spec/gitmine_spec.rb
96
100
  - spec/issue_spec.rb
101
+ - spec/lib/branch_spec.rb
102
+ - spec/lib/config_spec.rb
97
103
  - spec/spec_helper.rb
98
104
  has_rdoc: true
99
105
  homepage: http://github.com/pcreux/gitmine
@@ -134,4 +140,6 @@ test_files:
134
140
  - spec/commit_spec.rb
135
141
  - spec/gitmine_spec.rb
136
142
  - spec/issue_spec.rb
143
+ - spec/lib/branch_spec.rb
144
+ - spec/lib/config_spec.rb
137
145
  - spec/spec_helper.rb
@@ -1,105 +0,0 @@
1
- module Gitmine
2
- class Gitmine
3
- def self.list
4
- gm = Gitmine.new
5
- gm.commits.each do |commit|
6
- status = commit.issue ? commit.issue.status : 'N/A'
7
- puts "#{commit.id[0..6]} #{status.ljust(12)} #{commit.committer.name.ljust(15)} #{commit.message[0..50].gsub("\n", '')}"
8
- end
9
- end
10
-
11
- def initialize
12
- @repo = Grit::Repo.new(ENV['PWD'])
13
- @branch = File.read('./.git/HEAD').match(/^ref: refs\/heads\/(.+)/)[1]
14
- end
15
-
16
- def commits
17
- @repo.commits(@branch).map do |c|
18
- Commit.new(c)
19
- end
20
- end
21
-
22
-
23
- # TODO specs
24
- def self.branch(branch_name)
25
- issue_id = branch_name[/^\d+/]
26
- original_branch = File.read('./.git/HEAD').match(/^ref: refs\/heads\/(.+)/)[1]
27
- config = Issue.config
28
-
29
- raise "Invalid branch name. It should start with the issue number" unless issue_id
30
-
31
- puts "Create the branch #{branch_name}"
32
- run_cmd("git checkout -b #{branch_name}")
33
-
34
- puts "Push it to origin"
35
- run_cmd("git push origin #{branch_name}")
36
-
37
- puts "Make the local branch tracking the remote"
38
- run_cmd("git branch --set-upstream #{branch_name} origin/#{branch_name}")
39
-
40
- puts "Adding a note to the Issue ##{issue_id}"
41
- note = "Branch *#{branch_name}* created from #{original_branch}"
42
- if config['github']
43
- note << %{ - "See on Github":https://github.com/#{config['github']}/tree/#{branch_name}}
44
- note << %{ - "Compare on Github":https://github.com/#{config['github']}/compare/#{original_branch}...#{branch_name}}
45
- end
46
-
47
- puts 'Done!' if Issue.find(issue_id).add_note(note)
48
- end
49
-
50
- # TODO specs
51
- def self.checkout(issue_id)
52
- if local_branch = local_branches.select { |branch| branch[/^#{issue_id}-/] }.first
53
- run_cmd("git checkout #{local_branch}")
54
- return
55
- end
56
-
57
- if remote_branch = remote_branches.select { |branch| branch[/^#{issue_id}-/] }.first
58
- run_cmd("git checkout -b #{remote_branch} origin/#{remote_branch}")
59
- return
60
- end
61
-
62
- raise "Can't find branch starting with #{issue_id}"
63
- end
64
-
65
- # TODO specs
66
- def self.delete(issue_id)
67
- if remote_branch = remote_branches.select { |branch| branch[/^#{issue_id}-/] }.first
68
- run_cmd("git push origin :#{remote_branch}")
69
- else
70
- raise "Can't find branch starting with #{issue_id}"
71
- end
72
- end
73
-
74
- def self.run_cmd(cmd)
75
- puts cmd
76
- exit! unless system(cmd)
77
- end
78
-
79
- # TODO specs
80
- def self.local_branches
81
- branches = []
82
- `git branch`.each_line do |line|
83
- if match = line[/\d+.*$/]
84
- branches << match
85
- end
86
- end
87
-
88
- branches
89
- end
90
-
91
- # TODO specs
92
- def self.remote_branches
93
- run_cmd("git fetch")
94
-
95
- branches = []
96
- `git branch -r`.each_line do |line|
97
- if match = line.match(/origin\/(\d+.*)/)
98
- branches << match[1]
99
- end
100
- end
101
-
102
- branches
103
- end
104
- end
105
- end