Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
07007a5421 | ||
|
|
8a217b3982 | ||
|
|
2b50909946 | ||
|
|
baa6416208 | ||
|
|
6e99825d9f | ||
|
|
6e37bfde4d |
12
.github/workflows/checks.yml
vendored
Normal file
12
.github/workflows/checks.yml
vendored
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
name: Checks
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- master
|
||||||
|
jobs:
|
||||||
|
macOS:
|
||||||
|
runs-on: macos-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- run: swift --version
|
||||||
|
- run: swift test --parallel
|
||||||
77
.github/workflows/ci.yml
vendored
Normal file
77
.github/workflows/ci.yml
vendored
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
name: CI
|
||||||
|
on: [pull_request]
|
||||||
|
jobs:
|
||||||
|
smoke:
|
||||||
|
runs-on: macos-latest
|
||||||
|
steps:
|
||||||
|
- uses: technote-space/auto-cancel-redundant-job@v1
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- run: swift test --generate-linuxmain
|
||||||
|
- run: git diff --exit-code
|
||||||
|
macOS:
|
||||||
|
needs: smoke
|
||||||
|
runs-on: macos-latest
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
xcode:
|
||||||
|
#- 10.3 # Swift 5.0 (doesn’t work on GHA macOS image :-/)
|
||||||
|
- 11.3 # Swift 5.1
|
||||||
|
- ^11.4 # Swift 5.2
|
||||||
|
- latest # Swift 5.3
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- name: setup-xcode
|
||||||
|
uses: maxim-lobanov/setup-xcode@1.0
|
||||||
|
with:
|
||||||
|
xcode-version: ${{ matrix.xcode }}
|
||||||
|
- run: swift --version
|
||||||
|
- run: swift test --parallel
|
||||||
|
otherOS:
|
||||||
|
needs: smoke
|
||||||
|
runs-on: macos-latest
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
destination:
|
||||||
|
- platform=iOS Simulator,OS=latest,name=iPhone 11
|
||||||
|
- platform=tvOS Simulator,OS=latest,name=Apple TV
|
||||||
|
- platform=macOS # for code-coverage
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- run: swift package generate-xcodeproj --enable-code-coverage
|
||||||
|
- uses: sersoft-gmbh/xcodebuild-action@v1
|
||||||
|
with:
|
||||||
|
project: Path.swift.xcodeproj
|
||||||
|
scheme: Path.swift-Package
|
||||||
|
destination: ${{ matrix.destination }}
|
||||||
|
action: test
|
||||||
|
- uses: codecov/codecov-action@v1
|
||||||
|
watchOS:
|
||||||
|
needs: smoke
|
||||||
|
runs-on: macos-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- run: swift package generate-xcodeproj --enable-code-coverage
|
||||||
|
- uses: sersoft-gmbh/xcodebuild-action@v1
|
||||||
|
with:
|
||||||
|
project: Path.swift.xcodeproj
|
||||||
|
scheme: Path.swift-Package
|
||||||
|
destination: platform=watchOS Simulator,OS=latest,name=Apple Watch Series 5 - 40mm
|
||||||
|
action: build
|
||||||
|
linux:
|
||||||
|
needs: smoke
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
swift:
|
||||||
|
# - 4.0.3 fails for some reason
|
||||||
|
- 4.2
|
||||||
|
- 5.0.3
|
||||||
|
- 5.1
|
||||||
|
- 5.2
|
||||||
|
# - 5.3 not available yet sigh
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- uses: fwal/setup-swift@v1
|
||||||
|
with:
|
||||||
|
swift-version: ${{ matrix.swift }}
|
||||||
|
- run: swift test --parallel
|
||||||
82
.travis.yml
82
.travis.yml
@@ -1,90 +1,16 @@
|
|||||||
# only run for: merge commits, releases and pull-requests
|
# Travis does CD, GHA does CI
|
||||||
if: type != push OR branch = master OR branch =~ /^deploy-\d+\.\d+\.\d+(-.*)?$/ OR branch =~ /^\d+\.\d+\.\d+(-.*)?$/
|
if: branch =~ /^deploy-\d+\.\d+\.\d+(-.*)?$/ OR branch =~ /^\d+\.\d+\.\d+(-.*)?$/
|
||||||
|
|
||||||
stages:
|
stages:
|
||||||
- name: pretest
|
|
||||||
if: NOT branch =~ /^deploy-\d+\.\d+\.\d+(-.*)?$/
|
|
||||||
- name: test
|
|
||||||
if: NOT branch =~ /^deploy-\d+\.\d+\.\d+(-.*)?$/
|
|
||||||
- name: deploy
|
- name: deploy
|
||||||
if: branch =~ /^deploy-\d+\.\d+\.\d+(-.*)?$/
|
if: branch =~ /^deploy-\d+\.\d+\.\d+(-.*)?$/
|
||||||
- name: publish
|
- name: publish
|
||||||
if: branch =~ /^\d+\.\d+\.\d+(-.*)?$/
|
if: branch =~ /^\d+\.\d+\.\d+(-.*)?$/
|
||||||
|
|
||||||
os: osx
|
os: osx
|
||||||
language: swift
|
|
||||||
osx_image: xcode10.1
|
|
||||||
xcode_project: Path.swift.xcodeproj
|
|
||||||
xcode_scheme: Path.swift-Package
|
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
include:
|
include:
|
||||||
- name: macOS / Swift 4.0.3
|
|
||||||
before_script: swift build -Xswiftc -warnings-as-errors
|
|
||||||
script: swift test --parallel -Xswiftc -swift-version -Xswiftc 4
|
|
||||||
|
|
||||||
- &std
|
|
||||||
name: macOS / Swift 4.2.1
|
|
||||||
before_script: swift build -Xswiftc -warnings-as-errors
|
|
||||||
script: swift test --parallel
|
|
||||||
|
|
||||||
- <<: *std
|
|
||||||
name: macOS / Swift 5.0
|
|
||||||
osx_image: xcode10.2
|
|
||||||
|
|
||||||
- <<: *std
|
|
||||||
name: macOS / Swift 5.1
|
|
||||||
osx_image: xcode11
|
|
||||||
|
|
||||||
- &xcodebuild
|
|
||||||
before_install: swift package generate-xcodeproj --enable-code-coverage
|
|
||||||
xcode_destination: platform=iOS Simulator,OS=latest,name=iPhone XS
|
|
||||||
name: iOS / Swift 4.2.1
|
|
||||||
after_success: bash <(curl -s https://codecov.io/bash)
|
|
||||||
|
|
||||||
- <<: *xcodebuild
|
|
||||||
xcode_destination: platform=tvOS Simulator,OS=latest,name=Apple TV
|
|
||||||
name: tvOS / Swift 4.2.1
|
|
||||||
|
|
||||||
- <<: *xcodebuild
|
|
||||||
name: watchOS / Swift 4.2.1
|
|
||||||
script: |
|
|
||||||
set -o pipefail
|
|
||||||
xcodebuild \
|
|
||||||
-project Path.swift.xcodeproj \
|
|
||||||
-scheme Path.swift-Package \
|
|
||||||
-destination 'platform=watchOS Simulator,OS=latest,name=Apple Watch Series 4 - 40mm' \
|
|
||||||
build | xcpretty
|
|
||||||
after_success: false
|
|
||||||
|
|
||||||
- &linux
|
|
||||||
env: SWIFT_VERSION=4.2.4
|
|
||||||
os: linux
|
|
||||||
name: Linux / Swift 4.2.4
|
|
||||||
language: generic
|
|
||||||
sudo: false
|
|
||||||
install: eval "$(curl -sL https://swiftenv.fuller.li/install.sh)"
|
|
||||||
before_script: swift build -Xswiftc -warnings-as-errors
|
|
||||||
script: swift test --parallel
|
|
||||||
|
|
||||||
- <<: *linux
|
|
||||||
env: SWIFT_VERSION=5.0.3
|
|
||||||
name: Linux / Swift 5.0.3
|
|
||||||
|
|
||||||
- <<: *linux
|
|
||||||
env: SWIFT_VERSION=5.1.3
|
|
||||||
name: Linux / Swift 5.1.3
|
|
||||||
|
|
||||||
- <<: *linux
|
|
||||||
env: SWIFT_VERSION=5.2-DEVELOPMENT-SNAPSHOT-2020-01-22-a
|
|
||||||
name: Linux / Swift 5.2.0-dev+2020-01-22-a
|
|
||||||
|
|
||||||
- stage: pretest
|
|
||||||
name: Check Linux tests are sync’d
|
|
||||||
install: swift test --generate-linuxmain
|
|
||||||
script: git diff --exit-code
|
|
||||||
osx_image: xcode10.2
|
|
||||||
|
|
||||||
- stage: deploy
|
- stage: deploy
|
||||||
name: Deploy
|
name: Deploy
|
||||||
osx_image: xcode11
|
osx_image: xcode11
|
||||||
@@ -105,7 +31,7 @@ jobs:
|
|||||||
|
|
||||||
- stage: publish
|
- stage: publish
|
||||||
name: Jazzy
|
name: Jazzy
|
||||||
osx_image: xcode10.2
|
osx_image: xcode11
|
||||||
install: gem install jazzy
|
install: gem install jazzy
|
||||||
before_script: swift package generate-xcodeproj
|
before_script: swift package generate-xcodeproj
|
||||||
script: |
|
script: |
|
||||||
@@ -121,8 +47,8 @@ jobs:
|
|||||||
tags: true
|
tags: true
|
||||||
|
|
||||||
- name: CocoaPods
|
- name: CocoaPods
|
||||||
osx_image: xcode10.2
|
|
||||||
env: HOMEBREW_NO_INSTALL_CLEANUP=1
|
env: HOMEBREW_NO_INSTALL_CLEANUP=1
|
||||||
|
osx_image: xcode11
|
||||||
install:
|
install:
|
||||||
- brew install mxcl/made/swift-sh
|
- brew install mxcl/made/swift-sh
|
||||||
- curl -O https://raw.githubusercontent.com/mxcl/ops/master/deploy
|
- curl -O https://raw.githubusercontent.com/mxcl/ops/master/deploy
|
||||||
|
|||||||
39
README.md
39
README.md
@@ -31,6 +31,9 @@ print(bar.isFile) // => true
|
|||||||
let foo = try Path.root.join("foo").copy(into: Path.root.join("bar").mkdir())
|
let foo = try Path.root.join("foo").copy(into: Path.root.join("bar").mkdir())
|
||||||
print(foo) // => /bar/foo
|
print(foo) // => /bar/foo
|
||||||
print(foo.isFile) // => true
|
print(foo.isFile) // => true
|
||||||
|
// ^^ the `into:` version will only copy *into* a directory, the `to:` version copies
|
||||||
|
// to a file at that path, thus you will not accidentally copy into directories you
|
||||||
|
// may not have realized existed.
|
||||||
|
|
||||||
// we support dynamic-member-syntax when joining named static members, eg:
|
// we support dynamic-member-syntax when joining named static members, eg:
|
||||||
let prefs = Path.home.Library.Preferences // => /Users/mxcl/Library/Preferences
|
let prefs = Path.home.Library.Preferences // => /Users/mxcl/Library/Preferences
|
||||||
@@ -117,6 +120,25 @@ everything would compile if we allowed arbituary variables to take *any* named
|
|||||||
property as valid syntax. What we have is what you want most of the time but
|
property as valid syntax. What we have is what you want most of the time but
|
||||||
much less (potentially) dangerous (at runtime).
|
much less (potentially) dangerous (at runtime).
|
||||||
|
|
||||||
|
### Pathish
|
||||||
|
|
||||||
|
`Path`, and `DynamicPath` (the result of eg. `Path.root`) both conform to
|
||||||
|
`Pathish` which is a protocol that contains all pathing functions. Thus if
|
||||||
|
you create objects from a mixture of both you need to create generic
|
||||||
|
functions or convert any `DynamicPath`s to `Path` first:
|
||||||
|
|
||||||
|
```swift
|
||||||
|
let path1 = Path("/usr/lib")!
|
||||||
|
let path2 = Path.root.usr.bin
|
||||||
|
var paths = [Path]()
|
||||||
|
paths.append(path1) // fine
|
||||||
|
paths.append(path2) // error
|
||||||
|
paths.append(Path(path2)) // ok
|
||||||
|
```
|
||||||
|
|
||||||
|
This is inconvenient but as Swift stands there’s nothing we can think of
|
||||||
|
that would help.
|
||||||
|
|
||||||
## Initializing from user-input
|
## Initializing from user-input
|
||||||
|
|
||||||
The `Path` initializer returns `nil` unless fed an absolute path; thus to
|
The `Path` initializer returns `nil` unless fed an absolute path; thus to
|
||||||
@@ -140,7 +162,7 @@ strings that you need to be paths:
|
|||||||
|
|
||||||
```swift
|
```swift
|
||||||
let absolutePath = "/known/path"
|
let absolutePath = "/known/path"
|
||||||
let path1 = Path.root/pathString
|
let path1 = Path.root/absolutePath
|
||||||
|
|
||||||
let pathWithoutInitialSlash = "known/path"
|
let pathWithoutInitialSlash = "known/path"
|
||||||
let path2 = Path.root/pathWithoutInitialSlash
|
let path2 = Path.root/pathWithoutInitialSlash
|
||||||
@@ -278,6 +300,9 @@ Path.home/"/b" // => /Users/mxcl/b
|
|||||||
Path.home.foo.bar.join("..") // => /Users/mxcl/foo
|
Path.home.foo.bar.join("..") // => /Users/mxcl/foo
|
||||||
Path.home.foo.bar.join(".") // => /Users/mxcl/foo/bar
|
Path.home.foo.bar.join(".") // => /Users/mxcl/foo/bar
|
||||||
|
|
||||||
|
// though note that we provide `.parent`:
|
||||||
|
Path.home.foo.bar.parent // => /Users/mxcl/foo
|
||||||
|
|
||||||
// of course, feel free to join variables:
|
// of course, feel free to join variables:
|
||||||
let b = "b"
|
let b = "b"
|
||||||
let c = "c"
|
let c = "c"
|
||||||
@@ -342,9 +367,13 @@ no filesystem entry there at all check if `type` is `nil`.
|
|||||||
|
|
||||||
Changing directory is dangerous, you should *always* try to avoid it and thus
|
Changing directory is dangerous, you should *always* try to avoid it and thus
|
||||||
we don’t even provide the method. If you are executing a sub-process then
|
we don’t even provide the method. If you are executing a sub-process then
|
||||||
use `Process.currentDirectoryURL`.
|
use `Process.currentDirectoryURL` to change *its* working directory when it
|
||||||
|
executes.
|
||||||
|
|
||||||
If you must then use `FileManager.changeCurrentDirectory`.
|
If you must change directory then use `FileManager.changeCurrentDirectory` as
|
||||||
|
early in your process as *possible*. Altering the global state of your app’s
|
||||||
|
environment is fundamentally dangerous creating hard to debug issues that
|
||||||
|
you won‘t find for potentially *years*.
|
||||||
|
|
||||||
# I thought I should only use `URL`s?
|
# I thought I should only use `URL`s?
|
||||||
|
|
||||||
@@ -401,11 +430,11 @@ Carthage:
|
|||||||
|
|
||||||
|
|
||||||
[badge-platforms]: https://img.shields.io/badge/platforms-macOS%20%7C%20Linux%20%7C%20iOS%20%7C%20tvOS%20%7C%20watchOS-lightgrey.svg
|
[badge-platforms]: https://img.shields.io/badge/platforms-macOS%20%7C%20Linux%20%7C%20iOS%20%7C%20tvOS%20%7C%20watchOS-lightgrey.svg
|
||||||
[badge-languages]: https://img.shields.io/badge/swift-4.2%20%7C%205.0%20%7C%205.1%20%7C%205.2-orange.svg
|
[badge-languages]: https://img.shields.io/badge/swift-4.2%20%7C%205.0%20%7C%205.1%20%7C%205.2%20%7C%205.3-orange.svg
|
||||||
[docs]: https://mxcl.dev/Path.swift/Structs/Path.html
|
[docs]: https://mxcl.dev/Path.swift/Structs/Path.html
|
||||||
[badge-jazzy]: https://raw.githubusercontent.com/mxcl/Path.swift/gh-pages/badge.svg?sanitize=true
|
[badge-jazzy]: https://raw.githubusercontent.com/mxcl/Path.swift/gh-pages/badge.svg?sanitize=true
|
||||||
[badge-codecov]: https://codecov.io/gh/mxcl/Path.swift/branch/master/graph/badge.svg
|
[badge-codecov]: https://codecov.io/gh/mxcl/Path.swift/branch/master/graph/badge.svg
|
||||||
[badge-ci]: https://travis-ci.com/mxcl/Path.swift.svg
|
[badge-ci]: https://github.com/mxcl/Path.swift/workflows/Checks/badge.svg
|
||||||
[travis]: https://travis-ci.com/mxcl/Path.swift
|
[travis]: https://travis-ci.com/mxcl/Path.swift
|
||||||
[codecov]: https://codecov.io/gh/mxcl/Path.swift
|
[codecov]: https://codecov.io/gh/mxcl/Path.swift
|
||||||
[badge-version]: https://img.shields.io/cocoapods/v/Path.swift.svg?label=version
|
[badge-version]: https://img.shields.io/cocoapods/v/Path.swift.svg?label=version
|
||||||
|
|||||||
@@ -164,7 +164,7 @@ public extension Pathish {
|
|||||||
if options != .a, path.basename().hasPrefix(".") { return nil }
|
if options != .a, path.basename().hasPrefix(".") { return nil }
|
||||||
// ^^ we don’t use the Foundation `skipHiddenFiles` because it considers weird things hidden and we are mirroring `ls`
|
// ^^ we don’t use the Foundation `skipHiddenFiles` because it considers weird things hidden and we are mirroring `ls`
|
||||||
return path
|
return path
|
||||||
}
|
}.sorted()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Recursively find files under this path. If the path is a file, no files will be found.
|
/// Recursively find files under this path. If the path is a file, no files will be found.
|
||||||
|
|||||||
@@ -653,6 +653,12 @@ class PathTests: XCTestCase {
|
|||||||
XCTAssertEqual(bar.type, .symlink)
|
XCTAssertEqual(bar.type, .symlink)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func testOptionalInitializer() throws {
|
||||||
|
XCTAssertNil(Path(""))
|
||||||
|
XCTAssertNil(Path("./foo"))
|
||||||
|
XCTAssertEqual(Path("/foo"), Path.root.foo)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private func XCTAssertEqual<P: Pathish, Q: Pathish>(_ p: P, _ q: Q, file: StaticString = #file, line: UInt = #line) {
|
private func XCTAssertEqual<P: Pathish, Q: Pathish>(_ p: P, _ q: Q, file: StaticString = #file, line: UInt = #line) {
|
||||||
|
|||||||
@@ -46,6 +46,7 @@ extension PathTests {
|
|||||||
("testMoveInto", testMoveInto),
|
("testMoveInto", testMoveInto),
|
||||||
("testMoveTo", testMoveTo),
|
("testMoveTo", testMoveTo),
|
||||||
("testNoUndesiredSymlinkResolution", testNoUndesiredSymlinkResolution),
|
("testNoUndesiredSymlinkResolution", testNoUndesiredSymlinkResolution),
|
||||||
|
("testOptionalInitializer", testOptionalInitializer),
|
||||||
("testPathComponents", testPathComponents),
|
("testPathComponents", testPathComponents),
|
||||||
("testReadlinkOnFileReturnsSelf", testReadlinkOnFileReturnsSelf),
|
("testReadlinkOnFileReturnsSelf", testReadlinkOnFileReturnsSelf),
|
||||||
("testReadlinkOnNonExistantFileThrows", testReadlinkOnNonExistantFileThrows),
|
("testReadlinkOnNonExistantFileThrows", testReadlinkOnNonExistantFileThrows),
|
||||||
|
|||||||
Reference in New Issue
Block a user