diff --git a/Sources/ArenaCore/ArenaCommand.swift b/Sources/ArenaCore/ArenaCommand.swift index 2a934d1..f7a260b 100644 --- a/Sources/ArenaCore/ArenaCommand.swift +++ b/Sources/ArenaCore/ArenaCommand.swift @@ -143,9 +143,8 @@ extension Arena { // find libraries packageInfo = Array( zip(dependencies, - try dependencies.compactMap { - $0.path ?? $0.checkoutDir(packageDir: dependencyPackagePath) - }.compactMap { try getPackageInfo(in: $0) } ) + try dependencies.compactMap { $0.sourceDir(packageDir: dependencyPackagePath) } + .compactMap { try getPackageInfo(in: $0) } ) ) let libs = packageInfo.flatMap { $0.1.libraries } if libs.isEmpty { throw AppError.noLibrariesFound } @@ -211,27 +210,22 @@ extension Arena { // add playground do { try playgroundPath.mkdir() - let libsToImport = !libNames.isEmpty ? libNames : packageInfo.flatMap { $0.1.libraries } - let importClauses = - """ - // Playground generated with 🏟 Arena (https://github.com/finestructure/arena) - // ℹ️ If running the playground fails with an error "no such module ..." - // go to Product -> Build to re-trigger building the SPM package. - // ℹ️ Please restart Xcode if autocomplete is not working. - """ + "\n\n" + - libsToImport.map { "import \($0)" }.joined(separator: "\n") + "\n" - try importClauses.write(to: playgroundPath/"Contents.swift") - try """ - - - - - """.write(to: playgroundPath/"contents.xcplayground") + if dependencies.count == 1, + let sourceDir = dependencies.first?.sourceDir(packageDir: dependencyPackagePath), + let sampleCode = PackageGenerator.sampleCode(path: sourceDir) { + try sampleCode.write(to: playgroundPath/"Contents.swift") + } else { + let libraries = !libNames.isEmpty ? libNames : packageInfo.flatMap { $0.1.libraries } + try PackageGenerator.importLibrariesClause(libraries: libraries) + .write(to: playgroundPath/"Contents.swift") + } + try PackageGenerator.contentsXCPlayground(platform: platform) + .write(to: playgroundPath/"contents.xcplayground") } if book { let modules = dependencies - .compactMap { $0.path ?? $0.checkoutDir(packageDir: dependencyPackagePath) } + .compactMap { $0.sourceDir(packageDir: dependencyPackagePath) } .compactMap(Module.init) if modules.isEmpty { throw AppError.noSourcesFound } try PlaygroundBook.make(named: Self.playgroundName, in: outputPath, with: modules) diff --git a/Sources/ArenaCore/Dependency.swift b/Sources/ArenaCore/Dependency.swift index e31bece..a388114 100644 --- a/Sources/ArenaCore/Dependency.swift +++ b/Sources/ArenaCore/Dependency.swift @@ -53,6 +53,13 @@ public struct Dependency: Equatable, Hashable, Codable { requirement == .path ? nil : packageDir/".build/checkouts"/url.lastPathComponent(dropExtension: "git") } + /// Returns path to the package source code. Local directory if the dependency is a `path` requirement, otherwise the checkout directory of the given package directory. + /// - Parameter packageDir: fallback package directory + /// - Returns: source directory + func sourceDir(packageDir: Path) -> Path? { + path ?? checkoutDir(packageDir: packageDir) + } + func packageClause(name: String? = nil) -> String { #if swift(>=5.2) let n = name.map { #"name: "\#($0)", "# } ?? "" diff --git a/Sources/ArenaCore/PackageGenerator.swift b/Sources/ArenaCore/PackageGenerator.swift index 490cb54..812d0a1 100644 --- a/Sources/ArenaCore/PackageGenerator.swift +++ b/Sources/ArenaCore/PackageGenerator.swift @@ -1,3 +1,6 @@ +import Path + + enum PackageGenerator { static func productsClause(_ info: [(Dependency, PackageInfo)]) -> String { info @@ -72,6 +75,33 @@ extension PackageGenerator { ] """ } + + static func importLibrariesClause(libraries: [String]) -> String { + """ + // Playground generated with 🏟 Arena (https://github.com/finestructure/arena) + // ℹ️ If running the playground fails with an error "no such module ..." + // go to Product -> Build to re-trigger building the SPM package. + // ℹ️ Please restart Xcode if autocomplete is not working. + """ + "\n\n" + + libraries.map { "import \($0)" }.joined(separator: "\n") + "\n" + } + + static func contentsXCPlayground(platform: Platform) -> String { + """ + + + + + """ + } + + static func sampleCode(path: Path) -> String? { + let samplePath = path/".arena-sample.swift" + if samplePath.exists { + return try? String(contentsOf: samplePath) + } + return nil + } } diff --git a/Tests/ArenaTests/PackageGeneratorTests.swift b/Tests/ArenaTests/PackageGeneratorTests.swift index 671c43f..1649713 100644 --- a/Tests/ArenaTests/PackageGeneratorTests.swift +++ b/Tests/ArenaTests/PackageGeneratorTests.swift @@ -42,4 +42,16 @@ class PackageGeneratorTests: XCTestCase { record: false) } + func test_importLibrariesClause() throws { + assertSnapshot(matching: PackageGenerator.importLibrariesClause(libraries: ["A", "B"]), + as: .lines, + record: false) + } + + func test_contentsXCPlayground() throws { + assertSnapshot(matching: PackageGenerator.contentsXCPlayground(platform: .macos), + as: .lines, + record: false) + } + } diff --git a/Tests/ArenaTests/__Snapshots__/PackageGeneratorTests/test_contentsXCPlayground.1.txt b/Tests/ArenaTests/__Snapshots__/PackageGeneratorTests/test_contentsXCPlayground.1.txt new file mode 100644 index 0000000..bd4c33a --- /dev/null +++ b/Tests/ArenaTests/__Snapshots__/PackageGeneratorTests/test_contentsXCPlayground.1.txt @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/Tests/ArenaTests/__Snapshots__/PackageGeneratorTests/test_importLibrariesClause.1.txt b/Tests/ArenaTests/__Snapshots__/PackageGeneratorTests/test_importLibrariesClause.1.txt new file mode 100644 index 0000000..55fd40e --- /dev/null +++ b/Tests/ArenaTests/__Snapshots__/PackageGeneratorTests/test_importLibrariesClause.1.txt @@ -0,0 +1,7 @@ +// Playground generated with 🏟 Arena (https://github.com/finestructure/arena) +// ℹ️ If running the playground fails with an error "no such module ..." +// go to Product -> Build to re-trigger building the SPM package. +// ℹ️ Please restart Xcode if autocomplete is not working. + +import A +import B