Compare commits

...

6 Commits
1.0.1 ... 1.1.0

Author SHA1 Message Date
Max Howell
07007a5421 GHA CI Badge 2020-07-26 13:59:53 -04:00
Max Howell
8a217b3982 Merge pull request #62 from mxcl/sort-ls
ls() is sorted; Fixes #58
2020-07-26 13:58:44 -04:00
Max Howell
2b50909946 ls() is sorted; Fixes #58 2020-07-26 13:48:15 -04:00
Max Howell
baa6416208 Use GHA instead of Travis where possible 2020-07-26 13:39:10 -04:00
Max Howell
6e99825d9f Probably redundant tests, but why not 2020-02-09 14:52:49 -05:00
Max Howell
6e37bfde4d Update README.md 2020-02-09 14:29:28 -05:00
7 changed files with 135 additions and 84 deletions

12
.github/workflows/checks.yml vendored Normal file
View 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
View 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 (doesnt 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

View File

@@ -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 syncd
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

View File

@@ -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 theres 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 dont even provide the method. If you are executing a sub-process then we dont 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 apps
environment is fundamentally dangerous creating hard to debug issues that
you wont 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

View File

@@ -164,7 +164,7 @@ public extension Pathish {
if options != .a, path.basename().hasPrefix(".") { return nil } if options != .a, path.basename().hasPrefix(".") { return nil }
// ^^ we dont use the Foundation `skipHiddenFiles` because it considers weird things hidden and we are mirroring `ls` // ^^ we dont 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.

View File

@@ -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) {

View File

@@ -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),