This is an automated email from the ASF dual-hosted git repository.

jimjag pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/openoffice-devtools.git


The following commit(s) were added to refs/heads/main by this push:
     new f11d3f3  Update the version upodater to handle both 4xx and 5xx bumps.
f11d3f3 is described below

commit f11d3f3cf6df7eda051d8aa6f06ad519128753f4
Author: Jim Jagielski <[email protected]>
AuthorDate: Tue Sep 1 15:40:17 2026 -0400

    Update the version upodater to handle both 4xx and 5xx bumps.
---
 updateVersion/README.md            |  59 +++++
 updateVersion/bump.pl              | 125 +++++----
 updateVersion/updateVersion.config |  92 +++++--
 updateVersion/updateVersion.sh     | 516 +++++++++++++++++++++----------------
 4 files changed, 503 insertions(+), 289 deletions(-)

diff --git a/updateVersion/README.md b/updateVersion/README.md
new file mode 100644
index 0000000..5eee15c
--- /dev/null
+++ b/updateVersion/README.md
@@ -0,0 +1,59 @@
+# updateVersion
+
+Version bookkeeping for an Apache OpenOffice source tree. Both scripts read the
+tree's current state and derive everything else, so the same commands are
+correct on any release branch (AOO41X, AOO50X, trunk, ...).
+
+## updateVersion.sh
+
+    updateVersion.sh [options] <version> [oo_path]
+
+Sets the product version everywhere it is recorded:
+
+| file | what it gets |
+| --- | --- |
+| `main/solenv/inc/minor.mk` | `RSCVERSION`, `RSCREVISION`, `BUILD`, 
`LAST_MINOR`, `SOURCEVERSION` |
+| `main/solenv/inc/version.lst` | major/minor/micro, and the release date with 
`--date` |
+| `main/sysui/desktop/productversion.mk` | `PRODUCTVERSION`, 
`PRODUCTVERSIONSHORT` |
+| `main/odk/util/makefile.pmk` | `PRODUCT_RELEASE` |
+| `main/solenv/bin/srcrelease.xml` | `aoo.ver` |
+| `main/setup_native/source/win32/nsis/downloadtemplate.nsi` | 
`VIProductVersion` |
+| `main/instsetoo_native/util/openoffice.lst` | the version, package, brand, 
service-tag, database-name and update-URL entries |
+
+Options: `-b/--build <n|keep>` (default: current `BUILD` + 1), `-m/--milestone
+<n>` (default 1), `-p/--previous <ver|none>`, `-d/--date <yyyy-mm-dd>`,
+`-c/--config <file>`, `-n/--dry-run`. Run the dry run first; it prints every
+line it would touch. Progress is also appended to 
`/tmp/updateVersion_<date>.log`.
+
+    ./updateVersion.sh -n 4.1.18 ../openoffice      # AOO41X
+    ./updateVersion.sh 5.0.1 ../openoffice          # AOO50X
+
+Values that differ per branch are handled by reading, not by assuming:
+
+* Component count is preserved, so `PRODUCTVERSION` in `productversion.mk`
+  stays `4.1.18` on AOO41X and `5.0` on AOO50X.
+* `RSCVERSION`/`SOURCEVERSION` are the version's digits joined: 4.1.18 ->
+  `4118`, 5.0.1 -> `501`.
+* Values that merely contain the version (`UPDATEURL`, `DATABASENAME`,
+  `SERVICETAG_*NAME`) are rewritten only where the version being replaced
+  actually appears, so AOO41X's `aoo4117` becomes `aoo4118` while AOO50X's
+  version-independent `aoonext` URLs are left alone.
+* `PREVIOUS_VERSION` is set to the version being replaced only when the bump
+  stays inside one release line; use `--previous` to set it across lines.
+
+`updateVersion.config` maps files to keys and rules; its header documents the
+format. Files a branch does not have are skipped.
+
+## bump.pl
+
+    bump.pl [oo_path]
+
+For the rebuilds between two version bumps: increments the build number and the
+milestone in `minor.mk` and the build field of `VIProductVersion` in
+`downloadtemplate.nsi`, leaving the product version alone.
+
+## Not covered
+
+Moving to a new major line (4.x -> 5.x) additionally changes install paths,
+SDK examples and extension min/max versions in a few dozen files (`openoffice4`
+-> `openoffice5` and friends). That is a one-off, done by hand.
diff --git a/updateVersion/bump.pl b/updateVersion/bump.pl
index 7d8f794..c212c1f 100755
--- a/updateVersion/bump.pl
+++ b/updateVersion/bump.pl
@@ -1,55 +1,86 @@
 #!/usr/bin/env perl
 #
-# Simple perl script to "bump" the build numbers in
-# AOO main/solenv/inc/minor.mk
+# Bump the build and milestone numbers of an AOO source tree, for the
+# rebuilds between two version bumps.  The product version is left
+# alone; use updateVersion.sh to change that.
 #
-# We assume the string RSCREVISION is *canon*!
+#   usage: bump.pl [oo_path]
 #
