Housekeeping: implement a tool for producing intermediate alpha tarballs.
Intermediate tarballs have the same version number as initial alpha version, to which is appended a suffix "-N", where N is the number of commits between the current git HEAD and the original alpha release. Additionally, the --version (or -version, for MH) output has been changed to include the N and the git description (for all releases, but stable). * .gitignore: Update. * Makefile.am: Remove git-describe and git-describe.h goals. (alpha, alphacheck): Rewrite. * configure.ac (GITINFO): New subst variable. * include/mailutils/Makefile.am (gitinfo.h): New built source. * libmailutils/cli/cli.c: Include gitinfo.h (mu_version_hook): Rewrite. * mh/mh_getopt.c: Include gitinfo.h (mh_version_hook): Rewrite. * mu-aux/gitinfo.pl: New file. * mu-aux/Makefile.am (EXTRA_DIST): Add gitinfo.pl * mu/Makefile.am (mu-setup.c): Add dependency * testsuite/testsuite.inc (MUT_VERSION): Account for changes in version output.
Showing
10 changed files
with
512 additions
and
61 deletions
... | @@ -120,9 +120,8 @@ SUBDIRS = . \ | ... | @@ -120,9 +120,8 @@ SUBDIRS = . \ |
120 | $(MOVEMAIL_DIR)\ | 120 | $(MOVEMAIL_DIR)\ |
121 | $(MIMEVIEW_DIR) | 121 | $(MIMEVIEW_DIR) |
122 | 122 | ||
123 | EXTRA_DIST = COPYING.LESSER paths git-describe git-describe.h | 123 | EXTRA_DIST = COPYING.LESSER paths |
124 | BUILT_SOURCES = git-describe git-describe.h | 124 | DISTCLEANFILES = pathdefs.h |
125 | DISTCLEANFILES = pathdefs.h git-describe.h | ||
126 | 125 | ||
127 | gen_start_date = "2008-12-08" | 126 | gen_start_date = "2008-12-08" |
128 | prev_change_log = "doc/ChangeLog.CVS" | 127 | prev_change_log = "doc/ChangeLog.CVS" |
... | @@ -155,20 +154,7 @@ ChangeLog: | ... | @@ -155,20 +154,7 @@ ChangeLog: |
155 | mv cl-t ChangeLog; \ | 154 | mv cl-t ChangeLog; \ |
156 | fi | 155 | fi |
157 | 156 | ||
158 | .PHONY: git-describe | 157 | dist-hook: ChangeLog |
159 | git-describe: | ||
160 | $(AM_V_GEN)if test -d .git; then \ | ||
161 | dirty=`git diff-index --name-only HEAD 2>/dev/null` || dirty=;\ | ||
162 | test -n "$$dirty" && dirty="-dirty"; \ | ||
163 | descr=`git describe`; \ | ||
164 | echo $${descr}$$dirty > git-describe.tmp; \ | ||
165 | test -f git-describe && \ | ||
166 | cmp git-describe.tmp git-describe >/dev/null || \ | ||
167 | cp git-describe.tmp git-describe; \ | ||
168 | rm git-describe.tmp; \ | ||
169 | fi | ||
170 | |||
171 | dist-hook: ChangeLog git-describe | ||
172 | @PATCHLEV=`echo "$(PACKAGE_VERSION)" | \ | 158 | @PATCHLEV=`echo "$(PACKAGE_VERSION)" | \ |
173 | sed -r "s/[0-9]+\.[0-9]+\.?//"`; \ | 159 | sed -r "s/[0-9]+\.[0-9]+\.?//"`; \ |
174 | if test $${PATCHLEV:-0} -lt 50; then \ | 160 | if test $${PATCHLEV:-0} -lt 50; then \ |
... | @@ -178,30 +164,20 @@ dist-hook: ChangeLog git-describe | ... | @@ -178,30 +164,20 @@ dist-hook: ChangeLog git-describe |
178 | fi; \ | 164 | fi; \ |
179 | fi | 165 | fi |
180 | 166 | ||
181 | git-describe.h: git-describe | 167 | alpha: |
182 | $(AM_V_GEN)if test -f $(srcdir)/git-describe; then \ | 168 | version=`$(GITINFO) -H'$$refversion{?$$n>0??-$$n?}'`;\ |
183 | sed '1s/.*/#define GIT_DESCRIBE "&"/' $(srcdir)/git-describe; \ | 169 | if test -n "$$version"; then\ |
170 | $(MAKE) dist distdir=$(PACKAGE)-$$version; \ | ||
184 | else \ | 171 | else \ |
185 | echo "/* No git tag */"; \ | 172 | $(MAKE) dist; \ |
186 | fi > git-describe.h.tmp; \ | 173 | fi |
187 | test -f git-describe.h && \ | 174 | |
188 | cmp git-describe.h.tmp git-describe.h >/dev/null || \ | ||
189 | cp git-describe.h.tmp git-describe.h; \ | ||
190 | rm git-describe.h.tmp | ||
191 | |||
192 | alpha: git-describe | ||
193 | $(AM_V_GEN)if test -f $(srcdir)/git-describe; then \ | ||
194 | tag=`head -n 1 $(srcdir)/git-describe`; \ | ||
195 | else \ | ||
196 | tag=`date +"%Y%m%d"`; \ | ||
197 | fi; \ | ||
198 | $(MAKE) dist distdir=$(PACKAGE)-$(VERSION)-$$tag | ||
199 | 175 | ||
200 | alphacheck: | 176 | alphacheck: |
201 | $(AM_V_GEN)if test -f $(srcdir)/git-describe; then \ | 177 | version=`$(GITINFO) -H'$$refversion{?$$n>0??-$$n?}'`;\ |
202 | tag=`head -n 1 $(srcdir)/git-describe`; \ | 178 | if test -n "$$version"; then\ |
179 | $(MAKE) distcheck distdir=$(PACKAGE)-$$version; \ | ||
203 | else \ | 180 | else \ |
204 | tag=`date +"%Y%m%d"`; \ | 181 | $(MAKE) distcheck; \ |
205 | fi; \ | 182 | fi |
206 | $(MAKE) distcheck distdir=$(PACKAGE)-$(VERSION)-$$tag | ||
207 | 183 | ... | ... |
... | @@ -1370,6 +1370,12 @@ CPPFLAGS="$CPPFLAGS -DSYSCONFDIR=\\\"\$(sysconfdir)\\\"" | ... | @@ -1370,6 +1370,12 @@ CPPFLAGS="$CPPFLAGS -DSYSCONFDIR=\\\"\$(sysconfdir)\\\"" |
1370 | # Doc hints. | 1370 | # Doc hints. |
1371 | IMPRIMATUR_INIT([doc/imprimatur]) | 1371 | IMPRIMATUR_INIT([doc/imprimatur]) |
1372 | 1372 | ||
1373 | AC_PATH_PROG([PERL], perl) | ||
1374 | if test -z "$PERL"; then | ||
1375 | PERL=false | ||
1376 | fi | ||
1377 | AC_SUBST([GITINFO],'$(PERL) $(mu_aux_dir)/gitinfo.pl') | ||
1378 | |||
1373 | AC_CONFIG_COMMANDS([status],[ | 1379 | AC_CONFIG_COMMANDS([status],[ |
1374 | cat <<EOF | 1380 | cat <<EOF |
1375 | 1381 | ... | ... |
... | @@ -15,7 +15,7 @@ | ... | @@ -15,7 +15,7 @@ |
15 | ## You should have received a copy of the GNU General Public License | 15 | ## You should have received a copy of the GNU General Public License |
16 | ## along with GNU Mailutils. If not, see <http://www.gnu.org/licenses/>. | 16 | ## along with GNU Mailutils. If not, see <http://www.gnu.org/licenses/>. |
17 | 17 | ||
18 | BUILT_SOURCES=errno.h types.h | 18 | BUILT_SOURCES=errno.h types.h gitinfo.h |
19 | EXTRA_DIST=errno.hin types.hin | 19 | EXTRA_DIST=errno.hin types.hin |
20 | errno.h: $(top_srcdir)/libmailutils/diag/errors errno.hin | 20 | errno.h: $(top_srcdir)/libmailutils/diag/errors errno.hin |
21 | $(AM_V_GEN)$(AWK) -f $(mu_aux_dir)/generr.awk $(top_srcdir)/libmailutils/diag/errors errno.hin > errno.h | 21 | $(AM_V_GEN)$(AWK) -f $(mu_aux_dir)/generr.awk $(top_srcdir)/libmailutils/diag/errors errno.hin > errno.h |
... | @@ -24,7 +24,15 @@ types.h: $(top_srcdir)/include/mailutils/types.hin Makefile | ... | @@ -24,7 +24,15 @@ types.h: $(top_srcdir)/include/mailutils/types.hin Makefile |
24 | $(AM_V_GEN)sed -e 's/_MU_OFF_TYPE_/$(MU_OFF_TYPE)/' \ | 24 | $(AM_V_GEN)sed -e 's/_MU_OFF_TYPE_/$(MU_OFF_TYPE)/' \ |
25 | -e 's/_MU_DEFAULT_RECORD_/$(MU_DEFAULT_RECORD)/' \ | 25 | -e 's/_MU_DEFAULT_RECORD_/$(MU_DEFAULT_RECORD)/' \ |
26 | -e 's/_MU_PRI_OFF_T_/$(MU_PRI_OFF_T)/' \ | 26 | -e 's/_MU_PRI_OFF_T_/$(MU_PRI_OFF_T)/' \ |
27 | $(top_srcdir)/include/mailutils/types.hin > $@ | 27 | $(top_srcdir)/include/mailutils/types.hin > types.h |
28 | |||
29 | gitinfo.h: $(top_srcdir)/ChangeLog | ||
30 | $(AM_V_GEN)if ! $(GITINFO) -Hc -ogitinfo.h \ | ||
31 | && test ! -f $(srcdir)/gitinfo.h; then \ | ||
32 | echo '/* no info */' > gitinfo.h;\ | ||
33 | fi | ||
34 | |||
35 | |||
28 | DISTCLEANFILES = types.h | 36 | DISTCLEANFILES = types.h |
29 | 37 | ||
30 | pkginclude_HEADERS = \ | 38 | pkginclude_HEADERS = \ |
... | @@ -51,6 +59,7 @@ pkginclude_HEADERS = \ | ... | @@ -51,6 +59,7 @@ pkginclude_HEADERS = \ |
51 | error.h\ | 59 | error.h\ |
52 | filter.h\ | 60 | filter.h\ |
53 | folder.h\ | 61 | folder.h\ |
62 | gitinfo.h\ | ||
54 | glob.h\ | 63 | glob.h\ |
55 | gsasl.h\ | 64 | gsasl.h\ |
56 | guile.h\ | 65 | guile.h\ | ... | ... |
... | @@ -33,6 +33,7 @@ | ... | @@ -33,6 +33,7 @@ |
33 | #include <mailutils/io.h> | 33 | #include <mailutils/io.h> |
34 | #include <mailutils/syslog.h> | 34 | #include <mailutils/syslog.h> |
35 | #include <mailutils/mu_auth.h> | 35 | #include <mailutils/mu_auth.h> |
36 | #include <mailutils/gitinfo.h> | ||
36 | 37 | ||
37 | #define MU_LEGACY_CONFIG_FILE SYSCONFDIR "/mailutils.rc" | 38 | #define MU_LEGACY_CONFIG_FILE SYSCONFDIR "/mailutils.rc" |
38 | 39 | ||
... | @@ -59,10 +60,11 @@ const char mu_version_copyright[] = | ... | @@ -59,10 +60,11 @@ const char mu_version_copyright[] = |
59 | void | 60 | void |
60 | mu_version_hook (struct mu_parseopt *po, mu_stream_t stream) | 61 | mu_version_hook (struct mu_parseopt *po, mu_stream_t stream) |
61 | { | 62 | { |
62 | #ifdef GIT_DESCRIBE | 63 | #if MU_GIT_COMMIT_DISTANCE > 0 |
63 | mu_stream_printf (stream, "%s (%s) %s [%s]\n", | 64 | mu_stream_printf (stream, "%s (%s) %s-%d [%s]\n", |
64 | mu_program_name, PACKAGE_NAME, PACKAGE_VERSION, | 65 | mu_program_name, PACKAGE_NAME, PACKAGE_VERSION, |
65 | GIT_DESCRIBE); | 66 | MU_GIT_COMMIT_DISTANCE, |
67 | MU_GIT_DESCRIBE_STRING); | ||
66 | #else | 68 | #else |
67 | mu_stream_printf (stream, "%s (%s) %s\n", mu_program_name, | 69 | mu_stream_printf (stream, "%s (%s) %s\n", mu_program_name, |
68 | PACKAGE_NAME, PACKAGE_VERSION); | 70 | PACKAGE_NAME, PACKAGE_VERSION); | ... | ... |
... | @@ -27,6 +27,7 @@ | ... | @@ -27,6 +27,7 @@ |
27 | #include <mailutils/wordsplit.h> | 27 | #include <mailutils/wordsplit.h> |
28 | #include <mailutils/io.h> | 28 | #include <mailutils/io.h> |
29 | #include <mailutils/cli.h> | 29 | #include <mailutils/cli.h> |
30 | #include <mailutils/gitinfo.h> | ||
30 | 31 | ||
31 | struct getopt_data | 32 | struct getopt_data |
32 | { | 33 | { |
... | @@ -144,12 +145,13 @@ static struct mu_option folder_option[] = { | ... | @@ -144,12 +145,13 @@ static struct mu_option folder_option[] = { |
144 | void | 145 | void |
145 | mh_version_hook (struct mu_parseopt *po, mu_stream_t stream) | 146 | mh_version_hook (struct mu_parseopt *po, mu_stream_t stream) |
146 | { | 147 | { |
147 | #ifdef GIT_DESCRIBE | 148 | #if MU_GIT_COMMIT_DISTANCE > 0 |
148 | mu_stream_printf (stream, "%s (%s %s) [%s]\n", | 149 | mu_stream_printf (stream, "%s (%s) %s-%d [%s]\n", |
149 | mu_program_name, PACKAGE_NAME, PACKAGE_VERSION, | 150 | mu_program_name, PACKAGE_NAME, PACKAGE_VERSION, |
150 | GIT_DESCRIBE); | 151 | MU_GIT_COMMIT_DISTANCE, |
152 | MU_GIT_DESCRIBE_STRING); | ||
151 | #else | 153 | #else |
152 | mu_stream_printf (stream, "%s (%s %s)\n", mu_program_name, | 154 | mu_stream_printf (stream, "%s (%s) %s\n", mu_program_name, |
153 | PACKAGE_NAME, PACKAGE_VERSION); | 155 | PACKAGE_NAME, PACKAGE_VERSION); |
154 | #endif | 156 | #endif |
155 | /* TRANSLATORS: Translate "(C)" to the copyright symbol | 157 | /* TRANSLATORS: Translate "(C)" to the copyright symbol | ... | ... |
... | @@ -22,7 +22,8 @@ EXTRA_DIST = \ | ... | @@ -22,7 +22,8 @@ EXTRA_DIST = \ |
22 | mailutils.spec.in\ | 22 | mailutils.spec.in\ |
23 | texify.sed\ | 23 | texify.sed\ |
24 | sqlmod.sh\ | 24 | sqlmod.sh\ |
25 | generr.awk | 25 | generr.awk\ |
26 | gitinfo.pl | ||
26 | 27 | ||
27 | m4datadir = $(datadir)/aclocal | 28 | m4datadir = $(datadir)/aclocal |
28 | dist_m4data_DATA = mailutils.m4 | 29 | dist_m4data_DATA = mailutils.m4 | ... | ... |
mu-aux/gitinfo.pl
0 → 100644
1 | # This file is part of GNU Mailutils. | ||
2 | # Copyright (C) 2017 Free Software Foundation, Inc. | ||
3 | # | ||
4 | # GNU Mailutils is free software; you can redistribute it and/or | ||
5 | # modify it under the terms of the GNU General Public License as | ||
6 | # published by the Free Software Foundation; either version 3, or (at | ||
7 | # your option) any later version. | ||
8 | # | ||
9 | # GNU Mailutils is distributed in the hope that it will be useful, but | ||
10 | # WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
12 | # General Public License for more details. | ||
13 | # | ||
14 | # You should have received a copy of the GNU General Public License | ||
15 | # along with GNU Mailutils. If not, see <http://www.gnu.org/licenses/>. | ||
16 | |||
17 | use strict; | ||
18 | use Getopt::Long qw(:config gnu_getopt no_ignore_case); | ||
19 | use Pod::Usage; | ||
20 | use Pod::Man; | ||
21 | use Pod::Find qw(pod_where); | ||
22 | |||
23 | =head1 NAME | ||
24 | |||
25 | gitinfo.pl - build version tag for mailutils | ||
26 | |||
27 | =head1 SYNOPSIS | ||
28 | |||
29 | B<perl gitinfo.pl> | ||
30 | [B<-sv>] | ||
31 | [B<-C> I<DIR>] | ||
32 | [B<-H> I<FORMAT>] | ||
33 | [B<-o> I<FILE>] | ||
34 | [B<--directory=>I<DIR>] | ||
35 | [B<--format=>I<FORMAT>] | ||
36 | [B<--output=>I<FILE>] | ||
37 | [B<--stable>] | ||
38 | [B<--verbose>] | ||
39 | |||
40 | B<perl gitinfo.pl> B<-h> | B<--help> | B<--usage> | ||
41 | |||
42 | =head1 DESCRIPTION | ||
43 | |||
44 | Outputs Git information for the version of GNU mailutils in | ||
45 | the local source tree. The information is printed according to | ||
46 | the supplied I<FORMAT>. The format is an arbitrary string, containing | ||
47 | variable references in the form B<$I<VARIABLE>> or B<${I<VARIABLE>}>. | ||
48 | If the variable reference occurs within a quoted string, any occurrences | ||
49 | of double quotes and backslashes in the expansion will be escaped by | ||
50 | backslashes. | ||
51 | |||
52 | The following variables are defined: | ||
53 | |||
54 | =over 4 | ||
55 | |||
56 | =item B<package> | ||
57 | |||
58 | Package name, obtained from the B<AC_INIT> line in F<configure.ac>. | ||
59 | |||
60 | =item B<version> | ||
61 | |||
62 | Package version, from the same source. | ||
63 | |||
64 | =item B<refversion> | ||
65 | |||
66 | Reference version. By default, it is the same as B<version> above. If, | ||
67 | however, the B<-s> (B<--stable>) option is given, B<refversion> is set | ||
68 | to the most recent stable release. The B<NEWS> file is analyzed in order | ||
69 | to find it. | ||
70 | |||
71 | =item B<refdate> | ||
72 | |||
73 | Date when B<refversion> was released. Normally this is meaningful only for | ||
74 | stable versions (in other words, when the B<-s> option is given). | ||
75 | |||
76 | =item B<refcommit> | ||
77 | |||
78 | Hash of the commit corresponding to the B<refversion>. | ||
79 | |||
80 | =item B<n> | ||
81 | |||
82 | Number of commits between B<refcommit> and B<HEAD>. | ||
83 | |||
84 | =item B<describe> | ||
85 | |||
86 | Result of the B<git describe> command. | ||
87 | |||
88 | =item B<dirty> | ||
89 | |||
90 | If the source tree has uncommitted modifications, this variable is set | ||
91 | to 1. Otherwise, it is undefined. | ||
92 | |||
93 | =item B<commit_hash> | ||
94 | |||
95 | The hash of the topmost commit. | ||
96 | |||
97 | =item B<commit_time> | ||
98 | |||
99 | Time of the topmost commit (UNIX timestamp). | ||
100 | |||
101 | =item B<commit_subject> | ||
102 | |||
103 | Subject of the topmost commit. | ||
104 | |||
105 | =back | ||
106 | |||
107 | The construct | ||
108 | |||
109 | B<{?I<EXPR>??I<REPL-IF-TRUE>>[B<?|I<REPL-IF-FALSE>>]B<?}> | ||
110 | |||
111 | within a format string provides a rudimental control flow facility. The | ||
112 | I<EXPR> is evaluated as a Perl expression in an environment when the variales | ||
113 | disucussed above are defined. If the result is true (in Perl sense), the | ||
114 | construct expands to I<REPL-IF-TRUE>. Othervise, it expands to | ||
115 | I<REPL-IF-FALSE> or, if it is not defined, to the empty string. | ||
116 | |||
117 | Notice, that conditional expressions cannot be nested. | ||
118 | |||
119 | In addition to the format strings, the argument to the B<--format> option | ||
120 | can be any of the following predefined format names: | ||
121 | |||
122 | =over 4 | ||
123 | |||
124 | =item B<h> | ||
125 | |||
126 | =item B<c> | ||
127 | |||
128 | Produces a set of B<C> defines. It is equivalent to the following multi-line | ||
129 | format: | ||
130 | |||
131 | #define MU_GIT_COMMIT_HASH "$commit_hash" | ||
132 | #define MU_GIT_COMMIT_TIME "$commit_time" | ||
133 | #define MU_GIT_COMMIT_SUBJECT "$commit_subject" | ||
134 | {?$n>0??#define MU_GIT_COMMIT_DISTANCE $n | ||
135 | ?}#define MU_GIT_DESCRIBE_STRING "$describe{?$dirty??-dirty?}" | ||
136 | |||
137 | =item B<all> | ||
138 | |||
139 | This is the default format. It outputs all variables as B<I<NAME>="I<VALUE>"> | ||
140 | pairs, each pair on a separate line. Occurrences of B<"> and B<\> within | ||
141 | values are escaped by additional backslashes. | ||
142 | |||
143 | =back | ||
144 | |||
145 | =head1 OPTIONS | ||
146 | |||
147 | =over 4 | ||
148 | |||
149 | =item B<-C>, B<--directory=>I<DIR> | ||
150 | |||
151 | Use I<DIR> as the top-level source directory. By default it is determined | ||
152 | automatically, which works for as long as B<gitinfo.pl> is run from a | ||
153 | subdirectory of the git-controlled working tree. | ||
154 | |||
155 | =item B<-H>, B<--format>=I<FORMAT> | ||
156 | |||
157 | Select output format. See B<DESCRIPTION> for the details. | ||
158 | |||
159 | =item B<-o>, B<--output=>I<FILE> | ||
160 | |||
161 | Output results to the I<FILE>, instead of the standard output. | ||
162 | |||
163 | =item B<-s>, B<--stable> | ||
164 | |||
165 | Count versions from the most recent stable version. | ||
166 | |||
167 | =item B<-v>, B<--verbose> | ||
168 | |||
169 | Verbose output. | ||
170 | |||
171 | =item B<-h> | ||
172 | |||
173 | Display short help summary. | ||
174 | |||
175 | =item B<--help> | ||
176 | |||
177 | Display the manpage. | ||
178 | |||
179 | =item B<--usage> | ||
180 | |||
181 | Display command line usage summary. | ||
182 | |||
183 | =back | ||
184 | |||
185 | =cut | ||
186 | |||
187 | # find_commit(VERSION) | ||
188 | # Finds commit corresponding to the version number VERSION. | ||
189 | sub find_commit($) { | ||
190 | my $v = quotemeta(shift); | ||
191 | my $cmd = q{git log -S'^AC_INIT\(\[[^]]+\][[:space:]]*,[[:space:]]*\[} | ||
192 | . $v | ||
193 | . q{\]' --pickaxe-regex --reverse --pretty=format:%H -- configure.ac}; | ||
194 | open(my $fd, '-|', $cmd) | ||
195 | or die "$cmd: $!"; | ||
196 | my $s = <$fd>; | ||
197 | close $fd; | ||
198 | chomp $s; | ||
199 | return $s; | ||
200 | } | ||
201 | |||
202 | # find_count(VERSIN) | ||
203 | # Returns number of commits between VERSION and the current commit. | ||
204 | sub find_count($) { | ||
205 | my $v = shift; | ||
206 | my $cmd = "git rev-list --count $v..HEAD"; | ||
207 | open(my $fd, '-|', $cmd) or die "$cmd: $!"; | ||
208 | my $s = <$fd>; | ||
209 | close $fd; | ||
210 | chomp $s; | ||
211 | return $s; | ||
212 | } | ||
213 | |||
214 | # recent_version(STABLE) | ||
215 | # Returns the most recent version described in the NEWS file. | ||
216 | # If STABLE is true, returns the most recent stable version, i.e. | ||
217 | # the one, for which release date is set. | ||
218 | sub recent_version($) { | ||
219 | my ($stable) = @_; | ||
220 | my $file = 'NEWS'; | ||
221 | open(my $fd, '<', $file) or die "can't open $file: $!"; | ||
222 | my ($version, $date); | ||
223 | while (<$fd>) { | ||
224 | chomp; | ||
225 | if (/^(?:\*[[:space:]]+)? | ||
226 | [vV]ersion [[:space:]]+ | ||
227 | ([[:digit:]](?:[.,][[:digit:]]+){1,2}(?:[[:digit:]._-])*) | ||
228 | (?:(?:.*)[[:punct:]][[:space:]]* | ||
229 | ([[:digit:]]{4}-[[:digit:]]{2}-[[:digit:]]{2}))?/x) { | ||
230 | next if ($stable && !defined($2)); | ||
231 | ($version, $date) = ($1, $2); | ||
232 | last; | ||
233 | } | ||
234 | } | ||
235 | close $fd; | ||
236 | return ($version, $date); | ||
237 | } | ||
238 | |||
239 | # this_version() | ||
240 | # Returns a list (package, version). | ||
241 | sub this_version() { | ||
242 | my $file = 'configure.ac'; | ||
243 | open(my $fd, '<', $file) or die "can't open $file: $!"; | ||
244 | while (<$fd>) { | ||
245 | chomp; | ||
246 | return ($1, $2) if (/^AC_INIT\(\[(.+?)\]\s*,\s*\[(.+?)\].*/); | ||
247 | } | ||
248 | } | ||
249 | |||
250 | # git_describe($HASHREF) | ||
251 | # Define 'describe' and 'dirty' keys in $HASHREF | ||
252 | sub git_describe($) { | ||
253 | my ($href) = @_; | ||
254 | my $descr = `git describe`; | ||
255 | chomp $descr; | ||
256 | $href->{describe} = $descr; | ||
257 | if (`git diff-index --name-only HEAD 2>/dev/null`) { | ||
258 | $href->{dirty} = 1; | ||
259 | } | ||
260 | return $descr; | ||
261 | } | ||
262 | |||
263 | # last_commit_info($HASHREF) | ||
264 | # Populates %$HASHREF with entries describing the current commit. | ||
265 | sub last_commit_info { | ||
266 | my ($hashref) = @_; | ||
267 | my @names = qw(commit_hash commit_time commit_subject); | ||
268 | open(my $fd,'-|', | ||
269 | "git log --max-count=1 --pretty=format:'%H%n%ai%n%s' HEAD") | ||
270 | or die; | ||
271 | while (<$fd>) { | ||
272 | chomp; | ||
273 | my $name = shift @names; | ||
274 | last unless $name; | ||
275 | $hashref->{$name} = $_; | ||
276 | } | ||
277 | close $fd; | ||
278 | } | ||
279 | |||
280 | # Convert POD markup to the usage message suitable for --help and --usage | ||
281 | # output. | ||
282 | sub pod_usage_msg() { | ||
283 | my %args; | ||
284 | open my $fd, '>', \my $msg; | ||
285 | |||
286 | $args{-input} = pod_where({-inc => 1}, __PACKAGE__); | ||
287 | pod2usage(-verbose => 99, | ||
288 | -sections => 'NAME', | ||
289 | -output => $fd, | ||
290 | -exitval => 'NOEXIT', | ||
291 | %args); | ||
292 | my @a = split /\n/, $msg; | ||
293 | $msg = $a[1]; | ||
294 | $msg =~ s/^\s+//; | ||
295 | $msg =~ s/ - /: /; | ||
296 | return $msg; | ||
297 | } | ||
298 | |||
299 | my %gitinfo; | ||
300 | |||
301 | sub eval_format { | ||
302 | my ($format) = @_; | ||
303 | my @res; | ||
304 | while ($format) { | ||
305 | if ($format =~ /^(?<pfx>.*?)"(?<sfx>.*)$/s) { | ||
306 | push @res, eval_format($+{pfx}); | ||
307 | my $acc; | ||
308 | $format = $+{sfx}; | ||
309 | my $s = $format; | ||
310 | while ($s) { | ||
311 | if ($s =~ /^([^\\"]*?)\\"(.*)$/s) { | ||
312 | $acc .= $1 . '"'; | ||
313 | $s = $2; | ||
314 | } elsif ($s =~ /^(.*?)"(.*)$/s) { | ||
315 | $acc .= $1; | ||
316 | $format = $2; | ||
317 | last; | ||
318 | } else { | ||
319 | $acc = undef; | ||
320 | last; | ||
321 | } | ||
322 | } | ||
323 | if (defined($acc)) { | ||
324 | my $x = eval_format($acc); | ||
325 | $x =~ s/(["\\])/\\$1/g; | ||
326 | push @res, '"', $x, '"'; | ||
327 | } | ||
328 | } elsif ($format =~ /^(?<pfx>.*?) | ||
329 | \{\? | ||
330 | (?<cond>.+?) | ||
331 | \?\? | ||
332 | (?<iftrue>.+?) | ||
333 | (?:\?\|(?<iffalse>.*?))? | ||
334 | \?\}(?<sfx>.*)$/sx) { | ||
335 | |||
336 | my ($pfx, $cond, $iftrue, $iffalse, $sfx) = | ||
337 | ($+{pfx}, $+{cond}, $+{iftrue}, $+{iffalse}, $+{sfx}); | ||
338 | |||
339 | use Safe; | ||
340 | my $s = new Safe; | ||
341 | while (my ($k,$v) = each %gitinfo) { | ||
342 | ${$s->varglob($k)} = $v; | ||
343 | } | ||
344 | my $x = $s->reval($cond); | ||
345 | push @res, eval_format($pfx); | ||
346 | if ($x) { | ||
347 | push @res, eval_format($iftrue); | ||
348 | } else { | ||
349 | push @res, eval_format($iffalse); | ||
350 | } | ||
351 | $format = $sfx; | ||
352 | } elsif ($format =~ /^(?<pfx>.*?) | ||
353 | \$(?<ocb>{?) | ||
354 | (?<var>[a-zA-Z_][a-zA-Z_0-9]*) | ||
355 | (?<ccb>}?) | ||
356 | (?<sfx>.*)$/sx) { | ||
357 | my ($pfx, $ocb, $var, $ccb, $sfx) = | ||
358 | ($+{pfx}, $+{ocb}, $+{var}, $+{ccb}, $+{sfx}); | ||
359 | if ("$ocb$ccb" =~ /^(?:{})?$/) { | ||
360 | push @res, $pfx; | ||
361 | my $val = $gitinfo{$var} if defined $gitinfo{$var}; | ||
362 | #$val =~ s/(["\\])/\\$1/g if $odq; | ||
363 | push @res, $val; | ||
364 | $format = $sfx; | ||
365 | } else { | ||
366 | last; | ||
367 | } | ||
368 | } else { | ||
369 | last; | ||
370 | } | ||
371 | } | ||
372 | |||
373 | push @res, $format if $format; | ||
374 | |||
375 | return join('', @res); | ||
376 | } | ||
377 | |||
378 | my $from_stable; | ||
379 | my $verbose; | ||
380 | my $output; | ||
381 | my $format = 'all'; | ||
382 | |||
383 | my %fmtab = ( | ||
384 | c => <<'EOT' | ||
385 | #define MU_GIT_COMMIT_HASH "$commit_hash" | ||
386 | #define MU_GIT_COMMIT_TIME "$commit_time" | ||
387 | #define MU_GIT_COMMIT_SUBJECT "$commit_subject" | ||
388 | {?$n>0??#define MU_GIT_COMMIT_DISTANCE $n | ||
389 | ?}#define MU_GIT_DESCRIBE_STRING "$describe{?$dirty??-dirty?}" | ||
390 | EOT | ||
391 | , | ||
392 | 'h' => 'c', | ||
393 | 'all' => sub { | ||
394 | foreach my $name (sort keys %gitinfo) { | ||
395 | my $val = $gitinfo{$name}; | ||
396 | $val =~ s/(["\\])/\\$1/g; | ||
397 | print "$name=\"$val\"\n"; | ||
398 | } | ||
399 | } | ||
400 | ); | ||
401 | |||
402 | my $dir; | ||
403 | |||
404 | GetOptions("help" => sub { | ||
405 | pod2usage(-exitstatus => 0, -verbose => 2); | ||
406 | }, | ||
407 | "h" => sub { | ||
408 | pod2usage(-message => pod_usage_msg(), | ||
409 | -exitstatus => 0); | ||
410 | }, | ||
411 | "usage" => sub { | ||
412 | pod2usage(-exitstatus => 0, -verbose => 0); | ||
413 | }, | ||
414 | "directory|C=s" => \$dir, | ||
415 | "stable|s" => \$from_stable, | ||
416 | "verbose|v" => \$verbose, | ||
417 | "format|H=s" => \$format, | ||
418 | "output|o=s" => \$output | ||
419 | ) or exit(1); | ||
420 | |||
421 | if ($output) { | ||
422 | open(STDOUT, '>', $output) or die "can't open $output: $!" | ||
423 | } | ||
424 | |||
425 | if ($dir) { | ||
426 | chdir($dir) or die "can't change to $dir: $!"; | ||
427 | } elsif (! -d '.git') { | ||
428 | $dir = `git rev-parse --show-toplevel 2>/dev/null`; | ||
429 | chomp $dir; | ||
430 | chdir($dir) or die "can't change to $dir: $!"; | ||
431 | } | ||
432 | |||
433 | if (-d '.git') { | ||
434 | ($gitinfo{refversion}, my $date) = recent_version($from_stable); | ||
435 | $gitinfo{refdate} = $date if defined $date; | ||
436 | if ($verbose) { | ||
437 | print STDERR "# counting from version $gitinfo{refversion}"; | ||
438 | print STDERR ", released on $gitinfo{refdate}" | ||
439 | if exists $gitinfo{refdate}; | ||
440 | print STDERR "\n"; | ||
441 | } | ||
442 | |||
443 | $gitinfo{refcommit} = find_commit($gitinfo{refversion}); | ||
444 | print STDERR "# commit $gitinfo{refcommit}\n" | ||
445 | if $verbose; | ||
446 | my $n = find_count($gitinfo{refcommit}); | ||
447 | |||
448 | if ($n =~ /^[1-9][0-9]*$/) { | ||
449 | $gitinfo{n} = $n; | ||
450 | } | ||
451 | last_commit_info(\%gitinfo); | ||
452 | git_describe(\%gitinfo); | ||
453 | ($gitinfo{package}, $gitinfo{version}) = this_version; | ||
454 | } | ||
455 | |||
456 | $format = $fmtab{$format} while exists $fmtab{$format}; | ||
457 | if (ref($format) eq 'CODE') { | ||
458 | &{$format} | ||
459 | } else { | ||
460 | $format = "$format\n" unless $format =~ /\n$/s; | ||
461 | print eval_format($format); | ||
462 | } | ||
463 |
... | @@ -108,6 +108,6 @@ mu-setup.h: Makefile.am $(MODULES) $(IDLE_MODULES) | ... | @@ -108,6 +108,6 @@ mu-setup.h: Makefile.am $(MODULES) $(IDLE_MODULES) |
108 | $(AM_V_GEN)$(AWK) -f $(srcdir)/mu-setup.awk -v mode=h \ | 108 | $(AM_V_GEN)$(AWK) -f $(srcdir)/mu-setup.awk -v mode=h \ |
109 | $(MODULES) $(IDLE_MODULES) > mu-setup.h | 109 | $(MODULES) $(IDLE_MODULES) > mu-setup.h |
110 | 110 | ||
111 | mu-setup.c: Makefile.am $(MODULES) | 111 | mu-setup.c: Makefile.am $(MODULES) $(IDLE_MODULES) |
112 | $(AM_V_GEN)$(AWK) -f $(srcdir)/mu-setup.awk -v mode=c \ | 112 | $(AM_V_GEN)$(AWK) -f $(srcdir)/mu-setup.awk -v mode=c \ |
113 | $(MODULES) $(IDLE_MODULES) > mu-setup.c | 113 | $(MODULES) $(IDLE_MODULES) > mu-setup.c | ... | ... |
... | @@ -34,19 +34,10 @@ dnl | ... | @@ -34,19 +34,10 @@ dnl |
34 | m4_define([MUT_VERSION],[ | 34 | m4_define([MUT_VERSION],[ |
35 | AT_SETUP([$1 version]) | 35 | AT_SETUP([$1 version]) |
36 | 36 | ||
37 | AT_CHECK([$1 --version | sed '1{s/ *[\[.*\]]//;q;}' ], | 37 | AT_CHECK([$1 --version | sed ['1{s/-[0-9][0-9]* //;s/ *\[.*\]//;q;}'] ], |
38 | [0], | 38 | [0], |
39 | [$1 (AT_PACKAGE_NAME) AT_PACKAGE_VERSION | 39 | [$1 (AT_PACKAGE_NAME) AT_PACKAGE_VERSION |
40 | ], | 40 | ]) |
41 | [], | ||
42 | [cat >.xfailfile <<'_EOT' | ||
43 | |||
44 | ============================================================== | ||
45 | WARNING: Not using the proper version, *all* checks dubious... | ||
46 | ============================================================== | ||
47 | _EOT | ||
48 | ], | ||
49 | [rm -f $[]XFAILFILE]) | ||
50 | 41 | ||
51 | AT_CLEANUP | 42 | AT_CLEANUP |
52 | ]) | 43 | ]) | ... | ... |
-
Please register or sign in to post a comment