1
0
mirror of https://github.com/nicoverbruggen/phpmon.git synced 2025-08-07 03:50:08 +02:00
Files
app/phpmon/Common/PHP/PHP Version/PhpHelper.swift
2023-03-03 23:11:40 +01:00

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.")
}
}