From 908140e92011df85e8a2c55c5a13a79426270c5c Mon Sep 17 00:00:00 2001 From: Timon Weide Date: Thu, 30 Jan 2025 09:38:10 +0100 Subject: [PATCH 1/3] Add option to provide custom packages as JSON --- README.md | 44 ++++++++++++++----- .../Files/CustomPackages.swift | 25 +++++++++++ .../SwiftPackageList+InputOptions.swift | 7 +++ .../swift-package-list/SwiftPackageList.swift | 10 ++++- 4 files changed, 73 insertions(+), 13 deletions(-) create mode 100644 Sources/SwiftPackageListCore/Files/CustomPackages.swift diff --git a/README.md b/README.md index d04f717..4523fd3 100644 --- a/README.md +++ b/README.md @@ -44,17 +44,18 @@ Currently supported are: In addition to that you can specify the following options: -| Option | Description | -| ------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------- | -| --custom-derived-data-path \ | A custom path to your DerivedData-folder. | -| --custom-source-packages-path \ | A custom path to the SourcePackages-folder. | -| --output-type \ | The type of output for the package-list. (values: stdout, json, plist, settings-bundle, pdf; default: stdout) | -| --output-path \ | The path where the package-list file will be stored. (Not required for stdout output-type) | -| --custom-file-name \ | A custom filename to be used instead of the default ones. | -| --requires-license | Will skip the packages without a license-file. | -| --ignore-package \ | Will skip a package with the specified identity. (This option may be repeated multiple times) | -| --version | Show the version. | -| -h, --help | Show help information. | +| Option | Description | +| ------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------- | +| --custom-derived-data-path \ | A custom path to your DerivedData-folder. | +| --custom-source-packages-path \ | A custom path to the SourcePackages-folder. | +| --custom-packages-file-path \ | A path to a file containing custom packages in the same format as the JSON-output. (This option may be repeated multiple times) | +| --output-type \ | The type of output for the package-list. (values: stdout, json, plist, settings-bundle, pdf; default: stdout) | +| --output-path \ | The path where the package-list file will be stored. (Not required for stdout output-type) | +| --custom-file-name \ | A custom filename to be used instead of the default ones. | +| --requires-license | Will skip the packages without a license-file. | +| --ignore-package \ | Will skip a package with the specified identity. (This option may be repeated multiple times) | +| --version | Show the version. | +| -h, --help | Show help information. | ### Build Tool Plugin @@ -187,6 +188,26 @@ let url = Bundle.main.acknowledgementsURL ``` You can then use [QuickLook](https://developer.apple.com/documentation/quicklook), [NSWorkspace.open(\_:)](https://developer.apple.com/documentation/appkit/nsworkspace/1533463-open) or any other method to display the PDF. +### Custom Packages + +To provide custom packages or other items with licenses, you can use the `--custom-packages-file-path` option with a JSON file in the following format: + +```json +[ + { + "branch" : null, + "identity" : "custom-package-example", + "license" : null, + "location" : "", + "name" : "CustomPackageExample", + "revision" : null, + "version" : null + } +] +``` + +All optional fields have null values in this example and can be left out, the other ones are required. + ## Swift Package @@ -268,6 +289,7 @@ The Settings Bundle and the UI-components are currently localized in the followi > If a language has mistakes or is missing, feel free to create an issue or open a pull request. + ## Known limitations - SwiftPackageList won't include license files from packages that are located in a registry like Artifactory. diff --git a/Sources/SwiftPackageListCore/Files/CustomPackages.swift b/Sources/SwiftPackageListCore/Files/CustomPackages.swift new file mode 100644 index 0000000..ef666de --- /dev/null +++ b/Sources/SwiftPackageListCore/Files/CustomPackages.swift @@ -0,0 +1,25 @@ +// +// CustomPackages.swift +// SwiftPackageList +// +// Created by Felix Herrmann on 17.02.25. +// + +import Foundation +import SwiftPackageList + +public struct CustomPackages: File { + public let url: URL + + public init(url: URL) { + self.url = url + } +} + +extension CustomPackages { + public func packages() throws -> [Package] { + let data = try Data(contentsOf: url) + let decoder = JSONDecoder() + return try decoder.decode([Package].self, from: data) + } +} diff --git a/Sources/swift-package-list/SwiftPackageList+InputOptions.swift b/Sources/swift-package-list/SwiftPackageList+InputOptions.swift index 746d58d..0a0d17a 100644 --- a/Sources/swift-package-list/SwiftPackageList+InputOptions.swift +++ b/Sources/swift-package-list/SwiftPackageList+InputOptions.swift @@ -22,6 +22,13 @@ extension SwiftPackageList { @Option(help: "A custom path to the SourcePackages-folder.", completion: .directory) var customSourcePackagesPath: String? + + @Option( + name: .customLong("custom-packages-file-path"), + help: "A path to a file containing custom packages in the same format as the JSON-output. (This option may be repeated multiple times)", // swiftlint:disable:this line_length + completion: .file(extensions: ["json"]) + ) + var customPackagesFilePaths: [String] = [] } } diff --git a/Sources/swift-package-list/SwiftPackageList.swift b/Sources/swift-package-list/SwiftPackageList.swift index ed145af..1d9f0cb 100644 --- a/Sources/swift-package-list/SwiftPackageList.swift +++ b/Sources/swift-package-list/SwiftPackageList.swift @@ -26,11 +26,17 @@ struct SwiftPackageList: ParsableCommand { let projectFileURL = URL(fileURLWithPath: inputOptions.projectPath) let projectType = try ProjectType(fileURL: projectFileURL) let project = try projectType.project(fileURL: projectFileURL, options: inputOptions.projectOptions) - let packages = try project.packages().filter(outputOptions.filter(package:)) + + let packages = try project.packages() + .filter(outputOptions.filter(package:)) + let customPackages = try inputOptions.customPackagesFilePaths + .map { CustomPackages(url: URL(fileURLWithPath: $0)) } + .flatMap { try $0.packages() } + .filter(outputOptions.filter(package:)) let outputType = outputOptions.outputType let outputGenerator = try outputType.outputGenerator( - packages: packages, + packages: packages + customPackages, project: project, options: outputOptions.outputGeneratorOptions ) From 423fcc812841eec74faeb97f8491a19e0b89b097 Mon Sep 17 00:00:00 2001 From: Timon Weide Date: Wed, 5 Feb 2025 17:00:00 +0100 Subject: [PATCH 2/3] Add CustomPackagesTests --- .../CustomPackagesTests.swift | 30 +++++++++++++++++++ .../CustomPackages/custom-packages.json | 11 +++++++ 2 files changed, 41 insertions(+) create mode 100644 Tests/SwiftPackageListCoreTests/CustomPackagesTests.swift create mode 100644 Tests/SwiftPackageListCoreTests/Resources/CustomPackages/custom-packages.json diff --git a/Tests/SwiftPackageListCoreTests/CustomPackagesTests.swift b/Tests/SwiftPackageListCoreTests/CustomPackagesTests.swift new file mode 100644 index 0000000..3a57af2 --- /dev/null +++ b/Tests/SwiftPackageListCoreTests/CustomPackagesTests.swift @@ -0,0 +1,30 @@ +// +// CustomPackagesTests.swift +// SwiftPackageList +// +// Created by Felix Herrmann on 17.02.25. +// + +import XCTest +@testable import SwiftPackageListCore + +final class CustomPackagesTests: XCTestCase { + func testPackageParsing() throws { + let url = Bundle.module.url( + forResource: "custom-packages", + withExtension: ".json", + subdirectory: "Resources/CustomPackages" + ) + let unwrappedURL = try XCTUnwrap(url) + let customPackages = CustomPackages(url: unwrappedURL) + let package = try XCTUnwrap(try customPackages.packages().first) + + XCTAssertEqual(package.branch, "branch-test") + XCTAssertEqual(package.identity, "identity-test") + XCTAssertEqual(package.license, "license-test") + XCTAssertEqual(package.location, "location-tes") + XCTAssertEqual(package.name, "name-test") + XCTAssertEqual(package.revision, "revision-test") + XCTAssertEqual(package.version, "version-test") + } +} diff --git a/Tests/SwiftPackageListCoreTests/Resources/CustomPackages/custom-packages.json b/Tests/SwiftPackageListCoreTests/Resources/CustomPackages/custom-packages.json new file mode 100644 index 0000000..51742e3 --- /dev/null +++ b/Tests/SwiftPackageListCoreTests/Resources/CustomPackages/custom-packages.json @@ -0,0 +1,11 @@ +[ + { + "branch": "branch-test", + "identity" : "identity-test", + "license" : "license-test", + "location" : "location-tes", + "name" : "name-test", + "revision": "revision-test", + "version": "version-test" + } +] From 12e43271796cadef42879cc37cb4d4683797bf6f Mon Sep 17 00:00:00 2001 From: Felix Herrmann Date: Mon, 17 Feb 2025 23:45:47 +0100 Subject: [PATCH 3/3] Add customPackagesFilePaths option to plugin --- .../SwiftPackageListPlugin.Configuration.swift | 1 + Plugins/SwiftPackageListPlugin/SwiftPackageListPlugin.swift | 6 +++++- README.md | 3 +++ 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/Plugins/SwiftPackageListPlugin/SwiftPackageListPlugin.Configuration.swift b/Plugins/SwiftPackageListPlugin/SwiftPackageListPlugin.Configuration.swift index e0b117f..d6df620 100644 --- a/Plugins/SwiftPackageListPlugin/SwiftPackageListPlugin.Configuration.swift +++ b/Plugins/SwiftPackageListPlugin/SwiftPackageListPlugin.Configuration.swift @@ -21,6 +21,7 @@ extension SwiftPackageListPlugin.Configuration { let outputType: OutputType? let requiresLicense: Bool? // swiftlint:disable:this discouraged_optional_boolean let ignorePackages: [String]? // swiftlint:disable:this discouraged_optional_collection + let customPackagesFilePaths: [String]? // swiftlint:disable:this discouraged_optional_collection } } diff --git a/Plugins/SwiftPackageListPlugin/SwiftPackageListPlugin.swift b/Plugins/SwiftPackageListPlugin/SwiftPackageListPlugin.swift index ddfbf51..0fc99b4 100644 --- a/Plugins/SwiftPackageListPlugin/SwiftPackageListPlugin.swift +++ b/Plugins/SwiftPackageListPlugin/SwiftPackageListPlugin.swift @@ -24,6 +24,10 @@ struct SwiftPackageListPlugin: Plugin { return ["--ignore-package", identity] } ?? [] + let customPackagesFilePathArguments: [String] = targetConfiguration?.customPackagesFilePaths?.flatMap { filePath in + return ["--custom-packages-file-path", filePath] + } ?? [] + let outputFiles: [Path] if let fileName = outputType.fileName { outputFiles = [outputPath.appending(fileName)] @@ -41,7 +45,7 @@ struct SwiftPackageListPlugin: Plugin { "--output-type", outputType.rawValue, "--output-path", outputPath, requiresLicense ? "--requires-license" : "", - ] + ignorePackageArguments, + ] + ignorePackageArguments + customPackagesFilePathArguments, outputFiles: outputFiles ) ] diff --git a/README.md b/README.md index 4523fd3..39fa6ec 100644 --- a/README.md +++ b/README.md @@ -82,6 +82,9 @@ By default this will use the JSON output with `--requires-license` but you can c "ignorePackages" : [ "swift-package-list", "swift-argument-parser", + ], + "customPackagesFilePaths" : [ + "custom-packages.json", ] } }