Skip to content

Commit

Permalink
Support Linux (#98)
Browse files Browse the repository at this point in the history
* Add Linux tests

* No Objective-C targets on Linux

* No @objc in Linux

* No -Package suffix on scheme

* More Linux branching

* No NS-prefixed API

* No SQLite3 on Linux

* Handle return type

* scheme CacheAdvance-Package

* withUnsafeMutableBytes and check count instead of withUnsafeBytes
  • Loading branch information
dfed authored Jan 17, 2025
1 parent aa8536d commit 7d38a8f
Show file tree
Hide file tree
Showing 12 changed files with 69 additions and 33 deletions.
19 changes: 19 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,25 @@ jobs:
run: sudo xcode-select --switch /Applications/Xcode_16.app/Contents/Developer
- name: Build and Test Framework
run: xcrun swift test -c release -Xswiftc -enable-testing
linux:
name: Build and Test on Linux
runs-on: ubuntu-latest
container: swift:6.0.3
steps:
- name: Checkout Repo
uses: actions/checkout@v4
- name: Build and Test Framework
run: swift test -c release --enable-code-coverage -Xswiftc -enable-testing
- name: Prepare Coverage Reports
run: |
llvm-cov export -format="lcov" .build/x86_64-unknown-linux-gnu/release/CacheAdvancePackageTests.xctest -instr-profile .build/x86_64-unknown-linux-gnu/release/codecov/default.profdata > coverage.lcov
- name: Upload Coverage Reports
if: success()
uses: codecov/codecov-action@v4
with:
fail_ci_if_error: true
verbose: true
os: linux
readme-validation:
name: Check Markdown links
runs-on: ubuntu-latest
Expand Down
17 changes: 15 additions & 2 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,13 @@ let package = Package(
name: "CADCacheAdvance",
targets: ["CADCacheAdvance"]
),
],
].filter {
#if os(Linux)
$0.name != "CADCacheAdvance"
#else
true
#endif
},
targets: [
.target(
name: "CacheAdvance",
Expand Down Expand Up @@ -59,5 +65,12 @@ let package = Package(
.swiftLanguageMode(.v6),
]
),
]
].filter {
#if os(Linux)
$0.name != "CADCacheAdvance"
&& $0.name != "CADCacheAdvanceTests"
#else
true
#endif
}
)
9 changes: 5 additions & 4 deletions Sources/CacheAdvance/BigEndianHostSwappable.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import Foundation
protocol BigEndianHostSwappable where Self: FixedWidthInteger {

/// Converts the big-endian value in x to the current endian format and returns the resulting value.
static func swapToHost(_ x: Self) -> Self
init(bigEndian value: Self)

/// The maximum representable integer in this type.
static var max: Self { get }
Expand All @@ -34,10 +34,11 @@ extension BigEndianHostSwappable {
///
/// - Parameter data: A data blob representing encodable data. Must be of length `Self.storageLength`.
init(_ data: Data) {
let decodedSize = data.withUnsafeBytes {
$0.load(as: Self.self)
var decodedSize: Self = 0
_ = withUnsafeMutableBytes(of: &decodedSize) {
data.copyBytes(to: $0, count: data.count)
}
self = Self.swapToHost(decodedSize)
self = Self(bigEndian: decodedSize)
}

/// The length of a contiguous data blob required to store this type.
Expand Down
12 changes: 12 additions & 0 deletions Sources/CacheAdvance/FileHandleExtensions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,13 @@ extension FileHandle {

/// A method to read data from a file handle that is safe to call in Swift from any operation system version.
func readDataUp(toLength length: Int) throws -> Data {
#if os(Linux)
if let data = try read(upToCount: length) {
data
} else {
Data()
}
#else
if #available(iOS 13.4, tvOS 13.4, watchOS 6.2, macOS 10.15.4, *) {
if let data = try read(upToCount: length) {
data
Expand All @@ -32,15 +39,20 @@ extension FileHandle {
} else {
try __readDataUp(toLength: length)
}
#endif
}

/// A method to write data to a file handle that is safe to call in Swift from any operation system version.
func write(data: Data) throws {
#if os(Linux)
try write(contentsOf: data)
#else
if #available(iOS 13.4, tvOS 13.4, watchOS 6.2, macOS 10.15.4, *) {
try write(contentsOf: data)
} else {
try __write(data, error: ())
}
#endif
}

/// A method to seek on a file handle that is safe to call in Swift from any operation system version.
Expand Down
8 changes: 1 addition & 7 deletions Sources/CacheAdvance/UInt32+BigEndianHostSwappable.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,4 @@

import Foundation

extension UInt32: BigEndianHostSwappable {

static func swapToHost(_ x: UInt32) -> UInt32 {
NSSwapBigIntToHost(x)
}

}
extension UInt32: BigEndianHostSwappable {}
8 changes: 1 addition & 7 deletions Sources/CacheAdvance/UInt64+BigEndianHostSwappable.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,4 @@

import Foundation

extension UInt64: BigEndianHostSwappable {

static func swapToHost(_ x: UInt64) -> UInt64 {
NSSwapBigLongLongToHost(x)
}

}
extension UInt64: BigEndianHostSwappable {}
8 changes: 1 addition & 7 deletions Sources/CacheAdvance/UInt8+BigEndianHostSwappable.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,4 @@

import Foundation

extension UInt8: BigEndianHostSwappable {

static func swapToHost(_ x: UInt8) -> UInt8 {
x // UInt8 is 1-byte long, so local endianness does not affect storage of this type.
}

}
extension UInt8: BigEndianHostSwappable {}
10 changes: 8 additions & 2 deletions Sources/LorumIpsum/LorumIpsumMessages.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,7 @@

import Foundation

@objc(CADLorumIpsum)
public final class LorumIpsum: NSObject {
@objc
public static let messages: [String] = [
"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.",
"Arcu cursus euismod quis viverra nibh cras pulvinar.",
Expand Down Expand Up @@ -503,3 +501,11 @@ public final class LorumIpsum: NSObject {
"Eu turpis egestas pretium aenean pharetra magna.",
]
}

#if !os(Linux)
@objc
public final class CADLorumIpsum: NSObject {
@objc
public static let messages = LorumIpsum.messages
}
#endif
5 changes: 3 additions & 2 deletions Tests/CacheAdvanceTests/CacheAdvanceTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -726,10 +726,11 @@ final class CacheAdvanceTests: XCTestCase {
}

private func clearCacheFile() {
FileManager.default.createFile(
XCTAssertTrue(FileManager.default.createFile(
atPath: testFileLocation.path,
contents: nil,
attributes: nil)
attributes: nil
))
}

private let testFileLocation = FileManager.default.temporaryDirectory.appendingPathComponent("CacheAdvanceTests")
Expand Down
2 changes: 1 addition & 1 deletion Tests/CacheAdvanceTests/CacheHeaderHandleTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ final class CacheHeaderHandleTests: XCTestCase {

override func setUp() {
super.setUp()
FileManager.default.createFile(atPath: testFileLocation.path, contents: nil, attributes: nil)
XCTAssertTrue(FileManager.default.createFile(atPath: testFileLocation.path, contents: nil, attributes: nil))
}

override func tearDown() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ final class FlushableCachePerformanceComparisonTests: XCTestCase {
super.setUp()

// Delete the existing cache.
FileManager.default.createFile(atPath: testFileLocation.path, contents: nil, attributes: nil)
XCTAssertTrue(FileManager.default.createFile(atPath: testFileLocation.path, contents: nil, attributes: nil))
}

// MARK: Behavior Tests
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
// limitations under the License.
//

#if !os(Linux)
import SQLite3
import XCTest

Expand Down Expand Up @@ -318,3 +319,4 @@ class SQLiteCache<T: Codable> {
}

}
#endif

0 comments on commit 7d38a8f

Please sign in to comment.