Skip to content

Commit

Permalink
Modified WhiteList
Browse files Browse the repository at this point in the history
  • Loading branch information
Kyome22 committed Oct 7, 2022
1 parent 7fe370f commit 956bf89
Show file tree
Hide file tree
Showing 17 changed files with 166 additions and 111 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/release-artifact-bundle.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ jobs:
runs-on: macos-12
timeout-minutes: 20
env:
DEVELOPER_DIR: "/Applications/Xcode_13.4.1.app/Contents/Developer"
DEVELOPER_DIR: "/Applications/Xcode_14.0.1.app/Contents/Developer"
ARTIFACT_BUNDLE: "license-checker.artifactbundle"

steps:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ jobs:
runs-on: macos-12
timeout-minutes: 20
env:
DEVELOPER_DIR: "/Applications/Xcode_13.4.1.app/Contents/Developer"
DEVELOPER_DIR: "/Applications/Xcode_14.0.1.app/Contents/Developer"

steps:
- name: Checkout
Expand Down
3 changes: 3 additions & 0 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ let package = Package(
dependencies: [
.target(name: "LicenseCheckerModule"),
.target(name: "TestResources")
],
resources: [
.process("Resources")
]
),
.testTarget(
Expand Down
84 changes: 44 additions & 40 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,29 +14,27 @@ It can detect libraries that are not included in a whitelist specifying the lice

```shell
$ license-checker --source-packages-path ~/SourcePackages --white-list-path ~/white-list.json
abseil Apache
BoringSSL-GRPC BoringSSL
Eureka MIT
Firebase Apache
GoogleAppMeasurement Apache
GoogleDataTransport Apache
GoogleUtilities MIT
gRPC Apache
GTMSessionFetcher Apache
Kanna MIT
KeychainAccess MIT
Kingfisher MIT
leveldb BSD
LicenseChecker unknown
LicenseList MIT
nanopb zlib
ObjectMapper MIT
Promises Apache
R.swift.Library MIT
Reachability MIT
RxGesture MIT
RxSwift MIT
SwiftProtobuf Apache
✔︎ abseil Apache
✔︎ BoringSSL-GRPC BoringSSL
✔︎ Firebase Apache
✔︎ GoogleAppMeasurement Apache
✔︎ GoogleDataTransport Apache
✔︎ GoogleUtilities MIT
✔︎ gRPC Apache
✔︎ GTMSessionFetcher Apache
✔︎ Kanna MIT
✔︎ KeychainAccess MIT
✔︎ Kingfisher MIT
✔︎ leveldb BSD
✔︎ LicenseList MIT
✔︎ nanopb zlib
✔︎ ObjectMapper MIT
✔︎ Promises Apache
✔︎ R.swift.Library MIT
✔︎ Reachability MIT
✔︎ RxGesture MIT
✔︎ RxSwift MIT
✔︎ SwiftProtobuf Apache
✅ No problems with library licensing.
$
```
Expand Down Expand Up @@ -134,8 +132,6 @@ LicenseChecker supports the following licenses:
license-checker -s ${SOURCE_PACKAGES_PATH} -w [Path to white-list.json]
```

⚠️ `white-list.json` must be included in Target Membership.

### BuildToolPlugin (for Swift Package Project)

1. Add binary target & plugin to `Package.swift`.
Expand Down Expand Up @@ -165,25 +161,33 @@ LicenseChecker supports the following licenses:

@main
struct LicenseCheckerPlugin: BuildToolPlugin {
enum LCError: Error {
case sourcePackagesNotFound
}

func sourcePackages(_ pluginWorkDirectory: Path) throws -> Path {
var tmpPath = pluginWorkDirectory
guard pluginWorkDirectory.string.contains("SourcePackages") else {
throw LCError.sourcePackagesNotFound
}
while tmpPath.lastComponent != "SourcePackages" {
tmpPath = tmpPath.removingLastComponent()
}
return tmpPath
}

func createBuildCommands(context: PluginContext, target: Target) async throws -> [Command] {
let executablePath = try context.tool(named: "license-checker").path
let sourcePackagesPath = try sourcePackages(context.pluginWorkDirectory)
let whiteListPath = "Path to white-list.json" // Please change accordingly.
let pluginWorkDirectory = context.pluginWorkDirectory.string
let regex = try NSRegularExpression(pattern: ".*SourcePackages")
let range = NSMakeRange(0, pluginWorkDirectory.utf16.count)
guard let result = regex.firstMatch(in: pluginWorkDirectory, range: range) else {
throw NSError(domain: "com.cybozu.LicenseCheckerPlugin",
code: 1,
userInfo: ["message": "Failed to match"])
}
let sourcePackageDirectory = NSString(string: pluginWorkDirectory)
.substring(with: result.range(at: 0))

return [
.prebuildCommand(
displayName: "LicenseChecker",
executable: try context.tool(named: "license-checker").path,
displayName: "Prepare LicenseList",
executable: executablePath,
arguments: [
"--source-packages-path",
sourcePackageDirectory,
sourcePackagesPath.string,
"--white-list-path",
whiteListPath
],
Expand Down Expand Up @@ -220,9 +224,9 @@ USAGE: license-checker --source-packages-path <source-packages-path> --white-lis

OPTIONS:
-s, --source-packages-path <source-packages-path>
Path of SourcePackages directory
Path to SourcePackages directory
-w, --white-list-path <white-list-path>
Path of white-list.json
Path to white-list.json
--version Show the version.
-h, --help Show help information.
```
3 changes: 2 additions & 1 deletion Sources/LicenseCheckerModule/Acknowledgements.swift
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
public struct Acknowledgement: Hashable {
public let libraryName: String
public let license: String
public let licenseType: LicenseType
public let isForbidden: Bool
}
7 changes: 4 additions & 3 deletions Sources/LicenseCheckerModule/LCMain.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ public final class LCMain {
guard let whiteList = WhiteList.load(url: whiteListURL) else {
throw LCError.notLoadedWiteList
}
let acknowledgements = packageParser.parse(with: checkoutsPath)
let acknowledgements = packageParser.parse(with: checkoutsPath, whiteList: whiteList)
printAcknowledgments(acknowledgements)
guard acknowledgements.allSatisfy({ whiteList.contains($0) }) else {
guard acknowledgements.allSatisfy({ $0.isForbidden == false }) else {
throw LCError.forbiddenLibraryFound
}
Swift.print("✅ No problems with library licensing.")
Expand All @@ -27,9 +27,10 @@ public final class LCMain {
$0.libraryName.count < $1.libraryName.count
}?.libraryName.count ?? 0
acknowledgements.forEach { acknowledgement in
let mark = acknowledgement.isForbidden ? "×" : "✔︎"
let library = acknowledgement.libraryName
.padding(toLength: length, withPad: " ", startingAt: 0)
Swift.print(library, acknowledgement.license)
Swift.print(mark, library, acknowledgement.licenseType.rawValue)
}
}
}
12 changes: 12 additions & 0 deletions Sources/LicenseCheckerModule/LicenseType.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
public enum LicenseType: String {
case apache = "Apache"
case mit = "MIT"
case bsd = "BSD"
case zlib = "zlib"
case boringSSL = "BoringSSL"
case unknown = "unknown"

public var lowercased: String {
self.rawValue.lowercased()
}
}
29 changes: 16 additions & 13 deletions Sources/LicenseCheckerModule/PackageParser.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,18 +15,21 @@ public struct PackageParser {
self.workspaceState = workspaceState
}

public func parse(with checkoutsPath: String) -> [Acknowledgement] {
public func parse(with checkoutsPath: String, whiteList: WhiteList) -> [Acknowledgement] {
return workspaceState.object.dependencies.map { dependency in
let components = dependency.packageRef.location.components(separatedBy: "/")
let repoName = components.last!.replacingOccurrences(of: ".git", with: "")
let dirURL = URL(fileURLWithPath: checkoutsPath).appendingPathComponent(repoName)
let license = extractLicense(dirURL: dirURL)
return Acknowledgement(libraryName: dependency.packageRef.name,
license: license ?? "unknown")
let libraryName = dependency.packageRef.name
let licenseType = extractLicense(dirURL: dirURL)
let isForbidden = !whiteList.contains(libraryName, licenseType: licenseType)
return Acknowledgement(libraryName: libraryName,
licenseType: licenseType,
isForbidden: isForbidden)
}.sorted { $0.libraryName.lowercased() < $1.libraryName.lowercased() }
}

public func extractLicense(dirURL: URL) -> String? {
public func extractLicense(dirURL: URL) -> LicenseType {
let fm = FileManager.default
let contents = (try? fm.contentsOfDirectory(atPath: dirURL.path)) ?? []
let _licenseURL = contents.map { content in
Expand All @@ -40,25 +43,25 @@ public struct PackageParser {
return false
}.first
guard let licenseURL = _licenseURL, var text = try? String(contentsOf: licenseURL) else {
return nil
return .unknown
}
text = text.replace(of: #"( +|\n)"#, with: " ")
var license: String? = nil
var licenseType = LicenseType.unknown
if text.contains("Apache License") || text.contains(APACHE_TEXT) {
license = "Apache"
licenseType = .apache
}
if text.contains("MIT License") || text.contains(MIT_TEXT) {
license = "MIT"
licenseType = .mit
}
if text.contains(BSD_TEXT) {
license = "BSD"
licenseType = .bsd
}
if text.contains(ZLIB_TEXT) {
license = "zlib"
licenseType = .zlib
}
if text.contains(BORINGSSL_TEXT) {
license = "BoringSSL"
licenseType = .boringSSL
}
return license
return licenseType
}
}
31 changes: 16 additions & 15 deletions Sources/LicenseCheckerModule/WhiteList.swift
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
import Foundation

public struct WhiteList: Decodable {
let licenses: [String]
let libraries: [String]
let licenses: [String]?
let libraries: [String]?

public init(licenses: [String]?, libraries: [String]?) {
self.licenses = licenses
self.libraries = libraries
}

private init?(url: URL) {
guard let data = try? Data(contentsOf: url),
Expand All @@ -11,21 +16,17 @@ public struct WhiteList: Decodable {
self = whiteList
}

public func contains(_ acknowledgement: Acknowledgement) -> Bool {
if acknowledgement.license == "unknown" {
let satisfy = self.libraries.contains(acknowledgement.libraryName)
if !satisfy {
Swift.print(acknowledgement.libraryName, acknowledgement.license)
}
return satisfy
public func contains(_ libraryName: String, licenseType: LicenseType) -> Bool {
if let libraries, libraries.contains(libraryName) {
return true
}
if licenseType == .unknown {
return false
}
let satisfy = self.licenses
.map({ $0.lowercased() })
.contains(acknowledgement.license.lowercased())
if !satisfy {
Swift.print(acknowledgement.libraryName, acknowledgement.license)
if let licenses {
return licenses.map({ $0.lowercased() }).contains(licenseType.lowercased)
}
return satisfy
return false
}

static func load(url: URL) -> WhiteList? {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
{
"licenses": [
]
"xxxxx": [,
}

0 comments on commit 956bf89

Please sign in to comment.