release v3.2.2
[m6w6/ext-http] / scripts / 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_commonly_ignored($file)) {
28 continue;
29 }
30 if (!is_dir($file)) {
31 if (!in_array($file, $xml_files)) {
32 echo "Missing file $file\n";
33 }
34 } else {
35 $base = basename($file);
36 if ($base{0} !== ".") {
37 array_push($dirs, $file);
38 }
39 }
40 }
41 }
42 foreach ($xml_files as $file) {
43 if (!file_exists($file)) {
44 echo "Extraneous file $file\n";
45 }
46 }
47 }
48
49 ###
50
51 function error($fmt) {
52 trigger_error(call_user_func_array("sprintf", func_get_args()));
53 }
54
55 function stdin_is_readable() {
56 $r = [STDIN]; $w = $e = [];
57 return stream_select($r, $w, $e, 0);
58 }
59
60 function is_gitignored($file) {
61 static $gitignore, $gitmodules;
62
63 if (!isset($gitmodules)) {
64 if (is_readable("./.gitmodules")) {
65 $gitmodules = explode("\n", `git submodule status | awk '{printf$2}'`);
66 } else {
67 $gitmodules = false;
68 }
69 }
70 if (!isset($gitignore)) {
71 if (is_readable("./.gitignore")) {
72 $ignore_submodules = $gitmodules ? " ! -path './".implode("/*' ! -path './", $gitmodules)."/*'" : "";
73 $gitignore = explode("\n", `find . $ignore_submodules | git check-ignore --stdin`);
74 } else {
75 $gitignore = false;
76 }
77 }
78 if ($gitignore) {
79 if (in_array($file, $gitignore)) {
80 return true;
81 }
82 }
83 if ($gitmodules) {
84 foreach ($gitmodules as $module) {
85 if (fnmatch("./$module/*", $file)) {
86 return true;
87 }
88 }
89 }
90 return false;
91 }
92
93 function is_commonly_ignored($file) {
94 return fnmatch("./.git*", $file)
95 || in_array($file, ["./package.xml", "./package2.xml", "./.travis.yml", "./.editorconfig"], true);
96 }
97
98 function xmllist(SimpleXmlElement $dir, $p = ".", &$a = null) {
99 settype($a, "array");
100 $p = trim($p, "/") . "/" . trim($dir["name"], "/") . "/";
101 foreach ($dir as $file) {
102 switch ($file->getName()) {
103 case "dir":
104 xmllist($file, $p, $a);
105 break;
106 case "file":
107 $a[] = sprintf("%s/%s", trim($p, "/"), trim($file["name"]));
108 break;
109 default:
110 error("Unknown content type: %s", $file->getName());
111 break;
112 }
113 }
114 return $a;
115 }
116
117 function dirlist($dir, $p = null) {
118 $p = implode("/", array_filter([trim($p, "/"), trim($dir, "/")]));
119 foreach (scandir($p) as $file) {
120 yield $p."/".$file;
121 }
122 }