mirror of
https://github.com/nicoverbruggen/phpmon.git
synced 2025-08-08 04:20:07 +02:00
Compare commits
21 Commits
Author | SHA1 | Date | |
---|---|---|---|
50f6afb3c5 | |||
67e80aac8d | |||
e683b6bc9a | |||
e854ebe114 | |||
b792f55e5f | |||
cbf5526881 | |||
f62297ee3d | |||
2f017f6732 | |||
1c62a100af | |||
e176d6fa2d | |||
ea60626c47 | |||
69c3386088 | |||
3e898d435b | |||
a4dcd0cd3d | |||
bb382c0f74 | |||
c87c532d1c | |||
b26099369f | |||
90a8e7c336 | |||
398dad9d5e | |||
48d0878dfd | |||
4ba3415bf4 |
2
.gitignore
vendored
2
.gitignore
vendored
@ -1,2 +1,4 @@
|
||||
phpmon.xcodeproj/project.xcworkspace
|
||||
phpmon.xcodeproj/xcuserdata
|
||||
PHP Monitor.xcodeproj/project.xcworkspace
|
||||
PHP Monitor.xcodeproj/xcuserdata
|
||||
|
21
LICENSE
Normal file
21
LICENSE
Normal file
@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2019 Nico Verbruggen
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
@ -8,26 +8,24 @@
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
C41C1B3722B0097F00E7CF16 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = C41C1B3622B0097F00E7CF16 /* AppDelegate.swift */; };
|
||||
C41C1B3922B0097F00E7CF16 /* LogViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C41C1B3822B0097F00E7CF16 /* LogViewController.swift */; };
|
||||
C41C1B3B22B0098000E7CF16 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = C41C1B3A22B0098000E7CF16 /* Assets.xcassets */; };
|
||||
C41C1B3E22B0098000E7CF16 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = C41C1B3C22B0098000E7CF16 /* Main.storyboard */; };
|
||||
C41C1B4722B009A400E7CF16 /* Shell.swift in Sources */ = {isa = PBXBuildFile; fileRef = C41C1B4622B009A400E7CF16 /* Shell.swift */; };
|
||||
C41C1B4922B00A9800E7CF16 /* MenuBarImageGenerator.swift in Sources */ = {isa = PBXBuildFile; fileRef = C41C1B4822B00A9800E7CF16 /* MenuBarImageGenerator.swift */; };
|
||||
C41C1B4B22B019FF00E7CF16 /* PhpVersion.swift in Sources */ = {isa = PBXBuildFile; fileRef = C41C1B4A22B019FF00E7CF16 /* PhpVersion.swift */; };
|
||||
C41C1B4D22B0215A00E7CF16 /* Actions.swift in Sources */ = {isa = PBXBuildFile; fileRef = C41C1B4C22B0215A00E7CF16 /* Actions.swift */; };
|
||||
C42295DD2358D02000E263B2 /* Command.swift in Sources */ = {isa = PBXBuildFile; fileRef = C42295DC2358D02000E263B2 /* Command.swift */; };
|
||||
C476FF9822B0DD830098105B /* Alert.swift in Sources */ = {isa = PBXBuildFile; fileRef = C476FF9722B0DD830098105B /* Alert.swift */; };
|
||||
C4811D2422D70A4700B5F6B3 /* App.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4811D2322D70A4700B5F6B3 /* App.swift */; };
|
||||
C4811D2A22D70F9A00B5F6B3 /* MainMenu.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4811D2922D70F9A00B5F6B3 /* MainMenu.swift */; };
|
||||
C4D8016622B1584700C6DA1B /* Startup.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4D8016522B1584700C6DA1B /* Startup.swift */; };
|
||||
C4EE188422D3386B00E126E5 /* Constants.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4EE188322D3386B00E126E5 /* Constants.swift */; };
|
||||
C4F8C0A422D4F12C002EFE61 /* DateExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4F8C0A322D4F12C002EFE61 /* DateExtension.swift */; };
|
||||
C4F8C0A622D4FA41002EFE61 /* README.md in Resources */ = {isa = PBXBuildFile; fileRef = C4F8C0A522D4FA41002EFE61 /* README.md */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
C41C1B3322B0097F00E7CF16 /* phpmon.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = phpmon.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
C41C1B3322B0097F00E7CF16 /* PHP Monitor.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "PHP Monitor.app"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
C41C1B3622B0097F00E7CF16 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
|
||||
C41C1B3822B0097F00E7CF16 /* LogViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LogViewController.swift; sourceTree = "<group>"; };
|
||||
C41C1B3A22B0098000E7CF16 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
|
||||
C41C1B3D22B0098000E7CF16 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
|
||||
C41C1B3F22B0098000E7CF16 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
@ -36,6 +34,7 @@
|
||||
C41C1B4822B00A9800E7CF16 /* MenuBarImageGenerator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MenuBarImageGenerator.swift; sourceTree = "<group>"; };
|
||||
C41C1B4A22B019FF00E7CF16 /* PhpVersion.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PhpVersion.swift; sourceTree = "<group>"; };
|
||||
C41C1B4C22B0215A00E7CF16 /* Actions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Actions.swift; sourceTree = "<group>"; };
|
||||
C42295DC2358D02000E263B2 /* Command.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Command.swift; sourceTree = "<group>"; };
|
||||
C476FF9722B0DD830098105B /* Alert.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Alert.swift; sourceTree = "<group>"; };
|
||||
C4811D2322D70A4700B5F6B3 /* App.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = App.swift; sourceTree = "<group>"; };
|
||||
C4811D2922D70F9A00B5F6B3 /* MainMenu.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainMenu.swift; sourceTree = "<group>"; };
|
||||
@ -68,7 +67,7 @@
|
||||
C41C1B3422B0097F00E7CF16 /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
C41C1B3322B0097F00E7CF16 /* phpmon.app */,
|
||||
C41C1B3322B0097F00E7CF16 /* PHP Monitor.app */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
@ -102,7 +101,6 @@
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
C41C1B3C22B0098000E7CF16 /* Main.storyboard */,
|
||||
C41C1B3822B0097F00E7CF16 /* LogViewController.swift */,
|
||||
);
|
||||
path = "View Controllers";
|
||||
sourceTree = "<group>";
|
||||
@ -113,6 +111,7 @@
|
||||
C41C1B4622B009A400E7CF16 /* Shell.swift */,
|
||||
C4811D2322D70A4700B5F6B3 /* App.swift */,
|
||||
C4811D2922D70F9A00B5F6B3 /* MainMenu.swift */,
|
||||
C42295DC2358D02000E263B2 /* Command.swift */,
|
||||
);
|
||||
path = Singletons;
|
||||
sourceTree = "<group>";
|
||||
@ -147,9 +146,9 @@
|
||||
/* End PBXGroup section */
|
||||
|
||||
/* Begin PBXNativeTarget section */
|
||||
C41C1B3222B0097F00E7CF16 /* phpmon */ = {
|
||||
C41C1B3222B0097F00E7CF16 /* PHP Monitor */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = C41C1B4322B0098000E7CF16 /* Build configuration list for PBXNativeTarget "phpmon" */;
|
||||
buildConfigurationList = C41C1B4322B0098000E7CF16 /* Build configuration list for PBXNativeTarget "PHP Monitor" */;
|
||||
buildPhases = (
|
||||
C41C1B2F22B0097F00E7CF16 /* Sources */,
|
||||
C41C1B3022B0097F00E7CF16 /* Frameworks */,
|
||||
@ -159,9 +158,9 @@
|
||||
);
|
||||
dependencies = (
|
||||
);
|
||||
name = phpmon;
|
||||
name = "PHP Monitor";
|
||||
productName = phpmon;
|
||||
productReference = C41C1B3322B0097F00E7CF16 /* phpmon.app */;
|
||||
productReference = C41C1B3322B0097F00E7CF16 /* PHP Monitor.app */;
|
||||
productType = "com.apple.product-type.application";
|
||||
};
|
||||
/* End PBXNativeTarget section */
|
||||
@ -171,7 +170,7 @@
|
||||
isa = PBXProject;
|
||||
attributes = {
|
||||
LastSwiftUpdateCheck = 1020;
|
||||
LastUpgradeCheck = 1020;
|
||||
LastUpgradeCheck = 1110;
|
||||
ORGANIZATIONNAME = "Nico Verbruggen";
|
||||
TargetAttributes = {
|
||||
C41C1B3222B0097F00E7CF16 = {
|
||||
@ -179,7 +178,7 @@
|
||||
};
|
||||
};
|
||||
};
|
||||
buildConfigurationList = C41C1B2E22B0097F00E7CF16 /* Build configuration list for PBXProject "phpmon" */;
|
||||
buildConfigurationList = C41C1B2E22B0097F00E7CF16 /* Build configuration list for PBXProject "PHP Monitor" */;
|
||||
compatibilityVersion = "Xcode 9.3";
|
||||
developmentRegion = en;
|
||||
hasScannedForEncodings = 0;
|
||||
@ -192,7 +191,7 @@
|
||||
projectDirPath = "";
|
||||
projectRoot = "";
|
||||
targets = (
|
||||
C41C1B3222B0097F00E7CF16 /* phpmon */,
|
||||
C41C1B3222B0097F00E7CF16 /* PHP Monitor */,
|
||||
);
|
||||
};
|
||||
/* End PBXProject section */
|
||||
@ -202,7 +201,6 @@
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
C4F8C0A622D4FA41002EFE61 /* README.md in Resources */,
|
||||
C41C1B3B22B0098000E7CF16 /* Assets.xcassets in Resources */,
|
||||
C41C1B3E22B0098000E7CF16 /* Main.storyboard in Resources */,
|
||||
);
|
||||
@ -219,10 +217,10 @@
|
||||
C4F8C0A422D4F12C002EFE61 /* DateExtension.swift in Sources */,
|
||||
C41C1B4722B009A400E7CF16 /* Shell.swift in Sources */,
|
||||
C41C1B4D22B0215A00E7CF16 /* Actions.swift in Sources */,
|
||||
C42295DD2358D02000E263B2 /* Command.swift in Sources */,
|
||||
C4811D2422D70A4700B5F6B3 /* App.swift in Sources */,
|
||||
C41C1B4922B00A9800E7CF16 /* MenuBarImageGenerator.swift in Sources */,
|
||||
C4811D2A22D70F9A00B5F6B3 /* MainMenu.swift in Sources */,
|
||||
C41C1B3922B0097F00E7CF16 /* LogViewController.swift in Sources */,
|
||||
C41C1B3722B0097F00E7CF16 /* AppDelegate.swift in Sources */,
|
||||
C41C1B4B22B019FF00E7CF16 /* PhpVersion.swift in Sources */,
|
||||
C476FF9822B0DD830098105B /* Alert.swift in Sources */,
|
||||
@ -364,14 +362,17 @@
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CODE_SIGN_ENTITLEMENTS = phpmon/phpmon.entitlements;
|
||||
CODE_SIGN_IDENTITY = "-";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
CURRENT_PROJECT_VERSION = 18;
|
||||
DEVELOPMENT_TEAM = 8M54J5J787;
|
||||
INFOPLIST_FILE = phpmon/Info.plist;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/../Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 1.8;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.nicoverbruggen.phpmon;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SWIFT_VERSION = 5.0;
|
||||
@ -383,14 +384,17 @@
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CODE_SIGN_ENTITLEMENTS = phpmon/phpmon.entitlements;
|
||||
CODE_SIGN_IDENTITY = "-";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
CURRENT_PROJECT_VERSION = 18;
|
||||
DEVELOPMENT_TEAM = 8M54J5J787;
|
||||
INFOPLIST_FILE = phpmon/Info.plist;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/../Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 1.8;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.nicoverbruggen.phpmon;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SWIFT_VERSION = 5.0;
|
||||
@ -400,7 +404,7 @@
|
||||
/* End XCBuildConfiguration section */
|
||||
|
||||
/* Begin XCConfigurationList section */
|
||||
C41C1B2E22B0097F00E7CF16 /* Build configuration list for PBXProject "phpmon" */ = {
|
||||
C41C1B2E22B0097F00E7CF16 /* Build configuration list for PBXProject "PHP Monitor" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
C41C1B4122B0098000E7CF16 /* Debug */,
|
||||
@ -409,7 +413,7 @@
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
C41C1B4322B0098000E7CF16 /* Build configuration list for PBXNativeTarget "phpmon" */ = {
|
||||
C41C1B4322B0098000E7CF16 /* Build configuration list for PBXNativeTarget "PHP Monitor" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
C41C1B4422B0098000E7CF16 /* Debug */,
|
85
README.md
85
README.md
@ -1,16 +1,20 @@
|
||||
# phpmon
|
||||
# PHP Monitor
|
||||
|
||||
phpmon is a macOS utility that runs on your Mac and displays the active PHP version in your status bar.
|
||||
PHP Monitor (or phpmon) is a macOS utility that runs on your Mac and displays the active PHP version in your status bar. It also gives you quick access to various useful functionality (like switching PHP versions, restarting services, accessing configuration files, and more).
|
||||
|
||||
<img src="./docs/screenshot.png" width="278px" alt="phpmon screenshot"/>
|
||||
|
||||
For me, it comes in handy when running multiple versions of PHP with Homebrew and you wish to be able to see at a glance which version is currently linked & active with Laravel Valet, and switch between versions.
|
||||
|
||||
This version of phpmon was developed for:
|
||||
## System requirements
|
||||
|
||||
* macOS Mojave (10.14)
|
||||
* PHP 7.x with Homebrew 2.x (with support for PHP 5.6 and PHP 7.0 [as well](https://github.com/eXolnet/homebrew-deprecated))
|
||||
* Laravel Valet 2.2
|
||||
* macOS 10.15 Catalina
|
||||
* PHP 7.4 installed with Homebrew 2.x
|
||||
- other versions of PHP are optional
|
||||
- includes support for PHP 5.6 and PHP 7.0 [as well](https://github.com/eXolnet/homebrew-deprecated)
|
||||
* Laravel Valet 2.8
|
||||
|
||||
If you're looking to run PHP Monitor in combination with an older version of macOS or Laravel Valet, please check out the older releases of the software.
|
||||
|
||||
## Why I built this
|
||||
|
||||
@ -30,19 +34,82 @@ This utility will detect which PHP versions you have installed via Homebrew, and
|
||||
|
||||
This means:
|
||||
|
||||
- You have at least the latest version of PHP installed (`php@7.3`)
|
||||
- You have at least the latest version of PHP installed (`php@7.4`)
|
||||
- You have installed Laravel Valet (`which valet` returns `/usr/local/bin/valet`)
|
||||
- You ran `valet trust`, which means Valet commands can be run without using sudo
|
||||
|
||||
The utility runs the following commands:
|
||||
|
||||
- Unlink all detected PHP versions
|
||||
- Switch to PHP 7.3 (this is done in order to ensure that Valet works, even when attempting to use PHP 5.6)
|
||||
- Tell Valet to switch to a specific PHP version
|
||||
- Switch to PHP 7.4 (this is done in order to ensure that Valet works, even when attempting to use PHP 5.6)
|
||||
- Stop all php-fpm service instances
|
||||
- Link the desired version of PHP
|
||||
- Start the correct php-fpm service for the desired PHP version
|
||||
|
||||
### Want to know more?
|
||||
|
||||
If you want to know more about how this works, I recommend you check out the source code.
|
||||
|
||||
This app isn't very complicated after all. In the end, this just (conveniently) executes some shell commands.
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
---
|
||||
|
||||
### Reasons for alerts at startup
|
||||
|
||||
PHP Monitor performs some integrity checks to ensure a good experience when using the app. You'll get a message telling you that PHP Monitor won't work correctly in the following scenarios:
|
||||
|
||||
- The PHP binary is not located in `/usr/local/bin/php`
|
||||
- PHP 7.4 is missing in `/usr/local/opt`
|
||||
- Laravel Valet is missing in `/usr/local/bin/valet`
|
||||
- Brew has not been added to sudoers in `/private/etc/sudoers.d/brew`
|
||||
- Valet has not been added to sudoers in `/private/etc/sudoers.d/valet`
|
||||
|
||||
Follow instructions as specified in the alert in order to resolve any issues.
|
||||
|
||||
---
|
||||
|
||||
### Laravel Valet is using a different version of PHP than what is active in PHP Monitor and in my terminal!
|
||||
|
||||
If you're still seeing another version of PHP in your scripts — e.g. when running `phpinfo()` — I recommend you shut down all PHP services that are currently active. You can find out what services are active by running:
|
||||
|
||||
sudo brew services list | grep php
|
||||
|
||||
This will present to you a list of services, like so (depending on the installed versions of PHP):
|
||||
|
||||
```
|
||||
php started root /Library/LaunchDaemons/homebrew.mxcl.php.plist
|
||||
php@5.6 stopped
|
||||
php@7.0 stopped
|
||||
php@7.1 stopped
|
||||
php@7.2 stopped
|
||||
php@7.3 stopped
|
||||
```
|
||||
|
||||
You'll want to make sure that **only one service is running** and that it is running **as `root`**. You can terminate a service by running:
|
||||
|
||||
sudo brew services stop {service_name}
|
||||
|
||||
So in order to disable PHP 7.3, you'd need to run:
|
||||
|
||||
sudo brew services stop php@7.3
|
||||
|
||||
If you notice that PHP FPM is running as your own user account, you can turn off the service by running:
|
||||
|
||||
brew services stop php@7.3
|
||||
|
||||
The easiest way to make sure that PHP Monitor works again is to run the following commands:
|
||||
|
||||
sudo brew services stop php
|
||||
sudo brew services stop php@7.3
|
||||
sudo brew services stop php@7.2
|
||||
sudo brew services stop php@7.1
|
||||
sudo brew services stop php@7.0
|
||||
sudo brew services stop php@5.6
|
||||
|
||||
Then, in PHP Monitor, select "Restart php-fpm service", which should start the service. Alternatively, you can run `sudo brew services start php@{x}` where `{x}` is your preferred version of PHP (for the latest version of PHP, you can omit `@{x}`).
|
||||
|
||||
---
|
||||
|
||||
If this software has been useful to you, star the repository so I know that the software is being used. I did not include any tracking or analytics software, so if you encounter issues, let me know via an issue.
|
Binary file not shown.
Before Width: | Height: | Size: 314 KiB After Width: | Height: | Size: 615 KiB |
@ -1,7 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Workspace
|
||||
version = "1.0">
|
||||
<FileRef
|
||||
location = "self:phpmon.xcodeproj">
|
||||
</FileRef>
|
||||
</Workspace>
|
@ -1,8 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>IDEDidComputeMac32BitWarning</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
@ -1,6 +1,6 @@
|
||||
//
|
||||
// AppDelegate.swift
|
||||
// phpmon
|
||||
// PHP Monitor
|
||||
//
|
||||
// Created by Nico Verbruggen on 11/06/2019.
|
||||
// Copyright © 2019 Nico Verbruggen. All rights reserved.
|
||||
@ -12,6 +12,7 @@ import Cocoa
|
||||
class AppDelegate: NSObject, NSApplicationDelegate {
|
||||
|
||||
// MARK: - Variables
|
||||
|
||||
let sharedShell : Shell
|
||||
let state : App
|
||||
let menu : MainMenu
|
||||
@ -32,7 +33,7 @@ class AppDelegate: NSObject, NSApplicationDelegate {
|
||||
}
|
||||
|
||||
func applicationWillTerminate(_ aNotification: Notification) {
|
||||
// Insert code here to tear down your application
|
||||
self.state.windowController = nil
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
//
|
||||
// Services.swift
|
||||
// phpmon
|
||||
// PHP Monitor
|
||||
//
|
||||
// Created by Nico Verbruggen on 11/06/2019.
|
||||
// Copyright © 2019 Nico Verbruggen. All rights reserved.
|
||||
@ -26,22 +26,81 @@ class Actions {
|
||||
return versionsOnly
|
||||
}
|
||||
|
||||
public static func restartPhpFpm() {
|
||||
let version = App.shared.currentVersion!.short
|
||||
if (version == Constants.LatestPhpVersion) {
|
||||
Shell.user.run("sudo brew services restart php")
|
||||
} else {
|
||||
Shell.user.run("sudo brew services restart php@\(version)")
|
||||
}
|
||||
}
|
||||
|
||||
public static func restartNginx()
|
||||
{
|
||||
Shell.user.run("sudo brew services restart nginx")
|
||||
}
|
||||
|
||||
public static func switchToPhpVersion(version: String, availableVersions: [String]) {
|
||||
availableVersions.forEach { (version) in
|
||||
// Unlink the current version
|
||||
Shell.user.run("brew unlink php@\(version)")
|
||||
}
|
||||
if (availableVersions.contains("7.3")) {
|
||||
Shell.user.run("brew link php@7.3")
|
||||
// Stop the services
|
||||
if (version == Constants.LatestPhpVersion) {
|
||||
Shell.user.run( "valet use php")
|
||||
Shell.user.run("sudo brew services stop php")
|
||||
} else {
|
||||
Shell.user.run("valet use php@\(version)")
|
||||
Shell.user.run("sudo brew services stop php@\(version)")
|
||||
}
|
||||
}
|
||||
if (availableVersions.contains(Constants.LatestPhpVersion)) {
|
||||
// Use the latest version as a default
|
||||
Shell.user.run("brew link php@\(Constants.LatestPhpVersion) --overwrite --force")
|
||||
if (version == Constants.LatestPhpVersion) {
|
||||
// If said version was also requested, all we need to do is start the service
|
||||
Shell.user.run("sudo brew services start php")
|
||||
} else {
|
||||
// Otherwise, link the correct php version + start the correct service
|
||||
Shell.user.run("brew link php@\(version) --overwrite --force")
|
||||
Shell.user.run("sudo brew services start php@\(version)")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static func openPhpConfigFolder(version: String) {
|
||||
let files = [NSURL(fileURLWithPath: "/usr/local/etc/php/\(version)/php.ini")];
|
||||
NSWorkspace.shared.activateFileViewerSelecting(files as [URL]);
|
||||
NSWorkspace.shared.activateFileViewerSelecting(files as [URL])
|
||||
}
|
||||
|
||||
public static func openValetConfigFolder() {
|
||||
let files = [NSURL(fileURLWithPath: NSString(string: "~/.config/valet").expandingTildeInPath)];
|
||||
NSWorkspace.shared.activateFileViewerSelecting(files as [URL])
|
||||
}
|
||||
|
||||
public static func XdebugFound(_ version: String) -> Bool {
|
||||
let command = """
|
||||
grep -q 'zend_extension="xdebug.so"' /usr/local/etc/php/\(version)/php.ini; [ $? -eq 0 ] && echo "YES" || echo "NO"
|
||||
"""
|
||||
let output = Shell.user.pipe(command).trimmingCharacters(in: .whitespacesAndNewlines)
|
||||
return (output == "YES")
|
||||
}
|
||||
|
||||
public static func XdebugEnabled(_ version: String) -> Bool {
|
||||
let command = """
|
||||
grep -q '; zend_extension="xdebug.so"' /usr/local/etc/php/\(version)/php.ini; [ $? -eq 0 ] && echo "YES" || echo "NO"
|
||||
"""
|
||||
let output = Shell.user.pipe(command).trimmingCharacters(in: .whitespacesAndNewlines)
|
||||
return (output == "NO")
|
||||
}
|
||||
|
||||
public static func toggleXdebug() {
|
||||
let version = App.shared.currentVersion?.short
|
||||
var command = """
|
||||
sed -i '' 's/; zend_extension="xdebug.so"/zend_extension="xdebug.so"/g' /usr/local/etc/php/\(version!)/php.ini
|
||||
"""
|
||||
if (self.XdebugEnabled(version!)) {
|
||||
command = """
|
||||
sed -i '' 's/zend_extension="xdebug.so"/; zend_extension="xdebug.so"/g' /usr/local/etc/php/\(version!)/php.ini
|
||||
"""
|
||||
}
|
||||
Shell.user.run(command)
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
//
|
||||
// Environment.swift
|
||||
// phpmon
|
||||
// PHP Monitor
|
||||
//
|
||||
// Created by Nico Verbruggen on 12/06/2019.
|
||||
// Copyright © 2019 Nico Verbruggen. All rights reserved.
|
||||
@ -19,9 +19,9 @@ class Startup {
|
||||
)
|
||||
|
||||
self.presentAlertOnMainThreadIf(
|
||||
!Shell.user.pipe("ls /usr/local/opt | grep php@7.3").contains("php@7.3"),
|
||||
messageText: "PHP 7.3 is not correctly installed",
|
||||
informativeText: "PHP 7.3 alias was not found in `/usr/local/opt`. The app will not work correctly until you resolve this issue."
|
||||
!Shell.user.pipe("ls /usr/local/opt | grep php@7.4").contains("php@7.4"),
|
||||
messageText: "PHP 7.4 is not correctly installed",
|
||||
informativeText: "PHP 7.4 alias was not found in `/usr/local/opt`. The app will not work correctly until you resolve this issue."
|
||||
)
|
||||
|
||||
self.presentAlertOnMainThreadIf(
|
||||
|
@ -1,6 +1,6 @@
|
||||
//
|
||||
// Alert.swift
|
||||
// phpmon
|
||||
// PHP Monitor
|
||||
//
|
||||
// Created by Nico Verbruggen on 12/06/2019.
|
||||
// Copyright © 2019 Nico Verbruggen. All rights reserved.
|
||||
|
@ -1,6 +1,6 @@
|
||||
//
|
||||
// ImageGenerator.swift
|
||||
// phpmon
|
||||
// PHP Monitor
|
||||
//
|
||||
// Created by Nico Verbruggen on 11/06/2019.
|
||||
// Copyright © 2019 Nico Verbruggen. All rights reserved.
|
||||
@ -39,7 +39,7 @@ class MenuBarImageGenerator {
|
||||
let imageRect = CGRect(x: 0, y: 0, width: image.size.width, height: image.size.height)
|
||||
|
||||
// Position the text inside the image rect
|
||||
let textRect = CGRect(x: padding, y: 0, width: image.size.width, height: image.size.height)
|
||||
let textRect = CGRect(x: padding, y: 0.5, width: image.size.width, height: image.size.height)
|
||||
|
||||
let targetImage: NSImage = NSImage(size: image.size)
|
||||
let rep: NSBitmapImageRep = NSBitmapImageRep(
|
||||
|
@ -1,6 +1,6 @@
|
||||
//
|
||||
// PhpVersionExtractor.swift
|
||||
// phpmon
|
||||
// PHP Monitor
|
||||
//
|
||||
// Created by Nico Verbruggen on 11/06/2019.
|
||||
// Copyright © 2019 Nico Verbruggen. All rights reserved.
|
||||
@ -13,17 +13,25 @@ class PhpVersion {
|
||||
var short : String = "???"
|
||||
var long : String = "???"
|
||||
|
||||
var xdebugFound: Bool = false
|
||||
var xdebugEnabled : Bool = false
|
||||
|
||||
init() {
|
||||
let version = Shell.user
|
||||
// Get the version directly from PHP
|
||||
.pipe("php -r 'print phpversion();'")
|
||||
let version = Command.execute(path: "/usr/local/bin/php", arguments: ["-r", "print phpversion();"])
|
||||
|
||||
// That's the long version
|
||||
self.long = version
|
||||
|
||||
// Next up, let's strip away the minor version number
|
||||
let segments = long.components(separatedBy: ".")
|
||||
|
||||
// Get the first two elements
|
||||
self.short = segments[0...1].joined(separator: ".")
|
||||
|
||||
// Load xdebug support
|
||||
self.xdebugFound = Actions.XdebugFound(self.short)
|
||||
if (self.xdebugFound) {
|
||||
self.xdebugEnabled = Actions.XdebugEnabled(self.short)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
//
|
||||
// Constants.swift
|
||||
// phpmon
|
||||
// PHP Monitor
|
||||
//
|
||||
// Created by Nico Verbruggen on 08/07/2019.
|
||||
// Copyright © 2019 Nico Verbruggen. All rights reserved.
|
||||
@ -14,13 +14,13 @@ class Constants {
|
||||
* The PHP versions supported by this application.
|
||||
*/
|
||||
static let SupportedPhpVersions = [
|
||||
"5.6", "7.0", "7.1", "7.2", "7.3"
|
||||
"5.6", "7.0", "7.1", "7.2", "7.3", "7.4"
|
||||
]
|
||||
|
||||
/**
|
||||
Which php version is aliased as `php` to brew?
|
||||
This is usually the latest PHP version.
|
||||
*/
|
||||
static let LatestPhpVersion = "7.3"
|
||||
static let LatestPhpVersion = "7.4"
|
||||
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
//
|
||||
// Date.swift
|
||||
// phpmon
|
||||
// PHP Monitor
|
||||
//
|
||||
// Created by Nico Verbruggen on 09/07/2019.
|
||||
// Copyright © 2019 Nico Verbruggen. All rights reserved.
|
||||
|
@ -17,9 +17,9 @@
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.3</string>
|
||||
<string>$(MARKETING_VERSION)</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>10</string>
|
||||
<string>$(CURRENT_PROJECT_VERSION)</string>
|
||||
<key>LSApplicationCategoryType</key>
|
||||
<string>public.app-category.utilities</string>
|
||||
<key>LSMinimumSystemVersion</key>
|
||||
@ -27,7 +27,7 @@
|
||||
<key>LSUIElement</key>
|
||||
<true/>
|
||||
<key>NSHumanReadableCopyright</key>
|
||||
<string>Copyright © 2019 Nico Verbruggen. All rights reserved.</string>
|
||||
<string>Copyright © 2020 Nico Verbruggen. All rights reserved.</string>
|
||||
<key>NSMainStoryboardFile</key>
|
||||
<string>Main</string>
|
||||
<key>NSPrincipalClass</key>
|
||||
|
@ -1,6 +1,6 @@
|
||||
//
|
||||
// StateManager.swift
|
||||
// phpmon
|
||||
// PHP Monitor
|
||||
//
|
||||
// Created by Nico Verbruggen on 11/07/2019.
|
||||
// Copyright © 2019 Nico Verbruggen. All rights reserved.
|
||||
|
50
phpmon/Singletons/Command.swift
Normal file
50
phpmon/Singletons/Command.swift
Normal file
@ -0,0 +1,50 @@
|
||||
//
|
||||
// Command.swift
|
||||
// PHP Monitor
|
||||
//
|
||||
// Created by Nico Verbruggen on 17/10/2019.
|
||||
// Copyright © 2019 Nico Verbruggen. All rights reserved.
|
||||
//
|
||||
|
||||
import Cocoa
|
||||
|
||||
class Command {
|
||||
|
||||
public static func execute(path: String, arguments: [String]) -> String {
|
||||
let task = Process()
|
||||
task.launchPath = path
|
||||
task.arguments = arguments
|
||||
|
||||
let pipe = Pipe()
|
||||
task.standardOutput = pipe
|
||||
task.launch()
|
||||
|
||||
let data = pipe.fileHandleForReading.readDataToEndOfFile()
|
||||
let output: String = String.init(data: data, encoding: String.Encoding.utf8)!
|
||||
return output;
|
||||
}
|
||||
|
||||
public static func experiment() {
|
||||
/*
|
||||
print("Running '/usr/local/bin/php -v' directly...")
|
||||
print("========================================")
|
||||
var start = DispatchTime.now()
|
||||
print(Command.execute(path: "/usr/local/bin/php", arguments: ["-v"]))
|
||||
var end = DispatchTime.now()
|
||||
var nanoTime = end.uptimeNanoseconds - start.uptimeNanoseconds
|
||||
var timeInterval = Double(nanoTime) / 1_000_000_000
|
||||
print("Time to run command directly: \(timeInterval) seconds")
|
||||
|
||||
print("")
|
||||
print("Running 'bash -> php -v'...")
|
||||
print("========================================")
|
||||
start = DispatchTime.now()
|
||||
print(Shell.user.pipe("php -v"))
|
||||
end = DispatchTime.now()
|
||||
nanoTime = end.uptimeNanoseconds - start.uptimeNanoseconds
|
||||
timeInterval = Double(nanoTime) / 1_000_000_000
|
||||
print("Time to run command via bash: \(timeInterval) seconds")
|
||||
*/
|
||||
}
|
||||
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
//
|
||||
// MainMenu.swift
|
||||
// phpmon
|
||||
// PHP Monitor
|
||||
//
|
||||
// Created by Nico Verbruggen on 11/07/2019.
|
||||
// Copyright © 2019 Nico Verbruggen. All rights reserved.
|
||||
@ -57,21 +57,47 @@ class MainMenu: NSObject, NSWindowDelegate {
|
||||
menu.addItem(menuItem)
|
||||
}
|
||||
menu.addItem(NSMenuItem.separator())
|
||||
menu.addItem(NSMenuItem(title: "Active Services", action: nil, keyEquivalent: ""))
|
||||
menu.addItem(NSMenuItem(title: "Restart php-fpm service", action: #selector(self.restartPhpFpm), keyEquivalent: "f"))
|
||||
menu.addItem(NSMenuItem(title: "Restart nginx service", action: #selector(self.restartNginx), keyEquivalent: "n"))
|
||||
menu.addItem(NSMenuItem.separator())
|
||||
}
|
||||
if (App.shared.busy) {
|
||||
menu.addItem(NSMenuItem(title: "Switching PHP versions...", action: nil, keyEquivalent: ""))
|
||||
menu.addItem(NSMenuItem(title: "PHP Monitor is busy...", action: nil, keyEquivalent: ""))
|
||||
menu.addItem(NSMenuItem.separator())
|
||||
}
|
||||
if (App.shared.currentVersion != nil) {
|
||||
menu.addItem(NSMenuItem(title: "PHP configuration file (php.ini)", action: #selector(self.openActiveConfigFolder), keyEquivalent: ""))
|
||||
menu.addItem(NSMenuItem(title: "Configuration", action: nil, keyEquivalent: ""))
|
||||
menu.addItem(NSMenuItem(title: "Valet configuration (.config/valet)", action: #selector(self.openValetConfigFolder), keyEquivalent: "v"))
|
||||
menu.addItem(NSMenuItem(title: "PHP configuration file (php.ini)", action: #selector(self.openActiveConfigFolder), keyEquivalent: "c"))
|
||||
menu.addItem(NSMenuItem.separator())
|
||||
menu.addItem(NSMenuItem(title: "Enabled Extensions", action: nil, keyEquivalent: ""))
|
||||
let xdebugFound = App.shared.currentVersion!.xdebugFound
|
||||
if (xdebugFound) {
|
||||
let xdebugOn = App.shared.currentVersion!.xdebugEnabled
|
||||
let xdebugToggleMenuItem = NSMenuItem(
|
||||
title: "Xdebug",
|
||||
action: #selector(self.toggleXdebug), keyEquivalent: "x"
|
||||
)
|
||||
if (xdebugOn) {
|
||||
xdebugToggleMenuItem.state = .on
|
||||
}
|
||||
menu.addItem(xdebugToggleMenuItem)
|
||||
} else {
|
||||
let disabledItem = NSMenuItem(
|
||||
title: "xdebug.so missing",
|
||||
action: nil, keyEquivalent: "x"
|
||||
)
|
||||
disabledItem.isEnabled = false
|
||||
menu.addItem(disabledItem)
|
||||
}
|
||||
}
|
||||
menu.addItem(NSMenuItem(title: "View shell output", action: #selector(self.openOutput), keyEquivalent: ""))
|
||||
menu.addItem(NSMenuItem.separator())
|
||||
menu.addItem(NSMenuItem(title: "About phpmon", action: #selector(self.openAbout), keyEquivalent: ""))
|
||||
menu.addItem(NSMenuItem(title: "About PHP Monitor", action: #selector(self.openAbout), keyEquivalent: ""))
|
||||
menu.items.forEach({ (item) in
|
||||
item.target = self
|
||||
})
|
||||
menu.addItem(NSMenuItem(title: "Quit phpmon", action: #selector(NSApplication.terminate(_:)), keyEquivalent: "q"))
|
||||
menu.addItem(NSMenuItem(title: "Quit PHP Monitor", action: #selector(NSApplication.terminate(_:)), keyEquivalent: "q"))
|
||||
DispatchQueue.main.async {
|
||||
self.statusItem.menu = menu
|
||||
}
|
||||
@ -95,10 +121,6 @@ class MainMenu: NSObject, NSWindowDelegate {
|
||||
|
||||
// MARK: - Callable via Obj-C (#selector)
|
||||
|
||||
@objc func openOutput() {
|
||||
LogViewController.show(delegate: self)
|
||||
}
|
||||
|
||||
@objc func updatePhpVersionInStatusBar() {
|
||||
App.shared.currentVersion = PhpVersion()
|
||||
if (App.shared.busy) {
|
||||
@ -113,6 +135,39 @@ class MainMenu: NSObject, NSWindowDelegate {
|
||||
self.update()
|
||||
}
|
||||
|
||||
@objc func setBusyImage() {
|
||||
DispatchQueue.main.async {
|
||||
self.setStatusBar(image: NSImage(named: NSImage.Name("StatusBarIcon"))!)
|
||||
}
|
||||
}
|
||||
|
||||
private func waitAndExecute(_ execute: @escaping () -> Void)
|
||||
{
|
||||
App.shared.busy = true
|
||||
self.setBusyImage()
|
||||
DispatchQueue.global(qos: .userInitiated).async { [unowned self] in
|
||||
self.update()
|
||||
execute()
|
||||
App.shared.busy = false
|
||||
DispatchQueue.main.async {
|
||||
self.updatePhpVersionInStatusBar()
|
||||
self.update()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@objc public func restartPhpFpm() {
|
||||
self.waitAndExecute({
|
||||
Actions.restartPhpFpm()
|
||||
})
|
||||
}
|
||||
|
||||
@objc public func restartNginx() {
|
||||
self.waitAndExecute({
|
||||
Actions.restartNginx()
|
||||
})
|
||||
}
|
||||
|
||||
@objc public func openAbout() {
|
||||
NSApplication.shared.activate(ignoringOtherApps: true)
|
||||
NSApplication.shared.orderFrontStandardAboutPanel()
|
||||
@ -122,8 +177,12 @@ class MainMenu: NSObject, NSWindowDelegate {
|
||||
Actions.openPhpConfigFolder(version: App.shared.currentVersion!.short)
|
||||
}
|
||||
|
||||
@objc public func openValetConfigFolder() {
|
||||
Actions.openValetConfigFolder()
|
||||
}
|
||||
|
||||
@objc public func switchToPhpVersion(sender: AnyObject) {
|
||||
self.setStatusBar(image: NSImage(named: NSImage.Name("StatusBarIcon"))!)
|
||||
self.setBusyImage()
|
||||
let index = sender.tag!
|
||||
let version = App.shared.availablePhpVersions[index]
|
||||
App.shared.busy = true
|
||||
@ -147,6 +206,19 @@ class MainMenu: NSObject, NSWindowDelegate {
|
||||
}
|
||||
}
|
||||
|
||||
@objc public func toggleXdebug() {
|
||||
DispatchQueue.global(qos: .userInitiated).async { [unowned self] in
|
||||
DispatchQueue.main.async {
|
||||
self.setStatusBar(image: NSImage(named: NSImage.Name("StatusBarIcon"))!)
|
||||
}
|
||||
Actions.toggleXdebug()
|
||||
DispatchQueue.main.async {
|
||||
self.updatePhpVersionInStatusBar()
|
||||
self.update()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func windowWillClose(_ notification: Notification) {
|
||||
App.shared.windowController = nil
|
||||
Shell.user.delegate = nil
|
||||
|
@ -1,6 +1,6 @@
|
||||
//
|
||||
// Shell.swift
|
||||
// phpmon
|
||||
// PHP Monitor
|
||||
//
|
||||
// Created by Nico Verbruggen on 11/06/2019.
|
||||
// Copyright © 2019 Nico Verbruggen. All rights reserved.
|
||||
@ -60,11 +60,15 @@ class Shell {
|
||||
) as String
|
||||
|
||||
let historyItem = ShellHistoryItem(command: command, output: output)
|
||||
history.append(historyItem)
|
||||
// Keep the last 100 items
|
||||
history = history.suffix(100)
|
||||
delegate?.didCompleteCommand(historyItem: historyItem)
|
||||
|
||||
DispatchQueue.global(qos: .userInitiated).async { [unowned self] in
|
||||
self.history.append(historyItem)
|
||||
// Keep the last 100 items
|
||||
self.history = self.history.suffix(100)
|
||||
}
|
||||
|
||||
delegate?.didCompleteCommand(historyItem: historyItem)
|
||||
|
||||
return output
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.Storyboard.XIB" version="3.0" toolsVersion="14490.70" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.Storyboard.XIB" version="3.0" toolsVersion="15702" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
|
||||
<dependencies>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="14490.70"/>
|
||||
<deployment identifier="macosx"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="15702"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<scenes>
|
||||
@ -11,18 +12,18 @@
|
||||
<application id="hnw-xV-0zn" sceneMemberID="viewController">
|
||||
<menu key="mainMenu" title="Main Menu" systemMenu="main" id="AYu-sK-qS6">
|
||||
<items>
|
||||
<menuItem title="phpmon" id="1Xt-HY-uBw">
|
||||
<menuItem title="PHP Monitor" id="1Xt-HY-uBw">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="phpmon" systemMenu="apple" id="uQy-DD-JDr">
|
||||
<menu key="submenu" title="PHP Monitor" systemMenu="apple" id="uQy-DD-JDr">
|
||||
<items>
|
||||
<menuItem title="About phpmon" id="5kV-Vb-QxS">
|
||||
<menuItem title="About PHP Monitor" id="5kV-Vb-QxS">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="orderFrontStandardAboutPanel:" target="Ady-hI-5gd" id="Exp-CZ-Vem"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="VOq-y0-SEH"/>
|
||||
<menuItem title="Quit phpmon" keyEquivalent="q" id="4sb-4s-VLi">
|
||||
<menuItem title="Quit PHP Monitor" keyEquivalent="q" id="4sb-4s-VLi">
|
||||
<connections>
|
||||
<action selector="terminate:" target="Ady-hI-5gd" id="Te7-pn-YzF"/>
|
||||
</connections>
|
||||
@ -34,7 +35,7 @@
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Help" systemMenu="help" id="F2S-fz-NVQ">
|
||||
<items>
|
||||
<menuItem title="phpmon Help" keyEquivalent="?" id="FKE-Sm-Kum">
|
||||
<menuItem title="PHP Monitor Help" keyEquivalent="?" id="FKE-Sm-Kum">
|
||||
<connections>
|
||||
<action selector="showHelp:" target="Ady-hI-5gd" id="y7X-2Q-9no"/>
|
||||
</connections>
|
||||
@ -48,22 +49,22 @@
|
||||
<outlet property="delegate" destination="Voe-Tx-rLC" id="PrD-fu-P6m"/>
|
||||
</connections>
|
||||
</application>
|
||||
<customObject id="Voe-Tx-rLC" customClass="AppDelegate" customModule="phpmon" customModuleProvider="target"/>
|
||||
<customObject id="Voe-Tx-rLC" customClass="AppDelegate" customModule="PHP_Monitor" customModuleProvider="target"/>
|
||||
<customObject id="YLy-65-1bz" customClass="NSFontManager"/>
|
||||
<customObject id="Ady-hI-5gd" userLabel="First Responder" customClass="NSResponder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="134" y="40"/>
|
||||
<point key="canvasLocation" x="-343" y="-16"/>
|
||||
</scene>
|
||||
<!--Log View Controller-->
|
||||
<scene sceneID="hIz-AP-VOD">
|
||||
<objects>
|
||||
<viewController storyboardIdentifier="logWindow" id="XfG-lQ-9wD" customClass="LogViewController" customModule="phpmon" customModuleProvider="target" sceneMemberID="viewController">
|
||||
<viewController storyboardIdentifier="logWindow" id="XfG-lQ-9wD" customClass="LogViewController" customModule="PHP_Monitor" customModuleProvider="target" sceneMemberID="viewController">
|
||||
<view key="view" identifier="main" id="m2S-Jp-Qdl">
|
||||
<rect key="frame" x="0.0" y="0.0" width="662" height="475"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="ICa-gx-jgq">
|
||||
<rect key="frame" x="573" y="8" width="75" height="32"/>
|
||||
<rect key="frame" x="578" y="8" width="75" height="32"/>
|
||||
<buttonCell key="cell" type="push" title="Close" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="3md-FI-EWa">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
@ -73,37 +74,38 @@
|
||||
</connections>
|
||||
</button>
|
||||
<scrollView borderType="line" horizontalLineScroll="10" horizontalPageScroll="10" verticalLineScroll="10" verticalPageScroll="10" hasHorizontalScroller="NO" translatesAutoresizingMaskIntoConstraints="NO" id="vZy-5S-021">
|
||||
<rect key="frame" x="20" y="46" width="622" height="409"/>
|
||||
<rect key="frame" x="15" y="46" width="632" height="414"/>
|
||||
<clipView key="contentView" drawsBackground="NO" copiesOnScroll="NO" id="s5L-AU-0fw">
|
||||
<rect key="frame" x="1" y="1" width="620" height="407"/>
|
||||
<rect key="frame" x="1" y="1" width="630" height="412"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<textView importsGraphics="NO" richText="NO" verticallyResizable="YES" smartInsertDelete="YES" id="tN6-Y9-1pA">
|
||||
<rect key="frame" x="0.0" y="0.0" width="620" height="407"/>
|
||||
<rect key="frame" x="0.0" y="0.0" width="630" height="412"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<color key="textColor" name="textColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
<size key="minSize" width="620" height="407"/>
|
||||
<size key="maxSize" width="620" height="10000000"/>
|
||||
<size key="minSize" width="630" height="412"/>
|
||||
<size key="maxSize" width="640" height="10000000"/>
|
||||
<color key="insertionPointColor" name="textColor" catalog="System" colorSpace="catalog"/>
|
||||
</textView>
|
||||
</subviews>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
</clipView>
|
||||
<scroller key="horizontalScroller" hidden="YES" wantsLayer="YES" verticalHuggingPriority="750" horizontal="YES" id="Kho-JF-NZJ">
|
||||
<rect key="frame" x="-100" y="-100" width="240" height="16"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
</scroller>
|
||||
<scroller key="verticalScroller" wantsLayer="YES" verticalHuggingPriority="750" horizontal="NO" id="qp7-7R-gTO">
|
||||
<rect key="frame" x="605" y="1" width="16" height="407"/>
|
||||
<rect key="frame" x="615" y="1" width="16" height="412"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
</scroller>
|
||||
</scrollView>
|
||||
</subviews>
|
||||
<constraints>
|
||||
<constraint firstItem="vZy-5S-021" firstAttribute="leading" secondItem="m2S-Jp-Qdl" secondAttribute="leading" constant="20" id="K0k-oE-r37"/>
|
||||
<constraint firstAttribute="trailing" secondItem="ICa-gx-jgq" secondAttribute="trailing" constant="20" id="LFS-0E-Ibw"/>
|
||||
<constraint firstItem="vZy-5S-021" firstAttribute="top" secondItem="m2S-Jp-Qdl" secondAttribute="top" constant="20" id="Nec-oI-CjE"/>
|
||||
<constraint firstAttribute="trailing" secondItem="vZy-5S-021" secondAttribute="trailing" constant="20" id="kBJ-O5-eYI"/>
|
||||
<constraint firstItem="vZy-5S-021" firstAttribute="leading" secondItem="m2S-Jp-Qdl" secondAttribute="leading" constant="15" id="K0k-oE-r37"/>
|
||||
<constraint firstAttribute="trailing" secondItem="ICa-gx-jgq" secondAttribute="trailing" constant="15" id="LFS-0E-Ibw"/>
|
||||
<constraint firstItem="vZy-5S-021" firstAttribute="top" secondItem="m2S-Jp-Qdl" secondAttribute="top" constant="15" id="Nec-oI-CjE"/>
|
||||
<constraint firstAttribute="trailing" secondItem="vZy-5S-021" secondAttribute="trailing" constant="15" id="kBJ-O5-eYI"/>
|
||||
<constraint firstAttribute="bottom" secondItem="ICa-gx-jgq" secondAttribute="bottom" constant="15" id="kYB-Fn-DSA"/>
|
||||
<constraint firstItem="ICa-gx-jgq" firstAttribute="top" secondItem="vZy-5S-021" secondAttribute="bottom" constant="10" id="xdn-yU-LVb"/>
|
||||
</constraints>
|
||||
|
@ -1,72 +0,0 @@
|
||||
//
|
||||
// ViewController.swift
|
||||
// phpmon
|
||||
//
|
||||
// Created by Nico Verbruggen on 11/06/2019.
|
||||
// Copyright © 2019 Nico Verbruggen. All rights reserved.
|
||||
//
|
||||
|
||||
import Cocoa
|
||||
|
||||
class LogViewController: NSViewController, ShellDelegate {
|
||||
|
||||
public static func show(delegate: NSWindowDelegate? = nil) {
|
||||
if (App.shared.windowController == nil) {
|
||||
let vc = NSStoryboard(name: "Main", bundle: nil).instantiateController(withIdentifier: "logWindow") as! LogViewController
|
||||
Shell.user.delegate = vc
|
||||
let window = NSWindow(contentViewController: vc)
|
||||
window.title = "Terminal Output"
|
||||
window.delegate = delegate
|
||||
App.shared.windowController = NSWindowController(window: window)
|
||||
}
|
||||
App.shared.windowController!.showWindow(self)
|
||||
NSApp.activate(ignoringOtherApps: true)
|
||||
}
|
||||
|
||||
@IBOutlet var textView: NSTextView!
|
||||
|
||||
public func appendHistoryItem(_ historyItem: ShellHistoryItem) {
|
||||
self.append(
|
||||
"""
|
||||
======
|
||||
@ \(historyItem.date.toString())
|
||||
------
|
||||
$ \(historyItem.command)
|
||||
------
|
||||
> \(historyItem.output)
|
||||
|
||||
"""
|
||||
)
|
||||
}
|
||||
|
||||
public func append(_ text : String) {
|
||||
self.textView.textStorage?.append(
|
||||
NSAttributedString(
|
||||
string: text,
|
||||
attributes: [
|
||||
NSAttributedString.Key.font: NSFont(name: "Menlo", size: 12.0)!
|
||||
]
|
||||
)
|
||||
)
|
||||
self.textView.scrollToEndOfDocument(nil)
|
||||
}
|
||||
|
||||
override func viewDidLoad() {
|
||||
self.textView.isEditable = false
|
||||
for entry in Shell.user.history {
|
||||
self.appendHistoryItem(entry)
|
||||
}
|
||||
}
|
||||
|
||||
func didCompleteCommand(historyItem: ShellHistoryItem) {
|
||||
self.appendHistoryItem(historyItem)
|
||||
}
|
||||
|
||||
@IBAction func pressed(_ sender: Any) {
|
||||
self.view.window?.windowController?.close()
|
||||
}
|
||||
|
||||
deinit {
|
||||
print("VC deallocated")
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user