gitmine 0.1.5 → 0.1.6

Sign up to get free protection for your applications and to get access to all the features.
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