Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Begin migration to use System.FilePath for implementation #2

Merged
merged 4 commits into from
Feb 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "PathKit",
"image": "swift:5.8",
"image": "swift:5.9",
"features": {
"ghcr.io/devcontainers/features/common-utils:2": {
"installZsh": "false",
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@ jobs:
environment: default
strategy:
matrix:
xcode: ['14.3.1', '15.2']
# Swift: 5.8.1 , 5.9.2
xcode: ['15.2']
# Swift: 5.9.2
steps:
- uses: actions/checkout@v3
- name: Select Xcode ${{ matrix.xcode }}
Expand Down
14 changes: 14 additions & 0 deletions Package.resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"pins" : [
{
"identity" : "swift-system",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-system.git",
"state" : {
"revision" : "025bcb1165deab2e20d4eaba79967ce73013f496",
"version" : "1.2.1"
}
}
],
"version" : 2
}
13 changes: 11 additions & 2 deletions Package.swift
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
// swift-tools-version:5.8
// swift-tools-version:5.9
import PackageDescription

let package = Package(
name: "PathKit",
platforms: [.iOS(.v12), .macOS(.v10_13), .watchOS(.v4), .tvOS(.v12), .macCatalyst(.v13)],
platforms: [.iOS(.v15), .macOS(.v12), .watchOS(.v8), .tvOS(.v15), .macCatalyst(.v15), .visionOS(.v1)],
products: [
.library(name: "PathKit", targets: ["PathKit"]),
],
Expand All @@ -22,6 +22,15 @@ let package = Package(
]
)

#if !canImport(System)
package.dependencies += [.package(url: "https://github.com/apple/swift-system.git", from: "1.2.1")]
for target in package.targets {
if target.name == "PathKit" {
target.dependencies += [Target.Dependency.product(name: "SystemPackage", package: "swift-system")]
}
}
#endif

extension [SwiftSetting] {
static let swiftSix: [SwiftSetting] = [
.enableUpcomingFeature("BareSlashRegexLiterals"),
Expand Down
18 changes: 0 additions & 18 deletions Sources/PathKit/Internal/Array+FullSlice.swift

This file was deleted.

8 changes: 4 additions & 4 deletions Sources/PathKit/Operators.swift
Original file line number Diff line number Diff line change
Expand Up @@ -31,17 +31,17 @@ func + (lhs: String, rhs: String) -> Path {
// Absolute paths replace relative paths
return Path(rhs)
} else {
var lSlice = NSString(string: lhs).pathComponents.fullSlice
var rSlice = NSString(string: rhs).pathComponents.fullSlice
var lSlice = ArraySlice(NSString(string: lhs).pathComponents)
var rSlice = ArraySlice(NSString(string: rhs).pathComponents)

// Get rid of trailing "/" at the left side
if lSlice.count > 1, lSlice.last == Path.separator {
lSlice.removeLast()
}

// Advance after the first relevant "."
lSlice = lSlice.filter { $0 != "." }.fullSlice
rSlice = rSlice.filter { $0 != "." }.fullSlice
lSlice = lSlice.filter { $0 != "." }
rSlice = rSlice.filter { $0 != "." }

// Eats up trailing components of the left and leading ".." of the right side
while lSlice.last != "..", !lSlice.isEmpty, rSlice.first == ".." {
Expand Down
17 changes: 8 additions & 9 deletions Sources/PathKit/Path+Components.swift
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ extension Path {
/// - Returns: the last path component
///
public var lastComponent: String {
NSString(string: path).lastPathComponent
filePath.lastComponent?.string ?? ""
}

/// The last path component without file extension
Expand All @@ -29,7 +29,7 @@ extension Path {
/// - Returns: the last path component without file extension
///
public var lastComponentWithoutExtension: String {
NSString(string: lastComponent).deletingPathExtension
filePath.stem ?? ""
}

/// Splits the string representation on the directory separator.
Expand All @@ -38,19 +38,18 @@ extension Path {
/// - Returns: all path components
///
public var components: [String] {
NSString(string: path).pathComponents
if let root = filePath.root {
CollectionOfOne(root.string) + filePath.components.map(\.string)
} else {
filePath.components.map(\.string)
}
}

/// The file extension behind the last dot of the last component.
///
/// - Returns: the file extension
///
public var `extension`: String? {
let pathExtension = NSString(string: path).pathExtension
if pathExtension.isEmpty {
return nil
}

return pathExtension
filePath.extension
}
}
2 changes: 1 addition & 1 deletion Sources/PathKit/Path+FileInfo.swift
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ extension Path {
///
public var isSymlink: Bool {
do {
try Path.fileManager.destinationOfSymbolicLink(atPath: path)
_ = try Path.fileManager.destinationOfSymbolicLink(atPath: path)
return true
} catch {
return false
Expand Down
4 changes: 2 additions & 2 deletions Sources/PathKit/Path+PathInfo.swift
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,15 @@ extension Path {
/// - Returns: `true` iff the path begins with a slash
///
public var isAbsolute: Bool {
path.hasPrefix(Path.separator)
filePath.isAbsolute
}

/// Test whether a path is relative.
///
/// - Returns: `true` iff a path is relative (not absolute)
///
public var isRelative: Bool {
!isAbsolute
filePath.isRelative
}

/// Concatenates relative paths to the current directory and derives the normalized path
Expand Down
42 changes: 32 additions & 10 deletions Sources/PathKit/Path.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,21 +12,41 @@
// LICENSE file in the root directory of this source tree.

import Foundation
#if canImport(System)
import System
#else
import SystemPackage

extension FilePath: @unchecked Sendable {}
#endif

/// Represents a filesystem path.
public struct Path: Sendable {
/// The character used by the OS to separate two path elements
public static let separator = "/"

/// The underlying `FilePath` representation
public let filePath: FilePath

/// The underlying string representation
let path: String
var path: String { filePath.string }

static let fileManager = FileManager.default

let fileSystemInfo: any FileSystemInfo

// MARK: Init

init(filePath: FilePath, fileSystemInfo: any FileSystemInfo) {
self.filePath = filePath
self.fileSystemInfo = fileSystemInfo
}

/// Create a Path from a `System.FilePath`
public init(filePath: FilePath) {
self.init(filePath: filePath, fileSystemInfo: DefaultFileSystemInfo())
}

public init() {
self.init("")
}
Expand All @@ -37,8 +57,7 @@ public struct Path: Sendable {
}

init(_ path: String, fileSystemInfo: any FileSystemInfo) {
self.path = path
self.fileSystemInfo = fileSystemInfo
self.init(filePath: FilePath(path), fileSystemInfo: fileSystemInfo)
}

init(fileSystemInfo: any FileSystemInfo) {
Expand Down Expand Up @@ -79,24 +98,27 @@ extension Path: ExpressibleByStringLiteral {

extension Path: CustomStringConvertible {
public var description: String {
path
filePath.description
}
}

extension Path: CustomDebugStringConvertible {
public var debugDescription: String {
filePath.debugDescription
}
}

extension Path: Equatable {
/// Determines if two paths are identical
///
/// - Note: The comparison is string-based. Be aware that two different paths (foo.txt and
/// ./foo.txt) can refer to the same file.
///
public static func == (lhs: Path, rhs: Path) -> Bool {
lhs.path == rhs.path
lhs.filePath == rhs.filePath
}
}

extension Path: Hashable {
public func hash(into hasher: inout Hasher) {
hasher.combine(path.hashValue)
hasher.combine(filePath.hashValue)
hasher.combine(ObjectIdentifier(Self.self))
}
}

Expand Down
Loading