-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathgit-store-dates.mk
More file actions
executable file
·148 lines (111 loc) · 4.15 KB
/
git-store-dates.mk
File metadata and controls
executable file
·148 lines (111 loc) · 4.15 KB
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
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
#!/usr/bin/make -f
MAKEFLAGS += -Rr
MAKEFLAGS += --warn-undefined-variables
SHELL := $(shell which bash)
.SHELLFLAGS := -euo pipefail -c
.ONESHELL:
.DELETE_ON_ERROR:
.PHONY: phony
ifdef NEVER
.RECIPEPREFIX :=
.RECIPEPREFIX +=
endif
_WS := $(or ) $(or )
.RECIPEPREFIX := $(_WS)
.DEFAULT_GOAL := main
MIN_VERSION := 4.1
VERSION_ERROR := make $(MAKE_VERSION) < $(MIN_VERSION)
$(and $(or $(filter $(MIN_VERSION),$(firstword $(sort $(MAKE_VERSION) $(MIN_VERSION)))),$(error $(VERSION_ERROR))),)
self := $(lastword $(MAKEFILE_LIST))
$(self) := $(basename $(self))
$(self):;
top: phony; @date
################
dry := .SHELLFLAGS += -nv
verb := .SHELLFLAGS += -v
trace := .SHELLFLAGS += -x
vartar := dry verb trace
# Add "$(eval $(vartar2e))" As last line
vartar2e = $$(vartar):; @: $$(eval $$($$@))
################
git.version.min := 2.23.0
git.version.use := $(word 3, $(shell git version))
git.version.seq := <(echo $(git.version.min) $(git.version.use) | xargs -n1)
git.version.cmp != cmp -s <(sort -V $(git.version.seq)) $(git.version.seq) || date
$(if $(git.version.cmp), $(error want git $(git.version.min), found git $(git.version.use)))
################
toplevel != git rev-parse --show-toplevel
$(if $(toplevel),, $(error not in git context))
found := $(toplevel)/.git/hooks/.found-dates
saved := $(toplevel)/.saved-dates
save: phony find $(saved)
main: phony save
find restore: vars := -v RS='\0' -v q='"'
find save: ifzero = $(found)$(if $(ZERO),,-nozero)
ZERO :=
zero := ZERO := 42
vartar += zero
ifne := /usr/bin/ifne
$(ifne):; sudo aptitude install -y moreutils
gawk := /usr/bin/gawk
$(gawk):; sudo aptitude install -y $(@F)
bindeps := $(ifne) $(gawk)
find: find := git ls-files -sz | grep -zave $(notdir $(saved)) | cut -zf2
find: stat := xargs -0 stat -c '%Y %n' | tr '\n' '\0' | sort -zrn
find: awk := FNR == 1 { print "touch -d @" $$1 FS q "$(found)" q }
find: $(bindeps) phony; @:
$(find) | $(stat) > $(found)
awk $(vars) '$(awk)' $(found) | dash
< $(found) tr -cd '\n' | ifne /bin/false # don't accept '\n' in filename
$(found):;
$(found)-nozero: $(found); @:
< $< tr '\0' '\n'n > $@; touch -r $< $@
cmp -s $(ifzero) $(saved) || rm -f $(saved)
$(saved): $(found)-nozero; @cp -p $(ifzero) $@; git add $@; echo $(self): dates upgraded
show: $(saved) phony; @< $< tr '\0' '\n'
restore: awk := { print "touch -d @" $$1 sprintf("", sub($$1 FS, "")) FS q $$0 q }
restore: $(bindeps) phony; @:
test -f $(saved) || exit 0
# zero fmt
if < $(saved) tr -cd '\0' | ifne -n /bin/false; then awk $(vars) '$(awk)' $(saved);
# nozero fmt
else < $(saved) tr '\n' '\0' | awk $(vars) '$(awk)'; fi | dash
hooks: list := pre-commit post-merge
hooks: pre-commit := \#!/bin/sh\n\ngit-store-dates
hooks: post-merge := $(pre-commit) restore
hooks: links := $(toplevel)/.git/hooks/%
hooks: files := $(links).store-dates
hooks: tests := $(links).tests
hooks: . := $(eval hooks_files := $(list:%=$(files)))
hooks: . := $(eval hooks_links := $(list:%=$(links)))
hooks: . := $(eval hooks_tests := $(list:%=$(tests)))
hooks: . := $(eval hooks_files_p := $(files))
hooks: . := $(eval hooks_links_p := $(links))
$(hooks_files): $(hooks_files_p) :; echo -e '$($*)' > $@; chmod +x $@
$(hooks_links_p): $(hooks_files_p); (cd $(@D); ln -s $(<F) $(@F))
$(hooks_tests):
@test -h $(basename $@) || (test -f $(basename $@) \
&& (echo -e "\n\t*** hook $(basename $(@F)) already exists\n"; exit 1))
hooks: phony $(hooks_files) $(hooks_links) $(hooks_tests);
ifeq ($(MAKECMDGOALS), install)
release != lsb_release -is
ifeq ($(release), Debian)
USER ?= no_user
staff := staff
$(if $(shell test $(USER) == root || getent group $(staff) | grep -q $(USER) || date),$(error $(USER) not in group $(staff), use "sudo make -f $(self) install"))
endif
ifeq ($(dir $(self)),./)
install_dir := /usr/local/bin
install_list := $(self)
$(install_dir)/%: %; install $< $@; $(if $($*),(cd $(@D); $(strip $(foreach _, $($*), ln -sf $* $_;))))
install: phony $(install_list:%=$(install_dir)/%);
else
install: phony; @echo "can't install from installed"
endif
endif
define help
$($(self)) save restore hooks
endef
help:; @echo $($@)
################
$(eval $(vartar2e))