-use File::Slurp;
-
-my $build, $milestone;
-my $s1;
-my $s2;
-my $bumped;
-print "Looking for './main/solenv/inc/minor.mk'...";
-if ( -r "main/solenv/inc/minor.mk" && -w "main/solenv/inc/minor.mk") {
-    print "Good, we can read and write the file.\n";
-} else {
-    die "Error accessing file. Wrong perms or location.\n"
+# RSCVERSION in main/solenv/inc/minor.mk is canon, so the same script
+# serves any release branch (AOO41X, AOO50X, trunk, ...).
+
+use strict;
+use warnings;
+
+my $root = shift @ARGV;
+$root = "." unless defined $root;
+$root =~ s|/+$||;
+
+die "usage: $0 [oo_path]\n" if @ARGV;
+
+my $minor = "$root/main/solenv/inc/minor.mk";
+my $nsi   = "$root/main/setup_native/source/win32/nsis/downloadtemplate.nsi";
+
+die "$minor: not readable/writable. Wrong perms or location?\n"
+    unless -r $minor && -w $minor;
+
+my @lines = read_lines($minor);
+
+my ($rscversion) = map { /^RSCVERSION=(\S+)/ ? $1 : () } @lines;
+die "$minor: no RSCVERSION found\n" unless defined $rscversion;
+
+my ($milestone, $build);
+for (@lines) {
+    ($milestone, $build) = ($1, $2) if 
/^RSCREVISION=\Q$rscversion\Em(\d+)\(Build:(\d+)\)/;
+}
+die "$minor: no RSCREVISION matching RSCVERSION=$rscversion\n"
+    unless defined $build;
+
+my $new_milestone = $milestone + 1;
+my $new_build     = $build + 1;
+
+print "Version $rscversion: build $build -> $new_build, milestone m$milestone 
-> m$new_milestone\n";
+
+my $seen = 0;
+for (@lines) {
+    $seen++ if 
s/^RSCREVISION=\Q$rscversion\Em\d+\(Build:\d+\)\s*$/RSCREVISION=${rscversion}m${new_milestone}(Build:${new_build})\n/;
+    $seen++ if s/^BUILD=\d+\s*$/BUILD=${new_build}\n/;
+    $seen++ if s/^LAST_MINOR=m\d+\s*$/LAST_MINOR=m${new_milestone}\n/;
 }
-my @lines = read_file("main/solenv/inc/minor.mk");
-
-while (!$s1 || !$s2) {
-
-    foreach my $i (0 .. $#lines) {
-        if ($lines[$i] =~ /^RSCREVISION=\d+m(\d+).*Build:(\d+)\).*$/) {
-            if (!$bumped) {
-                print "Build was $2, now is ";
-                $build = $2 + 1;
-                print $build . "\n";
-                print "Milestone was $1, now is ";
-                $milestone = $1 + 1;
-                print $milestone . "\n";
-                $lines[$i] = "RSCREVISION=420m${milestone}(Build:${build})$/";
-                $bumped = 1;
-                print "Now:  $lines[$i]\n";
-            }
-        } elsif ($lines[$i] =~ /^BUILD=\d+$/) {
-            if ($bumped && !$s1) {
-                $lines[$i] = "BUILD=${build}$/";
-                $s1 = 1;
-                print "Updated BUILD  ";
-            }
-        } elsif ($lines[$i] =~ /^LAST_MINOR=m\d+$/) {
-            if ($bumped && !$s2) {
-                $lines[$i] = "LAST_MINOR=m${milestone}$/";
-                $s2 = 1;
-                print "Updated LAST_MINOR  ";
-            }
-        }
+die "$minor: expected RSCREVISION, BUILD and LAST_MINOR, found $seen of 3\n"
+    unless $seen == 3;
+
+write_lines($minor, \@lines);
+print "Updated $minor\n";
+
+# VIProductVersion carries the build number as its third field
+if (-r $nsi && -w $nsi) {
+    my @nsi_lines = read_lines($nsi);
+    my $hit = 0;
+    for (@nsi_lines) {
+        $hit++ if 
s/^(VIProductVersion\s+"\d+\.\d+\.)\d+(\.\d+")/$1${new_build}$2/;
     }
+    if ($hit) {
+        write_lines($nsi, \@nsi_lines);
+        print "Updated $nsi\n";
+    } else {
+        print "No VIProductVersion in $nsi, skipped\n";
+    }
+} else {
+    print "Not in this branch, skipped: $nsi\n";
 }
 
-print "\nWriting file...";
-write_file("main/solenv/inc/minor.mk", @lines);
-print "Done\n";
+sub read_lines {
+    my ($file) = @_;
+    open my $fh, "<", $file or die "$file: $!\n";
+    my @l = <$fh>;
+    close $fh;
+    return @l;
+}
+
+sub write_lines {
+    my ($file, $lines) = @_;
+    open my $fh, ">", $file or die "$file: $!\n";
+    print {$fh} @$lines;
+    close $fh or die "$file: $!\n";
+}
diff --git a/updateVersion/updateVersion.config 
b/updateVersion/updateVersion.config
index e994a68..095e718 100644
--- a/updateVersion/updateVersion.config
+++ b/updateVersion/updateVersion.config
@@ -1,20 +1,72 @@
---- file: productversion.mk
-PRODUCTVERSION
---- file: main/odk/util/makefile.pmk
-PRODUCT_RELEASE
---- file: srcrelease.xml
-aoo.ver
---- file: minor.mk
-RSCVERSION
-RSCREVISION=450m1(Build:9900)
-BUILD=9900
-LAST_MINOR=m1
-SOURCEVERSION=AOO450
---- file: openoffice.lst
-OOOPACKAGEVERSION
-UREPACKAGEVERSION
-PRODUCTVERSION
-ABOUTBOXPRODUCTVERSION
-BASEPRODUCTVERSION
-PACKAGEVERSION
-UPDATEURL
+# Version map for updateVersion.sh
+#
+# Section header:  file: <path below the source root>   syntax: mk|lst|xml|nsi
+#   mk   KEY = value            (minor.mk, version.lst, productversion.mk, 
makefile.pmk)
+#   lst  KEY<tab>value          (instsetoo_native/util/openoffice.lst)
+#   xml  <property name="KEY" value="..."/>
+#   nsi  KEY "value"
+#
+# Entry:  <KEY> <rule>
+#   full         x.y.z
+#   base         x.y
+#   major        x
+#   minor        y
+#   micro        z
+#   compact      xyz  (4.1.17 -> 4117, 5.0.1 -> 501)
+#   srcversion   AOOxyz
+#   rscrevision  xyzm<milestone>(Build:<build>)
+#   build        <build>
+#   lastminor    m<milestone>
+#   fileversion  x.y.<build>.500
+#   previous     the version being replaced (only with --previous or a 
same-branch bump)
+#   day/month/year   release date, only with --date
+#   keep         the new version at the component count the file already uses
+#   embed        rewrite the old version where it appears inside a larger 
string,
+#                and leave the value alone when it carries no version
+#
+# Keys absent from a branch are skipped, so one map serves AOO41X, AOO50X and 
trunk.
+
+file: main/solenv/inc/minor.mk   syntax: mk
+RSCVERSION      compact
+RSCREVISION     rscrevision
+BUILD           build
+LAST_MINOR      lastminor
+SOURCEVERSION   srcversion
+
+file: main/solenv/inc/version.lst   syntax: mk
+OOOBASEVERSIONMAJOR   major
+OOOBASEVERSIONMINOR   minor
+OOOBASEVERSIONMICRO   micro
+OOOBASEVERSIONDAY     day
+OOOBASEVERSIONMONTH   month
+OOOBASEVERSIONYEAR    year
+
+file: main/sysui/desktop/productversion.mk   syntax: mk
+PRODUCTVERSION        keep
+PRODUCTVERSIONSHORT   major
+
+file: main/odk/util/makefile.pmk   syntax: mk
+PRODUCT_RELEASE   full
+
+file: main/solenv/bin/srcrelease.xml   syntax: xml
+aoo.ver   full
+
+file: main/setup_native/source/win32/nsis/downloadtemplate.nsi   syntax: nsi
+VIProductVersion   fileversion
+
+file: main/instsetoo_native/util/openoffice.lst   syntax: lst
+OOOBASEVERSION              base
+OOOPACKAGEVERSION           full
+UREPACKAGEVERSION           full
+PRODUCTVERSION              full
+ABOUTBOXPRODUCTVERSION      full
+PACKAGEVERSION              full
+BASEPRODUCTVERSION          base
+SERVICETAG_PRODUCTVERSION   base
+BRANDPACKAGEVERSION         major
+USERDIRPRODUCTVERSION       major
+PREVIOUS_VERSION            previous
+SERVICETAG_PRODUCTNAME      embed
+SERVICETAG_PARENTNAME       embed
+DATABASENAME                embed
+UPDATEURL                   embed
diff --git a/updateVersion/updateVersion.sh b/updateVersion/updateVersion.sh
index fc0eba2..30328d3 100755
--- a/updateVersion/updateVersion.sh
+++ b/updateVersion/updateVersion.sh
@@ -1,249 +1,321 @@
 #!/usr/bin/env bash
 #-------------------------------------------------------------------
 #
