Skip to content

Commit

Permalink
Improvement
Browse files Browse the repository at this point in the history
  • Loading branch information
mackoj committed Oct 22, 2022
1 parent 186a82c commit 100f5cf
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 17 deletions.
58 changes: 43 additions & 15 deletions Plugins/SchemeGeneratorPlugin/SchemeGenerator.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ import CryptoKit
public struct SchemeGenerator {
// MARK: - Public
public static func generateSchemes(_ packageDirectory: FileURL, _ arguments: [String], _ productNames: [String], _ packageTempFolder: FileURL) {
/// Load Tool Configuration
let toolConfigFileURL: FileURL = packageTempFolder.appendingPathComponent("config.json")
var toolConfig = getDefaultConfigurationName(toolConfigFileURL)

/// Prepare configuration
let configurationFileURL = getConfigurationFileURL(packageDirectory, arguments)
if FileManager.default.fileExists(atPath: configurationFileURL.path) == false {
Expand All @@ -13,21 +17,49 @@ public struct SchemeGenerator {
let config = loadConfiguration(configurationFileURL)
validateConfiguration(config, configurationFileURL)

if config.verbose { print("toolConfigFileURL:", toolConfigFileURL.path) }

/// Prepare productNames
testProductNamesContent(productNames, packageTempFolder)
toolConfig = testProductNamesContent(productNames, packageTempFolder, toolConfig)
saveToolConfig(toolConfig, toolConfigFileURL)

let filteredProductNames = filterUsefullProducts(productNames, config)
if config.verbose {
print("Schemes that will be created:")
print(filteredProductNames.joined(separator: "\n"))
}

// Generate Schemes Files
generateSchemesFiles(filteredProductNames, config)
generateSchemesFiles(filteredProductNames, config)
}

// MARK: - Private

// MARK: Configuration
private static func saveToolConfig(_ toolConfig: ToolConfiguration, _ toolConfigFileURL: FileURL) {
do {
let data = try JSONEncoder().encode(toolConfig)
try data.write(to: toolConfigFileURL, options: [.atomic])
} catch {
Diagnostics.emit(.warning, "Failed to write ToolConfiguration file.")
}
}

private static func getDefaultConfigurationName(_ toolConfigFileURL: FileURL) -> ToolConfiguration {
if FileManager.default.fileExists(atPath: toolConfigFileURL.path) {
do {
let data = try Data(contentsOf: toolConfigFileURL)
let toolConfig = try JSONDecoder().decode(ToolConfiguration.self, from: data)
return toolConfig
} catch {
Diagnostics.emit(.error, "Failed to load ToolConfiguration file.")
}
}
let toolConfig = ToolConfiguration()
saveToolConfig(toolConfig, toolConfigFileURL)
return toolConfig
}

private static func getConfigurationFileURL(_ packageDirectory: FileURL, _ arguments: [String]) -> FileURL {
var configurationFileName = "schemeGenerator.json"
if let cf = arguments.firstIndex(of: "--confFile") {
Expand All @@ -54,7 +86,7 @@ public struct SchemeGenerator {
fatalError(.error, "Failed to encode a default configuration.")
}
do {
try defaultConf.write(to: configurationFileURL)
try defaultConf.write(to: configurationFileURL, options: [.atomic])
} catch {
fatalError(.error, "Failed to encode write a default configuration at \(configurationFileURL.path)")
}
Expand All @@ -80,7 +112,8 @@ public struct SchemeGenerator {
}

// MARK: Product Names
private static func testProductNamesContent(_ productNames: [String], _ packageTempFolder: FileURL) {
private static func testProductNamesContent(_ productNames: [String], _ packageTempFolder: FileURL, _ toolConfig: ToolConfiguration) -> ToolConfiguration {
var toolConfig = toolConfig
if productNames.isEmpty {
fatalError(.warning, "No products found.")
}
Expand All @@ -97,25 +130,20 @@ public struct SchemeGenerator {
.compactMap { String(format: "%02x", $0) }
.joined()

let productNamesFileURL = packageTempFolder.appendingPathComponent(hash)

if FileManager.default.fileExists(atPath: productNamesFileURL.path) {
if toolConfig.lastProductNamesHash != hash {
toolConfig.lastProductNamesHash = hash
} else {
fatalError(.remark, "There is no change in products list.")
}

do {
try Data().write(to: productNamesFileURL)
} catch {
fatalError(.error, "Failed to write temporary product list in \(productNamesFileURL.path).")
}
return toolConfig
}

private static func filterUsefullProducts(_ productNames: [String], _ config: SchemeGeneratorConfiguration) -> [String] {
if FileManager.default.fileExists(atPath: config.schemesDirectory!.path) == false {
do {
try FileManager.default.createDirectory(at: config.schemesDirectory!, withIntermediateDirectories: true)
} catch {
fatalError(.error, "Schemes output directory(\(config.schemesDirectory)) don't exist and failed to created it.")
fatalError(.error, "Schemes output directory(\(String(describing: config.schemesDirectory))) don't exist and failed to created it.")
}
}

Expand All @@ -132,7 +160,7 @@ public struct SchemeGenerator {
}.map { $0.lastPathComponent.replacingOccurrences(of: ".\($0.pathExtension)", with: "") }

var schemesSet = Set<String>(schemes)
var productNamesSet = Set<String>(productNames)
let productNamesSet = Set<String>(productNames)

// exclude from processing schemes that already exist
schemesSet.subtract(config.excludedSchemes)
Expand Down
2 changes: 1 addition & 1 deletion Plugins/SchemeGeneratorPlugin/SchemeGeneratorPlugin.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,5 @@ struct SchemeGeneratorPlugin: CommandPlugin {

public func fatalError(_ severity: PackagePlugin.Diagnostics.Severity, _ description: String, file: StaticString = #file, line: UInt = #line) -> Never {
Diagnostics.emit(severity, description)
fatalError()
fatalError(file: file, line: line)
}
11 changes: 11 additions & 0 deletions Plugins/SchemeGeneratorPlugin/ToolConfiguration.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import Foundation

struct ToolConfiguration: Codable {
let defaultConfigFileName: String
var lastProductNamesHash: String?

init(defaultConfigFileName: String = "schemeGenerator.json", lastProductNamesHash: String? = nil) {
self.defaultConfigFileName = defaultConfigFileName
self.lastProductNamesHash = lastProductNamesHash
}
}
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,12 @@ This file contain theses keys:
- schemesDirectory: A string that represent where the schemes will be saved
- removeNotGeneratedSchemes: A bool that represent if it should remove schemes that are no longer in Package.swift
- overwriteAlreadyGeneratedSchemes: A bool that represent if it should force the overwrite of schemes already present scheme
- excludedSchemes: A Array of String that represent the **name** of the schemes files that already exist and should not be processed
- verbose: A bool that represent if it should print more information in the console
```json
{
"schemesDirectory": "",
"excludedSchemes": [],
"removeNotGeneratedSchemes": true,
"overwriteAlreadyGeneratedSchemes": false,
"verbose": true
Expand All @@ -25,7 +27,7 @@ This file contain theses keys:
To run it right click on the package you want to run it on.
![Capture d’écran 2022-10-21 à 13 16 35](https://user-images.githubusercontent.com/661647/197189715-d810a52d-ce88-4371-9c9d-09d6d41fe883.png)

It will propose you to run it you can provide an optional argument that will allow you to change the name of the configuration file.
It will propose you to run it you can provide an optional argument(`--confFile newName.json`) that will allow you to change the name of the configuration file.
![Capture d’écran 2022-10-21 à 13 38 29](https://user-images.githubusercontent.com/661647/197189807-327b51b5-5f5b-4162-a433-a4c3215e67ec.png)

At first lunch it will ask for permission to write files into the schemesDirectory in order for it to work you have to say yes.
Expand Down

0 comments on commit 100f5cf

Please sign in to comment.