Skip to content
Browse files

Add branch command. Need refactoring.

Issue #10
  • Loading branch information...
1 parent 1141000 commit 8497d6843a064b5a2d3e927704c1e7633c6d7049 @pcreux committed
Showing with 219 additions and 130 deletions.
  1. +1 −0 .gitignore
  2. +1 −1 .gitmine.yml
  3. +26 −0 Gemfile.lock
  4. +1 −1 bin/gitmine
  5. +2 −105 lib/gitmine.rb
  6. +26 −0 lib/gitmine/cli.rb
  7. +28 −0 lib/gitmine/commit.rb
  8. +51 −0 lib/gitmine/gitmine.rb
  9. +68 −0 lib/gitmine/issue.rb
  10. +3 −2 spec/commit_spec.rb
  11. +3 −3 spec/gitmine_spec.rb
  12. +9 −18 spec/issue_spec.rb
View
1 .gitignore
@@ -19,3 +19,4 @@ rdoc
pkg
## PROJECT::SPECIFIC
+.gitmine.yml.mine
View
2 .gitmine.yml
@@ -1,2 +1,2 @@
host: 'http://redmine-gitmine.heroku.com'
-#api_key: '' # No need for api_key since the redmine project is public.
+github: 'pcreux/gitmine'
View
26 Gemfile.lock
@@ -0,0 +1,26 @@
+GEM
+ specs:
+ crack (0.1.8)
+ diff-lcs (1.1.2)
+ grit (2.0.0)
+ diff-lcs (>= 1.1.2)
+ mime-types (>= 1.15)
+ httparty (0.6.1)
+ crack (= 0.1.8)
+ mime-types (1.16)
+ rspec (2.0.0.beta.17)
+ rspec-core (= 2.0.0.beta.17)
+ rspec-expectations (= 2.0.0.beta.17)
+ rspec-mocks (= 2.0.0.beta.17)
+ rspec-core (2.0.0.beta.17)
+ rspec-expectations (2.0.0.beta.17)
+ diff-lcs (>= 1.1.2)
+ rspec-mocks (2.0.0.beta.17)
+
+PLATFORMS
+ ruby
+
+DEPENDENCIES
+ grit
+ httparty
+ rspec (= 2.0.0.beta.17)
View
2 bin/gitmine 100644 → 100755
@@ -1,4 +1,4 @@
#!/usr/bin/env ruby
require File.dirname(__FILE__) + '/../lib/gitmine'
-Gitmine.run
+Gitmine::CLI.run
View
107 lib/gitmine.rb
@@ -4,109 +4,6 @@
require 'yaml'
require 'httparty'
-class Gitmine
- # CLI interface
- def self.run
- gm = Gitmine.new
- gm.commits.each do |commit|
- status = commit.issue ? commit.issue.status : 'N/A'
- puts "#{commit.id[0..6]} #{status.ljust(12)} #{commit.committer.name.ljust(15)} #{commit.message[0..50].gsub("\n", '')}"
- end
- end
-
- def initialize
- @repo = Grit::Repo.new(ENV['PWD'])
- @branch = File.read('./.git/HEAD').match(/^ref: refs\/heads\/(.+)/)[1]
- end
-
- def commits
- @repo.commits(@branch).map do |c|
- Commit.new(c)
- end
- end
-
-
- class Commit
- attr_reader :grit_commit
-
- # Initialize a new Commit objects that delegates methods to the Grit::Commit object passed in
- def initialize(grit_commit)
- @grit_commit = grit_commit
- end
-
- # Issue associated with this commit
- # Return nil if their is no associated issue
- def issue
- @issue ||= Issue.get_for_commit(message)
- end
-
- # Delegate #id to Grit::Commit
- def id
- @grit_commit.id
- end
-
- protected
- # Delegate methods to Grit::Commit
- def method_missing(m, *args, &block)
- return @grit_commit.send(m, args, block) if @grit_commit.respond_to? m
- super
- end
- end
-
- class Issue
- CONFIG_FILE = './.gitmine.yml'
-
- attr_reader :id, :subject, :status
-
- # Extract the issue_id from a commit message.
- # Examples:
- # CommitMsgToIssueId.parse("Message for Issue #123.")
- # => 123
- # CommitMsgToIssueId.parse("#123.")
- # => nil
- #
- def self.parse_for_issue_id(msg)
- match = msg.match(/Issue #(\d+)/)
- match ? match[1] : nil
- end
-
- # Parse the commit_message and get the associated issue if any.
- def self.get_for_commit(commit_message)
- issue_id = parse_for_issue_id(commit_message)
- issue_id ? Issue.get(issue_id) : nil
- end
-
- # Get the issue from redmine
- def self.get(issue_id)
- Issue.new.tap { |issue|
- issue.build_via_issue_id(issue_id)
- }
- end
-
- # Config from .gitmine.yml
- def config
- @config ||= YAML.load_file(CONFIG_FILE)
- end
-
- # Get attributes from redmine and set them all
- def build_via_issue_id(issue_id)
- @id = issue_id
- data = get(issue_id).parsed_response['issue']
- @subject = data['subject']
- @status = data['status']['name']
- end
-
- protected
-
- # Url to redmine/issues
- def url(id)
- "#{config['host']}/issues/#{id}.xml?key=#{config['api_key']}"
- end
-
- # http_get the issue using HTTParty
- def get(issue_id)
- HTTParty.get(url(issue_id))
- end
- end
-
+%w(gitmine issue commit cli).each do |filename|
+ require File.dirname(__FILE__) + "/gitmine/#{filename}.rb"
end
View
26 lib/gitmine/cli.rb
@@ -0,0 +1,26 @@
+module Gitmine
+ class CLI
+ def self.run
+ case ARGV[0]
+ when nil
+ list
+ when "branch"
+ branch
+ else
+ puts <<-EOS
+ Usage:
+ gitmine: show the 10 latest commits and their associated issue status
+ gitmine branch [BRANCH_NAME]: create a new branch
+ EOS
+ end
+ end
+
+ def self.list
+ Gitmine.list
+ end
+
+ def self.branch
+ Gitmine.branch(ARGV[1])
+ end
+ end
+end
View
28 lib/gitmine/commit.rb
@@ -0,0 +1,28 @@
+module Gitmine
+ class Commit
+ attr_reader :grit_commit
+
+ # Initialize a new Commit objects that delegates methods to the Grit::Commit object passed in
+ def initialize(grit_commit)
+ @grit_commit = grit_commit
+ end
+
+ # Issue associated with this commit
+ # Return nil if their is no associated issue
+ def issue
+ @issue ||= Issue.get_for_commit(message)
+ end
+
+ # Delegate #id to Grit::Commit
+ def id
+ @grit_commit.id
+ end
+
+ protected
+ # Delegate methods to Grit::Commit
+ def method_missing(m, *args, &block)
+ return @grit_commit.send(m, args, block) if @grit_commit.respond_to? m
+ super
+ end
+ end
+end
View
51 lib/gitmine/gitmine.rb
@@ -0,0 +1,51 @@
+module Gitmine
+ class Gitmine
+ def self.list
+ gm = Gitmine.new
+ gm.commits.each do |commit|
+ status = commit.issue ? commit.issue.status : 'N/A'
+ puts "#{commit.id[0..6]} #{status.ljust(12)} #{commit.committer.name.ljust(15)} #{commit.message[0..50].gsub("\n", '')}"
+ end
+ end
+
+ def initialize
+ @repo = Grit::Repo.new(ENV['PWD'])
+ @branch = File.read('./.git/HEAD').match(/^ref: refs\/heads\/(.+)/)[1]
+ end
+
+ def commits
+ @repo.commits(@branch).map do |c|
+ Commit.new(c)
+ end
+ end
+
+
+ def self.branch(branch_name)
+ issue_id = branch_name[/^\d+/]
+ original_branch = File.read('./.git/HEAD').match(/^ref: refs\/heads\/(.+)/)[1]
+ config = Issue.config
+
+ raise "Invalid branch name. It should start with the issue number" unless issue_id
+
+ puts "Creating the remote branch #{branch_name}"
+
+ run_cmd("git push origin origin:refs/heads/#{branch_name}")
+ run_cmd("git checkout --track -b #{branch_name} origin/#{branch_name}")
+
+
+ puts "Adding a note to the Issue ##{issue_id}"
+ note = "Branch *#{branch_name}* created from #{original_branch}"
+ if config['github']
+ note << %{ - "See on Github":https://github.com/#{config['github']}/tree/#{branch_name}}
+ note << %{ - "Compare on Github":https://github.com/#{config['github']}/compare/#{original_branch}...#{branch_name}}
+ end
+
+ Issue.find(issue_id).add_note(note)
+ end
+
+ def self.run_cmd(cmd)
+ puts cmd
+ system cmd
+ end
+ end
+end
View
68 lib/gitmine/issue.rb
@@ -0,0 +1,68 @@
+module Gitmine
+ class Issue
+ CONFIG_FILE = './.gitmine.yml'
+
+ attr_reader :id, :subject, :status
+
+ # Config from .gitmine.yml
+ def self.config
+ @@config ||= YAML.load_file(CONFIG_FILE)
+ end
+
+ # Extract the issue_id from a commit message.
+ # Examples:
+ # CommitMsgToIssueId.parse("Message for Issue #123.")
+ # => 123
+ # CommitMsgToIssueId.parse("#123.")
+ # => nil
+ #
+ def self.parse_for_issue_id(msg)
+ match = msg.match(/Issue #(\d+)/)
+ match ? match[1] : nil
+ end
+
+ # Parse the commit_message and get the associated issue if any.
+ def self.get_for_commit(commit_message)
+ issue_id = parse_for_issue_id(commit_message)
+ issue_id ? Issue.find(issue_id) : nil
+ end
+
+ # Get the issue from redmine
+ def self.find(issue_id)
+ Issue.new.tap { |issue|
+ issue.build_via_issue_id(issue_id)
+ }
+ end
+
+ # Get attributes from redmine and set them all
+ def build_via_issue_id(issue_id)
+ @id = issue_id
+ data = http_get(issue_id).parsed_response['issue']
+ @subject = data['subject']
+ @status = data['status']['name']
+ end
+
+ # Add a note to the Issue
+ def add_note(note)
+ p self.class.put(url(self.id),
+ :query => {:notes => note},
+ :body => "") # nginx reject requests without body
+ end
+
+ include HTTParty
+ base_uri "#{config['host']}/issues/"
+ basic_auth config['api_key'], '' # username is api_key, password is empty
+ headers 'Content-type' => 'text/xml' # by-pass rails authenticity token mechanism
+
+ protected
+
+ # Url to redmine/issues
+ def url(id)
+ "/#{id}.xml"
+ end
+
+ def http_get(issue_id)
+ self.class.get(url(issue_id))
+ end
+ end
+end
View
5 spec/commit_spec.rb
@@ -30,7 +30,8 @@
it "should memoize issue" do
Gitmine::Issue.should_receive(:get_for_commit).with("Commit message") { issue }.once
- commit.issue.should == issue
- commit.issue.should == issue
+ 2.times do
+ commit.issue.should == issue
+ end
end
end
View
6 spec/gitmine_spec.rb
@@ -1,11 +1,11 @@
require 'spec_helper'
-describe Gitmine do
+describe Gitmine::Gitmine do
before do
File.stub!(:read) { "ref: refs/heads/wip" }
end
- let(:gitmine) { Gitmine.new }
+ let(:gitmine) { Gitmine::Gitmine.new }
let(:commit_1) do
mock(
@@ -41,7 +41,7 @@
it "should check out to the current branch" do
Grit::Repo.should_receive(:new).with(ENV['PWD']) { grit_repo }
- Gitmine.new
+ Gitmine::Gitmine.new
end
end
end
View
27 spec/issue_spec.rb
@@ -10,18 +10,10 @@
describe "#config" do
it "should load the config from config.yml" do
- issue.config.should == {"host"=>"http://localhost:3000", "api_key"=>"api_key"}
+ Gitmine::Issue.config.should == {"host"=>"http://redmine-gitmine.heroku.com", "github" => "pcreux/gitmine"}
end
end
- describe "#url (protected)" do
- it "should build up URL based on the config" do
- issue.send(:url, '123').should == 'http://localhost:3000/issues/123.xml?key=api_key'
- end
-
- end
-
-
describe "#get_for_commit" do
it "should parse the commit message to find a commit_id and call #get" do
commit_msg = 'A commit msg Issue #123'
@@ -30,19 +22,19 @@
end
end
- describe "#get (class method)" do
+ describe "#find (class method)" do
it "should build_via_issue_id" do
issue = Gitmine::Issue.new
Gitmine::Issue.should_receive(:new) { issue }
issue.should_receive(:build_via_issue_id)
- Gitmine::Issue.get(123)
+ Gitmine::Issue.find(123)
end
end
describe "#build_via_issue_id" do
before do
@httparty = mock(:http_party_response, :parsed_response => {'issue' => { 'subject' => 'A subject', 'status' => {'name' => 'Completed'}}})
- issue.stub!(:get) { @httparty }
+ issue.stub!(:http_get) { @httparty }
end
it "should get issue data and load attributes" do
@@ -58,12 +50,11 @@
end
end
- describe "#get (protected instance method)" do
- it "should create a new issue via HTTParty" do
- issue.stub!(:url) { 'the_url' }
- HTTParty.should_receive(:get).with('the_url')
- issue.send(:get, 123)
+ describe "#add_note" do
+ it "should PUT a note" do
+ issue.stub!(:id) { 1 }
+ issue.class.should_receive(:put).with('/1.xml', :query => {:notes => "Hello"}, :body => "")
+ issue.add_note("Hello")
end
end
-
end

0 comments on commit 8497d68

Please sign in to comment.
Something went wrong with that request. Please try again.