move subs from bottom to top, and add a vim and shebang line
[perl.git] / make_patchnum.pl
1 #!/usr/bin/perl
2 use strict;
3 use warnings;
4
5 =head1 NAME
6
7 make_patchnum.pl - make patchnum
8
9 =head1 SYNOPSIS
10
11 ...
12
13 =cut
14
15 BEGIN {
16     my $root=".";
17     while (!-e "$root/perl.c" and length($root)<100) {
18         if ($root eq '.') {
19                 $root="..";
20         } else {
21                 $root.="/..";
22             }
23     }
24     die "Can't find toplevel" if !-e "$root/perl.c";
25     sub path_to { "$root/$_[0]" } # use $_[0] if this'd be placed in toplevel.
26 }
27
28 sub read_file {
29     my $file = path_to(@_);
30     return "" unless -e $file;
31     open my $fh, '<', $file
32         or die "Failed to open for read '$file':$!";
33     return do { local $/; <$fh> };
34 }
35
36 sub write_file {
37     my ($file, $content) = @_;
38     $file= path_to($file);
39     open my $fh, '>', $file
40         or die "Failed to open for write '$file':$!";
41     print $fh $content;
42     close $fh;
43 }
44
45 sub backtick {
46     my $command = shift;
47     my $result = `$command`;
48     chomp $result;
49     return $result;
50 }
51
52 my $existing_patchnum = read_file('.patchnum');
53 my $existing_config   = read_file('lib/Config_git.pl');
54 my $existing_unpushed = read_file('unpushed.h');
55
56 my $unpushed_commits = '/*no-op*/';
57 my ($read, $branch, $snapshot_created, $commit_id, $describe);
58 my ($changed, $extra_info, $commit_title, $new_patchnum);
59 if (my $patch_file= read_file('.patch')) {
60     ($branch, $snapshot_created, $commit_id, $describe) = split /\s+/, $patchfile;
61     $extra_info = "git_snapshot_date='$snapshot_created'";
62     $commit_title = "Snapshot of:";
63 }
64 elsif (-d path_to('.git')) {
65     # git branch | awk 'BEGIN{ORS=""} /\*/ { print $2 }'
66     $branch = join "", map { (split /\s/, $_)[1] }
67               grep {/\*/} split /\n/, backtick('git branch');
68     my $remote;
69     if (length $branch) {
70         $remote = backtick("git config branch.$branch.remote");
71     }
72     $commit_id = backtick("git rev-parse HEAD");
73     $describe = backtick("git describe");
74     my $commit_created = backtick(qq{git log -1 --pretty="format:%ci"});
75     $new_patchnum = "describe: $describe";
76     $extra_info = "git_commit_date='$commit_created'";
77     if (length $branch && length $remote) {
78         # git cherry $remote/$branch | awk 'BEGIN{ORS=","} /\+/ {print $2}' | sed -e 's/,$//'
79         my $unpushed_commit_list =
80             join ",", map { (split /\s/, $_)[1] }
81             grep {/\+/} split /\n/, backtick("git cherry $remote/$branch");
82         # git cherry $remote/$branch | awk 'BEGIN{ORS="\t\\\\\n"} /\+/ {print ",\"" $2 "\""}'
83         $unpushed_commits =
84             join "", map { ',"'.(split /\s/, $_)[1].'"'."\t\\\n" }
85             grep {/\+/} split /\n/, backtick("git cherry $remote/$branch");
86         if (length $unpushed_commits) {
87             $commit_title = "Local Commit:";
88             my $ancestor = backtick("git rev-parse $remote/$branch");
89             $extra_info = "$extra_info
90 git_ancestor='$ancestor'
91 git_unpushed='$unpushed_commit_list'";
92         }
93     }
94     if (length $changed) {
95         $changed = 'true';
96         $commit_title =  "Derived from:";
97         $new_patchnum = "$new_patchnum
98 status: uncommitted-changes";
99     }
100     if (not length $commit_title) {
101         $commit_title = "Commit id:";
102     }
103 }
104
105 my $new_unpushed =<<"EOFTEXT";
106 /*********************************************************************
107 * WARNING: unpushed.h is automatically generated by make_patchnum.pl *
108 *          DO NOT EDIT DIRECTLY - edit make_patchnum.pl instead      *
109 *********************************************************************/
110 #define PERL_GIT_UNPUSHED_COMMITS       $unpushed_commits
111 /*leave-this-comment*/
112 EOFTEXT
113
114 my $new_config =<<"EOFDATA";
115 #################################################################
116 # WARNING: lib/Config_git.pl is generated by make_patchnum.pl   #
117 #          DO NOT EDIT DIRECTLY - edit make_patchnum.pl instead #
118 #################################################################
119 \$Config::Git_Data=<<'ENDOFGIT';
120 git_commit_id='$commit_id'
121 git_describe='$describe'
122 git_branch='$branch'
123 git_uncommitted_changes='$changed'
124 git_commit_id_title='$commit_title'
125 $extra_info
126 ENDOFGIT
127 EOFDATA
128
129 # only update the files if necessary, other build product depends on these files
130 if (( $existing_patchnum ne $new_patchnum ) || ( $existing_config ne $new_config ) || ( $existing_unpushed ne $new_unpushed )) {
131     print "Updating .patchnum and lib/Config_git.pl\n";
132     write_file('.patchnum', $new_patchnum);
133     write_file('lib/Config_git.pl', $new_config);
134     write_file('unpushed.h', $new_unpushed);
135 }
136 else {
137     print "Reusing .patchnum and lib/Config_git.pl\n"
138 }
139
140 # ex: set ts=4 sts=4 et ft=perl: