dependency-timeline-audit 0.0.0 → 0.0.2

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2e4a44a4760b883532f6bf9640b0df6f791e8a8518e8747e3078b0d17a39f540
4
- data.tar.gz: c2656213c2c3e337f3ad974a2488815a1c61040d62f84072d74b4f1cfbe427eb
3
+ metadata.gz: d4fb437a64c2b990372ff5137b6deb79d5405f5522e81b02830108cc43596155
4
+ data.tar.gz: 9edf8bfe737bb3991802e93c01d272aa786b4bd1dd8a6733c6de17099175b013
5
5
  SHA512:
6
- metadata.gz: a8b74f3e417d9460bebbaa784253b8579e3074c10e5910ff3642b25e49745f068c2b557079c0f3b9b74545a9d825fdaddd58b4bafaaef838ddf2a9f5bf213ba8
7
- data.tar.gz: 0e56d272cbc09eddd6cb043fa5659f265538e1f61f8ee7708ac1e237b5417f071a1ce7387e77e48517c298be10d5865e2797de7e78a6d569b1cd56e2ca8b3794
6
+ metadata.gz: 9e19239773413b37e23d54c21dd22cbbc65f65102f778d5437676da683fb76a202bf197f7b01e6ce874f8ce6761e53ccd7d9e2d9985a4096d46e9a86ae63e769
7
+ data.tar.gz: e52bc4921722fc2be009aed94f7009917d4034ccc48c4f130c4fac5651af46e482d58765fd0171c87ecdd2abb2431d479926de3be4b6dc9d8c08684cabf37374
@@ -0,0 +1,34 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'dependency-timeline-audit'
4
+ require 'optparse'
5
+
6
+ # See: https://docs.ruby-lang.org/en/master/OptionParser.html
7
+
8
+ begin
9
+ options = {}
10
+ OptionParser.new do |opts|
11
+ opts.banner = "Usage: dependency-timeline-audit [options]\n"
12
+
13
+ opts.on('-i', '--interactive-ignore', 'Allows interactively generating an ignore file')
14
+ opts.on('-v', '--verbose', 'Provides more verbose output')
15
+ opts.on('--lockfile=LOCKFILE', 'Allows overwriting where the lockfile is located (default: "Gemfile.lock")')
16
+ opts.on('--outdated-threshold=YEARS', Integer, 'Allows overwriting the number of years before a gem is considered outdated (default: 1)')
17
+ opts.on_tail('-h', '--help', 'Prints this help') do
18
+ puts opts
19
+ exit
20
+ end
21
+ opts.on('-V', '--version', 'Prints the version of dependency-timeline-audit') do
22
+ puts "Dependency Timeline Audit (Ruby) - version: #{DependencyTimelineAudit.gem_version}"
23
+ exit
24
+ end
25
+ end.parse!(into: options)
26
+ rescue OptionParser::InvalidOption, OptionParser::MissingArgument => e
27
+ puts e.message
28
+ exit(1)
29
+ end
30
+
31
+ DependencyTimelineAudit::Check.check(
32
+ lockfile: options[:lockfile],
33
+ verbose: options[:verbose]
34
+ )
@@ -0,0 +1,95 @@
1
+ require 'date'
2
+ require 'active_support/all'
3
+
4
+ module DependencyTimelineAudit
5
+ class Check
6
+ # TODO: activesupport is kinda hefty for just grabbing 1.year.ago, remove
7
+ def self.outdated_threshold
8
+ 1.year.ago
9
+ end
10
+
11
+ def self.check(lockfile: 'Gemfile.lock', verbose: true)
12
+ outdated_versions = []
13
+ locked_gems.each do |gem|
14
+ lock_released_at = GemInfo.version_created_at(gem[:name], gem[:locked_version])
15
+ latest_version = GemInfo.latest_version(gem[:name])
16
+ outdated_versions.push(gem[:name]) if gem_outdated?(lock_released_at)
17
+ print_info(gem, lock_released_at, latest_version) if verbose
18
+ end
19
+
20
+ print "\n" if verbose
21
+
22
+ if outdated_versions.any?
23
+ set_text_color_red
24
+ puts "Outdated gems detected!"
25
+ puts " - #{outdated_versions.join(', ')}"
26
+
27
+ exit(1) # Failure
28
+ else
29
+ reset_text_style
30
+ puts "All gems are within the accepted threshold!"
31
+
32
+ exit(0) # Success
33
+ end
34
+ end
35
+
36
+ private
37
+
38
+ def self.gem_outdated?(released_at)
39
+ released_at <= outdated_threshold
40
+ end
41
+
42
+ def self.print_info(gem, lock_released_at, latest_version)
43
+ puts "Gem: \e[1m#{gem[:name]}\e[0m"
44
+ set_text_color(lock_released_at, gem[:locked_version] == latest_version[:version])
45
+ puts " - Locked to: #{gem[:locked_version]} (Released: #{format_date(lock_released_at)})"
46
+ set_text_color(latest_version[:created_at])
47
+ puts " - Latest: #{latest_version[:version]} (Released: #{format_date(latest_version[:created_at])})"
48
+ reset_text_style
49
+ end
50
+
51
+ def self.set_text_color(released_at, using_latest = true)
52
+ if gem_outdated?(released_at)
53
+ set_text_color_red
54
+ else
55
+ if using_latest
56
+ set_text_color_green
57
+ else
58
+ set_text_color_yellow
59
+ end
60
+ end
61
+ end
62
+
63
+ def self.set_text_bold
64
+ print "\e[1m"
65
+ end
66
+
67
+ def self.set_text_color_red
68
+ print "\e[31m"
69
+ end
70
+
71
+ def self.set_text_color_green
72
+ print "\e[32m"
73
+ end
74
+
75
+ def self.set_text_color_yellow
76
+ print "\e[33m"
77
+ end
78
+
79
+ def self.reset_text_style
80
+ print "\e[0m"
81
+ end
82
+
83
+ def self.locked_gems
84
+ lockfile = Bundler::LockfileParser.new(File.read('Gemfile.lock'))
85
+ lockfile.specs.map do |gem|
86
+ { name: gem.name, locked_version: gem.version.to_s }
87
+ end
88
+ end
89
+
90
+ def self.format_date(date_string)
91
+ date = Date.parse(date_string)
92
+ date.strftime("%Y-%m-%d")
93
+ end
94
+ end
95
+ end
@@ -0,0 +1,41 @@
1
+ require 'net/http'
2
+ require 'json'
3
+
4
+ module DependencyTimelineAudit
5
+ # Define a class for interacting with the RubyGems API
6
+ class GemInfo
7
+ API_URL = 'https://rubygems.org/api/v1/versions/'
8
+ @@gem_cache = {}
9
+
10
+ # Method to fetch the gem data and cache it
11
+ def self.fetch_gem_data(gem_name)
12
+ # Check if gem info is already cached
13
+ unless @@gem_cache[gem_name]
14
+ url = URI("#{API_URL}#{gem_name}.json")
15
+ response = Net::HTTP.get(url)
16
+ @@gem_cache[gem_name] = JSON.parse(response)
17
+ end
18
+
19
+ # Return cached gem info
20
+ @@gem_cache[gem_name]
21
+ end
22
+
23
+ # Method to fetch the latest version and its created_at timestamp
24
+ def self.latest_version(gem_name)
25
+ versions = fetch_gem_data(gem_name)
26
+ latest = versions.first # The first entry is the latest version
27
+ version_number = latest['number']
28
+ created_at = latest['created_at']
29
+ { version: version_number, created_at: created_at }
30
+ end
31
+
32
+ # Method to fetch the created_at timestamp for a specific version
33
+ def self.version_created_at(gem_name, version)
34
+ versions = fetch_gem_data(gem_name)
35
+ # Find the version that matches the requested version string
36
+ version_info = versions.find { |v| v['number'] == version }
37
+
38
+ version_info.present? ? version_info['created_at'] : nil
39
+ end
40
+ end
41
+ end
@@ -2,7 +2,7 @@ module DependencyTimelineAudit
2
2
  module VERSION
