gems_bond 1.0.4 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/gems_bond.rb +3 -2
- data/lib/gems_bond/configuration.rb +2 -0
- data/lib/gems_bond/{examination_helper.rb → examination.rb} +30 -18
- data/lib/gems_bond/fetchers/fetcher.rb +34 -0
- data/lib/gems_bond/{fetcher → fetchers}/github.rb +54 -10
- data/lib/gems_bond/fetchers/ruby_gems.rb +82 -0
- data/lib/gems_bond/gem.rb +128 -10
- data/lib/gems_bond/helpers/concurrency_helper.rb +24 -0
- data/lib/gems_bond/helpers/formatting_helper.rb +48 -0
- data/lib/gems_bond/printers/csv.rb +54 -0
- data/lib/gems_bond/printers/html.rb +61 -0
- data/lib/gems_bond/printers/printer.rb +58 -0
- data/lib/gems_bond/printers/stdout.rb +90 -0
- data/lib/gems_bond/railtie.rb +2 -1
- data/lib/gems_bond/spy/all.rb +93 -0
- data/lib/gems_bond/spy/one.rb +59 -0
- data/lib/gems_bond/version.rb +1 -1
- data/lib/tasks/gems_bond/spy/all.rake +36 -0
- data/lib/tasks/gems_bond/spy/one.rake +29 -0
- metadata +17 -10
- data/lib/gems_bond/fetch_helper.rb +0 -71
- data/lib/gems_bond/fetcher/ruby_gems.rb +0 -58
- data/lib/gems_bond/printer.rb +0 -88
- data/lib/gems_bond/spy.rb +0 -62
- data/lib/tasks/gems_bond/spy.rake +0 -34
@@ -0,0 +1,59 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "gems_bond/gem"
|
4
|
+
require "gems_bond/printers/stdout"
|
5
|
+
|
6
|
+
module GemsBond
|
7
|
+
module Spy
|
8
|
+
# Inspects gem and outputs the result in terminal
|
9
|
+
class One
|
10
|
+
PRELOAD_KEYS = %i[
|
11
|
+
contributors_count
|
12
|
+
days_since_last_commit
|
13
|
+
days_since_last_version
|
14
|
+
downloads_count
|
15
|
+
forks_count
|
16
|
+
source_code_uri
|
17
|
+
stars_count
|
18
|
+
versions
|
19
|
+
].freeze
|
20
|
+
|
21
|
+
# Initializes an instance
|
22
|
+
# @param name [String]
|
23
|
+
# @return [GemsBond::Spy::One]
|
24
|
+
def initialize(name)
|
25
|
+
@name = name
|
26
|
+
end
|
27
|
+
|
28
|
+
# Fetches gem then prints information
|
29
|
+
# @return [void]
|
30
|
+
def call
|
31
|
+
if gem.exist?
|
32
|
+
gem.prepare_data(keys: PRELOAD_KEYS, concurrency: false)
|
33
|
+
GemsBond::Printers::Stdout.new(gem).call
|
34
|
+
else
|
35
|
+
puts "Sorry, this gem could not be found!"
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
# Finds dependency corresponding to the name
|
42
|
+
# @return [Bundler::Dependency, nil]
|
43
|
+
def dependency
|
44
|
+
@dependency ||= Bundler.load.gems.find { |dep| dep.name == @name }
|
45
|
+
end
|
46
|
+
|
47
|
+
# Generates a gem instance
|
48
|
+
# @return [GemsBond::Gem]
|
49
|
+
def gem
|
50
|
+
if dependency
|
51
|
+
GemsBond::Gem.new(dependency)
|
52
|
+
else
|
53
|
+
unknown_dependency = Bundler::Dependency.new(@name, nil)
|
54
|
+
GemsBond::Gem.new(unknown_dependency, unknown: true)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
data/lib/gems_bond/version.rb
CHANGED
@@ -0,0 +1,36 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "gems_bond/spy/all"
|
4
|
+
|
5
|
+
begin
|
6
|
+
require "#{Rails.root}/config/initializers/gems_bond" if defined?(Rails)
|
7
|
+
rescue LoadError
|
8
|
+
nil
|
9
|
+
end
|
10
|
+
|
11
|
+
namespace :gems_bond do
|
12
|
+
namespace :spy do
|
13
|
+
desc "Investigates all gems and prints information"
|
14
|
+
task :all do
|
15
|
+
puts "Welcome, my name is Bond, Gems Bond."\
|
16
|
+
" I will do some spying on your gems for you…"
|
17
|
+
|
18
|
+
GemsBond.configure do |config|
|
19
|
+
# set github_token from ENV if given
|
20
|
+
config.github_token = ENV["GITHUB_TOKEN"] if ENV["GITHUB_TOKEN"]
|
21
|
+
end
|
22
|
+
|
23
|
+
unless GemsBond.configuration.github_token
|
24
|
+
puts "It seems that you didn’t provide any GitHub token."\
|
25
|
+
" This is necessary to fetch more data from GitHub,"\
|
26
|
+
" like the last commit date, the forks count, the size of the repository…"
|
27
|
+
|
28
|
+
puts "Please provide a GitHub token by adding it to the configuration"\
|
29
|
+
" or passing GITHUB_TOKEN=<token> when running the task."
|
30
|
+
exit
|
31
|
+
end
|
32
|
+
|
33
|
+
GemsBond::Spy::All.new.call
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "gems_bond/spy/one"
|
4
|
+
|
5
|
+
begin
|
6
|
+
require "#{Rails.root}/config/initializers/gems_bond" if defined?(Rails)
|
7
|
+
rescue LoadError
|
8
|
+
nil
|
9
|
+
end
|
10
|
+
|
11
|
+
namespace :gems_bond do
|
12
|
+
namespace :spy do
|
13
|
+
desc "Display information for the given gem"
|
14
|
+
task :one do
|
15
|
+
GemsBond.configure do |config|
|
16
|
+
# set github_token from ENV if given
|
17
|
+
config.github_token = ENV["GITHUB_TOKEN"] if ENV["GITHUB_TOKEN"]
|
18
|
+
end
|
19
|
+
|
20
|
+
ARGV.each { |a| task(a) }
|
21
|
+
name = ARGV[1]
|
22
|
+
if name
|
23
|
+
GemsBond::Spy::One.new(name).call
|
24
|
+
else
|
25
|
+
puts "Please provide the gem name, for example: `rake gems_bond:spy:one devise`"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: gems_bond
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Edouard Piron
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-03-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: gems
|
@@ -47,17 +47,24 @@ extra_rdoc_files: []
|
|
47
47
|
files:
|
48
48
|
- lib/gems_bond.rb
|
49
49
|
- lib/gems_bond/configuration.rb
|
50
|
-
- lib/gems_bond/
|
51
|
-
- lib/gems_bond/
|
52
|
-
- lib/gems_bond/
|
53
|
-
- lib/gems_bond/
|
50
|
+
- lib/gems_bond/examination.rb
|
51
|
+
- lib/gems_bond/fetchers/fetcher.rb
|
52
|
+
- lib/gems_bond/fetchers/github.rb
|
53
|
+
- lib/gems_bond/fetchers/ruby_gems.rb
|
54
54
|
- lib/gems_bond/gem.rb
|
55
|
-
- lib/gems_bond/
|
55
|
+
- lib/gems_bond/helpers/concurrency_helper.rb
|
56
|
+
- lib/gems_bond/helpers/formatting_helper.rb
|
57
|
+
- lib/gems_bond/printers/csv.rb
|
58
|
+
- lib/gems_bond/printers/html.rb
|
59
|
+
- lib/gems_bond/printers/printer.rb
|
60
|
+
- lib/gems_bond/printers/stdout.rb
|
56
61
|
- lib/gems_bond/railtie.rb
|
57
62
|
- lib/gems_bond/scores.yml
|
58
|
-
- lib/gems_bond/spy.rb
|
63
|
+
- lib/gems_bond/spy/all.rb
|
64
|
+
- lib/gems_bond/spy/one.rb
|
59
65
|
- lib/gems_bond/version.rb
|
60
|
-
- lib/tasks/gems_bond/spy.rake
|
66
|
+
- lib/tasks/gems_bond/spy/all.rake
|
67
|
+
- lib/tasks/gems_bond/spy/one.rake
|
61
68
|
- views/diagnosis.erb
|
62
69
|
homepage: https://github.com/BigBigDoudou/gems_bond
|
63
70
|
licenses:
|
@@ -80,7 +87,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
80
87
|
- !ruby/object:Gem::Version
|
81
88
|
version: '0'
|
82
89
|
requirements: []
|
83
|
-
rubygems_version: 3.
|
90
|
+
rubygems_version: 3.2.11
|
84
91
|
signing_key:
|
85
92
|
specification_version: 4
|
86
93
|
summary: Inspect gems
|
@@ -1,71 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "gems_bond/fetcher/ruby_gems"
|
4
|
-
require "gems_bond/fetcher/github"
|
5
|
-
|
6
|
-
module GemsBond
|
7
|
-
# Handles gem data
|
8
|
-
module FetchHelper
|
9
|
-
RUBY_GEM_KEYS = %i[
|
10
|
-
last_version_date
|
11
|
-
downloads_count
|
12
|
-
source_code_uri
|
13
|
-
versions
|
14
|
-
last_version
|
15
|
-
last_version_date
|
16
|
-
days_since_last_version
|
17
|
-
].freeze
|
18
|
-
|
19
|
-
GITHUB_KEYS = %i[
|
20
|
-
contributors_count
|
21
|
-
stars_count
|
22
|
-
forks_count
|
23
|
-
last_commit_date
|
24
|
-
open_issues_count
|
25
|
-
days_since_last_commit
|
26
|
-
].freeze
|
27
|
-
|
28
|
-
KEYS = RUBY_GEM_KEYS + GITHUB_KEYS
|
29
|
-
|
30
|
-
RUBY_GEM_KEYS.each do |key|
|
31
|
-
define_method(key) do
|
32
|
-
memoize(key) do
|
33
|
-
fetch(ruby_gems_fetcher, key)
|
34
|
-
end
|
35
|
-
end
|
36
|
-
end
|
37
|
-
|
38
|
-
GITHUB_KEYS.each do |key|
|
39
|
-
define_method(key) do
|
40
|
-
memoize(key) do
|
41
|
-
fetch(github_fetcher, key)
|
42
|
-
end
|
43
|
-
end
|
44
|
-
end
|
45
|
-
|
46
|
-
def fetch_all(verbose: false)
|
47
|
-
KEYS.each do |key|
|
48
|
-
__send__(key)
|
49
|
-
end
|
50
|
-
verbose && puts(name)
|
51
|
-
end
|
52
|
-
|
53
|
-
private
|
54
|
-
|
55
|
-
def fetch(fetcher, key)
|
56
|
-
fetcher&.public_send(key)
|
57
|
-
end
|
58
|
-
|
59
|
-
def ruby_gems_fetcher
|
60
|
-
return @ruby_gems_fetcher if defined?(@ruby_gems_fetcher)
|
61
|
-
|
62
|
-
@ruby_gems_fetcher = GemsBond::Fetcher::RubyGems.new(name).start
|
63
|
-
end
|
64
|
-
|
65
|
-
def github_fetcher
|
66
|
-
return @github_fetcher if defined?(@github_fetcher)
|
67
|
-
|
68
|
-
@github_fetcher = github_url && GemsBond::Fetcher::Github.new(github_url).start
|
69
|
-
end
|
70
|
-
end
|
71
|
-
end
|
@@ -1,58 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "gems"
|
4
|
-
require "rubygems"
|
5
|
-
|
6
|
-
module GemsBond
|
7
|
-
module Fetcher
|
8
|
-
# Fetches data from RubyGems
|
9
|
-
class RubyGems
|
10
|
-
def initialize(name)
|
11
|
-
@name = name
|
12
|
-
end
|
13
|
-
|
14
|
-
def source
|
15
|
-
"ruby gems"
|
16
|
-
end
|
17
|
-
|
18
|
-
def start
|
19
|
-
@info = Gems.info(@name)
|
20
|
-
self
|
21
|
-
rescue Gems::NotFound
|
22
|
-
nil
|
23
|
-
end
|
24
|
-
|
25
|
-
def downloads_count
|
26
|
-
Gems.total_downloads(@name)[:total_downloads]
|
27
|
-
end
|
28
|
-
|
29
|
-
def source_code_uri
|
30
|
-
@info["metadata"]["source_code_uri"]
|
31
|
-
end
|
32
|
-
|
33
|
-
def versions
|
34
|
-
Gems.versions(@name).map do |version|
|
35
|
-
{
|
36
|
-
number: version["number"],
|
37
|
-
created_at: Date.parse(version["created_at"]),
|
38
|
-
prerelease: version["prerelease"]
|
39
|
-
}
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
|
-
def last_version
|
44
|
-
versions&.first&.dig(:number)
|
45
|
-
end
|
46
|
-
|
47
|
-
def last_version_date
|
48
|
-
versions&.first&.dig(:created_at)
|
49
|
-
end
|
50
|
-
|
51
|
-
def days_since_last_version
|
52
|
-
return unless last_version_date
|
53
|
-
|
54
|
-
Date.today - last_version_date
|
55
|
-
end
|
56
|
-
end
|
57
|
-
end
|
58
|
-
end
|
data/lib/gems_bond/printer.rb
DELETED
@@ -1,88 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "erb"
|
4
|
-
require "fileutils"
|
5
|
-
|
6
|
-
module GemsBond
|
7
|
-
# Prints gems table
|
8
|
-
class Printer
|
9
|
-
MISSING = "-"
|
10
|
-
|
11
|
-
def initialize(gems)
|
12
|
-
@gems = gems
|
13
|
-
end
|
14
|
-
|
15
|
-
def call
|
16
|
-
puts "\nPreparing data for printing results..."
|
17
|
-
create_directory
|
18
|
-
File.open("gems_bond/spy.html", "w") do |file|
|
19
|
-
file.puts content
|
20
|
-
end
|
21
|
-
puts "Open file gems_bond/spy.html to display the results."
|
22
|
-
end
|
23
|
-
|
24
|
-
private
|
25
|
-
|
26
|
-
def create_directory
|
27
|
-
return if File.directory?("gems_bond")
|
28
|
-
|
29
|
-
FileUtils.mkdir_p("gems_bond")
|
30
|
-
end
|
31
|
-
|
32
|
-
def template
|
33
|
-
File.read(File.join(File.dirname(__FILE__), "../../views/", "diagnosis.erb"))
|
34
|
-
end
|
35
|
-
|
36
|
-
def content
|
37
|
-
ERB.new(template).result(binding)
|
38
|
-
end
|
39
|
-
|
40
|
-
def sorted_gems
|
41
|
-
# sort with putting gems without average_score at the end
|
42
|
-
@gems.sort do |a, b|
|
43
|
-
if a.average_score && b.average_score
|
44
|
-
a.average_score <=> b.average_score
|
45
|
-
else
|
46
|
-
a.average_score ? -1 : 1
|
47
|
-
end
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
51
|
-
def version_color(gap)
|
52
|
-
return "secondary" if gap.nil?
|
53
|
-
return "success" if gap.zero?
|
54
|
-
|
55
|
-
gap < 3 ? "warning" : "danger"
|
56
|
-
end
|
57
|
-
|
58
|
-
def color(score)
|
59
|
-
return "secondary" if score.nil?
|
60
|
-
|
61
|
-
if score < 0.33
|
62
|
-
"danger"
|
63
|
-
elsif score < 0.66
|
64
|
-
"warning"
|
65
|
-
else
|
66
|
-
"success"
|
67
|
-
end
|
68
|
-
end
|
69
|
-
|
70
|
-
def human_date(date)
|
71
|
-
return MISSING if date.nil?
|
72
|
-
|
73
|
-
date.strftime("%F")
|
74
|
-
end
|
75
|
-
|
76
|
-
def human_number(number)
|
77
|
-
return MISSING if number.nil?
|
78
|
-
|
79
|
-
number.to_s.gsub(/(\d)(?=(\d\d\d)+(?!\d))/, "\\1 ")
|
80
|
-
end
|
81
|
-
|
82
|
-
def human_score(score)
|
83
|
-
return MISSING if score.nil?
|
84
|
-
|
85
|
-
(score * 100).round
|
86
|
-
end
|
87
|
-
end
|
88
|
-
end
|
data/lib/gems_bond/spy.rb
DELETED
@@ -1,62 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "gems_bond/gem"
|
4
|
-
require "gems_bond/printer"
|
5
|
-
|
6
|
-
module GemsBond
|
7
|
-
# Inspects gems and outputs the result
|
8
|
-
class Spy
|
9
|
-
RETRIES = 2
|
10
|
-
|
11
|
-
def call
|
12
|
-
chrono do
|
13
|
-
fetch_gems
|
14
|
-
GemsBond::Printer.new(gems).call
|
15
|
-
end
|
16
|
-
end
|
17
|
-
|
18
|
-
def gems_count
|
19
|
-
@gems_count ||= gems.count
|
20
|
-
end
|
21
|
-
|
22
|
-
private
|
23
|
-
|
24
|
-
def chrono
|
25
|
-
start_at = Time.now
|
26
|
-
yield
|
27
|
-
seconds = Time.now - start_at
|
28
|
-
time_per_gem_text = "#{(seconds / Float(gems_count)).round(2)} second(s) per gem"
|
29
|
-
puts "\nIt took #{seconds} second(s) to spy #{gems_count} gem(s) (#{time_per_gem_text})."
|
30
|
-
end
|
31
|
-
|
32
|
-
def gems
|
33
|
-
@gems ||=
|
34
|
-
Bundler.load.current_dependencies.map do |dependency|
|
35
|
-
GemsBond::Gem.new(dependency)
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
|
-
def fetch_gems
|
40
|
-
puts "Fetching data for..."
|
41
|
-
gems.each_slice(100) do |batch|
|
42
|
-
threads = []
|
43
|
-
batch.each do |gem|
|
44
|
-
threads << gem_thread(gem)
|
45
|
-
end
|
46
|
-
threads.each(&:join)
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
|
-
def gem_thread(gem)
|
51
|
-
Thread.new do
|
52
|
-
begin
|
53
|
-
retries ||= 0
|
54
|
-
gem.fetch_all(verbose: true)
|
55
|
-
# rescue SocketError, Faraday::ConnectionFailed...
|
56
|
-
rescue StandardError
|
57
|
-
(retries += 1) <= RETRIES ? retry : nil
|
58
|
-
end
|
59
|
-
end
|
60
|
-
end
|
61
|
-
end
|
62
|
-
end
|