This is an automated email from the ASF dual-hosted git repository.
kezhenxu94 pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/skywalking-eyes.git
The following commit(s) were added to refs/heads/main by this push:
new 18cb362 GemfileLockResolver adjusted to exclude all specs when
runtime dependencies are empty (#208)
18cb362 is described below
commit 18cb362bacae99d5a5c940d67847b52e19741e85
Author: |7eter l-|. l3oling <[email protected]>
AuthorDate: Sat Sep 13 15:12:12 2025 +0700
GemfileLockResolver adjusted to exclude all specs when runtime dependencies
are empty (#208)
- regression test: Ruby library projects with no runtime dependencies do
not include development dependencies
---
pkg/deps/ruby.go | 13 ++++++------
pkg/deps/ruby_test.go | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 61 insertions(+), 7 deletions(-)
diff --git a/pkg/deps/ruby.go b/pkg/deps/ruby.go
index 2cebd3b..3b63e16 100644
--- a/pkg/deps/ruby.go
+++ b/pkg/deps/ruby.go
@@ -70,12 +70,11 @@ func (r *GemfileLockResolver) Resolve(lockfile string,
config *ConfigDeps, repor
if err != nil {
return err
}
- if len(runtimeRoots) == 0 {
- // Fallback: if not found, use DEPENDENCIES from
lockfile
- roots = deps
- } else {
- roots = runtimeRoots
- }
+ // Use only runtime dependencies from gemspec(s);
+ // Do not fallback to DEPENDENCIES
+ // A gem library inherits runtime dependencies ONLY from the
gemspec.
+ // All other dependencies are development only.
+ roots = runtimeRoots
} else {
// App: all declared dependencies are relevant
roots = deps
@@ -84,7 +83,7 @@ func (r *GemfileLockResolver) Resolve(lockfile string, config
*ConfigDeps, repor
// Compute the set of included gems
include := reachable(specs, roots)
// For app without explicit deps (rare), include all specs
- if len(roots) == 0 {
+ if !isLibrary && len(roots) == 0 {
for name := range specs {
include[name] = struct{}{}
}
diff --git a/pkg/deps/ruby_test.go b/pkg/deps/ruby_test.go
index c925cd0..be96ce2 100644
--- a/pkg/deps/ruby_test.go
+++ b/pkg/deps/ruby_test.go
@@ -187,3 +187,58 @@ func TestRubyMissingSpecIsSkippedGracefully(t *testing.T) {
t.Fatalf("expected missing_gem to be marked as skipped")
}
}
+
+func TestRubyLibraryWithNoRuntimeDependenciesIncludesNone(t *testing.T) {
+ resolver := new(GemfileLockResolver)
+
+ // Prepare a library project with a gemspec that has NO runtime
dependencies
+ dir := t.TempDir()
+ lockContent := "" +
+ "GEM\n" +
+ " remote: https://rubygems.org/\n" +
+ " specs:\n" +
+ " rake (13.0.6)\n" +
+ " rspec (3.10.0)\n" +
+ " rspec-core (~> 3.10)\n" +
+ " rspec-core (3.10.1)\n" +
+ "\n" +
+ "PLATFORMS\n" +
+ " ruby\n" +
+ "\n" +
+ "DEPENDENCIES\n" +
+ " rake\n" +
+ " rspec\n" +
+ "\n" +
+ "BUNDLED WITH\n" +
+ " 2.4.10\n"
+ if err := writeFileRuby(filepath.Join(dir, "Gemfile.lock"),
lockContent); err != nil {
+ t.Fatal(err)
+ }
+
+ gemspec := "" +
+ "# minimal gemspec without runtime dependencies\n" +
+ "Gem::Specification.new do |spec|\n" +
+ " spec.name = \"sample\"\n" +
+ " spec.version = \"0.1.0\"\n" +
+ " spec.summary = \"Sample gem\"\n" +
+ " spec.description = \"Sample\"\n" +
+ " spec.authors = [\"Test\"]\n" +
+ " spec.files = []\n" +
+ " # only development dependency present\n" +
+ " spec.add_development_dependency 'rspec', '~> 3.10'\n" +
+ "end\n"
+ if err := writeFileRuby(filepath.Join(dir, "sample.gemspec"), gemspec);
err != nil {
+ t.Fatal(err)
+ }
+
+ lock := filepath.Join(dir, "Gemfile.lock")
+ cfg := &ConfigDeps{Files: []string{lock}}
+ report := Report{}
+ if err := resolver.Resolve(lock, cfg, &report); err != nil {
+ t.Fatal(err)
+ }
+
+ if got := len(report.Resolved) + len(report.Skipped); got != 0 {
+ t.Fatalf("expected 0 dependencies for library with no runtime
deps, got %d", got)
+ }
+}