From 741ab18a6635043b52da733dfa4d6964e1634a4a Mon Sep 17 00:00:00 2001 From: Jared Date: Mon, 12 May 2025 21:03:36 -0500 Subject: [PATCH 1/4] [JAR-16] adding the ability to parse for dev dependencies --- lib/orion/gems/parser.rb | 34 ++++++++++++++++++++++++++++++++-- lib/orion/gems/security.rb | 14 ++++++++++++-- 2 files changed, 44 insertions(+), 4 deletions(-) diff --git a/lib/orion/gems/parser.rb b/lib/orion/gems/parser.rb index 70b9d35..26235b4 100644 --- a/lib/orion/gems/parser.rb +++ b/lib/orion/gems/parser.rb @@ -17,12 +17,19 @@ def initialize(lockfile:, include_dev: false) def run content = File.read(@lockfile) parser = Bundler::LockfileParser.new(content) - security = Orion::Gems::Security.new(lockfile: @lockfile) + security = Orion::Gems::Security.new(lockfile: @lockfile, include_dev: @include_dev) + + dev_dependencies = extract_dev_dependencies + vuln_map = security.vulnerable_gems_map vulnerabilities = security.detailed_vulnerabilities - analyzed_gems = parser.specs.map do |spec| + analyzed_gems = parser.specs.filter_map do |spec| + is_dev = dev_dependencies.include?(spec.name) + + next if is_dev && !@include_dev + { name: spec.name, version: spec.version.to_s, @@ -96,6 +103,29 @@ def export_gem_report(gems, vulns, include_vulns: false, filename: "orion_gem_re write_out(dir, "#{filename}.csv", data) end end + + def extract_dev_dependencies + return [] unless @include_dev + + # assumption here is that Gemfile is next to lockfile + lockfile_path = Pathname.new(@lockfile).dirname.to_s + gemfile_path = File.join(lockfile_path, "Gemfile") + + unless File.exist?(gemfile_path) + warn "[orion]: Gemfile not found at #{gemfile_path}. Skipping dev dependency analysis." + return [] + end + + begin + definition = Bundler::Definition.build(gemfile_path, @lockfile, nil) + definition.dependencies + .select { |dep| dep.groups.include?(:development) } + .map(&:name) + rescue => e + warn "[orion]: Failed to parse Gemfile for dev dependencies: #{e.class} - #{e.message}" + [] + end + end end end end diff --git a/lib/orion/gems/security.rb b/lib/orion/gems/security.rb index da4ead8..846b111 100644 --- a/lib/orion/gems/security.rb +++ b/lib/orion/gems/security.rb @@ -5,9 +5,11 @@ module Orion module Gems class Security - def initialize(lockfile:) + def initialize(lockfile:, include_dev: false, dev_dependencies: nil) @lockfile = lockfile @lockfile_dir = Pathname.new(@lockfile).dirname.to_s + @include_dev = include_dev + @dev_dependencies = dev_dependencies || [] @scan_results = nil begin @@ -27,12 +29,16 @@ def scan! def vulnerable_gems_map scan!.each_with_object({}) do |result, hash| + next if skip_dev_gem?(result.gem.name) + hash[result.gem.name] = true end end def detailed_vulnerabilities - scan!.map do |result| + scan!.filter_map do |result| + next if skip_dev_gem?(result.gem.name) + { name: result.gem.name, advisory: result.advisory.title, @@ -42,6 +48,10 @@ def detailed_vulnerabilities } end end + + def skip_dev_gem?(name) + !@include_dev && @dev_dependencies.include?(name) + end end end end From ae5f8ba669a802591871628dd42ecac313873fd1 Mon Sep 17 00:00:00 2001 From: Jared Date: Mon, 12 May 2025 21:10:42 -0500 Subject: [PATCH 2/4] [JAR-16] up version for new feature --- lib/orion/version.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/orion/version.rb b/lib/orion/version.rb index c8ae28d..d4f9344 100644 --- a/lib/orion/version.rb +++ b/lib/orion/version.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true module Orion - VERSION = "0.5.1" + VERSION = "0.6.1" end From 9f64a5f3409063d0a569e834dc5077de24c31010 Mon Sep 17 00:00:00 2001 From: Jared Date: Mon, 12 May 2025 22:20:28 -0500 Subject: [PATCH 3/4] [JAR-16] adding a nil guard for vulnerabilities --- lib/orion/gems/parser.rb | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/lib/orion/gems/parser.rb b/lib/orion/gems/parser.rb index 26235b4..3125007 100644 --- a/lib/orion/gems/parser.rb +++ b/lib/orion/gems/parser.rb @@ -17,17 +17,18 @@ def initialize(lockfile:, include_dev: false) def run content = File.read(@lockfile) parser = Bundler::LockfileParser.new(content) - security = Orion::Gems::Security.new(lockfile: @lockfile, include_dev: @include_dev) - dev_dependencies = extract_dev_dependencies + security = Orion::Gems::Security.new( + lockfile: @lockfile, + include_dev: @include_dev, + dev_dependencies: dev_dependencies + ) - - vuln_map = security.vulnerable_gems_map - vulnerabilities = security.detailed_vulnerabilities + vuln_map = security.vulnerable_gems_map || [] + vulnerabilities = security.detailed_vulnerabilities || [] analyzed_gems = parser.specs.filter_map do |spec| is_dev = dev_dependencies.include?(spec.name) - next if is_dev && !@include_dev { @@ -105,8 +106,6 @@ def export_gem_report(gems, vulns, include_vulns: false, filename: "orion_gem_re end def extract_dev_dependencies - return [] unless @include_dev - # assumption here is that Gemfile is next to lockfile lockfile_path = Pathname.new(@lockfile).dirname.to_s gemfile_path = File.join(lockfile_path, "Gemfile") From 5e8e6daa07d7d65fa87f26f151154cb54f3e4424 Mon Sep 17 00:00:00 2001 From: Jared Date: Mon, 12 May 2025 22:36:14 -0500 Subject: [PATCH 4/4] [JAR-16] adding release workflow for later use --- .github/workflows/release.yml | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 .github/workflows/release.yml diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..a6250ea --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,27 @@ +name: Release Gem + +on: + workflow_dispatch: + +jobs: + release: + name: Publish to RubyGems + runs-on: ubuntu-latest + environment: release-approval + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Set up Ruby + uses: ruby/setup-ruby@v1 + with: + ruby-version: '3.4.2' + bundler-cache: true + + - name: Build gem + run: gem build orion.gemspec + + - name: Publish to RubyGems + run: gem push orion-*.gem + env: + RUBYGEMS_API_KEY: ${{ secrets.RUBYGEMS_API_KEY }}