Skip to content

Commit

Permalink
Preview searching optimization
Browse files Browse the repository at this point in the history
  • Loading branch information
BarredEwe committed Dec 15, 2024
1 parent 21a298d commit 8d2ebcc
Show file tree
Hide file tree
Showing 16 changed files with 332 additions and 306 deletions.
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,11 @@ enum GeneratePlaybookCommand {
static let macroPreviewBodies = "macroPreviewBodies"
}

static func run(_ options: GeneratedPlaybookOptions) throws {
static func run(_ options: GeneratedPlaybookOptions) async throws {
let task = Process()
task.executableURL = URL(filePath: options.sourcery)

let rawArguments = makeArguments(for: options)
let rawArguments = await makeArguments(for: options)
let yamlContent = YAMLParser().string(from: rawArguments)
let filePath = (options.cacheBasePath?.appending("/") ?? FileManager.default.temporaryDirectory.path())
.appending(Constants.configFileName)
Expand All @@ -66,10 +66,10 @@ enum GeneratePlaybookCommand {
task.waitUntilExit()
}

static func makeArguments(for options: GeneratedPlaybookOptions) -> [String: Any?] {
static func makeArguments(for options: GeneratedPlaybookOptions) async -> [String: Any?] {
// Works with `#Preview` macro
#if swift(>=5.9)
let previewBodies = PreviewLoader.loadMacroPreviewBodies(for: options.sources, defaultEnabled: options.previewDefaultEnabled)
let previewBodies = await PreviewLoader.loadMacroPreviewBodies(for: options.sources, defaultEnabled: options.previewDefaultEnabled)
#else
let previewBodies: String? = nil
#endif
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import ArgumentParser
import Foundation

extension Prefire {
struct Playbook: ParsableCommand {
struct Playbook: AsyncParsableCommand {
static let configuration = CommandConfiguration(abstract: "Generate Playbook")

@Argument(help: "Paths to a source swift files or directories.")
Expand All @@ -25,10 +25,10 @@ extension Prefire {
@Flag(help: "Display full info")
var verbose = false

func run() throws {
func run() async throws {
Logger.verbose = verbose

try GeneratePlaybookCommand.run(
try await GeneratePlaybookCommand.run(
GeneratedPlaybookOptions(
sourcery: sourcery,
targetPath: targetPath,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,11 +77,11 @@ enum GenerateTestsCommand {
static let previewsMacros = "previewsMacros"
}

static func run(_ options: GeneratedTestsOptions) throws {
static func run(_ options: GeneratedTestsOptions) async throws {
let task = Process()
task.executableURL = URL(filePath: options.sourcery)

let rawArguments = makeArguments(for: options)
let rawArguments = await makeArguments(for: options)
let yamlContent = YAMLParser().string(from: rawArguments)
let filePath = (options.cacheBasePath?.appending("/") ?? FileManager.default.temporaryDirectory.path())
.appending(Constants.configFileName)
Expand All @@ -94,7 +94,7 @@ enum GenerateTestsCommand {
task.waitUntilExit()
}

static func makeArguments(for options: GeneratedTestsOptions) -> [String: Any?] {
static func makeArguments(for options: GeneratedTestsOptions) async -> [String: Any?] {
let sources = options.sources
let output = options.output ?? FileManager.default.currentDirectoryPath.appending("/\(Constants.snapshotFileName).generated.swift")
let snapshotOutput = options.testTargetPath?.appending("/\(Constants.snapshotFileName).swift")
Expand All @@ -114,7 +114,7 @@ enum GenerateTestsCommand {

// Works with `#Preview` macro
#if swift(>=5.9)
let previewBodies = PreviewLoader.loadPreviewBodies(for: sources, defaultEnabled: options.prefireEnabledMarker)
let previewBodies = await PreviewLoader.loadPreviewBodies(for: sources, defaultEnabled: options.prefireEnabledMarker)
#else
let previewBodies: String? = nil
#endif
Expand Down
6 changes: 3 additions & 3 deletions PrefireExecutable/Sources/prefire/Commands/Tests/Tests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import ArgumentParser
import Foundation

extension Prefire {
struct Tests: ParsableCommand {
struct Tests: AsyncParsableCommand {
static let configuration = CommandConfiguration(abstract: "Generate Snapshot/Accessibility Tests")

@Argument(help: "Paths to a source swift files or directories.")
Expand Down Expand Up @@ -34,10 +34,10 @@ extension Prefire {
@Flag(help: "Display full info")
var verbose = false

func run() throws {
func run() async throws {
Logger.verbose = verbose

try GenerateTestsCommand.run(
try await GenerateTestsCommand.run(
GeneratedTestsOptions(
sourcery: sourcery,
target: target,
Expand Down
223 changes: 45 additions & 178 deletions PrefireExecutable/Sources/prefire/Config/Config.swift
Original file line number Diff line number Diff line change
@@ -1,136 +1,58 @@
import Foundation

private enum Constants {
static let separtor = ":"
}

struct Config {
struct TestsConfig {
var target: String?
var sources: [String]?
var testFilePath: String?
var template: String?
var device: String?
var osVersion: String?
var snapshotDevices: [String]?
var previewDefaultEnabled: Bool?
var imports: [String]?
var testableImports: [String]?
}

struct PlaybookConfig {
var targetPath: String?
var template: String?
var previewDefaultEnabled: Bool?
var imports: [String]?
var testableImports: [String]?
}

var tests = TestsConfig()
var playbook = PlaybookConfig()

init?(from configDataString: String, env: [String : String]) {
var isTestConfig = false
var isPlaybookConfig = false

let lines = configDataString.components(separatedBy: .newlines)

for index in 0..<lines.count {
if lines[index].contains(Keys.test_configuration.rawValue + Constants.separtor) {
isPlaybookConfig = false
isTestConfig = true
continue
} else if lines[index].contains(Keys.playbook_configuration.rawValue + Constants.separtor) {
isTestConfig = false
isPlaybookConfig = true
continue
}

let components = lines[index].components(separatedBy: Constants.separtor)

if isTestConfig {
if let target = Config.getValue(from: components, key: .target, env: env) {
tests.target = target
continue
}
if let sources = Config.getValues(from: components, lines: Array(lines[index..<lines.count]), key: .sources, env: env) {
tests.sources = sources
continue
}
if let testFilePath = Config.getValue(from: components, key: .test_file_path, env: env) {
tests.testFilePath = testFilePath
continue
}
if let template = Config.getValue(from: components, key: .template_file_path, env: env) {
tests.template = template
continue
}
if let device = Config.getValue(from: components, key: .simulator_device, env: env) {
tests.device = device
continue
}
if let osVersion = Config.getValue(from: components, key: .required_os, env: env) {
tests.osVersion = osVersion
continue
}
if let snapshotDevices = Config.getValues(from: components, lines: Array(lines[index..<lines.count]), key: .snapshot_devices, env: env) {
tests.snapshotDevices = snapshotDevices
continue
}
if let previewDefaultEnabled = Config.getValue(from: components, key: .preview_default_enabled, env: env) {
tests.previewDefaultEnabled = previewDefaultEnabled == "true"
continue
}
if let imports = Config.getValues(from: components, lines: Array(lines[index..<lines.count]), key: .imports, env: env) {
tests.imports = imports
continue
}
if let testableImports = Config.getValues(from: components, lines: Array(lines[index..<lines.count]), key: .testable_imports, env: env) {
tests.testableImports = testableImports
continue
}
}
enum CodingKeys: String, CodingKey {
case tests = "test_configuration"
case playbook = "playbook_configuration"
}
}

if isPlaybookConfig {
if let template = Config.getValue(from: components, key: .template_file_path, env: env) {
playbook.template = template
continue
}
if let previewDefaultEnabled = Config.getValue(from: components, key: .preview_default_enabled, env: env) {
playbook.previewDefaultEnabled = previewDefaultEnabled == "true"
continue
}
if let imports = Config.getValues(from: components, lines: Array(lines[index..<lines.count]), key: .imports, env: env) {
playbook.imports = imports
continue
}
if let testableImports = Config.getValues(from: components, lines: Array(lines[index..<lines.count]), key: .testable_imports, env: env) {
playbook.testableImports = testableImports
continue
}
}
}
struct TestsConfig {
var target: String?
var sources: [String]?
var testFilePath: String?
var template: String?
var device: String?
var osVersion: String?
var snapshotDevices: [String]?
var previewDefaultEnabled: Bool?
var imports: [String]?
var testableImports: [String]?

enum CodingKeys: String, CodingKey {
case target = "target"
case sources = "sources"
case testFilePath = "test_file_path"
case template = "template_file_path"
case device = "simulator_device"
case osVersion = "required_os"
case snapshotDevices = "snapshot_devices"
case previewDefaultEnabled = "preview_default_enabled"
case imports = "imports"
case testableImports = "testable_imports"
}
}

// MARK: - Initialization
struct PlaybookConfig {
var targetPath: String?
var template: String?
var previewDefaultEnabled: Bool?
var imports: [String]?
var testableImports: [String]?

enum CodingKeys: String, CodingKey {
case targetPath = "target"
case template = "template_file_path"
case previewDefaultEnabled = "preview_default_enabled"
case imports = "imports"
case testableImports = "testable_imports"
}
}

extension Config {
enum Keys: String {
case target
case sources
case test_file_path
case template_file_path
case simulator_device
case required_os
case snapshot_devices
case preview_default_enabled
case imports
case testable_imports
case test_configuration
case playbook_configuration
}

static func load(from configPath: String?, testTargetPath: String?, env: [String : String]) -> Config? {
let possibleConfigPaths = ConfigPathBuilder.possibleConfigPaths(for: configPath, testTargetPath: testTargetPath)

Expand All @@ -141,66 +63,11 @@ extension Config {

Logger.print("🟢 The '.prefire' file is used on the path: \(configUrl.path)")

if let configuration = Config(from: configDataString, env: env) {
return configuration
}
return ConfigDecoder().decode(from: configDataString, env: env)
}

Logger.print("🟡 The '.prefire' file was not found by paths:" + possibleConfigPaths.map({ "\n - " + $0 }).reduce("", +))
Logger.print("🟡 The '.prefire' file was not found by paths:" + possibleConfigPaths.map({ "\n - " + $0 }).joined())

return nil
}

// MARK: - Private

private static func getValues(from components: [String], lines: [String], key: Keys, env: [String : String]) -> [String]? {
guard (components.first?.hasSuffix("- \(key.rawValue)") ?? false) == true, components.last?.isEmpty == true else { return nil }

var values = [String]()

for line in lines[1..<lines.count] {
guard !line.contains(Constants.separtor) else { return values }

var value = line
.trimmingCharacters(in: CharacterSet.whitespaces)
.replacingOccurrences(of: "\"", with: "")
.replacingOccurrences(of: "- ", with: "")

guard !value.isEmpty else { continue }

// Check and replace if the value contains a key formatted as "${key}"
if let key = value.findKey(), let envValue = env[key] {
value = value.replacingOccurrences(of: "${\(key)}", with: envValue)
}

values.append(value)
}

return values
}

private static func getValue(from components: [String], key: Keys, env: [String : String]) -> String? {
guard components.first?.hasSuffix("- \(key.rawValue)") == true else { return nil }

var value = components.last?
.trimmingCharacters(in: CharacterSet.whitespaces)
.replacingOccurrences(of: "\"", with: "")

// Check and replace if the value contains a key formatted as "${key}"
if let key = value?.findKey(), let envValue = env[key] {
value = value?.replacingOccurrences(of: "${\(key)}", with: envValue)
}

return value
}
}

private extension String {
/// Extract the key enclosed within "${}" from a string
/// - Returns: Key
func findKey() -> String? {
guard contains("${") else { return nil }

return components(separatedBy: "${").last?.components(separatedBy: "}").first
}
}
Loading

0 comments on commit 8d2ebcc

Please sign in to comment.