1
0
mirror of https://github.com/nicoverbruggen/phpmon.git synced 2025-08-07 03:50:08 +02:00

Add marketing mode

This commit is contained in:
2022-03-19 15:13:46 +01:00
parent aec8fb1168
commit 083f8ebec8
6 changed files with 208 additions and 71 deletions

View File

@ -62,6 +62,10 @@
C417DC75277614690015E6EE /* Helpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = C417DC73277614690015E6EE /* Helpers.swift */; };
C4188989275FE8CB001EF227 /* Filesystem.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4188988275FE8CB001EF227 /* Filesystem.swift */; };
C418898A275FE8CB001EF227 /* Filesystem.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4188988275FE8CB001EF227 /* Filesystem.swift */; };
C41C02A627E60D7A009F26CB /* SiteScanner.swift in Sources */ = {isa = PBXBuildFile; fileRef = C41C02A527E60D7A009F26CB /* SiteScanner.swift */; };
C41C02A927E61A65009F26CB /* ValetSite+Fake.swift in Sources */ = {isa = PBXBuildFile; fileRef = C41C02A827E61A65009F26CB /* ValetSite+Fake.swift */; };
C41C02AA27E61CA3009F26CB /* SiteScanner.swift in Sources */ = {isa = PBXBuildFile; fileRef = C41C02A527E60D7A009F26CB /* SiteScanner.swift */; };
C41C02AB27E61CB3009F26CB /* ValetSite+Fake.swift in Sources */ = {isa = PBXBuildFile; fileRef = C41C02A827E61A65009F26CB /* ValetSite+Fake.swift */; };
C41C1B3722B0097F00E7CF16 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = C41C1B3622B0097F00E7CF16 /* AppDelegate.swift */; };
C41C1B3B22B0098000E7CF16 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = C41C1B3A22B0098000E7CF16 /* Assets.xcassets */; };
C41C1B3E22B0098000E7CF16 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = C41C1B3C22B0098000E7CF16 /* Main.storyboard */; };
@ -267,6 +271,8 @@
C4168F4427ADB4A3003B6C39 /* DEVELOPER.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = DEVELOPER.md; sourceTree = "<group>"; };
C417DC73277614690015E6EE /* Helpers.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Helpers.swift; sourceTree = "<group>"; };
C4188988275FE8CB001EF227 /* Filesystem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Filesystem.swift; sourceTree = "<group>"; };
C41C02A527E60D7A009F26CB /* SiteScanner.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SiteScanner.swift; sourceTree = "<group>"; };
C41C02A827E61A65009F26CB /* ValetSite+Fake.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ValetSite+Fake.swift"; sourceTree = "<group>"; };
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>"; };
C41C1B3A22B0098000E7CF16 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
@ -656,6 +662,8 @@
children = (
C4AF9F792754499000D44ED0 /* Valet.swift */,
C4E4404527C56F4700D225E1 /* ValetSite.swift */,
C41C02A827E61A65009F26CB /* ValetSite+Fake.swift */,
C41C02A527E60D7A009F26CB /* SiteScanner.swift */,
C4D5CFC927E0F9CD00035329 /* NginxConfigParser.swift */,
);
path = Valet;
@ -978,6 +986,7 @@
C48D0CA325CC992000CC7490 /* StatsView.swift in Sources */,
C40C7F2827721FF600DDDCDC /* ActivePhpInstallation+Checks.swift in Sources */,
C4EE55A927708B9E001DF387 /* PMHeaderView.swift in Sources */,
C41C02A927E61A65009F26CB /* ValetSite+Fake.swift in Sources */,
C4F2E4372752F0870020E974 /* HomebrewDiagnostics.swift in Sources */,
C4CCBA6C275C567B008C7055 /* PMWindowController.swift in Sources */,
C4B585442770FE3900DA4FBE /* Command.swift in Sources */,
@ -1043,6 +1052,7 @@
C4D89BC62783C99400A02B68 /* ComposerJson.swift in Sources */,
C46FA23F246C358E00944F05 /* StringExtension.swift in Sources */,
C4B97B75275CF08C003F3378 /* AppDelegate+MenuOutlets.swift in Sources */,
C41C02A627E60D7A009F26CB /* SiteScanner.swift in Sources */,
C464ADAC275A7A3F003FCD53 /* SiteListWC.swift in Sources */,
C464ADB2275A87CA003FCD53 /* SiteListCellProtocol.swift in Sources */,
C4EE188422D3386B00E126E5 /* Constants.swift in Sources */,
@ -1066,6 +1076,7 @@
C4F780C825D80B75000DBC97 /* DateExtension.swift in Sources */,
C493084B279F331F009C240B /* AddSiteVC.swift in Sources */,
C4D9ADC0277610E1007277F4 /* PhpSwitcher.swift in Sources */,
C41C02AA27E61CA3009F26CB /* SiteScanner.swift in Sources */,
C4080FFB27BD956700BF2C6B /* BetterAlertVC.swift in Sources */,
C4F780CC25D80B75000DBC97 /* ActivePhpInstallation.swift in Sources */,
54D9E0BB27E4F51E003B9AD9 /* ModifierFlagsExtension.swift in Sources */,
@ -1139,6 +1150,7 @@
C4E4404727C56F4700D225E1 /* ValetSite.swift in Sources */,
C44CCD4A27AFF3BC00CE40E5 /* MainMenu+Async.swift in Sources */,
C48D6C71279CD2AC00F26D7E /* PhpVersionNumber.swift in Sources */,
C41C02AB27E61CB3009F26CB /* ValetSite+Fake.swift in Sources */,
C4F780C925D80B75000DBC97 /* StringExtension.swift in Sources */,
C4B5853F2770FE3900DA4FBE /* Paths.swift in Sources */,
C481F79A26164A7C004FBCFF /* Preferences.swift in Sources */,

