Skip to content

Commit

Permalink
Merge pull request #39 from finestructure/issue-38
Browse files Browse the repository at this point in the history
Issue 38
  • Loading branch information
finestructure authored Mar 27, 2020
2 parents 59cdb93 + d77d369 commit b4e1272
Show file tree
Hide file tree
Showing 11 changed files with 138 additions and 59 deletions.
4 changes: 4 additions & 0 deletions .github/workflows/swift.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ jobs:

steps:
- uses: actions/checkout@v2
- name: Set Xcode version
run: sudo xcode-select --switch /Applications/Xcode_11.4.app
- name: Log Xcode version
run: /usr/bin/xcodebuild -version
- name: Build
run: swift build -v
- name: Run tests
Expand Down
2 changes: 1 addition & 1 deletion .swift-version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
5.1.3
5.2
21 changes: 15 additions & 6 deletions Package.resolved
Original file line number Diff line number Diff line change
Expand Up @@ -41,18 +41,27 @@
"package": "llbuild",
"repositoryURL": "https://github.com/apple/swift-llbuild.git",
"state": {
"branch": null,
"revision": "f73b84bc1525998e5e267f9d830c1411487ac65e",
"version": "0.2.0"
"branch": "swift-5.2-branch",
"revision": "fb7ebf0b06c0d7c45ca8e18b3371424503a38b5c",
"version": null
}
},
{
"package": "SwiftPM",
"repositoryURL": "https://github.com/apple/swift-package-manager",
"state": {
"branch": null,
"revision": "9abcc2260438177cecd7cf5185b144d13e74122b",
"version": "0.5.0"
"branch": "swift-5.2-RELEASE",
"revision": "f2318da4f96b0607ade27eff51558206f57c2f98",
"version": null
}
},
{
"package": "swift-tools-support-core",
"repositoryURL": "https://github.com/apple/swift-tools-support-core.git",
"state": {
"branch": "swift-5.2-branch",
"revision": "98a5916a811fcaaed770f1ed812e9405be762945",
"version": null
}
}
]
Expand Down
2 changes: 1 addition & 1 deletion Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ let package = Package(
],
dependencies: [
.package(url: "https://github.com/apple/swift-argument-parser", from: "0.0.1"),
.package(url: "https://github.com/apple/swift-package-manager", from: "0.5.0"),
.package(url: "https://github.com/apple/swift-package-manager", .revision("swift-5.2-RELEASE")),
.package(url: "https://github.com/finestructure/Parser", from: "0.0.0"),
.package(url: "https://github.com/JohnSundell/ShellOut.git", from: "2.0.0"),
.package(url: "https://github.com/mxcl/Path.swift.git", from: "1.0.0"),
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
![Swift-5.1](https://github.com/finestructure/Arena/workflows/Swift/badge.svg)
![Swift-5.2](https://github.com/finestructure/Arena/workflows/Swift/badge.svg)
[![@_sa_s](https://img.shields.io/badge/Twitter-@_sa_s-3e8bb0.svg?style=flat)](https://twitter.com/_sa_s)

# 🏟 Arena
Expand Down
49 changes: 35 additions & 14 deletions Sources/ArenaCore/ArenaCommand.swift
Original file line number Diff line number Diff line change
Expand Up @@ -178,37 +178,58 @@ extension Arena {
}

// update Package.swift dependencies
// we need to keep the original description around, because we're going to re-write
// the manifest a second time, after we've resolved the packages. This is because we
// the manifest to resolve the packages and we need package resolution to be able to
// get PackageInfo, which we'll need to write out the proper dependency incl `name:`
// See https://github.com/finestructure/Arena/issues/33
// and https://github.com/finestructure/Arena/issues/38
let packagePath = projectPath/"Package.swift"
let originalPackageDescription = try String(contentsOf: packagePath)
do {
let packagePath = projectPath/"Package.swift"
let packageDescription = try String(contentsOf: packagePath)
let depsClause = dependencies.map { " " + $0.packageClause }.joined(separator: ",\n")
let depsClause = dependencies.map { " " + $0.packageClause() }.joined(separator: ",\n")
let updatedDeps = "package.dependencies = [\n\(depsClause)\n]"
try [packageDescription, updatedDeps].joined(separator: "\n").write(to: packagePath)
try [originalPackageDescription, updatedDeps].joined(separator: "\n").write(to: packagePath)
}

do {
progress(.resolvePackages, "🔧 Resolving package dependencies ...")
try shellOut(to: ShellOutCommand(string: "swift package resolve"), at: projectPath)
}

let libs: [LibraryInfo]
let packageInfo: [(Dependency, PackageInfo)]
do {
// find libraries
libs = try dependencies
.compactMap { $0.path ?? $0.checkoutDir(projectDir: projectPath) }
.flatMap { try getLibraryInfo(for: $0) }
packageInfo = Array(
zip(dependencies,
dependencies.compactMap {
$0.path ?? $0.checkoutDir(projectDir: projectPath)
}.compactMap { try? getPackageInfo(for: $0) } )
)
let libs = packageInfo.flatMap { $0.1.libraries }
if libs.isEmpty { throw ArenaError.noLibrariesFound }
progress(.listLibraries, "📔 Libraries found: \(libs.map({ $0.libraryName }).joined(separator: ", "))")
progress(.listLibraries, "📔 Libraries found: \(libs.joined(separator: ", "))")
}

// update Package.swift dependencies again, adding in package `name:`
do {
let depsClause = packageInfo.map { (dep, pkg) in
" " + dep.packageClause(name: pkg.name)
}.joined(separator: ",\n")
let updatedDeps = "package.dependencies = [\n\(depsClause)\n]"
try [originalPackageDescription, updatedDeps].joined(separator: "\n").write(to: packagePath)
}

// update Package.swift targets
do {
let packagePath = projectPath/"Package.swift"
let packageDescription = try String(contentsOf: packagePath)
let productsClause = libs.map {
$0.libraryName == $0.packageName
? #".product(name: "\#($0.libraryName)")"#
: #".product(name: "\#($0.libraryName)", package: "\#($0.packageName)")"#
let productsClause = packageInfo
.flatMap { pkg in pkg.1.libraries.map { (package: pkg.1.name, library: $0) } }
.map {
"""
.product(name: "\($0.library)", package: "\($0.package)")
"""
}.joined(separator: ",\n")
let updatedTgts = """
package.targets = [
Expand Down Expand Up @@ -251,7 +272,7 @@ extension Arena {
// add playground
do {
try playgroundPath.mkdir()
let libsToImport = !libNames.isEmpty ? libNames : libs.map({ $0.libraryName })
let libsToImport = !libNames.isEmpty ? libNames : packageInfo.flatMap { $0.1.libraries }
let importClauses =
"""
// ℹ️ If running the playground fails with an error "no such module ..."
Expand Down
21 changes: 13 additions & 8 deletions Sources/ArenaCore/Dependency.swift
Original file line number Diff line number Diff line change
Expand Up @@ -53,22 +53,27 @@ public struct Dependency: Equatable, Hashable, Codable {
requirement == .path ? nil : projectDir/".build/checkouts"/url.lastPathComponent(dropExtension: "git")
}

var packageClause: String {
func packageClause(name: String? = nil) -> String {
#if swift(>=5.2)
let n = name.map { #"name: "\#($0)", "# } ?? ""
#else
let n = ""
#endif
switch requirement {
case .branch(let b):
return #".package(url: "\#(url.absoluteString)", .branch("\#(b)"))"#
return #".package(\#(n)url: "\#(url.absoluteString)", .branch("\#(b)"))"#
case .exact(let v):
return #".package(url: "\#(url.absoluteString)", .exact("\#(v)"))"#
return #".package(\#(n)url: "\#(url.absoluteString)", .exact("\#(v)"))"#
case .from(let v):
return #".package(url: "\#(url.absoluteString)", from: "\#(v)")"#
return #".package(\#(n)url: "\#(url.absoluteString)", from: "\#(v)")"#
case .path:
return #".package(path: "\#(url.path)")"#
return #".package(\#(n)path: "\#(url.path)")"#
case .range(let r):
return #".package(url: "\#(url.absoluteString)", "\#(r.lowerBound)"..<"\#(r.upperBound)")"#
return #".package(\#(n)url: "\#(url.absoluteString)", "\#(r.lowerBound)"..<"\#(r.upperBound)")"#
case .revision(let r):
return #".package(url: "\#(url.absoluteString)", .revision("\#(r)"))"#
return #".package(\#(n)url: "\#(url.absoluteString)", .revision("\#(r)"))"#
case .noVersion:
return #".package(url: "\#(url.absoluteString)", from: "0.0.0")"#
return #".package(\#(n)url: "\#(url.absoluteString)", from: "0.0.0")"#
}
}
}
Expand Down
18 changes: 10 additions & 8 deletions Sources/ArenaCore/Helpers.swift
Original file line number Diff line number Diff line change
Expand Up @@ -23,25 +23,27 @@ let swiftCompiler: AbsolutePath = {
}()


public struct LibraryInfo {
var libraryName: String
var packageName: String
public struct PackageInfo {
var name: String
var path: AbsolutePath
var libraries: [String]
}


public func getLibraryInfo(for package: Path) throws -> [LibraryInfo] {
public func getPackageInfo(for package: Path) throws -> PackageInfo {
let path = AbsolutePath(package.string)
let manifest = try ManifestLoader.loadManifest(packagePath: path, swiftCompiler: swiftCompiler)
return manifest.products.filter { p in
let manifest = try ManifestLoader.loadManifest(packagePath: path,
swiftCompiler: swiftCompiler,
packageKind: .remote)
let libs = manifest.products.filter { p in
if case .library = p.type {
return true
} else {
return false
}
}.map {
LibraryInfo(libraryName: $0.name, packageName: manifest.name, path: path)
}
.map { $0.name }
return PackageInfo(name: manifest.name, path: path, libraries: libs)
}


Expand Down
34 changes: 22 additions & 12 deletions Tests/ArenaTests/ArenaTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -35,16 +35,18 @@ final class ArenaTests: XCTestCase {
let p = checkoutsDirectory/"swift-package-manager"
print(p)
let package = AbsolutePath(p.string)
let manifest = try ManifestLoader.loadManifest(packagePath: package, swiftCompiler: swiftCompiler)
let manifest = try ManifestLoader.loadManifest(packagePath: package,
swiftCompiler: swiftCompiler,
packageKind: .remote)
XCTAssertEqual(manifest.name, "SwiftPM")
XCTAssertEqual(manifest.products.map { $0.name }, ["SwiftPM", "SwiftPM-auto", "SPMUtility"])
XCTAssertEqual(manifest.products.map { $0.type }, [.library(.dynamic), .library(.automatic), .library(.automatic)])
XCTAssertEqual(manifest.products.map { $0.name }, ["SwiftPM", "SwiftPM-auto", "PackageDescription"])
XCTAssertEqual(manifest.products.map { $0.type }, [.library(.dynamic), .library(.automatic), .library(.dynamic)])
}

func test_getLibraryInfo() throws {
func test_getPackageInfo() throws {
let package = checkoutsDirectory/"swift-package-manager"
XCTAssertEqual(try getLibraryInfo(for: package).map({ $0.libraryName }),
["SwiftPM", "SwiftPM-auto", "SPMUtility"])
XCTAssertEqual(try getPackageInfo(for: package).libraries,
["SwiftPM", "SwiftPM-auto", "PackageDescription"])
}

func test_args_multiple_deps() throws {
Expand Down Expand Up @@ -266,27 +268,35 @@ final class ArenaTests: XCTestCase {
func test_dependency_package_clause() throws {
do {
let dep = Dependency(url: URL(string: "https://github.com/foo/bar")!, requirement: .branch("develop"))
XCTAssertEqual(dep.packageClause, #".package(url: "https://github.com/foo/bar", .branch("develop"))"#)
XCTAssertEqual(dep.packageClause(), #".package(url: "https://github.com/foo/bar", .branch("develop"))"#)
}
do {
let dep = Dependency(url: URL(string: "https://github.com/foo/bar")!, requirement: .exact("1.2.3"))
XCTAssertEqual(dep.packageClause, #".package(url: "https://github.com/foo/bar", .exact("1.2.3"))"#)
XCTAssertEqual(dep.packageClause(), #".package(url: "https://github.com/foo/bar", .exact("1.2.3"))"#)
}
do {
let dep = Dependency(url: URL(string: "https://github.com/foo/bar")!, requirement: .from("1.2.3"))
XCTAssertEqual(dep.packageClause, #".package(url: "https://github.com/foo/bar", from: "1.2.3")"#)
XCTAssertEqual(dep.packageClause(), #".package(url: "https://github.com/foo/bar", from: "1.2.3")"#)
}
do {
let dep = Dependency(url: URL(string: "https://github.com/foo/bar")!, requirement: .range("1.2.3"..<"2.3.4"))
XCTAssertEqual(dep.packageClause, #".package(url: "https://github.com/foo/bar", "1.2.3"..<"2.3.4")"#)
XCTAssertEqual(dep.packageClause(), #".package(url: "https://github.com/foo/bar", "1.2.3"..<"2.3.4")"#)
}
do {
let dep = Dependency(url: URL(string: "https://github.com/foo/bar")!, requirement: .revision("foo"))
XCTAssertEqual(dep.packageClause, #".package(url: "https://github.com/foo/bar", .revision("foo"))"#)
XCTAssertEqual(dep.packageClause(), #".package(url: "https://github.com/foo/bar", .revision("foo"))"#)
}
do {
let dep = Dependency(url: URL(string: "file:///foo/bar")!, requirement: .path)
XCTAssertEqual(dep.packageClause, #".package(path: "/foo/bar")"#)
XCTAssertEqual(dep.packageClause(), #".package(path: "/foo/bar")"#)
}
do {
let dep = Dependency(url: URL(string: "https://github.com/foo/bar")!, requirement: .revision("foo"))
XCTAssertEqual(dep.packageClause(name: "bar"), #".package(name: "bar", url: "https://github.com/foo/bar", .revision("foo"))"#)
}
do {
let dep = Dependency(url: URL(string: "file:///foo/bar")!, requirement: .path)
XCTAssertEqual(dep.packageClause(name: "bar"), #".package(name: "bar", path: "/foo/bar")"#)
}
}

Expand Down
35 changes: 30 additions & 5 deletions Tests/ArenaTests/IntegrationTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,11 @@ class IntegrationTests: XCTestCase {
try arena.run()

let expectation = """
➡️ Package: https://github.com/finestructure/ArenaTest @ exact(0.0.3)
🔧 Resolving package dependencies ...
📔 Libraries found: ArenaTest
🔨 Building package dependencies ...
Created project in folder 'ArenaIntegrationTest'
➡️ Package: https://github.com/finestructure/ArenaTest @ exact(0.0.3)
🔧 Resolving package dependencies ...
📔 Libraries found: ArenaTest
🔨 Building package dependencies ...
✅ Created project in folder 'ArenaIntegrationTest'
Run
open ArenaIntegrationTest/ArenaIntegrationTest.xcworkspace
to open the project in Xcode
Expand All @@ -47,5 +47,30 @@ class IntegrationTests: XCTestCase {
}
#endif

#if swift(>=5.2)
func test_Gen() throws {
try XCTSkipUnless(ProcessInfo().hostName == "luna.local", "fails on CI, only run locally")

let arena = try Arena.parse([
"https://github.com/pointfreeco/[email protected]",
"--name=ArenaIntegrationTest",
"--force",
"--skip-open"])

let exp = self.expectation(description: "exp")

let progress: ProgressUpdate = { stage, _ in
print("progress: \(stage)")
if stage == .completed {
exp.fulfill()
}
}

try arena.run(progress: progress)

wait(for: [exp], timeout: 10)
}
#endif

}

9 changes: 6 additions & 3 deletions misc/run_tests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,14 @@

swift build

for cmd in "arena https://github.com/pointfreeco/swift-gen.git"
for dep in "finestructure/Gala" \
"finestructure/Parser" \
"alamofire/alamofire" \
"pointfreeco/swift-gen"
do
echo "-------------------------"
echo $cmd
swift run ${cmd} -f --skip-open
echo Test: $dep
swift run arena ${dep} -f --skip-open
echo
done
echo "-------------------------"

0 comments on commit b4e1272

Please sign in to comment.