compare_linker 1.1.1
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.
- checksums.yaml +7 -0
- data/.gitignore +4 -0
- data/.rspec +2 -0
- data/.travis.yml +5 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +44 -0
- data/LICENSE.txt +22 -0
- data/README.md +15 -0
- data/Rakefile +7 -0
- data/compare_linker.gemspec +27 -0
- data/guides/jenkins_setup_guide.md +85 -0
- data/lib/compare_linker.rb +69 -0
- data/lib/compare_linker/formatter/markdown.rb +30 -0
- data/lib/compare_linker/formatter/text.rb +30 -0
- data/lib/compare_linker/github_link_finder.rb +33 -0
- data/lib/compare_linker/github_tag_finder.rb +18 -0
- data/lib/compare_linker/lockfile_comparator.rb +37 -0
- data/lib/compare_linker/lockfile_fetcher.rb +24 -0
- data/lib/compare_linker/version.rb +3 -0
- data/lib/compare_linker/webhook_payload.rb +22 -0
- data/payload.rb +10 -0
- data/runner.rb +32 -0
- data/spec/fixtures/rails.json +1 -0
- data/spec/fixtures/web_translate_it.json +1 -0
- data/spec/lib/compare_linker/github_link_finder_spec.rb +32 -0
- data/spec/spec_helper.rb +11 -0
- data/spec/support/load_fixture.rb +5 -0
- metadata +145 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: af95f0a2fa32ca45c3466eaea99a42a60f459ee8
|
4
|
+
data.tar.gz: c326f2ce50e6ee13d95fb6902fd5485c670388cc
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: f2658bdebc63b821bfe21fe64ac000ebcbef6ae64bf9259f694bb50dda824bcc866e2d9f12e7c308ea62b13132d3b5e49e77ae36458751471db8bb7159c41dc8
|
7
|
+
data.tar.gz: 7141938c57780fee24b2e814cdc01b4fabcb21f23060969c14a9564c88d88fe95a4d5310d0c8c5ef55e688895ce4c04f19251bb105dd645ae46abb7bc52f67b4
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
compare_linker (1.1.1)
|
5
|
+
httpclient
|
6
|
+
octokit
|
7
|
+
|
8
|
+
GEM
|
9
|
+
remote: https://rubygems.org/
|
10
|
+
specs:
|
11
|
+
addressable (2.3.7)
|
12
|
+
diff-lcs (1.2.5)
|
13
|
+
faraday (0.9.1)
|
14
|
+
multipart-post (>= 1.2, < 3)
|
15
|
+
httpclient (2.6.0.1)
|
16
|
+
multipart-post (2.0.0)
|
17
|
+
octokit (3.8.0)
|
18
|
+
sawyer (~> 0.6.0, >= 0.5.3)
|
19
|
+
rake (10.4.2)
|
20
|
+
rspec (3.2.0)
|
21
|
+
rspec-core (~> 3.2.0)
|
22
|
+
rspec-expectations (~> 3.2.0)
|
23
|
+
rspec-mocks (~> 3.2.0)
|
24
|
+
rspec-core (3.2.1)
|
25
|
+
rspec-support (~> 3.2.0)
|
26
|
+
rspec-expectations (3.2.0)
|
27
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
28
|
+
rspec-support (~> 3.2.0)
|
29
|
+
rspec-mocks (3.2.1)
|
30
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
31
|
+
rspec-support (~> 3.2.0)
|
32
|
+
rspec-support (3.2.2)
|
33
|
+
sawyer (0.6.0)
|
34
|
+
addressable (~> 2.3.5)
|
35
|
+
faraday (~> 0.8, < 0.10)
|
36
|
+
|
37
|
+
PLATFORMS
|
38
|
+
ruby
|
39
|
+
|
40
|
+
DEPENDENCIES
|
41
|
+
bundler (~> 1.3)
|
42
|
+
compare_linker!
|
43
|
+
rake
|
44
|
+
rspec
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2014 Kensuke Nagae
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
Compare Linker
|
2
|
+
==============
|
3
|
+
|
4
|
+
Create GitHub's compare view URLs for pull request from diff of `Gemfile.lock` (and post comment to pull request).
|
5
|
+
|
6
|
+

