Module: Psdk::Cli::PSDK

Defined in:
lib/psdk/helpers/psdk.rb

Overview

Module holding all the utility to interact with PSDK repository

Constant Summary collapse

MAIN_REPOSITORY_URL =

Default URL to the PSDK repository

'https://gitlab.com/pokemonsdk/pokemonsdk.git'

Class Method Summary collapse

Class Method Details

.ensure_project_repositoryString

Ensure the project's pokemonsdk repository exists, cloning it if necessary

Returns:

  • (String)

    path to the project's pokemonsdk repository



167
168
169
170
171
172
173
174
175
176
177
# File 'lib/psdk/helpers/psdk.rb', line 167

def ensure_project_repository
  path = File.join(Configuration.project_path, 'pokemonsdk')
  return path if File.exist?(File.join(path, '.git'))

  raise "#{path} exists but is not a Git repository" if Dir.exist?(path)

  success = system('git', 'clone', MAIN_REPOSITORY_URL, path)
  raise "Failed to clone pokemonsdk into `#{path}`" unless success

  return path
end

.ensure_repository_clonedObject

Ensure the PSDK module is cloned



16
17
18
19
20
21
22
23
24
# File 'lib/psdk/helpers/psdk.rb', line 16

def ensure_repository_cloned
  return if Dir.exist?(File.join(repository_path, '.git'))

  res = system('git', 'clone', MAIN_REPOSITORY_URL, chdir: Configuration::PATH)
  return if res

  puts "[Error] Failed to setup pokemonsdk repository in `#{Configuration::PATH}`"
  exit(1)
end

.fetch_repository(path) ⇒ Object

Fetch the latest refs from origin

Parameters:

  • path (String)

    path to the repository



181
182
183
# File 'lib/psdk/helpers/psdk.rb', line 181

def fetch_repository(path)
  run_git(path, 'fetch', 'origin')
end

.git_project?(project_path) ⇒ Boolean

Check if the project is a git project

Parameters:

  • project_path (String)

    the path to the project

Returns:

  • (Boolean)


103
104
105
# File 'lib/psdk/helpers/psdk.rb', line 103

def git_project?(project_path)
  return File.exist?(File.join(project_path, '.git'))
end

.handle_non_submodule_folder(psdk_path, delete) ⇒ Object

Handle the pokemonsdk folder when it's not a submodule

Parameters:

  • psdk_path (String)

    the path to the pokemonsdk folder

  • delete (Boolean)

    if the folder should be deleted



92
93
94
95
96
97
98
# File 'lib/psdk/helpers/psdk.rb', line 92

def handle_non_submodule_folder(psdk_path, delete)
  if delete
    FileUtils.rm_rf(psdk_path)
  else
    rename_pokemonsdk_folder(psdk_path)
  end
end

.remove_submodule(project_path, delete) ⇒ Object

Remove the submodule

Parameters:

  • project_path (String)

    the path to the project

  • delete (Boolean)

    if the folder should be deleted



117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
# File 'lib/psdk/helpers/psdk.rb', line 117

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

.rename_pokemonsdk_folder(psdk_path) ⇒ Object

Rename the pokemonsdk folder

Parameters:

  • psdk_path (String)

    the path to the pokemonsdk folder



142
143
144
145
146
147
148
149
150
# File 'lib/psdk/helpers/psdk.rb', line 142

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

.repository_pathString

Get the repository path

Returns:

  • (String)


28
29
30
# File 'lib/psdk/helpers/psdk.rb', line 28

def repository_path
  return File.join(Configuration::PATH, 'pokemonsdk')
end

.run_git(path, *arguments) ⇒ String

Run a git command in the given repository and return its output

Parameters:

  • path (String)

    path to the repository

  • arguments (Array<String>)

    git subcommand and its arguments

Returns:

  • (String)

    the stripped stdout of the command



189
190
191
192
193
194
# File 'lib/psdk/helpers/psdk.rb', line 189

def run_git(path, *arguments)
  output = IO.popen(['git', *arguments], chdir: path, &:read)
  return output.strip if $?.success? # rubocop:disable Style/SpecialGlobalVars

  raise "git #{arguments.join(' ')} failed"
end

.show_active_target(path, target) ⇒ Object

Show the confirmation message for the currently active PSDK target

Parameters:

  • path (String)

    path to the repository

  • target (String)

    human-readable description of the active target



199
200
201
202
203
204
# File 'lib/psdk/helpers/psdk.rb', line 199

