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 2ca7b4d  fix: Gemfile / Gemspec parser to ignore commented 
dependencies (#249)
2ca7b4d is described below

commit 2ca7b4de66bc42c76dc23a9a63a9899a31434fd1
Author: |7eter l-|. l3oling <[email protected]>
AuthorDate: Sun Sep 14 17:04:10 2025 +0700

    fix: Gemfile / Gemspec parser to ignore commented dependencies (#249)
---
 pkg/deps/ruby.go      | 19 +++++++++++++++----
 pkg/deps/ruby_test.go | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 65 insertions(+), 4 deletions(-)

diff --git a/pkg/deps/ruby.go b/pkg/deps/ruby.go
index 3b63e16..ec769fb 100644
--- a/pkg/deps/ruby.go
+++ b/pkg/deps/ruby.go
@@ -213,7 +213,7 @@ func hasGemspec(dir string) bool {
        return false
 }
 
-var gemspecRuntimeRe = 
regexp.MustCompile(`(?m)\badd_(?:runtime_)?dependency\s*\(?\s*["']([^"']+)["']`)
+var gemspecRuntimeRe = 
regexp.MustCompile(`\badd_(?:runtime_)?dependency\s*\(?\s*["']([^"']+)["']`)
 
 func runtimeDepsFromGemspecs(dir string) ([]string, error) {
        entries, err := os.ReadDir(dir)
@@ -225,15 +225,26 @@ func runtimeDepsFromGemspecs(dir string) ([]string, 
error) {
                if e.IsDir() || !strings.HasSuffix(e.Name(), ".gemspec") {
                        continue
                }
-               b, err := os.ReadFile(filepath.Join(dir, e.Name()))
+               path := filepath.Join(dir, e.Name())
+               f, err := os.Open(path)
                if err != nil {
                        return nil, err
                }
-               for _, m := range 
gemspecRuntimeRe.FindAllStringSubmatch(string(b), -1) {
-                       if len(m) == 2 {
+               scanner := bufio.NewScanner(f)
+               for scanner.Scan() {
+                       line := scanner.Text()
+                       trimLeft := strings.TrimLeft(line, " \t")
+                       if strings.HasPrefix(trimLeft, "#") {
+                               continue // ignore commented-out lines
+                       }
+                       if m := gemspecRuntimeRe.FindStringSubmatch(line); 
len(m) == 2 {
                                runtime[m[1]] = struct{}{}
                        }
                }
+               _ = f.Close()
+               if err := scanner.Err(); err != nil {
+                       return nil, err
+               }
        }
        res := make([]string, 0, len(runtime))
        for k := range runtime {
diff --git a/pkg/deps/ruby_test.go b/pkg/deps/ruby_test.go
index be96ce2..319991c 100644
--- a/pkg/deps/ruby_test.go
+++ b/pkg/deps/ruby_test.go
@@ -242,3 +242,53 @@ func 
TestRubyLibraryWithNoRuntimeDependenciesIncludesNone(t *testing.T) {
                t.Fatalf("expected 0 dependencies for library with no runtime 
deps, got %d", got)
        }
 }
+
+func TestGemspecIgnoresCommentedRuntimeDependencies(t *testing.T) {
+       resolver := new(GemfileLockResolver)
+
+       // Prepare a library project whose gemspec contains a commented runtime 
dependency line
+       dir := t.TempDir()
+       lockContent := "" +
+               "GEM\n" +
+               "  remote: https://rubygems.org/\n"; +
+               "  specs:\n" +
+               "    rake (13.0.6)\n" +
+               "\n" +
+               "PLATFORMS\n" +
+               "  ruby\n" +
+               "\n" +
+               "DEPENDENCIES\n" +
+               "  rake\n" +
+               "\n" +
+               "BUNDLED WITH\n" +
+               "   2.4.10\n"
+       if err := writeFileRuby(filepath.Join(dir, "Gemfile.lock"), 
lockContent); err != nil {
+               t.Fatal(err)
+       }
+
+       gemspec := "" +
+               "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" +
+               "  # spec.add_dependency(\"git\", \">= 1.19.1\")\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)
+       }
+
+       // There are no runtime dependencies in gemspec; the commented one must 
be ignored
+       if got := len(report.Resolved) + len(report.Skipped); got != 0 {
+               t.Fatalf("expected 0 dependencies when runtime deps are only 
commented, got %d", got)
+       }
+}

Reply via email to