       let importFile = line.components(separatedBy: " ")[1]
       if inSwiftPackageElse {
         if importFile.first != "<" {
-          genError("Import error: \(file):\(lineNum) Import in SWIFT_PACKAGE #else should start with \"<\".")
+          logger
+            .importLog("Import in SWIFT_PACKAGE #else should start with \"<\".", file, lineNum)
         }
         continue
       }

              continue nextLine
            }
          }
          genError("Import error: \(file):\(lineNum) Import \(importFileRaw) does not exist.")
        }
      } else if importFile.first == "<" {
        // Verify that double quotes are always used for intra-module imports.
        if importFileRaw.starts(with: "Firebase") ||
          importFileRaw.starts(with: "GoogleUtilities") ||
          importFileRaw.starts(with: "GoogleDataTransport") {
          genError("Import error: \(file):\(lineNum) Imports internal to the repo should use double quotes not \"<\"")
        }
      }
    }
  }
}

// Search the path upwards to find the root of the firebase-ios-sdk repo.
var url = URL(fileURLWithPath: FileManager().currentDirectoryPath)
while url.path != "/", url.lastPathComponent != "firebase-ios-sdk" {
  url = url.deletingLastPathComponent()
}

let repoURL = url

let contents =
  try FileManager.default.contentsOfDirectory(at: repoURL,
                                              includingPropertiesForKeys: nil,
                                              options: [.skipsHiddenFiles])

for rootURL in contents {
  if !rootURL.hasDirectoryPath {
    continue
  }
  let enumerator = FileManager.default.enumerator(atPath: rootURL.path)
  whileLoop: while let file = enumerator?.nextObject() as? String {
    if let fType = enumerator?.fileAttributes?[FileAttributeKey.type] as? FileAttributeType,
      fType == .typeRegular {
      if file.starts(with: ".") {
        continue
      }
      if !(file.hasSuffix(".h") ||
        file.hasSuffix(".m") ||
        file.hasSuffix(".mm") ||
        file.hasSuffix(".c")) {
        continue
      }
      let fullTransformPath = rootURL.path + "/" + file
      for dirPattern in skipDirPatterns {
        if fullTransformPath.range(of: dirPattern) != nil {
          continue whileLoop
        }
      }
      let isPublic = file.range(of: "/Public/") != nil &&
        // TODO: Skip legacy GDTCCTLibrary file that isn't Public and should be moved.
        file.range(of: "GDTCCTLibrary/Public/GDTCOREvent+GDTCCTSupport.h") == nil
      checkFile(fullTransformPath, isPublic: isPublic)
    }
  }
}

exit(foundError ? 1 : 0)

  "FBLPromise",
]

private class ErrorLogger {
  var foundError = false
  func log(_ message: String) {
    print(message)
    foundError = true
  }

  func importLog(_ message: String, _ file: String, _ line: Int) {
    log("Import Error: \(file):\(line) \(message)")
  }
}

private func checkFile(_ file: String, logger: ErrorLogger, inRepo repoURL: URL, isPublic: Bool) {
  var fileContents = ""
  do {
    fileContents = try String(contentsOfFile: file, encoding: .utf8)
  } catch {
    logger.log("Could not read \(file). \(error)")
    // Not a source file, give up and return.
    return
  }
