Compare commits

..

8 Commits
0.3.0 ... 0.4.1

Author SHA1 Message Date
Max Howell
5cc2fcbf30 Tag 0.4.1 2019-01-20 16:26:22 -05:00
Max Howell
7595c601e8 Attempt custom Jazzy index/contents 2019-01-20 16:24:06 -05:00
Luciano Almeida
d8ea357459 Adding ls -a like functionality to Path.ls() 2019-01-20 16:23:40 -05:00
Max Howell
86798755be Deploy to CocoaPods 2019-01-20 13:37:34 -05:00
Max Howell
152ad8a8ae Implementations of CommonDirs for Linux 2019-01-20 13:03:38 -05:00
Max Howell
a98ba37e59 Merge pull request #1 from itsallmememe/master
Common Directories
2019-01-20 12:30:29 -05:00
Max Howell
1c2cffada5 Support CocoaPods 2019-01-19 22:12:06 -05:00
Niall McCormack
12c7b348d6 added hooks for common directories - Documents, Caches and Application Support 2019-01-19 00:24:20 +08:00
7 changed files with 181 additions and 39 deletions

View File

@@ -47,16 +47,26 @@ jobs:
- <<: *xcodebuild
stage: deploy
name: Jazzy
before_install: |
cat << EOF > .jazzy.yml
custom_categories:
- name: Path
children:
- Path
- /(_:_:)
EOF
touch Contents.md
install: gem install jazzy
script: |
jazzy \
--min-acl internal \
--no-hide-documentation-coverage \
--theme fullwidth \
--output output \
--readme README.md \
--readme Contents.md \
--root-url https://mxcl.github.io/Path.swift/ \
--github_url https://github.com/mxcl/Path.swift
--github_url https://github.com/mxcl/Path.swift \
--module Path \
--module-version $TRAVIS_TAG
deploy:
provider: pages
skip-cleanup: true
@@ -64,3 +74,8 @@ jobs:
local-dir: output
on:
tags: true
- stage: deploy
name: CocoaPods
install: gem install cocoapods --pre
script: pod trunk push --allow-warnings

19
Path.swift.podspec Normal file
View File

@@ -0,0 +1,19 @@
Pod::Spec.new do |s|
s.name = 'Path.swift'
s.version = '0.4.1'
s.summary = 'Delightful, robust file-pathing functions'
s.homepage = 'https://github.com/mxcl/Path.swift'
s.license = { :type => 'Unlicense', :file => 'LICENSE.md' }
s.author = { 'mxcl' => 'mxcl@me.com' }
s.source = { :git => 'https://github.com/mxcl/Path.swift.git', :tag => s.version.to_s }
s.social_media_url = 'https://twitter.com/mxcl'
s.osx.deployment_target = '10.10'
s.ios.deployment_target = '8.0'
s.tvos.deployment_target = '10.0'
s.watchos.deployment_target = '3.0'
s.source_files = 'Sources/*'
s.swift_version = "4.2"
end

View File

@@ -16,14 +16,14 @@ let docs = Path.home/"Documents"
let path = Path(userInput) ?? Path.cwd/userInput
// chainable syntax so you have less boilerplate
try Path.home.join("foo").mkpath().join("bar").touch().chmod(0o555)
try Path.home.join("foo").mkdir().join("bar").touch().chmod(0o555)
// easy file-management
try Path.root.join("foo").copy(to: Path.root/"bar")
// careful API to avoid common bugs
try Path.root.join("foo").copy(into: Path.root.mkdir("bar"))
// ^^ other libraries would make the `to:` form handle both these cases
// ^^ other libraries would make the above `to:` form handle both these cases
// but that can easily lead to bugs where you accidentally write files that
// were meant to be directory destinations
```
@@ -41,6 +41,8 @@ can continue to make tools and software you need and love. I appreciate it x.
<img src="https://c5.patreon.com/external/logo/become_a_patron_button@2x.png" width="160">
</a>
[Other donation/tipping options](http://mxcl.github.io/donate/)
# Handbook
Our [online API documentation] is automatically updated for new releases.
@@ -97,6 +99,11 @@ This is explicit, not hiding anything that code-review may miss and preventing
common bugs like accidentally creating `Path` objects from strings you did not
expect to be relative.
Our initializer is nameless because we conform to `LosslessStringConvertible`,
the same conformance as that `Int`, `Float` etc. conform. The protocol enforces
a nameless initialization and since it is appropriate for us to conform to it,
we do.
## Extensions
We have some extensions to Apple APIs:
@@ -165,7 +172,7 @@ Path.root/"~b" // => /~b
Path.root/"~/b" // => /~/b
// but is here
Path("~/foo")! // => /Users/foo
Path("~/foo")! // => /Users/mxcl/foo
// this does not work though
Path("~foo") // => nil
@@ -173,12 +180,21 @@ Path("~foo") // => nil
# Installation
SwiftPM only:
SwiftPM:
```swift
package.append(.package(url: "https://github.com/mxcl/Path.swift", from: "0.0.0"))
package.append(.package(url: "https://github.com/mxcl/Path.swift", from: "0.4.1"))
```
CocoaPods:
```ruby
pod 'Path.swift' ~> '0.4.1'
```
Please note! We are pre 1.0, thus we can change the API as we like! We will tag
1.0 as soon as possible.
### Get push notifications for new releases
https://codebasesaga.com/canopy/

View File

@@ -0,0 +1,90 @@
import Foundation
extension Path {
/// Returns a `Path` containing ``FileManager.default.currentDirectoryPath`.
public static var cwd: Path {
return Path(string: FileManager.default.currentDirectoryPath)
}
/// Returns a `Path` representing the root path.
public static var root: Path {
return Path(string: "/")
}
/// Returns a `Path` representing the users home directory
public static var home: Path {
let string: String
#if os(macOS)
if #available(OSX 10.12, *) {
string = FileManager.default.homeDirectoryForCurrentUser.path
} else {
string = NSHomeDirectory()
}
#else
string = NSHomeDirectory()
#endif
return Path(string: string)
}
/// Helper to allow search path and domain mask to be passed in.
private static func path(for searchPath: FileManager.SearchPathDirectory) -> Path {
#if os(Linux)
// the urls(for:in:) function is not implemented on Linux
//TODO strictly we should first try to use the provided binary tool
let foo = { ProcessInfo.processInfo.environment[$0].flatMap(Path.init) ?? $1 }
switch searchPath {
case .documentDirectory:
return Path.home/"Documents"
case .applicationSupportDirectory:
return foo("XDG_DATA_HOME", Path.home/".local/share")
case .cachesDirectory:
return foo("XDG_CACHE_HOME", Path.home/".cache")
default:
fatalError()
}
#else
guard let pathString = FileManager.default.urls(for: searchPath, in: .userDomainMask).first?.path else {
switch searchPath {
case .documentDirectory:
return Path.home/"Documents"
case .applicationSupportDirectory:
return Path.home/"Library/Application Support"
case .cachesDirectory:
return Path.home/"Library/Caches"
default:
fatalError()
}
}
return Path(string: pathString)
#endif
}
/**
The root for user documents.
- Note: There is no standard location for documents on Linux, thus we return `~/Documents`.
- Note: You should create a subdirectory before creating any files.
*/
public static var documents: Path {
return path(for: .documentDirectory)
}
/**
The root for cache files.
- Note: On Linux this is 'XDG_CACHE_HOME'.
- Note: You should create a subdirectory before creating any files.
*/
public static var caches: Path {
return path(for: .cachesDirectory)
}
/**
For data that supports your running application.
- Note: On Linux is `XDG_DATA_HOME`.
- Note: You should create a subdirectory before creating any files.
*/
public static var applicationSupport: Path {
return path(for: .applicationSupportDirectory)
}
}

