From 335b52e1f945fbd604969f5902fae4162a8fcd3a Mon Sep 17 00:00:00 2001 From: Nuri Yuri Date: Thu, 1 Jan 2026 17:49:52 +0100 Subject: [PATCH 1/2] Handle the psdk-use studio command #15 #16 --- .rubocop.yml | 2 + Gemfile | 2 + Gemfile.lock | 2 + lib/psdk/cli/use.rb | 9 +-- lib/psdk/helpers/psdk.rb | 80 +++++++++++++++++++ spec/psdk/helpers/psdk_spec.rb | 141 +++++++++++++++++++++++++++++++++ 6 files changed, 229 insertions(+), 7 deletions(-) create mode 100644 spec/psdk/helpers/psdk_spec.rb diff --git a/.rubocop.yml b/.rubocop.yml index c365e01..609491a 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -2,6 +2,8 @@ AllCops: TargetRubyVersion: 3.2 NewCops: enable SuggestExtensions: false + Exclude: + - 'spec/**/*' Style/StringLiterals: EnforcedStyle: single_quotes diff --git a/Gemfile b/Gemfile index a45fcd0..8d866e5 100644 --- a/Gemfile +++ b/Gemfile @@ -13,3 +13,5 @@ gem 'rspec', '~> 3.0' gem 'rubocop', '~> 1.21' gem 'thor', '~> 1.4.0' + +gem 'fileutils', '~> 1.5.0' diff --git a/Gemfile.lock b/Gemfile.lock index 50ffa79..39616f2 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -10,6 +10,7 @@ GEM date (3.5.0) diff-lcs (1.6.2) erb (5.1.3) + fileutils (1.5.0) io-console (0.8.1) irb (1.15.3) pp (>= 0.6.0) @@ -79,6 +80,7 @@ PLATFORMS ruby DEPENDENCIES + fileutils (~> 1.5.0) irb psdk-cli! rake (~> 13.0) diff --git a/lib/psdk/cli/use.rb b/lib/psdk/cli/use.rb index 707c919..157ae86 100644 --- a/lib/psdk/cli/use.rb +++ b/lib/psdk/cli/use.rb @@ -13,13 +13,8 @@ class Use < Thor desc: 'delete local pokemonsdk folder' def studio ensure_project - # should_delete_local_pokemonsdk_folder = options[:delete] - # if should_delete_local_pokemonsdk_folder - # # TODO: delete pokemonsdk folder from project, remove submodule if it is a submodule - # else - # # TODO: rename pokemonsdk folder from project, remove submodule if it is a submodule - # end - puts options[:delete] + require_relative '../helpers/psdk' + PSDK.unuse_local_pokemonsdk(delete: options[:delete]) end desc 'version PSDK_VERSION', 'make the project use a specific PSDK version' diff --git a/lib/psdk/helpers/psdk.rb b/lib/psdk/helpers/psdk.rb index 66fdc82..7ad890c 100644 --- a/lib/psdk/helpers/psdk.rb +++ b/lib/psdk/helpers/psdk.rb @@ -1,6 +1,7 @@ # frozen_string_literal: true require_relative '../cli/configuration' +require 'fileutils' module Psdk module Cli @@ -27,6 +28,85 @@ def ensure_repository_cloned def repository_path return File.join(Configuration::PATH, 'pokemonsdk') end + + # Unuse the local pokemonsdk folder (meaning we want the project to fallback on Pokémon Studio's PSDK) + # @param delete [Boolean] if the folder should be deleted + def unuse_local_pokemonsdk(delete:) + project_path = Configuration.project_path + psdk_path = File.join(project_path, 'pokemonsdk') + return unless Dir.exist?(psdk_path) + + if git_project?(project_path) && submodule?(project_path) + remove_submodule(project_path, delete) + else + handle_non_submodule_folder(psdk_path, delete) + end + ensure + puts "Successfully set project to use Pokémon Studio's PSDK version" + end + + # Handle the pokemonsdk folder when it's not a submodule + # @param psdk_path [String] the path to the pokemonsdk folder + # @param delete [Boolean] if the folder should be deleted + def handle_non_submodule_folder(psdk_path, delete) + if delete + FileUtils.rm_rf(psdk_path) + else + rename_pokemonsdk_folder(psdk_path) + end + end + + # Check if the project is a git project + # @param project_path [String] the path to the project + # @return [Boolean] + def git_project?(project_path) + return File.exist?(File.join(project_path, '.git')) + end + + # Check if the project is a submodule + # @param project_path [String] the path to the project + # @return [Boolean] + def submodule?(project_path) + return system('git', 'submodule', 'status', 'pokemonsdk', chdir: project_path, out: File::NULL, err: File::NULL) + end + + # Remove the submodule + # @param project_path [String] the path to the project + # @param delete [Boolean] if the folder should be deleted + def remove_submodule(project_path, delete) + return show_remove_submodule_delete_error unless delete + + r = system('git', 'submodule', 'deinit', '-f', 'pokemonsdk', chdir: project_path, out: File::NULL, err: File::NULL) + raise 'Failed to deinit pokemonsdk submodule' unless r + + r = system('git', 'rm', '-f', 'pokemonsdk', chdir: project_path, out: File::NULL, err: File::NULL) + raise 'Failed to remove pokemonsdk submodule' unless r + + FileUtils.rm_rf(File.join(project_path, '.git', 'modules', 'pokemonsdk')) + puts 'Successfully removed the submodule' + rescue StandardError => e + puts "[Error] Failed to remove the submodule (#{e.message})" + exit(1) + end + + # Show the error message when attempting to delete the pokemonsdk submodule + def show_remove_submodule_delete_error + puts "[Error] Cannot use Studio's PSDK version if the project has a submodule." + puts 'Please follow this guide to remove the submodule: https://stackoverflow.com/a/1260982' + exit(1) + end + + # Rename the pokemonsdk folder + # @param psdk_path [String] the path to the pokemonsdk folder + def rename_pokemonsdk_folder(psdk_path) + new_path = "#{psdk_path}_old" + if File.exist?(new_path) + puts "[Error] Folder `#{new_path}` already exists. Please remove it manually." + exit(1) + else + File.rename(psdk_path, new_path) + end + end end end end diff --git a/spec/psdk/helpers/psdk_spec.rb b/spec/psdk/helpers/psdk_spec.rb new file mode 100644 index 0000000..a3dee17 --- /dev/null +++ b/spec/psdk/helpers/psdk_spec.rb @@ -0,0 +1,141 @@ +# frozen_string_literal: true + +require 'spec_helper' +require 'psdk/helpers/psdk' + +RSpec.describe Psdk::Cli::PSDK do + describe '.unuse_local_pokemonsdk' do + let(:project_path) { '/path/to/project' } + let(:psdk_path) { File.join(project_path, 'pokemonsdk') } + let(:delete_option) { false } + + before do + allow(Psdk::Cli::Configuration).to receive(:project_path).and_return(project_path) + allow(File).to receive(:join).with(project_path, 'pokemonsdk').and_return(psdk_path) + # Allow File.join with other arguments to work as usual + allow(File).to receive(:join).and_call_original + allow(Psdk::Cli::PSDK).to receive(:puts) + allow(Psdk::Cli::PSDK).to receive(:exit) { raise 'Exited 1' } + allow(FileUtils).to receive(:rm_rf) + allow(File).to receive(:rename) + allow(Psdk::Cli::PSDK).to receive(:system) + end + + context 'when psdk folder does not exist' do + before do + allow(Dir).to receive(:exist?).with(psdk_path).and_return(false) + end + + it 'does nothing' do + expect(Psdk::Cli::PSDK).not_to receive(:git_project?) + expect(FileUtils).not_to receive(:rm_rf) + expect(File).not_to receive(:rename) + + Psdk::Cli::PSDK.unuse_local_pokemonsdk(delete: delete_option) + end + end + + context 'when psdk folder exists' do + before do + allow(Dir).to receive(:exist?).with(psdk_path).and_return(true) + # Default non-git, non-submodule for basic checking unless overridden + allow(Psdk::Cli::PSDK).to receive(:git_project?).with(project_path).and_return(false) + allow(Psdk::Cli::PSDK).to receive(:submodule?).with(project_path).and_return(false) + end + + context 'when it is not a git submodule' do + context 'with delete: true' do + let(:delete_option) { true } + + it 'deletes the folder' do + expect(FileUtils).to receive(:rm_rf).with(psdk_path) + expect(Psdk::Cli::PSDK).to receive(:puts).with("Successfully set project to use Pokémon Studio's PSDK version") + + Psdk::Cli::PSDK.unuse_local_pokemonsdk(delete: delete_option) + end + end + + context 'with delete: false' do + let(:delete_option) { false } + let(:new_path) { "#{psdk_path}_old" } + + context 'when _old folder already exists' do + before do + allow(File).to receive(:exist?).with(new_path).and_return(true) + end + + it 'exits with error' do + expect(Psdk::Cli::PSDK).to receive(:puts).with("[Error] Folder `#{new_path}` already exists. Please remove it manually.") + expect { Psdk::Cli::PSDK.unuse_local_pokemonsdk(delete: delete_option) }.to raise_error('Exited 1') + end + end + + context 'when _old folder does not exist' do + before do + allow(File).to receive(:exist?).with(new_path).and_return(false) + end + + it 'renames the folder' do + expect(File).to receive(:rename).with(psdk_path, new_path) + expect(Psdk::Cli::PSDK).to receive(:puts).with("Successfully set project to use Pokémon Studio's PSDK version") + + Psdk::Cli::PSDK.unuse_local_pokemonsdk(delete: delete_option) + end + end + end + end + + context 'when it IS a git submodule' do + before do + allow(Psdk::Cli::PSDK).to receive(:git_project?).with(project_path).and_return(true) + allow(Psdk::Cli::PSDK).to receive(:submodule?).with(project_path).and_return(true) + end + + context 'with delete: false' do + let(:delete_option) { false } + + it 'exits with error advising to remove submodule manually' do + expect(Psdk::Cli::PSDK).to receive(:puts).with("[Error] Cannot use Studio's PSDK version if the project has a submodule.") + expect(Psdk::Cli::PSDK).to receive(:puts).with('Please follow this guide to remove the submodule: https://stackoverflow.com/a/1260982') + expect { Psdk::Cli::PSDK.unuse_local_pokemonsdk(delete: delete_option) }.to raise_error('Exited 1') + end + end + + context 'with delete: true' do + let(:delete_option) { true } + + it 'removes the submodule successfully' do + # Mock successful git commands + expect(Psdk::Cli::PSDK).to receive(:system).with('git', 'submodule', 'deinit', '-f', 'pokemonsdk', + chdir: project_path, out: File::NULL, err: File::NULL).and_return(true) + expect(Psdk::Cli::PSDK).to receive(:system).with('git', 'rm', '-f', 'pokemonsdk', chdir: project_path, + out: File::NULL, err: File::NULL).and_return(true) + + # Module folder cleanup + expect(FileUtils).to receive(:rm_rf).with(File.join(project_path, '.git', 'modules', 'pokemonsdk')) + + expect(Psdk::Cli::PSDK).to receive(:puts).with('Successfully removed the submodule') + expect(Psdk::Cli::PSDK).to receive(:puts).with("Successfully set project to use Pokémon Studio's PSDK version") + + Psdk::Cli::PSDK.unuse_local_pokemonsdk(delete: delete_option) + end + + it 'fails to deinit submodule' do + expect(Psdk::Cli::PSDK).to receive(:system).with('git', 'submodule', 'deinit', any_args).and_return(false) + + expect(Psdk::Cli::PSDK).to receive(:puts).with('[Error] Failed to remove the submodule (Failed to deinit pokemonsdk submodule)') + expect { Psdk::Cli::PSDK.unuse_local_pokemonsdk(delete: delete_option) }.to raise_error('Exited 1') + end + + it 'fails to remove submodule' do + expect(Psdk::Cli::PSDK).to receive(:system).with('git', 'submodule', 'deinit', any_args).and_return(true) + expect(Psdk::Cli::PSDK).to receive(:system).with('git', 'rm', any_args).and_return(false) + + expect(Psdk::Cli::PSDK).to receive(:puts).with('[Error] Failed to remove the submodule (Failed to remove pokemonsdk submodule)') + expect { Psdk::Cli::PSDK.unuse_local_pokemonsdk(delete: delete_option) }.to raise_error('Exited 1') + end + end + end + end + end +end From b1e4ac84360e3494cd40981fd40625a472c32929 Mon Sep 17 00:00:00 2001 From: Nuri Yuri Date: Thu, 1 Jan 2026 18:13:00 +0100 Subject: [PATCH 2/2] Check if hangup comes from exclusion in rubocop --- .rubocop.yml | 2 -- spec/psdk/helpers/psdk_spec.rb | 40 +++++++++++++++++++++++----------- 2 files changed, 27 insertions(+), 15 deletions(-) diff --git a/.rubocop.yml b/.rubocop.yml index 609491a..c365e01 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -2,8 +2,6 @@ AllCops: TargetRubyVersion: 3.2 NewCops: enable SuggestExtensions: false - Exclude: - - 'spec/**/*' Style/StringLiterals: EnforcedStyle: single_quotes diff --git a/spec/psdk/helpers/psdk_spec.rb b/spec/psdk/helpers/psdk_spec.rb index a3dee17..c9db673 100644 --- a/spec/psdk/helpers/psdk_spec.rb +++ b/spec/psdk/helpers/psdk_spec.rb @@ -3,8 +3,8 @@ require 'spec_helper' require 'psdk/helpers/psdk' -RSpec.describe Psdk::Cli::PSDK do - describe '.unuse_local_pokemonsdk' do +RSpec.describe Psdk::Cli::PSDK do # rubocop:disable Metrics/BlockLength + describe '.unuse_local_pokemonsdk' do # rubocop:disable Metrics/BlockLength let(:project_path) { '/path/to/project' } let(:psdk_path) { File.join(project_path, 'pokemonsdk') } let(:delete_option) { false } @@ -35,7 +35,7 @@ end end - context 'when psdk folder exists' do + context 'when psdk folder exists' do # rubocop:disable Metrics/BlockLength before do allow(Dir).to receive(:exist?).with(psdk_path).and_return(true) # Default non-git, non-submodule for basic checking unless overridden @@ -43,13 +43,15 @@ allow(Psdk::Cli::PSDK).to receive(:submodule?).with(project_path).and_return(false) end - context 'when it is not a git submodule' do + context 'when it is not a git submodule' do # rubocop:disable Metrics/BlockLength context 'with delete: true' do let(:delete_option) { true } it 'deletes the folder' do expect(FileUtils).to receive(:rm_rf).with(psdk_path) - expect(Psdk::Cli::PSDK).to receive(:puts).with("Successfully set project to use Pokémon Studio's PSDK version") + expect(Psdk::Cli::PSDK).to receive(:puts).with( + "Successfully set project to use Pokémon Studio's PSDK version" + ) Psdk::Cli::PSDK.unuse_local_pokemonsdk(delete: delete_option) end @@ -65,7 +67,9 @@ end it 'exits with error' do - expect(Psdk::Cli::PSDK).to receive(:puts).with("[Error] Folder `#{new_path}` already exists. Please remove it manually.") + expect(Psdk::Cli::PSDK).to receive(:puts).with( + "[Error] Folder `#{new_path}` already exists. Please remove it manually." + ) expect { Psdk::Cli::PSDK.unuse_local_pokemonsdk(delete: delete_option) }.to raise_error('Exited 1') end end @@ -77,7 +81,9 @@ it 'renames the folder' do expect(File).to receive(:rename).with(psdk_path, new_path) - expect(Psdk::Cli::PSDK).to receive(:puts).with("Successfully set project to use Pokémon Studio's PSDK version") + expect(Psdk::Cli::PSDK).to receive(:puts).with( + "Successfully set project to use Pokémon Studio's PSDK version" + ) Psdk::Cli::PSDK.unuse_local_pokemonsdk(delete: delete_option) end @@ -85,7 +91,7 @@ end end - context 'when it IS a git submodule' do + context 'when it IS a git submodule' do # rubocop:disable Metrics/BlockLength before do allow(Psdk::Cli::PSDK).to receive(:git_project?).with(project_path).and_return(true) allow(Psdk::Cli::PSDK).to receive(:submodule?).with(project_path).and_return(true) @@ -95,13 +101,15 @@ let(:delete_option) { false } it 'exits with error advising to remove submodule manually' do - expect(Psdk::Cli::PSDK).to receive(:puts).with("[Error] Cannot use Studio's PSDK version if the project has a submodule.") + expect(Psdk::Cli::PSDK).to receive(:puts).with( + "[Error] Cannot use Studio's PSDK version if the project has a submodule." + ) expect(Psdk::Cli::PSDK).to receive(:puts).with('Please follow this guide to remove the submodule: https://stackoverflow.com/a/1260982') expect { Psdk::Cli::PSDK.unuse_local_pokemonsdk(delete: delete_option) }.to raise_error('Exited 1') end end - context 'with delete: true' do + context 'with delete: true' do # rubocop:disable Metrics/BlockLength let(:delete_option) { true } it 'removes the submodule successfully' do @@ -115,7 +123,9 @@ expect(FileUtils).to receive(:rm_rf).with(File.join(project_path, '.git', 'modules', 'pokemonsdk')) expect(Psdk::Cli::PSDK).to receive(:puts).with('Successfully removed the submodule') - expect(Psdk::Cli::PSDK).to receive(:puts).with("Successfully set project to use Pokémon Studio's PSDK version") + expect(Psdk::Cli::PSDK).to receive(:puts).with( + "Successfully set project to use Pokémon Studio's PSDK version" + ) Psdk::Cli::PSDK.unuse_local_pokemonsdk(delete: delete_option) end @@ -123,7 +133,9 @@ it 'fails to deinit submodule' do expect(Psdk::Cli::PSDK).to receive(:system).with('git', 'submodule', 'deinit', any_args).and_return(false) - expect(Psdk::Cli::PSDK).to receive(:puts).with('[Error] Failed to remove the submodule (Failed to deinit pokemonsdk submodule)') + expect(Psdk::Cli::PSDK).to receive(:puts).with( + '[Error] Failed to remove the submodule (Failed to deinit pokemonsdk submodule)' + ) expect { Psdk::Cli::PSDK.unuse_local_pokemonsdk(delete: delete_option) }.to raise_error('Exited 1') end @@ -131,7 +143,9 @@ expect(Psdk::Cli::PSDK).to receive(:system).with('git', 'submodule', 'deinit', any_args).and_return(true) expect(Psdk::Cli::PSDK).to receive(:system).with('git', 'rm', any_args).and_return(false) - expect(Psdk::Cli::PSDK).to receive(:puts).with('[Error] Failed to remove the submodule (Failed to remove pokemonsdk submodule)') + expect(Psdk::Cli::PSDK).to receive(:puts).with( + '[Error] Failed to remove the submodule (Failed to remove pokemonsdk submodule)' + ) expect { Psdk::Cli::PSDK.unuse_local_pokemonsdk(delete: delete_option) }.to raise_error('Exited 1') end end