diff --git a/.swiftlint.yml b/.swiftlint.yml index 0c07d4ee..49b50f7d 100644 --- a/.swiftlint.yml +++ b/.swiftlint.yml @@ -1,6 +1,7 @@ disabled_rules: - identifier_name - force_try + - force_cast - function_parameter_count included: diff --git a/Sources/LicensePlistCore/Collector/GitHubLicense.collector.swift b/Sources/LicensePlistCore/Collector/GitHubLicense.collector.swift index bb9dedd6..3ce70772 100644 --- a/Sources/LicensePlistCore/Collector/GitHubLicense.collector.swift +++ b/Sources/LicensePlistCore/Collector/GitHubLicense.collector.swift @@ -41,7 +41,7 @@ extension GitHubLicense: Collector { let license = GitHubLicense(library: library, body: response.downloadUrl.downloadContent().resultSync().value!, githubResponse: response) - return Result.init(value: license) + return Result(value: license) } } } diff --git a/Sources/LicensePlistCore/ConfigLoader.swift b/Sources/LicensePlistCore/ConfigLoader.swift index efff86cc..f9743b32 100644 --- a/Sources/LicensePlistCore/ConfigLoader.swift +++ b/Sources/LicensePlistCore/ConfigLoader.swift @@ -10,6 +10,12 @@ class ConfigLoader { let githubs = value["github"].array?.map { $0.string! } ?? [] let gitHubList = githubs.map { GitHub.parse($0, mark: "", quotes: "") }.flatMap { $0 } let excludes = value["exclude"].array?.map { $0.string! } ?? [] - return Config(githubs: gitHubList, excludes: excludes) + let renames = value["rename"].dictionary?.reduce([String: String]()) { sum, e in + guard let from = e.key.string, let to = e.value.string else { return sum } + var sum = sum + sum[from] = to + return sum + } ?? [:] + return Config(githubs: gitHubList, excludes: excludes, renames: renames) } } diff --git a/Sources/LicensePlistCore/Entity/CocoaPods.swift b/Sources/LicensePlistCore/Entity/CocoaPods.swift index accb6216..8827fb88 100644 --- a/Sources/LicensePlistCore/Entity/CocoaPods.swift +++ b/Sources/LicensePlistCore/Entity/CocoaPods.swift @@ -3,7 +3,7 @@ import APIKit import LoggerAPI public struct CocoaPods: Library { - public let name: String + public var name: String } extension CocoaPods { diff --git a/Sources/LicensePlistCore/Entity/Config.swift b/Sources/LicensePlistCore/Entity/Config.swift index 5e0988ce..99057634 100644 --- a/Sources/LicensePlistCore/Entity/Config.swift +++ b/Sources/LicensePlistCore/Entity/Config.swift @@ -4,6 +4,7 @@ import LoggerAPI struct Config { let githubs: [GitHub] let excludes: [String] + let renames: [String: String] func excluded(name: String) -> Bool { if excludes.contains(name) { @@ -39,10 +40,37 @@ struct Config { } return nsText.substring(with: match.rangeAt(1)) } + + func filterExcluded(_ names: [T]) -> [T] where T: HasName { + return names.filter { + let name = $0.name + let result = !excluded(name: name) + if !result { + Log.warning("\(type(of: $0.self))'s \(name) was excluded according to config YAML.") + } + return result + } + } + func apply(githubs: [GitHub]) -> [GitHub] { + self.githubs.forEach { Log.warning("\($0.name) was loaded from config YAML.") } + return filterExcluded((self.githubs + githubs)) + } + func rename(licenses: [LicenseInfo]) -> [LicenseInfo] { + return licenses.map { name in + if let to = renames[name.name] { + var name = name + name.name = to + return name + } + return name + } + } } extension Config: Equatable { public static func==(lhs: Config, rhs: Config) -> Bool { - return lhs.githubs == rhs.githubs && lhs.excludes == rhs.excludes + return lhs.githubs == rhs.githubs && + lhs.excludes == rhs.excludes && + lhs.renames == rhs.renames } } diff --git a/Sources/LicensePlistCore/Entity/GitHub.swift b/Sources/LicensePlistCore/Entity/GitHub.swift index 666a94c5..1454d3a1 100644 --- a/Sources/LicensePlistCore/Entity/GitHub.swift +++ b/Sources/LicensePlistCore/Entity/GitHub.swift @@ -3,7 +3,7 @@ import APIKit import LoggerAPI public struct GitHub: Library { - public let name: String + public var name: String var owner: String } diff --git a/Sources/LicensePlistCore/Entity/HasName.swift b/Sources/LicensePlistCore/Entity/HasName.swift index eee36fd1..de5afa8a 100644 --- a/Sources/LicensePlistCore/Entity/HasName.swift +++ b/Sources/LicensePlistCore/Entity/HasName.swift @@ -4,16 +4,6 @@ public protocol HasName { var name: String { get } } -extension Array where Element: HasName { - func filterExcluded(config: Config?) -> [Element] { - return filter { - let name = $0.name - guard let config = config else { return true } - let result = !config.excluded(name: name) - if !result { - Log.warning("\(type(of: Element.self))'s \(name) was excluded according to config YAML.") - } - return result - } - } +public protocol HasChangeableName: HasName { + var name: String { get set } } diff --git a/Sources/LicensePlistCore/Entity/Library.swift b/Sources/LicensePlistCore/Entity/Library.swift index 574f7926..0f3eb55b 100644 --- a/Sources/LicensePlistCore/Entity/Library.swift +++ b/Sources/LicensePlistCore/Entity/Library.swift @@ -2,8 +2,7 @@ import Foundation import APIKit import LoggerAPI -public protocol Library: Hashable, Equatable, HasName { - var name: String { get } +public protocol Library: Hashable, Equatable, HasChangeableName { } extension Library { diff --git a/Sources/LicensePlistCore/Entity/License.swift b/Sources/LicensePlistCore/Entity/License.swift index 4ba2446e..0ec6cb81 100644 --- a/Sources/LicensePlistCore/Entity/License.swift +++ b/Sources/LicensePlistCore/Entity/License.swift @@ -2,30 +2,42 @@ import Foundation import APIKit import LoggerAPI -public protocol LicenseInfo: HasName { - var name: String { get } +public protocol LicenseInfo: HasChangeableName { var body: String { get } } public protocol License: LicenseInfo { associatedtype LibraryType: Library - var library: LibraryType { get } + var library: LibraryType { get set } var body: String { get } } extension License { - public var name: String { return library.name } + public var name: String { + set { library.name = newValue } + get { return library.name } + } } -public struct GitHubLicense: License { - public let library: GitHub +public struct GitHubLicense: License, Equatable { + public var library: GitHub public let body: String let githubResponse: LicenseResponse + + public static func==(lhs: GitHubLicense, rhs: GitHubLicense) -> Bool { + return lhs.library == rhs.library && + lhs.body == rhs.body + } } -public struct CocoaPodsLicense: License { - public let library: CocoaPods +public struct CocoaPodsLicense: License, Equatable { + public var library: CocoaPods public let body: String + + public static func==(lhs: CocoaPodsLicense, rhs: CocoaPodsLicense) -> Bool { + return lhs.library == rhs.library && + lhs.body == rhs.body + } } extension CocoaPodsLicense: CustomStringConvertible { diff --git a/Sources/LicensePlistCore/Extension/URL.extension.swift b/Sources/LicensePlistCore/Extension/URL.extension.swift index 7e867a3d..747a3c07 100644 --- a/Sources/LicensePlistCore/Extension/URL.extension.swift +++ b/Sources/LicensePlistCore/Extension/URL.extension.swift @@ -5,7 +5,7 @@ public extension URL { public func downloadContent() -> ResultOperation { let operation = ResultOperation { _ in do { - return Result.init(value: try String(contentsOf: self)) + return Result(value: try String(contentsOf: self)) } catch let e { return Result(error: e as NSError) } diff --git a/Sources/LicensePlistCore/LicensePlist.swift b/Sources/LicensePlistCore/LicensePlist.swift index 2cfdcd29..dc4e6053 100644 --- a/Sources/LicensePlistCore/LicensePlist.swift +++ b/Sources/LicensePlistCore/LicensePlist.swift @@ -31,25 +31,23 @@ public final class LicensePlist { shell("open", outputPath.path) } - private func collectLicenseInfos(cartfilePath: URL, podsPath: URL, config: Config?, outputPath: URL, force: Bool) -> [LicenseInfo] { + private func collectLicenseInfos(cartfilePath: URL, podsPath: URL, config: Config, outputPath: URL, force: Bool) -> [LicenseInfo] { Log.info("Pods License parse start") let podsAcknowledgements = readPodsAcknowledgements(path: podsPath) - let cocoaPodsLicenses = podsAcknowledgements + var cocoaPodsLicenses = podsAcknowledgements .map { CocoaPodsLicense.parse($0) } .flatMap { $0 } - .filterExcluded(config: config) + cocoaPodsLicenses = config.filterExcluded(cocoaPodsLicenses) Log.info("Carthage License collect start") - var gitHubLibraries: [GitHub] = config?.githubs ?? [] - gitHubLibraries.forEach { Log.warning("\($0.name) was loaded from config YAML.") } - if let cartfileContent = readCartfile(path: cartfilePath) { - gitHubLibraries += GitHub.parse(cartfileContent) - } - gitHubLibraries = gitHubLibraries.filterExcluded(config: config) + var gitHubLibraries = GitHub.parse(readCartfile(path: cartfilePath) ?? "") + gitHubLibraries = config.apply(githubs: gitHubLibraries) - let contents = (cocoaPodsLicenses.map { String(describing: $0) } + gitHubLibraries.map { String(describing: $0) }) + let contents = (cocoaPodsLicenses.map { String(describing: $0) } + + gitHubLibraries.map { String(describing: $0) } + + config.renames.map { "\($0.key):\($0.value)" }) .joined(separator: "\n\n") let savePath = outputPath.appendingPathComponent("\(Consts.prefix).latest_result.txt") if let previous = read(path: savePath), previous == contents, !force { @@ -66,13 +64,14 @@ public final class LicensePlist { let carthageLicenses = carthageOperations.map { $0.result?.value }.flatMap { $0 } self.githubLibraries = gitHubLibraries - return Array(((cocoaPodsLicenses as [LicenseInfo]) + (carthageLicenses as [LicenseInfo])) + let licenses = ((cocoaPodsLicenses as [LicenseInfo]) + (carthageLicenses as [LicenseInfo])) .reduce([String: LicenseInfo]()) { sum, e in var sum = sum sum[e.name] = e return sum }.values - .sorted { $0.name.lowercased() < $1.name.lowercased() }) + .sorted { $0.name.lowercased() < $1.name.lowercased() } + return config.rename(licenses: licenses) } private func reportMissings(licenses: [LicenseInfo]) { @@ -91,11 +90,11 @@ public final class LicensePlist { } } -private func loadConfig(configPath: URL) -> Config? { +private func loadConfig(configPath: URL) -> Config { if let yaml = read(path: configPath) { return ConfigLoader.shared.load(yaml: yaml) } - return nil + return Config(githubs: [], excludes: [], renames: [:]) } private func outputPlist(licenses: [LicenseInfo], outputPath: URL) { diff --git a/Tests/LicensePlistTests/ConfigLoaderTests.swift b/Tests/LicensePlistTests/ConfigLoaderTests.swift index 6470d0bb..f10149c6 100644 --- a/Tests/LicensePlistTests/ConfigLoaderTests.swift +++ b/Tests/LicensePlistTests/ConfigLoaderTests.swift @@ -5,12 +5,13 @@ import XCTest class ConfigLoaderTests: XCTestCase { private let target = ConfigLoader.shared func testLoad_empty() { - XCTAssertEqual(target.load(yaml: ""), Config(githubs: [], excludes: [])) + XCTAssertEqual(target.load(yaml: ""), Config(githubs: [], excludes: [], renames: [:])) } func testLoad_sample() { let path = "https://raw.githubusercontent.com/mono0926/LicensePlist/master/Tests/LicensePlistTests/Resources/license_plist.yml" XCTAssertEqual(target.load(yaml: URL(string: path)!.downloadContent().resultSync().value!), Config(githubs: [GitHub(name: "NativePopup", owner: "mono0926")], - excludes: ["RxSwift", "ios-license-generator", "/^Core.*$/"])) + excludes: ["RxSwift", "ios-license-generator", "/^Core.*$/"], + renames: ["LicensePlist": "License Plist"])) } } diff --git a/Tests/LicensePlistTests/Entity/ConfigTests.swift b/Tests/LicensePlistTests/Entity/ConfigTests.swift index f31bde4a..92648821 100644 --- a/Tests/LicensePlistTests/Entity/ConfigTests.swift +++ b/Tests/LicensePlistTests/Entity/ConfigTests.swift @@ -5,7 +5,7 @@ import XCTest class ConfigTests: XCTestCase { func testExcluded() { - let target = Config(githubs: [], excludes: ["lib1"]) + let target = Config(githubs: [], excludes: ["lib1"], renames: [:]) XCTAssertTrue(target.excluded(name: "lib1")) XCTAssertFalse(target.excluded(name: "lib2")) } @@ -16,9 +16,33 @@ class ConfigTests: XCTestCase { } func testExcluded_regex() { - let target = Config(githubs: [], excludes: ["/^lib.*$/"]) + let target = Config(githubs: [], excludes: ["/^lib.*$/"], renames: [:]) XCTAssertTrue(target.excluded(name: "lib1")) XCTAssertTrue(target.excluded(name: "lib2")) XCTAssertFalse(target.excluded(name: "hello")) } + + func testApply_filterExcluded() { + let config = Config(githubs: [], excludes: ["lib2"], renames: [:]) + let shouldBeIncluded = GitHub.init(name: "lib1", owner: "o1") + let result = config.filterExcluded([shouldBeIncluded, GitHub(name: "lib2", owner: "o2")]) + XCTAssertEqual(result, [shouldBeIncluded]) + } + + func testApply_githubs() { + let github1 = GitHub(name: "github1", owner: "g1") + let config = Config(githubs: [github1], excludes: ["lib2"], renames: [:]) + let shouldBeIncluded = GitHub(name: "lib1", owner: "o1") + let result = config.apply(githubs: [shouldBeIncluded, GitHub(name: "lib2", owner: "o2")]) + XCTAssertEqual(result, [github1, shouldBeIncluded]) + } + + func testApply_rename() { + var cocoapod1 = CocoaPodsLicense(library: CocoaPods(name: "lib1"), body: "body") + let config = Config(githubs: [], excludes: [], renames: ["lib1": "lib1_renamed"]) + let result = config.rename(licenses: [cocoapod1]) as! [CocoaPodsLicense] + + cocoapod1.name = "lib1_renamed" + XCTAssertEqual(result, [cocoapod1]) + } } diff --git a/Tests/LicensePlistTests/Entity/HasNameTests.swift b/Tests/LicensePlistTests/Entity/HasNameTests.swift index 33bf67bb..ee465ba6 100644 --- a/Tests/LicensePlistTests/Entity/HasNameTests.swift +++ b/Tests/LicensePlistTests/Entity/HasNameTests.swift @@ -3,12 +3,4 @@ import XCTest @testable import LicensePlistCore class HasNameTests: XCTestCase { - - func testfilterExcluded() { - let config = Config(githubs: [], excludes: ["lib2"]) - let shouldBeIncluded = GitHub.init(name: "lib1", owner: "o1") - let result = [shouldBeIncluded, GitHub.init(name: "lib2", owner: "o2")] - .filterExcluded(config: config) - XCTAssertEqual(result, [shouldBeIncluded]) - } }