Class: Fastlane::Helper::GodotHelper

Inherits:
Object
  • Object
show all
Defined in:
lib/fastlane/plugin/godot/helper/godot_helper.rb

Constant Summary collapse

PLATFORM_TEMPLATE_FILES =

The template archive each platform's export requires, keyed by the platform string Godot writes into export_presets.cfg.

{
  'iOS' => ['ios.zip'],
  'Android' => ['android_debug.apk', 'android_release.apk', 'android_source.zip'],
  'macOS' => ['macos.zip'],
  'Web' => ['web_release.zip', 'web_debug.zip']
}.freeze
COMMON_BINARY_LOCATIONS =

Where the godot binary lives when it isn't simply on the PATH.

[
  '/Applications/Godot.app/Contents/MacOS/Godot',
  '/opt/homebrew/bin/godot',
  '/usr/local/bin/godot',
  '/usr/bin/godot'
].freeze

Class Method Summary collapse

Class Method Details

.discover_godot_binary(configured) ⇒ Object



110
111
112
113
114
115
116
117
# File 'lib/fastlane/plugin/godot/helper/godot_helper.rb', line 110

def self.discover_godot_binary(configured)
  return configured unless configured == 'godot'
  return configured unless `which godot 2>/dev/null`.strip.empty?
  found = ENV['GODOT'] || COMMON_BINARY_LOCATIONS.find { |path| File.executable?(path) }
  UI.user_error!("Could not find a Godot binary — none on the PATH, no GODOT environment variable, and nothing at: #{COMMON_BINARY_LOCATIONS.join(', ')}") unless found
  UI.message("Using Godot binary at #{found}")
  found
end

.find_preset(cfg_path, preset_name) ⇒ Object



56
57
58
59
60
61
62
63
64
# File 'lib/fastlane/plugin/godot/helper/godot_helper.rb', line 56

def self.find_preset(cfg_path, preset_name)
  presets = parse_presets(cfg_path)
  preset = presets.find { |p| p[:name] == preset_name }
  unless preset
    available = presets.map { |p| "'#{p[:name]}' (#{p[:platform]})" }.join(', ')
    UI.user_error!("No export preset named '#{preset_name}' in #{cfg_path}. Available presets: #{available.empty? ? 'none' : available}")
  end
  preset
end

.godot_version(godot_binary) ⇒ Object

Full version string, e.g. "4.7.1.stable.official.a13da4feb"



9
10
11
12
13
# File 'lib/fastlane/plugin/godot/helper/godot_helper.rb', line 9

def self.godot_version(godot_binary)
  output = `#{godot_binary.shellescape} --version 2>/dev/null`.strip
  UI.user_error!("Could not run '#{godot_binary} --version' — is Godot installed and on the PATH?") if output.empty?
  output.lines.last.strip
end

.parse_presets(cfg_path) ⇒ Object

Minimal parse of export_presets.cfg: the preset headers plus the name/platform/export_path lines that follow each one.



33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
# File 'lib/fastlane/plugin/godot/helper/godot_helper.rb', line 33

def self.parse_presets(cfg_path)
  UI.user_error!("No export_presets.cfg found at #{cfg_path} — create an export preset first (Project > Export in the Godot editor, or commit one)") unless File.exist?(cfg_path)

  presets = []
  current = nil
  File.foreach(cfg_path) do |line|
    case line
    when /^\[preset\.\d+\]\s*$/
      current = {}
      presets << current
    when /^\[preset\.\d+\.options\]\s*$/
      current = nil
    when /^name="(.*)"\s*$/
      current[:name] = Regexp.last_match(1) if current
    when /^platform="(.*)"\s*$/
      current[:platform] = Regexp.last_match(1) if current
    when /^export_path="(.*)"\s*$/
      current[:export_path] = Regexp.last_match(1) if current
    end
  end
  presets
end

.project_feature_version(project_path) ⇒ Object

The engine version a project declares, e.g. "4.7" from config/features=PackedStringArray("4.7", "GL Compatibility")



77
78
79
80
81
82
83
84
85
86
87
# File 'lib/fastlane/plugin/godot/helper/godot_helper.rb', line 77

def self.project_feature_version(project_path)
  project_file = File.join(project_path, 'project.godot')
  return nil unless File.exist?(project_file)
  File.foreach(project_file) do |line|
    match = line.match(/^config\/features=PackedStringArray\((.*)\)/)
    next unless match
    feature = match[1].scan(/"([^"]+)"/).flatten.find { |f| f.match?(/\A\d+\.\d+\z/) }
    return feature
  end
  nil
end

.template_directory_name(version_string) ⇒ Object

Export templates live in a directory named after the version's release segment: "4.7.1.stable.official.a13da4feb" -> "4.7.1.stable"



17
18
19
20
21
# File 'lib/fastlane/plugin/godot/helper/godot_helper.rb', line 17

def self.template_directory_name(version_string)
  match = version_string.match(/^(\d+\.\d+(?:\.\d+)?\.[a-z0-9]+)/)
  UI.user_error!("Unrecognized Godot version string: '#{version_string}'") unless match
  match[1]
end

.template_download_url(version_string) ⇒ Object

Official export-templates archive for a stable version string.



120
121
122
123
124
125
# File 'lib/fastlane/plugin/godot/helper/godot_helper.rb', line 120

def self.template_download_url(version_string)
  release = template_directory_name(version_string)
  UI.user_error!("Only stable releases have predictable template downloads (got '#{release}') — install templates for prereleases manually") unless release.end_with?('.stable')
  base = release.sub(/\.stable\z/, '')
  "https://github.com/godotengine/godot/releases/download/#{base}-stable/Godot_v#{base}-stable_export_templates.tpz"
end

.templates_rootObject



23
24
25
26
27
28
29
# File 'lib/fastlane/plugin/godot/helper/godot_helper.rb', line 23

def self.templates_root
  if FastlaneCore::Helper.mac?
    File.expand_path('~/Library/Application Support/Godot/export_templates')
  else
    File.expand_path('~/.local/share/godot/export_templates')
  end
end

.verify_binary_matches_project!(version_string, project_path) ⇒ Object



89
90
91
92
93
94
95
96
97
98
99
100
# File 'lib/fastlane/plugin/godot/helper/godot_helper.rb', line 89

def self.verify_binary_matches_project!(version_string, project_path)
  declared = project_feature_version(project_path)
  return if declared.nil?
  binary_minor = version_string.split('.')[0, 2].join('.')
  return if binary_minor == declared
  UI.user_error!(
    "This project declares Godot #{declared} (config/features in project.godot) " \
    "but the resolved binary is #{template_directory_name(version_string)}. " \
    'Exporting across engine versions corrupts import caches and breaks scenes. ' \
    "Point godot_binary at a Godot #{declared} install, or pass skip_version_check: true if you know what you are doing"
  )
end

.verify_templates!(version_string, platform) ⇒ Object



127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
# File 'lib/fastlane/plugin/godot/helper/godot_helper.rb', line 127

def self.verify_templates!(version_string, platform)
  dir = File.join(templates_root, template_directory_name(version_string))
  needed = PLATFORM_TEMPLATE_FILES[platform]
  return if needed.nil? # platform we don't know how to check — let Godot decide

  missing = needed.reject { |f| File.exist?(File.join(dir, f)) }
  return if missing.empty?

  UI.user_error!(
    "Godot #{template_directory_name(version_string)} export templates for #{platform} " \
    "are missing (#{missing.join(', ')} not found in #{dir}). " \
    'Download the templates bundle from https://godotengine.org/download and install it, ' \
    "or unzip the needed files from the .tpz archive into #{dir}"
  )
end