Skip to content

Commit

Permalink
Adds GitLab formatter
Browse files Browse the repository at this point in the history
  • Loading branch information
jeroenj committed Nov 21, 2014
1 parent c2db6da commit 0c6d064
Show file tree
Hide file tree
Showing 9 changed files with 218 additions and 1 deletion.
36 changes: 36 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,42 @@ formatter = Pronto::Formatter::GithubFormatter.new # or GithubPullRequestFormatt
Pronto.run('origin/master', '.', formatter)
```

### GitLab Integration

You can run Pronto as a step of your CI builds and get the results as comments
on GitLab commits using `GitlabFormatter`.

Add Pronto runners you want to use to your Gemfile:
```ruby
gem 'pronto'
gem 'pronto-rubocop', require: false
gem 'pronto-scss', require: false
```
or gemspec file:
```ruby
s.add_development_dependency 'pronto'
s.add_development_dependency 'pronto-rubocop'
s.add_development_dependency 'pronto-scss'
```

Set the `GITLAB_API_ENDPOINT` environment variable to your API endpoint URL.
If you are using Gitlab.com's hosted service your endpoint will be `https://gitlab.com/api/v3`.
Set the `GITLAB_API_PRIVATE_TOKEN` environment variable to your Gitlab private token
which you can find in your account settings.

Then just run it:
```bash
GITLAB_API_ENDPOINT="https://gitlab.com/api/v3" GITLAB_API_PRIVATE_TOKEN=token pronto run -f gitlab -c origin/master
```

As an alternative, you can also set up a rake task:
```ruby
Pronto.gem_names.each { |gem_name| require "pronto/#{gem_name}" }

formatter = Pronto::Formatter::GitlabFormatter.new
Pronto.run('origin/master', '.', formatter)
```

### Local Changes

You can run Pronto locally. First, install Pronto and the runners you want to use:
Expand Down
3 changes: 3 additions & 0 deletions lib/pronto.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
require 'rugged'
require 'octokit'
require 'gitlab'
require 'forwardable'

require 'pronto/git/repository'
Expand All @@ -11,11 +12,13 @@
require 'pronto/message'
require 'pronto/runner'
require 'pronto/github'
require 'pronto/gitlab'

require 'pronto/formatter/text_formatter'
require 'pronto/formatter/json_formatter'
require 'pronto/formatter/github_formatter'
require 'pronto/formatter/github_pull_request_formatter'
require 'pronto/formatter/gitlab_formatter'
require 'pronto/formatter/checkstyle_formatter'
require 'pronto/formatter/formatter'

