annotate vendor/psy/psysh/src/ConfigPaths.php @ 19:fa3358dc1485 tip

Add ndrum files
author Chris Cannam
date Wed, 28 Aug 2019 13:14:47 +0100
parents 129ea1e6d783
children
rev   line source
Chris@13 1 <?php
Chris@13 2
Chris@13 3 /*
Chris@13 4 * This file is part of Psy Shell.
Chris@13 5 *
Chris@13 6 * (c) 2012-2018 Justin Hileman
Chris@13 7 *
Chris@13 8 * For the full copyright and license information, please view the LICENSE
Chris@13 9 * file that was distributed with this source code.
Chris@13 10 */
Chris@13 11
Chris@13 12 namespace Psy;
Chris@13 13
Chris@13 14 use XdgBaseDir\Xdg;
Chris@13 15
Chris@13 16 /**
Chris@13 17 * A Psy Shell configuration path helper.
Chris@13 18 */
Chris@13 19 class ConfigPaths
Chris@13 20 {
Chris@13 21 /**
Chris@13 22 * Get potential config directory paths.
Chris@13 23 *
Chris@13 24 * Returns `~/.psysh`, `%APPDATA%/PsySH` (when on Windows), and all
Chris@13 25 * XDG Base Directory config directories:
Chris@13 26 *
Chris@13 27 * http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html
Chris@13 28 *
Chris@13 29 * @return string[]
Chris@13 30 */
Chris@13 31 public static function getConfigDirs()
Chris@13 32 {
Chris@13 33 $xdg = new Xdg();
Chris@13 34
Chris@13 35 return self::getDirNames($xdg->getConfigDirs());
Chris@13 36 }
Chris@13 37
Chris@13 38 /**
Chris@13 39 * Get potential home config directory paths.
Chris@13 40 *
Chris@13 41 * Returns `~/.psysh`, `%APPDATA%/PsySH` (when on Windows), and the
Chris@13 42 * XDG Base Directory home config directory:
Chris@13 43 *
Chris@13 44 * http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html
Chris@13 45 *
Chris@13 46 * @return string[]
Chris@13 47 */
Chris@13 48 public static function getHomeConfigDirs()
Chris@13 49 {
Chris@13 50 $xdg = new Xdg();
Chris@13 51
Chris@13 52 return self::getDirNames([$xdg->getHomeConfigDir()]);
Chris@13 53 }
Chris@13 54
Chris@13 55 /**
Chris@13 56 * Get the current home config directory.
Chris@13 57 *
Chris@13 58 * Returns the highest precedence home config directory which actually
Chris@13 59 * exists. If none of them exists, returns the highest precedence home
Chris@13 60 * config directory (`%APPDATA%/PsySH` on Windows, `~/.config/psysh`
Chris@13 61 * everywhere else).
Chris@13 62 *
Chris@13 63 * @see self::getHomeConfigDirs
Chris@13 64 *
Chris@13 65 * @return string
Chris@13 66 */
Chris@13 67 public static function getCurrentConfigDir()
Chris@13 68 {
Chris@13 69 $configDirs = self::getHomeConfigDirs();
Chris@13 70 foreach ($configDirs as $configDir) {
Chris@17 71 if (@\is_dir($configDir)) {
Chris@13 72 return $configDir;
Chris@13 73 }
Chris@13 74 }
Chris@13 75
Chris@13 76 return $configDirs[0];
Chris@13 77 }
Chris@13 78
Chris@13 79 /**
Chris@13 80 * Find real config files in config directories.
Chris@13 81 *
Chris@13 82 * @param string[] $names Config file names
Chris@13 83 * @param string $configDir Optionally use a specific config directory
Chris@13 84 *
Chris@13 85 * @return string[]
Chris@13 86 */
Chris@13 87 public static function getConfigFiles(array $names, $configDir = null)
Chris@13 88 {
Chris@13 89 $dirs = ($configDir === null) ? self::getConfigDirs() : [$configDir];
Chris@13 90
Chris@13 91 return self::getRealFiles($dirs, $names);
Chris@13 92 }
Chris@13 93
Chris@13 94 /**
Chris@13 95 * Get potential data directory paths.
Chris@13 96 *
Chris@13 97 * If a `dataDir` option was explicitly set, returns an array containing
Chris@13 98 * just that directory.
Chris@13 99 *
Chris@13 100 * Otherwise, it returns `~/.psysh` and all XDG Base Directory data directories:
Chris@13 101 *
Chris@13 102 * http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html
Chris@13 103 *
Chris@13 104 * @return string[]
Chris@13 105 */
Chris@13 106 public static function getDataDirs()
Chris@13 107 {
Chris@13 108 $xdg = new Xdg();
Chris@13 109
Chris@13 110 return self::getDirNames($xdg->getDataDirs());
Chris@13 111 }
Chris@13 112
Chris@13 113 /**
Chris@13 114 * Find real data files in config directories.
Chris@13 115 *
Chris@13 116 * @param string[] $names Config file names
Chris@13 117 * @param string $dataDir Optionally use a specific config directory
Chris@13 118 *
Chris@13 119 * @return string[]
Chris@13 120 */
Chris@13 121 public static function getDataFiles(array $names, $dataDir = null)
Chris@13 122 {
Chris@13 123 $dirs = ($dataDir === null) ? self::getDataDirs() : [$dataDir];
Chris@13 124
Chris@13 125 return self::getRealFiles($dirs, $names);
Chris@13 126 }
Chris@13 127
Chris@13 128 /**
Chris@13 129 * Get a runtime directory.
Chris@13 130 *
Chris@13 131 * Defaults to `/psysh` inside the system's temp dir.
Chris@13 132 *
Chris@13 133 * @return string
Chris@13 134 */
Chris@13 135 public static function getRuntimeDir()
Chris@13 136 {
Chris@13 137 $xdg = new Xdg();
Chris@13 138
Chris@17 139 \set_error_handler(['Psy\Exception\ErrorException', 'throwException']);
Chris@13 140
Chris@13 141 try {
Chris@13 142 // XDG doesn't really work on Windows, sometimes complains about
Chris@13 143 // permissions, sometimes tries to remove non-empty directories.
Chris@13 144 // It's a bit flaky. So we'll give this a shot first...
Chris@13 145 $runtimeDir = $xdg->getRuntimeDir(false);
Chris@13 146 } catch (\Exception $e) {
Chris@13 147 // Well. That didn't work. Fall back to a boring old folder in the
Chris@13 148 // system temp dir.
Chris@17 149 $runtimeDir = \sys_get_temp_dir();
Chris@13 150 }
Chris@13 151
Chris@17 152 \restore_error_handler();
Chris@13 153
Chris@17 154 return \strtr($runtimeDir, '\\', '/') . '/psysh';
Chris@13 155 }
Chris@13 156
Chris@13 157 private static function getDirNames(array $baseDirs)
Chris@13 158 {
Chris@17 159 $dirs = \array_map(function ($dir) {
Chris@17 160 return \strtr($dir, '\\', '/') . '/psysh';
Chris@13 161 }, $baseDirs);
Chris@13 162
Chris@13 163 // Add ~/.psysh
Chris@17 164 if ($home = \getenv('HOME')) {
Chris@17 165 $dirs[] = \strtr($home, '\\', '/') . '/.psysh';
Chris@13 166 }
Chris@13 167
Chris@13 168 // Add some Windows specific ones :)
Chris@17 169 if (\defined('PHP_WINDOWS_VERSION_MAJOR')) {
Chris@17 170 if ($appData = \getenv('APPDATA')) {
Chris@13 171 // AppData gets preference
Chris@17 172 \array_unshift($dirs, \strtr($appData, '\\', '/') . '/PsySH');
Chris@13 173 }
Chris@13 174
Chris@17 175 $dir = \strtr(\getenv('HOMEDRIVE') . '/' . \getenv('HOMEPATH'), '\\', '/') . '/.psysh';
Chris@17 176 if (!\in_array($dir, $dirs)) {
Chris@13 177 $dirs[] = $dir;
Chris@13 178 }
Chris@13 179 }
Chris@13 180
Chris@13 181 return $dirs;
Chris@13 182 }
Chris@13 183
Chris@13 184 private static function getRealFiles(array $dirNames, array $fileNames)
Chris@13 185 {
Chris@13 186 $files = [];
Chris@13 187 foreach ($dirNames as $dir) {
Chris@13 188 foreach ($fileNames as $name) {
Chris@13 189 $file = $dir . '/' . $name;
Chris@17 190 if (@\is_file($file)) {
Chris@13 191 $files[] = $file;
Chris@13 192 }
Chris@13 193 }
Chris@13 194 }
Chris@13 195
Chris@13 196 return $files;
Chris@13 197 }
Chris@13 198
Chris@13 199 /**
Chris@13 200 * Ensure that $file exists and is writable, make the parent directory if necessary.
Chris@13 201 *
Chris@13 202 * Generates E_USER_NOTICE error if either $file or its directory is not writable.
Chris@13 203 *
Chris@13 204 * @param string $file
Chris@13 205 *
Chris@13 206 * @return string|false Full path to $file, or false if file is not writable
Chris@13 207 */
Chris@13 208 public static function touchFileWithMkdir($file)
Chris@13 209 {
Chris@17 210 if (\file_exists($file)) {
Chris@17 211 if (\is_writable($file)) {
Chris@13 212 return $file;
Chris@13 213 }
Chris@13 214
Chris@17 215 \trigger_error(\sprintf('Writing to %s is not allowed.', $file), E_USER_NOTICE);
Chris@13 216
Chris@13 217 return false;
Chris@13 218 }
Chris@13 219
Chris@17 220 $dir = \dirname($file);
Chris@13 221
Chris@17 222 if (!\is_dir($dir)) {
Chris@13 223 // Just try making it and see if it works
Chris@17 224 @\mkdir($dir, 0700, true);
Chris@13 225 }
Chris@13 226
Chris@17 227 if (!\is_dir($dir) || !\is_writable($dir)) {
Chris@17 228 \trigger_error(\sprintf('Writing to %s is not allowed.', $dir), E_USER_NOTICE);
Chris@13 229
Chris@13 230 return false;
Chris@13 231 }
Chris@13 232
Chris@17 233 \touch($file);
Chris@13 234
Chris@13 235 return $file;
Chris@13 236 }
Chris@13 237 }