Class: Pindo::BuildHelper

Inherits:
Object
  • Object
show all
Includes:
Singleton
Defined in:
lib/pindo/module/build/build_helper.rb

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.share_instanceObject



12
13
14
# File 'lib/pindo/module/build/build_helper.rb', line 12

def share_instance
  instance
end

Instance Method Details

#android_project?(project_path) ⇒ Boolean

Returns:

  • (Boolean)


70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
# File 'lib/pindo/module/build/build_helper.rb', line 70

def android_project?(project_path)
  # 检查Android工程的关键文件和目录
  gradle_file = File.exist?(File.join(project_path, "build.gradle")) || File.exist?(File.join(project_path, "build.gradle.kts"))
  settings_gradle = File.exist?(File.join(project_path, "settings.gradle")) || File.exist?(File.join(project_path, "settings.gradle.kts"))

  # 尝试获取主模块
  main_module = nil
  begin
    main_module = get_main_module(project_path)
  rescue => e
    puts "获取主模块失败: #{e.message}" if ENV['DEBUG']
  end

  # Android Studio项目结构
  if gradle_file && settings_gradle && main_module
    app_gradle = File.exist?(File.join(main_module, "build.gradle")) || File.exist?(File.join(main_module, "build.gradle.kts"))
    app_manifest = File.exist?(File.join(main_module, "src", "main", "AndroidManifest.xml"))
    return true if app_gradle && app_manifest
  end

  # 如果无法通过标准方式检测,尝试更宽松的检测
  # 检查是否有任何包含 build.gradle 的子目录
  if gradle_file && settings_gradle
    Dir.entries(project_path).each do |entry|
      next if entry.start_with?('.')
      entry_path = File.join(project_path, entry)
      if File.directory?(entry_path)
        app_gradle = File.exist?(File.join(entry_path, "build.gradle")) || File.exist?(File.join(entry_path, "build.gradle.kts"))
        app_manifest = File.exist?(File.join(entry_path, "src", "main", "AndroidManifest.xml"))
        if app_gradle && app_manifest
          return true
        end
      end
    end
  end

  false
end

#get_project_name(project_path) ⇒ Object



132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
# File 'lib/pindo/module/build/build_helper.rb', line 132

