diff --git a/phpmon-common/Core/Paths.swift b/phpmon-common/Core/Paths.swift index 355da3e..c63d4cd 100644 --- a/phpmon-common/Core/Paths.swift +++ b/phpmon-common/Core/Paths.swift @@ -17,8 +17,11 @@ public class Paths { private var baseDir : Paths.HomebrewDir + private var userName : String + init() { baseDir = Shell.fileExists("\(HomebrewDir.opt.rawValue)/bin/brew") ? .opt : .usr + userName = String(Shell.pipe("whoami").split(separator: "\n")[0]) } // - MARK: Binaries @@ -42,7 +45,7 @@ public class Paths { // - MARK: Paths public static var whoami: String { - return String(Shell.pipe("whoami").split(separator: "\n")[0]) + return shared.userName } public static var binPath: String { diff --git a/phpmon/Domain/Integrations/Valet/Valet.swift b/phpmon/Domain/Integrations/Valet/Valet.swift index 5690c66..25d18af 100644 --- a/phpmon/Domain/Integrations/Valet/Valet.swift +++ b/phpmon/Domain/Integrations/Valet/Valet.swift @@ -164,6 +164,13 @@ class Valet { /// The absolute path to the directory that is served. var absolutePath: String! + /// The absolute path to the directory that is served, + /// replacing the user's home folder with ~. + lazy var absolutePathRelative: String = { + return self.absolutePath + .replacingOccurrences(of: "/Users/\(Paths.whoami)", with: "~") + }() + /// Location of the alias. If set, this is a linked domain. var aliasPath: String? @@ -182,6 +189,9 @@ class Valet { /// The PHP version as discovered in composer.json. var composerPhp: String = "???" + /// Check whether the PHP version is valid for the current version. + var composerPhpMatchesSystem: Bool = false + /// How the PHP version was determined. var composerPhpSource: String = "unknown" @@ -238,6 +248,7 @@ class Valet { public func determineComposerPhpVersion() { let path = "\(absolutePath!)/composer.json" + do { if Filesystem.fileExists(path) { let decoded = try JSONDecoder().decode( @@ -251,6 +262,18 @@ class Valet { } catch { Log.err("Something went wrong reading the composer JSON file.") } + + if self.composerPhp == "???" { + return + } + + // Split the composer list (on "|") to evaluate multiple constraints + // For example, for Laravel 8 projects the value is "^7.3|^8.0" + self.composerPhpMatchesSystem = self.composerPhp.split(separator: "|").map { string in + return PhpVersionNumberCollection.make(from: [PhpEnv.phpInstall.version.long]) + .matching(constraint: string.trimmingCharacters(in: .whitespacesAndNewlines)) + .count > 0 + }.contains(true) } } diff --git a/phpmon/Domain/SiteList/SiteListCell.swift b/phpmon/Domain/SiteList/SiteListCell.swift index d73e724..1486959 100644 --- a/phpmon/Domain/SiteList/SiteListCell.swift +++ b/phpmon/Domain/SiteList/SiteListCell.swift @@ -36,8 +36,7 @@ class SiteListCell: NSTableCellView labelSiteName.stringValue = "\(site.name!).\(Valet.shared.config.tld)" // Show the absolute path, except make sure to replace the /Users/username segment with ~ for readability - labelPathName.stringValue = site.absolutePath - .replacingOccurrences(of: "/Users/\(Paths.whoami)", with: "~") + labelPathName.stringValue = site.absolutePathRelative // If the `aliasPath` is nil, we're dealing with a parked site (otherwise: linked). imageViewType.image = NSImage( @@ -48,7 +47,7 @@ class SiteListCell: NSTableCellView imageViewType.contentTintColor = NSColor.tertiaryLabelColor // Show the green or red lock based on whether the site was secured - imageViewLock.image = NSImage(named: site.secured ? "Lock" : "LockUnlocked") + // imageViewLock.image = NSImage(named: site.secured ? "Lock" : "LockUnlocked") imageViewLock.contentTintColor = site.secured ? NSColor.init(red: 63/255, green: 195/255, blue: 128/255, alpha: 1.0) // green : NSColor.init(red: 246/255, green: 71/255, blue: 71/255, alpha: 1.0) // red @@ -70,15 +69,8 @@ class SiteListCell: NSTableCellView buttonPhpVersion.title = " PHP \(site.composerPhp) " buttonPhpVersion.isHidden = (site.composerPhp == "???") - // Split the composer list (on "|") to evaluate multiple constraints - // For example, for Laravel 8 projects the value is "^7.3|^8.0" - let matchesConstraint = site.composerPhp.split(separator: "|").map { string in - return PhpVersionNumberCollection.make(from: [PhpEnv.phpInstall.version.long]) - .matching(constraint: string.trimmingCharacters(in: .whitespacesAndNewlines)) - .count > 0 - }.contains(true) - - imageViewPhpVersionOK.isHidden = (site.composerPhp == "???" || !matchesConstraint) + + imageViewPhpVersionOK.isHidden = (site.composerPhp == "???" || !site.composerPhpMatchesSystem) } @IBAction func pressedPhpVersion(_ sender: Any) { diff --git a/phpmon/Domain/SiteList/SiteListVC.swift b/phpmon/Domain/SiteList/SiteListVC.swift index cfdd7f9..b441153 100644 --- a/phpmon/Domain/SiteList/SiteListVC.swift +++ b/phpmon/Domain/SiteList/SiteListVC.swift @@ -93,6 +93,7 @@ class SiteListVC: NSViewController, NSTableViewDelegate, NSTableViewDataSource { progressIndicator.startAnimation(nil) tableView.alphaValue = 0.3 tableView.isEnabled = false + tableView.selectRowIndexes([], byExtendingSelection: true) } /** @@ -201,8 +202,14 @@ class SiteListVC: NSViewController, NSTableViewDelegate, NSTableViewDataSource { return } + let splitSearchString: [String] = searchString + .split(separator: " ") + .map { return String($0) } + sites = Valet.shared.sites.filter({ site in - return site.name.lowercased().contains(searchString) + return !splitSearchString.map { searchString in + return site.name.lowercased().contains(searchString) + }.contains(false) }) DispatchQueue.main.async { diff --git a/phpmon/Domain/SiteList/SiteListWC.swift b/phpmon/Domain/SiteList/SiteListWC.swift index aba9a57..c423da4 100644 --- a/phpmon/Domain/SiteList/SiteListWC.swift +++ b/phpmon/Domain/SiteList/SiteListWC.swift @@ -43,7 +43,7 @@ class SiteListWC: PMWindowController, NSSearchFieldDelegate, NSToolbarDelegate { self.searchTimer?.invalidate() - searchTimer = Timer.scheduledTimer(withTimeInterval: 0.3, repeats: false, block: { _ in + searchTimer = Timer.scheduledTimer(withTimeInterval: 0.15, repeats: false, block: { _ in self.contentVC.searchedFor(text: searchField.stringValue) }) } diff --git a/phpmon/Localizable.strings b/phpmon/Localizable.strings index c0b0504..67d870f 100644 --- a/phpmon/Localizable.strings +++ b/phpmon/Localizable.strings @@ -235,6 +235,10 @@ You can do this by running `composer global update` in your terminal. After that "startup.errors.sudoers_valet.title" = "Valet has not been added to sudoers.d"; "startup.errors.sudoers_valet.desc" = "You must run `sudo valet trust` to ensure Valet can start and stop services without having to use sudo every time. The app will not work correctly until you resolve this issue. If you did this before, please run `sudo valet trust` again."; -/// 6. Multiple services active +/// 6. Cannot retrieve services +"startup.errors.services_json_error.title" = "Cannot determine services status"; +"startup.errors.services_json_error.desc" = "PHP Monitor was unable to check if any of the services are up and running. PHP Monitor usually queries `brew` using the following command: ``. PHP Monitor received an invalid response (no JSON)."; + +/// 7. Multiple services active "startup.errors.services.title" = "Multiple PHP services are active"; "startup.errors.services.desc" = "This can cause php-fpm to serve a more recent version of PHP than the one you'd like to see active. Please terminate all extra PHP processes.\n\nThe easiest solution is to choose the option 'Force load latest PHP version' in the menu bar.\n\nAlternatively, you can fix this manually. You can do this by running `brew services list` and running `sudo brew services stop php@7.3` (and use the version that applies).\n\nPHP Monitor usually handles the starting and stopping of these services, so once the correct version is the only PHP version running you should not have any issues. It is recommended to restart PHP Monitor once you have resolved this issue.\n\nFor more information about this issue, please see the README.md file in the repository on GitHub.";