def show_active_target(path, target)
  commit = run_git(path, 'rev-parse', '--short', 'HEAD')
  version = File.read(File.join(path, 'version.txt')).to_i
  version_string = [version].pack('I>').unpack('C*').join('.').gsub(/^(0\.)+/, '')
  puts "Active PSDK: #{target} (version #{version_string}, commit #{commit})"
end

.show_remove_submodule_delete_errorObject

Show the error message when attempting to delete the pokemonsdk submodule



134
135
136
137
138
# File 'lib/psdk/helpers/psdk.rb', line 134

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

.show_switch_error(error) ⇒ Object

Show the error message when a PSDK switch operation fails

Parameters:

  • error (StandardError)

    the error that was raised



208
209
210
211
# File 'lib/psdk/helpers/psdk.rb', line 208

def show_switch_error(error)
  puts "[Error] Failed to switch PSDK: #{error.message}"
  exit(1)
end

.submodule?(project_path) ⇒ Boolean

Check if the project is a submodule

Parameters:

  • project_path (String)

    the path to the project

Returns:

  • (Boolean)


110
111
112
# File 'lib/psdk/helpers/psdk.rb', line 110

def submodule?(project_path)
  return system('git', 'submodule', 'status', 'pokemonsdk', chdir: project_path, out: File::NULL, err: File::NULL)
end

.switch_project_repository(target) {|path| ... } ⇒ Object

Run a repository switch: resolve the project's pokemonsdk path, apply the given block, then refresh submodules and report the active target

Parameters:

  • target (String)

    human-readable description of the switch target, used in the confirmation message

Yield Parameters:

  • path (String)

    path to the project's pokemonsdk repository



156
157
158
159
160
161
162
163
# File 'lib/psdk/helpers/psdk.rb', line 156

def switch_project_repository(target)
  path = ensure_project_repository
  yield(path)
  run_git(path, 'submodule', 'update', '--init', '--recursive')
  show_active_target(path, target)
rescue StandardError => e
  show_switch_error(e)
end

.unuse_local_pokemonsdk(delete:) ⇒ Object

Unuse the local pokemonsdk folder (meaning we want the project to fallback on Pokémon Studio's PSDK)

Parameters:

  • delete (Boolean)

    if the folder should be deleted



75
76
77
78
79
80
81
82
83
84
85
86
87
# File 'lib/psdk/helpers/psdk.rb', line 75

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

.use_commit(commit) ⇒ Object

Make the project use a specific PSDK commit

Parameters:

  • commit (String)

    commit identifier (e.g., "deadcafe")



47
48
49
50
51
52
53
# File 'lib/psdk/helpers/psdk.rb', line 47

def use_commit(commit)
  switch_project_repository("commit #{commit}") do |path|
    fetch_repository(path)
    resolved_commit = run_git(path, 'rev-parse', '--verify', '--end-of-options', "#{commit}^{commit}")
    run_git(path, 'checkout', '--detach', resolved_commit)
  end
end

.use_latestObject

Make the project use the latest development commit



66
67
68
69
70
71
# File 'lib/psdk/helpers/psdk.rb', line 66

def use_latest
  switch_project_repository('latest development commit') do |path|
    fetch_repository(path)
    run_git(path, 'checkout', '-B', 'development', 'origin/development')
  end
end

.use_mr(id) ⇒ Object

Make the project use the head of a GitLab merge request

Parameters:

  • id (String)

    merge request ID (e.g., "123")



57
58
59
60
61
62
63
# File 'lib/psdk/helpers/psdk.rb', line 57

def use_mr(id)
  switch_project_repository("merge request !#{id}") do |path|
    ref = "refs/remotes/origin/merge-requests/#{id}"
    run_git(path, 'fetch', 'origin', "+refs/merge-requests/#{id}/head:#{ref}")
    run_git(path, 'checkout', '-B', "mr-#{id}", ref)
  end
end

.use_version(version) ⇒ Object

Make the project use an official PSDK release

Parameters:

  • version (String)

    release identifier (e.g., "26.58")



34
35
36
37
38
39
40
41
42
43
# File 'lib/psdk/helpers/psdk.rb', line 34

def use_version(version)
  switch_project_repository("official release #{version}") do |path|
    fetch_repository(path)
    commit = run_git(path, 'log', '--format=%H', '--extended-regexp',
                     "--grep=^Release #{Regexp.escape(version)}$", '--max-count=1', 'origin/release')
    raise "PSDK release #{version} was not found" if commit.empty?

    run_git(path, 'checkout', '--detach', commit)
  end
end