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
|
=head1 NAME
make_patchnum.pl - make patchnum
=head1 SYNOPSIS
...
=cut
use strict;
use warnings;
no warnings 'uninitialized';
my $existing_patchnum = read_file('.patchnum');
my $existing_config = read_file('lib/Config_git.pl');
my $existing_unpushed = read_file('unpushed.h');
my $unpushed_commits = '/*no-op*/';
my ($read, $branch, $snapshot_created, $commit_id, $describe);
my ($changed, $extra_info, $commit_title, $new_patchnum);
if (-s path_to('.patch')) {
open my $fh, '<', path_to('.patch') or die "Failed to read .patch:$!";
($read, $branch, $snapshot_created, $commit_id, $describe) = map { chomp $_; $_ } <$fh>;
$changed = '';
$extra_info = "git_snapshot_date='$snapshot_created'";
$commit_title = "Snapshot of:";
}
elsif (-d path_to('.git')) {
# git branch | awk 'BEGIN{ORS=""} /\*/ { print $2 }'
$branch = join "", map { (split /\s/, $_)[1] }
grep {/\*/} split /\n/, backtick('git branch');
my $remote;
if (length $branch) {
$remote = backtick("git config branch.$branch.remote");
}
$commit_id = backtick("git rev-parse HEAD");
$describe = backtick("git describe --tags");
my $commit_created = backtick(qq{git log -1 --pretty="format:%ci"});
$new_patchnum = "describe: $describe";
$extra_info = "git_commit_date='$commit_created'";
if (length $branch && length $remote) {
# git cherry $remote/$branch | awk 'BEGIN{ORS=","} /\+/ {print $2}' | sed -e 's/,$//'
my $unpushed_commit_list =
join ",", map { (split /\s/, $_)[1] }
grep {/\+/} split /\n/, backtick("git cherry $remote/$branch");
# git cherry $remote/$branch | awk 'BEGIN{ORS="\t\\\\\n"} /\+/ {print ",\"" $2 "\""}'
$unpushed_commits =
join "", map { ',"'.(split /\s/, $_)[1].'"'."\t\\\n" }
grep {/\+/} split /\n/, backtick("git cherry $remote/$branch");
if (length $unpushed_commits) {
$commit_title = "Local Commit:";
my $ancestor = backtick("git rev-parse $remote/$branch");
$extra_info = "$extra_info
git_ancestor='$ancestor'
git_unpushed='$unpushed_commit_list'";
}
}
if (length $changed) {
$changed = 'true';
$commit_title = "Derived from:";
$new_patchnum = "$new_patchnum
status: uncommitted-changes";
}
if (not length $commit_title) {
$commit_title = "Commit id:";
}
}
my $new_unpushed =<<"EOFTEXT";
/*********************************************************************
* WARNING: unpushed.h is automatically generated by make_patchnum.pl *
* DO NOT EDIT DIRECTLY - edit make_patchnum.pl instead *
*********************************************************************/
#define PERL_GIT_UNPUSHED_COMMITS $unpushed_commits
/*leave-this-comment*/
EOFTEXT
my $new_config =<<"EOFDATA";
#################################################################
# WARNING: lib/Config_git.pl is generated by make_patchnum.pl #
# DO NOT EDIT DIRECTLY - edit make_patchnum.pl instead #
#################################################################
\$Config::Git_Data=<<'ENDOFGIT';
git_commit_id='$commit_id'
git_describe='$describe'
git_branch='$branch'
git_uncommitted_changes='$changed'
git_commit_id_title='$commit_title'
$extra_info
ENDOFGIT
EOFDATA
# only update the files if necessary, other build product depends on these files
if (( $existing_patchnum ne $new_patchnum ) || ( $existing_config ne $new_config ) || ( $existing_unpushed ne $new_unpushed )) {
print "Updating .patchnum and lib/Config_git.pl\n";
write_file('.patchnum', $new_patchnum);
write_file('lib/Config_git.pl', $new_config);
write_file('unpushed.h', $new_unpushed);
}
else {
print "Reusing .patchnum and lib/Config_git.pl\n"
}
sub path_to { "../$_[0]" } # use $_[0] if this'd be placed in toplevel.
sub read_file {
my $file = shift;
return unless -f path_to($file);
open my $fh, '<', path_to($file) or die "Failed to open $file:$!";
return do { local $/; <$fh> };
}
sub write_file {
my ($file, $content) = @_;
open my $fh, '>', path_to($file) or die "Failed to open $file:$!";
print $fh $content;
close $fh;
}
sub backtick {
my $command = shift;
my $result = `$command`;
chomp $result;
return $result;
}
|