|
7
|
+
|
8
|
+
[GitHub Compare View](https://github.com/blog/612-introducing-github-compare-view) rocks.But [diff of Gemfile.lock](https://github.com/kyanny/compare_linker_demo/pull/14/files) sucks. So I made Compare Linker.
|
9
|
+
|
10
|
+
Rack app for listening GitHub Webhook
|
11
|
+
-------------------------------------
|
12
|
+
|
13
|
+
There's rack application for Compare Linker with GitHub's Webhook.
|
14
|
+
|
15
|
+
https://github.com/kyanny/compare_linker_rack_app
|
data/Rakefile
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'compare_linker/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "compare_linker"
|
8
|
+
spec.version = CompareLinker::VERSION
|
9
|
+
spec.authors = ["Kensuke Nagae"]
|
10
|
+
spec.email = ["kyanny@gmail.com"]
|
11
|
+
spec.description = %q{Create GitHub's compare view URLs for pull request from diff of Gemfile.lock}
|
12
|
+
spec.summary = %q{Create GitHub's compare view URLs for pull request}
|
13
|
+
spec.homepage = "https://github.com/masutaka/compare_linker"
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files`.split($/)
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_dependency "octokit"
|
22
|
+
spec.add_dependency "httpclient"
|
23
|
+
|
24
|
+
spec.add_development_dependency "bundler", "~> 1.3"
|
25
|
+
spec.add_development_dependency "rake"
|
26
|
+
spec.add_development_dependency "rspec"
|
27
|
+
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
CompareLinker Jenkins Setup Guide
|
2
|
+
=================================
|
3
|
+
|
4
|
+
This guide describes how to setup Jenkins job for CompareLinker.
|
5
|
+
|
6
|
+
Before setup, you have to install and run your Jenkins CI server.
|
7
|
+
And you have to install Ruby 1.9 or higher with `bundler` gem in your Jenkins server, too.
|
8
|
+
|
9
|
+
1. Install "Parameterized Trigger Plugin"
|
10
|
+
-----------------------------------------
|
11
|
+
|
12
|
+
https://wiki.jenkins-ci.org/display/JENKINS/Parameterized+Trigger+Plugin
|
13
|
+
|
14
|
+
1. Create new job
|
15
|
+
-----------------
|
16
|
+
|
17
|
+
Create new "Build a free-style software project" job.
|
18
|
+
|
19
|
+
3. Check "This build is parameterized" and parameters
|
20
|
+
-----------------------------------------------------
|
21
|
+
|
22
|
+
You need to add two string parameters:
|
23
|
+
|
24
|
+
1. `payload` (default value is `none`)
|
25
|
+
2. `OCTOKIT_ACCESS_TOKEN` (default value is your GitHub access token)
|
26
|
+
|
27
|
+
If you don't have GitHub access token, you can get it from https://github.com/settings/tokens/new.
|
28
|
+
|
29
|
+

|
30
|
+
|
31
|
+
4. Setup "Source Code Management" section
|
32
|
+
-----------------------------------------
|
33
|
+
|
34
|
+
Choose "Git". Repository URL is https://github.com/kyanny/compare_linker.git.
|
35
|
+
|
36
|
+

|
37
|
+
|
38
|
+
5. Setup "Build Triggers" section
|
39
|
+
---------------------------------
|
40
|
+
|
41
|
+
Check "Trigger builds remotely".
|
42
|
+
|
43
|
+
If you want to enable authentication to start build job, fill in "Authentication Token" field.
|
44
|
+
|
45
|
+

|
46
|
+
|
47
|
+
6. Setup "Build" section
|
48
|
+
------------------------
|
49
|
+
|
50
|
+
Choose "Execute Shell". Command is below.
|
51
|
+
|
52
|
+
```
|
53
|
+
#!/bin/bash
|
54
|
+
|
55
|
+
bundle install --path vendor/bundle
|
56
|
+
bundle exec ruby runner.rb
|
57
|
+
```
|
58
|
+
|
59
|
+
7. Add GitHub Webhook to your repository
|
60
|
+
----------------------------------------
|
61
|
+
|
62
|
+
CompareLinker rack app listens GitHub's pull request webhook.
|
63
|
+
Webhook URL is like `http://example.com/jenkins/[job_name]/buildWithParameters?token=[jenkins_auth_token]`.
|
64
|
+
|
65
|
+
You can add webhook to your repository by `curl(1)`:
|
66
|
+
|
67
|
+
```
|
68
|
+
$ curl -H 'Authorization: token [your_github_access_token]' \
|
69
|
+
-d '{"name": "web", "active": true, "events": ["pull_request"], "config": {"url": "your_jenkins_webhook_url"}}' \
|
70
|
+
https://api.github.com/repos/[repo_owner_account]/[repo_name]/hooks
|
71
|
+
```
|
72
|
+
|
73
|
+
Or by http://www.hurl.it/:
|
74
|
+
|
75
|
+

|
76
|
+
|
77
|
+
If your jenkins requires authentication, you need basic auth to access jenkins.
|
78
|
+
You can embed basic auth credential to URL like "http://user@pass:host" style.
|
79
|
+
|
80
|
+
8. Open new pull request
|
81
|
+
------------------------
|
82
|
+
|
83
|
+
That's all! When your repository gets new open pull request, you will see new comment like that:
|
84
|
+
|
85
|
+

|
@@ -0,0 +1,69 @@
|
|
1
|
+
require "octokit"
|
2
|
+
require_relative "compare_linker/formatter/text"
|
3
|
+
require_relative "compare_linker/formatter/markdown"
|
4
|
+
require_relative "compare_linker/github_link_finder"
|
5
|
+
require_relative "compare_linker/github_tag_finder"
|
6
|
+
require_relative "compare_linker/lockfile_comparator"
|
7
|
+
require_relative "compare_linker/lockfile_fetcher"
|
8
|
+
|
9
|
+
class CompareLinker
|
10
|
+
attr_reader :repo_full_name, :pr_number, :compare_links
|
11
|
+
attr_accessor :formatter, :octokit
|
12
|
+
|
13
|
+
def initialize(repo_full_name, pr_number)
|
14
|
+
@repo_full_name = repo_full_name
|
15
|
+
@pr_number = pr_number
|
16
|
+
@octokit ||= Octokit::Client.new(access_token: ENV["OCTOKIT_ACCESS_TOKEN"])
|
17
|
+
@formatter = Formatter::Text.new
|
18
|
+
end
|
19
|
+
|
20
|
+
def make_compare_links
|
21
|
+
if octokit.pull_request_files(repo_full_name, pr_number).find { |resource| resource.filename == "Gemfile.lock" }
|
22
|
+
pull_request = octokit.pull_request(repo_full_name, pr_number)
|
23
|
+
|
24
|
+
fetcher = LockfileFetcher.new(octokit)
|
25
|
+
old_lockfile = fetcher.fetch(repo_full_name, pull_request.base.sha)
|
26
|
+
new_lockfile = fetcher.fetch(repo_full_name, pull_request.head.sha)
|
27
|
+
|
28
|
+
comparator = LockfileComparator.new
|
29
|
+
comparator.compare(old_lockfile, new_lockfile)
|
30
|
+
@compare_links = comparator.updated_gems.map { |gem_name, gem_info|
|
31
|
+
if gem_info[:owner].nil?
|
32
|
+
finder = GithubLinkFinder.new(octokit)
|
33
|
+
finder.find(gem_name)
|
34
|
+
if finder.repo_owner.nil?
|
35
|
+
gem_info[:homepage_uri] = finder.homepage_uri
|
36
|
+
formatter.format(gem_info)
|
37
|
+
else
|
38
|
+
gem_info[:repo_owner] = finder.repo_owner
|
39
|
+
gem_info[:repo_name] = finder.repo_name
|
40
|
+
|
41
|
+
tag_finder = GithubTagFinder.new(octokit)
|
42
|
+
old_tag = tag_finder.find(finder.repo_full_name, gem_info[:old_ver])
|
43
|
+
new_tag = tag_finder.find(finder.repo_full_name, gem_info[:new_ver])
|
44
|
+
|
45
|
+
if old_tag && new_tag
|
46
|
+
gem_info[:old_tag] = old_tag.name
|
47
|
+
gem_info[:new_tag] = new_tag.name
|
48
|
+
formatter.format(gem_info)
|
49
|
+
else
|
50
|
+
formatter.format(gem_info)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
else
|
54
|
+
formatter.format(gem_info)
|
55
|
+
end
|
56
|
+
}
|
57
|
+
@compare_links
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def add_comment(repo_full_name, pr_number, compare_links)
|
62
|
+
res = octokit.add_comment(
|
63
|
+
repo_full_name,
|
64
|
+
pr_number,
|
65
|
+
compare_links
|
66
|
+
)
|
67
|
+
"https://github.com/#{repo_full_name}/pull/#{pr_number}#issuecomment-#{res.id}"
|
68
|
+
end
|
69
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require "ostruct"
|
2
|
+
|
3
|
+
class CompareLinker
|
4
|
+
class Formatter
|
5
|
+
class Markdown
|
6
|
+
def format(gem_info)
|
7
|
+
g = OpenStruct.new(gem_info)
|
8
|
+
|
9
|
+
text = case
|
10
|
+
when g.owner && g.old_rev && g.new_rev
|
11
|
+
"* #{g.gem_name}: https://github.com/#{g.owner}/#{g.gem_name}/compare/#{g.old_rev}...#{g.new_rev}"
|
12
|
+
when g.homepage_uri
|
13
|
+
"* [#{g.gem_name}](#{g.homepage_uri}): #{g.old_ver} => #{g.new_ver}"
|
14
|
+
when g.old_tag && g.new_tag
|
15
|
+
"* #{g.gem_name}: https://github.com/#{g.repo_owner}/#{g.repo_name}/compare/#{g.old_tag}...#{g.new_tag}"
|
16
|
+
when g.repo_owner && g.repo_name
|
17
|
+
"* [#{g.gem_name}](https://github.com/#{g.repo_owner}/#{g.repo_name}): #{g.old_ver} => #{g.new_ver}"
|
18
|
+
else
|
19
|
+
"* #{g.gem_name}: (link not found) #{g.old_ver} => #{g.new_ver}"
|
20
|
+
end
|
21
|
+
|
22
|
+
if (g.old_tag && g.new_tag && g.new_tag.to_f < g.old_tag.to_f) || g.new_ver.to_f < g.old_ver.to_f
|
23
|
+
text += " (downgrade)"
|
24
|
+
end
|
25
|
+
|
26
|
+
text
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require "ostruct"
|
2
|
+
|
3
|
+
class CompareLinker
|
4
|
+
class Formatter
|
5
|
+
class Text
|
6
|
+
def format(gem_info)
|
7
|
+
g = OpenStruct.new(gem_info)
|
8
|
+
|
9
|
+
text = case
|
10
|
+
when g.owner && g.old_rev && g.new_rev
|
11
|
+
"#{g.gem_name}: https://github.com/#{g.owner}/#{g.gem_name}/compare/#{g.old_rev}...#{g.new_rev}"
|
12
|
+
when g.homepage_uri
|
13
|
+
"#{g.gem_name} (#{g.homepage_uri}): #{g.old_ver} => #{g.new_ver}"
|
14
|
+
when g.old_tag && g.new_tag
|
15
|
+
"#{g.gem_name}: https://github.com/#{g.repo_owner}/#{g.repo_name}/compare/#{g.old_tag}...#{g.new_tag}"
|
16
|
+
when g.repo_owner && g.repo_name
|
17
|
+
"#{g.gem_name}: https://github.com/#{g.repo_owner}/#{g.repo_name} #{g.old_ver} => #{g.new_ver}"
|
18
|
+
else
|
19
|
+
"#{g.gem_name} (link not found): #{g.old_ver} => #{g.new_ver}"
|
20
|
+
end
|
21
|
+
|
22
|
+
if (g.old_tag && g.new_tag && g.new_tag.to_f < g.old_tag.to_f) || g.new_ver.to_f < g.old_ver.to_f
|
23
|
+
text += " (downgrade)"
|
24
|
+
end
|
25
|
+
|
26
|
+
text
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require "json"
|
2
|
+
require "httpclient"
|
3
|
+
|
4
|
+
class CompareLinker
|
5
|
+
class GithubLinkFinder
|
6
|
+
attr_reader :octokit, :repo_owner, :repo_name, :homepage_uri
|
7
|
+
|
8
|
+
def initialize(octokit)
|
9
|
+
@octokit = octokit
|
10
|
+
end
|
11
|
+
|
12
|
+
def find(gem_name)
|
13
|
+
gem_info = JSON.parse(
|
14
|
+
HTTPClient.get("https://rubygems.org/api/v1/gems/#{gem_name}.json").body
|
15
|
+
)
|
16
|
+
|
17
|
+
github_url = [
|
18
|
+
gem_info["homepage_uri"],
|
19
|
+
gem_info["source_code_uri"]
|
20
|
+
].find { |uri| uri.to_s.match(/github\.com\//) }
|
21
|
+
|
22
|
+
if github_url.nil?
|
23
|
+
@homepage_uri = gem_info["homepage_uri"]
|
24
|
+
else
|
25
|
+
_, @repo_owner, @repo_name = github_url.match(%r!github\.com/([^/]+)/([^/]+)!).to_a
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def repo_full_name
|
30
|
+
"#{@repo_owner}/#{repo_name}"
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
class CompareLinker
|
2
|
+
class GithubTagFinder
|
3
|
+
attr_reader :octokit
|
4
|
+
|
5
|
+
def initialize(octokit)
|
6
|
+
@octokit = octokit
|
7
|
+
end
|
8
|
+
|
9
|
+
def find(repo_full_name, gem_version)
|
10
|
+
tags = octokit.tags(repo_full_name)
|
11
|
+
if tags
|
12
|
+
tags.find { |tag|
|
13
|
+
tag.name == gem_version || tag.name == "v#{gem_version}"
|
14
|
+
}
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
class CompareLinker
|
2
|
+
class LockfileComparator
|
3
|
+
attr_accessor :updated_gems
|
4
|
+
|
5
|
+
def initialize
|
6
|
+
@updated_gems = {}
|
7
|
+
end
|
8
|
+
|
9
|
+
def compare(old_lockfile, new_lockfile)
|
10
|
+
old_lockfile.specs.each do |old_spec|
|
11
|
+
new_lockfile.specs.each do |new_spec|
|
12
|
+
if old_spec.name == new_spec.name
|
13
|
+
old_rev = old_spec.source.options["revision"]
|
14
|
+
new_rev = new_spec.source.options["revision"]
|
15
|
+
if old_rev && new_rev && (old_rev != new_rev)
|
16
|
+
_, owner, gem_name = old_spec.source.uri.match(/github\.com\/([^\/]+)\/([^.]+)/).to_a
|
17
|
+
updated_gems[old_spec.name] = {
|
18
|
+
owner: owner,
|
19
|
+
gem_name: gem_name,
|
20
|
+
old_rev: old_rev,
|
21
|
+
new_rev: new_rev,
|
22
|
+
}
|
23
|
+
elsif old_spec.version != new_spec.version
|
24
|
+
updated_gems[old_spec.name] = {
|
25
|
+
owner: nil,
|
26
|
+
gem_name: old_spec.name,
|
27
|
+
old_ver: old_spec.version.to_s,
|
28
|
+
new_ver: new_spec.version.to_s,
|
29
|
+
}
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
updated_gems
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require "bundler"
|
2
|
+
|
3
|
+
class CompareLinker
|
4
|
+
class LockfileFetcher
|
5
|
+
attr_reader :octokit
|
6
|
+
|
7
|
+
def initialize(octokit)
|
8
|
+
@octokit = octokit
|
9
|
+
end
|
10
|
+
|
11
|
+
def fetch(repo_full_name, ref)
|
12
|
+
lockfile_content = octokit.contents(
|
13
|
+
repo_full_name, { ref: ref }
|
14
|
+
).find { |content|
|
15
|
+
content.name == "Gemfile.lock"
|
16
|
+
}
|
17
|
+
Bundler::LockfileParser.new(
|
18
|
+
Base64.decode64(
|
19
|
+
octokit.blob(repo_full_name, lockfile_content.sha).content
|
20
|
+
)
|
21
|
+
)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require "json"
|
2
|
+
|
3
|
+
class CompareLinker
|
4
|
+
class WebhookPayload
|
5
|
+
def initialize(payload)
|
6
|
+
@payload = payload
|
7
|
+
@json = JSON.parse(@payload)
|
8
|
+
end
|
9
|
+
|
10
|
+
def action
|
11
|
+
@json["action"]
|
12
|
+
end
|
13
|
+
|
14
|
+
def repo_full_name
|
15
|
+
@json["repository"]["full_name"]
|
16
|
+
end
|
17
|
+
|
18
|
+
def pr_number
|
19
|
+
@json["number"]
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
data/payload.rb
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
require_relative "lib/compare_linker"
|
2
|
+
require_relative "lib/compare_linker/webhook_payload"
|
3
|
+
|
4
|
+
payload = CompareLinker::WebhookPayload.new(ENV["payload"])
|
5
|
+
exit if payload.action != "opened"
|
6
|
+
|
7
|
+
compare_linker = CompareLinker.new(payload.repo_full_name, payload.pr_number)
|
8
|
+
compare_linker.formatter = CompareLinker::Formatter::Markdown.new
|
9
|
+
compare_links = compare_linker.make_compare_links.join("\n")
|
10
|
+
puts compare_linker.add_comment(payload.repo_full_name, payload.pr_number, compare_links)
|
data/runner.rb
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
require_relative "lib/compare_linker"
|
2
|
+
require "optparse"
|
3
|
+
|
4
|
+
options = {}
|
5
|
+
opt = OptionParser.new
|
6
|
+
opt.on("-f VAL", "--format VAL") { |val|
|
7
|
+
case val
|
8
|
+
when /t(ext)?/i
|
9
|
+
options[:formatter] = CompareLinker::Formatter::Text.new
|
10
|
+
when /m(arkdown|d)?/i
|
11
|
+
options[:formatter] = CompareLinker::Formatter::Markdown.new
|
12
|
+
end
|
13
|
+
}
|
14
|
+
opt.on("--post-comment") { options[:post_comment] = true }
|
15
|
+
opt.parse!
|
16
|
+
|
17
|
+
repo_full_name, pr_number = *ARGV
|
18
|
+
if repo_full_name.nil? || pr_number.nil?
|
19
|
+
puts <<USAGE
|
20
|
+
Usage: ruby #{$0} [repo_full_name] [pr_number]
|
21
|
+
ruby #{$0} [repo_full_name] [pr_number] OCTOKIT_ACCESS_TOKEN=[your github access token]
|
22
|
+
USAGE
|
23
|
+
exit!
|
24
|
+
end
|
25
|
+
|
26
|
+
compare_linker = CompareLinker.new(repo_full_name, pr_number.to_i)
|
27
|
+
compare_linker.formatter = options[:formatter] if options[:formatter]
|
28
|
+
puts compare_linker.make_compare_links
|
29
|
+
if options[:post_comment]
|
30
|
+
compare_linker.formatter = CompareLinker::Formatter::Markdown.new
|
31
|
+
puts compare_linker.add_comment(repo_full_name, pr_number, compare_linker.compare_links)
|
32
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
{"name":"rails","downloads":31913037,"version":"4.0.2","version_downloads":485385,"platform":"ruby","authors":"David Heinemeier Hansson","info":"Ruby on Rails is a full-stack web framework optimized for programmer happiness and sustainable productivity. It encourages beautiful code by favoring convention over configuration.","licenses":["MIT"],"project_uri":"http://rubygems.org/gems/rails","gem_uri":"http://rubygems.org/gems/rails-4.0.2.gem","homepage_uri":"http://www.rubyonrails.org","wiki_uri":"http://wiki.rubyonrails.org","documentation_uri":"http://api.rubyonrails.org","mailing_list_uri":"http://groups.google.com/group/rubyonrails-talk","source_code_uri":"http://github.com/rails/rails","bug_tracker_uri":"http://github.com/rails/rails/issues","dependencies":{"development":[],"runtime":[{"name":"actionmailer","requirements":"= 4.0.2"},{"name":"actionpack","requirements":"= 4.0.2"},{"name":"activerecord","requirements":"= 4.0.2"},{"name":"activesupport","requirements":"= 4.0.2"},{"name":"bundler","requirements":"< 2.0, >= 1.3.0"},{"name":"railties","requirements":"= 4.0.2"},{"name":"sprockets-rails","requirements":"~> 2.0.0"}]}}
|
@@ -0,0 +1 @@
|
|
1
|
+
{"name":"web_translate_it","downloads":143572,"version":"2.2.1","version_downloads":321,"platform":"ruby","authors":"Edouard Briere","info":"A gem to push and pull language files to WebTranslateIt.com.","licenses":["MIT"],"project_uri":"http://rubygems.org/gems/web_translate_it","gem_uri":"http://rubygems.org/gems/web_translate_it-2.2.1.gem","homepage_uri":"https://webtranslateit.com","wiki_uri":"","documentation_uri":"","mailing_list_uri":"","source_code_uri":"http://github.com/atelierconvivialite/webtranslateit/","bug_tracker_uri":"http://github.com/atelierconvivialite/webtranslateit/issues","dependencies":{"development":[{"name":"guard-rspec","requirements":">= 0"},{"name":"rspec","requirements":">= 2.6.0"}],"runtime":[{"name":"multi_json","requirements":">= 0"},{"name":"multipart-post","requirements":"~> 2.0"},{"name":"trollop","requirements":"~> 2.0"}]}}
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe CompareLinker::GithubLinkFinder do
|
4
|
+
let(:octokit) { double.as_null_object }
|
5
|
+
|
6
|
+
subject { described_class.new(octokit) }
|
7
|
+
|
8
|
+
|
9
|
+
describe "#find" do
|
10
|
+
before do
|
11
|
+
allow(HTTPClient).to receive_message_chain(:get, :body).and_return load_fixture("rails.json")
|
12
|
+
end
|
13
|
+
|
14
|
+
it "extracts repo_owner and repo_name" do
|
15
|
+
subject.find("rails")
|
16
|
+
expect(subject.repo_owner).to eq "rails"
|
17
|
+
expect(subject.repo_name).to eq "rails"
|
18
|
+
end
|
19
|
+
|
20
|
+
context "if github url includes trailing slash" do
|
21
|
+
before do
|
22
|
+
allow(HTTPClient).to receive_message_chain(:get, :body).and_return load_fixture("web_translate_it.json")
|
23
|
+
end
|
24
|
+
|
25
|
+
it "extracts repo_owner and repo_name without trailing slash" do
|
26
|
+
subject.find("web_translate_it")
|
27
|
+
expect(subject.repo_owner).to eq "atelierconvivialite"
|
28
|
+
expect(subject.repo_name).to eq "webtranslateit"
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,145 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: compare_linker
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.1.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Kensuke Nagae
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-02-28 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: octokit
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: httpclient
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: bundler
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '1.3'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '1.3'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rake
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rspec
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
description: Create GitHub's compare view URLs for pull request from diff of Gemfile.lock
|
84
|
+
email:
|
85
|
+
- kyanny@gmail.com
|
86
|
+
executables: []
|
87
|
+
extensions: []
|
88
|
+
extra_rdoc_files: []
|
89
|
+
files:
|
90
|
+
- ".gitignore"
|
91
|
+
- ".rspec"
|
92
|
+
- ".travis.yml"
|
93
|
+
- Gemfile
|
94
|
+
- Gemfile.lock
|
95
|
+
- LICENSE.txt
|
96
|
+
- README.md
|
97
|
+
- Rakefile
|
98
|
+
- compare_linker.gemspec
|
99
|
+
- guides/jenkins_setup_guide.md
|
100
|
+
- lib/compare_linker.rb
|
101
|
+
- lib/compare_linker/formatter/markdown.rb
|
102
|
+
- lib/compare_linker/formatter/text.rb
|
103
|
+
- lib/compare_linker/github_link_finder.rb
|
104
|
+
- lib/compare_linker/github_tag_finder.rb
|
105
|
+
- lib/compare_linker/lockfile_comparator.rb
|
106
|
+
- lib/compare_linker/lockfile_fetcher.rb
|
107
|
+
- lib/compare_linker/version.rb
|
108
|
+
- lib/compare_linker/webhook_payload.rb
|
109
|
+
- payload.rb
|
110
|
+
- runner.rb
|
111
|
+
- spec/fixtures/rails.json
|
112
|
+
- spec/fixtures/web_translate_it.json
|
113
|
+
- spec/lib/compare_linker/github_link_finder_spec.rb
|
114
|
+
- spec/spec_helper.rb
|
115
|
+
- spec/support/load_fixture.rb
|
116
|
+
homepage: https://github.com/masutaka/compare_linker
|
117
|
+
licenses:
|
118
|
+
- MIT
|
119
|
+
metadata: {}
|
120
|
+
post_install_message:
|
121
|
+
rdoc_options: []
|
122
|
+
require_paths:
|
123
|
+
- lib
|
124
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
125
|
+
requirements:
|
126
|
+
- - ">="
|
127
|
+
- !ruby/object:Gem::Version
|
128
|
+
version: '0'
|
129
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
130
|
+
requirements:
|
131
|
+
- - ">="
|
132
|
+
- !ruby/object:Gem::Version
|
133
|
+
version: '0'
|
134
|
+
requirements: []
|
135
|
+
rubyforge_project:
|
136
|
+
rubygems_version: 2.4.5
|
137
|
+
signing_key:
|
138
|
+
specification_version: 4
|
139
|
+
summary: Create GitHub's compare view URLs for pull request
|
140
|
+
test_files:
|
141
|
+
- spec/fixtures/rails.json
|
142
|
+
- spec/fixtures/web_translate_it.json
|
143
|
+
- spec/lib/compare_linker/github_link_finder_spec.rb
|
144
|
+
- spec/spec_helper.rb
|
145
|
+
- spec/support/load_fixture.rb
|