Skip to content

Commit

Permalink
Merge pull request #133 from FelixHerrmann/feature/custom-packages-file
Browse files Browse the repository at this point in the history
[Feature] Custom Packages File
  • Loading branch information
FelixHerrmann authored Feb 19, 2025
2 parents d4ce3d3 + 12e4327 commit 8de42b4
Show file tree
Hide file tree
Showing 8 changed files with 123 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
}

Expand Down
6 changes: 5 additions & 1 deletion Plugins/SwiftPackageListPlugin/SwiftPackageListPlugin.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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)]
Expand All @@ -41,7 +45,7 @@ struct SwiftPackageListPlugin: Plugin {
"--output-type", outputType.rawValue,
"--output-path", outputPath,
requiresLicense ? "--requires-license" : "",
] + ignorePackageArguments,
] + ignorePackageArguments + customPackagesFilePathArguments,
outputFiles: outputFiles
)
]
Expand Down
47 changes: 36 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,17 +44,18 @@ Currently supported are:

In addition to that you can specify the following options:

| Option | Description |
| ------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------- |
| --custom-derived-data-path \<custom-derived-data-path\> | A custom path to your DerivedData-folder. |
| --custom-source-packages-path \<custom-source-packages-path\> | A custom path to the SourcePackages-folder. |
| --output-type \<output-type\> | The type of output for the package-list. (values: stdout, json, plist, settings-bundle, pdf; default: stdout) |
| --output-path \<output-path\> | The path where the package-list file will be stored. (Not required for stdout output-type) |
| --custom-file-name \<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 \<package-identity\> | 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 \<custom-derived-data-path\> | A custom path to your DerivedData-folder. |
| --custom-source-packages-path \<custom-source-packages-path\> | A custom path to the SourcePackages-folder. |
| --custom-packages-file-path \<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 \<output-type\> | The type of output for the package-list. (values: stdout, json, plist, settings-bundle, pdf; default: stdout) |
| --output-path \<output-path\> | The path where the package-list file will be stored. (Not required for stdout output-type) |
| --custom-file-name \<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 \<package-identity\> | 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

Expand All @@ -81,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",
]
}
}
Expand Down Expand Up @@ -187,6 +191,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

Expand Down Expand Up @@ -268,6 +292,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.
Expand Down
25 changes: 25 additions & 0 deletions Sources/SwiftPackageListCore/Files/CustomPackages.swift
Original file line number Diff line number Diff line change
@@ -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)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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] = []
}
}

Expand Down
10 changes: 8 additions & 2 deletions Sources/swift-package-list/SwiftPackageList.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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
)
Expand Down
30 changes: 30 additions & 0 deletions Tests/SwiftPackageListCoreTests/CustomPackagesTests.swift
Original file line number Diff line number Diff line change
@@ -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")
}
}
Original file line number Diff line number Diff line change
@@ -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"
}
]

0 comments on commit 8de42b4

Please sign in to comment.