New Upstream Release - ruby-license-finder

Ready changes

Summary

Merged new upstream version: 7.1.0 (was: 7.0.1).

Resulting package

Built on 2023-02-26T08:58 (took 2m31s)

The resulting binary packages can be installed (if you have the apt repository enabled) by running one of:

apt install -t fresh-releases ruby-license-finder

Lintian Result

Diff

diff --git a/.github/dependabot.yml b/.github/dependabot.yml
index d8c995a..69047ed 100644
--- a/.github/dependabot.yml
+++ b/.github/dependabot.yml
@@ -7,3 +7,10 @@ updates:
     time: "20:00"
     timezone: America/Los_Angeles
   open-pull-requests-limit: 10
+- package-ecosystem: docker 
+  directory: "/"
+  schedule:
+    interval: daily
+    time: "20:00"
+    timezone: America/Los_Angeles
+  open-pull-requests-limit: 10
diff --git a/.pre-commit-hooks.yaml b/.pre-commit-hooks.yaml
new file mode 100644
index 0000000..1ffcb7b
--- /dev/null
+++ b/.pre-commit-hooks.yaml
@@ -0,0 +1,10 @@
+- id: license-finder
+  name: Audit licenses of dependencies
+  entry: license_finder
+  language: ruby
+  pass_filenames: false
+  description: >
+    LicenseFinder works with your package managers to find dependencies, detect
+    the licenses of the packages in them, compare those licenses against a
+    user-defined list of permitted licenses, and give you an actionable
+    exception report.
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 2328168..2605fdd 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,4 +1,27 @@
+# [7.1.0] / 2022-11-28
+
+### Added
+* Missing New BSD alternative name - [64d425d9](https://github.com/pivotal/LicenseFinder/commit/64d425d9210794c6b45c60bf730931e459a1e959) 
+* pre-commit hook - [2fd5ac85](https://github.com/pivotal/LicenseFinder/commit/2fd5ac85fbd4ea03b6f274f2c977448a8a517c2c) - Kurt von Laven
+
+### Fixed
+* - Apache 2 license being too restrictive on matching - [c7fd0399](https://github.com/pivotal/LicenseFinder/commit/c7fd03994592ca97408f5134dd9eac6566e51c48) 
+* - Erlang not installing properly with mix - [74af3885](https://github.com/pivotal/LicenseFinder/commit/74af388579dd2f26b1814ece39c869d684218cd9) 
+* Scan transitive Yarn v2+ dependencies - [0115445e](https://github.com/pivotal/LicenseFinder/commit/0115445eb26de3185518adfb257b0e1911cf2fbd) - Kurt von Laven
+
+* Issue with chaining commands with dlf - [a6af8c3e](https://github.com/pivotal/LicenseFinder/commit/a6af8c3e0abb932ed8d3c0215175f23cf75b5fb2) 
+* Nuget and dotnet not returning proper licenses - [e3452336](https://github.com/pivotal/LicenseFinder/commit/e3452336aa980f26de9a7d44d725bddb0ddd67a0) 
+* Save help documentation for the default file name - [09a93762](https://github.com/pivotal/LicenseFinder/commit/09a93762dc3bd714fdcdebb4aa84af4c7dbefa04) 
+* - Yarn2 output parsing - [395a7f02](https://github.com/pivotal/LicenseFinder/commit/395a7f02b7729243aaf730b6ede71cae8f21cfeb) 
+
+### Changed
+* - Bump docker image golang version to 1.17.13 - [4f3df246](https://github.com/pivotal/LicenseFinder/commit/4f3df246d2f5245681a943a6fb6dee49e3ed3ed1) 
+
 # [7.0.1] / 2022-03-18
+### Fixed
+* Maven Wrapper command path must be relative to working directory - [298a733a](https://github.com/pivotal/LicenseFinder/commit/298a733a67f34341ffabc7dfbf2ee5c27574b979) - jbmgrtn 
+* Support yarn license command for yarn v2+ - [ed3b319b](https://github.com/pivotal/LicenseFinder/commit/ed3b319b64bf9c72c12fd5a365952137cf7f33b6)
+
 
 # [7.0.0] / 2022-03-04
 
@@ -1010,3 +1033,4 @@ Bugfixes:
 [6.15.0]: https://github.com/pivotal/LicenseFinder/compare/v6.14.2...v6.15.0
 [7.0.0]: https://github.com/pivotal/LicenseFinder/compare/v6.15.0...v7.0.0
 [7.0.1]: https://github.com/pivotal/LicenseFinder/compare/v7.0.0...v7.0.1
+[7.1.0]: https://github.com/pivotal/LicenseFinder/compare/v7.0.1...v7.1.0
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 13996d7..e6666cd 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -78,6 +78,7 @@ If you come up with something useful, consider posting it to the Google Group
 To successfully run the test suite, you will need the following installed:
 - NPM (requires Node)
 - Yarn (requires Node)
+- PNPM (requires Node)
 - Bower (requires Node and NPM)
 - Maven (requires Java)
 - Gradle (requires Java)
diff --git a/Dockerfile b/Dockerfile
index 7caf637..e218843 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -5,25 +5,25 @@ WORKDIR /tmp
 # Versioning
 ENV PIP_INSTALL_VERSION 19.0.2
 ENV PIP3_INSTALL_VERSION 20.0.2
-ENV GO_LANG_VERSION 1.14.3
+ENV GO_LANG_VERSION 1.17.13
 ENV MAVEN_VERSION 3.6.0
 ENV SBT_VERSION 1.3.3
 ENV GRADLE_VERSION 5.6.4
 ENV RUBY_VERSION 3.1.1
-ENV MIX_VERSION 1.0
+ENV MIX_VERSION 2.0
 ENV COMPOSER_ALLOW_SUPERUSER 1
 
 # programs needed for building
 RUN apt-get update && apt-get install -y \
-  build-essential \
-  curl \
-  sudo \
-  unzip \
-  wget \
-  gnupg2 \
-  apt-utils \
-  software-properties-common \
-  bzr
+    build-essential \
+    curl \
+    sudo \
+    unzip \
+    wget \
+    gnupg2 \
+    apt-utils \
+    software-properties-common \
+    bzr
 
 RUN add-apt-repository ppa:git-core/ppa && apt-get update && apt-get install -y git
 
@@ -33,14 +33,18 @@ RUN curl -sL https://deb.nodesource.com/setup_14.x | bash - && \
 
 # install yarn
 RUN curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | sudo apt-key add - && \
-  echo "deb https://dl.yarnpkg.com/debian/ stable main" | sudo tee /etc/apt/sources.list.d/yarn.list && \
-  apt-get update && \
-  apt-get install yarn
+    echo "deb https://dl.yarnpkg.com/debian/ stable main" | sudo tee /etc/apt/sources.list.d/yarn.list && \
+    apt-get update && \
+    apt-get install yarn
 
 # install bower
 RUN npm install -g bower && \
     echo '{ "allow_root": true }' > /root/.bowerrc
 
+# install pnpm
+RUN npm install -g pnpm && \
+    pnpm version
+
 # install jdk 12
 RUN curl -L -o openjdk12.tar.gz https://download.java.net/java/GA/jdk12.0.2/e482c34c86bd4bf8b56c0b35558996b9/10/GPL/openjdk-12.0.2_linux-x64_bin.tar.gz && \
     tar xvf openjdk12.tar.gz && \
@@ -95,14 +99,29 @@ ENV PATH=$PATH:/go/bin
 ENV GOROOT=/go
 ENV GOPATH=/gopath
 ENV PATH=$PATH:$GOPATH/bin
+
 RUN mkdir /gopath && \
-  go get github.com/tools/godep && \
-  go get github.com/FiloSottile/gvt && \
-  go get github.com/Masterminds/glide && \
-  go get github.com/kardianos/govendor && \
-  go get github.com/golang/dep/cmd/dep && \
-  go get -u github.com/rancher/trash && \
-  go clean -cache
+    go install github.com/tools/godep@latest && \
+    go install github.com/FiloSottile/gvt@latest && \
+    go install github.com/kardianos/govendor@latest && \
+    go clean -cache
+
+#install rvm and glide and godep
+RUN apt-add-repository -y ppa:rael-gc/rvm && \
+    add-apt-repository -y ppa:masterminds/glide  && \
+    apt update && apt install -y rvm && \
+    /usr/share/rvm/bin/rvm install --default $RUBY_VERSION &&\
+    apt-get install -y glide && \
+    apt-get install -y go-dep
+
+# install trash
+RUN curl -Lo trash.tar.gz https://github.com/rancher/trash/releases/download/v0.2.7/trash-linux_amd64.tar.gz && \
+    tar xvf trash.tar.gz && \
+    rm trash.tar.gz && \
+    sudo mv trash /usr/local/bin/
+
+# install bundler
+RUN bash -lc "gem update --system && gem install bundler"
 
 WORKDIR /tmp
 # Fix the locale
@@ -115,47 +134,44 @@ ENV LC_ALL=en_US.UTF-8
 # install Cargo
 RUN curl https://sh.rustup.rs -sSf | bash -ls -- -y --profile minimal
 
-#install rvm
-RUN apt-add-repository -y ppa:rael-gc/rvm && \
-    apt update && apt install -y rvm && \
-    /usr/share/rvm/bin/rvm install --default $RUBY_VERSION
-
-# install bundler
-RUN bash -lc "gem update --system && gem install bundler"
-
 #install mix
 RUN wget https://packages.erlang-solutions.com/erlang-solutions_${MIX_VERSION}_all.deb && \
     sudo dpkg -i erlang-solutions_${MIX_VERSION}_all.deb && \
     sudo rm -f erlang-solutions_${MIX_VERSION}_all.deb && \
     sudo apt-get update && \
-    sudo apt-get install -y esl-erlang && \
-    sudo apt-get install -y elixir
+    sudo apt-get install -y esl-erlang
+# Install Elixir
+WORKDIR /tmp/elixir-build
+RUN git clone https://github.com/elixir-lang/elixir.git
+WORKDIR elixir
+RUN make && make install
+WORKDIR /
 
 # install conan
 RUN apt-get install -y python-dev && \
-	pip install --no-cache-dir --ignore-installed six --ignore-installed colorama \
-	    --ignore-installed requests --ignore-installed chardet \
-	    --ignore-installed urllib3 \
-	    --upgrade setuptools && \
-    pip install --no-cache-dir -Iv conan==1.43.0 && \
+    pip install --no-cache-dir --ignore-installed six --ignore-installed colorama \
+    --ignore-installed requests --ignore-installed chardet \
+    --ignore-installed urllib3 \
+    --upgrade setuptools && \
+    pip3 install --no-cache-dir -Iv conan==1.51.3 && \
     conan config install https://github.com/conan-io/conanclientcert.git
 
 
 # install NuGet (w. mono)
 # https://docs.microsoft.com/en-us/nuget/install-nuget-client-tools#macoslinux
 RUN apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF &&\
-  echo "deb https://download.mono-project.com/repo/ubuntu stable-bionic main" | sudo tee /etc/apt/sources.list.d/mono-official-stable.list &&\
-  apt-get update &&\
-  apt-get install -y mono-complete &&\
-  curl -o "/usr/local/bin/nuget.exe" "https://dist.nuget.org/win-x86-commandline/latest/nuget.exe" &&\
-  curl -o "/usr/local/bin/nugetv3.5.0.exe" "https://dist.nuget.org/win-x86-commandline/v3.5.0/nuget.exe"
+    echo "deb https://download.mono-project.com/repo/ubuntu stable-bionic main" | sudo tee /etc/apt/sources.list.d/mono-official-stable.list &&\
+    apt-get update &&\
+    apt-get install -y mono-complete &&\
+    curl -o "/usr/local/bin/nuget.exe" "https://dist.nuget.org/win-x86-commandline/latest/nuget.exe" &&\
+    curl -o "/usr/local/bin/nugetv3.5.0.exe" "https://dist.nuget.org/win-x86-commandline/v3.5.0/nuget.exe"
 
 # install dotnet core
 RUN wget -q https://packages.microsoft.com/config/ubuntu/18.04/packages-microsoft-prod.deb &&\
-  sudo dpkg -i packages-microsoft-prod.deb &&\
-  rm packages-microsoft-prod.deb &&\
-  sudo apt-get update &&\
-  sudo apt-get install -y dotnet-runtime-2.1 dotnet-sdk-2.1 dotnet-sdk-2.2 dotnet-sdk-3.0 dotnet-sdk-3.1
+    sudo dpkg -i packages-microsoft-prod.deb &&\
+    rm packages-microsoft-prod.deb &&\
+    sudo apt-get update &&\
+    sudo apt-get install -y dotnet-runtime-2.1 dotnet-sdk-2.1 dotnet-sdk-2.2 dotnet-sdk-3.0 dotnet-sdk-3.1
 
 # install Composer
 # The ARG and ENV are for installing tzdata which is part of this installaion.
@@ -178,12 +194,12 @@ RUN apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 4F4EA0AAE5
 # See https://docs.conda.io/en/latest/miniconda_hashes.html
 # for latest versions and SHAs.
 RUN  \
-  conda_installer=Miniconda3-py38_4.9.2-Linux-x86_64.sh &&\
-  ref='1314b90489f154602fd794accfc90446111514a5a72fe1f71ab83e07de9504a7' &&\
-  wget -q https://repo.anaconda.com/miniconda/${conda_installer} &&\
-  sha=`openssl sha256 "${conda_installer}" | cut -d' ' -f2` &&\
-  ([ "$sha" = "${ref}" ] || (echo "Verification failed: ${sha} != ${ref}"; false)) &&\
-  (echo; echo "yes") | sh "${conda_installer}"
+    conda_installer=Miniconda3-py38_4.9.2-Linux-x86_64.sh &&\
+    ref='1314b90489f154602fd794accfc90446111514a5a72fe1f71ab83e07de9504a7' &&\
+    wget -q https://repo.anaconda.com/miniconda/${conda_installer} &&\
+    sha=`openssl sha256 "${conda_installer}" | cut -d' ' -f2` &&\
+    ([ "$sha" = "${ref}" ] || (echo "Verification failed: ${sha} != ${ref}"; false)) &&\
+    (echo; echo "yes") | sh "${conda_installer}"
 
 # install Swift Package Manager
 # Based on https://github.com/apple/swift-docker/blob/main/5.3/ubuntu/18.04/Dockerfile
@@ -208,11 +224,12 @@ RUN apt-get -q install -y \
 
 #install flutter
 ENV FLUTTER_HOME=/root/flutter
+RUN git config --global --add safe.directory /root/flutter
 RUN curl -o flutter_linux_2.8.1-stable.tar.xz https://storage.googleapis.com/flutter_infra_release/releases/stable/linux/flutter_linux_2.8.1-stable.tar.xz \
     && tar xf flutter_linux_2.8.1-stable.tar.xz \
     && mv flutter ${FLUTTER_HOME} \
     && rm flutter_linux_2.8.1-stable.tar.xz
-        
+
 ENV PATH=$PATH:${FLUTTER_HOME}/bin:${FLUTTER_HOME}/bin/cache/dart-sdk/bin
 RUN flutter doctor -v \
     && flutter update-packages \
diff --git a/README.md b/README.md
index e7a6de3..8dc450a 100644
--- a/README.md
+++ b/README.md
@@ -57,8 +57,19 @@ and give you an actionable exception report.
 
 ## Installation
 
-License Finder requires Ruby 2.4.0 or greater to run. If you have an older
-version of Ruby installed, you can update via Homebrew:
+License Finder may be run as a [pre-commit](https://pre-commit.com) hook by
+adding the following to your `.pre-commit-config.yaml`:
+
+```yaml
+repos:
+  - repo: https://github.com/pivotal/LicenseFinder
+    rev: v7.1.0 # You probably want the latest tag.
+    hooks:
+      - id: license-finder
+```
+
+Running License Finder directly requires Ruby 2.4.0 or greater. If you have an
+older version of Ruby installed, you can update via Homebrew:
 
 ```sh
 $ ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
@@ -70,7 +81,7 @@ then:
 $ brew install ruby
 ```
 
-The easiest way to use `license_finder` is to install it as a command
+The easiest way to use `license_finder` directly is to install it as a command
 line tool, like brew, awk, gem or bundler:
 
 ```sh
@@ -154,7 +165,8 @@ $ dlf "bundle install && license_finder"
 
 You can better understand the way this script works by looking at its source, but for
 reference it will mount your current directory at the path `/scan` and run any commands
-passed to it from that directory.
+passed to it from that directory. If your command has `&&`, ensure you quote the command. 
+If it does not, ensure the command is not quoted.
 
 Note that the docker image will run the gem which is installed within it.
 So the docker image tagged `7.0.0` will run *License Finder Version 7.0.0*
@@ -195,7 +207,7 @@ languages, as long as that language has a package definition in the project dire
 * `build.sbt` file (for `sbt`)
 * `Cargo.lock` file (for `cargo`)
 * `composer.lock` file (for `composer`)
-* `environment,yml` file (for `conda`)
+* `environment.yml` file (for `conda`)
 * `pubspec.yaml & .pub cache locaton through ENV variable` (for `flutter`)
 
 ### Continuous Integration
@@ -333,12 +345,40 @@ you should manually research what the actual license is.  When you
 have established the real license, you can record it with:
 
 ```sh
-$ license_finder licenses add my_unknown_dependency MIT --homepage="www.unknown-code.org"
+$ license_finder licenses add my_unknown_dependency MIT
+```
+
+This command would assign the MIT license to all versions of the dependency
+`my_unknown_dependency`. If you prefer, you could instead assign the license
+to only a specific version of the dependency:
+
+```sh
+$ license_finder licenses add my_unknown_dependency MIT --version=1.0.0
 ```
 
-This command would assign the MIT license to the dependency
-`my_unknown_dependency`. It will also set its homepage to `www.unknown-code.org`.
+Please note that adding a license to a specific version of a dependency will 
+cause any licenses previously added to all versions of that dependency to be 
+forgotten. Similarly, adding a license to all versions of a dependency will 
+override any licenses previously added to specific versions of that dependency.
+
+There are several ways in which you can remove licenses that were previously
+added through the `licenses add` command:
+
+```sh
+# Removes all licenses from any version of the dependency
+$ license_finder licenses remove my_unknown_dependency
 
+# Removes just the MIT license from any version of the dependency
+$ license_finder licenses remove my_unknown_dependency MIT
+
+# Removes all licenses from only version 1.0.0 of the dependency
+# This has no effect if you had last added a license to all versions of the dependency
+$ license_finder licenses remove my_unknown_dependency --version=1.0.0
+
+# Removes just the MIT license from only version 1.0.0 of the dependency
+# This has no effect if you had last added a license to all versions of the dependency
+$ license_finder licenses remove my_unknown_dependency MIT --version=1.0.0
+```
 
 ### Adding Hidden Dependencies
 
diff --git a/VERSION b/VERSION
index 9fe9ff9..a3fcc71 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-7.0.1
+7.1.0
diff --git a/debian/changelog b/debian/changelog
index 78be471..4e0a87e 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,9 @@
+ruby-license-finder (7.1.0-1) UNRELEASED; urgency=low
+
+  * New upstream release.
+
+ -- Debian Janitor <janitor@jelmer.uk>  Sun, 26 Feb 2023 08:56:07 -0000
+
 ruby-license-finder (7.0.1-2) unstable; urgency=medium
 
   * Team upload.
diff --git a/debian/patches/0001-embed-python-file-path.patch b/debian/patches/0001-embed-python-file-path.patch
index 37b114a..8f84aa0 100644
--- a/debian/patches/0001-embed-python-file-path.patch
+++ b/debian/patches/0001-embed-python-file-path.patch
@@ -6,10 +6,10 @@ Subject: embed python file path
  lib/license_finder/package_managers/pip.rb | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)
 
-diff --git a/lib/license_finder/package_managers/pip.rb b/lib/license_finder/package_managers/pip.rb
-index a4199bf..31b6c2a 100644
---- a/lib/license_finder/package_managers/pip.rb
-+++ b/lib/license_finder/package_managers/pip.rb
+Index: ruby-license-finder.git/lib/license_finder/package_managers/pip.rb
+===================================================================
+--- ruby-license-finder.git.orig/lib/license_finder/package_managers/pip.rb
++++ ruby-license-finder.git/lib/license_finder/package_managers/pip.rb
 @@ -54,7 +54,7 @@ module LicenseFinder
      private
  
diff --git a/dlf b/dlf
index b8c1d40..cc62b69 100755
--- a/dlf
+++ b/dlf
@@ -7,7 +7,12 @@ if `which docker > /dev/null`; then
     for p in "$@"; do
       escaped_params="$escaped_params \"$p\""
     done
-    docker run -v $PWD:/scan -it licensefinder/license_finder /bin/bash -lc "cd /scan && $escaped_params"
+    if [[ $escaped_params =~ "&&" ]]; then
+      command=${escaped_params:2:${#escaped_params}-3}
+    else
+      command=$escaped_params
+    fi
+    docker run -v $PWD:/scan -it licensefinder/license_finder /bin/bash -lc "cd /scan && $command"
   fi
 else
   echo "You do not have docker installed. Please install it:"
diff --git a/lib/license_finder/cli/base.rb b/lib/license_finder/cli/base.rb
index 3c7d4c5..915fd34 100644
--- a/lib/license_finder/cli/base.rb
+++ b/lib/license_finder/cli/base.rb
@@ -46,6 +46,8 @@ module LicenseFinder
           :maven_include_groups,
           :maven_options,
           :npm_options,
+          :yarn_options,
+          :pnpm_options,
           :pip_requirements_path,
           :python_version,
           :rebar_command,
diff --git a/lib/license_finder/cli/licenses.rb b/lib/license_finder/cli/licenses.rb
index f99edc1..d34c984 100644
--- a/lib/license_finder/cli/licenses.rb
+++ b/lib/license_finder/cli/licenses.rb
@@ -7,19 +7,24 @@ module LicenseFinder
       include MakesDecisions
 
       auditable
+      method_option :version, desc: 'The version associated with the license'
       desc 'add DEPENDENCY LICENSE', "Set a dependency's licenses, overwriting any license_finder has found"
       def add(name, license)
         modifying { decisions.license(name, license, txn) }
 
-        printer.say "The #{name} dependency has been marked as using #{license} license!", :green
+        version_info = options[:version] ? " with version #{options[:version]}" : ''
+        printer.say "The #{name} dependency#{version_info} has been marked as using #{license} license!", :green
       end
 
       auditable
+      method_option :version, desc: 'The version associated with the license'
       desc 'remove DEPENDENCY LICENSE', 'Remove a manually set license'
-      def remove(dep, lic)
+      def remove(dep, lic = nil)
         modifying { decisions.unlicense(dep, lic, txn) }
 
-        printer.say "The dependency #{dep} no longer has a manual license"
+        version_info = options[:version] ? " with version #{options[:version]}" : ''
+        suffix = lic ? " of #{lic}" : ''
+        printer.say "The dependency #{dep}#{version_info} no longer has a manual license#{suffix}"
       end
     end
   end
diff --git a/lib/license_finder/cli/main.rb b/lib/license_finder/cli/main.rb
index 357b689..00a6834 100644
--- a/lib/license_finder/cli/main.rb
+++ b/lib/license_finder/cli/main.rb
@@ -32,6 +32,8 @@ module LicenseFinder
       class_option :maven_include_groups, desc: 'Whether dependency name should include group id. Only meaningful if used with a Java/maven project. Defaults to false.'
       class_option :maven_options, desc: 'Maven options to append to command. Defaults to empty.'
       class_option :npm_options, desc: 'npm options to append to command. Defaults to empty.'
+      class_option :yarn_options, desc: 'yarn options to append to command. Defaults to empty.'
+      class_option :pnpm_options, desc: 'pnpm options to append to command. Defaults to empty.'
       class_option :pip_requirements_path, desc: 'Path to python requirements file. Defaults to requirements.txt.'
       class_option :python_version, desc: 'Python version to invoke pip with. Valid versions: 2 or 3. Default: 2'
       class_option :rebar_command, desc: "Command to use when fetching rebar packages. Only meaningful if used with a Erlang/rebar project. Defaults to 'rebar'."
@@ -152,7 +154,7 @@ module LicenseFinder
       shared_options
       format_option
       method_option :write_headers, type: :boolean, desc: 'Write exported columns as header row (csv).', default: false, required: false
-      method_option :save, desc: "Save report to a file. Default: 'license_report.csv' in project root.", lazy_default: 'license_report'
+      method_option :save, desc: "Save report to a file. Default: 'license_report' in project root.", lazy_default: 'license_report'
 
       def report
         finder = LicenseAggregator.new(config, aggregate_paths)
diff --git a/lib/license_finder/configuration.rb b/lib/license_finder/configuration.rb
index 5a57f8c..eccde11 100644
--- a/lib/license_finder/configuration.rb
+++ b/lib/license_finder/configuration.rb
@@ -97,6 +97,14 @@ module LicenseFinder
       get(:npm_options)
     end
 
+    def yarn_options
+      get(:yarn_options)
+    end
+
+    def pnpm_options
+      get(:pnpm_options)
+    end
+
     def pip_requirements_path
       get(:pip_requirements_path)
     end
diff --git a/lib/license_finder/core.rb b/lib/license_finder/core.rb
index 22cdc31..38defd3 100644
--- a/lib/license_finder/core.rb
+++ b/lib/license_finder/core.rb
@@ -101,6 +101,8 @@ module LicenseFinder
         maven_include_groups: config.maven_include_groups,
         maven_options: config.maven_options,
         npm_options: config.npm_options,
+        yarn_options: config.yarn_options,
+        pnpm_options: config.pnpm_options,
         pip_requirements_path: config.pip_requirements_path,
         python_version: config.python_version,
         rebar_command: config.rebar_command,
diff --git a/lib/license_finder/decision_applier.rb b/lib/license_finder/decision_applier.rb
index e0e3d2e..8a49956 100644
--- a/lib/license_finder/decision_applier.rb
+++ b/lib/license_finder/decision_applier.rb
@@ -44,7 +44,7 @@ module LicenseFinder
     end
 
     def with_decided_licenses(package)
-      decisions.licenses_of(package.name).each do |license|
+      decisions.licenses_of(package.name, package.version).each do |license|
         package.decide_on_license license
       end
       package
diff --git a/lib/license_finder/decisions.rb b/lib/license_finder/decisions.rb
index 3f673d5..e1bc4a7 100644
--- a/lib/license_finder/decisions.rb
+++ b/lib/license_finder/decisions.rb
@@ -2,6 +2,7 @@
 
 require 'open-uri'
 require 'license_finder/license'
+require 'license_finder/manual_licenses'
 
 module LicenseFinder
   class Decisions
@@ -11,8 +12,8 @@ module LicenseFinder
 
     attr_reader :packages, :permitted, :restricted, :ignored, :ignored_groups, :project_name, :inherited_decisions
 
-    def licenses_of(name)
-      @licenses[name]
+    def licenses_of(name, version = nil)
+      @manual_licenses.licenses_of(name, version)
     end
 
     def homepage_of(name)
@@ -76,7 +77,7 @@ module LicenseFinder
     def initialize
       @decisions = []
       @packages = Set.new
-      @licenses = Hash.new { |h, k| h[k] = Set.new }
+      @manual_licenses = ManualLicenses.new
       @homepages = {}
       @approvals = {}
       @permitted = Set.new
@@ -100,13 +101,29 @@ module LicenseFinder
 
     def license(name, lic, txn = {})
       add_decision [:license, name, lic, txn]
-      @licenses[name] << License.find_by_name(lic)
+
+      versions = txn[:versions]
+
+      if versions.nil? || versions.empty?
+        @manual_licenses.assign_to_all_versions(name, lic)
+      else
+        @manual_licenses.assign_to_specific_versions(name, lic, versions)
+      end
+
       self
     end
 
     def unlicense(name, lic, txn = {})
       add_decision [:unlicense, name, lic, txn]
-      @licenses[name].delete(License.find_by_name(lic))
+
+      versions = txn[:versions]
+
+      if versions.nil? || versions.empty?
+        @manual_licenses.unassign_from_all_versions(name, lic)
+      else
+        @manual_licenses.unassign_from_specific_versions(name, lic, versions)
+      end
+
       self
     end
 
@@ -235,9 +252,10 @@ module LicenseFinder
     end
 
     def restore_inheritance(decisions)
+      previous_value = @inherited
       @inherited = true
       self.class.restore(decisions, self)
-      @inherited = false
+      @inherited = previous_value
       self
     end
 
diff --git a/lib/license_finder/license/definitions.rb b/lib/license_finder/license/definitions.rb
index bce03b5..6560090 100644
--- a/lib/license_finder/license/definitions.rb
+++ b/lib/license_finder/license/definitions.rb
@@ -265,7 +265,9 @@ module LicenseFinder
             'BSD 3',
             'BSD-3',
             '3-clause BSD',
+            '3-Clause BSD License',
             'BSD-3-Clause',
+            'BSD 3-Clause',
             'BSD 3-Clause License',
             'The 3-Clause BSD License',
             'BSD 3-clause New License',
diff --git a/lib/license_finder/license/templates/Apache2.txt b/lib/license_finder/license/templates/Apache2.txt
index 4c38ebd..0e35d80 100644
--- a/lib/license_finder/license/templates/Apache2.txt
+++ b/lib/license_finder/license/templates/Apache2.txt
@@ -168,5 +168,3 @@
       defend, and hold each Contributor harmless for any liability
       incurred by, or claims asserted against, such Contributor by reason
       of your accepting any such warranty or additional liability.
-
-   END OF TERMS AND CONDITIONS
diff --git a/lib/license_finder/manual_licenses.rb b/lib/license_finder/manual_licenses.rb
new file mode 100644
index 0000000..b8aac94
--- /dev/null
+++ b/lib/license_finder/manual_licenses.rb
@@ -0,0 +1,79 @@
+# frozen_string_literal: true
+
+module LicenseFinder
+  class ManualLicenses
+    def initialize
+      @all_versions = {}
+      @specific_versions = {}
+    end
+
+    def licenses_of(name, version = nil)
+      return @all_versions[name] if @all_versions[name]
+
+      if version && @specific_versions[name] && @specific_versions[name][version]
+        @specific_versions[name][version]
+      else
+        Set.new
+      end
+    end
+
+    def assign_to_all_versions(name, lic)
+      # Ex: licenses add foo_gem MIT => Adds MIT at "all" versions for this gem
+
+      @all_versions[name] ||= Set.new
+      @all_versions[name] << to_license(lic)
+
+      @specific_versions.delete(name)
+    end
+
+    def assign_to_specific_versions(name, lic, versions)
+      # Ex: licenses add foo_gem MIT --version=1.0 => Adds MIT at only 1.0 for this gem
+
+      @specific_versions[name] ||= {}
+      versions.each do |version|
+        @specific_versions[name][version] ||= Set.new
+        @specific_versions[name][version] << to_license(lic)
+      end
+
+      @all_versions.delete(name)
+    end
+
+    def unassign_from_all_versions(name, lic = nil)
+      if lic
+        # Ex: licenses remove foo_gem MIT => Removes MIT at all versions for this gem
+        @all_versions[name]&.delete(to_license(lic))
+
+        @specific_versions[name]&.each do |_version, licenses|
+          licenses.delete(to_license(lic))
+        end
+      else
+        # Ex: licenses remove foo_gem => Removes all licenses for all versions of the gem
+        @all_versions.delete(name)
+        @specific_versions.delete(name)
+      end
+    end
+
+    def unassign_from_specific_versions(name, lic, versions)
+      return unless @specific_versions[name]
+
+      versions.each do |version|
+        if @specific_versions[name][version]
+          if lic
+            # Ex: licenses remove foo_gem MIT --version=1.0 => Removes MIT at only 1.0 for this gem
+            @specific_versions[name][version].delete(to_license(lic))
+            @specific_versions[name].delete(version) if @specific_versions[name][version].empty?
+          else
+            # Ex: licenses remove foo_gem --version=1.0 => Removes all licenses at only 1.0 for the gem
+            @specific_versions[name].delete(version)
+          end
+        end
+      end
+    end
+
+    private
+
+    def to_license(lic)
+      License.find_by_name(lic)
+    end
+  end
+end
diff --git a/lib/license_finder/package.rb b/lib/license_finder/package.rb
index 04a8370..c10096b 100644
--- a/lib/license_finder/package.rb
+++ b/lib/license_finder/package.rb
@@ -187,6 +187,7 @@ require 'license_finder/packages/merged_package'
 require 'license_finder/packages/nuget_package'
 require 'license_finder/packages/conan_package'
 require 'license_finder/packages/yarn_package'
+require 'license_finder/packages/pnpm_package'
 require 'license_finder/packages/sbt_package'
 require 'license_finder/packages/cargo_package'
 require 'license_finder/packages/composer_package'
diff --git a/lib/license_finder/package_manager.rb b/lib/license_finder/package_manager.rb
index 95c9efc..1ab041e 100644
--- a/lib/license_finder/package_manager.rb
+++ b/lib/license_finder/package_manager.rb
@@ -158,6 +158,7 @@ require 'license_finder/package_managers/go_modules'
 require 'license_finder/package_managers/trash'
 require 'license_finder/package_managers/bundler'
 require 'license_finder/package_managers/npm'
+require 'license_finder/package_managers/pnpm'
 require 'license_finder/package_managers/yarn'
 require 'license_finder/package_managers/pip'
 require 'license_finder/package_managers/pipenv'
diff --git a/lib/license_finder/package_managers/dotnet.rb b/lib/license_finder/package_managers/dotnet.rb
index dffb257..e186ba5 100644
--- a/lib/license_finder/package_managers/dotnet.rb
+++ b/lib/license_finder/package_managers/dotnet.rb
@@ -42,9 +42,13 @@ module LicenseFinder
       end
 
       def read_license_urls
-        possible_spec_paths.flat_map do |path|
+        raw_licenses = possible_spec_paths.flat_map do |path|
           Nuget.nuspec_license_urls(File.read(path)) if File.exist? path
         end.compact
+
+        raw_licenses&.map! do |license|
+          license.gsub('https://licenses.nuget.org/', '')
+        end
       end
 
       def ==(other)
@@ -61,7 +65,6 @@ module LicenseFinder
       package_metadatas = asset_files
                           .flat_map { |path| AssetFile.new(path).dependencies }
                           .uniq { |d| [d.name, d.version] }
-
       package_metadatas.map do |d|
         path = Dir.glob("#{Dir.home}/.nuget/packages/#{d.name.downcase}/#{d.version}").first
         NugetPackage.new(d.name, d.version, spec_licenses: d.read_license_urls, install_path: path)
diff --git a/lib/license_finder/package_managers/nuget.rb b/lib/license_finder/package_managers/nuget.rb
index 6a1ea77..eb8a1c6 100644
--- a/lib/license_finder/package_managers/nuget.rb
+++ b/lib/license_finder/package_managers/nuget.rb
@@ -51,6 +51,10 @@ module LicenseFinder
     def current_packages
       dependencies.each_with_object({}) do |dep, memo|
         licenses = license_urls(dep)
+        licenses&.map! do |license|
+          license.gsub('https://licenses.nuget.org/', '')
+        end
+
         path = Dir.glob("#{Dir.home}/.nuget/packages/#{dep.name.downcase}/#{dep.version}").first
 
         memo[dep.name] ||= NugetPackage.new(dep.name, dep.version, spec_licenses: licenses, install_path: path)
@@ -60,6 +64,7 @@ module LicenseFinder
 
     def license_urls(dep)
       files = Dir["**/#{dep.name}.#{dep.version}.nupkg"]
+
       return nil if files.empty?
 
       file = files.first
diff --git a/lib/license_finder/package_managers/pnpm.rb b/lib/license_finder/package_managers/pnpm.rb
new file mode 100644
index 0000000..61c402a
--- /dev/null
+++ b/lib/license_finder/package_managers/pnpm.rb
@@ -0,0 +1,120 @@
+# frozen_string_literal: true
+
+require 'json'
+require 'tempfile'
+
+module LicenseFinder
+  class PNPM < PackageManager
+    def initialize(options = {})
+      super
+      @pnpm_options = options[:pnpm_options]
+    end
+
+    SHELL_COMMAND = 'pnpm licenses list --json --long'
+
+    def possible_package_paths
+      [project_path.join('pnpm-lock.yaml')]
+    end
+
+    def self.takes_priority_over
+      NPM
+    end
+
+    def current_packages
+      # check if the minimum version of PNPM is met
+      raise 'The minimum PNPM version is not met, requires 7.17.0 or later' unless supported_pnpm?
+
+      # check if the project directory has workspace file
+      cmd = PNPM::SHELL_COMMAND.to_s
+      cmd += ' --no-color'
+      cmd += ' --recursive' unless project_has_workspaces == false
+      cmd += " --dir #{project_path}" unless project_path.nil?
+      cmd += " #{@pnpm_options}" unless @pnpm_options.nil?
+
+      stdout, stderr, status = Cmd.run(cmd)
+      raise "Command '#{cmd}' failed to execute: #{stderr}" unless status.success?
+
+      json_objects = JSON.parse(stdout)
+      get_pnpm_packages(json_objects)
+    end
+
+    def get_pnpm_packages(json_objects)
+      packages = []
+      incompatible_packages = []
+
+      json_objects.map do |_, value|
+        value.each do |pkg|
+          name = pkg['name']
+          version = pkg['version']
+          license = pkg['license']
+          homepage = pkg['vendorUrl']
+          author = pkg['vendorName']
+          module_path = pkg['path']
+
+          package = PNPMPackage.new(
+            name,
+            version,
+            spec_licenses: [license],
+            homepage: homepage,
+            authors: author,
+            install_path: module_path
+          )
+          packages << package
+        end
+      end
+
+      packages + incompatible_packages.uniq
+    end
+
+    def package_management_command
+      'pnpm'
+    end
+
+    def prepare_command
+      'pnpm install --no-lockfile --ignore-scripts'
+    end
+
+    def prepare
+      prep_cmd = "#{prepare_command}#{production_flag}"
+      _stdout, stderr, status = Dir.chdir(project_path) { Cmd.run(prep_cmd) }
+
+      return if status.success?
+
+      log_errors stderr
+      raise "Prepare command '#{prep_cmd}' failed" unless @prepare_no_fail
+    end
+
+    private
+
+    def project_has_workspaces
+      Dir.chdir(project_path) do
+        return File.file?('pnpm-workspace.yaml')
+      end
+    end
+
+    # PNPM introduced the licenses command in 7.17.0
+    def supported_pnpm?
+      Dir.chdir(project_path) do
+        version_string, stderr_str, status = Cmd.run('pnpm --version')
+        raise "Command 'pnpm -v' failed to execute: #{stderr_str}" unless status.success?
+
+        version = version_string.split('.').map(&:to_i)
+        major = version[0]
+        minor = version[1]
+        patch = version[1]
+
+        return true if major > 7
+        return true if major == 7 && minor > 17
+        return true if major == 7 && minor == 17 && patch >= 0
+
+        return false
+      end
+    end
+
+    def production_flag
+      return '' if @ignored_groups.nil?
+
+      @ignored_groups.include?('devDependencies') ? ' --prod' : ''
+    end
+  end
+end
diff --git a/lib/license_finder/package_managers/yarn.rb b/lib/license_finder/package_managers/yarn.rb
index 2992a77..f196c1f 100644
--- a/lib/license_finder/package_managers/yarn.rb
+++ b/lib/license_finder/package_managers/yarn.rb
@@ -2,7 +2,12 @@
 
 module LicenseFinder
   class Yarn < PackageManager
-    SHELL_COMMAND = 'yarn licenses list --json'
+    def initialize(options = {})
+      super
+      @yarn_options = options[:yarn_options]
+    end
+
+    SHELL_COMMAND = 'yarn licenses list --recursive --json'
 
     def possible_package_paths
       [project_path.join('yarn.lock')]
@@ -14,31 +19,20 @@ module LicenseFinder
       if yarn_version == 1
         cmd += ' --no-progress'
         cmd += " --cwd #{project_path}" unless project_path.nil?
+        cmd += " #{@yarn_options}" unless @yarn_options.nil?
       end
 
       stdout, stderr, status = Cmd.run(cmd)
       raise "Command '#{cmd}' failed to execute: #{stderr}" unless status.success?
 
-      packages = []
-      incompatible_packages = []
-
       json_strings = stdout.encode('ASCII', invalid: :replace, undef: :replace, replace: '?').split("\n")
       json_objects = json_strings.map { |json_object| JSON.parse(json_object) }
 
-      if json_objects.last['type'] == 'table'
-        license_json = json_objects.pop['data']
-        packages = packages_from_json(license_json)
-      end
-
-      json_objects.each do |json_object|
-        match = /(?<name>[\w,\-]+)@(?<version>(\d+\.?)+)/ =~ json_object['data'].to_s
-        if match
-          package = YarnPackage.new(name, version, spec_licenses: ['unknown'])
-          incompatible_packages.push(package)
-        end
+      if yarn_version == 1
+        get_yarn1_packages(json_objects)
+      else
+        get_yarn_packages(json_objects)
       end
-
-      packages + incompatible_packages.uniq
     end
 
     def prepare
@@ -94,6 +88,61 @@ module LicenseFinder
       end
     end
 
+    def get_yarn_packages(json_objects)
+      packages = []
+      incompatible_packages = []
+      json_objects.each do |json_object|
+        license = json_object['value']
+        body = json_object['children']
+
+        body.each do |package_name, vendor_info|
+          valid_match = %r{(?<name>[@,\w,\-,/,.]+)@(?<manager>\D*):\D*(?<version>(\d+\.?)+)} =~ package_name.to_s
+          valid_match = %r{(?<name>[@,\w,\-,/,.]+)@virtual:.+#(\D*):\D*(?<version>(\d+\.?)+)} =~ package_name.to_s if manager.eql?('virtual')
+
+          if valid_match
+            homepage = vendor_info['children']['vendorUrl']
+            author = vendor_info['children']['vendorName']
+            package = YarnPackage.new(
+              name,
+              version,
+              spec_licenses: [license],
+              homepage: homepage,
+              authors: author,
+              install_path: project_path.join(modules_folder, name)
+            )
+            packages << package
+          end
+          incompatible_match = /(?<name>[\w,\-]+)@[a-z]*:(?<version>(\.))/ =~ package_name.to_s
+
+          if incompatible_match
+            package = YarnPackage.new(name, version, spec_licenses: ['unknown'])
+            incompatible_packages.push(package)
+          end
+        end
+      end
+
+      packages + incompatible_packages.uniq
+    end
+
+    def get_yarn1_packages(json_objects)
+      packages = []
+      incompatible_packages = []
+      if json_objects.last['type'] == 'table'
+        license_json = json_objects.pop['data']
+        packages = packages_from_json(license_json)
+      end
+
+      json_objects.each do |json_object|
+        match = /(?<name>[\w,\-]+)@(?<version>(\d+\.?)+)/ =~ json_object['data'].to_s
+        if match
+          package = YarnPackage.new(name, version, spec_licenses: ['unknown'])
+          incompatible_packages.push(package)
+        end
+      end
+
+      packages + incompatible_packages.uniq
+    end
+
     def packages_from_json(json_data)
       body = json_data['body']
       head = json_data['head']
diff --git a/lib/license_finder/package_utils/pypi.rb b/lib/license_finder/package_utils/pypi.rb
index fac02ec..38003fd 100644
--- a/lib/license_finder/package_utils/pypi.rb
+++ b/lib/license_finder/package_utils/pypi.rb
@@ -25,7 +25,9 @@ module LicenseFinder
       def definition(name, version)
         response = request("https://pypi.org/pypi/#{name}/#{version}/json")
         response.is_a?(Net::HTTPSuccess) ? JSON.parse(response.body).fetch('info', {}) : {}
-      rescue *CONNECTION_ERRORS
+      rescue *CONNECTION_ERRORS => e
+        raise e, "Unable to read package from pypi.org #{name} #{version}: #{e}" unless @prepare_no_fail
+
         {}
       end
 
diff --git a/lib/license_finder/packages/npm_package.rb b/lib/license_finder/packages/npm_package.rb
index 3ee8966..c31863b 100644
--- a/lib/license_finder/packages/npm_package.rb
+++ b/lib/license_finder/packages/npm_package.rb
@@ -72,11 +72,32 @@ module LicenseFinder
             @identifier.version,
             description: npm_json['description'],
             homepage: npm_json['homepage'],
+            authors: author_names,
             spec_licenses: Package.license_names_from_standard_spec(npm_json),
             install_path: npm_json['path'],
             children: @dependencies.map(&:name))
     end
 
+    def author_names
+      names = []
+      names.push(author_name(@json['author'])) unless @json['author'].nil?
+      names += @json['contributors'].map { |c| author_name(c) } if @json['contributors'].is_a?(Array)
+      names.join(', ')
+    end
+
+    def author_name(author)
+      if author.instance_of?(String)
+        author_name_from_combined(author)
+      else
+        author['name']
+      end
+    end
+
+    def author_name_from_combined(author)
+      matches = author.match /^(.*?)\s*(<.*?>)?\s*(\(.*?\))?\s*$/
+      matches[1]
+    end
+
     def ==(other)
       other.is_a?(NpmPackage) && @identifier == other.identifier
     end
diff --git a/lib/license_finder/packages/pnpm_package.rb b/lib/license_finder/packages/pnpm_package.rb
new file mode 100644
index 0000000..6264f26
--- /dev/null
+++ b/lib/license_finder/packages/pnpm_package.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+module LicenseFinder
+  class PNPMPackage < Package
+    def package_manager
+      'PNPM'
+    end
+
+    def package_url
+      "https://www.npmjs.com/package/#{CGI.escape(name)}/v/#{CGI.escape(version)}"
+    end
+  end
+end
diff --git a/lib/license_finder/reports/csv_report.rb b/lib/license_finder/reports/csv_report.rb
index 6feb8df..dfb0680 100644
--- a/lib/license_finder/reports/csv_report.rb
+++ b/lib/license_finder/reports/csv_report.rb
@@ -4,7 +4,7 @@ module LicenseFinder
   class CsvReport < Report
     COMMA_SEP = ','.freeze
     NEWLINE_SEP = '\@NL'.freeze
-    AVAILABLE_COLUMNS = %w[name version authors licenses license_links approved summary description homepage install_path package_manager groups texts notice].freeze
+    AVAILABLE_COLUMNS = %w[name version authors licenses license_links approved summary description homepage install_path package_manager groups texts notice approved_by approved_reason].freeze
     MISSING_DEPENDENCY_TEXT = 'This package is not installed. Please install to determine licenses.'.freeze
 
     def initialize(dependencies, options)
@@ -95,5 +95,14 @@ module LicenseFinder
         dep.groups.join(self.class::COMMA_SEP)
       end
     end
+
+    def format_approved_by(dep)
+      dep.approved_manually? ? dep.manual_approval.who : ''
+    end
+
+    def format_approved_reason(dep)
+      dep.approved_manually? ? dep.manual_approval.why : ''
+    end
+
   end
 end
diff --git a/lib/license_finder/scanner.rb b/lib/license_finder/scanner.rb
index a0fbc19..0d5f78b 100644
--- a/lib/license_finder/scanner.rb
+++ b/lib/license_finder/scanner.rb
@@ -3,7 +3,7 @@
 module LicenseFinder
   class Scanner
     PACKAGE_MANAGERS = [
-      GoModules, GoDep, GoWorkspace, Go15VendorExperiment, Glide, Gvt, Govendor, Trash, Dep, Bundler, NPM, Pip,
+      GoModules, GoDep, GoWorkspace, Go15VendorExperiment, Glide, Gvt, Govendor, Trash, Dep, Bundler, NPM, PNPM, Pip,
       Yarn, Bower, Maven, Gradle, CocoaPods, Rebar, Erlangmk, Nuget, Carthage, Mix, Conan, Sbt, Cargo, Dotnet, Composer, Pipenv,
       Conda, Spm, Pub
     ].freeze
diff --git a/license_finder.gemspec b/license_finder.gemspec
index 5081119..4ee8563 100644
--- a/license_finder.gemspec
+++ b/license_finder.gemspec
@@ -50,11 +50,11 @@ Gem::Specification.new do |s|
   s.add_dependency 'with_env', '1.1.0'
   s.add_dependency 'xml-simple', '~> 1.1.9'
 
-  s.add_development_dependency 'addressable', '2.8.0'
+  s.add_development_dependency 'addressable', '2.8.1'
   s.add_development_dependency 'capybara', '~> 3.32.2'
   s.add_development_dependency 'cocoapods', '>= 1.0.0' if RUBY_PLATFORM.match?(/darwin/)
   s.add_development_dependency 'e2mmap', '~> 0.1.0'
-  s.add_development_dependency 'fakefs', '~> 1.4.1'
+  s.add_development_dependency 'fakefs', '~> 1.8.0'
   s.add_development_dependency 'matrix', '~> 0.1.0'
   s.add_development_dependency 'mime-types', '3.4.1'
   s.add_development_dependency 'pry', '~> 0.14.1'
@@ -66,8 +66,8 @@ Gem::Specification.new do |s|
   s.add_development_dependency 'webmock', '~> 3.14'
 
   s.add_development_dependency 'nokogiri', '~>1.10'
-  s.add_development_dependency 'rack', '~> 2.2.3'
-  s.add_development_dependency 'rack-test', '~> 1.1.0', '> 0.7'
+  s.add_development_dependency 'rack', '~> 3.0.0'
+  s.add_development_dependency 'rack-test', '> 0.7', '~> 2.0.2'
 
   s.files         = `git ls-files`.split("\n").reject { |f| f.start_with?('spec', 'features') }
   s.executables   = `git ls-files -- bin/*`.split("\n").map { |f| File.basename(f) }

Debdiff

Debdiff is too long (more than 200 lines). Download the raw debdiff.

More details

Full run details