def get_project_name(project_path)
  case project_type(project_path)
  when :unity
    File.basename(project_path)
  when :ios
    xcodeproj = Dir.glob(File.join(project_path, "*.xcodeproj")).first
    File.basename(xcodeproj, ".xcodeproj") if xcodeproj
  when :android
    settings_gradle = File.join(project_path, "settings.gradle")
    settings_gradle_kts = File.join(project_path, "settings.gradle.kts")
    
    # 优先使用 settings.gradle.kts,如果不存在则使用 settings.gradle
    if File.exist?(settings_gradle_kts)
      settings_gradle = settings_gradle_kts
    end
    
    if File.exist?(settings_gradle)
      content = File.read(settings_gradle)
      if content =~ /rootProject\.name\s*=\s*['"](.+)['"]/
        $1
      else
        File.basename(project_path)
      end
    else
      File.basename(project_path)
    end
  else
    File.basename(project_path)
  end
end

#get_project_version(project_path) ⇒ Object



163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
# File 'lib/pindo/module/build/build_helper.rb', line 163

def get_project_version(project_path)
  case project_type(project_path)
  when :unity
    version_file = File.join(project_path, "ProjectSettings", "ProjectVersion.txt")
    if File.exist?(version_file)
      content = File.read(version_file)
      if content =~ /m_EditorVersion: (.*)/
        $1.strip
      end
    end
  when :ios
    # 从Info.plist获取版本号
    nil
  when :android
    # 从build.gradle获取版本号
    nil
  end
end

#ios_project?(project_path) ⇒ Boolean

Returns:

  • (Boolean)


30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
# File 'lib/pindo/module/build/build_helper.rb', line 30

def ios_project?(project_path)
  # 检查iOS工程的关键文件
  xcodeproj_files = Dir.glob(File.join(project_path, "*.xcodeproj"))
  workspace_files = Dir.glob(File.join(project_path, "*.xcworkspace"))

  # 至少要有.xcodeproj文件或.xcworkspace文件
  return false if xcodeproj_files.empty? && workspace_files.empty?

  if !xcodeproj_files.empty?
    # 检查.xcodeproj内部结构
    project_file = File.join(xcodeproj_files.first, "project.pbxproj")
    return true if File.exist?(project_file)
  end

  if !workspace_files.empty?
    # 检查.xcworkspace内部结构
    contents_file = File.join(workspace_files.first, "contents.xcworkspacedata")
    return true if File.exist?(contents_file)
  end

  false
end

#load_jps_build_config(project_dir) ⇒ String?

加载 JPSBuildConfig.json 并设置项目名称到 GlobalOptionsState

Parameters:

  • project_dir (String)

    项目目录

Returns:

  • (String, nil)

    项目名称(如果存在)



197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
# File 'lib/pindo/module/build/build_helper.rb', line 197

def load_jps_build_config(project_dir)
  # 检测工程类型:Unity 工程配置在 ProjectSettings 目录
  config_file = if unity_project?(project_dir)
    File.join(project_dir, 'ProjectSettings', 'JPSBuildConfig.json')
  else
    File.join(project_dir, 'JPSBuildConfig.json')
  end

  return nil unless File.exist?(config_file)

  begin
    config = JSON.parse(File.read(config_file))
    project_name = config['project_name']
    if project_name && !project_name.empty?
      # 设置到 GlobalOptionsState
      Pindo::Options::GlobalOptionsState.instance[:proj] = project_name
      puts "使用 JPS 配置的项目名称: #{project_name}"
      return project_name
    end
  rescue => e
    puts "加载 JPSBuildConfig.json 失败: #{e.message}" if ENV['PINDO_VERBOSE'] == '1'
  end
  nil
end

#macos_project?(project_path) ⇒ Boolean

Returns:

  • (Boolean)


53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
# File 'lib/pindo/module/build/build_helper.rb', line 53

def macos_project?(project_path)
  # 检查是否为 macOS 工程
  begin
    project_fullname = Dir.glob(File.join(project_path, "*.xcodeproj")).max_by {|f| File.mtime(f)}
    if !project_fullname.nil?
      project_obj = Xcodeproj::Project.open(project_fullname)
      project_build_platform = project_obj.root_object.build_configuration_list.get_setting("SDKROOT")["Release"]
      if !project_build_platform.nil? && project_build_platform.eql?("macosx")
        return true
      end
    end
  rescue => e
    puts "判断 macOS 工程失败: #{e.message}" if ENV['DEBUG']
  end
  false
end

#project_type(project_path) ⇒ Object

Raises:

  • (ArgumentError)


109
110
111
112
113
114
115
116
117
# File 'lib/pindo/module/build/build_helper.rb', line 109

def project_type(project_path)
  raise ArgumentError, "项目路径不能为空" if project_path.nil? || project_path.empty?
  raise ArgumentError, "项目路径不存在: #{project_path}" unless File.directory?(project_path)

  return :unity if unity_project?(project_path)
  return :ios if ios_project?(project_path)
  return :android if android_project?(project_path)
  :unknown
end

#project_type_name(project_path) ⇒ Object



119
120
121
122
123
124
125
126
127
128
129
130
# File 'lib/pindo/module/build/build_helper.rb', line 119

def project_type_name(project_path)
  case project_type(project_path)
  when :unity
    "Unity"
  when :ios
    "iOS"
  when :android
    "Android"
  else
    "Unknown"
  end
end

#pull_appconfig_with_reponame(repo_name:, target_dir: nil) ⇒ Boolean

拉取应用配置仓库(委托给 BuildInfoManager)

Parameters:

  • repo_name (String)

    仓库名称(Bundle ID)

  • target_dir (String, nil) (defaults to: nil)

    目标目录(默认:当前目录)

Returns:

  • (Boolean)

    是否成功拉取配置



186
187
188
189
190
191
192
# File 'lib/pindo/module/build/build_helper.rb', line 186

def pull_appconfig_with_reponame(repo_name:, target_dir: nil)
  require_relative '../../config/build_info_manager'
  Pindo::BuildInfoManager.share_instance.pull_appconfig_with_reponame(
    repo_name: repo_name,
    target_dir: target_dir
  )
end

#unity_project?(project_path) ⇒ Boolean

Returns:

  • (Boolean)


17
18
19
20
21
22
23
24
25
26
27
28
# File 'lib/pindo/module/build/build_helper.rb', line 17

def unity_project?(project_path)
  # 检查Unity工程的关键文件和目录
  project_settings_path = File.join(project_path, "ProjectSettings")
  assets_path = File.join(project_path, "Assets")
  packages_path = File.join(project_path, "Packages")

  # Unity工程必须包含这些目录和文件
  File.directory?(project_settings_path) &&
  File.directory?(assets_path) &&
  File.directory?(packages_path) &&
  File.exist?(File.join(project_settings_path, "ProjectSettings.asset"))
end