X-Git-Url: https://git.m6w6.name/?p=m6w6%2Fext-http;a=blobdiff_plain;f=scripts%2Fcheck_package-xml.php;fp=scripts%2Fcheck_package-xml.php;h=e422c6a993b679961601565940b6fdaa6c489d16;hp=0000000000000000000000000000000000000000;hb=bdd6edb59194cda9e5fcb393c48ab4230fceb32a;hpb=c05ef71b26a8d16bf5af2bd8275e08ba5ae02b52 diff --git a/scripts/check_package-xml.php b/scripts/check_package-xml.php new file mode 100755 index 0000000..e422c6a --- /dev/null +++ b/scripts/check_package-xml.php @@ -0,0 +1,122 @@ +#!/usr/bin/env php + 1) { + if ($argv[1] === "-") { + $file = "php://stdin"; + } else { + $file = $argv[1]; + } +} elseif (stdin_is_readable()) { + $file = "php://stdin"; +} else { + $file = "./package.xml"; +} + +if (($xml = simplexml_load_file($file))) { + $xml_files = xmllist($xml->contents[0]); + $dirs = ["."]; + while ($dir = array_shift($dirs)) { + foreach (dirlist($dir) as $file) { + if (is_gitignored($file)) { + continue; + } + if (is_commonly_ignored($file)) { + continue; + } + if (!is_dir($file)) { + if (!in_array($file, $xml_files)) { + echo "Missing file $file\n"; + } + } else { + $base = basename($file); + if ($base{0} !== ".") { + array_push($dirs, $file); + } + } + } + } + foreach ($xml_files as $file) { + if (!file_exists($file)) { + echo "Extraneous file $file\n"; + } + } +} + +### + +function error($fmt) { + trigger_error(call_user_func_array("sprintf", func_get_args())); +} + +function stdin_is_readable() { + $r = [STDIN]; $w = $e = []; + return stream_select($r, $w, $e, 0); +} + +function is_gitignored($file) { + static $gitignore, $gitmodules; + + if (!isset($gitmodules)) { + if (is_readable("./.gitmodules")) { + $gitmodules = explode("\n", `git submodule status | awk '{printf$2}'`); + } else { + $gitmodules = false; + } + } + if (!isset($gitignore)) { + if (is_readable("./.gitignore")) { + $ignore_submodules = $gitmodules ? " ! -path './".implode("/*' ! -path './", $gitmodules)."/*'" : ""; + $gitignore = explode("\n", `find . $ignore_submodules | git check-ignore --stdin`); + } else { + $gitignore = false; + } + } + if ($gitignore) { + if (in_array($file, $gitignore)) { + return true; + } + } + if ($gitmodules) { + foreach ($gitmodules as $module) { + if (fnmatch("./$module/*", $file)) { + return true; + } + } + } + return false; +} + +function is_commonly_ignored($file) { + return fnmatch("./.git*", $file) + || in_array($file, ["./package.xml", "./package2.xml", "./.travis.yml", "./.editorconfig"], true); +} + +function xmllist(SimpleXmlElement $dir, $p = ".", &$a = null) { + settype($a, "array"); + $p = trim($p, "/") . "/" . trim($dir["name"], "/") . "/"; + foreach ($dir as $file) { + switch ($file->getName()) { + case "dir": + xmllist($file, $p, $a); + break; + case "file": + $a[] = sprintf("%s/%s", trim($p, "/"), trim($file["name"])); + break; + default: + error("Unknown content type: %s", $file->getName()); + break; + } + } + return $a; +} + +function dirlist($dir, $p = null) { + $p = implode("/", array_filter([trim($p, "/"), trim($dir, "/")])); + foreach (scandir($p) as $file) { + yield $p."/".$file; + } +}