Skip to content

Instantly share code, notes, and snippets.

@tox2ik
Created March 31, 2020 19:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tox2ik/4ba4482ea60897d3f62d69bee015a762 to your computer and use it in GitHub Desktop.
Save tox2ik/4ba4482ea60897d3f62d69bee015a762 to your computer and use it in GitHub Desktop.
<?php
/*
* Generate a manifest:
*
* php clean-dirs.php save vendor
* git add .present.vendor # optional, may be rsynced/uploaded to document root
*/
/** pretend to generate some assets */
function build(): array {
if (!is_dir('dist')) mkdir('dist');
$extensions = ['js', 'css', 'png'];
$time = date('Ym-d_H:i:s');
$new_files = [];
foreach (range(1, 10) as $e) {
$ix = rand(0, count($extensions)-1);
$ext = $extensions[$ix];
$current_file = "dist/$time.$e.$ext";
$new_files[] = $current_file;
touch($current_file);
}
return $new_files;
}
/** record present files */
function save(string $dir = 'dist/'): string {
$dir = trim($dir, '/');
$files = _find($dir, '/.*/', 'fl');
$outFile = realpath(__DIR__) . "/.present.$dir";
file_put_contents($outFile, implode(PHP_EOL, $files).PHP_EOL);
return $outFile;
}
/**
* remove files below DIR iff manifest file DIR/../.prerent.dir exists.
* the manifest file enumerates files to keep.
* everything below DIR is removed if the manifest file is empty.
* nothing is removed if the manifest file is missing.
*/
function purge(string $dir = 'dist/'): void {
$dir = trim($dir, '/');
$rpath = dirname(realpath($dir));
$keepFilesFrom = "$rpath/.present.$dir";
if (! is_dir($dir)) return;
if (! is_readable($keepFilesFrom)) return;
$keep = [];
$keeps = file_get_contents($keepFilesFrom);
if (strlen($keeps)) {
$keep = explode("\n", $keeps);
unset($keeps);
}
$purgeList = _find($dir, '/.*/', 'fl');
$purgeList = array_flip($purgeList);
foreach ($keep as $keep1) {
if (isset($purgeList[$keep1])) {
unset($purgeList[$keep1]);
}
}
foreach ($purgeList as $goner => $i) {
$err = fopen('php://stderr', 'w');
unlink($goner);
fprintf($err, "gone: %s\n", $goner);
}
unlink($keepFilesFrom);
}
function _find($folder, $pattern = '/.*/', $filter = 'dfl'): array {
$dir = new RecursiveDirectoryIterator($folder);
$ite = new RecursiveIteratorIterator($dir);
/** @var SplFileInfo[] $files */
$files = new RegexIterator($ite, $pattern, RegexIterator::MATCH);
$ff = [];
foreach($files as $file) {
$f = false !== strpos($filter, 'f') && $file->isFile();
$d = false !== strpos($filter, 'd') && $file->isDir();
$l = false !== strpos($filter, 'l') && $file->isLink();
if ($f || $d || $l)
$ff[] = $file->getPathname();
}
return $ff;
}
function _cat(array $stuff): string {
return join(PHP_EOL, $stuff) . PHP_EOL;
}
function _help() {
preg_match_all('/\nfunction ([a-z][^:]+)/s', file_get_contents(__FILE__), $functions, PREG_PATTERN_ORDER);
printf("Usage:\n\tphp %s fn-name\n\t..where fn is one of:\n\n", basename(__FILE__));
echo _cat($functions[1]);
}
function _main() {
global $argc, $argv;
if ($argc >= 2) {
$path = $argv[2] ?? 'dist/';
switch ($argv[1]) {
case 'build': echo _cat(build()); break;
case 'save': echo _cat([save($path)]); break;
case 'purge':
foreach (['dist/', 'vendor/'] as $purgeDir) {
purge($purgeDir);
}
break;
default:
_help();
}
}
if ($argc == 1) {
_help();
}
if ($_GET['build'] ?? false) {
_cat(build());
}
}
_main();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment