mirror of
https://github.com/samsonjs/FileOtter.git
synced 2026-03-25 08:25:49 +00:00
WIP
This commit is contained in:
parent
8227e5ee7b
commit
c74842ef76
4 changed files with 180 additions and 0 deletions
|
|
@ -11,6 +11,9 @@
|
|||
7B5064BF2BD9F236009CEFF9 /* FileOtter.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7B5064B42BD9F236009CEFF9 /* FileOtter.framework */; };
|
||||
7B5064C42BD9F236009CEFF9 /* FileOtterTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B5064C32BD9F236009CEFF9 /* FileOtterTests.swift */; };
|
||||
7B5064C52BD9F236009CEFF9 /* FileOtter.h in Headers */ = {isa = PBXBuildFile; fileRef = 7B5064B72BD9F236009CEFF9 /* FileOtter.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
7B5064CF2BD9F2C0009CEFF9 /* Readme.md in Resources */ = {isa = PBXBuildFile; fileRef = 7B5064CE2BD9F2C0009CEFF9 /* Readme.md */; };
|
||||
7B5064D12BD9F322009CEFF9 /* File.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B5064D02BD9F322009CEFF9 /* File.swift */; };
|
||||
7B5064D32BD9F339009CEFF9 /* Dir.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B5064D22BD9F339009CEFF9 /* Dir.swift */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXContainerItemProxy section */
|
||||
|
|
@ -29,6 +32,9 @@
|
|||
7B5064B82BD9F236009CEFF9 /* FileOtter.docc */ = {isa = PBXFileReference; lastKnownFileType = folder.documentationcatalog; path = FileOtter.docc; sourceTree = "<group>"; };
|
||||
7B5064BE2BD9F236009CEFF9 /* FileOtterTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = FileOtterTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
7B5064C32BD9F236009CEFF9 /* FileOtterTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FileOtterTests.swift; sourceTree = "<group>"; };
|
||||
7B5064CE2BD9F2C0009CEFF9 /* Readme.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = net.daringfireball.markdown; path = Readme.md; sourceTree = "<group>"; };
|
||||
7B5064D02BD9F322009CEFF9 /* File.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = File.swift; sourceTree = "<group>"; };
|
||||
7B5064D22BD9F339009CEFF9 /* Dir.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Dir.swift; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
|
|
@ -53,6 +59,7 @@
|
|||
7B5064AA2BD9F235009CEFF9 = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
7B5064CE2BD9F2C0009CEFF9 /* Readme.md */,
|
||||
7B5064B62BD9F236009CEFF9 /* FileOtter */,
|
||||
7B5064C22BD9F236009CEFF9 /* FileOtterTests */,
|
||||
7B5064B52BD9F236009CEFF9 /* Products */,
|
||||
|
|
@ -73,6 +80,8 @@
|
|||
children = (
|
||||
7B5064B72BD9F236009CEFF9 /* FileOtter.h */,
|
||||
7B5064B82BD9F236009CEFF9 /* FileOtter.docc */,
|
||||
7B5064D02BD9F322009CEFF9 /* File.swift */,
|
||||
7B5064D22BD9F339009CEFF9 /* Dir.swift */,
|
||||
);
|
||||
path = FileOtter;
|
||||
sourceTree = "<group>";
|
||||
|
|
@ -177,6 +186,7 @@
|
|||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
7B5064CF2BD9F2C0009CEFF9 /* Readme.md in Resources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
|
@ -195,6 +205,8 @@
|
|||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
7B5064B92BD9F236009CEFF9 /* FileOtter.docc in Sources */,
|
||||
7B5064D12BD9F322009CEFF9 /* File.swift in Sources */,
|
||||
7B5064D32BD9F339009CEFF9 /* Dir.swift in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
|
@ -423,6 +435,7 @@
|
|||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALLOW_TARGET_PLATFORM_SPECIALIZATION = YES;
|
||||
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
DEVELOPMENT_TEAM = X45WPY5JFZ;
|
||||
|
|
@ -444,6 +457,7 @@
|
|||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALLOW_TARGET_PLATFORM_SPECIALIZATION = YES;
|
||||
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
DEVELOPMENT_TEAM = X45WPY5JFZ;
|
||||
|
|
|
|||
150
FileOtter/Dir.swift
Normal file
150
FileOtter/Dir.swift
Normal file
|
|
@ -0,0 +1,150 @@
|
|||
//
|
||||
// Dir.swift
|
||||
// FileOtter
|
||||
//
|
||||
// Created by Sami Samhuri on 2024-04-24.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
public struct Dir: Equatable, Hashable, RandomAccessCollection {
|
||||
public let startIndex: Int
|
||||
|
||||
public let endIndex: Int
|
||||
|
||||
public let url: URL
|
||||
|
||||
public init(url: URL) throws {
|
||||
self.init(url: url, children: try Dir.children(url))
|
||||
}
|
||||
|
||||
private let children: [URL]
|
||||
|
||||
private init(url: URL, children: [URL]) {
|
||||
self.url = url
|
||||
self.children = children
|
||||
startIndex = children.startIndex
|
||||
endIndex = children.endIndex
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Well-known Directories
|
||||
extension Dir {
|
||||
public static var caches: URL {
|
||||
URL.cachesDirectory
|
||||
}
|
||||
|
||||
public static var current: URL {
|
||||
URL.currentDirectory()
|
||||
}
|
||||
|
||||
public static var documents: URL {
|
||||
URL.documentsDirectory
|
||||
}
|
||||
|
||||
public static var home: URL {
|
||||
URL.homeDirectory
|
||||
}
|
||||
|
||||
public static var library: URL {
|
||||
URL.libraryDirectory
|
||||
}
|
||||
|
||||
public static var pwd: URL {
|
||||
.currentDirectory()
|
||||
}
|
||||
|
||||
public static var getwd: URL {
|
||||
.currentDirectory()
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Mutations
|
||||
extension Dir {
|
||||
@discardableResult
|
||||
public static func chdir(_ url: URL) -> Bool {
|
||||
FileManager.default.changeCurrentDirectoryPath(url.path)
|
||||
}
|
||||
|
||||
@discardableResult
|
||||
public static func chdir<T>(_ url: URL, block: (URL) -> T) -> T {
|
||||
let previousDir = pwd
|
||||
FileManager.default.changeCurrentDirectoryPath(url.path)
|
||||
defer {
|
||||
FileManager.default.changeCurrentDirectoryPath(previousDir.path)
|
||||
}
|
||||
return block(url)
|
||||
}
|
||||
|
||||
@discardableResult
|
||||
public static func unlink(_ url: URL) -> Bool {
|
||||
do {
|
||||
try FileManager.default.removeItem(at: url)
|
||||
return true
|
||||
} catch {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
@discardableResult
|
||||
public static func rmdir(_ url: URL) -> Bool {
|
||||
unlink(url)
|
||||
}
|
||||
|
||||
@discardableResult
|
||||
public static func delete(_ url: URL) -> Bool {
|
||||
unlink(url)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Reading Contents
|
||||
extension Dir {
|
||||
public static func children(_ url: URL) throws -> [URL] {
|
||||
try FileManager.default
|
||||
.contentsOfDirectory(at: url, includingPropertiesForKeys: nil)
|
||||
}
|
||||
|
||||
public static func entries(_ url: URL) throws -> [String] {
|
||||
#warning("TODO: implement this ... maybe, it's dumb")
|
||||
return []
|
||||
}
|
||||
|
||||
public static func exists(_ url: URL) throws -> Bool {
|
||||
var isDirectory: ObjCBool = false
|
||||
let exists = FileManager.default.fileExists(atPath: url.path, isDirectory: &isDirectory)
|
||||
return exists && isDirectory.boolValue
|
||||
}
|
||||
|
||||
public static func isEmpty(_ url: URL) throws -> Bool {
|
||||
try FileManager.default
|
||||
.contentsOfDirectory(at: url, includingPropertiesForKeys: nil)
|
||||
.isEmpty
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Globbing
|
||||
extension Dir {
|
||||
public static func glob(base: URL? = nil, _ patterns: String...) -> [URL] {
|
||||
_glob(base: base, patterns: patterns)
|
||||
}
|
||||
|
||||
public static subscript(base: URL? = nil, _ patterns: String...) -> [URL] {
|
||||
_glob(base: base, patterns: patterns)
|
||||
}
|
||||
|
||||
private static func _glob(base: URL?, patterns: [String]) -> [URL] {
|
||||
#warning("TODO: implement me")
|
||||
return []
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - RandomAccessCollection
|
||||
extension Dir {
|
||||
public func makeIterator() -> any IteratorProtocol<URL> {
|
||||
children.makeIterator()
|
||||
}
|
||||
|
||||
public subscript(position: Int) -> URL {
|
||||
children[position]
|
||||
}
|
||||
}
|
||||
10
FileOtter/File.swift
Normal file
10
FileOtter/File.swift
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
//
|
||||
// File.swift
|
||||
// FileOtter
|
||||
//
|
||||
// Created by Sami Samhuri on 2024-04-24.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
public struct File {}
|
||||
6
Readme.md
Normal file
6
Readme.md
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
# FileOtter
|
||||
|
||||
A sleek way to interact with the filesystem in Swift. Heavily inspired by Ruby's `[Dir][]` and `[File][]` classes from the standard library.
|
||||
|
||||
[Dir]: https://docs.ruby-lang.org/en/3.3/Dir.html
|
||||
[File]: https://docs.ruby-lang.org/en/3.3/File.html
|
||||
Loading…
Reference in a new issue