gems_bond 1.0.4 → 1.1.0

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.
@@ -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
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module GemsBond
4
- VERSION = "1.0.4"
4
+ VERSION = "1.1.0"
5
5
  end
@@ -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
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-01-29 00:00:00.000000000 Z
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/examination_helper.rb
51
- - lib/gems_bond/fetch_helper.rb
52
- - lib/gems_bond/fetcher/github.rb
53
- - lib/gems_bond/fetcher/ruby_gems.rb
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/printer.rb
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.0.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
@@ -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