2

I wrote a script that replaces last 3 digits of a version number in a file containing a string in this format

"version-all:255.24.788"

There are 2 modes for the script: regular and advanced. Regular mode just makes the necessary changes, adds the files to git and commits them. Advanced version creates a branch to make those changes in, modifies the files, adds, commits, then returns to the original working branch.

I observe an odd behavior when running the script. The script works when ran first time, but when ran second time, it stops committing the results and tries to change the branch resulting in merge conflicts. I can't figure out why the script would only work odd number of times (first, third, fifth time) and when ran even number of times (second, fourth, sixth), fails.

I've tried changing the syntax of variables and replaced perl calls with a simple

echo "test" > file1.txt

for debugging purposes and it seems to work fine then. When adding perl commands back, the script seems to return to its odd behaviour.

#!/bin/bash
# This script replaces last 3 digits of a version number in a file
# There are 2 modes for the script
#   1. Regular - no flag needed, requires 1 argument: a version number
#   2. Advanced - flag "-a" needs to be used followed by 3 arguments: version number, push repo name, remote repo name.

advanced_script=false
version="none"

if [ "$1" = "-a" ] ; then
    advanced_script=true
fi

if [ "$advanced_script" = true ] ; then 
    if [ $# -ne 4 ] ; then
        echo -e "ERROR: Please supply the following 3 arguments and try again.\n" 
        echo -e "       1. New version number\n"
        echo -e "       2. Push repository name\n"
        echo -e "       3. Remote repository name\n"
        exit 1
    fi
    version="$2"
else
    if [ $# -ne 1 ] ; then
        echo -e "ERROR: Please supply version number and try again.\n"  
        exit 1
    fi 
    version="$1"
fi

old_version_full="version-all:255.24.788"
old_version=${old_version_full##*all:}
new_version=${old_version%.*}
new_version+=".${version}"

current_branch=$(git branch | grep \* | cut -d ' ' -f2)
commit_string="Bump the version to $version"

if [ "$advanced_script" = true ] ; then 
    local_branch="new_$version"
    remote_master="$4/master"
    git stash
    git checkout -b "$local_branch" "$remote_master"
fi 

perl -i -pe"s/${old_version}/${new_version}/g" file1.txt
perl -i -pe"s/${old_version}/${new_version}/g" file2.txt

git add file1.txt
git add file2.txt

git status

git commit -m "$commit_string"

if [ "$advanced_script" = true ] ; then 
    git push "$3"
    git checkout "$current_branch"
    git stash apply
fi
darknight
  • 53
  • 8
  • 1
    `git stash` will sometimes do nothing and not create any stash. If that's the case, your later `git stash apply` will apply some *other* stash, if there is one, or just fail; neither seems like a good idea. This is probably not related to the problem you're seeing, but maybe it is, it's hard to tell since you don't have a [mcve] here. – torek May 27 '19 at 20:21
  • 1
    Probably unrelated issue: `.` has special meaning in Perl regex, so your pattern doesn't match what you think it does. Fix that and the related code injection bugs as follows: `perl -i -spe's/\Q$o/$n/g' -- -o="$old_version" -n="$new_version" file1.txt` – ikegami May 27 '19 at 20:22
  • 1
    Tip: You can combine both calls to `perl`: `perl -i -spe's/\Q$o/$n/g' -- -o="$old_version" -n="$new_version" file1.txt file2.txt` – ikegami May 27 '19 at 20:39

1 Answers1

3

The problem was in regex pattern used in the perl call. Changing it the following line has solved the problem:

perl -i -spe's/\Q$o/$n/g' -- -o="$old_version" -n="$new_version" file1.txt file2.txt

Thanks @ikegami for the solution

darknight
  • 53
  • 8