11#! /bin/bash
2+ function usage {
3+ echo " Usage: $( basename " $0 " ) [-c] -f FILE_TO_CHANGE REPLACEMENT_FORMAT [-f FILE_TO_CHANGE REPLACEMENT_FORMAT ...]" 2>&1
4+ echo ' Synchronize files to latest version in source file'
5+ echo ' -s Specifies source file for version (default is CHANGELOG.md)'
6+ echo ' -f Specifies a file to change and the format for searching and replacing versions'
7+ echo ' FILE_TO_CHANGE is the file to be updated/checked for updates'
8+ echo ' REPLACEMENT_FORMAT is one of (semver, release, api-release)'
9+ echo ' semver indicates to look for a full semver version and replace with the latest full version'
10+ echo ' release indicates to look for a release semver version (x.x.x) and replace with the latest release version'
11+ echo ' api-release indicates to look for a release semver version in the context of an api route and replace with the latest release version'
12+ echo ' -c Compare versions and output proposed changes without changing anything.'
13+ }
214
3- CHECK=0
4- while getopts " :c" opt; do
15+ function getopts-extra () {
16+ declare i=1
17+ # if the next argument is not an option, then append it to array OPTARG
18+ while [[ ${OPTIND} -le $# && ${! OPTIND: 0: 1} != ' -' ]]; do
19+ OPTARG[i]=${! OPTIND}
20+ i+=1
21+ OPTIND+=1
22+ done
23+ }
24+
25+ # Parse input options
26+ declare CHECK=0
27+ declare SOURCE_FILE=" CHANGELOG.md"
28+ declare -a FILES_TO_CHECK=()
29+ declare -a REPLACEMENT_FORMATS=()
30+ declare args
31+ declare OPTIND OPTARG opt
32+ while getopts " :hcs:f:" opt; do
533 case $opt in
34+ h)
35+ usage
36+ exit 0
37+ ;;
638 c)
739 CHECK=1
840 ;;
41+ s)
42+ SOURCE_FILE=" $OPTARG "
43+ ;;
44+ f)
45+ getopts-extra " $@ "
46+ args=( " ${OPTARG[@]} " )
47+ # validate length of args, should be 2
48+ if [ ${# args[@]} -eq 2 ]; then
49+ FILES_TO_CHECK+=( " ${args[0]} " )
50+ REPLACEMENT_FORMATS+=( " ${args[1]} " )
51+ else
52+ echo " Exactly 2 arguments must follow -f option." >&2
53+ exit 1
54+ fi
55+ ;;
956 \? )
10- echo " Invalid option: -$OPTARG . Use -c to show changes without applying, use no options to apply changes." >&2
57+ echo " Invalid option: -$OPTARG ." >&2
58+ usage
1159 exit 1
1260 ;;
1361 esac
1462done
1563
16- # Version appearing earliest in CHANGELOGFILE will be used as ground truth.
17- CHANGELOGFILE=" CHANGELOG.md"
18- VERSIONFILE=" unstructured_inference/__version__.py"
64+ # Parse REPLACEMENT_FORMATS
1965RE_SEMVER_FULL=" (0|[1-9][0-9]*)\.(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)(-((0|[1-9][0-9]*|[0-9]*[a-zA-Z-][0-9a-zA-Z-]*)(\.(0|[1-9][0-9]*|[0-9]*[a-zA-Z-][0-9a-zA-Z-]*))*))?(\+([0-9a-zA-Z-]+(\.[0-9a-zA-Z-]+)*))?"
20- # Pull out semver appearing earliest in CHANGELOGFILE.
21- LAST_VERSION=$( grep -o -m 1 -E " ${RE_SEMVER_FULL} " " $CHANGELOGFILE " )
66+ RE_RELEASE=" (0|[1-9][0-9]*)\.(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)"
67+ RE_API_RELEASE=" v(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)"
68+ # Pull out semver appearing earliest in SOURCE_FILE.
69+ LAST_VERSION=$( grep -o -m 1 -E " ${RE_SEMVER_FULL} " " $SOURCE_FILE " )
70+ LAST_RELEASE=$( grep -o -m 1 -E " ${RE_RELEASE} ($|[^-+])" " $SOURCE_FILE " | grep -o -m 1 -E " ${RE_RELEASE} " )
71+ LAST_API_RELEASE=" v$( grep -o -m 1 -E " ${RE_RELEASE} ($|[^-+])$" " $SOURCE_FILE " | grep -o -m 1 -E " ${RE_RELEASE} " ) "
72+ declare -a RE_SEMVERS=()
73+ declare -a UPDATED_VERSIONS=()
74+ for i in " ${! REPLACEMENT_FORMATS[@]} " ; do
75+ REPLACEMENT_FORMAT=${REPLACEMENT_FORMATS[$i]}
76+ case $REPLACEMENT_FORMAT in
77+ semver)
78+ RE_SEMVERS+=( " $RE_SEMVER_FULL " )
79+ UPDATED_VERSIONS+=( " $LAST_VERSION " )
80+ ;;
81+ release)
82+ RE_SEMVERS+=( " $RE_RELEASE " )
83+ UPDATED_VERSIONS+=( " $LAST_RELEASE " )
84+ ;;
85+ api-release)
86+ RE_SEMVERS+=( " $RE_API_RELEASE " )
87+ UPDATED_VERSIONS+=( " $LAST_API_RELEASE " )
88+ ;;
89+ * )
90+ echo " Invalid replacement format: \" ${REPLACEMENT_FORMAT} \" . Use semver, release, or api-release" >&2
91+ exit 1
92+ ;;
93+ esac
94+ done
2295
2396if [ -z " $LAST_VERSION " ];
2497then
25- # No match to semver regex in CHANGELOGFILE , so no version to go from.
26- printf " Error: Unable to find latest version from %s.\n" " $CHANGELOGFILE "
98+ # No match to semver regex in SOURCE_FILE , so no version to go from.
99+ printf " Error: Unable to find latest version from %s.\n" " $SOURCE_FILE "
27100 exit 1
28101fi
29102
30- # Add files to this array that need to be kept in sync.
31- FILES_TO_CHANGE=(" $VERSIONFILE " )
32- # Add patterns to this array to be matched in the above files.
33- RE_SEMVERS=(" $RE_SEMVER_FULL " )
34- # Add versions to this array to be used as replacements for the patterns matched above from the corresponding files.
35- UPDATED_VERSIONS=(" $LAST_VERSION " )
103+ # Search files in FILES_TO_CHECK and change (or get diffs)
104+ declare FAILED_CHECK=0
36105
37- for i in " ${! FILES_TO_CHANGE [@]} " ; do
38- FILE_TO_CHANGE=${FILES_TO_CHANGE [$i]}
106+ for i in " ${! FILES_TO_CHECK [@]} " ; do
107+ FILE_TO_CHANGE=${FILES_TO_CHECK [$i]}
39108 RE_SEMVER=${RE_SEMVERS[$i]}
40109 UPDATED_VERSION=${UPDATED_VERSIONS[$i]}
41110 FILE_VERSION=$( grep -o -m 1 -E " ${RE_SEMVER} " " $FILE_TO_CHANGE " )
@@ -45,7 +114,7 @@ for i in "${!FILES_TO_CHANGE[@]}"; do
45114 printf " Error: No semver version found in file %s.\n" " $FILE_TO_CHANGE "
46115 exit 1
47116 else
48- # Replace semver in VERSIONFILE with semver obtained from CHANGELOGFILE
117+ # Replace semver in VERSIONFILE with semver obtained from SOURCE_FILE
49118 TMPFILE=$( mktemp /tmp/new_version.XXXXXX)
50119 # Check sed version, exit if version < 4.3
51120 if ! sed --version > /dev/null 2>&1 ; then
@@ -57,23 +126,29 @@ for i in "${!FILES_TO_CHANGE[@]}"; do
57126 if [ " $( printf ' %s\n' " $REQUIRED_VERSION " " $CURRENT_VERSION " | sort -V | head -n1) " != " $REQUIRED_VERSION " ]; then
58127 echo " sed version must be >= ${REQUIRED_VERSION} " && exit 1
59128 fi
60- sed -r " s/$RE_SEMVER /$UPDATED_VERSION /" " $FILE_TO_CHANGE " > " $TMPFILE "
129+ sed -E - r " s/$RE_SEMVER /$UPDATED_VERSION /" " $FILE_TO_CHANGE " > " $TMPFILE "
61130 if [ $CHECK == 1 ];
62131 then
63132 DIFF=$( diff " $FILE_TO_CHANGE " " $TMPFILE " )
64133 if [ -z " $DIFF " ];
65134 then
66- printf " version sync would make no changes.\n"
135+ printf " version sync would make no changes to %s .\n" " $FILE_TO_CHANGE "
67136 rm " $TMPFILE "
68- exit 0
69137 else
70- printf " version sync would make the following changes:\n%s\n" " $DIFF "
138+ FAILED_CHECK=1
139+ printf " version sync would make the following changes to %s:\n%s\n" " $FILE_TO_CHANGE " " $DIFF "
71140 rm " $TMPFILE "
72- exit 1
73141 fi
74142 else
75- cp " $TMPFILE " " $FILE_TO_CHANGE "
143+ cp " $TMPFILE " " $FILE_TO_CHANGE "
76144 rm " $TMPFILE "
77145 fi
78146 fi
79147done
148+
149+ # Exit with code determined by whether changes were needed in a check.
150+ if [ ${FAILED_CHECK} -ne 0 ]; then
151+ exit 1
152+ else
153+ exit 0
154+ fi
0 commit comments