         let folder = try Folder(path: directoryPath)
         return folder.subfolders
             .filter { folder in
-                let projectName = folder.name.deleting(suffix: "." + Keys.projectExtension)
-                var isValid = folder.name.hasSuffix(Keys.projectExtension)
+                let projectName = folder.name.deleting(suffix: "." + Constants.projectExtension)
+                var isValid = folder.name.hasSuffix(Constants.projectExtension)
                 if filterNames.isEmpty == false {
                     isValid = isValid && filterNames.contains(projectName)
                 }

    public func updateScript(withName scriptName: String, format: Format, targetName: String?, projectNames: [String]) throws {
        let projectPaths = try self.projectPaths(inDirectory: projectDirectoryPath, filterNames: projectNames)
        guard projectPaths.count > 0 else {
            throw Error.nothingToUpdate
        }
        for path in projectPaths {
            try updateScript(withName: scriptName, format: format, targetName: targetName, projectPath: path)

    enum Error: Swift.Error {
        case projectFileReadingFailed
        case targetFilterFailed(name: String)
        case noTargets(name: String?)
    }

    private enum Constants {
        static let projectExtension = "xcodeproj"
        static let carthageScript = "/usr/local/bin/carthage copy-frameworks"
        static let nothingToUpdate = "🤷‍♂️ Nothing to update."
    }

    public let projectDirectoryPath: String?