View File

@ -62,6 +62,13 @@
ReferencedContainer = "container:PHP Monitor.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
<EnvironmentVariables>
<EnvironmentVariable
key = "PHPMON_MARKETING_MODE"
value = "YES"
isEnabled = "YES">
</EnvironmentVariable>
</EnvironmentVariables>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"

View File

@ -0,0 +1,118 @@
//
// ValetSiteScanner.swift
// PHP Monitor
//
// Created by Nico Verbruggen on 19/03/2022.
// Copyright © 2022 Nico Verbruggen. All rights reserved.
//
import Foundation
protocol SiteScanner
{
func resolveSiteCount(paths: [String]) -> Int
func resolveSitesFrom(paths: [String]) -> [ValetSite]
}
class FakeSiteScanner: SiteScanner
{
let fakes = [
ValetSite(fakeWithName: "laravel", tld: "test", secure: true, path: "~/Code/laravel/framework", linked: true),
ValetSite(fakeWithName: "tailwind", tld: "test", secure: true, path: "~/Code/tailwind/site", linked: true),
ValetSite(fakeWithName: "forge", tld: "test", secure: true, path: "~/Code/laravel/forge", linked: true),
ValetSite(fakeWithName: "wordpress", tld: "test", secure: false,
path: "~/Code/wordpress", linked: false, driver: "Wordpress", constraint: "^7.4", isolated: "7.4")
]
func resolveSiteCount(paths: [String]) -> Int {
return fakes.count
}
func resolveSitesFrom(paths: [String]) -> [ValetSite] {
return fakes
}
}
class ValetSiteScanner: SiteScanner
{
func resolveSiteCount(paths: [String]) -> Int {
return paths.map { path in
let entries = try! FileManager.default
.contentsOfDirectory(atPath: path)
return entries
.map { self.isSite($0, forPath: path) }
.filter{ $0 == true}
.count
}.reduce(0, +)
}
func resolveSitesFrom(paths: [String]) -> [ValetSite] {
var sites: [ValetSite] = []
paths.forEach { path in
let entries = try! FileManager.default
.contentsOfDirectory(atPath: path)
return entries.forEach {
if let site = self.getSite($0, forPath: path, tld: Valet.shared.config.tld) {
sites.append(site)
}
}
}
return sites
}
/**
Determines whether the site can be resolved as a symbolic link or as a directory.
Regular files are ignored. Returns true if the path can be parsed.
*/
private func isSite(_ entry: String, forPath path: String) -> Bool {
let siteDir = path + "/" + entry
let attrs = try! FileManager.default.attributesOfItem(atPath: siteDir)
let type = attrs[FileAttributeKey.type] as! FileAttributeType
if type == FileAttributeType.typeSymbolicLink || type == FileAttributeType.typeDirectory {
return true
}
return false
}
/**
Determines whether the site can be resolved as a symbolic link or as a directory.
Regular files are ignored, and the site is added to Valet's list of sites.
*/
private func getSite(_ entry: String, forPath path: String, tld: String) -> ValetSite? {
let siteDir = path + "/" + entry
// See if the file is a symlink, if so, resolve it
let attrs = try! FileManager.default.attributesOfItem(atPath: siteDir)
// 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
if URL(fileURLWithPath: siteDir).lastPathComponent == "" {
Log.warn("Could not parse the site: \(siteDir), skipping!")
return nil
}
if type == FileAttributeType.typeSymbolicLink {
return ValetSite(aliasPath: siteDir, tld: tld)
} else if type == FileAttributeType.typeDirectory {
return ValetSite(absolutePath: siteDir, tld: tld)
}
return nil
}
}

View File

