From 31f019e2aa0be11341ad7c39c600a6b32da8d6d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Thu, 2 Nov 2023 22:41:05 +0100 Subject: [PATCH] Raise user error when Yarn is misconfigured --- common/lib/dependabot/errors.rb | 21 ++++++++++++++ .../lib/dependabot/npm_and_yarn/helpers.rb | 11 +++++++ .../update_checker/version_resolver_spec.rb | 22 ++++++++++++++ .../yarn_berry/misconfigured/.yarnrc.yml | 1 + .../yarn_berry/misconfigured/package.json | 16 ++++++++++ .../yarn_berry/misconfigured/yarn.lock | 29 +++++++++++++++++++ .../lib/dependabot/update_files_command.rb | 5 ++++ 7 files changed, 105 insertions(+) create mode 100644 npm_and_yarn/spec/fixtures/projects/yarn_berry/misconfigured/.yarnrc.yml create mode 100644 npm_and_yarn/spec/fixtures/projects/yarn_berry/misconfigured/package.json create mode 100644 npm_and_yarn/spec/fixtures/projects/yarn_berry/misconfigured/yarn.lock diff --git a/common/lib/dependabot/errors.rb b/common/lib/dependabot/errors.rb index ddc1a4e05811..2b62d5cabb79 100644 --- a/common/lib/dependabot/errors.rb +++ b/common/lib/dependabot/errors.rb @@ -109,6 +109,27 @@ def initialize(source, msg = nil) # File level errors # ##################### + class MisconfiguredTool < DependabotError + extend T::Sig + + sig { returns(String) } + attr_reader :tool_name + + sig do + params( + tool_name: String, + msg: String + ).void + end + def initialize(tool_name, msg) + @tool_name = tool_name + + msg = "Dependabot detected that #{tool_name} is misconfigured in this repository. " \ + "Running `#{tool_name.downcase}` results in the following error: #{msg}" + super(msg) + end + end + class ToolVersionNotSupported < DependabotError extend T::Sig diff --git a/npm_and_yarn/lib/dependabot/npm_and_yarn/helpers.rb b/npm_and_yarn/lib/dependabot/npm_and_yarn/helpers.rb index 6548196561c2..c309fae15dbf 100644 --- a/npm_and_yarn/lib/dependabot/npm_and_yarn/helpers.rb +++ b/npm_and_yarn/lib/dependabot/npm_and_yarn/helpers.rb @@ -4,6 +4,8 @@ module Dependabot module NpmAndYarn module Helpers + YARN_PATH_NOT_FOUND = /^.*(?The "yarn-path" option has been set.*)/ + def self.npm_version(lockfile_content) "npm#{npm_version_numeric(lockfile_content)}" end @@ -57,6 +59,15 @@ def self.yarn_major_version def self.fetch_yarn_major_version output = SharedHelpers.run_shell_command("yarn --version") Version.new(output).major + rescue SharedHelpers::HelperSubprocessFailed => e + message = e.message + + if YARN_PATH_NOT_FOUND.match?(message) + error = T.must(T.must(YARN_PATH_NOT_FOUND.match(message))[:error]).gsub(Dir.pwd, ".") + raise MisconfiguredTool.new("Yarn", error) + end + + raise end def self.yarn_zero_install? diff --git a/npm_and_yarn/spec/dependabot/npm_and_yarn/update_checker/version_resolver_spec.rb b/npm_and_yarn/spec/dependabot/npm_and_yarn/update_checker/version_resolver_spec.rb index 67104b3dbc11..8f0f5c4d397b 100644 --- a/npm_and_yarn/spec/dependabot/npm_and_yarn/update_checker/version_resolver_spec.rb +++ b/npm_and_yarn/spec/dependabot/npm_and_yarn/update_checker/version_resolver_spec.rb @@ -80,6 +80,28 @@ describe "#latest_resolvable_version" do subject { resolver.latest_resolvable_version } + context "with a misconfigured yarn-berry project" do + let(:project_name) { "yarn_berry/misconfigured" } + let(:latest_allowable_version) { Gem::Version.new("1.3.0") } + let(:dependency) do + Dependabot::Dependency.new( + name: "left-pad", + version: "1.0.1", + requirements: [{ + file: "package.json", + requirement: "^1.0.1", + groups: ["dependencies"], + source: { type: "registry", url: "https://registry.npmjs.org" } + }], + package_manager: "npm_and_yarn" + ) + end + + it "raises a Dependabot::MisconfiguredTool error" do + expect { subject }.to raise_error(Dependabot::MisconfiguredTool) + end + end + context "with an npm 8 package-lock.json using the v3 lockfile format" do context "updating a dependency without peer dependency issues" do let(:project_name) { "npm8/package-lock-v3" } diff --git a/npm_and_yarn/spec/fixtures/projects/yarn_berry/misconfigured/.yarnrc.yml b/npm_and_yarn/spec/fixtures/projects/yarn_berry/misconfigured/.yarnrc.yml new file mode 100644 index 000000000000..6d57ac04916a --- /dev/null +++ b/npm_and_yarn/spec/fixtures/projects/yarn_berry/misconfigured/.yarnrc.yml @@ -0,0 +1 @@ +yarnPath: .yarn/releases/yarn-3.5.1.cjs diff --git a/npm_and_yarn/spec/fixtures/projects/yarn_berry/misconfigured/package.json b/npm_and_yarn/spec/fixtures/projects/yarn_berry/misconfigured/package.json new file mode 100644 index 000000000000..6752ce72683d --- /dev/null +++ b/npm_and_yarn/spec/fixtures/projects/yarn_berry/misconfigured/package.json @@ -0,0 +1,16 @@ +{ + "name": "original", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "", + "license": "ISC", + "dependencies": { + "is-positive": "3.1.0", + "left-pad": "^1.0.1" + }, + "packageManager": "yarn@3.5.1" +} diff --git a/npm_and_yarn/spec/fixtures/projects/yarn_berry/misconfigured/yarn.lock b/npm_and_yarn/spec/fixtures/projects/yarn_berry/misconfigured/yarn.lock new file mode 100644 index 000000000000..df60ddc2b36f --- /dev/null +++ b/npm_and_yarn/spec/fixtures/projects/yarn_berry/misconfigured/yarn.lock @@ -0,0 +1,29 @@ +# This file is generated by running "yarn install" inside your project. +# Manual changes might be lost - proceed with caution! + +__metadata: + version: 6 + cacheKey: 8 + +"is-positive@npm:3.1.0": + version: 3.1.0 + resolution: "is-positive@npm:3.1.0" + checksum: 3675229110735f470860b5fe0740dae1baa9d6f7c6a69f25116aa1888cbc3d092f068f6f94219c290022d0e334f1c82db3041286236ae8a8e132146fd7bcf99d + languageName: node + linkType: hard + +"left-pad@npm:^1.0.1": + version: 1.3.0 + resolution: "left-pad@npm:1.3.0" + checksum: 13fa96e17b70a54836490de22d4bab706e2ed508338bbabecfac72ecce445a74139c5b009a8112252cab8fc4ab7ac4ebd870e5b35bd236b443b12be96f8745ac + languageName: node + linkType: hard + +"original@workspace:.": + version: 0.0.0-use.local + resolution: "original@workspace:." + dependencies: + is-positive: 3.1.0 + left-pad: ^1.0.1 + languageName: unknown + linkType: soft diff --git a/updater/lib/dependabot/update_files_command.rb b/updater/lib/dependabot/update_files_command.rb index c30309992d1e..c0d32cec5cd6 100644 --- a/updater/lib/dependabot/update_files_command.rb +++ b/updater/lib/dependabot/update_files_command.rb @@ -112,6 +112,11 @@ def handle_parser_error(error) "error-type": "git_dependencies_not_reachable", "error-detail": { "dependency-urls": error.dependency_urls } } + when Dependabot::MisconfiguredTool + { + "error-type": "misconfigured_tool", + "error-detail": { "tool-name": error.tool_name, message: error.message } + } when Dependabot::NotImplemented { "error-type": "not_implemented",