Class: Pindo::GitRepoHelper
- Inherits:
-
Object
- Object
- Pindo::GitRepoHelper
- Includes:
- Singleton
- Defined in:
- lib/pindo/module/build/git_repo_helper.rb
Instance Attribute Summary collapse
-
#temp_tag_decision ⇒ Object
Returns the value of attribute temp_tag_decision.
Class Method Summary collapse
Instance Method Summary collapse
-
#add_git_cliffconfig(project_path) ⇒ Object
添加 git-cliff 配置.
-
#calculate_build_version(project_dir:, tag_prefix: 'v', create_tag_type: nil, version_increase_type: nil) ⇒ String
计算构建版本号.
-
#check_check_and_install_cliff(project_path) ⇒ Object
检查并安装 git-cliff.
-
#check_gitignore(git_root_dir, auto_commit_push: true) ⇒ Boolean
检查并写入 .gitignore 文件(不会重复添加规则) 如果修改了文件,会自动执行 git add、commit 和 push.
-
#create_and_push_tag(project_dir:, tag_name:, tag_type:) ⇒ String?
创建并推送 Tag.
-
#get_build_number_from_commit(project_dir: nil) ⇒ Integer
获取Build号(从commit hash转换而来).
-
#get_current_version_from_tag(project_dir: nil, tag_prefixes: nil) ⇒ String
版本号(例如:1.2.0),如果没有tag则返回0.0.1.
-
#head_has_version_tag?(project_dir:, tag_prefix: 'v') ⇒ Boolean
检查HEAD是否已有版本tag.
-
#install_gitcliff ⇒ Object
安装 git-cliff.
-
#valid_build_number?(build_number) ⇒ Boolean
验证Build号是否在有效范围内.
Instance Attribute Details
#temp_tag_decision ⇒ Object
Returns the value of attribute temp_tag_decision.
24 25 26 |
# File 'lib/pindo/module/build/git_repo_helper.rb', line 24 def temp_tag_decision @temp_tag_decision end |
Class Method Details
.share_instance ⇒ Object
27 28 29 |
# File 'lib/pindo/module/build/git_repo_helper.rb', line 27 def share_instance instance end |
Instance Method Details
#add_git_cliffconfig(project_path) ⇒ Object
添加 git-cliff 配置
55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 |
# File 'lib/pindo/module/build/git_repo_helper.rb', line 55 def add_git_cliffconfig(project_path) temp_dir = Dir.pwd Funlog.instance.("添加日志变更git-cliff配置...") if Pindo::GitHandler.is_git_directory?(local_repo_dir: project_path) current_git_root_path = Pindo::GitHandler.git_root_directory(local_repo_dir: project_path) Dir.chdir(current_git_root_path) pindo_common_dir = clone_pindo_common_config_repo(force_delete:false) if File.exist?(File.join(pindo_common_dir, 'cliff.toml')) FileUtils.cp_r(File.join(pindo_common_dir, 'cliff.toml'), File.join(current_git_root_path, 'cliff.toml')) end Funlog.instance.("仓库添加git-cliff配置") # 不自动提交推送,因为后续会将 cliff.toml 和 .gitignore 一起提交 check_gitignore(current_git_root_path, auto_commit_push: false) Funlog.instance.("仓库检查并添加.gitignore规则") Dir.chdir(current_git_root_path) current_branch = Pindo::GitHandler.git!(%W(-C #{current_git_root_path} rev-parse --abbrev-ref HEAD)).strip Pindo::GitHandler.git!(%W(-C #{current_git_root_path} add cliff.toml)) # .gitignore 已由 check_gitignore 自动添加到暂存区,无需重复添加 = "docs: 添加日志变更配置".encode('UTF-8') Pindo::GitHandler.git!(%W(-C #{current_git_root_path} commit -m #{commit_message})) Pindo::GitHandler.git!(%W(-C #{current_git_root_path} push origin #{current_branch})) else Funlog.instance.("当前目录不是git仓库,请在git仓库根目录下执行此命令") Dir.chdir(temp_dir) return end Funlog.instance.("日志变更git-cliff配置完成!") Dir.chdir(temp_dir) end |
#calculate_build_version(project_dir:, tag_prefix: 'v', create_tag_type: nil, version_increase_type: nil) ⇒ String
计算构建版本号
283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 |
# File 'lib/pindo/module/build/git_repo_helper.rb', line 283 def calculate_build_version(project_dir:, tag_prefix: 'v', create_tag_type: nil, version_increase_type: nil) raise ArgumentError, "项目目录不能为空" if project_dir.nil? # 设置默认值 create_tag_type ||= Pindo::CreateTagType::NEW version_increase_type ||= Pindo::VersionIncreaseType::MINI # 获取当前版本号 current_version = get_current_version_from_tag( project_dir: project_dir, tag_prefixes: [tag_prefix] ) # 根据 create_tag_type 计算 build_version case create_tag_type when Pindo::CreateTagType::NONE, Pindo::CreateTagType::RECREATE # 不创建tag或重新创建当前tag,使用当前版本号 current_version when Pindo::CreateTagType::NEW # 创建新tag,需要检查HEAD是否已有tag if head_has_version_tag?(project_dir: project_dir, tag_prefix: tag_prefix) # HEAD已有tag,不需要创建新tag,使用当前版本号 Funlog.instance.("HEAD已存在tag,使用当前版本号: #{current_version}") current_version else # HEAD没有tag,根据 version_increase_type 计算新版本号 # 解析版本号 parts = current_version.split('.').map(&:to_i) major = parts[0] || 0 minor = parts[1] || 0 patch = parts[2] || 0 case version_increase_type when Pindo::VersionIncreaseType::MAIN major += 1 minor = 0 patch = 0 when Pindo::VersionIncreaseType::MINI minor += 1 patch = 0 when Pindo::VersionIncreaseType::PATCH patch += 1 end new_version = "#{major}.#{minor}.#{patch}" Funlog.instance.("新的版本号是: #{new_version}") new_version end else current_version end end |
#check_check_and_install_cliff(project_path) ⇒ Object
检查并安装 git-cliff
34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
# File 'lib/pindo/module/build/git_repo_helper.rb', line 34 def check_check_and_install_cliff(project_path) if Pindo::GitHandler.is_git_directory?(local_repo_dir: project_path) current_git_root_path = Pindo::GitHandler.git_root_directory(local_repo_dir: project_path) unless File.exist?(File.join(current_git_root_path, 'cliff.toml')) add_git_cliffconfig(current_git_root_path) end end begin if !system('which git-cliff > /dev/null 2>&1') puts "安装git-cliff..." install_gitcliff() end rescue Funlog.instance.("安装git-cliff出现错误") return end end |
#check_gitignore(git_root_dir, auto_commit_push: true) ⇒ Boolean
检查并写入 .gitignore 文件(不会重复添加规则)如果修改了文件,会自动执行 git add、commit 和 push
103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 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 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 |
# File 'lib/pindo/module/build/git_repo_helper.rb', line 103 def check_gitignore(git_root_dir, auto_commit_push: true) gitignore_path = File.join(git_root_dir, '.gitignore') file_modified = false # 定义要添加的gitignore规则数组 ignore_rules = [ 'Temp', 'Logs', 'build_ios.log', 'feishu.json', 'CHANGELOG.md', 'GoodPlatform/iOS/*', 'GoodPlatform/Android/*', 'GoodPlatform/BaseiOS/Unity/*', 'GoodPlatform/BaseiOS/Pods/', 'GoodPlatform/BaseiOS/build', 'GoodPlatform/BaseiOS/config.json', 'GoodPlatform/BaseiOS/Podfile.lock', 'GoodPlatform/BaseAndroid/Unity/*', 'GoodPlatform/BaseAndroid/build', 'GoodPlatform/WebGL', 'config.json', 'Assets/Packages', 'Assets/WebGLTemplates.meta', 'Assets/WebGLTemplates/', 'JPSMedia', 'Packages/packages-lock.json' ] # 读取现有的gitignore内容 existing_lines = [] if File.exist?(gitignore_path) existing_lines = File.readlines(gitignore_path).map(&:strip) end # 过滤出需要添加的规则(不存在的) rules_to_add = ignore_rules.reject { |rule| existing_lines.include?(rule) } # 如果有需要添加的规则,则添加 unless rules_to_add.empty? File.open(gitignore_path, 'a') do |f| # 检查是否已有Pindo标记,如果没有则添加 pindo_marker = '# Added by Pindo (pindo_common_ignore_1.0.0)' f.puts("\n#{pindo_marker}") unless existing_lines.include?(pindo_marker.strip) # 添加每条新规则 rules_to_add.each do |rule| f.puts(rule) end end # 标记文件已修改 file_modified = true # 自动添加到 Git 暂存区、提交并推送 if Pindo::GitHandler.is_git_directory?(local_repo_dir: git_root_dir) begin # 1. 添加到暂存区 Pindo::GitHandler.git!(%W(-C #{git_root_dir} add .gitignore)) Funlog.instance.("已自动添加 .gitignore 到 Git 暂存区") # 2. 如果需要,自动提交并推送 if auto_commit_push # 获取当前分支 current_branch = Pindo::GitHandler.git!(%W(-C #{git_root_dir} rev-parse --abbrev-ref HEAD)).strip # 提交 = "chore: 更新 .gitignore 规则" Pindo::GitHandler.git!(%W(-C #{git_root_dir} commit -m #{commit_message})) Funlog.instance.("已自动提交 .gitignore 更改") # 推送到远程 Pindo::GitHandler.git!(%W(-C #{git_root_dir} push origin #{current_branch})) Funlog.instance.("已自动推送 .gitignore 到远程仓库") end rescue => e Funlog.instance.("Git 操作失败: #{e.message}") end end end file_modified end |
#create_and_push_tag(project_dir:, tag_name:, tag_type:) ⇒ String?
创建并推送 Tag
355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 |
# File 'lib/pindo/module/build/git_repo_helper.rb', line 355 def create_and_push_tag(project_dir:, tag_name:, tag_type:) raise ArgumentError, "项目目录不能为空" if project_dir.nil? raise ArgumentError, "tag名称不能为空" if tag_name.nil? || tag_name.empty? case tag_type when Pindo::CreateTagType::NONE Funlog.instance.("跳过创建 Tag") return nil when Pindo::CreateTagType::RECREATE # 删除旧 tag(本地和远程) if Pindo::GitHandler.remote_tag_exists?(local_repo_dir: project_dir, tag_name: tag_name) Funlog.instance.("删除远程 Tag: #{tag_name}") Pindo::GitHandler.git!(%W(-C #{project_dir} push origin :refs/tags/#{tag_name})) end if Pindo::GitHandler.local_tag_exists?(local_repo_dir: project_dir, tag_name: tag_name) Funlog.instance.("删除本地 Tag: #{tag_name}") Pindo::GitHandler.git!(%W(-C #{project_dir} tag -d #{tag_name})) end when Pindo::CreateTagType::NEW local_exists = Pindo::GitHandler.local_tag_exists?(local_repo_dir: project_dir, tag_name: tag_name) remote_exists = Pindo::GitHandler.remote_tag_exists?(local_repo_dir: project_dir, tag_name: tag_name) # 如果 tag 在 HEAD 上,不需要重新创建 if local_exists && Pindo::GitHandler.is_tag_at_head?(git_root_dir: project_dir, tag_name: tag_name) if !remote_exists # 本地存在且在 HEAD,但远程不存在,推送到远程 Pindo::GitHandler.git!(%W(-C #{project_dir} push origin #{tag_name})) Funlog.instance.("推送 Tag 到远程: #{tag_name}") else Funlog.instance.("Tag 已存在且在 HEAD: #{tag_name}") end return tag_name end # tag 不在 HEAD 上,需要删除后重新创建 if remote_exists Funlog.instance.("删除远程 Tag: #{tag_name}") Pindo::GitHandler.git!(%W(-C #{project_dir} push origin :refs/tags/#{tag_name})) end if local_exists Funlog.instance.("删除本地 Tag: #{tag_name}") Pindo::GitHandler.git!(%W(-C #{project_dir} tag -d #{tag_name})) end # 继续创建新 tag end # 创建并推送 tag Pindo::GitHandler.git!(%W(-C #{project_dir} tag #{tag_name})) Pindo::GitHandler.git!(%W(-C #{project_dir} push origin #{tag_name})) Funlog.instance.("创建并推送 Tag: #{tag_name}") tag_name end |
#get_build_number_from_commit(project_dir: nil) ⇒ Integer
获取Build号(从commit hash转换而来)
236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 |
# File 'lib/pindo/module/build/git_repo_helper.rb', line 236 def get_build_number_from_commit(project_dir: nil) raise ArgumentError, "项目目录不能为空" if project_dir.nil? # 获取git根目录 git_root = Pindo::GitHandler.git_root_directory(local_repo_dir: project_dir) return 1 unless git_root begin # 获取当前HEAD的commit hash前6位 commit_hash = Pindo::GitHandler.git!(%W(-C #{git_root} rev-parse HEAD)).strip[0..5] # 将16进制转换为10进制 build_number = commit_hash.to_i(16) # 确保在Android versionCode安全范围内(最大值为2^31-1) max_value = 2**31 - 1 build_number = build_number % max_value if build_number > max_value # 确保build_number不为0 build_number = 1 if build_number == 0 build_number rescue StandardError => e Funlog.instance.("获取commit hash失败: #{e.message}") # 如果获取失败,返回基于时间戳的默认值 Time.now.to_i % 1000000 + 1 end end |
#get_current_version_from_tag(project_dir: nil, tag_prefixes: nil) ⇒ String
Returns 版本号(例如:1.2.0),如果没有tag则返回0.0.1.
191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 |
# File 'lib/pindo/module/build/git_repo_helper.rb', line 191 def get_current_version_from_tag(project_dir: nil, tag_prefixes: nil) raise ArgumentError, "项目目录不能为空" if project_dir.nil? # 获取git根目录 git_root = Pindo::GitHandler.git_root_directory(local_repo_dir: project_dir) return "0.0.1" unless git_root # 如果传入的前缀为空或nil,使用默认值 prefixes = (tag_prefixes.nil? || tag_prefixes.empty?) ? ["v", "release", ""] : tag_prefixes # 尝试不同的tag前缀 latest_tag = nil matched_prefix = nil prefixes.each do |prefix| latest_tag = Pindo::GitHandler.get_latest_version_tag(project_dir: git_root, tag_prefix: prefix) if latest_tag matched_prefix = prefix break end end return "0.0.1" if latest_tag.nil? # 从tag中提取版本号,移除匹配到的前缀 version = if matched_prefix && !matched_prefix.empty? latest_tag.sub(/^#{Regexp.escape(matched_prefix)}/, '') else latest_tag end # 确保版本号格式正确(x.y.z) if version =~ /^\d+\.\d+\.\d+$/ version elsif version =~ /^\d+\.\d+$/ "#{version}.0" elsif version =~ /^\d+$/ "#{version}.0.0" else "0.0.1" end end |
#head_has_version_tag?(project_dir:, tag_prefix: 'v') ⇒ Boolean
检查HEAD是否已有版本tag
340 341 342 343 344 345 346 347 348 |
# File 'lib/pindo/module/build/git_repo_helper.rb', line 340 def head_has_version_tag?(project_dir:, tag_prefix: 'v') latest_tag = Pindo::GitHandler.get_latest_version_tag( project_dir: project_dir, tag_prefix: tag_prefix ) return false if latest_tag.nil? Pindo::GitHandler.is_tag_at_head?(git_root_dir: project_dir, tag_name: latest_tag) end |
#install_gitcliff ⇒ Object
安装 git-cliff
86 87 88 89 90 91 92 93 94 95 |
# File 'lib/pindo/module/build/git_repo_helper.rb', line 86 def install_gitcliff puts "\n检查git-cliff命令是否安装" begin if !system('which git-cliff > /dev/null 2>&1') system('bash -c "$(curl -fsSL https://gitee.com/goodtools/env/raw/master/gitcliff_install.sh)"') end rescue Funlog.instance.("安装git-cliff出现错误") end end |
#valid_build_number?(build_number) ⇒ Boolean
验证Build号是否在有效范围内
270 271 272 273 274 275 |
# File 'lib/pindo/module/build/git_repo_helper.rb', line 270 def valid_build_number?(build_number) return false if build_number.nil? # Android versionCode的有效范围是1到2^31-1 build_number >= 1 && build_number <= 2**31 - 1 end |