func run()

in ReleaseTooling/Sources/ZipBuilder/main.swift [194:332]


  func run() throws {
    // Keep timing for how long it takes to build the zip file for information purposes.
    let buildStart = Date()
    var cocoaPodsUpdateMessage = ""

    // Do a `pod update` if requested.
    if updatePodRepo {
      CocoaPodUtils.updateRepos()
      cocoaPodsUpdateMessage =
        "CocoaPods took \(-buildStart.timeIntervalSinceNow) seconds to update."
    }

    // Register the build root if it was passed in.
    if let buildRoot = buildRoot {
      FileManager.registerBuildRoot(buildRoot: buildRoot.standardizedFileURL)
    }

    // Get the repoDir by deleting four path components from this file to the repo root.
    let repoDir = URL(fileURLWithPath: #file)
      .deletingLastPathComponent().deletingLastPathComponent()
      .deletingLastPathComponent().deletingLastPathComponent()

    // Validate the repoDir exists, as well as the templateDir.
    guard FileManager.default.directoryExists(at: repoDir) else {
      fatalError("Failed to find the repo root at \(repoDir).")
    }

    // Validate the templateDir exists.
    let templateDir = ZipBuilder.FilesystemPaths.templateDir(fromRepoDir: repoDir)
    guard FileManager.default.directoryExists(at: templateDir) else {
      fatalError("Missing template inside of the repo. \(templateDir) does not exist.")
    }

    // Update iOS target platforms if `--include-catalyst` was specified.
    if !includeCatalyst {
      SkipCatalyst.set()
    }

    // 32 bit iOS slices should only be built if the minimum iOS version is less than 11.
    guard let minVersion = Float(minimumIOSVersion) else {
      fatalError("Invalid minimum iOS version: \(minimumIOSVersion)")
    }
    if minVersion < 11.0 {
      Included32BitIOS.set()
    }

    let paths = ZipBuilder.FilesystemPaths(repoDir: repoDir,
                                           buildRoot: buildRoot,
                                           outputDir: outputDir,
                                           localPodspecPath: localPodspecPath,
                                           logsOutputDir: outputDir?
                                             .appendingPathComponent("build_logs"))

    // Populate the platforms list if it's empty. This isn't a great spot, but the argument parser
    // can't specify a default for arrays.
    let platformsToBuild = !platforms.isEmpty ? platforms : Platform.allCases
    let builder = ZipBuilder(paths: paths,
                             platforms: platformsToBuild,
                             dynamicFrameworks: dynamic,
                             customSpecRepos: customSpecRepos)

    if let outputDir = outputDir {
      do {
        // Clear out the output directory if it exists.
        FileManager.default.removeIfExists(at: outputDir)
        try FileManager.default.createDirectory(at: outputDir, withIntermediateDirectories: true)
      }
    }

    var podsToBuild = zipPods
    if pods.count > 0 {
      guard podsToBuild == nil else {
        fatalError("Only one of `--zipPods` or `--pods` can be specified.")
      }
      podsToBuild = pods.map { CocoaPodUtils.VersionedPod(name: $0, version: nil) }
    }

    if let podsToBuild = podsToBuild {
      // Set the platform minimum versions.
      PlatformMinimum.initialize(ios: minimumIOSVersion,
                                 macos: minimumMacOSVersion,
                                 tvos: minimumTVOSVersion)

      let (installedPods, frameworks, _) =
        builder.buildAndAssembleZip(podsToInstall: podsToBuild,
                                    includeCarthage: false,
                                    includeDependencies: buildDependencies)
      let staging = FileManager.default.temporaryDirectory(withName: "Binaries")
      try builder.copyFrameworks(fromPods: Array(installedPods.keys), toDirectory: staging,
                                 frameworkLocations: frameworks)
      let zipped = Zip.zipContents(ofDir: staging, name: "Frameworks.zip")
      print(zipped.absoluteString)
      if let outputDir = outputDir {
        let outputFile = outputDir.appendingPathComponent("Frameworks.zip")
        try FileManager.default.copyItem(at: zipped, to: outputFile)
        print("Success! Zip file can be found at \(outputFile.path)")
      } else {
        // Move zip to parent directory so it doesn't get removed with other artifacts.
        let parentLocation =
          zipped.deletingLastPathComponent().deletingLastPathComponent()
            .appendingPathComponent(zipped.lastPathComponent)
        // Clear out the output file if it exists.
        FileManager.default.removeIfExists(at: parentLocation)
        do {
          try FileManager.default.moveItem(at: zipped, to: parentLocation)
        } catch {
          fatalError("Could not move Zip file to output directory: \(error)")
        }
        print("Success! Zip file can be found at \(parentLocation.path)")
      }
    } else {
      // Do a Firebase Zip Release package build.

      // For the Firebase zip distribution, we disable version checking at install time by
      // setting a high version to install. The minimum versions are controlled by each individual
      // pod's podspec options.
      PlatformMinimum.useRecentVersions()

      let jsonDir = paths.repoDir.appendingPathComponents(["ReleaseTooling", "CarthageJSON"])
      let carthageOptions = CarthageBuildOptions(jsonDir: jsonDir,
                                                 isVersionCheckEnabled: carthageVersionCheck)

      FirebaseBuilder(zipBuilder: builder).build(templateDir: paths.templateDir,
                                                 carthageBuildOptions: carthageOptions)
    }

    if !keepBuildArtifacts {
      let tempDir = FileManager.default.temporaryDirectory(withName: "placeholder")
      FileManager.default.removeIfExists(at: tempDir.deletingLastPathComponent())
    }

    // Get the time since the start of the build to get the full time.
    let secondsSinceStart = -Int(buildStart.timeIntervalSinceNow)
    print("""
    Time profile:
      It took \(secondsSinceStart) seconds (~\(secondsSinceStart / 60)m) to build the zip file.
      \(cocoaPodsUpdateMessage)
    """)
  }