mirror of
https://github.com/nicoverbruggen/phpmon.git
synced 2025-08-07 03:50:08 +02:00
109 lines
4.2 KiB
Swift
109 lines
4.2 KiB
Swift
//
|
|
// PhpHelper.swift
|
|
// PHP Monitor
|
|
//
|
|
// Created by Nico Verbruggen on 17/03/2022.
|
|
// Copyright © 2023 Nico Verbruggen. All rights reserved.
|
|
//
|
|
|
|
import Foundation
|
|
|
|
class PhpHelper {
|
|
|
|
static let keyPhrase = "This file was automatically generated by PHP Monitor."
|
|
|
|
public static func generate(for version: String) async {
|
|
// Take the PHP version (e.g. "7.2") and generate a dotless version
|
|
let dotless = version.replacingOccurrences(of: ".", with: "")
|
|
|
|
// Determine the dotless name for this PHP version
|
|
let destination = "\(Paths.homePath)/.config/phpmon/bin/pm\(dotless)"
|
|
|
|
// Check if the ~/.config/phpmon/bin directory is in the PATH
|
|
let inPath = Shell.PATH.contains("\(Paths.homePath)/.config/phpmon/bin")
|
|
|
|
// Check if we can create symlinks (`/usr/local/bin` must be writable)
|
|
let canWriteSymlinks = FileSystem.isWriteableFile("/usr/local/bin/")
|
|
|
|
Task { // Create the appropriate folders and check if the files exist
|
|
do {
|
|
if !FileSystem.directoryExists("~/.config/phpmon/bin") {
|
|
Task { @MainActor in
|
|
try FileSystem.createDirectory(
|
|
"~/.config/phpmon/bin",
|
|
withIntermediateDirectories: true
|
|
)
|
|
}
|
|
}
|
|
|
|
if FileSystem.fileExists(destination) {
|
|
let contents = try String(contentsOfFile: destination)
|
|
if !contents.contains(keyPhrase) {
|
|
Log.info("The file at '\(destination)' already exists and was not generated by PHP Monitor "
|
|
+ "(or is unreadable). Not updating this file.")
|
|
return
|
|
}
|
|
}
|
|
|
|
// Let's follow the symlink to the PHP binary folder
|
|
let path = URL(fileURLWithPath: "\(Paths.optPath)/php@\(version)/bin")
|
|
.resolvingSymlinksInPath().path
|
|
|
|
// The contents of the script!
|
|
let script = """
|
|
#!/bin/zsh
|
|
# \(keyPhrase)
|
|
# It reflects the location of PHP \(version)'s binaries on your system.
|
|
# Usage: . pm\(dotless)
|
|
[[ $ZSH_EVAL_CONTEXT =~ :file$ ]] \\
|
|
&& echo "PHP Monitor has enabled this terminal to use PHP \(version)." \\
|
|
|| echo "You must run '. pm\(dotless)' (or 'source pm\(dotless)') instead!";
|
|
export PATH=\(path):$PATH
|
|
"""
|
|
|
|
Task { @MainActor in
|
|
try FileSystem.writeAtomicallyToFile(destination, content: script)
|
|
|
|
if !FileSystem.isExecutableFile(destination) {
|
|
try FileSystem.makeExecutable(destination)
|
|
}
|
|
}
|
|
|
|
// Create a symlink if the folder is not in the PATH
|
|
if !inPath {
|
|
// First, check if we can create symlinks at all
|
|
if !canWriteSymlinks {
|
|
Log.err("PHP Monitor does not have permission to symlink `/usr/local/bin/\(dotless)`.")
|
|
return
|
|
}
|
|
|
|
// Write the symlink
|
|
await self.createSymlink(dotless)
|
|
}
|
|
} catch {
|
|
Log.err(error)
|
|
Log.err("Could not write PHP Monitor helper for PHP \(version) to \(destination))")
|
|
}
|
|
}
|
|
}
|
|
|
|
private static func createSymlink(_ dotless: String) async {
|
|
let source = "\(Paths.homePath)/.config/phpmon/bin/pm\(dotless)"
|
|
let destination = "/usr/local/bin/pm\(dotless)"
|
|
|
|
if !FileSystem.fileExists(destination) {
|
|
Log.info("Creating new symlink: \(destination)")
|
|
await Shell.quiet("ln -s \(source) \(destination)")
|
|
return
|
|
}
|
|
|
|
if !FileSystem.isSymlink(destination) {
|
|
Log.info("Overwriting existing file with new symlink: \(destination)")
|
|
await Shell.quiet("ln -fs \(source) \(destination)")
|
|
return
|
|
}
|
|
|
|
Log.info("Symlink in \(destination) already exists, OK.")
|
|
}
|
|
}
|