From 7f08790ce1d7cd12ccd0aa9de114ca3366ab408c Mon Sep 17 00:00:00 2001 From: Jason Smith Date: Tue, 14 Dec 2021 16:06:03 -0500 Subject: [PATCH 1/2] FEAT: [#180578287] Add Yarn2 support --- lib/license_finder/package_managers/yarn.rb | 36 ++++++++- .../package_managers/yarn_spec.rb | 76 ++++++++++++++++--- 2 files changed, 97 insertions(+), 15 deletions(-) diff --git a/lib/license_finder/package_managers/yarn.rb b/lib/license_finder/package_managers/yarn.rb index 0c7683b5f..1bf5ad3e1 100644 --- a/lib/license_finder/package_managers/yarn.rb +++ b/lib/license_finder/package_managers/yarn.rb @@ -9,7 +9,7 @@ def possible_package_paths end def current_packages - cmd = "#{Yarn::SHELL_COMMAND}#{production_flag}" + cmd = "#{Yarn::SHELL_COMMAND}#{yarn1_production_flag}" suffix = " --cwd #{project_path}" unless project_path.nil? cmd += suffix unless suffix.nil? @@ -39,7 +39,7 @@ def current_packages end def prepare - prep_cmd = "#{prepare_command}#{production_flag}" + prep_cmd = "#{prepare_command}" _stdout, stderr, status = Dir.chdir(project_path) { Cmd.run(prep_cmd) } return if status.success? @@ -56,11 +56,33 @@ def package_management_command end def prepare_command - 'yarn install --ignore-engines --ignore-scripts' + if yarn2_project? + yarn2_prepare_command + else + yarn1_prepare_command + end end private + def yarn2_prepare_command + "#{yarn2_production_flag}yarn install" + end + + def yarn1_prepare_command + "yarn install --ignore-engines --ignore-scripts#{yarn1_production_flag}" + end + + def yarn2_project? + Dir.chdir(project_path) do + version_string, stderr_str, status = Cmd.run('yarn -v') + raise "Command 'yarn -v' failed to execute: #{stderr_str}" unless status.success? + + version = version_string.split('.').map { |v| v.to_i } + return version[0] >= 2 + end + end + def packages_from_json(json_data) body = json_data['body'] head = json_data['head'] @@ -98,10 +120,16 @@ def filter_yarn_internal_package(all_packages) all_packages - [yarn_internal_package] end - def production_flag + def yarn1_production_flag return '' if @ignored_groups.nil? @ignored_groups.include?('devDependencies') ? ' --production' : '' end + + def yarn2_production_flag + return '' if @ignored_groups.nil? + + @ignored_groups.include?('devDependencies') ? 'yarn plugin import workspace-tools && yarn workspaces focus --all --production && ' : '' + end end end diff --git a/spec/lib/license_finder/package_managers/yarn_spec.rb b/spec/lib/license_finder/package_managers/yarn_spec.rb index 11ef63e73..02d93b971 100644 --- a/spec/lib/license_finder/package_managers/yarn_spec.rb +++ b/spec/lib/license_finder/package_managers/yarn_spec.rb @@ -28,18 +28,48 @@ module LicenseFinder FileUtils.mkdir_p(root) end - it 'should call yarn install' do - expect(SharedHelpers::Cmd).to receive(:run).with('yarn install --ignore-engines --ignore-scripts') - .and_return([yarn_shell_command_output, '', cmd_success]) - subject.prepare + context 'when using Yarn 1.x projects' do + before do + allow(SharedHelpers::Cmd).to receive(:run).with('yarn -v').and_return(['1.9.4', '', cmd_success]) + end + + it 'should call yarn install with expected cli parameters' do + expect(SharedHelpers::Cmd).to receive(:run).with('yarn install --ignore-engines --ignore-scripts') + .and_return([yarn_shell_command_output, '', cmd_success]) + subject.prepare + end + + context 'ignored_groups contains devDependencies' do + subject { Yarn.new(project_path: Pathname(root), ignored_groups: 'devDependencies') } + it 'should include a production flag' do + expect(SharedHelpers::Cmd).to receive(:run).with('yarn install --ignore-engines --ignore-scripts --production') + .and_return([yarn_shell_command_output, '', cmd_success]) + subject.prepare + end + end end - context 'ignored_groups contains devDependencies' do - subject { Yarn.new(project_path: Pathname(root), ignored_groups: 'devDependencies') } - it 'should include a production flag' do - expect(SharedHelpers::Cmd).to receive(:run).with('yarn install --ignore-engines --ignore-scripts --production') + + context 'when using Yarn 2.x+ projects' do + before do + allow(SharedHelpers::Cmd).to receive(:run).with('yarn -v').and_return(['3.0.1', '', cmd_success]) + end + + it 'should call yarn install with no cli parameters' do + expect(SharedHelpers::Cmd).to receive(:run).with('yarn install') .and_return([yarn_shell_command_output, '', cmd_success]) subject.prepare end + + context 'ignored_groups contains devDependencies' do + subject { Yarn.new(project_path: Pathname(root), ignored_groups: 'devDependencies') } + + it 'should include a production flag' do + expect(SharedHelpers::Cmd).to receive(:run).with('yarn plugin import workspace-tools && yarn workspaces focus --all --production && yarn install') + .and_return([yarn_shell_command_output, '', cmd_success]) + subject.prepare + end + end + end end @@ -144,10 +174,34 @@ module LicenseFinder end describe '.prepare_command' do - subject { Yarn.new(project_path: Pathname(root), logger: double(:logger, active: nil)) } - it 'returns the correct prepare method' do - expect(subject.prepare_command).to eq('yarn install --ignore-engines --ignore-scripts') + include FakeFS::SpecHelpers + before do + FileUtils.mkdir_p(Dir.tmpdir) + FileUtils.mkdir_p(root) end + + context 'when in a Yarn 1.x project' do + before do + allow(SharedHelpers::Cmd).to receive(:run).with('yarn -v').and_return(['1.9.1', '', cmd_success]) + end + + subject { Yarn.new(project_path: Pathname(root), logger: double(:logger, active: nil)) } + it 'returns the correct prepare method' do + expect(subject.prepare_command).to eq('yarn install --ignore-engines --ignore-scripts') + end + end + + context 'when in a Yarn 2.x project' do + before do + allow(SharedHelpers::Cmd).to receive(:run).with('yarn -v').and_return(['3.5.9', '', cmd_success]) + end + + subject { Yarn.new(project_path: Pathname(root), logger: double(:logger, active: nil)) } + it 'returns the correct prepare method' do + expect(subject.prepare_command).to eq('yarn install') + end + end + end describe '.package_management_command' do From 2a9c93e645dd76fc525f303ffba4647849e00796 Mon Sep 17 00:00:00 2001 From: Jason Smith Date: Tue, 14 Dec 2021 16:51:32 -0500 Subject: [PATCH 2/2] FEAT: [#180578287] Add Yarn2 support Fixing Rubocop errors --- lib/license_finder/package_managers/yarn.rb | 4 ++-- spec/lib/license_finder/package_managers/yarn_spec.rb | 2 -- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/lib/license_finder/package_managers/yarn.rb b/lib/license_finder/package_managers/yarn.rb index 1bf5ad3e1..d02d14528 100644 --- a/lib/license_finder/package_managers/yarn.rb +++ b/lib/license_finder/package_managers/yarn.rb @@ -39,7 +39,7 @@ def current_packages end def prepare - prep_cmd = "#{prepare_command}" + prep_cmd = prepare_command.to_s _stdout, stderr, status = Dir.chdir(project_path) { Cmd.run(prep_cmd) } return if status.success? @@ -78,7 +78,7 @@ def yarn2_project? version_string, stderr_str, status = Cmd.run('yarn -v') raise "Command 'yarn -v' failed to execute: #{stderr_str}" unless status.success? - version = version_string.split('.').map { |v| v.to_i } + version = version_string.split('.').map(&:to_i) return version[0] >= 2 end end diff --git a/spec/lib/license_finder/package_managers/yarn_spec.rb b/spec/lib/license_finder/package_managers/yarn_spec.rb index 02d93b971..8b4121cb1 100644 --- a/spec/lib/license_finder/package_managers/yarn_spec.rb +++ b/spec/lib/license_finder/package_managers/yarn_spec.rb @@ -69,7 +69,6 @@ module LicenseFinder subject.prepare end end - end end @@ -201,7 +200,6 @@ module LicenseFinder expect(subject.prepare_command).to eq('yarn install') end end - end describe '.package_management_command' do