-#              UPDATE VERSION FOR OO
+#              UPDATE VERSION FOR AOO
 #
-#   usage: updateVersion.sh <version> <oo_path>
+#   usage: updateVersion.sh [options] <version> [oo_path]
 #
-#   params:
-#           version - the version to update the files to
-#           oo_path - the path to the OO files 
+#   Sets the product version throughout an Apache OpenOffice source
+#   tree.  Every value is derived from <version> and from what the
+#   tree already contains, so the same invocation is correct on any
+#   release branch (AOO41X, AOO50X, trunk, ...).
 #
 #-------------------------------------------------------------------
-version=$1
-oo_path=$2
+set -u
 
-logfile=/tmp/updateVersion_$(date +%Y-%m-%d).log
+progname=$(basename "$0")
 configfile=$(dirname "$0")/updateVersion.config
+logfile=/tmp/updateVersion_$(date +%Y-%m-%d).log
+
+usage()
+{
+    cat <<EOF
+usage: ${progname} [options] <version> [oo_path]
+
+  <version>   x.y.z (or x.y, treated as x.y.0)
+  oo_path     source tree to update (default: current directory)
+
+options:
+  -b, --build <n|keep>   build number; default: current BUILD + 1
+  -m, --milestone <n>    milestone; default: 1
+  -p, --previous <ver>   value for PREVIOUS_VERSION; default: the version
+                         being replaced, when only the micro level changes
+  -d, --date <y-m-d>     release date for version.lst; default: leave as is
+  -c, --config <file>    version map (default: ${configfile})
+  -n, --dry-run          report the changes without writing anything
+  -h, --help             this text
+EOF
+}
+
+die()
+{
+    echo "${progname}: $*" >&2
+    exit 1
+}
+
+# --- options ------------------------------------------------------
+build_opt=""
+milestone=1
+previous_opt=""
+date_opt=""
+dryrun=0
+args=()
+
+while [ $# -gt 0 ]
+do
+    case "$1" in
+        -b|--build)     [ $# -ge 2 ] || die "$1 needs a value"; build_opt=$2; 
shift 2 ;;
+        -m|--milestone) [ $# -ge 2 ] || die "$1 needs a value"; milestone=$2; 
shift 2 ;;
+        -p|--previous)  [ $# -ge 2 ] || die "$1 needs a value"; 
previous_opt=$2; shift 2 ;;
+        -d|--date)      [ $# -ge 2 ] || die "$1 needs a value"; date_opt=$2; 
shift 2 ;;
+        -c|--config)    [ $# -ge 2 ] || die "$1 needs a value"; configfile=$2; 
shift 2 ;;
+        -n|--dry-run)   dryrun=1; shift ;;
+        -h|--help)      usage; exit 0 ;;
+        --)             shift; while [ $# -gt 0 ]; do args+=("$1"); shift; 
done ;;
+        -*)             usage >&2; die "unknown option $1" ;;
+        *)              args+=("$1"); shift ;;
+    esac
+done
 
