main.go 2.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. package main
  2. import (
  3. "os"
  4. "path/filepath"
  5. "regexp"
  6. "strings"
  7. "github.com/sagernet/sing-box/cmd/internal/build_shared"
  8. "github.com/sagernet/sing-box/log"
  9. "github.com/sagernet/sing/common"
  10. "howett.net/plist"
  11. )
  12. func main() {
  13. newVersion := common.Must1(build_shared.ReadTagVersion())
  14. newTag := common.Must1(build_shared.ReadTag())
  15. applePath, err := filepath.Abs("../sing-box-for-apple")
  16. if err != nil {
  17. log.Fatal(err)
  18. }
  19. common.Must(os.Chdir(applePath))
  20. projectFile := common.Must1(os.Open("sing-box.xcodeproj/project.pbxproj"))
  21. var project map[string]any
  22. decoder := plist.NewDecoder(projectFile)
  23. common.Must(decoder.Decode(&project))
  24. objectsMap := project["objects"].(map[string]any)
  25. projectContent := string(common.Must1(os.ReadFile("sing-box.xcodeproj/project.pbxproj")))
  26. newContent, updated0 := findAndReplace(objectsMap, projectContent, []string{"io.nekohasekai.sfa"}, newVersion)
  27. newContent, updated1 := findAndReplace(objectsMap, newContent, []string{"io.nekohasekai.sfa.independent", "io.nekohasekai.sfa.system"}, newTag)
  28. if updated0 || updated1 {
  29. log.Info("updated version to ", newTag)
  30. common.Must(os.WriteFile("sing-box.xcodeproj/project.pbxproj.bak", []byte(projectContent), 0o644))
  31. common.Must(os.WriteFile("sing-box.xcodeproj/project.pbxproj", []byte(newContent), 0o644))
  32. } else {
  33. log.Info("version not changed")
  34. }
  35. }
  36. func findAndReplace(objectsMap map[string]any, projectContent string, bundleIDList []string, newVersion string) (string, bool) {
  37. objectKeyList := findObjectKey(objectsMap, bundleIDList)
  38. var updated bool
  39. for _, objectKey := range objectKeyList {
  40. matchRegexp := common.Must1(regexp.Compile(objectKey + ".*= \\{"))
  41. indexes := matchRegexp.FindStringIndex(projectContent)
  42. indexStart := indexes[1]
  43. indexEnd := indexStart + strings.Index(projectContent[indexStart:], "}")
  44. versionStart := indexStart + strings.Index(projectContent[indexStart:indexEnd], "MARKETING_VERSION = ") + 20
  45. versionEnd := versionStart + strings.Index(projectContent[versionStart:indexEnd], ";")
  46. version := projectContent[versionStart:versionEnd]
  47. if version == newVersion {
  48. continue
  49. }
  50. updated = true
  51. projectContent = projectContent[indexStart:versionStart] + newVersion + projectContent[versionEnd:indexEnd]
  52. }
  53. return projectContent, updated
  54. }
  55. func findObjectKey(objectsMap map[string]any, bundleIDList []string) []string {
  56. var objectKeyList []string
  57. for objectKey, object := range objectsMap {
  58. buildSettings := object.(map[string]any)["buildSettings"]
  59. if buildSettings == nil {
  60. continue
  61. }
  62. bundleIDObject := buildSettings.(map[string]any)["PRODUCT_BUNDLE_IDENTIFIER"]
  63. if bundleIDObject == nil {
  64. continue
  65. }
  66. if common.Contains(bundleIDList, bundleIDObject.(string)) {
  67. objectKeyList = append(objectKeyList, objectKey)
  68. }
  69. }
  70. return objectKeyList
  71. }