View File

@@ -1,14 +1,18 @@
import Foundation
public extension Path {
/// same as the `ls` command is shallow
func ls() throws -> [Entry] {
let relativePaths = try FileManager.default.contentsOfDirectory(atPath: string)
func convert(relativePath: String) -> Entry {
let path = self/relativePath
/// Same as the `ls` command is shallow
/// - Parameter skipHiddenFiles: Same as the `ls -a` if false. Otherwise returns only the non hidden files. Default is false.
func ls(skipHiddenFiles: Bool = false) throws -> [Entry] {
let options: FileManager.DirectoryEnumerationOptions = skipHiddenFiles ? [.skipsHiddenFiles] : []
let paths = try FileManager.default.contentsOfDirectory(at: url,
includingPropertiesForKeys: nil,
options: options)
func convert(url: URL) -> Entry? {
guard let path = Path(url.path) else { return nil }
return Entry(kind: path.isDirectory ? .directory : .file, path: path)
}
return relativePaths.map(convert)
return paths.compactMap(convert)
}
}

View File

@@ -16,31 +16,6 @@ public struct Path: Equatable, Hashable, Comparable {
/// The underlying filesystem path
public let string: String
/// Returns a `Path` containing ``FileManager.default.currentDirectoryPath`.
public static var cwd: Path {
return Path(string: FileManager.default.currentDirectoryPath)
}
/// Returns a `Path` representing the root path.
public static var root: Path {
return Path(string: "/")
}
/// Returns a `Path` representing the users home directory
public static var home: Path {
let string: String
#if os(macOS)
if #available(OSX 10.12, *) {
string = FileManager.default.homeDirectoryForCurrentUser.path
} else {
string = NSHomeDirectory()
}
#else
string = NSHomeDirectory()
#endif
return Path(string: string)
}
/**
Returns the filename extension of this path.
- Remark: Implemented via `NSString.pathExtension`.

View File

@@ -17,6 +17,7 @@ class PathTests: XCTestCase {
try tmpdir.join("a").mkdir().join("c").touch()
try tmpdir.join("b").touch()
try tmpdir.join("c").touch()
try tmpdir.join(".d").mkdir().join("e").touch()
var paths = Set<String>()
var dirs = 0
@@ -26,8 +27,30 @@ class PathTests: XCTestCase {
}
paths.insert(entry.path.basename())
}
XCTAssertEqual(dirs, 2)
XCTAssertEqual(paths, ["a", "b", "c", ".d"])
}
func testEnumerationSkippingHiddenFiles() throws {
let tmpdir_ = try TemporaryDirectory()
let tmpdir = tmpdir_.path
try tmpdir.join("a").mkdir().join("c").touch()
try tmpdir.join("b").touch()
try tmpdir.join("c").touch()
try tmpdir.join(".d").mkdir().join("e").touch()
var paths = Set<String>()
var dirs = 0
for entry in try tmpdir.ls(skipHiddenFiles: true) {
if entry.kind == .directory {
dirs += 1
}
paths.insert(entry.path.basename())
}
XCTAssertEqual(dirs, 1)
XCTAssertEqual(paths, ["a", "b", "c"])
}
func testRelativeTo() {