Expand Down
1 change: 1 addition & 0 deletions lib/pronto/formatter/formatter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ def self.names
FORMATTERS = {
'github' => GithubFormatter,
'github_pr' => GithubPullRequestFormatter,
'gitlab' => GitlabFormatter,
'json' => JsonFormatter,
'checkstyle' => CheckstyleFormatter,
'text' => TextFormatter
Expand Down
29 changes: 29 additions & 0 deletions lib/pronto/formatter/gitlab_formatter.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
module Pronto
module Formatter
class GitlabFormatter
def format(messages, repo)
messages = messages.uniq { |message| [message.msg, message.line.new_lineno] }
client = Gitlab.new repo

commit_messages = messages.map do |message|
create_comment(client,
message.commit_sha,
message.msg,
message.path,
message.line.commit_line.new_lineno)
end

"#{commit_messages.compact.count} Pronto messages posted to GitLab"
end

private

def create_comment(client, sha, note, path, line)
comment = Gitlab::Comment.new(sha, note, path, line)
comments = client.commit_comments(sha)
existing = comments.any? { |c| comment == c }
client.create_commit_comment(comment) unless existing
end
end
end
end
55 changes: 55 additions & 0 deletions lib/pronto/gitlab.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
module Pronto
class Gitlab
def initialize(repo)
@repo = repo
@comment_cache = {}
end

def commit_comments(sha)
@comment_cache["#{sha}"] ||= begin
client.commit_comments(slug, sha).map do |comment|
Comment.new(sha, comment.note, comment.path, comment.line)
end
end
end

def create_commit_comment(comment)
client.create_commit_comment(slug, comment.sha, comment.note,
path: comment.path, line: comment.line,
line_type: 'new')
end

private

def slug
@slug ||= begin
host = URI.split(endpoint)[2, 2].compact.join(':')
slug = @repo.remote_urls.map do |url|
match = /.*#{host}(:|\/)(?<slug>.*).git/.match(url)
match[:slug] if match
end.compact.first
URI.escape(slug, '/') if slug
end
end

def client
@client ||= ::Gitlab.client(endpoint: endpoint, private_token: private_token)
end

def private_token
ENV['GITLAB_API_PRIVATE_TOKEN']
end

def endpoint
ENV['GITLAB_API_ENDPOINT']
end

class Comment < Struct.new(:sha, :note, :path, :line)
def ==(other)
line == other.line &&
path == other.path &&
note == other.note
end
end
end
end
1 change: 1 addition & 0 deletions pronto.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ Gem::Specification.new do |s|
s.add_runtime_dependency 'rugged', '~> 0.21.0'
s.add_runtime_dependency 'thor', '~> 0.19.0'
s.add_runtime_dependency 'octokit', '~> 3.2'
s.add_runtime_dependency 'gitlab', '~> 3.2'
s.add_development_dependency 'rake', '~> 10.3'
s.add_development_dependency 'rspec', '~> 3.0'
s.add_development_dependency 'rspec-its', '~> 1.0'
Expand Down
2 changes: 1 addition & 1 deletion spec/pronto/formatter/formatter_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ module Formatter

describe '.names' do
subject { Formatter.names }
it { should =~ %w(github github_pr json checkstyle text) }
it { should =~ %w(github github_pr gitlab json checkstyle text) }
end
end
end
61 changes: 61 additions & 0 deletions spec/pronto/formatter/gitlab_formatter_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
require 'spec_helper'

module Pronto
module Formatter
describe GitlabFormatter do
ENV['GITLAB_API_ENDPOINT'] = 'http://example.com/api/v3'
ENV['GITLAB_API_PRIVATE_TOKEN'] = 'token'

let(:gitlab_formatter) { GitlabFormatter.new }

describe '#format' do
subject { gitlab_formatter.format(messages, repository) }
let(:messages) { [message, message] }
let(:repository) { Git::Repository.new('.') }
let(:message) { Message.new('path/to', line, :warning, 'crucial') }
let(:line) { double(new_lineno: 1, commit_sha: '123', position: nil) }
before { line.stub(:commit_line).and_return(line) }

specify do
::Gitlab::Client.any_instance
.should_receive(:commit_comments)
.once
.and_return([])

::Gitlab::Client.any_instance
.should_receive(:create_commit_comment)
.once

subject
end
end

describe '#format without duplicates' do
subject { gitlab_formatter.format(messages, repository) }
let(:messages) { [message1, message2] }
let(:repository) { Git::Repository.new('.') }
let(:message1) { Message.new('path/to1', line1, :warning, 'crucial') }
let(:message2) { Message.new('path/to2', line2, :warning, 'crucial') }
let(:line1) { double(new_lineno: 1, commit_sha: '123', position: nil) }
let(:line2) { double(new_lineno: 2, commit_sha: '123', position: nil) }
before do
line1.stub(:commit_line).and_return(line1)
line2.stub(:commit_line).and_return(line2)
end

specify do
::Gitlab::Client.any_instance
.should_receive(:commit_comments)
.once
.and_return([])

::Gitlab::Client.any_instance
.should_receive(:create_commit_comment)
.twice

subject
end
end
end
end
end
31 changes: 31 additions & 0 deletions spec/pronto/gitlab_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
require 'spec_helper'

module Pronto
describe Gitlab do
let(:gitlab) { Gitlab.new(repo) }

describe '#commit_comments' do
subject { gitlab.commit_comments(sha) }

context 'three requests for same comments' do
let(:repo) { double(remote_urls: ['git@gitlab.example.com:mmozuras/pronto.git']) }
let(:sha) { 'foobar' }

specify do
ENV['GITLAB_API_ENDPOINT'] = 'http://gitlab.example.com/api/v3'
ENV['GITLAB_API_PRIVATE_TOKEN'] = 'token'

::Gitlab::Client.any_instance
.should_receive(:commit_comments)
.with('mmozuras%2Fpronto', sha)
.once
.and_return([])

subject
subject
subject
end
end
end
end
end

0 comments on commit 0c6d064

Please sign in to comment.