summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYves Orton <demerphq@gmail.com>2008-12-31 01:16:23 +0100
committerYves Orton <demerphq@gmail.com>2008-12-31 01:16:23 +0100
commit46807d8e809cc127621bf85d9e9cea2f838eb477 (patch)
tree602775de59ea65c577768fe05bca20ec88388f00
parent675b0f774d374f6951c02c6463c64a746ad46acd (diff)
downloadperl-46807d8e809cc127621bf85d9e9cea2f838eb477.tar.gz
much better git related version numbering in our (*nix for now) build process
The net result of this patch is to make available via Config.pm and -v/-V the details about the git version info we have available for the build. When built within a git repository git is queried directly. When built from a snapshot or bundle it is assumed that the source is unchanged, and that the required details are avaialble in a file called .patch, whose format current is a four field string in the following format: "$branchname $date.$time $sha1 $describe". The generator of these files currently resides on camel.booking.com. * git-describe is now used more directly with -v. When the prefix of git-describe matches the version number as determined by the defines in patchlevel.h then we use ONLY the git-describe output, otherwise we include the git describe in parenthesis after the version number. Either way the describe text is optionally followed by a star should there be uncommitted changes. eg: This is perl, v5.11.0 (GitLive-blead-136-g58ca560) built for i686-linux or: This is perl, v5.11.0-1-g58ca560 built for i686-linux or: This is perl, v5.11.0 built for i686-linux * include the SHA1 in perl -V summary, and automatically include unpushed commits in the registered patches list * include various git/version/.patch details in %Config, as follows: git_commit_id # sha1 of HEAD git_ancestor # ancestor in $remote/$branch (presumably canonical) git_describe # git describe git_branch # current branch git_uncommitted_changes # "true" if there are any, empty otherwise git_unpushed_commits # List of sha1's of unpushed commits git_commit_id_title # Used to make the perl -V summary output Additionally one more value is added depending on build process used: when building from an rsynced snapshot (or any dist including a file called .patch) then the second field will be used to populate the "git_snapshot_date" field. Otherwise if built in a git directory (as is hopefully recommended these day) then the field will be "git_commit_date" which will be the commit date of HEAD. This patch introduces two new files (on top of .patchnum) that will be generated by make_patchnum.sh: "lib/Config_git.pl" and "unpushed.h", the former is used to make git data available to Config.pm/%Config without rebuilding everything else, and the second is used to expose unpushed commits (if any) via the registered patch facility of patchlevel.h
-rw-r--r--.gitignore1
-rw-r--r--Makefile.SH9
-rwxr-xr-xcflags.SH10
-rwxr-xr-xconfigpm19
-rw-r--r--install_lib.pl1
-rwxr-xr-xinstallperl2
-rw-r--r--lib/.gitignore1
-rw-r--r--make_patchnum.sh102
-rw-r--r--myconfig.SH1
-rw-r--r--patchlevel.h14
-rw-r--r--perl.c38
-rw-r--r--t/run/switches.t5
12 files changed, 149 insertions, 54 deletions
diff --git a/.gitignore b/.gitignore
index 4b430f9485..362fc7a319 100644
--- a/.gitignore
+++ b/.gitignore
@@ -5,6 +5,7 @@
# these are generated by make_patchnum.sh from git or from a .patchfile
.patchnum
.sha1
+unpushed.h
# ignore bug*.pl
bug*.pl
diff --git a/Makefile.SH b/Makefile.SH
index ff50cfd0d7..9ad8b6f102 100644
--- a/Makefile.SH
+++ b/Makefile.SH
@@ -371,7 +371,10 @@ CCCMD = `sh $(shellflags) cflags "optimize='$(OPTIMIZE)'" $@`
CCCMDSRC = `sh $(shellflags) cflags "optimize='$(OPTIMIZE)'" $<`
+# we dont include lib/Config_git.pl here, as it causes circular dependencies
CONFIGPM = lib/Config.pm lib/Config_heavy.pl
+# so we add it here:
+CONFIGPM_EXTRA = $(CONFIGPM) lib/Config_git.pl
CONFIGPOD = lib/Config.pod
@@ -540,7 +543,8 @@ sperl.i: perl.c $(h)
make_patchnum:
sh $(shellflags) make_patchnum.sh
-perl$(OBJ_EXT): .patchnum .sha1
+# make sure that we recompile perl.c if .patchnum changes
+perl$(OBJ_EXT): .patchnum unpushed.h
translators: miniperl$(EXE_EXT) $(CONFIGPM) FORCE
@echo " "; echo " Making x2p stuff"; cd x2p; $(LDLIBPTH) $(MAKE) all
@@ -1217,7 +1221,8 @@ _tidy:
-cd utils; $(LDLIBPTH) $(MAKE) clean
-cd x2p; $(LDLIBPTH) $(MAKE) clean
-rm .patchnum
- -rm .sha1
+ -rm lib/Config_git.pl
+ -rm unpushed.h
-@for x in $(DYNALOADER) $(dynamic_ext) $(static_ext) $(nonxs_ext) ; do \
$(LDLIBPTH) sh ext/util/make_ext clean $$x MAKE=$(MAKE) ; \
done
diff --git a/cflags.SH b/cflags.SH
index 6e6e8a950e..132f466a92 100755
--- a/cflags.SH
+++ b/cflags.SH
@@ -297,12 +297,12 @@ for file do
opmini) ;;
pad) ;;
perl)
- if [ -f .patchnum -a -n "$(cat .patchnum)" ] ; then
- ccflags="-DPERL_PATCHNUM=`cat .patchnum` $ccflags"
- fi
- if [ -f .sha1 -a -n "$(cat .sha1)" ] ; then
- ccflags="-DPERL_GIT_SHA1=`cat .sha1` $ccflags"
+ if [ -f .patchnum -a -n "$(awk 'BEGIN{ORS=""} /describe:/ {print $1}' .patchnum)" ] ; then
+ ccflags="-DPERL_PATCHNUM=$(awk 'BEGIN{ORS=""} /describe:/ {print $2}' .patchnum) $ccflags"
fi
+ if [ -f .patchnum -a -n "$(awk 'BEGIN{ORS=""} /status:/ {print $2}' .patchnum)" ] ; then
+ ccflags="-DPERL_GIT_UNCOMMITTED_CHANGES=$(awk 'BEGIN{ORS=""} /status:/ {print $2}' .patchnum) $ccflags"
+ fi
;;
perlapi) ;;
perlmain) ;;
diff --git a/configpm b/configpm
index d781b50c6c..af6f65a0c8 100755
--- a/configpm
+++ b/configpm
@@ -458,7 +458,19 @@ my $summary_expanded;
sub myconfig {
return $summary_expanded if $summary_expanded;
($summary_expanded = $summary) =~ s{\$(\w+)}
- { my $c = $Config::Config{$1}; defined($c) ? $c : 'undef' }ge;
+ {
+ my $c;
+ if ($1 eq 'git_ancestor_line') {
+ if ($Config::Config{git_ancestor}) {
+ $c= "\n Ancestor: $Config::Config{git_ancestor}";
+ } else {
+ $c= "";
+ }
+ } else {
+ $c = $Config::Config{$1};
+ }
+ defined($c) ? $c : 'undef'
+ }ge;
$summary_expanded;
}
@@ -535,6 +547,11 @@ foreach my $prefix (qw(libs libswanted)) {
$heavy_txt .= "EOVIRTUAL\n";
+$heavy_txt .= <<'ENDOFGIT';
+require 'Config_git.pl';
+$Config_SH_expanded .= $Config::Git_Data;
+ENDOFGIT
+
$heavy_txt .= $fetch_string;
$config_txt .= <<'ENDOFEND';
diff --git a/install_lib.pl b/install_lib.pl
index 7eeae1d33c..ae8ba0a990 100644
--- a/install_lib.pl
+++ b/install_lib.pl
@@ -29,6 +29,7 @@ OS
undef %Config::;
delete $INC{"Config.pm"};
delete $INC{"Config_heavy.pl"};
+ delete $INC{"Config_git.pl"};
# You never saw us. We weren't here.
require Config;
diff --git a/installperl b/installperl
index da8f45ee4a..d8d36be7d6 100755
--- a/installperl
+++ b/installperl
@@ -759,7 +759,7 @@ sub installlib {
if ($dir =~ /^auto/ ||
($name =~ /^(.*)\.(?:pm|pod)$/ && $archpms{$1}) ||
($name =~ /^(.*)\.(?:h|lib)$/i && ($Is_W32 || $Is_NetWare)) ||
- $name eq 'Config_heavy.pl'
+ $name=~/^Config_(heavy\|git)\.pl\z/
) {
$installlib = $installarchlib;
return unless $do_installarchlib;
diff --git a/lib/.gitignore b/lib/.gitignore
index e6facd30ef..0fa004e77b 100644
--- a/lib/.gitignore
+++ b/lib/.gitignore
@@ -4,6 +4,7 @@
/Config.pm
/Config.pod
/Config_heavy.pl
+/Config_git.pl
/DB_File.pm
/Data
/Devel/DProf.pm
diff --git a/make_patchnum.sh b/make_patchnum.sh
index 9a2f946b18..c9c74af683 100644
--- a/make_patchnum.sh
+++ b/make_patchnum.sh
@@ -1,35 +1,85 @@
#!/bin/sh
-. ./config.sh
+# this script is used to regenerate a number of special build files
+# based on either information contained in a file called .patch or
+# directly from git.
+# The files involved are:
+# .patchnum # information about the current checkout
+# lib/Config_git.pl # holds some special configure settings related to git
+# unpushed.h # header file used by patchlevel.h to store unpushed commits
-Existing=`cat .patchnum 2>/dev/null`
-Existing_Sha1=`cat .sha1 2>/dev/null`
+existing_patchnum=$(cat .patchnum 2>/dev/null)
+existing_config=$(cat lib/Config_git.pl 2>/dev/null)
+existing_unpushed=$(cat unpushed.h 2>/dev/null)
-if test -s ".patch" ; then
- Current=`awk '{print $4}' .patch`
- Sha1=`awk '{print $3}' .patch`
-elif test -d ".git" ; then
- # we should do something better here
- Current=`git describe`
- Sha1=`git rev-parse HEAD`
- Changed=`git diff-index --name-only HEAD`
- test -n "$Changed" && Current="$Current-with-uncommitted-changes"
-fi
+unpushed_commits='/*no-op*/'
+if [ -s ".patch" ] ; then
+ read branch snapshot_created commit_id describe < .patch
+ changed=""
+ extra_info="git_snapshot_date='$snapshot_created'"
+ commit_title='Snapshot of:'
+elif [ -d ".git" ]; then
+ branch=$(git branch | awk 'BEGIN{ORS=""} /\*/ { print $2 }')
+ test -n "$branch" && remote=$(git config branch.$branch.remote)
+ commit_id=$(git rev-parse HEAD)
+ changed=$(git diff-index --name-only HEAD)
+ describe=$(git describe --tags)
+ commit_created=$(git log -1 --pretty='format:%ci')
+ new_patchnum="describe: $describe"
+ extra_info="git_commit_date='$commit_created'"
+ if [ -n "$branch" ] && [ -n "$remote" ]; then
+ unpushed_commit_list=$(git cherry $remote/$branch | awk 'BEGIN{ORS=","} /+/ {print $2}' | sed -e 's/,$//')
+ unpushed_commits=$(git cherry $remote/$branch | awk 'BEGIN{ORS="\t\\\n"} /+/ {print ",\"" $2 "\""}')
-if test "$Existing" != "$Current" -o "$Existing_Sha1" != "$Sha1" ; then
- (echo "hi there\c" ; echo " ") >.echotmp
- if $contains c .echotmp >/dev/null 2>&1 ; then
- n='-n'
- c=''
- else
- n=''
- c='\c'
+ if [ -n "$unpushed_commits" ]; then
+ commit_title="Local Commit:"
+ ancestor=`git rev-parse $remote/$branch`
+ extra_info="$extra_info
+git_ancestor='$ancestor'
+git_unpushed='$unpushed_commit_list'"
+ fi
+
+ fi
+ if [ -n "$changed" ]; then
+ changed="true"
+ commit_title="Derived from:"
+ new_patchnum="$new_patchnum
+status: uncommitted-changes"
fi
- rm -f .echotmp
- echo "Updating .patchnum and .sha1"
- echo $n "$Current$c" > .patchnum
- echo $n "$Sha1$c" > .sha1
+ test -z "$commit_title" && commit_title='Commit id:'
+fi
+new_unpushed=$(cat <<EOFTEXT
+/*********************************************************************
+* WARNING: unpushed.h is automatically generated by make_patchnum.sh *
+* DO NOT EDIT DIRECTLY - edit make_patchnum.sh instead *
+*********************************************************************/
+#define PERL_GIT_UNPUSHED_COMMITS $unpushed_commits
+/*leave-this-comment*/
+EOFTEXT
+)
+new_config=$(cat <<EOFDATA
+#################################################################
+# WARNING: lib/Config_git.pl is generated by make_patchnum.sh #
+# DO NOT EDIT DIRECTLY - edit make_patchnum.sh 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" != "$new_patchnum" ] || [ "$new_config" != "$existing_config" ] || [ "$existing_unpushed" != "$new_unpushed" ]; then
+ echo "Updating .patchnum and lib/Config_git.pl"
+ echo "$new_patchnum" > .patchnum
+ echo "$new_config" > lib/Config_git.pl
+ echo "$new_unpushed" > unpushed.h
else
- echo "Reusing .patchnum and .sha1"
+ echo "Reusing .patchnum and lib/Config_git.pl"
fi
+
diff --git a/myconfig.SH b/myconfig.SH
index 3dfd9537c5..f5b432ad31 100644
--- a/myconfig.SH
+++ b/myconfig.SH
@@ -28,6 +28,7 @@ $startsh
# Note that the text lines /^Summary of/ .. /^\s*$/ are copied into Config.pm.
cat <<'!NO!SUBS!'
Summary of my $package (revision $revision $version_patchlevel_string) configuration:
+ $git_commit_id_title $git_commit_id$git_ancestor_line
Platform:
osname=$osname, osvers=$osvers, archname=$archname
uname='$myuname'
diff --git a/patchlevel.h b/patchlevel.h
index 391cb4126c..a17a6e679d 100644
--- a/patchlevel.h
+++ b/patchlevel.h
@@ -116,9 +116,21 @@ hunk.
*/
#if !defined(PERL_PATCHLEVEL_H_IMPLICIT) && !defined(LOCAL_PATCH_COUNT)
+#include "unpushed.h"
+#if !defined(PERL_GIT_UNPUSHED_COMMITS)
+#define PERL_GIT_UNPUSHED_COMMITS_PATCH /* no-op */
+#else
+#define PERL_GIT_UNPUSHED_COMMITS_PATCH PERL_GIT_UNPUSHED_COMMITS
+#endif
+#if !defined(PERL_GIT_UNCOMMITTED_CHANGES)
+#define PERL_GIT_UNCOMMITTED_CHANGES_PATCH /*no op*/
+#else
+#define PERL_GIT_UNCOMMITTED_CHANGES_PATCH , STRINGIFY(PERL_GIT_UNCOMMITTED_CHANGES)
+#endif
static const char * const local_patches[] = {
NULL
- ,"DEVEL"
+ PERL_GIT_UNPUSHED_COMMITS_PATCH /* do not remove this line */
+ PERL_GIT_UNCOMMITTED_CHANGES_PATCH /* do not remove this line */
,NULL
};
diff --git a/perl.c b/perl.c
index 7c5da008ad..d224ca6d1d 100644
--- a/perl.c
+++ b/perl.c
@@ -1904,7 +1904,6 @@ S_parse_body(pTHX_ char **env, XSINIT_t xsinit)
#else
sv_catpvs(opts_prog,"\"\\nCharacteristics of this binary (from libperl): \\n");
#endif
- sv_catpvs(opts_prog," Source revision: " STRINGIFY(PERL_GIT_SHA1) "\\n");
sv_catpvs(opts_prog," Compile-time options: $_\\n\",");
#if defined(LOCAL_PATCH_COUNT)
@@ -1914,16 +1913,8 @@ S_parse_body(pTHX_ char **env, XSINIT_t xsinit)
"\" Locally applied patches:\\n\",");
for (i = 1; i <= LOCAL_PATCH_COUNT; i++) {
if (PL_localpatches[i])
-#ifdef X_PERL_PATCHNUM
-/* this is ifdef'ed out, we would enable this if we want to transform
- "DEVEL" registered patches into the git name */
- if (strEQ(PL_localpatches[i],"DEVEL"))
- Perl_sv_catpvf(aTHX_ opts_prog,"q%c\t%s\n%c,",
- 0, STRINGIFY(PERL_PATCHNUM), 0);
- else
-#endif
- Perl_sv_catpvf(aTHX_ opts_prog,"q%c\t%s\n%c,",
- 0, PL_localpatches[i], 0);
+ Perl_sv_catpvf(aTHX_ opts_prog,"q%c\t%s\n%c,",
+ 0, PL_localpatches[i], 0);
}
}
#endif
@@ -3315,11 +3306,29 @@ Perl_moreswitches(pTHX_ const char *s)
if (!sv_derived_from(PL_patchlevel, "version"))
upg_version(PL_patchlevel, TRUE);
#if !defined(DGUX)
- PerlIO_printf(PerlIO_stdout(),
+ {
+ SV* level= vstringify(PL_patchlevel);
+#ifdef PERL_PATCHNUM
+ SV* num= newSVpvn(STRINGIFY(PERL_PATCHNUM),sizeof(STRINGIFY(PERL_PATCHNUM))-1);
+#ifdef PERL_GIT_UNCOMMITTED_CHANGES
+ sv_catpvf(num,"%s","*");
+#endif
+
+ if (sv_len(num)>=sv_len(level) && strnEQ(SvPV_nolen(num),SvPV_nolen(level),sv_len(level))) {
+ SvREFCNT_dec(level);
+ level= num;
+ } else {
+ sv_catpvf(level, " (%s)",SvPV_nolen(num));
+ SvREFCNT_dec(num);
+ }
+ #endif
+ PerlIO_printf(PerlIO_stdout(),
"\nThis is perl, %"SVf
" built for %s",
- SVfARG(vstringify(PL_patchlevel)),
+ level,
ARCHNAME);
+ SvREFCNT_dec(level);
+ }
#else /* DGUX */
/* Adjust verbose output as in the perl that ships with the DG/UX OS from EMC */
PerlIO_printf(PerlIO_stdout(),
@@ -3332,9 +3341,6 @@ Perl_moreswitches(pTHX_ const char *s)
Perl_form(aTHX_ " OS Specific Release: %s\n",
OSVERS));
#endif /* !DGUX */
-#if defined PERL_PATCHNUM
- PerlIO_printf(PerlIO_stdout(),"\nCompiled from: %s",STRINGIFY(PERL_PATCHNUM));
-#endif
#if defined(LOCAL_PATCH_COUNT)
if (LOCAL_PATCH_COUNT > 0)
PerlIO_printf(PerlIO_stdout(),
diff --git a/t/run/switches.t b/t/run/switches.t
index 0d91d8a810..a9e23ea196 100644
--- a/t/run/switches.t
+++ b/t/run/switches.t
@@ -260,10 +260,11 @@ SWTESTPM
{
local $TODO = ''; # these ones should work on VMS
-
+ # there are definitely known build configs where this test will fail
+ # DG/UX comes to mind. Maybe we should remove these special cases?
my $v = sprintf "%vd", $^V;
like( runperl( switches => ['-v'] ),
- qr/This is perl, v$v (?:DEVEL:[-A-Za-z0-9]+ )?built for \Q$Config{archname}\E.+Copyright.+Larry Wall.+Artistic License.+GNU General Public License/s,
+ qr/This is perl, v$v(?:[-\w]+| \([^)]+\))? built for \Q$Config{archname}\E.+Copyright.+Larry Wall.+Artistic License.+GNU General Public License/s,
'-v looks okay' );
}