diff --git a/Plugins/SwiftPackageListPlugin/SwiftPackageListPlugin.Configuration.swift b/Plugins/SwiftPackageListPlugin/SwiftPackageListPlugin.Configuration.swift index 7da6272..0a9557a 100644 --- a/Plugins/SwiftPackageListPlugin/SwiftPackageListPlugin.Configuration.swift +++ b/Plugins/SwiftPackageListPlugin/SwiftPackageListPlugin.Configuration.swift @@ -19,6 +19,7 @@ extension SwiftPackageListPlugin { extension SwiftPackageListPlugin.Configuration { struct TargetConfiguration: Decodable { let outputType: OutputType? + let packageOrder: PackageOrder? 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 @@ -33,6 +34,14 @@ extension SwiftPackageListPlugin.Configuration { case settingsBundle = "settings-bundle" case pdf } + + enum PackageOrder: String, Decodable { + case source + case nameAscending = "name-ascending" + case nameDescending = "name-descending" + case identityAscending = "identity-ascending" + case identityDescending = "identity-descending" + } } extension SwiftPackageListPlugin.Configuration.OutputType { diff --git a/Plugins/SwiftPackageListPlugin/SwiftPackageListPlugin.swift b/Plugins/SwiftPackageListPlugin/SwiftPackageListPlugin.swift index 3eef84f..cc504f7 100644 --- a/Plugins/SwiftPackageListPlugin/SwiftPackageListPlugin.swift +++ b/Plugins/SwiftPackageListPlugin/SwiftPackageListPlugin.swift @@ -19,6 +19,7 @@ struct SwiftPackageListPlugin: Plugin { let sourcePackagesPath = try sourcePackagesDirectory(pluginWorkDirectory: pluginWorkDirectory) let outputType = targetConfiguration?.outputType ?? .json let outputPath = pluginWorkDirectory + let packageOrder = targetConfiguration?.packageOrder ?? .source let requiresLicense = targetConfiguration?.requiresLicense ?? true let ignorePackageArguments: [String] = targetConfiguration?.ignorePackages?.flatMap { identity in @@ -45,6 +46,7 @@ struct SwiftPackageListPlugin: Plugin { "--custom-source-packages-path", sourcePackagesPath, "--output-type", outputType.rawValue, "--output-path", outputPath, + "--package-order", packageOrder.rawValue, requiresLicense ? "--requires-license" : "", ] + ignorePackageArguments + customPackagesFilePathArguments, outputFiles: outputFiles diff --git a/README.md b/README.md index 3740c64..123f0df 100644 --- a/README.md +++ b/README.md @@ -50,18 +50,19 @@ 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. | -| --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. | +| 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. | +| --package-order \ | The order in which the packages will be listed. (values: source, name-ascending, name-descending, identity-ascending, identity-descending; default: source) | +| --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 @@ -83,6 +84,7 @@ By default this will use the JSON output with `--requires-license` but you can c targets: { "Target 1": { outputType: "settings-bundle", + packageOrder: "name-ascending", requiresLicense: true, }, "Target 2": { diff --git a/Sources/swift-package-list/SwiftPackageList+OutputOptions.swift b/Sources/swift-package-list/SwiftPackageList+OutputOptions.swift index 381f8b7..9f35d61 100644 --- a/Sources/swift-package-list/SwiftPackageList+OutputOptions.swift +++ b/Sources/swift-package-list/SwiftPackageList+OutputOptions.swift @@ -24,6 +24,9 @@ extension SwiftPackageList { @Option(help: "A custom filename to be used instead of the default ones.") var customFileName: String? + @Option(help: "The order in which the packages will be listed.") + var packageOrder: PackageOrder = .source + @Flag(help: "Will skip the packages without a license-file.") var requiresLicense = false @@ -38,6 +41,16 @@ extension SwiftPackageList { } } +extension SwiftPackageList.OutputOptions { + enum PackageOrder: String, CaseIterable, ExpressibleByArgument { + case source + case nameAscending = "name-ascending" + case nameDescending = "name-descending" + case identityAscending = "identity-ascending" + case identityDescending = "identity-descending" + } +} + extension SwiftPackageList.OutputOptions { var outputGeneratorOptions: OutputGeneratorOptions { let outputURL = outputPath.map { URL(fileURLWithPath: $0) } @@ -50,4 +63,19 @@ extension SwiftPackageList.OutputOptions { if requiresLicense && !package.hasLicense { return false } return !ignoredPackageIdentities.contains(package.identity) } + + func sort(lhs: Package, rhs: Package) -> Bool { + switch packageOrder { + case .source: + return false + case .nameAscending: + return lhs.name.lowercased() < rhs.name.lowercased() + case .nameDescending: + return lhs.name.lowercased() > rhs.name.lowercased() + case .identityAscending: + return lhs.identity.lowercased() < rhs.identity.lowercased() + case .identityDescending: + return lhs.identity.lowercased() > rhs.identity.lowercased() + } + } } diff --git a/Sources/swift-package-list/SwiftPackageList.swift b/Sources/swift-package-list/SwiftPackageList.swift index 05a6527..005f0ef 100644 --- a/Sources/swift-package-list/SwiftPackageList.swift +++ b/Sources/swift-package-list/SwiftPackageList.swift @@ -27,16 +27,17 @@ struct SwiftPackageList: ParsableCommand { 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 projectPackages = try project.packages() let customPackages = try inputOptions.customPackagesFilePaths .map { CustomPackages(url: URL(fileURLWithPath: $0)) } .flatMap { try $0.packages() } + let packages = (projectPackages + customPackages) .filter(outputOptions.filter(package:)) + .sorted(by: outputOptions.sort(lhs:rhs:)) let outputType = outputOptions.outputType let outputGenerator = try outputType.outputGenerator( - packages: packages + customPackages, + packages: packages, project: project, options: outputOptions.outputGeneratorOptions )