blob: 5450da4f4f33879ab64824f516616ae01337198d [file] [log] [blame]
Zack Williams48542de2018-12-19 17:26:41 -07001#!/usr/bin/env bash
Joey Armstrongf32accb2024-03-07 17:05:09 -05002# -----------------------------------------------------------------------
3# Copyright 2018-2024 Open Networking Foundation Contributors
Zack Williams48542de2018-12-19 17:26:41 -07004#
5# Licensed under the Apache License, Version 2.0 (the "License");
6# you may not use this file except in compliance with the License.
7# You may obtain a copy of the License at
8#
Joey Armstrongf32accb2024-03-07 17:05:09 -05009# http:#www.apache.org/licenses/LICENSE-2.0
Zack Williams48542de2018-12-19 17:26:41 -070010#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS,
Joey Armstrongf32accb2024-03-07 17:05:09 -050013# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Zack Williams48542de2018-12-19 17:26:41 -070014# See the License for the specific language governing permissions and
15# limitations under the License.
Joey Armstrongf32accb2024-03-07 17:05:09 -050016# -----------------------------------------------------------------------
17# SPDX-FileCopyrightText: 2018-2024 Open Networking Foundation Contributors
18# SPDX-License-Identifier: Apache-2.0
19# -----------------------------------------------------------------------
20# Intent:
Zack Williams48542de2018-12-19 17:26:41 -070021# chart_version_check.sh
22# checks that changes to a chart include a change to the chart version
Joey Armstrongaebf1852022-12-09 08:34:13 -050023# ---------------------------------------------------------------------------
Zack Williams48542de2018-12-19 17:26:41 -070024
25set -u
Joey Armstrongaebf1852022-12-09 08:34:13 -050026# set -euo pipefail
Zack Williams48542de2018-12-19 17:26:41 -070027
Joey Armstrongaebf1852022-12-09 08:34:13 -050028##-------------------##
29##---] GLOBALS [---##
30##-------------------##
31declare -i -g force_fail=0
32declare -a -g error_stream=()
Zack Williams48542de2018-12-19 17:26:41 -070033
Joey Armstrongaebf1852022-12-09 08:34:13 -050034# declare -A -g ARGV=() # ARGV['debug']=1
35# declare -i -g debug=1 # uncomment to enable
Zack Williams48542de2018-12-19 17:26:41 -070036
Joey Armstrongf32accb2024-03-07 17:05:09 -050037##--------------------##
38##---] INCLUDES [---##
39##--------------------##
40{
41 declare pgm
42 pgm="$(realpath "${BASH_SOURCE[0]}")"
43 declare libdir="${pgm%.sh}"
44
45 # shellcheck source=chart_version_check/filter_files.sh
46 # shellcheck disable=SC1091
47 source "$libdir/filter_files.sh"
48}
49
Joey Armstrongaebf1852022-12-09 08:34:13 -050050## -----------------------------------------------------------------------
51## Intent: Display a program banner for logging
52## -----------------------------------------------------------------------
53# shellcheck disable=SC2120
54function banner()
55{
56 local program="${0##*/}"
Zack Williams48542de2018-12-19 17:26:41 -070057
Joey Armstrongaebf1852022-12-09 08:34:13 -050058 cat <<BANNER
Zack Williams48542de2018-12-19 17:26:41 -070059
Joey Armstrongaebf1852022-12-09 08:34:13 -050060# -----------------------------------------------------------------------
61# Running: ${program} $@
62# -----------------------------------------------------------------------
63# Now: $(date '+%Y-%m-%d %H:%M:%S')
64# Git: $(git --version)
65# -----------------------------------------------------------------------
Joey Armstrongb879cf82024-02-10 12:55:17 -050066# WORKSPACE: $(realpath "${WORKSPACE}")
67# WORKSPACE_BRANCH: $(git rev-parse --abbrev-ref HEAD)
Joey Armstrongaebf1852022-12-09 08:34:13 -050068# COMPARISON_BRANCH: ${COMPARISON_BRANCH}
Joey Armstrongaebf1852022-12-09 08:34:13 -050069# -----------------------------------------------------------------------
70BANNER
Zack Williams48542de2018-12-19 17:26:41 -070071
Joey Armstrongaebf1852022-12-09 08:34:13 -050072 return
73}
Zack Williams48542de2018-12-19 17:26:41 -070074
Joey Armstrongaebf1852022-12-09 08:34:13 -050075## -----------------------------------------------------------------------
Joey Armstrongf91c4372024-02-09 16:28:02 -050076## Intent: Augment a version string for display. If the given string
77## is empty rewrite to make that detail painfully obvious.
78## -----------------------------------------------------------------------
79function version_for_display()
80{
81 local -n ref=$1; shift
82
83 if [[ ${#ref} -eq 0 ]]; then
84 ref='?????????????????' # higlight the problem for reporting
85 fi
86 return
87}
88
89## -----------------------------------------------------------------------
90## Intent: Use git commands to retrieve chart version embedded within a file
91## -----------------------------------------------------------------------
92## Given:
93## ref Indirect var for version string return.
94## path Repository path to a Chart.yaml file
95## branch git branch to retrieve
96##
97## Return:
98## ref Extracted version string
99## -----------------------------------------------------------------------
100function get_version_by_git()
101{
102 local -n ref=$1 ; shift
103 local path="$1" ; shift
104 local branch="$1" ; shift
Joey Armstrongf32accb2024-03-07 17:05:09 -0500105
Joey Armstrongf91c4372024-02-09 16:28:02 -0500106 ref=''
107
108 # -----------------------------------------------------------------------
109 # cat "{branch}:{chart}" to stdout: (wanted => 'version : x.y.z')
110 # -----------------------------------------------------------------------
111 readarray -t buffer < <(\
112 git show "${branch}:${path}" \
113 | grep '^[[:blank:]]*version[[:blank:]]*:'\
114 )
115
Joey Armstrongf32accb2024-03-07 17:05:09 -0500116 # -----------------------------------------------------------------------
Joey Armstrongf91c4372024-02-09 16:28:02 -0500117 # Extract version string
Joey Armstrongf32accb2024-03-07 17:05:09 -0500118 # -----------------------------------------------------------------------
119 if [[ ${#buffer[@]} -gt 1 ]]; then
120 cat <<EOM
121
122** -----------------------------------------------------------------------
123** IAM: ${BASH_SOURCE[0]} (LINENO: ${LINENO})
124** CHART: $path
125** WARNING: Unable to identify chart version, multiple strings detected.
126** : Consider updating the lint tool to be aware of Chart.yaml
127** : record syntax so versions can be extracted for comparison.
128** -----------------------------------------------------------------------
129EOM
130 ## c_v_c.sh needs to be aware of Chart.yaml record syntax
131 ## so a version can be targeted.
132
133 # shellcheck disable=SC1003
134 declare -p buffer \
135 | tr '"' '\n' \
136 | grep '\.' \
137 | sed -e 's/^[[:blank:]]*//' \
138 | awk -F'\\' '{print " "$1}' \
139 | sort -nr
140 echo
141
142 ref='' # Highly forgiving (display only)
143 elif [[ ${#buffer[@]} -ne 1 ]]; then
Joey Armstrongf91c4372024-02-09 16:28:02 -0500144 ref='' # Highly forgiving (display only)
145 else
146 local raw="${buffer[0]}"
Joey Armstrongf91c4372024-02-09 16:28:02 -0500147 # Extract value, split on whitespace, colon, comment or quote
148 readarray -t fields < <(awk -F '[[:blank:]:#"]+' '{print $2}' <<<"$raw")
149 ref="${fields[0]}"
150 fi
151
152 return
153}
154
155## -----------------------------------------------------------------------
Joey Armstrongaebf1852022-12-09 08:34:13 -0500156## Intent: Display a log summary entry then exit with status.
157## -----------------------------------------------------------------------
158function summary_status_with_exit()
159{
160 local exit_code=$1; shift
161 local program="${0##*/}"
162 local summary=''
163 [[ $# -gt 0 ]] && { summary=" - $1"; shift; }
Zack Williams48542de2018-12-19 17:26:41 -0700164
Joey Armstrongaebf1852022-12-09 08:34:13 -0500165 ## -----------------------------------
166 ## status override courtesy of error()
167 ## -----------------------------------
168 declare -i -g force_fail
169 if [ $force_fail -eq 1 ]; then exit_code=$force_fail; fi
Zack Williams48542de2018-12-19 17:26:41 -0700170
Joey Armstrongaebf1852022-12-09 08:34:13 -0500171 ## --------------------------
172 ## Set summary display string
173 ## --------------------------
174 case "$exit_code" in
Joey Armstrong0476e912024-02-09 16:00:26 -0500175 0) status='PASS' ;;
176 *) status='FAIL' ;;
Joey Armstrongaebf1852022-12-09 08:34:13 -0500177 esac
178
179 [[ $# -gt 0 ]] && formatStream "$@"
180
181 echo
182 echo "[$status] ${program} ${summary}"
183
Joey Armstrongf91c4372024-02-09 16:28:02 -0500184 exit "$exit_code"
Joey Armstrongaebf1852022-12-09 08:34:13 -0500185}
186
187## -----------------------------------------------------------------------
188## Intent: Display an error and configure report summary_status as FAIL
189## -----------------------------------------------------------------------
190function error()
191{
192 declare -i -g force_fail=1
193 declare -a -g error_stream
194
195 # shellcheck disable=SC2124
196 local error="[ERROR] $@"
197 error_stream+=("$error")
198 echo "$error"
199 return
200}
201
202## -----------------------------------------------------------------------
203## Intent: Given a list (header and data) format contents as a log entry
204## -----------------------------------------------------------------------
205## Usage: displayList --banner "List of something" "${data_stream[@]}"
206## -----------------------------------------------------------------------
207function displayList()
208{
209 local indent=''
210 while [ $# -gt 0 ]; do
Joey Armstrong0476e912024-02-09 16:00:26 -0500211 local arg="$1"
212 case "$arg" in
213 -*banner) shift; echo "$1" ;;
214 -*indent) shift; indent="$1" ;;
215 -*tab-2) echo -n ' ' ;;
216 -*tab-4) echo -n ' ' ;;
217 -*tab-6) echo -n ' ' ;;
218 -*tab-8) echo -n ' ' ;;
219 -*newline) echo; ;;
220 -*tab) echo -n ' ' ;;
221 *) break ;;
222 esac
223 shift
Joey Armstrongaebf1852022-12-09 08:34:13 -0500224 done
225
226 for line in "$@";
227 do
Joey Armstrong0476e912024-02-09 16:00:26 -0500228 echo -e " ${indent}$line"
Joey Armstrongaebf1852022-12-09 08:34:13 -0500229 done
230 return
231}
232
233## -----------------------------------------------------------------------
234## Intent: Program init, provide defaults for globals, etc.
235## -----------------------------------------------------------------------
236function init()
237{
238 # when not running under Jenkins, use current dir as workspace
239 # o [TODO] - Perform a secondary username check to guard against a
240 # jenkins/bash env hiccup leaving WORKSPACE= temporarily undefined.
241 WORKSPACE=${WORKSPACE:-.}
242 COMPARISON_BRANCH="${COMPARISON_BRANCH:-opencord/master}"
243 return
244}
245
246## -----------------------------------------------------------------------
247## Intent: Remove quotes, whitespace & garbage from a string
248## -----------------------------------------------------------------------
249## ..seealso: https://www.regular-expressions.info/posixbrackets.html
250## -----------------------------------------------------------------------
251function filter_codes()
252{
253 declare -n val="$1"; shift # indirect
254 val="${val//[\"\'[:blank:][:cntrl:]]}" # [:punct:] contains hyphen
255 return
256}
257
258## -----------------------------------------------------------------------
259## Intent: Detect and report VERSION file changes
260## -----------------------------------------------------------------------
261## :param path: Path to a Chart.yaml file.
262## :type path: str
263##
264## :param branch: Comparsion baranch (?-remote-?)
265## :type branch: str
266##
267## :return: true if embedded version string was modified.
268## :rtype: int
269## -----------------------------------------------------------------------
270## ..note: What about change detection for: apiVersion, appVersion (?)
271## -----------------------------------------------------------------------
272function version_diff()
273{
274 local path="$1"; shift
275 local branch="$1"; shift
276
277 declare -n old_var="$1"; shift # indirect
278 declare -n new_var="$1"; shift # indirect
279
280 old_var=''
281 new_var=''
282 readarray -t delta < <(git diff -p "$branch" -- "$path")
283
284 local modified=0
285 if [ ${#delta[@]} -gt 0 ]; then # modified
286
Joey Armstrong0476e912024-02-09 16:00:26 -0500287 #----------------------------------------
288 # diff --git a/voltha-adapter-openolt/Chart.yaml [...]
289 # --- a/voltha-adapter-openolt/Chart.yaml
290 # +++ b/voltha-adapter-openolt/Chart.yaml
291 # @@ -14,7 +14,7 @@
292 # ---
293 # -version: "2.11.3" (====> 2.11.3)
294 # +version: "2.11.8" (====> 2.11.8)
295 #----------------------------------------
296 local line
297 for line in "${delta[@]}";
298 do
Joey Armstrong0476e912024-02-09 16:00:26 -0500299 case "$line" in
Eric Balled4451c2024-11-13 14:57:55 -0800300 -version*:*)
Joey Armstrong0476e912024-02-09 16:00:26 -0500301 modified=1
Eric Balled4451c2024-11-13 14:57:55 -0800302 readarray -t tmp <<< "${line#*: }"
Joey Armstrong0476e912024-02-09 16:00:26 -0500303 # shellcheck disable=SC2034
304 old_var="${tmp[0]}"
305 filter_codes 'old_var'
306 ;;
Eric Balled4451c2024-11-13 14:57:55 -0800307 +version*:*)
308 readarray -t tmp <<< "${line#*: }"
Joey Armstrong0476e912024-02-09 16:00:26 -0500309 # shellcheck disable=SC2034
310 new_var="${tmp[0]}"
311 filter_codes 'new_var'
312 ;;
313 esac
314 done
Joey Armstrongaebf1852022-12-09 08:34:13 -0500315 fi
316
317 [ $modified -ne 0 ] # set $? for if/then/elif use: "if version_diff; then"
318 return
319}
320
321## -----------------------------------------------------------------------
322## Intent: Gather a list of Chart.yaml files from the workspace.
323## -----------------------------------------------------------------------
324function gather_charts()
325{
326 declare -n varname="$1"; shift
327 readarray -t varname < <(find . -name 'Chart.yaml' -print)
Joey Armstrongf32accb2024-03-07 17:05:09 -0500328 filter_files varname
Joey Armstrongaebf1852022-12-09 08:34:13 -0500329
330 local idx
331 for (( idx=0; idx<${#varname[@]}; idx++ ));
332 do
Joey Armstrong0476e912024-02-09 16:00:26 -0500333 local val="${varname[idx]}"
334 if [ ${#val} -lt 2 ]; then continue; fi
Joey Armstrongaebf1852022-12-09 08:34:13 -0500335
Joey Armstrong0476e912024-02-09 16:00:26 -0500336 # Normalize: remove './' to support path comparison
337 if [[ "${val:0:2}" == './' ]]; then
338 varname[idx]="${val:2:${#val}}"
339 [[ -v debug ]] && echo "[$idx] ${varname[$idx]}"
340 fi
Joey Armstrongaebf1852022-12-09 08:34:13 -0500341 done
342
343 [[ -v debug ]] && declare -p varname
344 return
345}
346
347## -----------------------------------------------------------------------
348## Intent: Given a chart file and complete list of modified files
349## display a list of files modified in the chart directory.
350## -----------------------------------------------------------------------
351## :param chart: path to a Chart.yaml file
352## :type chart: str
353##
354## :param varname: A list files modified in a git sandbox.
355## :type varname: list, indirect
356## -----------------------------------------------------------------------
357function report_modified()
358{
359 local chart="$1"; shift
360 local dir="${chart%/*}"
361 # shellcheck disable=SC2178
362 declare -n varname="$1"; shift
363
364 ## ---------------------------------------------
365 ## Gather files contained in the chart directory
366 ## ---------------------------------------------
367 declare -a found=()
368 for val in "${varname[@]}";
369 do
Joey Armstrong0476e912024-02-09 16:00:26 -0500370 case "$val" in
Joey Armstrongf32accb2024-03-07 17:05:09 -0500371 *'/Chart.yaml') ;; # special case
Joey Armstrong0476e912024-02-09 16:00:26 -0500372 "${dir}"*) found+=("$val") ;;
373 esac
Joey Armstrongaebf1852022-12-09 08:34:13 -0500374 done
375
376 ## --------------------------------------------
377 ## Display results when modified files detected
378 ## --------------------------------------------
379 if [ ${#found[@]} -gt 0 ]; then
Joey Armstrong0476e912024-02-09 16:00:26 -0500380 declare -a stream=()
381 stream+=('--tab-4')
382 stream+=('--banner' "Files Changed: $dir")
383 stream+=('--tab-6') # really --tab-8
384 stream+=("${found[@]}")
385 displayList "${stream[@]}"
Joey Armstrongaebf1852022-12-09 08:34:13 -0500386 fi
387
388 [ ${#found[@]} -gt 0 ] # set $? for if/else
389 return
390}
391
392## -----------------------------------------------------------------------
393## Intent: Gather a list of Chart.yaml files from the workspace.
394## -----------------------------------------------------------------------
395declare -a -g charts=()
396declare -a -g changes_remote=()
397declare -a -g untracked_files=()
398function gather_state()
399{
400 local branch="$1"; shift
401
402 gather_charts 'charts'
403 [[ -v debug ]] && declare -p charts
404
405 readarray -t changes_remote < <(git diff --name-only "$branch")
Joey Armstrongf32accb2024-03-07 17:05:09 -0500406 filter_files changes_remote
Joey Armstrongaebf1852022-12-09 08:34:13 -0500407 [[ -v debug ]] && declare -p changes_remote
408
409 readarray -t untracked_files < <(git ls-files -o --exclude-standard)
Joey Armstrongf32accb2024-03-07 17:05:09 -0500410 filter_files untracked_files
Joey Armstrongaebf1852022-12-09 08:34:13 -0500411 [[ -v debug ]] && declare -p untracked_files
412
413 return
414}
415
416# shellcheck disable=SC1073
417##----------------##
418##---] MAIN [---##
419##----------------##
420init
421# shellcheck disable=SC2119
422banner
423gather_state "$COMPARISON_BRANCH"
424
425chart=''
426for chart in "${charts[@]}";
Zack Williams48542de2018-12-19 17:26:41 -0700427do
Joey Armstrongaebf1852022-12-09 08:34:13 -0500428 [[ -v debug ]] && echo -e "\nCHART: $chart"
Zack Williams48542de2018-12-19 17:26:41 -0700429
Joey Armstrongaebf1852022-12-09 08:34:13 -0500430 ## ---------------------------
431 ## Detect VERSION file changes
432 ## ---------------------------
433 declare -i chart_modified=0
434 old=''
435 new=''
436 if version_diff "$chart" "$COMPARISON_BRANCH" 'old' 'new'; then
Joey Armstrongf91c4372024-02-09 16:28:02 -0500437 version_for_display new
Joey Armstrong0476e912024-02-09 16:00:26 -0500438 suffix="($old => $new)" # display verion deltas in the right margin
439 printf '[CHART] %-60s %s\n' "$chart" "$suffix"
440 chart_modified=1
Zack Williams48542de2018-12-19 17:26:41 -0700441 else
Joey Armstrongf91c4372024-02-09 16:28:02 -0500442 if [[ ${#old} -eq 0 ]]; then
443 get_version_by_git old "$chart" "$COMPARISON_BRANCH"
444 fi
445 version_for_display old
Joey Armstrong0476e912024-02-09 16:00:26 -0500446 suffix="($old)"
447 printf '[CHART] %s\n' "$chart"
Joey Armstrongf91c4372024-02-09 16:28:02 -0500448 new="$old"
Zack Williams48542de2018-12-19 17:26:41 -0700449 fi
Zack Williams48542de2018-12-19 17:26:41 -0700450
Joey Armstrongaebf1852022-12-09 08:34:13 -0500451 ## -----------------------------------
452 ## Report modified files for the chart
453 ## -----------------------------------
454 declare -a combo_list=()
455 combo_list+=("${changes_remote[@]}")
456 combo_list+=("${untracked_files[@]}")
457 if report_modified "$chart" 'combo_list';
458 then
Joey Armstrong0476e912024-02-09 16:00:26 -0500459 if [ $chart_modified -eq 0 ]; then
Joey Armstrongf91c4372024-02-09 16:28:02 -0500460 version_for_display new
461 suffix="($old)"
462 error "Chart modified but version unchanged: ${chart} ${suffix}"
Joey Armstrong0476e912024-02-09 16:00:26 -0500463 fi
Joey Armstrongaebf1852022-12-09 08:34:13 -0500464 fi
Zack Williams48542de2018-12-19 17:26:41 -0700465
Joey Armstrongaebf1852022-12-09 08:34:13 -0500466done
467
468## ---------------------------
469## Report summary: local edits
470## ---------------------------
Joey Armstrong0f8656b2022-12-21 11:29:36 -0500471if [[ -x changes_remote ]] && [ ${#changes_remote} -gt 0 ]; then # local_edits
Joey Armstrongaebf1852022-12-09 08:34:13 -0500472 displayList \
Joey Armstrong0476e912024-02-09 16:00:26 -0500473 '--newline' \
474 '--banner' 'Changed Files:' \
475 "${changes_remote[@]}"
Zack Williams48542de2018-12-19 17:26:41 -0700476fi
477
Joey Armstrongaebf1852022-12-09 08:34:13 -0500478## -------------------------------
479## Report summary: untracked files
480## -------------------------------
Joey Armstrongb41d8cc2023-01-03 10:49:10 -0500481if [ ${#untracked_files[@]} -gt 0 ]; then
Joey Armstrongaebf1852022-12-09 08:34:13 -0500482 displayList \
Joey Armstrong0476e912024-02-09 16:00:26 -0500483 '--newline' \
484 '--banner' 'Untracked Files:' \
485 "${untracked_files[@]}"
Joey Armstrongaebf1852022-12-09 08:34:13 -0500486fi
Zack Williams48542de2018-12-19 17:26:41 -0700487
Joey Armstrongaebf1852022-12-09 08:34:13 -0500488## ---------------------------------
489## Report summary: problems detected
490## ---------------------------------
491declare -a -g error_stream
492if [ ${#error_stream[@]} -gt 0 ]; then
493 displayList \
Joey Armstrong0476e912024-02-09 16:00:26 -0500494 '--newline' \
495 '--banner' 'Error Sumamry:' \
496 "${error_stream[@]}"
Joey Armstrongaebf1852022-12-09 08:34:13 -0500497fi
Zack Williams48542de2018-12-19 17:26:41 -0700498
Joey Armstrongaebf1852022-12-09 08:34:13 -0500499summary_status_with_exit $?
500
501# -----------------------------------------------------------------------
502# Running: chart_version_check.sh
503# -----------------------------------------------------------------------
504# Now: 2022-12-09 03:10:52
505# Git: git version 2.34.1
506# -----------------------------------------------------------------------
507# COMPARISON_BRANCH: origin/master
508# WORKSPACE: .
509# -----------------------------------------------------------------------
510# [CHART] voltha-adapter-openolt/Chart.yaml (2.11.3 => 2.11.8)
511# [CHART] voltha-tracing/Chart.yaml
512# [CHART] voltha/Chart.yaml
513# Files Changed: voltha-tracing
514# voltha-tracing/values.yaml
515# [ERROR] Chart modified but version unchanged: voltha-tracing
516# [CHART] voltha/Chart.yaml
517# -----------------------------------------------------------------------
518
519# [SEE ALSO
520# ---------------------------------------------------------------------------
521# https://www.regular-expressions.info/posixbrackets.html (character classes)
522# ---------------------------------------------------------------------------