topgit: version 0.19.13
[topgit/pro.git] / awk / topgit_msg_prepare.awk
blob46ad3e55feea03ba8fc2ea72be72c7fef5c9a63c
1 #!/usr/bin/awk -f
3 # topgit_msg_prepare - TopGit awk utility script used by tg--awksome
4 # Copyright (C) 2017 Kyle J. McKay <mackyle@gmail.com>
5 # All rights reserved.
6 # License GPLv2
8 # topgit_msg_prepare
10 # variable arguments (-v):
12 # brfile if non-empty, the named file gets a list of TopGit branches
13 # anfile if non-empty, annihilated branch names are written here
14 # withan if true, include annihilated branches in brfile and output
15 # withmt empty branches: "" (like withan), true (include) false (exclude)
16 # depsblob if true skip the 6th line of each group as it's a .topdeps blob
17 # missing if non-empty output its value for the .topmsg blob instead
18 # of skipping, but still skip annihilated unless withan is true
19 # misscmd if missing is used and not seen in a "check" line run this once
21 # note that withan affects brfile and output but withmt only affects output
23 # note that empty branches are always included in anfile (and brfile when
24 # withan is true) regardless of any withmt setting
26 # if withan is false annihilated branches are excluded (but see withmt)
28 # if withmt is empty ("") empty branches are treated the same as annihilated
29 # branches; if withmt is true empty branches are always included even if withan
30 # is false; if withmt is false (but not "") empty branches are always excluded
31 # even if withan is true
33 # input must be result of awk_ref_prepare after feeding through the correct
34 # git --batch-check command and must be generated with the "msgblob" variable
35 # set to a TRUE value AND the same depsblob value must be passed as when
36 # awk_ref_prepare was run
38 # if missing is non-empty there are two different possible choices:
40 # 1. the hash of the empty blob, this is the recommended value and will
41 # cause all annihilated (unless withan is false) and non-annihilaed
42 # branches (unless withmt excludes them) without a .topmsg file to
43 # produce an output line which can often be useful
45 # 2. an invalid ref value, do NOT use "missing" as there could be such a ref
46 # name in the repository ("?" or "?missing" are good choices) and it must
47 # not contain any whitespace either; in this case this will trigger the
48 # subsequent git cat-file --batch to generate a "xxx missing" line which
49 # will also remove the item and ultimately have the same effect as leaving
50 # missing unset in the first place
52 # 3. it says "two" above, so don't do this, but if the blob hash of
53 # a different .topmsg file is given its contents will be used as though
54 # it had been the branch's .topmsg file in the first place (only for
55 # annihilated/empty and branches without one though)
57 # If missing is non-empty AND it gets used AND misscmd is non-empty AND no
58 # "blob check ?" line was seen for missing then misscmd will be run the FIRST
59 # time missing is about to be output (it always runs BEFORE the line is output).
61 # output is 1 line per non-excluded TopGit branch with a .topmsg file where
62 # each output line has this format:
64 # <blob_hash_of_.topmsg_file> K <TopGit_branch_name>
66 # where kind of branch value K has these possible values and meanings:
68 # 0 non-annihilated, non-empty branch WITH a .topmsg file
69 # 1 non-annihilated, non-empty branch WITHOUT a .topmsg file
70 # 2 annihilated branch
71 # 3 empty branch (an empty branch has the same branch and base commit hash)
72 # 4 bare branch (only if depsblob is true and has a value other than "1")
74 # if missing is empty K = 1..4 lines will not be output at all
75 # if missing is anything that causes a "missing" result it will defeat all
76 # K = 1..4 output lines when subsequently fed through git cat-file --batch
78 # in most other contexts empty branches are treated the same as annihilated
79 # branches (because their branch and base trees are necessarily the same), but
80 # here a distinction is made so a different message can be shown for them
82 # if depsblob is true and set to a value other than "1" then the depsblob line
83 # won't just be ignored, it should be a real depsblob line and it will be used
84 # to generate the K = 4 status value
86 # output should then be fed to:
88 # git cat-file --batch='%(objecttype) %(objectsize) %(rest)' | tr '\0' '\27'
90 # note that brfile and anfile are both fully written and closed before the
91 # first line of stdout is written and will be truncated to empty even if there
92 # are no lines directed to them
95 BEGIN { exitcode = "" }
96 function exitnow(e) { exitcode=e; exit e }
97 END { if (exitcode != "") exit exitcode }
99 BEGIN {
100 cnt = 0
101 delay = 0
102 if (anfile != "") {
103 printf "" >anfile
104 delay=1
106 if (brfile != "") {
107 printf "" >brfile
108 delay=1
110 FS = " "
111 missblob = missing
112 if (missing != "" && missing !~ /:/) missing = missing "^{blob}"
115 NF == 4 && $4 == "?" && $3 == "check" && $2 == "blob" && $1 != "" {
116 check[$1] = "blob"
117 next
120 function domissing() {
121 if (misscmd == "" || missblob in check) return
122 system(misscmd)
123 check[missblob] = ""
126 NF == 4 && $4 == ":" && $3 != "" && $2 != "missing" && $1 != "" {
127 if ((getline bc + getline hc + \
128 getline bct + getline hct + getline hcm) != 5) exitnow(2)
129 if (depsblob) {
130 split(hcm, ahcd)
131 if ((getline hcm) != 1) exitnow(2)
133 split(bc, abc)
134 split(hc, ahc)
135 split(bct, abct)
136 split(hct, ahct)
137 split(hcm, ahcm)
138 if (abc[2] != "commit" || ahc[2] != "commit" ||
139 abct[2] != "tree" || ahct[2] != "tree") next
140 want = abct[1] != ahct[1]
141 if (!want) {
142 if (withmt != "" && abc[1] == ahc[1]) want = withmt
143 else want = withan
145 K = 0
146 if (abct[1] == ahct[1]) {
147 if (anfile) print $3 >anfile
148 if (!want || missing == "") {
149 if (withan && brfile) print $3 >brfile
150 next
152 ahcm[1] = missing
153 ahcm[2] = "blob"
154 K = (abc[1] == ahc[1]) ? 3 : 2
155 domissing()
157 if (brfile) print $3 >brfile
158 if (missing != "" && ahcm[2] != "blob") {
159 if (!K) {
160 if (depsblob && depsblob != "1" &&
161 ahcd[2] == "missing" && ahcm[2] == "missing")
162 K = 4
163 else
164 K = 1
166 ahcm[1] = missing
167 ahcm[2] = "blob"
168 domissing()
170 if (ahcm[2] == "blob") {
171 if (delay)
172 items[++cnt] = ahcm[1] " " K " " $3
173 else
174 print ahcm[1] " " K " " $3
178 END {
179 if (anfile) close(anfile)
180 if (brfile) close(brfile)
181 for (i = 1; i <= cnt; ++i) print items[i]