dependency-timeline-audit 0.0.0 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
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: []