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.
@@ -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