mirror of
https://github.com/nicoverbruggen/phpmon.git
synced 2025-08-11 13:30:07 +02:00
👌 Removed remaining FileManager.default
usage
This commit is contained in:
@@ -16,7 +16,11 @@ protocol FileSystemProtocol {
|
|||||||
|
|
||||||
func writeAtomicallyToFile(_ path: String, content: String) throws
|
func writeAtomicallyToFile(_ path: String, content: String) throws
|
||||||
|
|
||||||
func readStringFromFile(_ path: String) throws -> String
|
func getStringFromFile(_ path: String) throws -> String
|
||||||
|
|
||||||
|
func getContentsOfDirectory(_ path: String) throws -> [String]
|
||||||
|
|
||||||
|
func getDestinationOfSymlink(_ path: String) throws -> String
|
||||||
|
|
||||||
// MARK: - Move & Delete Files
|
// MARK: - Move & Delete Files
|
||||||
|
|
||||||
@@ -40,5 +44,7 @@ protocol FileSystemProtocol {
|
|||||||
|
|
||||||
func directoryExists(_ path: String) -> Bool
|
func directoryExists(_ path: String) -> Bool
|
||||||
|
|
||||||
func fileIsSymlink(_ path: String) -> Bool
|
func isSymlink(_ path: String) -> Bool
|
||||||
|
|
||||||
|
func isDirectory(_ path: String) -> Bool
|
||||||
}
|
}
|
||||||
|
@@ -33,13 +33,21 @@ class RealFileSystem: FileSystemProtocol {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
func readStringFromFile(_ path: String) throws -> String {
|
func getStringFromFile(_ path: String) throws -> String {
|
||||||
return try String(
|
return try String(
|
||||||
contentsOf: URL(fileURLWithPath: path.replacingTildeWithHomeDirectory),
|
contentsOf: URL(fileURLWithPath: path.replacingTildeWithHomeDirectory),
|
||||||
encoding: .utf8
|
encoding: .utf8
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getContentsOfDirectory(_ path: String) throws -> [String] {
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
func getDestinationOfSymlink(_ path: String) throws -> String {
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
|
||||||
// MARK: - Move & Delete Files
|
// MARK: - Move & Delete Files
|
||||||
|
|
||||||
func move(from path: String, to newPath: String) throws {
|
func move(from path: String, to newPath: String) throws {
|
||||||
@@ -96,7 +104,7 @@ class RealFileSystem: FileSystemProtocol {
|
|||||||
return exists && isDirectory.boolValue
|
return exists && isDirectory.boolValue
|
||||||
}
|
}
|
||||||
|
|
||||||
func fileIsSymlink(_ path: String) -> Bool {
|
func isSymlink(_ path: String) -> Bool {
|
||||||
do {
|
do {
|
||||||
let attribs = try FileManager.default.attributesOfItem(atPath: path)
|
let attribs = try FileManager.default.attributesOfItem(atPath: path)
|
||||||
return attribs[.type] as! FileAttributeType == FileAttributeType.typeSymbolicLink
|
return attribs[.type] as! FileAttributeType == FileAttributeType.typeSymbolicLink
|
||||||
@@ -104,4 +112,13 @@ class RealFileSystem: FileSystemProtocol {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func isDirectory(_ path: String) -> Bool {
|
||||||
|
do {
|
||||||
|
let attribs = try FileManager.default.attributesOfItem(atPath: path)
|
||||||
|
return attribs[.type] as! FileAttributeType == FileAttributeType.typeDirectory
|
||||||
|
} catch {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -93,7 +93,7 @@ class PhpHelper {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if !FileSystem.fileIsSymlink(destination) {
|
if !FileSystem.isSymlink(destination) {
|
||||||
Log.info("Overwriting existing file with new symlink: \(destination)")
|
Log.info("Overwriting existing file with new symlink: \(destination)")
|
||||||
await Shell.quiet("ln -fs \(source) \(destination)")
|
await Shell.quiet("ln -fs \(source) \(destination)")
|
||||||
return
|
return
|
||||||
|
@@ -33,7 +33,7 @@ class TestableFileSystem: FileSystemProtocol {
|
|||||||
self.files[path] = .fake(.text, content)
|
self.files[path] = .fake(.text, content)
|
||||||
}
|
}
|
||||||
|
|
||||||
func readStringFromFile(_ path: String) throws -> String {
|
func getStringFromFile(_ path: String) throws -> String {
|
||||||
guard let file = files[path] else {
|
guard let file = files[path] else {
|
||||||
throw TestableFileSystemError.fileMissing
|
throw TestableFileSystemError.fileMissing
|
||||||
}
|
}
|
||||||
@@ -41,6 +41,30 @@ class TestableFileSystem: FileSystemProtocol {
|
|||||||
return file.content ?? ""
|
return file.content ?? ""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getContentsOfDirectory(_ path: String) throws -> [String] {
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
func getDestinationOfSymlink(_ path: String) throws -> String {
|
||||||
|
guard let file = files[path] else {
|
||||||
|
throw TestableFileSystemError.fileMissing
|
||||||
|
}
|
||||||
|
|
||||||
|
if file.type != .symlink {
|
||||||
|
throw TestableFileSystemError.notSymlink
|
||||||
|
}
|
||||||
|
|
||||||
|
guard let pathToSymlink = file.content else {
|
||||||
|
throw TestableFileSystemError.invalidSymlink
|
||||||
|
}
|
||||||
|
|
||||||
|
if !files.keys.contains(pathToSymlink) {
|
||||||
|
throw TestableFileSystemError.invalidSymlink
|
||||||
|
}
|
||||||
|
|
||||||
|
return pathToSymlink
|
||||||
|
}
|
||||||
|
|
||||||
// MARK: - Move & Delete Files
|
// MARK: - Move & Delete Files
|
||||||
|
|
||||||
func move(from path: String, to newPath: String) throws {
|
func move(from path: String, to newPath: String) throws {
|
||||||
@@ -99,13 +123,21 @@ class TestableFileSystem: FileSystemProtocol {
|
|||||||
return [.directory].contains(file.type)
|
return [.directory].contains(file.type)
|
||||||
}
|
}
|
||||||
|
|
||||||
func fileIsSymlink(_ path: String) -> Bool {
|
func isSymlink(_ path: String) -> Bool {
|
||||||
guard let file = files[path] else {
|
guard let file = files[path] else {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
return file.type == .symlink
|
return file.type == .symlink
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func isDirectory(_ path: String) -> Bool {
|
||||||
|
guard let file = files[path] else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return file.type == .directory
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
enum FakeFileType: Codable {
|
enum FakeFileType: Codable {
|
||||||
@@ -139,4 +171,6 @@ class FakeFile: Codable {
|
|||||||
enum TestableFileSystemError: Error {
|
enum TestableFileSystemError: Error {
|
||||||
case fileMissing
|
case fileMissing
|
||||||
case alreadyExists
|
case alreadyExists
|
||||||
|
case notSymlink
|
||||||
|
case invalidSymlink
|
||||||
}
|
}
|
||||||
|
@@ -86,7 +86,7 @@ class Startup {
|
|||||||
// The Homebrew binary must exist.
|
// The Homebrew binary must exist.
|
||||||
// =================================================================================
|
// =================================================================================
|
||||||
EnvironmentCheck(
|
EnvironmentCheck(
|
||||||
command: { return !FileManager.default.fileExists(atPath: Paths.brew) },
|
command: { return !FileSystem.fileExists(Paths.brew) },
|
||||||
name: "`\(Paths.brew)` exists",
|
name: "`\(Paths.brew)` exists",
|
||||||
titleText: "alert.homebrew_missing.title".localized,
|
titleText: "alert.homebrew_missing.title".localized,
|
||||||
subtitleText: "alert.homebrew_missing.subtitle".localized,
|
subtitleText: "alert.homebrew_missing.subtitle".localized,
|
||||||
@@ -205,7 +205,7 @@ class Startup {
|
|||||||
command: {
|
command: {
|
||||||
let nodePath = await Shell.pipe("which node").out
|
let nodePath = await Shell.pipe("which node").out
|
||||||
return App.architecture == "x86_64"
|
return App.architecture == "x86_64"
|
||||||
&& FileManager.default.fileExists(atPath: "/usr/local/bin/which")
|
&& FileSystem.fileExists("/usr/local/bin/which")
|
||||||
&& nodePath.contains("env: node: No such file or directory")
|
&& nodePath.contains("env: node: No such file or directory")
|
||||||
},
|
},
|
||||||
name: "`env: node` issue does not apply",
|
name: "`env: node` issue does not apply",
|
||||||
|
@@ -12,8 +12,8 @@ class ValetSiteScanner: SiteScanner {
|
|||||||
func resolveSiteCount(paths: [String]) -> Int {
|
func resolveSiteCount(paths: [String]) -> Int {
|
||||||
return paths.map { path in
|
return paths.map { path in
|
||||||
|
|
||||||
let entries = try! FileManager.default
|
let entries = try! FileSystem
|
||||||
.contentsOfDirectory(atPath: path)
|
.getContentsOfDirectory(path)
|
||||||
|
|
||||||
return entries
|
return entries
|
||||||
.map { self.isSite($0, forPath: path) }
|
.map { self.isSite($0, forPath: path) }
|
||||||
@@ -27,8 +27,8 @@ class ValetSiteScanner: SiteScanner {
|
|||||||
var sites: [ValetSite] = []
|
var sites: [ValetSite] = []
|
||||||
|
|
||||||
paths.forEach { path in
|
paths.forEach { path in
|
||||||
let entries = try! FileManager.default
|
let entries = try! FileSystem
|
||||||
.contentsOfDirectory(atPath: path)
|
.getContentsOfDirectory(path)
|
||||||
|
|
||||||
return entries.forEach {
|
return entries.forEach {
|
||||||
if let site = self.resolveSite(path: "\(path)/\($0)") {
|
if let site = self.resolveSite(path: "\(path)/\($0)") {
|
||||||
@@ -48,24 +48,19 @@ class ValetSiteScanner: SiteScanner {
|
|||||||
// Get the TLD from the global Valet object
|
// Get the TLD from the global Valet object
|
||||||
let tld = Valet.shared.config.tld
|
let tld = Valet.shared.config.tld
|
||||||
|
|
||||||
// See if the file is a symlink, if so, resolve it
|
if !FileSystem.anyExists(path) {
|
||||||
guard let attrs = try? FileManager.default.attributesOfItem(atPath: path) else {
|
|
||||||
Log.warn("Could not parse the site: \(path), skipping!")
|
Log.warn("Could not parse the site: \(path), skipping!")
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// We can also determine whether the thing at the path is a directory, too
|
|
||||||
let type = attrs[FileAttributeKey.type] as! FileAttributeType
|
|
||||||
|
|
||||||
// We should also check that we can interpret the path correctly
|
// We should also check that we can interpret the path correctly
|
||||||
if URL(fileURLWithPath: path).lastPathComponent == "" {
|
if URL(fileURLWithPath: path).lastPathComponent == "" {
|
||||||
Log.warn("Could not parse the site: \(path), skipping!")
|
Log.warn("Could not parse the site: \(path), skipping!")
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if type == FileAttributeType.typeSymbolicLink {
|
if FileSystem.isSymlink(path) {
|
||||||
return ValetSite(aliasPath: path, tld: tld)
|
return ValetSite(aliasPath: path, tld: tld)
|
||||||
} else if type == FileAttributeType.typeDirectory {
|
} else if FileSystem.isDirectory(path) {
|
||||||
return ValetSite(absolutePath: path, tld: tld)
|
return ValetSite(absolutePath: path, tld: tld)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -79,14 +74,6 @@ class ValetSiteScanner: SiteScanner {
|
|||||||
private func isSite(_ entry: String, forPath path: String) -> Bool {
|
private func isSite(_ entry: String, forPath path: String) -> Bool {
|
||||||
let siteDir = path + "/" + entry
|
let siteDir = path + "/" + entry
|
||||||
|
|
||||||
let attrs = try! FileManager.default.attributesOfItem(atPath: siteDir)
|
return (FileSystem.isDirectory(siteDir) || FileSystem.isSymlink(siteDir))
|
||||||
|
|
||||||
let type = attrs[FileAttributeKey.type] as! FileAttributeType
|
|
||||||
|
|
||||||
if type == FileAttributeType.typeSymbolicLink || type == FileAttributeType.typeDirectory {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -94,7 +94,7 @@ class ValetSite: DomainListable {
|
|||||||
|
|
||||||
convenience init(aliasPath: String, tld: String) {
|
convenience init(aliasPath: String, tld: String) {
|
||||||
let name = URL(fileURLWithPath: aliasPath).lastPathComponent
|
let name = URL(fileURLWithPath: aliasPath).lastPathComponent
|
||||||
let absolutePath = try! FileManager.default.destinationOfSymbolicLink(atPath: aliasPath)
|
let absolutePath = try! FileSystem.getDestinationOfSymlink(aliasPath)
|
||||||
self.init(name: name, tld: tld, absolutePath: absolutePath, aliasPath: aliasPath)
|
self.init(name: name, tld: tld, absolutePath: absolutePath, aliasPath: aliasPath)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -101,7 +101,7 @@ class Valet {
|
|||||||
do {
|
do {
|
||||||
config = try JSONDecoder().decode(
|
config = try JSONDecoder().decode(
|
||||||
Valet.Configuration.self,
|
Valet.Configuration.self,
|
||||||
from: FileSystem.readStringFromFile("~/.config/valet/config.json").data(using: .utf8)!
|
from: FileSystem.getStringFromFile("~/.config/valet/config.json").data(using: .utf8)!
|
||||||
)
|
)
|
||||||
} catch {
|
} catch {
|
||||||
Log.err(error)
|
Log.err(error)
|
||||||
@@ -206,10 +206,7 @@ class Valet {
|
|||||||
|
|
||||||
proxies = ValetScanners.proxyScanner
|
proxies = ValetScanners.proxyScanner
|
||||||
.resolveProxies(
|
.resolveProxies(
|
||||||
directoryPath: FileManager.default
|
directoryPath: "~/.config/valet/Nginx".replacingTildeWithHomeDirectory
|
||||||
.homeDirectoryForCurrentUser
|
|
||||||
.appendingPathComponent(".config/valet/Nginx")
|
|
||||||
.path
|
|
||||||
)
|
)
|
||||||
|
|
||||||
if let defaultPath = Valet.shared.config.defaultSite,
|
if let defaultPath = Valet.shared.config.defaultSite,
|
||||||
|
@@ -33,7 +33,7 @@ class WarningManager {
|
|||||||
Warning(
|
Warning(
|
||||||
command: {
|
command: {
|
||||||
return !Shell.PATH.contains("\(Paths.homePath)/.config/phpmon/bin") &&
|
return !Shell.PATH.contains("\(Paths.homePath)/.config/phpmon/bin") &&
|
||||||
!FileManager.default.isWritableFile(atPath: "/usr/local/bin/")
|
!FileSystem.isWriteableFile("/usr/local/bin/")
|
||||||
},
|
},
|
||||||
name: "Helpers cannot be symlinked and not in PATH",
|
name: "Helpers cannot be symlinked and not in PATH",
|
||||||
title: "warnings.helper_permissions.title",
|
title: "warnings.helper_permissions.title",
|
||||||
|
@@ -21,6 +21,10 @@ class PhpConfigWatcher {
|
|||||||
var watchers: [FSWatcher] = []
|
var watchers: [FSWatcher] = []
|
||||||
|
|
||||||
init(for url: URL) {
|
init(for url: URL) {
|
||||||
|
if FileSystem is TestableFileSystem {
|
||||||
|
fatalError("PhpConfigWatcher is not compatible with testable FS! You are not allowed to instantiate these while using a testable FS.")
|
||||||
|
}
|
||||||
|
|
||||||
self.url = url
|
self.url = url
|
||||||
|
|
||||||
// Add a watcher for php.ini
|
// Add a watcher for php.ini
|
||||||
|
Reference in New Issue
Block a user