-
Notifications
You must be signed in to change notification settings - Fork 4
/
update-readme.awk
executable file
·132 lines (107 loc) · 3.3 KB
/
update-readme.awk
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
#!/usr/bin/awk -f
# This script updates the README with descriptions extracted from patches.
# Write a message to standard error and exit with a non-zero status.
#
function abort(message)
{
system("rm -f README.md.tmp")
print message > "/dev/fd/2"
close("/dev/fd/2")
exit 1
}
# Add a line to the output buffer.
#
function buffer(line)
{
buffered_lines[buffered_line_count++] = line
if (line !~ /^[ \t]*$/) {
buffered_last_non_blank_line = buffered_line_count
}
}
BEGIN {
if (ARGC > 1) {
abort("this script does not accept arguments")
}
ARGC = 2
ARGV[1] = "README.md"
split("", buffered_lines)
}
# When a setext header is encountered that ends with a "/" the header name is
# interpreted as the directory that contains a "patches" folder.
/^-+$/ && previous_line ~ /\/$/ {
if (skip) {
buffer(previous_line)
}
skip = 0
directory = previous_line
}
# Once the "Patches" section of the document is reached, all of the existing
# content in the section is discarded and regenerated from patch descriptions.
$0 == "### patches/ ###" {
glob = directory "/patches/*"
("echo " glob) | getline glob_expansion
if (!(path_count = split(glob_expansion, paths)) || paths[1] ~ /\*$/) {
abort(glob ": glob expansion did not match any files")
}
buffer($0)
buffer("")
for (cursor = 1; cursor <= path_count; cursor++) {
path = paths[cursor]
# Do not document security patches since they are not really
# customizations.
if (path ~ /-CVE-/) {
continue
}
basename = path
sub(/^.*\//, "", basename)
patch_line_number = 1
skipping_header = 0
header_buffered = 0
# Extract the description from the patch. If the first line starts with
# "- ", that indicates that the first paragraph is general metadata
# that shouldn't be included in the README.
while ((status = (getline < path)) > 0 && !/^(diff -|---)/) {
# Patches pulled in from the canonical Git repo aren't documented
# since they're not really customizations.
if (/^commit [a-f0-9]+$/) {
break
}
if (!header_buffered) {
buffer("#### " basename " ####\n")
header_buffered = 1
}
if (patch_line_number == 1 && $0 ~ /^- /) {
skipping_header = 1
} else if (!skipping_header) {
buffer($0)
patch_line_number++
} else if (!NF) {
skipping_header = 0
}
}
error = length(ERRNO) ? ERRNO : "I/O error reading file"
close(path)
if (status < 0) {
abort(path ": " error)
}
}
skip = 1
}
{
if (!skip) {
buffer($0)
}
previous_line = $0
}
END {
system("rm -f README.md.tmp")
for (cursor = 0; cursor < buffered_last_non_blank_line; cursor++) {
print buffered_lines[cursor] >> "README.md.tmp"
}
if (close("README.md.tmp")) {
error = length(ERRNO) ? ERRNO : "close(2) reported an I/O error"
abort("README.md.tmp: " error)
} else if (system("mv README.md.tmp README.md")) {
abort("could not rename temporary file; mv failed")
}
}