gems-status 0.6.0 → 0.7.0
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/gems-status.rb +2 -1
- data/lib/gems-status/exists_in_upstream.rb +2 -2
- data/lib/gems-status/gem_checker.rb +4 -2
- data/lib/gems-status/gems_composite_command.rb +10 -8
- data/lib/gems-status/gems_status_metadata.rb +1 -1
- data/lib/gems-status/git_check_messages.rb +23 -0
- data/lib/gems-status/hg_check_messages.rb +27 -0
- data/lib/gems-status/not_a_security_alert_checker.rb +105 -0
- data/lib/gems-status/not_native_gem_checker.rb +3 -2
- data/lib/gems-status/not_rails_checker.rb +2 -2
- data/lib/gems-status/scm_check_messages.rb +49 -0
- data/lib/gems-status/scm_security_messages.rb +5 -0
- data/lib/gems-status/svn_check_messages.rb +26 -0
- data/test/gem_graph.png +0 -0
- metadata +12 -5
data/lib/gems-status.rb
CHANGED
@@ -31,7 +31,8 @@ class GemStatus
|
|
31
31
|
end
|
32
32
|
if @conf["checkers"]
|
33
33
|
@conf["checkers"].each do |c|
|
34
|
-
|
34
|
+
checker = eval(c["classname"]).new(c)
|
35
|
+
gems_composite_command.add_checker(checker)
|
35
36
|
end
|
36
37
|
end
|
37
38
|
if @conf["comments"]
|
@@ -4,7 +4,7 @@ require 'gems-status/gem_checker'
|
|
4
4
|
require 'gems-status/utils'
|
5
5
|
|
6
6
|
class ExistsInUpstream < GemChecker
|
7
|
-
def
|
7
|
+
def check?(gem)
|
8
8
|
Utils::log_debug("Looking for #{gem.name}")
|
9
9
|
result = nil
|
10
10
|
gem_uri = "#{gem.gems_url}/#{gem.name}-#{gem.version}.gem"
|
@@ -15,7 +15,7 @@ class ExistsInUpstream < GemChecker
|
|
15
15
|
return false
|
16
16
|
end
|
17
17
|
end
|
18
|
-
def
|
18
|
+
def description
|
19
19
|
"This gem does not exist in upstream: "
|
20
20
|
end
|
21
21
|
end
|
@@ -4,6 +4,7 @@ require "gems-status/not_native_gem_checker"
|
|
4
4
|
require "gems-status/not_rails_checker"
|
5
5
|
require "gems-status/exists_in_upstream"
|
6
6
|
require "gems-status/view_results"
|
7
|
+
require "gems-status/not_a_security_alert_checker"
|
7
8
|
|
8
9
|
class GemsCompositeCommand < GemsCommand
|
9
10
|
def initialize(target)
|
@@ -19,8 +20,8 @@ class GemsCompositeCommand < GemsCommand
|
|
19
20
|
@commands << command
|
20
21
|
end
|
21
22
|
|
22
|
-
def add_checker(
|
23
|
-
@checkers <<
|
23
|
+
def add_checker(check_object)
|
24
|
+
@checkers << check_object
|
24
25
|
end
|
25
26
|
|
26
27
|
def execute
|
@@ -35,14 +36,15 @@ class GemsCompositeCommand < GemsCommand
|
|
35
36
|
@commands.each do |command|
|
36
37
|
@results[command.ident] = command.result
|
37
38
|
end
|
38
|
-
@checkers.each do |
|
39
|
-
Utils::log_debug "checking #{
|
39
|
+
@checkers.each do |check_object|
|
40
|
+
Utils::log_debug "checking #{check_object.class.name}"
|
40
41
|
@results[@target].sort.each do |k, gems|
|
41
|
-
@checker_results[k] = ""
|
42
|
+
@checker_results[k] = "" unless @checker_results[k]
|
42
43
|
gems.each do |gem|
|
43
|
-
if !
|
44
|
-
@checker_results[gem.name] << "
|
45
|
-
|
44
|
+
if !check_object.check?(gem)
|
45
|
+
@checker_results[gem.name] << "
|
46
|
+
<br/>#{gem.name} #{gem.version} #{gem.origin}: <br/>
|
47
|
+
#{check_object.description} "
|
46
48
|
end
|
47
49
|
end
|
48
50
|
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require "git"
|
2
|
+
|
3
|
+
require "gems-status/scm_check_messages"
|
4
|
+
|
5
|
+
class GitCheckMessages < ScmCheckMessages
|
6
|
+
|
7
|
+
private
|
8
|
+
|
9
|
+
def message(commit)
|
10
|
+
return commit.message
|
11
|
+
end
|
12
|
+
|
13
|
+
def messages(name, source_repo)
|
14
|
+
begin
|
15
|
+
g = Git.open(name)
|
16
|
+
rescue
|
17
|
+
g = Git.clone(source_repo, name)
|
18
|
+
end
|
19
|
+
g.pull
|
20
|
+
return g.log
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require "mercurial-ruby"
|
2
|
+
|
3
|
+
require "gems-status/scm_check_messages"
|
4
|
+
|
5
|
+
class HgCheckMessages < ScmCheckMessages
|
6
|
+
def initialize
|
7
|
+
Mercurial.configure do |conf|
|
8
|
+
conf.hg_binary_path = "/usr/bin/hg"
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
private
|
13
|
+
|
14
|
+
def message(commit)
|
15
|
+
return commit.message
|
16
|
+
end
|
17
|
+
|
18
|
+
def messages(name, source_repo)
|
19
|
+
if ! File.exists?(name)
|
20
|
+
Mercurial::Repository.clone(source_repo, name, {})
|
21
|
+
end
|
22
|
+
repo = Mercurial::Repository.open(name)
|
23
|
+
repo.pull
|
24
|
+
return repo.commits
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
@@ -0,0 +1,105 @@
|
|
1
|
+
require "json"
|
2
|
+
require "open-uri"
|
3
|
+
|
4
|
+
require "gems-status/gem_checker"
|
5
|
+
require "gems-status/git_check_messages"
|
6
|
+
require "gems-status/hg_check_messages"
|
7
|
+
require "gems-status/svn_check_messages"
|
8
|
+
require "gems-status/scm_security_messages"
|
9
|
+
|
10
|
+
class NotASecurityAlertChecker < GemChecker
|
11
|
+
def initialize(conf)
|
12
|
+
Utils::check_parameters('NotASecurityAlertChecker', conf, ["fixed", "source_repos"])
|
13
|
+
@fixed = conf["fixed"]
|
14
|
+
@source_repos = conf["source_repos"]
|
15
|
+
@security_messages = {}
|
16
|
+
end
|
17
|
+
|
18
|
+
def check?(gem)
|
19
|
+
@security_messages = {}
|
20
|
+
version = gem.version
|
21
|
+
source_repo = source_repo(gem)
|
22
|
+
if ! source_repo
|
23
|
+
Utils::log_error gem.name, "Not source URL for #{gem.name}"
|
24
|
+
@security_messages = {gem.name => "Not source URL for #{gem.name}"}
|
25
|
+
return false
|
26
|
+
end
|
27
|
+
Utils::log_debug "Source URL for #{gem.name} #{source_repo}"
|
28
|
+
look_for_security_messages(gem.name, source_repo)
|
29
|
+
filter_security_messages_already_fixed(gem.version)
|
30
|
+
return @security_messages.length == 0
|
31
|
+
end
|
32
|
+
|
33
|
+
def description
|
34
|
+
result = ""
|
35
|
+
@security_messages.keys.sort.each do |k|
|
36
|
+
result = result + "[#{k}] - #{@security_messages[k]}<br/>"
|
37
|
+
end
|
38
|
+
result = "Security alerts:" + result if result!=""
|
39
|
+
return result
|
40
|
+
end
|
41
|
+
|
42
|
+
private
|
43
|
+
|
44
|
+
def filter_security_messages_already_fixed(version)
|
45
|
+
@security_messages.delete_if do |k,v|
|
46
|
+
@fixed[k] && Gem::Version.new(@fixed[k]) <= version
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def source_repo(gem)
|
51
|
+
if @source_repos[gem.name]
|
52
|
+
return @source_repos[gem.name]
|
53
|
+
end
|
54
|
+
begin
|
55
|
+
gem_version_information = JSON.parse(open("http://rubygems.org/api/v1/gems/#{gem.name}.json").read)
|
56
|
+
rescue => e
|
57
|
+
Utils::log_error gem.name, "There was a problem downloading info for #{gem.name} #{e.to_s}"
|
58
|
+
return nil
|
59
|
+
end
|
60
|
+
uri = nil
|
61
|
+
if gem_version_information["project_uri"] &&
|
62
|
+
gem_version_information["project_uri"].include?("github")
|
63
|
+
uri = gem_version_information["project_uri"]
|
64
|
+
end
|
65
|
+
if gem_version_information["homepage_uri"] &&
|
66
|
+
gem_version_information["homepage_uri"].include?("github")
|
67
|
+
uri = gem_version_information["homepage_uri"]
|
68
|
+
end
|
69
|
+
if gem_version_information["source_code_uri"] &&
|
70
|
+
gem_version_information["source_code_uri"].include?("github")
|
71
|
+
uri = gem_version_information["source_code_uri"]
|
72
|
+
end
|
73
|
+
return uri
|
74
|
+
end
|
75
|
+
|
76
|
+
def look_for_security_messages(name, source_repo, counter = 0)
|
77
|
+
Utils::log_debug "looking for security messages on #{source_repo}"
|
78
|
+
if ! File.exists?("build_security_messages_check")
|
79
|
+
Dir.mkdir("build_security_messages_check")
|
80
|
+
end
|
81
|
+
Dir.chdir("build_security_messages_check") do
|
82
|
+
if ! File.exists?(name)
|
83
|
+
Dir.mkdir(name)
|
84
|
+
end
|
85
|
+
Dir.chdir(name) do
|
86
|
+
if source_repo.include?("git")
|
87
|
+
scmCheckMessages = GitCheckMessages.new
|
88
|
+
Utils::log_debug "git repo"
|
89
|
+
elsif source_repo.include?("svn")
|
90
|
+
scmCheckMessages = SvnCheckMessages.new
|
91
|
+
Utils::log_debug "svn repo"
|
92
|
+
elsif source_repo.include?("bitbucket")
|
93
|
+
scmCheckMessages = HgCheckMessages.new
|
94
|
+
Utils::log_debug "mercurial repo"
|
95
|
+
else
|
96
|
+
Utils::log_error name, "Not a valid source repo #{source_repo}"
|
97
|
+
return {}
|
98
|
+
end
|
99
|
+
@security_messages = scmCheckMessages.check_messages(name, source_repo,
|
100
|
+
ScmSecurityMessages.new)
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
end
|
@@ -4,7 +4,7 @@ require 'open-uri'
|
|
4
4
|
require 'gems-status/gem_checker'
|
5
5
|
|
6
6
|
class NotNativeGemChecker < GemChecker
|
7
|
-
def
|
7
|
+
def check?(gem)
|
8
8
|
result = nil
|
9
9
|
gem_uri = URI.parse("#{gem.gems_url}/#{gem.name}-#{gem.version}.gem" )
|
10
10
|
uri_debug = gem_uri.clone
|
@@ -33,7 +33,8 @@ class NotNativeGemChecker < GemChecker
|
|
33
33
|
return false unless result
|
34
34
|
return result.spec.extensions.empty?
|
35
35
|
end
|
36
|
-
|
36
|
+
|
37
|
+
def description
|
37
38
|
"This gem is a native gem or could not get specs: "
|
38
39
|
end
|
39
40
|
end
|
@@ -5,7 +5,7 @@ require 'gems-status/gem_checker'
|
|
5
5
|
|
6
6
|
class NotRailsChecker < GemChecker
|
7
7
|
RAILS_GEMS = ["rails", "railties","activesupport"]
|
8
|
-
def
|
8
|
+
def check?(gem)
|
9
9
|
return false if !gem.dependencies
|
10
10
|
gem.dependencies.each do |dep|
|
11
11
|
if RAILS_GEMS.include?(dep.name)
|
@@ -15,7 +15,7 @@ class NotRailsChecker < GemChecker
|
|
15
15
|
return true
|
16
16
|
end
|
17
17
|
|
18
|
-
def
|
18
|
+
def description
|
19
19
|
"This gem depends on rails or could not get spec: "
|
20
20
|
end
|
21
21
|
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
class ScmCheckMessages
|
2
|
+
MAX_RETRIES = 3
|
3
|
+
@@keys = {}
|
4
|
+
|
5
|
+
def check_messages(name, source_repo, message_checker, counter = 0)
|
6
|
+
begin
|
7
|
+
messages = messages(name, source_repo)
|
8
|
+
return security_alerts(name, messages, message_checker)
|
9
|
+
rescue => e
|
10
|
+
if counter == MAX_RETRIES
|
11
|
+
Utils::log_error name, "There was a problem checking out #{source_repo} #{e}"
|
12
|
+
return {}
|
13
|
+
else
|
14
|
+
Utils::log_debug "There was a problem checking out #{source_repo} #{e}: Trying it again..."
|
15
|
+
return check_messages(name, source_repo, message_checker, counter + 1)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def security_alerts(name, commits, message_checker)
|
23
|
+
results = {}
|
24
|
+
commits.each do |commit|
|
25
|
+
if message_checker.check_message?(message(commit))
|
26
|
+
Utils::log_debug "#{message(commit)}"
|
27
|
+
key = next_key(name)
|
28
|
+
Utils::log_debug "security key: #{key}"
|
29
|
+
results[key] = message(commit)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
return results
|
33
|
+
end
|
34
|
+
|
35
|
+
def next_key(name)
|
36
|
+
@@keys[name] = 0 unless @@keys[name]
|
37
|
+
key = name + @@keys[name].to_s
|
38
|
+
@@keys[name] = @@keys[name] + 1
|
39
|
+
return key
|
40
|
+
end
|
41
|
+
|
42
|
+
def message(commit)
|
43
|
+
raise NotImplementedError
|
44
|
+
end
|
45
|
+
|
46
|
+
def messages(name, source_repo)
|
47
|
+
raise NotImplementedError
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require "gems-status/scm_check_messages"
|
2
|
+
|
3
|
+
class SvnCheckMessages < ScmCheckMessages
|
4
|
+
|
5
|
+
private
|
6
|
+
|
7
|
+
def message(commit)
|
8
|
+
return commit
|
9
|
+
end
|
10
|
+
|
11
|
+
def messages(name, source_repo)
|
12
|
+
if ! File.exists?(svn_dir(source_repo))
|
13
|
+
`svn checkout #{source_repo}`
|
14
|
+
end
|
15
|
+
Dir.chdir(svn_dir(source_repo)) do
|
16
|
+
`svn update`
|
17
|
+
log_messages = `svn log`
|
18
|
+
return log_messages.split("\n")
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def svn_dir(source_repo)
|
23
|
+
source_repo_splitted = URI.parse(source_repo).path.split("/")
|
24
|
+
return source_repo_splitted[-1]
|
25
|
+
end
|
26
|
+
end
|
data/test/gem_graph.png
ADDED
Binary file
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: gems-status
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 3
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
|
-
-
|
8
|
+
- 7
|
9
9
|
- 0
|
10
|
-
version: 0.
|
10
|
+
version: 0.7.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Jordi Massaguer Pla
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2012-
|
18
|
+
date: 2012-05-14 00:00:00 Z
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
21
21
|
name: xml-simple
|
@@ -61,14 +61,20 @@ files:
|
|
61
61
|
- lib/gems-status/lockfile_gems.rb
|
62
62
|
- lib/gems-status/ruby_gems_gems_gem_simple.rb
|
63
63
|
- lib/gems-status/not_native_gem_checker.rb
|
64
|
+
- lib/gems-status/svn_check_messages.rb
|
64
65
|
- lib/gems-status/gems_composite_command.rb
|
66
|
+
- lib/gems-status/scm_security_messages.rb
|
67
|
+
- lib/gems-status/scm_check_messages.rb
|
68
|
+
- lib/gems-status/git_check_messages.rb
|
65
69
|
- lib/gems-status/gems_status_metadata.rb
|
70
|
+
- lib/gems-status/hg_check_messages.rb
|
66
71
|
- lib/gems-status/gem_checker.rb
|
67
72
|
- lib/gems-status/exists_in_upstream.rb
|
68
73
|
- lib/gems-status/not_rails_checker.rb
|
69
74
|
- lib/gems-status/view_results.rb
|
70
75
|
- lib/gems-status/obs_gems.rb
|
71
76
|
- lib/gems-status/gems_command.rb
|
77
|
+
- lib/gems-status/not_a_security_alert_checker.rb
|
72
78
|
- lib/gems-status/utils.rb
|
73
79
|
- bin/gems-status
|
74
80
|
- test/Gemfile.lock.test
|
@@ -81,6 +87,7 @@ files:
|
|
81
87
|
- test/test-obs_gems.rb
|
82
88
|
- test/Gemfile.lock
|
83
89
|
- test/Gemfile
|
90
|
+
- test/gem_graph.png
|
84
91
|
homepage: http://github.com/jordimassaguerpla/gems-status
|
85
92
|
licenses: []
|
86
93
|
|
@@ -110,7 +117,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
110
117
|
requirements: []
|
111
118
|
|
112
119
|
rubyforge_project:
|
113
|
-
rubygems_version: 1.8.
|
120
|
+
rubygems_version: 1.8.11
|
114
121
|
signing_key:
|
115
122
|
specification_version: 3
|
116
123
|
summary: compares rubygems from different sources
|