-exec > >(tee -ia ${logfile}) 2>&1
-echo "***************************************************"
-echo "STARTED UPDATING VERSIONS $(date)"
-echo "***************************************************"
+[ ${#args[@]} -ge 1 ] || { usage >&2; exit 1; }
+[ ${#args[@]} -le 2 ] || { usage >&2; die "too many arguments"; }
 
-# validate params
-if [[ -z ${version} && -z ${oo_path} ]]
+version=${args[0]}
+oo_path=${args[1]:-.}
+
+case "${version}" in
+    *.*.*) ;;
+    *.*)   version=${version}.0 ;;
+esac
+echo "${version}" | grep -qE '^[0-9]+\.[0-9]+\.[0-9]+$' \
+    || die "invalid version '${args[0]}': expected x.y.z or x.y"
+
+new_x=$(echo "${version}" | cut -d. -f1)
+new_y=$(echo "${version}" | cut -d. -f2)
+new_z=$(echo "${version}" | cut -d. -f3)
+
+echo "${milestone}" | grep -qE '^[0-9]+$' || die "invalid milestone 
'${milestone}'"
+
+new_day=""; new_month=""; new_year=""
+if [ -n "${date_opt}" ]
 then
-    echo "Missing both version and OO path. Exiting..."
-    echo "***************************************************"
-    echo "FINISHED UPDATING VERSIONS $(date)"
-    echo "***************************************************"
-    exit
+    echo "${date_opt}" | grep -qE '^[0-9]{4}-[0-9]{1,2}-[0-9]{1,2}$' \
+        || die "invalid date '${date_opt}': expected yyyy-mm-dd"
+    new_year=$(echo "${date_opt}" | cut -d- -f1)
+    new_month=$(echo "${date_opt}" | cut -d- -f2 | sed 's/^0*\([0-9]\)/\1/')
+    new_day=$(echo "${date_opt}" | cut -d- -f3 | sed 's/^0*\([0-9]\)/\1/')
 fi
-if [[ -z ${version} ]]
-then
-    echo "Missing version. Exiting..."
+
+[ -d "${oo_path}/main" ] || die "${oo_path} does not contain a main subfolder"
+[ -r "${configfile}" ]   || die "${configfile} does not exist or is not 
readable"
+
+# --- the work, piped so the log is flushed before we exit ------------
+run()
+{
     echo "***************************************************"
-    echo "FINISHED UPDATING VERSIONS $(date)"
+    echo "STARTED UPDATING VERSIONS $(date)"
     echo "***************************************************"
-    exit
-else
-    if [[ ${version} =~ [^[:digit:].] ]]
+
+    # --- what the tree holds today ------------------------------------
+    minor_mk=${oo_path}/main/solenv/inc/minor.mk
+    oo_lst=${oo_path}/main/instsetoo_native/util/openoffice.lst
+
+    [ -r "${minor_mk}" ] || die "${minor_mk} not found; is ${oo_path} an AOO 
source tree?"
+    [ -r "${oo_lst}" ]   || die "${oo_lst} not found; is ${oo_path} an AOO 
source tree?"
+
+    old_compact=$(sed -nE 
's/^RSCVERSION[[:blank:]]*=[[:blank:]]*([0-9]+).*/\1/p' "${minor_mk}" | head -1)
+    old_build=$(sed -nE 's/^BUILD[[:blank:]]*=[[:blank:]]*([0-9]+).*/\1/p' 
"${minor_mk}" | head -1)
+    old_full=$(sed -nE 
's/^[[:blank:]]*PRODUCTVERSION[[:blank:]]+([0-9][0-9.]*).*/\1/p' "${oo_lst}" | 
head -1)
+
+    [ -n "${old_compact}" ] || die "no RSCVERSION found in ${minor_mk}"
+    [ -n "${old_build}" ]   || die "no BUILD found in ${minor_mk}"
+    [ -n "${old_full}" ]    || die "no PRODUCTVERSION found in ${oo_lst}"
+
+    old_x=$(echo "${old_full}" | cut -d. -f1)
+    old_y=$(echo "${old_full}" | cut -d. -f2)
+    old_z=$(echo "${old_full}" | cut -d. -f3)
+    [ -n "${old_z}" ] || old_z=0
+    old_base=${old_x}.${old_y}
+
+    if [ "${old_x}${old_y}${old_z}" != "${old_compact}" ]
     then
-        echo "Invalid version format. It should be in the form x or x.x or 
x.x.x, where x is either a digit or a number. Exiting..."
-        echo "***************************************************"
-        echo "FINISHED UPDATING VERSIONS $(date)"
-        echo "***************************************************"
-        exit
+        echo "WARNING: RSCVERSION (${old_compact}) does not match 
PRODUCTVERSION (${old_full})"
     fi
-fi
 
-# validate paths
-if [[ -z ${oo_path} ]]
-then
-    echo "Missing OO path, assuming current working directory. I will look 
here for files to modify..."
-    oo_path=.
-fi
-if [[ ! -d "${oo_path}/main" ]]
-then
-    echo "${oo_path} does not contain a main subfolder. Exiting..."
-    echo "***************************************************"
-    echo "FINISHED UPDATING VERSIONS $(date)"
-    echo "***************************************************"
-    exit
-fi
+    # --- build number -------------------------------------------------
+    case "${build_opt}" in
+        "")     new_build=$((old_build + 1)) ;;
+        keep)   new_build=${old_build} ;;
+        *[!0-9]*) die "invalid build '${build_opt}'" ;;
+        *)      new_build=${build_opt} ;;
+    esac
 