@ -38,6 +38,19 @@ class Valet {
self.sites = []
}
/**
If marketing mode is enabled, show a list of sites that are used for promotional screenshots.
This can be done by swapping out the real Valet scanner with one that always returns a fixed
list of fake sites. You should not interact with these sites!
*/
static var siteScanner: SiteScanner {
if ProcessInfo.processInfo.environment["PHPMON_MARKETING_MODE"] != nil {
return FakeSiteScanner()
}
return ValetSiteScanner()
}
/**
Check if a particular feature is enabled.
*/
@ -89,7 +102,7 @@ class Valet {
return
}
resolvePaths(tld: config.tld)
resolvePaths()
}
/**
@ -128,82 +141,23 @@ class Valet {
Returns a count of how many sites are linked and parked.
*/
private func countPaths() -> Int {
var count = 0
for path in config.paths {
let entries = try! FileManager.default.contentsOfDirectory(atPath: path)
for entry in entries {
if resolveSite(entry, forPath: path) {
count += 1
}
}
}
return count
return Self.siteScanner
.resolveSiteCount(paths: config.paths)
}
/**
Resolves all paths and creates linked or parked site instances that can be referenced later.
*/
private func resolvePaths(tld: String) {
private func resolvePaths() {
isBusy = true
sites = []
for path in config.paths {
let entries = try! FileManager.default.contentsOfDirectory(atPath: path)
for entry in entries {
resolvePath(entry, forPath: path, tld: tld)
}
}
sites = sites.sorted { $0.absolutePath < $1.absolutePath }
sites = Self.siteScanner
.resolveSitesFrom(paths: config.paths)
.sorted { $0.absolutePath < $1.absolutePath }
isBusy = false
}
/**
Determines whether the site can be resolved as a symbolic link or as a directory.
Regular files are ignored. Returns true if the path can be parsed.
*/
private func resolveSite(_ entry: String, forPath path: String) -> Bool {
let siteDir = path + "/" + entry
let attrs = try! FileManager.default.attributesOfItem(atPath: siteDir)
let type = attrs[FileAttributeKey.type] as! FileAttributeType
if type == FileAttributeType.typeSymbolicLink || type == FileAttributeType.typeDirectory {
return true
}
return false
}
/**
Determines whether the site can be resolved as a symbolic link or as a directory.
Regular files are ignored, and the site is added to Valet's list of sites.
*/
private func resolvePath(_ entry: String, forPath path: String, tld: String) {
let siteDir = path + "/" + entry
// See if the file is a symlink, if so, resolve it
let attrs = try! FileManager.default.attributesOfItem(atPath: siteDir)
// 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
if URL(fileURLWithPath: siteDir).lastPathComponent == "" {
Log.warn("Could not parse the site: \(siteDir), skipping!")
return
}
if type == FileAttributeType.typeSymbolicLink {
sites.append(ValetSite(aliasPath: siteDir, tld: tld))
} else if type == FileAttributeType.typeDirectory {
sites.append(ValetSite(absolutePath: siteDir, tld: tld))
}
}
struct Configuration: Decodable {
/// Top level domain suffix. Usually "test" but can be set to something else.
/// - Important: Does not include the actual dot. ("test", not ".test"!)

View File

@ -0,0 +1,37 @@
//
// ValetSite+Fake.swift
// PHP Monitor
//
// Created by Nico Verbruggen on 19/03/2022.
// Copyright © 2022 Nico Verbruggen. All rights reserved.
//
import Foundation
extension ValetSite {
convenience init(
fakeWithName name: String,
tld: String,
secure: Bool,
path: String,
linked: Bool,
driver: String = "Laravel (^9.0)",
constraint: String = "^8.1",
isolated: String? = nil
) {
self.init(name: name, tld: tld, absolutePath: path, aliasPath: nil, makeDeterminations: false)
self.secured = secure
self.composerPhp = constraint
self.driver = driver
self.driverDeterminedByComposer = true
if linked {
self.aliasPath = self.absolutePath
}
if let isolated = isolated {
self.isolatedPhpVersion = PhpInstallation(isolated)
}
}
}

View File

@ -60,16 +60,25 @@ class ValetSite {
case valetphprc = "valetphprc"
}
init(name: String, tld: String, absolutePath: String, aliasPath: String? = nil) {
init(
name: String,
tld: String,
absolutePath: String,
aliasPath: String? = nil,
makeDeterminations: Bool = true
) {
self.name = name
self.tld = tld
self.absolutePath = absolutePath
self.aliasPath = aliasPath
self.secured = false
determineSecured()
determineComposerPhpVersion()
determineDriver()
determineIsolated()
if makeDeterminations {
determineSecured()
determineComposerPhpVersion()
determineDriver()
determineIsolated()
}
}
convenience init(absolutePath: String, tld: String) {