don't rely on external services (tm)
[m6w6/ext-http] / check_package-xml.php
1 #!/usr/bin/env php
2 <?php
3
4 ini_set("log_errors", false);
5 ini_set("display_errors", true);
6
7 if ($argc > 1) {
8 if ($argv[1] === "-") {
9 $file = "php://stdin";
10 } else {
11 $file = $argv[1];
12 }
13 } elseif (stdin_is_readable()) {
14 $file = "php://stdin";
15 } else {
16 $file = "./package.xml";
17 }
18
19 if (($xml = simplexml_load_file($file))) {
20 $xml_files = xmllist($xml->contents[0]);
21 $dirs = ["."];
22 while ($dir = array_shift($dirs)) {
23 foreach (dirlist($dir) as $file) {
24 if (is_gitignored($file)) {
25 continue;
26 }
27 if (!is_dir($file)) {
28 if (!in_array($file, $xml_files)) {
29 echo "Missing file $file\n";
30 }
31 } else {
32 $base = basename($file);
33 if ($base{0} !== ".") {
34 array_push($dirs, $file);
35 }
36 }
37 }
38 }
39 foreach ($xml_files as $file) {
40 if (!file_exists($file)) {
41 echo "Extraneous file $file\n";
42 }
43 }
44 }
45
46 ###
47
48 function error($fmt) {
49 trigger_error(call_user_func_array("sprintf", func_get_args()));
50 }
51
52 function stdin_is_readable() {
53 $r = [STDIN]; $w = $e = [];
54 return stream_select($r, $w, $e, 0);
55 }
56
57 function is_gitignored($file) {
58 static $gitignore;
59
60 if (!isset($gitignore)) {
61 if (is_readable(".gitignore")) {
62 $gitignore = explode("\n", `find | git check-ignore --stdin`);
63 } else {
64 $gitignore = false;
65 }
66 }
67 if ($gitignore) {
68 return in_array($file, $gitignore);
69 }
70 return false;
71 }
72
73 function xmllist(SimpleXmlElement $dir, $p = ".", &$a = null) {
74 settype($a, "array");
75 $p = trim($p, "/") . "/" . trim($dir["name"], "/") . "/";
76 foreach ($dir as $file) {
77 switch ($file->getName()) {
78 case "dir":
79 xmllist($file, $p, $a);
80 break;
81 case "file":
82 $a[] = sprintf("%s/%s", trim($p, "/"), trim($file["name"]));
83 break;
84 default:
85 error("Unknown content type: %s", $file->getName());
86 break;
87 }
88 }
89 return $a;
90 }
91
92 function dirlist($dir, $p = null) {
93 $p = implode("/", array_filter([trim($p, "/"), trim($dir, "/")]));
94 foreach (scandir($p) as $file) {
95 yield $p."/".$file;
96 }
97 }