Repository: licensee/licensed (Ruby)

Issue:
license = none in cache when ruby gem doesn't include License files but has license in gemspec

**steps to reproduce**

1. create all below files under dir x

Gemfile:
```
# frozen_string_literal:true
source "https://rubygems.org"
gem 'aws-sdk-core', '3.39.0'
gem 'licensed', :group => 'development'
```
Gemfile.lock:
```
GEM
  remote: https://rubygems.org/
  specs:
    addressable (2.5.2)
      public_suffix (>= 2.0.2, < 4.0)
    aws-eventstream (1.0.1)
    aws-partitions (1.142.0)
    aws-sdk-core (3.39.0)
      aws-eventstream (~> 1.0)
      aws-partitions (~> 1.0)
      aws-sigv4 (~> 1.0)
      jmespath (~> 1.0)
    aws-sigv4 (1.0.3)
    dotenv (2.7.1)
    faraday (0.15.4)
      multipart-post (>= 1.2, < 3)
    jmespath (1.4.0)
    licensed (2.0.1)
      bundler (>= 1.10)
      licensee (~> 9.10)
      pathname-common_prefix (~> 0.0.1)
      thor (~> 0.19)
      tomlrb (~> 1.2)
    licensee (9.11.0)
      dotenv (~> 2.0)
      octokit (~> 4.8.0)
      rugged (~> 0.24)
      thor (~> 0.19)
    multipart-post (2.0.0)
    octokit (4.8.0)
      sawyer (~> 0.8.0, >= 0.5.3)
    pathname-common_prefix (0.0.1)
    public_suffix (3.0.3)
    rugged (0.28.0)
    sawyer (0.8.1)
      addressable (>= 2.3.5, < 2.6)
      faraday (~> 0.8, < 1.0)
    thor (0.20.3)
    tomlrb (1.2.8)

PLATFORMS
  ruby

DEPENDENCIES
  aws-sdk-core (= 3.39.0)
  licensed

BUNDLED WITH
   2.0.1
```

licensed.yaml:
```
sources:
  bundler: true
```

2. navigate to directory x and run `licensed cache -c licensed.yaml`

**Issue:**

`.licenses/bundler/aws-sdk-*.dep.yml` are created with license set to none. ex:

```
---
name: aws-sdk-core
version: 3.46.1
type: bundler
summary: AWS SDK for Ruby - Core
homepage: http://github.com/aws/aws-sdk-ruby
license: none
licenses: []
notices: []
```

if one does `gem specification aws-sdk-core` you'd get yml containing licenses (since it is part of gemspec).  i.e.

```
...
licenses:
- Apache-2.0
...
```

would it be advisable to change licensed to fallback to using gemspec to:

1. retrieve the license from the gemspec metadata
2. try to find the license text using the gem homepage . ex: http://github.com/aws/aws-sdk-ruby

or is this something that needs to be reported to **licensee** project to properly handle this case ? 








Discussion:
/cc @benbalter @mlinksva do you have an opinion here?

IIRC `licensee` handles pulling data from project files like `*.gemspec` as a backup if other explicit license file contents aren't found, however I'm not sure how to tell `licensee` to look at both the gem's expanded location on disk as well as the gemspec file when they are in two different locations.  💭 ?
It seems the `aws-*` gems get installed (e.g., in `~/.rbenv/versions/2.5.3/lib/ruby/gems/2.5.0/gems`) with neither a `LICENSE` file nor a `.gemspec` file. I haven't looked into why this is the case, but the result is that licesne[ed] have nothing to work with locally. Compare with jmespath, which is also installed given the example files above, and licensed records the license found in its `LICENSE.txt`.



My understanding of RubyGems is obviously tenuous and I don't read closely...noting `gem specification aws-sdk-core` does find what ought to be in the gemspec file, I see that gemspec files for every installed gem are in (for my local case) `~/.rbenv/versions/2.5.3/lib/ruby/gems/2.5.0/specifications`. I guess that's what you were getting at @jonabc. I'm not sure either. I guess that it could make sense to look there as a fallback in `licensed` rather than `licensee`.
Ok, so to build on that.  If this is being handled by licensed, I think the best method to do so would be a `Bundler::Dependency` subclass that overrides [Project#package_manager_file](https://github.com/licensee/licensee/blob/da21bba0352f8086920ec59e61c8dbd93f4f0e6d/lib/licensee/projects/project.rb#L86-L99) and returns data for the gemspec file if the base implementation doesn't find a file and the spec file exists in the gem specifications directory.



Patch:
diff --git a/lib/licensed/sources/bundler.rb b/lib/licensed/sources/bundler.rb
index 41d09792..a619fefc 100644
--- a/lib/licensed/sources/bundler.rb
+++ b/lib/licensed/sources/bundler.rb
@@ -36,6 +36,34 @@ def error
         end
       end
 
+      class Dependency < Licensed::Dependency
+        attr_reader :loaded_from
+
+        def initialize(name:, version:, path:, loaded_from:, errors: [], metadata: {})
+          @loaded_from = loaded_from
+          super name: name, version: version, path: path, errors: errors, metadata: metadata
+        end
+
+        # Load a package manager file from the base Licensee::Projects::FsProject
+        # or from a gem specification file.
+        def package_file
+          super || spec_file
+        end
+
+        private
+
+        # Find a package manager file from the given bundler specification's
+        # `loaded_from` if available.
+        def spec_file
+          return @spec_file if defined?(@spec_file)
+          return @spec_file = nil unless loaded_from && File.exist?(loaded_from)
+          @spec_file = begin
+            file = { name: File.basename(loaded_from), dir: File.dirname(loaded_from) }
+            Licensee::ProjectFiles::PackageManagerFile.new(File.read(loaded_from), file)
+          end
+        end
+      end
+
       GEMFILES = %w{Gemfile gems.rb}.freeze
       DEFAULT_WITHOUT_GROUPS = %i{development test}
 
@@ -50,10 +78,11 @@ def enumerate_dependencies
         with_local_configuration do
           specs.map do |spec|
             error = spec.error if spec.respond_to?(:error)
-            Licensed::Dependency.new(
+            Dependency.new(
               name: spec.name,
               version: spec.version.to_s,
               path: spec.gem_dir,
+              loaded_from: spec.loaded_from,
               errors: Array(error),
               metadata: {
                 "type"     => Bundler.type,


Test patch:
diff --git a/test/fixtures/bundler/Gemfile b/test/fixtures/bundler/Gemfile
index e73e9380..5ba451e6 100644
--- a/test/fixtures/bundler/Gemfile
+++ b/test/fixtures/bundler/Gemfile
@@ -28,3 +28,6 @@ gem "pathed-gem-fixture", path: "pathed-gem-fixture"
 # verify https://github.com/github/licensed/issues/71
 git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }
 gem "mini_racer"
+
+# verify https://github.com/github/licensed/issues/153
+gem "aws-sdk-core", "3.39.0"
diff --git a/test/sources/bundler_test.rb b/test/sources/bundler_test.rb
index 1a612fcc..744402ae 100644
--- a/test/sources/bundler_test.rb
+++ b/test/sources/bundler_test.rb
@@ -207,6 +207,15 @@
           end
         end
       end
+
+      it "finds license metadata when gems are shipped without a gemspec" do
+        Dir.chdir(fixtures) do
+          dep = source.dependencies.find { |d| d.name == "aws-sdk-core" }
+          assert dep
+          assert_equal "3.39.0", dep.version
+          assert_equal "apache-2.0", dep.license_key
+        end
+      end
     end
 
     describe "bundler_exe" do