0

I have to use different keys based on the branch name. If the branch name starts with release/master need to use the prod keys. But this regex doesnot seem to work in this shell script.

echo copying firebase keys based on the branch name
branch=$(git branch | sed -n -e 's/^\* \(.*\)/\1/p')
mkdir firebase
chmod 777 firebase
release="^(master$|release\/\S+)"
if [[ $branch == $release ]];
then cp  $(pwd)/firebase_keys/prod/*  $(pwd)/firebase;
  echo "prod firebase keys used"
else cp  $(pwd)/firebase_keys/dev/*  $(pwd)/firebase;
  echo "dev firebase keys used"
fi
rohitwtbs
  • 509
  • 5
  • 17
  • Try switching the operator from `==` to `=~`, any better results? – Milag Aug 27 '20 at 13:37
  • nope the same results on changing to =~, – rohitwtbs Aug 27 '20 at 13:38
  • OK, may need to adjust the regex; please post an example value of `$branch` – Milag Aug 27 '20 at 13:48
  • 2
    Whatever you are hoping to accomplish, **`chmod 777` is *wrong* and *dangerous.*** You will want to revert to sane permissions ASAP (for your use case, probably `chmod 755` or perhaps `775`) and if you have had world writable system files on a public-facing system, at the very least investigate whether it could have been breached and used as a pivot point for breaking into your organization’s network. – tripleee Aug 27 '20 at 13:54
  • @tripleee it is just build thing for building the app with the respective keys. – rohitwtbs Aug 27 '20 at 14:02
  • @Milag branch can be someting like this master-develop-sync – rohitwtbs Aug 27 '20 at 14:08
  • This is not the place and the time for a discussion; but you are not convincing me that this is necessary or that you know what you are doing. Maybe post a separate question if you need help sanitizing that; feed free to ping me here. – tripleee Aug 27 '20 at 14:11

3 Answers3

2

Without using Bashisms:

if [ -n "$branch" ] && ! {
    [ "$branch" = "${branch#master}" ] &&
    [ "$branch" = "${branch#release}" ]
  }
then
  cp -- "$PWD/firebase_keys/prod/"* "$PWD/firebase"
  echo "prod firebase keys used"
else
  cp -- "$PWD/firebase_keys/dev/"* "$PWD/firebase"
  echo "dev firebase keys used"
fi

How it works:

"${branch#master}" removes the leading word master from the branch variable.

Lets say the branch is masterpiece:

  • "${branch#master}" would remove the leading master from masterpiecepiece

the [ "$branch" = "${branch#master}" ] comparison would translates into [ "masterpiece" = "piece" ] which is false, so it confirms that masterpiece starts with master.

So:

  • [ -n "$branch" ]: if the branch name is not empty
  • && !: AND NOT
  • {: Open grouping for the NOT condition statements
  • [ "$branch" = "${branch#master}" ]: the branch name does not start with master.
  • &&: AND
  • [ "$branch" = "${branch#release}" ]: the branch name does not start with release.
  • }: close the statements group
Léa Gris
  • 17,497
  • 4
  • 32
  • 41
1

There is =~ operator for bash regexp

re='^(master|release)'
if [[ $branch =~ $re ]];
then cp  $(pwd)/firebase_keys/prod/*  $(pwd)/firebase;
  echo "prod firebase keys used"
else cp  $(pwd)/firebase_keys/dev/*  $(pwd)/firebase;
  echo "dev firebase keys used"
fi

Update

re='^(master|release)'
[[ $branch =~ $re ]] && dir=prod || dir=dev
echo "$dir firebase keys used"
cp firebase_keys/$dir/* firebase/

Testing

test=(
    'asd master dvsdfc'
    'asf release sdflk '
    'master asdcal asdlk'
    'release sdddsfdf'
    'asfsf sdsd master'
    'asfasf sdfsdfrelease'
)

re='^(master|release)'
for string in "${test[@]}"; {
    [[ $string =~ $re ]] && printf "$string\tprod\n" || printf "$string\tdev\n"
}

Output

asd master dvsdfc       dev
asf release sdflk       dev
master asdcal asdlk     prod
release sdddsfdf        prod
asfsf sdsd master       dev
asfasf sdfsdfrelease    dev

Without regex

branch=${branch//master*}
branch=${branch//release*}
[[ $branch ]] && dir=dev || dir=prod
echo $dir
Ivan
  • 6,188
  • 1
  • 16
  • 23
1

Your regex has a few issues. Firstly, Bash doesn't support Perl extensions like \S. Secondly, harmlessly but revealingly, you don't need to escape the slash, because the slash character has no special significance in regular expressions. (There are some languages like Awk which use slashes as separators around regexes; then you do have to escape them. But Bash is not one of those languages.)

Anyway, especially if you are not very comfortable with regex, I would refactor to use a case statement instead. The syntax will seem alien at first if you are not already familiar with it, but I think you will find that this is actually quite readable, maintainable, and versatile (as well as portable to basic sh).

case $(git branch | sed -n 's/^\* \(.*\)/\1/p') in
  master/* | release/* )
    env='prod';;
  * )
    env='dev';;
esac
cp  ./firebase_keys/"$env"/*  ./firebase
echo "$env firebase keys used"

Notice also how the current working directory is already the default for any relative paths; there is basically never a need to use $(pwd) - or, in Bash, the more economical built-in variable $PWD - unless you specifically need to force absolute paths. (Perhaps see also Difference between ./ and ~/)

tripleee
  • 175,061
  • 34
  • 275
  • 318