-# validate config file
-if [[ ! -r ${configfile} ]]
-then
-    echo "${configfile} either does not exist or is not readable. Exiting..."
-    echo "***************************************************"
-    echo "FINISHED UPDATING VERSIONS $(date)"
+    # --- PREVIOUS_VERSION ---------------------------------------------
+    # Only meaningful for a bump inside one release line; across lines
+    # (4.1.x -> 5.0.0) the previous release is not what the tree holds.
+    case "${previous_opt}" in
+        none) previous="" ;;
+        "")   if [ "${old_base}" = "${new_x}.${new_y}" ] && [ "${old_full}" != 
"${version}" ]
+              then
+                  previous=${old_full}
+              else
+                  previous=""
+              fi ;;
+        *)    previous=${previous_opt} ;;
+    esac
+
+    echo "source tree : ${oo_path}"
+    echo "old version : ${old_full} (RSCVERSION ${old_compact}, BUILD 
${old_build})"
+    echo "new version : ${version} (RSCVERSION ${new_x}${new_y}${new_z}, BUILD 
${new_build}, milestone m${milestone})"
+    if [ -n "${previous}" ]
+    then
+        echo "PREVIOUS_VERSION: ${previous}"
+    else
+        echo "PREVIOUS_VERSION: left unchanged"
+    fi
+    if [ -n "${date_opt}" ]
+    then
+        echo "release date: ${new_year}-${new_month}-${new_day}"
+    else
+        echo "release date: left unchanged"
+    fi
+    [ ${dryrun} -eq 1 ] && echo "DRY RUN - no files will be written"
     echo "***************************************************"
-    exit
-fi
 
