pboling commented on code in PR #255:
URL: https://github.com/apache/skywalking-eyes/pull/255#discussion_r2636576470


##########
pkg/deps/ruby.go:
##########
@@ -116,12 +133,104 @@ func (r *GemfileLockResolver) Resolve(lockfile string, 
config *ConfigDeps, repor
        return nil
 }
 
+// GemspecResolver resolves dependencies from a .gemspec file.
+// It extracts runtime dependencies defined in the gemspec and recursively 
resolves
+// their transitive dependencies by looking up installed gems in the local 
environment.
+type GemspecResolver struct {
+       Resolver
+}
+
+// CanResolve checks if the given file is a .gemspec file.
+func (r *GemspecResolver) CanResolve(file string) bool {
+       return strings.HasSuffix(file, ".gemspec")
+}
+
+// Resolve parses the gemspec file, identifies runtime dependencies, and 
resolves
+// them along with their transitive dependencies. It reports the found 
dependencies
+// and their licenses.
+func (r *GemspecResolver) Resolve(file string, config *ConfigDeps, report 
*Report) error {
+       f, err := os.Open(file)
+       if err != nil {
+               return err
+       }
+       defer f.Close()
+
+       scanner := bufio.NewScanner(f)
+       deps := make(map[string]string) // name -> version constraint
+       for scanner.Scan() {
+               line := scanner.Text()
+               trimLeft := strings.TrimLeft(line, " \t")
+               if strings.HasPrefix(trimLeft, "#") {
+                       continue
+               }
+               if m := gemspecRuntimeRe.FindStringSubmatch(line); len(m) == 2 {
+                       deps[m[1]] = "" // We don't extract version constraint 
yet, or we could improve regex
+               }
+       }
+       if err := scanner.Err(); err != nil {
+               return err
+       }
+
+       // Recursive resolution
+       queue := make([]string, 0, len(deps))
+       visited := make(map[string]struct{}, len(deps))
+       for name := range deps {
+               queue = append(queue, name)
+               visited[name] = struct{}{}
+       }
+
+       for i := 0; i < len(queue); i++ {
+               name := queue[i]
+               // Find installed gemspec for 'name'
+               path, err := findInstalledGemspec(name, "")
+               if err == nil && path != "" {
+                       // Parse dependencies of this gemspec
+                       newDeps, err := parseGemspecDependencies(path)
+                       if err == nil {
+                               for _, dep := range newDeps {
+                                       if _, ok := visited[dep]; !ok {
+                                               visited[dep] = struct{}{}
+                                               queue = append(queue, dep)
+                                               if _, ok := deps[dep]; !ok {
+                                                       deps[dep] = ""
+                                               }
+                                       }
+                               }
+                       }
+               }
+       }
+
+       for name, version := range deps {
+               if exclude, _ := config.IsExcluded(name, version); exclude {
+                       continue
+               }
+               if l, ok := config.GetUserConfiguredLicense(name, version); ok {
+                       report.Resolve(&Result{Dependency: name, LicenseSpdxID: 
l, Version: version})
+                       continue
+               }
+
+               // Assume remote dependency
+               licenseID := fetchInstalledLicense(name, version)
+               var err error
+               if licenseID == "" {
+                       licenseID, err = fetchRubyGemsLicense(name, version)
+               }

Review Comment:
   Fixed in 0fb3ded



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to