1

I need a fairly portable way of manipulating semver values in a posix environment.

Specifically:
1. sorting, and
2. incrementing one of: major, minor, patch of a given semver value.

Etan Reisner
  • 77,877
  • 8
  • 106
  • 148
Mark Bolusmjak
  • 23,606
  • 10
  • 74
  • 129
  • [This question](http://stackoverflow.com/q/4023830/258523) has answers about sorting. Some of the components involved are re-usable for incrementing as well. – Etan Reisner Jul 09 '15 at 21:47

1 Answers1

2

If you've got bash, I imagine you could read semver values into arrays:

File

10.4.3
11.5
124.4.5
12

You can reprint them with space padding

$ deSemverize(){ while read line; do IFS=. read -a fields<<<"$line"; printf "%4d %4d %4d\n" ${fields[@]}; done ; }
$ deSemversize < File
#=>
  10    4    3
  11    5    0
 124    4    5
  12    0    0

and since ' ' < '0', you can sort the result lexically and it'll be as if you sorted first by MAJOR, then MINOR and then PATCH. You can then print the results as Semver values again:

$ semverize() { while read line; do read -a fields<<<"$line"; printf "%d.%d.%d\n" ${fields[@]}; done; }

$ deSemversize < File | sort | semverize
#=>   10.4.3
      11.5.0
      12.0.0
     124.4.5

As for modifying the fields, you can do standard bash arithmetics on numerical variables with (()) or $(()), e.g.:

echo "$((fields[0]+1))"

I would use a right-aligned Mask:

semverBump() {
  local mask=$1
  local dots_in_mask=${mask//[^.]/}
  case "$dots_in_mask" in
   "") mask=..$mask;;
   ".") mask=.$mask;;
  esac

  local maskarray
  IFS=. read -a maskarray<<<"$mask"

  while read line; 
  do IFS=. read -a fields<<<"$line"; 
    for((i=0;i<3;i++))
    do
      ((fields[$i]+=0))
      [[ -z "${maskarray[$i]}" ]] && continue

      if [[ "${maskarray[$i]}" =~ ^[+-].* ]]; then
        ((fields[$i]+=maskarray[$i]))
      else
        ((fields[$i]=maskarray[$i]))
      fi
    done
    printf "%d.%d.%d\n" ${fields[@]}
  done ;
}

E.g.:

   semverBump +2 < File  #increase all minor by 2
   semverBump 2 < File  #set all minor to two
   semverBump +1.-1.0 < File  #increment major, decrement minor, set  patch to zero
Petr Skocik
  • 58,047
  • 6
  • 95
  • 142