-files=()
-patterns=()
-while read line
-do
-    if [[ ${line} == ---* ]]
+    # --- the editor ---------------------------------------------------
+    read -r -d '' editprog <<'PERL'
+BEGIN {
+    $key   = quotemeta $ENV{UV_KEY};
+    $rule  = $ENV{UV_RULE};
+    $syn   = $ENV{UV_SYNTAX};
+    ($X, $Y, $Z) = @ENV{qw(UV_X UV_Y UV_Z)};
+    $build = $ENV{UV_BUILD};
+    $ms    = $ENV{UV_MILESTONE};
+    $prev  = $ENV{UV_PREVIOUS};
+    ($ofull, $ocomp, $obase) = @ENV{qw(UV_OLD_FULL UV_OLD_COMPACT 
UV_OLD_BASE)};
+    ($day, $month, $year)    = @ENV{qw(UV_DAY UV_MONTH UV_YEAR)};
+    open($CH, '>>', $ENV{UV_CHANGES}) or die "cannot log changes: $!";
+}
+
+sub value {
+    my ($old) = @_;
+
+    # never touch a value that is a make/ant reference
+    return $old if $old =~ /[\$\{]/;
+
+    return "$X.$Y.$Z"                       if $rule eq 'full';
+    return "$X.$Y"                          if $rule eq 'base';
+    return $X                               if $rule eq 'major';
+    return $Y                               if $rule eq 'minor';
+    return $Z                               if $rule eq 'micro';
+    return "$X$Y$Z"                         if $rule eq 'compact';
+    return "AOO$X$Y$Z"                      if $rule eq 'srcversion';
+    return "$X$Y${Z}m$ms(Build:$build)"     if $rule eq 'rscrevision';
+    return $build                           if $rule eq 'build';
+    return "m$ms"                           if $rule eq 'lastminor';
+    return "$X.$Y.$build.500"               if $rule eq 'fileversion';
+    return ($prev ne '' ? $prev : $old)     if $rule eq 'previous';
+    return ($day   ne '' ? $day   : $old)   if $rule eq 'day';
+    return ($month ne '' ? $month : $old)   if $rule eq 'month';
+    return ($year  ne '' ? $year  : $old)   if $rule eq 'year';
+
+    if ($rule eq 'keep') {
+        return $old unless $old =~ /^(\d+)(?:\.(\d+))?(?:\.(\d+))?$/;
+        return defined $3 ? "$X.$Y.$Z" : defined $2 ? "$X.$Y" : $X;
+    }
+
+    if ($rule eq 'embed') {
+        my $new = $old;
+        $new =~ s/(?<!\d)\Q$ofull\E(?!\d)/$X.$Y.$Z/g;
+        $new =~ s/(?<!\d)\Q$ocomp\E(?!\d)/$X$Y$Z/g;
+        $new =~ s/(?<!\d)\Q$obase\E(?!\.?\d)/$X.$Y/g;
+        return $new;
+    }
+
+    die "unknown rule '$rule'\n";
+}
+
+sub replace {
+    my ($old) = @_;
+    my $new = value($old);
+    print $CH "$ENV{UV_FILE}:$.: $ENV{UV_KEY}: $old -> $new\n" if $new ne $old;
+    return $new;
+}
+
+if    ($syn eq 'mk')  { s{^([ \t]*$key[ \t]*=[ \t]*)(.*?)([ \t]*)$}{ $1 . 
replace($2) . $3 }e }
+elsif ($syn eq 'lst') { s{^([ \t]*$key)([ \t]+)(.*?)([ \t]*)$}{ $1 . $2 . 
replace($3) . $4 }e }
+elsif ($syn eq 'xml') { s{(name="$key"[ \t]+value=")([^"]*)(")}{ $1 . 
replace($2) . $3 }e }
+elsif ($syn eq 'nsi') { s{^([ \t]*$key[ \t]+")([^"]*)(")}{ $1 . replace($2) . 
$3 }e }
+else                  { die "unknown syntax '$syn'\n" }
+PERL
+
+    changes=$(mktemp "${TMPDIR:-/tmp}/updateVersion.XXXXXX")
+    trap 'rm -f "${changes}"' EXIT
+
+    apply()  # <file> <syntax> <key> <rule>
+    {
+        UV_FILE=$1 UV_SYNTAX=$2 UV_KEY=$3 UV_RULE=$4 \
+        UV_X=${new_x} UV_Y=${new_y} UV_Z=${new_z} \
+        UV_BUILD=${new_build} UV_MILESTONE=${milestone} 
UV_PREVIOUS=${previous} \
+        UV_OLD_FULL=${old_full} UV_OLD_COMPACT=${old_compact} 
UV_OLD_BASE=${old_base} \
+        UV_DAY=${new_day} UV_MONTH=${new_month} UV_YEAR=${new_year} \
+        UV_CHANGES=${changes} \
+        perl ${perl_inplace} -p -e "${editprog}" -- "$1" > /dev/null || die 
"failed while editing $1 (${3})"
+    }
+
+    if [ ${dryrun} -eq 1 ]
     then
-        filename=`echo ${line} | cut -d':' -f 2`
-        files+=("${filename:1}")
-        if [[ ! -z ${pattern} ]]
-        then
-            patterns+=("${pattern}")
-            pattern=""
-        fi
+        perl_inplace=""
     else
-        pattern=${pattern}" "${line}
+        perl_inplace="-i"
     fi
-done < ${configfile}
-patterns+=("${pattern}")
-
-# echo "***************************************************"
-# echo "found ${#files[@]} files and ${#patterns[@]} pattern groups"
-# for (( i=0; i<${#files[@]}; i++ ))
-# do
-#     echo "file: ${files[$i]}"
-#     echo "patterns: ${patterns[$i]}"
-# done
-
-echo "***************************************************"
-for (( i=0; i<${#files[@]}; i++ ))
-do
-    echo "*********************"
-    if [[ ${files[$i]} == */* ]]
-    then # files given as path, like odk/utils/makefile.pmk
-        filepath=`find ${oo_path} -path "*${files[$i]}"`
-    else # just the filename
-        filepath=`find ${oo_path} -type f -name ${files[$i]}`
-    fi    
-    if [[ -z ${filepath} ]]
+
+    # --- walk the version map -----------------------------------------
+    file=""
+    syntax=""
+    total=0
+
+    while IFS= read -r line || [ -n "${line}" ]
+    do
+        case "${line}" in
+            ""|\#*) continue ;;
+        esac
+
+        if echo "${line}" | grep -qE '^file:'
+        then
+            file=$(echo "${line}" | awk '{ for (i = 1; i < NF; i++) if ($i == 
"file:") print $(i + 1) }')
+            syntax=$(echo "${line}" | awk '{ for (i = 1; i < NF; i++) if ($i 
== "syntax:") print $(i + 1) }')
+            [ -n "${file}" ] && [ -n "${syntax}" ] || die "malformed section 
in ${configfile}: ${line}"
+            echo "*********************"
+            if [ -f "${oo_path}/${file}" ]
+            then
+                echo "updating file: ${oo_path}/${file}"
+            else
+                echo "not in this branch, skipping: ${file}"
+                file=""
+            fi
+            continue
+        fi
+
+        [ -n "${file}" ] || continue
+
+        key=$(echo "${line}" | awk '{print $1}')
+        rule=$(echo "${line}" | awk '{print $2}')
+        [ -n "${key}" ] && [ -n "${rule}" ] || die "malformed entry in 
${configfile}: ${line}"
+
+        before=$(wc -l < "${changes}" | tr -d " ")
+        apply "${oo_path}/${file}" "${syntax}" "${key}" "${rule}"
+        after=$(wc -l < "${changes}" | tr -d " ")
+
+        if [ "${before}" -eq "${after}" ]
+        then
+            echo "  ${key}: no change"
+        else
+            sed -n "$((before + 1)),${after}p" "${changes}" | sed 
"s|^${oo_path}/||;s/^/  /"
+        fi
+        total=$((after))
+    done < "${configfile}"
+
+    echo "***************************************************"
+    if [ ${dryrun} -eq 1 ]
     then
-        echo "File not found. Skipping..."
+        echo "${total} line(s) would change; nothing written (dry run)"
     else
-        declare -i nbrFilesFound
-        nbrFilesFound=`echo ${filepath} | grep -o "${files[$i]}" | wc -l`
-        readarray -t filepaths <<< "${filepath}"
-        for (( f=0; f<${nbrFilesFound}; f++ ))
-        do
-            filepath=${filepaths[$f]}
-            echo "**********"
-            echo "updating file: ${filepath}"
-            for j in ${patterns[$i]}
-            do
-                # TYPE I substitution: 
-                # -> the file is xml, we have name=<pattern> and 
value=<old_version>
-                # -> old_version will be updated
-                # -> ex. srcrelease.xml
-                if [[ ${files[$i]} == *.xml ]]
-                then
-                    readarray -t lines < <(grep -w ${j} ${filepath} | grep -v 
-e '{' -e '(')
-                    for (( s=0; s<${#lines[@]}; s++ ))
-                    do
-                        echo "line: ${lines[$s]}"
-                        newline=`echo ${lines[$s]} | gsed -E 
"s|(value=\")[0-9]+.?[0-9]*.?[0-9]*(\")|\1${version}\2|"`
-                        echo "newline: ${newline}"
-                        gsed -E -i 
"s|(value=\")[0-9]+.?[0-9]*.?[0-9]*(\")|\1${version}\2|" ${filepath}
-                        echo "**********"
-                    done
-                #
-                # TYPE II substitution:
-                # -> the pattern is in the form <pattern>=<new_value>
-                # -> replace the old value of <pattern> with the <new_value>
-                # -> ex. minor.mk
-                elif [[ $j == *=* ]]
-                then
-                    patt2brepl=`echo $j | cut -d'=' -f 1`
-                    patt2replWith=`echo $j | cut -d'=' -f 2`
-                    echo "pattern to be replaced: ${patt2brepl}"
-                    echo "pattern to replace with: ${patt2replWith}"
-                    if [[ ${patt2replWith} == *\(* && ${patt2replWith} == *\)* 
]]
-                    then
-                        replStr=`grep -w ${patt2brepl} ${filepath} | tr '(' 
'+'`
-                        replStr=`echo ${replStr} | tr ')' '+'`
-                        gsed -E -i "s/(.*)${patt2brepl}.*/\1${replStr}/" 
${filepath}
-                        echo "temporarily changing file contents replStr 
${replStr}"
-                    fi
-                    readarray -t lines < <(grep -w ${patt2brepl} ${filepath} | 
grep -v -e '{' -e '(')
-                    for (( s=0; s<${#lines[@]}; s++ ))
-                    do
-                        echo "line: ${lines[$s]}"
-                        newline=`echo ${lines[$s]} | gsed -E "s|(${patt2brepl} 
?=? ?)[a-zA-Z0-9]+.?[a-zA-Z0-9]*.?[a-zA-Z0-9]*[+]*|\1${patt2replWith}|"`
-                        echo "newline: ${newline}"
-                        gsed -E -i "s|(${patt2brepl} ?=? 
?)[a-zA-Z0-9]+.?[a-zA-Z0-9]*.?[a-zA-Z0-9]*[+]*|\1${patt2replWith}|" ${filepath}
-                        echo "**********"
-                    done
-                else
-                #
-                # TYPE III substitution:
-                # -> replace right-side pattern with new value
-                # -> ex. openoffice.lst
-                    readarray -t lines < <(grep -w ${j} ${filepath} | grep -v 
-e '{' -e '(')
-                    for (( s=0; s<${#lines[@]}; s++ ))
-                    do
-                        echo "line: ${lines[$s]}"
-                        line=`echo ${lines[$s]} | awk '{$1=$1};1'`
-                        patt2brepl=`echo ${line} | cut -d'=' -f 2`
-                        if [[ ${patt2brepl} == ${line} ]]
-                        then
-                            patt2brepl=`echo ${line} | cut -d' ' -f 2`
-                        fi
-                        
-                        # search inside words for patterns like aoo412 or 
AOO4.1.2
-                        insStrPatt=`echo ${patt2brepl} | egrep -w 
"[aA][oO][oO][0-9]+.?[0-9]*.?[0-9]*"`
-                        if [[ ${patt2brepl} == ${insStrPatt} ]]
-                        then
-                            partAOO=`echo ${patt2brepl} | gsed -E -n 
"s|.*([aA][oO][oO])[0-9]+.?[0-9]*.?[0-9]*[^a-zA-Z/].*|\1|p"`
-                            partVer=`echo ${patt2brepl} | gsed -E -n 
"s|.*([aA][oO][oO])([0-9]+.?[0-9]*.?[0-9]*[^a-zA-Z/]).*|\2|p"`
-                            patt2brepl=${partVer}
-                        fi
-                        echo "patt2brepl: [${patt2brepl}]"
-                        
-                        v0=`echo ${version} | cut -d'.' -f 1`
-                        if [[ ${v0} != ${version} ]]
-                        then
-                            v1=`echo ${version} | cut -d'.' -f 2`
-                            v2=`echo ${version} | cut -d'.' -f 3`
-                        fi
-                        
-                        p0=`echo ${patt2brepl} | cut -d'.' -f 1`
-                        p1=`echo ${patt2brepl} | cut -d'.' -f 2`
-                        p2=`echo ${patt2brepl} | cut -d'.' -f 3`
-                        
-                        if [[ ${p0} == ${patt2brepl} ]]  # right side is in 
the form x or xx (one or more numbers only)
-                        then
-                            declare -i nbr
-                            nbr=${#patt2brepl}
-                            if [[ ${nbr} -eq 1 ]]   # right side is just x
-                            then
-                                newline=`echo ${line} | gsed -E 
"s|(${partAOO})[0-9]+.?[0-9]*.?[0-9]*[^a-zA-Z/]|\1${v0}|"`
-                            else
-                                if [[ ${nbr} -eq 2 ]]   # right side is xx
-                                then
-                                    if [[ ${p0}+1 -eq ${v0} ]]  # right side + 
1 is version
-                                    then
-                                        newline=`echo ${line} | gsed -E 
"s|(${partAOO})[0-9]+.?[0-9]*.?[0-9]*[^a-zA-Z/]|\1${v0}|"`
-                                    else
-                                        newline=`echo ${line} | gsed -E 
"s|(${partAOO})[0-9]+.?[0-9]*.?[0-9]*[^a-zA-Z/]|\1${v0}${v1}|"`
-                                    fi
-                                else
-                                    newline=`echo ${line} | gsed -E 
"s|(${partAOO})[0-9]+.?[0-9]*.?[0-9]*[^a-zA-Z/]|\1${v0}${v1}${v2}|"`
-                                fi
-                            fi
-                        elif [[ -z ${p2} ]]  # right side is in the form x.x
-                            then
-                                if [[ -n ${v1} ]]
-                                then 
-                                    newline=`echo ${line} | gsed -E 
"s|(${partAOO})[0-9]+.?[0-9]*.?[0-9]*[^a-zA-Z/]|\1${v0}.${v1}|"`
-                                else
-                                    newline=`echo ${line} | gsed -E 
"s|(${partAOO})[0-9]+.?[0-9]*.?[0-9]*[^a-zA-Z/]|\1${version}|"`
-                                fi
-                            else
-                                newline=`echo ${line} | gsed -E 
"s|(${partAOO})[0-9]+.?[0-9]*.?[0-9]*[^a-zA-Z/]|\1${version}|"`
-                        fi
-                        
-                        echo "newline: ${newline}"
-                        echo "**********"
-                        gsed -E -i "s|${line}|${newline}|" ${filepath}
-                    done
-                fi
-            done
-      done
+        echo "${total} line(s) changed"
     fi
-done
-echo "***************************************************"
-echo "FINISHED UPDATING VERSIONS $(date)"
-echo "***************************************************"
+    echo "FINISHED UPDATING VERSIONS $(date)"
+    echo "***************************************************"
+}
+
+run 2>&1 | tee -a "${logfile}"
+exit ${PIPESTATUS[0]}

Reply via email to