3
3
  MAJOR = 0
4
4
  MINOR = 0
5
- PATCH = 0
5
+ PATCH = 2
6
6
 
7
7
  STRING = [MAJOR, MINOR, PATCH].join('.')
8
8
  end
@@ -1,4 +1,6 @@
1
1
  module DependencyTimelineAudit
2
+ autoload :Check, 'dependency-timeline-audit/check'
3
+ autoload :GemInfo, 'dependency-timeline-audit/gem_info'
2
4
  autoload :VERSION, 'dependency-timeline-audit/version'
3
5
 
4
6
  def self.gem_version
metadata CHANGED
@@ -1,22 +1,54 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dependency-timeline-audit
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.0
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Josh Buker
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-09-24 00:00:00.000000000 Z
12
- dependencies: []
11
+ date: 2024-09-26 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: activesupport
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: bundler
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'
13
41
  description: Provides a way to audit your dependencies based on release timeline.
14
42
  email: crypto@joshbuker.com
15
- executables: []
43
+ executables:
44
+ - dependency-timeline-audit
16
45
  extensions: []
17
46
  extra_rdoc_files: []
18
47
  files:
48
+ - bin/dependency-timeline-audit
19
49
  - lib/dependency-timeline-audit.rb
50
+ - lib/dependency-timeline-audit/check.rb
51
+ - lib/dependency-timeline-audit/gem_info.rb
20
52
  - lib/dependency-timeline-audit/version.rb
21
53
  homepage: https://github.com/CloudSecurityAlliance/Dependency-Timeline-Audit
22
54
  licenses:
@@ -24,7 +56,7 @@ licenses:
24
56
  metadata:
25
57
  bug_tracker_uri: https://github.com/CloudSecurityAlliance/Dependency-Timeline-Audit/issues
26
58
  rubygems_mfa_required: 'true'
27
- post_install_message:
59
+ post_install_message:
28
60
  rdoc_options: []
29
61
  require_paths:
30
62
  - lib
@@ -39,8 +71,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
39
71
  - !ruby/object:Gem::Version
40
72
  version: '0'
41
73
  requirements: []
42
- rubygems_version: 3.5.11
43
- signing_key:
74
+ rubygems_version: 3.3.5
75
+ signing_key:
44
76
  specification_version: 4
45
77
  summary: Dependency Timeline Audit Ruby Interface
46
78
  test_files: []