diff --git a/objects.tar.gz b/objects.tar.gz index 9f0cb8185..4fcc882aa 100644 Binary files a/objects.tar.gz and b/objects.tar.gz differ diff --git a/sherpa-manager.tar.gz b/sherpa-manager.tar.gz index aa78fdb41..5b10991e3 100644 Binary files a/sherpa-manager.tar.gz and b/sherpa-manager.tar.gz differ diff --git a/support/sherpa-manager.source b/support/sherpa-manager.source index 429eb0de3..f6c86e9f3 100755 --- a/support/sherpa-manager.source +++ b/support/sherpa-manager.source @@ -219,6 +219,7 @@ LoadConsts() readonly r_report_qpkg_is_enabled_column_width=8 readonly r_report_qpkg_is_installed_column_width=10 readonly r_report_qpkg_is_managed_column_width=8 + readonly r_report_qpkg_is_plugin_column_width=11 readonly r_report_qpkg_max_os_version_column_width=8 readonly r_report_qpkg_min_os_version_column_width=8 readonly r_report_qpkg_min_ram_column_width=13 @@ -1316,43 +1317,77 @@ QPKGsAssignToActions() # 2. rebuild all (meta-action: `download`, `install` & `restore` QPKG, but only if package has an existing backup file) # 3. reassign all # 4. download all -# + # 5. stop/deactivate dependents # 6. disable-auto-update dependents # 7. backup dependents # 8. disable dependents # 9. uninstall dependents + +# 10. stop/deactivate plugins for dependents +# 11. disable-auto-update plugins for dependents +# 12. backup plugins for dependents +# 13. disable plugins for dependents +# 14. uninstall plugins for dependents + +# 15. stop/deactivate independents +# 16. disable-auto-update independents +# 17. backup independents +# 18. disable independents +# 19. uninstall independents # -# 10. stop/deactivate independents -# 11. disable-auto-update independents -# 12. backup independents -# 13. disable independents -# 14. uninstall independents -# -# 15. upgrade independents -# 16. reinstall independents -# 17. install independents -# 18. restore independents -# 19. enable-auto-update independents -# 20. clean independents -# 21. enable independents -# 22. restart/reactivate independents -# 23. start/activate independents -# -# 24. auxiliary packages (IPKs and PIPs) are managed here. -# -# 25. "sign" independents -# -# 26. upgrade dependents -# 27. reinstall dependents -# 28. install dependents -# 29. restore dependents -# 30. enable-auto-update dependents -# 31. clean dependents -# 32. "sign" dependents -# 33. enable dependents -# 34. restart/reactivate dependents -# 35. start/activate dependents +# 20. stop/deactivate plugins for independents +# 21. disable-auto-update plugins for independents +# 22. backup plugins for independents +# 23. disable plugins for independents +# 24. uninstall plugins for independents + +# 25. upgrade plugins for independents +# 26. reinstall plugins for independents +# 27. install plugins for independents +# 28. restore plugins for independents +# 29. enable-auto-update plugins for independents +# 30. clean plugins for independents +# 31. enable plugins for independents +# 32. restart/reactivate plugins for independents +# 33. start/activate plugins for independents + +# 34. upgrade independents +# 35. reinstall independents +# 36. install independents +# 37. restore independents +# 38. enable-auto-update independents +# 39. clean independents +# 40. enable independents +# 41. restart/reactivate independents +# 42. start/activate independents + +# 43. auxiliary packages (IPKs and PIPs) are managed here. + +# 44. "sign" plugins for independents +# 45. "sign" independents + +# 46. upgrade plugins for dependents +# 47. reinstall plugins for dependents +# 48. install plugins for dependents +# 49. restore plugins for dependents +# 50. enable-auto-update plugins for dependents +# 51. clean plugins for dependents +# 52. "sign" plugins for dependents +# 53. enable plugins for dependents +# 54. restart/reactivate plugins for dependents +# 55. start/activate plugins for dependents + +# 56. upgrade dependents +# 57. reinstall dependents +# 58. install dependents +# 59. restore dependents +# 60. enable-auto-update dependents +# 61. clean dependents +# 62. "sign" dependents +# 63. enable dependents +# 64. restart/reactivate dependents +# 65. start/activate dependents ProcActions() { @@ -4689,6 +4724,72 @@ DisplayAsIndentQuotedInfoItem() } +GenerateReportField() + { + + # Inputs: (global) + # $r_chars_alert + # $r_chars_attention + # $r_chars_blank + # $r_chars_normal + + # Inputs: (local) + # $1 = field text + # $2 (optional) = type of field prefix to generate ('attention', 'alert', 'blank', etc...) + + local a='' + local b='' + + case ${2:-blank} in + alert) + a=$(TextBrightRedBlink "$r_chars_alert") + b=$(TextBrightRedBlink "$1") + ;; + attention) + a=$(TextBrightOrange "$r_chars_attention") + b=$(TextBrightOrange "$1") + ;; + notice) + a=$(TextBrightRed "$r_chars_alert") + b=$(TextBrightRed "$1") + ;; + oops) + a=$r_chars_blank + b=$(TextBrightRed "$1") + ;; + normal) + a=$r_chars_normal + b=$1 + ;; + highlight) + a=$r_chars_blank + b=$(TextBrightOrange "$1") + ;; + highlight_ok) + a=$r_chars_blank + b=$(TextBrightGreen "$1") + ;; + normal_highlight) + a=$r_chars_normal + b=$(TextBrightGreen "$1") + ;; + mute) + a=$r_chars_blank + b=$(TextDarkGrey "$1") + ;; + normal_mute) + a=$(TextDarkGrey "$r_chars_normal") + b=$(TextDarkGrey "$1") + ;; + *) + a=$r_chars_blank + b=$1 + esac + + printf '%s' "${a}${b}" + + } + GeneratePacksReportTitleLine() { @@ -4826,28 +4927,43 @@ _GenerateStatusReportDataLine_() # Inputs: (global) # $qpkg_name - local action='' - local action_msg=$r_chars_blank - local app_ver=$(QpkgGetDatabaseApplVer) - local app_ver_msg=$r_chars_blank + local a='' + local -a column_vars=(action app_ver name path status ver) local mode='' local -i n=0 - local name_msg=$r_chars_blank - local path=$(QpkgGetInstalledPath) - local path_msg=$r_chars_blank local result='' - local status='' - local status_msg=$r_chars_normal - local ver=$(QpkgGetInstalledVer) - local ver_msg=$r_chars_blank + local req_alert=false + local req_attention=false + local req_oops=false + + # Init field messages. + + for a in "${column_vars[@]}"; do + local ${a}=false + local ${a}_msg='' + done + + app_ver=$(QpkgGetDatabaseApplVer) + name=$qpkg_name + path=$(QpkgGetInstalledPath) + ver=$(QpkgGetInstalledVer) + + # Set display mode. if QpkgIsInstalledMissing; then mode=missing + /bin/touch "$r_report_flags_path"/status-missing elif QpkgIsInstalled; then mode=normal + /bin/touch "$r_report_flags_path"/state-installed else - mode=mute - QpkgIsReallyInstalled && QpkgIsNtInstalledAuthorOk && mode=author + if QpkgIsReallyInstalled && QpkgIsNtInstalledAuthorOk; then + mode=author + /bin/touch "$r_report_flags_path"/status-wrongauthor + else + mode=mute + /bin/touch "$r_report_flags_path"/state-notinstalled + fi fi case $app_ver in @@ -4856,20 +4972,18 @@ _GenerateStatusReportDataLine_() esac case $mode in - missing|normal) + missing|mute|normal) if QpkgIsDatabaseSherpaCompatible; then action=$(QpkgGetInstalledServiceAction) /bin/touch "$r_report_flags_path"/action-$action if [[ $action = not-found ]]; then if OsIsStartingPackages && QpkgIsInstalledEnabled; then - action_msg+=$(TextBrightOrange pending) + action=$(TextBrightOrange pending) /bin/touch "$r_report_flags_path"/action-pending else - action_msg+=$(TextDarkGrey not-found) + action=$(TextDarkGrey not-found) fi - else - action_msg+=$action fi result=$(QpkgGetInstalledServiceResult) @@ -4877,142 +4991,132 @@ _GenerateStatusReportDataLine_() case $result in aborted|failed) - action_msg+=' '$(Parenthesise "$(TextBrightRed "$result")") + action+=' '$(Parenthesise "$(TextBrightRed "$result")") ;; in-progress) - action_msg+=' '$(Parenthesise "$(TextBrightOrange "$result")") + action+=' '$(Parenthesise "$(TextBrightOrange "$result")") ;; ok) - action_msg+=' '$(Parenthesise "$(TextBrightGreen "$(Uppercase "$result")")") + action+=' '$(Parenthesise "$(TextBrightGreen "$(Uppercase "$result")")") esac else action=unsupported /bin/touch "$r_report_flags_path"/action-unsupported - action_msg+=$(TextDarkGrey "$action") + action=$(TextDarkGrey "$action") fi ;; *) - action=N/A /bin/touch "$r_report_flags_path"/na esac case $mode in author) - /bin/touch "$r_report_flags_path"/status-wrongauthor - /bin/touch "$r_report_flags_path"/na - - # Set field values. app_ver=N/A - status='incompatible author' + action=N/A ver=N/A + /bin/touch "$r_report_flags_path"/na - # Assign field messages. - action_msg+=$action - app_ver_msg+=$app_ver - name_msg+=$qpkg_name - path_msg+=$path - status_msg=${r_chars_attention}${status} - ver_msg+=$ver - - # Highlight field messages. - action_msg=$(TextBrightOrange "$action_msg") - app_ver_msg=$(TextBrightOrange "$app_ver_msg") - name_msg=$(TextBrightOrange "$name_msg") - path_msg=$(TextBrightOrange "$path_msg") - status_msg=$(TextBrightOrange "$status_msg") - ver_msg=$(TextBrightOrange "$ver_msg") + for a in "${column_vars[@]}"; do + case $a in + name) + : # Do nothing, this is set later. + ;; + status) + status_msg=$(GenerateReportField 'incompatible author' attention) + req_attention=true + ;; + *) + local ${a}_msg="$(GenerateReportField "${!a}" highlight)" + esac + done ;; missing) - /bin/touch "$r_report_flags_path"/status-missing - - # Set field values. - status=missing - - # Assign field messages. - app_ver_msg+=$app_ver - name_msg+=$qpkg_name - path_msg+=$path - status_msg=${r_chars_alert}${status} - ver_msg+=$ver - - # Highlight field messages. - app_ver_msg=$(TextBrightRed "$app_ver_msg") - name_msg=$(TextBrightRed "$name_msg") - path_msg=$(TextBrightRedBlink "$path_msg") - status_msg=$(TextBrightRedBlink "$status_msg") - ver_msg=$(TextBrightRed "$ver_msg") + for a in "${column_vars[@]}"; do + case $a in + action) + local ${a}_msg="$(GenerateReportField "${!a}")" + ;; + name) + : # Do nothing, this is set later. + ;; + status) + status_msg=$(GenerateReportField missing alert) + ;; + *) + local ${a}_msg="$(GenerateReportField "${!a}" oops)" + req_oops=true + esac + done ;; mute) - /bin/touch "$r_report_flags_path"/state-notinstalled - /bin/touch "$r_report_flags_path"/na - - # Set field values. path=N/A + /bin/touch "$r_report_flags_path"/na if ! QpkgIsDatabaseArchOK; then - status+='incompatible architecture' + status='incompatible architecture' elif ! QpkgIsDatabaseMinOSVerOk || ! QpkgIsDatabaseMaxOSVerOk; then - status+='incompatible '$(OsGetQnapOS) + status='incompatible '$(OsGetQnapOS) elif ! QpkgIsDatabaseMinRAMOk; then - status+='insufficient RAM installed' + status='insufficient RAM installed' else - status+='not installed' + status='not installed' fi ver=$(QpkgGetDatabaseVer "$qpkg_name") - # Assign field messages. - action_msg+=$action - app_ver_msg+=$app_ver - name_msg+=$qpkg_name - path_msg+=$path - status_msg+=$status - ver_msg+=$ver - - # Highlight field messages. - action_msg=$(TextDarkGrey "$action_msg") - app_ver_msg=$(TextDarkGrey "$app_ver_msg") - name_msg=$(TextDarkGrey "$name_msg") - path_msg=$(TextDarkGrey "$path_msg") - status_msg=$(TextDarkGrey "$status_msg") - ver_msg=$(TextDarkGrey "$ver_msg") + for a in "${column_vars[@]}"; do + case $a in + name) + : # Do nothing, this is set later. + ;; + status) + status_msg=$(GenerateReportField "$status" normal_mute) + ;; + *) + local ${a}_msg="$(GenerateReportField "${!a}" mute)" + esac + done ;; - normal) - /bin/touch "$r_report_flags_path"/state-installed - - # Set field values. - - # Assign highlighting earlier than-usual as each status can have a different highlight. + *) + for a in "${column_vars[@]}"; do + case $a in + name) + : # Do nothing, this is set later. + ;; + status) + if QPKGs-ISenabled.Exist "$qpkg_name"; then + status_msg+=' '$(TextBrightGreen enabled) + /bin/touch "$r_report_flags_path"/state-enabled + else + status_msg+=' '$(TextBrightRed disabled) + /bin/touch "$r_report_flags_path"/state-disabled + fi - if QPKGs-ISenabled.Exist "$qpkg_name"; then - status+=' '$(TextBrightGreen enabled) - /bin/touch "$r_report_flags_path"/state-enabled - else - status+=' '$(TextBrightRed disabled) - /bin/touch "$r_report_flags_path"/state-disabled - fi + if QPKGs-ISactive.Exist "$qpkg_name"; then + status_msg+=' '$(TextBrightGreen active) + /bin/touch "$r_report_flags_path"/status-active + elif QPKGs-ISslow.Exist "$qpkg_name"; then + status_msg+=' '$(TextBrightOrange slow) + /bin/touch "$r_report_flags_path"/status-slow + elif QPKGs-ISNTactive.Exist "$qpkg_name"; then + status_msg+=' '$(TextBrightRed inactive) + /bin/touch "$r_report_flags_path"/status-inactive + else + status_msg+=' '$(TextBrightOrange unknown) + /bin/touch "$r_report_flags_path"/status-unknown + fi - if QPKGs-ISactive.Exist "$qpkg_name"; then - status+=' '$(TextBrightGreen active) - /bin/touch "$r_report_flags_path"/status-active - elif QPKGs-ISslow.Exist "$qpkg_name"; then - status+=' '$(TextBrightOrange slow) - /bin/touch "$r_report_flags_path"/status-slow - elif QPKGs-ISNTactive.Exist "$qpkg_name"; then - status+=' '$(TextBrightRed inactive) - /bin/touch "$r_report_flags_path"/status-inactive - else - status+=' '$(TextBrightOrange unknown) - /bin/touch "$r_report_flags_path"/status-unknown - fi + if QPKGs-ISupgradable.Exist "$qpkg_name"; then + status_msg+=' '$(TextBrightOrange upgradable) + fi - # Assign field messages. - app_ver_msg+=$app_ver - name_msg+=$qpkg_name - path_msg+=$path - status_msg+=$(AddSeparators "$status") - ver_msg+=$ver + status_msg=$(GenerateReportField "$(AddSeparators "$status_msg")" normal) + ;; + *) + local ${a}_msg="$(GenerateReportField "${!a}")" + esac + done esac if QPKGs-ISupgradable.Exist "$qpkg_name"; then @@ -5020,6 +5124,21 @@ _GenerateStatusReportDataLine_() /bin/touch "$r_report_flags_path"/status-upgradable fi + if [[ $req_alert = true ]]; then + /bin/touch "$r_report_flags_path"/req-alert + name_msg=$(GenerateReportField "$name" alert) + elif [[ $req_attention = true ]]; then + /bin/touch "$r_report_flags_path"/req-attention + name_msg=$(GenerateReportField "$name" attention) + elif [[ $req_oops = true ]]; then + /bin/touch "$r_report_flags_path"/req-attention + name_msg=$(GenerateReportField "$name" oops) + elif [[ $mode = mute ]]; then + name_msg=$(GenerateReportField "$name" mute) + else + name_msg=$(GenerateReportField "$name") + fi + if OsIsSupportAutowidthTableColumns; then printf '%s' "$name_msg|$status_msg|$action_msg|$ver_msg|$app_ver_msg|$path_msg" else @@ -5062,10 +5181,6 @@ _GenerateReposReportDataLine_() # Inputs: (global) # $qpkg_name - # $r_chars_alert - # $r_chars_attention - # $r_chars_blank - # $r_chars_normal # $r_report_column_spacing # $r_report_flags_path # $r_report_qpkg_install_date_column_width @@ -5075,15 +5190,21 @@ _GenerateReposReportDataLine_() # Outputs: (local) # stdout = single report line with data fields. - local assigned_repo='' - local assigned_repo_msg=$r_chars_normal - local install_date=$(QpkgGetInstalledDate) - local install_date_msg=$r_chars_blank + local a='' + local -a column_vars=(assigned_repo install_date name) local mode='' - local name_msg=$r_chars_blank + local req_alert=false + local req_attention=false local store_id=$(QpkgGetInstalledStoreID) [[ $store_id = undefined ]] && store_id=sherpa + for a in "${column_vars[@]}"; do + local ${a}=false + local ${a}_msg='' + done + + name=$qpkg_name + if QpkgIsInstalledMissing; then mode=highlight /bin/touch "$r_report_flags_path"/status-missing @@ -5104,61 +5225,66 @@ _GenerateReposReportDataLine_() case $mode in highlight) - install_date=missing - case $assigned_repo in sherpa) - assigned_repo_msg+=$(TextBrightGreen "$assigned_repo") + assigned_repo_msg=$(GenerateReportField "$assigned_repo" normal_highlight) ;; unassigned) - assigned_repo_msg+=$(TextBrightOrange "$assigned_repo") + assigned_repo_msg=$(GenerateReportField "$assigned_repo" highlight) ;; *) - assigned_repo_msg+=$assigned_repo + assigned_repo_msg=$(GenerateReportField "$assigned_repo") /bin/touch "$r_report_flags_path"/repo-other esac - install_date_msg=$(TextBrightRedBlink "${r_chars_alert}${install_date}") - name_msg=$(TextBrightRed "${name_msg}${qpkg_name}") + install_date_msg=$(GenerateReportField missing alert) + req_alert=true ;; - normal) + mute) + /bin/touch "$r_report_flags_path"/na + + if ! QpkgIsDatabaseArchOK; then + assigned_repo='incompatible architecture' + elif ! QpkgIsDatabaseMinOSVerOk; then + assigned_repo='incompatible '$(OsGetQnapOS) + elif ! QpkgIsDatabaseMinRAMOk; then + assigned_repo='insufficient RAM installed' + else + assigned_repo='not installed' + fi + + assigned_repo_msg=$(GenerateReportField "$assigned_repo" normal_mute) + install_date_msg=$(GenerateReportField N/A mute) + ;; + *) case $assigned_repo in sherpa) - assigned_repo_msg+=$(TextBrightGreen "$assigned_repo") - name_msg+=$qpkg_name + assigned_repo_msg=$(GenerateReportField "$assigned_repo" normal_highlight) ;; undefined) - assigned_repo_msg+=N/A - name_msg+=$qpkg_name + assigned_repo_msg=N/A /bin/touch "$r_report_flags_path"/na ;; *) - assigned_repo_msg=$(TextBrightOrange "${r_chars_attention}${assigned_repo}") - name_msg=$(TextBrightOrange "${name_msg}${qpkg_name}") + assigned_repo_msg=$(GenerateReportField "$assigned_repo" attention) /bin/touch "$r_report_flags_path"/repo-other esac - install_date_msg+=$install_date - ;; - mute) - assigned_repo=N/A - /bin/touch "$r_report_flags_path"/na - - if ! QpkgIsDatabaseArchOK; then - install_date='incompatible architecture' - elif ! QpkgIsDatabaseMinOSVerOk; then - install_date='incompatible '$(OsGetQnapOS) - elif ! QpkgIsDatabaseMinRAMOk; then - install_date='insufficient RAM installed' - else - install_date='not installed' - fi - - assigned_repo_msg=$(TextDarkGrey "${assigned_repo_msg}${assigned_repo}") - install_date_msg=$(TextDarkGrey "${install_date_msg}${install_date}") - name_msg=$(TextDarkGrey "${name_msg}${qpkg_name}") + install_date_msg=$(GenerateReportField "$(QpkgGetInstalledDate)") esac + if [[ $req_alert = true ]]; then + /bin/touch "$r_report_flags_path"/req-alert + name_msg=$(GenerateReportField "$name" alert) + elif [[ $req_attention = true ]]; then + /bin/touch "$r_report_flags_path"/req-attention + name_msg=$(GenerateReportField "$name" attention) + elif [[ $mode = mute ]]; then + name_msg=$(GenerateReportField "$name" mute) + else + name_msg=$(GenerateReportField "$name") + fi + if OsIsSupportAutowidthTableColumns; then printf '%s' "$name_msg|$assigned_repo_msg|$install_date_msg" else @@ -5216,11 +5342,6 @@ _GenerateAbsReportDataLine_() fi case $mode in - normal) - abs_msg=${r_chars_normal}$(AddSeparators "$(QpkgGetDatabaseAbbrvs)") - installed_msg+=true - name_msg+=$qpkg_name - ;; mute) if ! QpkgIsDatabaseArchOK "$qpkg_name"; then abs_msg=$r_chars_alert'incompatible architecture' @@ -5240,6 +5361,11 @@ _GenerateAbsReportDataLine_() abs_msg=$(TextBrightRed "${r_chars_alert}$(AddSeparators "$(QpkgGetDatabaseAbbrvs)")") installed_msg=$(TextBrightRedBlink "${r_chars_alert}missing") name_msg+=$(TextBrightRed "$qpkg_name") + ;; + *) + abs_msg=${r_chars_normal}$(AddSeparators "$(QpkgGetDatabaseAbbrvs)") + installed_msg+=true + name_msg+=$qpkg_name esac if OsIsSupportAutowidthTableColumns; then @@ -5295,35 +5421,34 @@ _GenerateDepsReportDataLine_() # Inputs: (global) # $qpkg_name + # $r_report_flags_path - local author=$(QpkgGetInstalledAuthor) - local author_ok=false - local author_msg=$r_chars_blank - local arch=false - local arch_msg=$r_chars_blank + local a='' + local -a column_vars=(author arch deps enabled installed managed max_os min_os min_ram name) local dep_name='' - local deps='' - local deps_msg=$r_chars_normal local deps_raw=$(QpkgGetDatabaseDependencies "$qpkg_name") - local enabled=false - local enabled_msg=$r_chars_blank - local installed=false - local installed_msg=$r_chars_blank - local managed=false - local managed_msg=$r_chars_blank - local max_os=$(QpkgGetDatabaseMaxOSVer "$qpkg_name") - local max_os_msg=$r_chars_blank - local max_os_ok=false - local min_os=$(QpkgGetDatabaseMinOSVer "$qpkg_name") - local min_os_msg=$r_chars_blank - local min_os_ok=false - local min_ram=$(QpkgGetDatabaseMinRAM "$qpkg_name") - local min_ram_msg=$r_chars_blank - local min_ram_ok=false local mode='' - local name_msg=$r_chars_blank local req_alert=false local req_attention=false + local req_notice=false + + for a in "${column_vars[@]}"; do + local ${a}=false + local ${a}_msg='' + done + + name=$qpkg_name + author=$(QpkgGetInstalledAuthor) + max_os=$(QpkgGetDatabaseMaxOSVer "$name") + min_os=$(QpkgGetDatabaseMinOSVer "$name") + min_ram=$(QpkgGetDatabaseMinRAM "$name") + QpkgIsDatabaseArchOK && arch=true + QpkgIsInstalledRepoSelfManaged && managed=true + QpkgIsInstalledEnabled "$name" && enabled=true + [[ -z $deps_raw ]] && deps_raw=none + [[ -n $max_os && $max_os != none && ${#max_os} -eq 3 ]] && max_os=${max_os:0:1}.${max_os:1:1}.${max_os:2:1} + [[ -n $min_os && $min_os != none && ${#min_os} -eq 3 ]] && min_os=${min_os:0:1}.${min_os:1:1}.${min_os:2:1} + [[ $min_ram != none ]] && min_ram=$(FormatAsThous "$min_ram")kB /bin/touch "$r_report_flags_path"/deps @@ -5336,168 +5461,37 @@ _GenerateDepsReportDataLine_() QpkgIsReallyInstalled && QpkgIsNtInstalledAuthorOk && mode=author fi - [[ -z $deps_raw ]] && deps_raw=none - [[ -n $max_os && $max_os != none && ${#max_os} -eq 3 ]] && max_os=${max_os:0:1}.${max_os:1:1}.${max_os:2:1} - [[ -n $min_os && $min_os != none && ${#min_os} -eq 3 ]] && min_os=${min_os:0:1}.${min_os:1:1}.${min_os:2:1} - [[ $min_ram != none ]] && min_ram=$(FormatAsThous "$min_ram")kB - case $mode in author) /bin/touch "$r_report_flags_path"/status-wrongauthor - - # Set field values. - arch=N/A - deps='incompatible author' - enabled=N/A - installed=true - managed=N/A - max_os=N/A - min_os=N/A - min_ram=N/A req_attention=true - # Assign field messages. - arch_msg+=$arch - author_msg=${r_chars_attention}${author} - deps_msg=${r_chars_attention}${deps} - enabled_msg+=$enabled - installed_msg+=$installed - managed_msg+=$managed - max_os_msg+=$max_os - min_os_msg+=$min_os - min_ram_msg+=$min_ram - - # Highlight field messages. - arch_msg=$(TextBrightOrange "$arch_msg") - author_msg=$(TextBrightOrange "$author_msg") - deps_msg=$(TextBrightOrange "$deps_msg") - enabled_msg=$(TextBrightOrange "$enabled_msg") - installed_msg=$(TextBrightGreen "$installed_msg") - managed_msg=$(TextBrightOrange "$managed_msg") - max_os_msg=$(TextBrightOrange "$max_os_msg") - min_os_msg=$(TextBrightOrange "$min_os_msg") - min_ram_msg=$(TextBrightOrange "$min_ram_msg") + for a in "${column_vars[@]}"; do + case $a in + author) + author_msg=$(GenerateReportField "$author" attention) + ;; + deps) + deps_msg=$(GenerateReportField 'incompatible author' attention) + ;; + name) + : # Do nothing, this will be set later. + ;; + *) + local ${a}_msg="$(GenerateReportField N/A highlight)" + esac + done ;; missing) - # Set field values. - QpkgIsDatabaseArchOK && arch=true - - if [[ $deps_raw != none ]]; then - for dep_name in $deps_raw; do - [[ -n $deps ]] && deps+=' ' - - # Assign highlighting earlier than-usual as each QPKG name can have a different highlight. - - if QpkgIsInstalled "$dep_name" && QpkgIsInstalledEnabled "$dep_name"; then - deps+=$(TextBrightGreen "$dep_name") - else - deps+=$(TextBrightRed "$dep_name") - fi - done - else - deps+=$(TextBrightGreen "$deps_raw") - fi - - QpkgIsInstalledEnabled && enabled=true - installed=missing - QpkgIsInstalledRepoSelfManaged && managed=true - QpkgIsDatabaseMaxOSVerOk && max_os_ok=true - QpkgIsDatabaseMinOSVerOk && min_os_ok=true - QpkgIsDatabaseMinRAMOk && min_ram_ok=true req_alert=true # Assign field messages. - - if [[ $arch = true ]]; then - arch_msg+=$arch - else - arch_msg=${r_chars_alert}${arch} - fi - - author_msg+=$author - deps_msg+=${deps// /, } - - if [[ $enabled = true ]]; then - enabled_msg+=$enabled - else - enabled_msg=${r_chars_alert}${enabled} - fi - - installed_msg=${r_chars_alert}${installed} - managed_msg+=$managed - - if [[ $max_os_ok = true ]]; then - max_os_msg+=$max_os - else - max_os_msg=${r_chars_alert}${max_os} - fi - - if [[ $min_os_ok = true ]]; then - min_os_msg+=$min_os - else - min_os_msg=${r_chars_alert}${min_os} - fi - - if [[ $min_ram_ok = true ]]; then - min_ram_msg+=$min_ram - else - min_ram_msg=${r_chars_alert}${min_ram} - fi - - # Highlight field messages. - - if [[ $arch = true ]]; then - arch_msg=$(TextBrightGreen "$arch_msg") - else - arch_msg=$(TextBrightRed "$arch_msg") - fi - - author_msg=$(TextBrightGreen "$author_msg") - - if [[ $enabled = true ]]; then - enabled_msg=$(TextBrightGreen "$enabled_msg") - else - enabled_msg=$(TextBrightRedBlink "$enabled_msg") - fi - - installed_msg=$(TextBrightRedBlink "$installed_msg") - - if [[ $managed = true ]]; then - managed_msg=$(TextBrightGreen "$managed_msg") - else - managed_msg=$(TextBrightOrange "$managed_msg") - fi - - if [[ $max_os_ok = true ]]; then - if [[ $max_os != none ]]; then - max_os_msg=$(TextBrightGreen "$max_os_msg") - fi - else - max_os_msg=$(TextBrightRed "$max_os_msg") - fi - - if [[ $min_os_ok = true ]]; then - if [[ $min_os != none ]]; then - min_os_msg=$(TextBrightGreen "$min_os_msg") - fi - else - min_os_msg=$(TextBrightRed "$min_os_msg") - fi - - if [[ $min_ram_ok = true ]]; then - if [[ $min_ram != none ]]; then - min_ram_msg=$(TextBrightGreen "$min_ram_msg") - fi - else - min_ram_msg=$(TextBrightRed "$min_ram_msg") - fi + installed_msg=$(GenerateReportField missing alert) ;; mute) /bin/touch "$r_report_flags_path"/state-notinstalled - # Set field values. - QpkgIsDatabaseArchOK "$qpkg_name" && arch=true - author=N/A + deps='' if [[ $deps_raw != none ]]; then for dep_name in $deps_raw; do @@ -5505,109 +5499,64 @@ _GenerateDepsReportDataLine_() deps+=$dep_name done else - deps+=$deps_raw + deps=$deps_raw fi - enabled=N/A - managed=N/A - QpkgIsDatabaseMaxOSVerOk "$qpkg_name" && max_os_ok=true - QpkgIsDatabaseMinOSVerOk "$qpkg_name" && min_os_ok=true - QpkgIsDatabaseMinRAMOk "$qpkg_name" && min_ram_ok=true - /bin/touch "$r_report_flags_path"/na - # Assign field messages. + # Assign & highlight field messages. - if [[ $arch = true ]]; then - arch_msg+=$arch + if QpkgIsDatabaseArchOK; then + arch_msg=$(GenerateReportField "$arch" mute) else - arch_msg=${r_chars_attention}${arch} + arch_msg=$(GenerateReportField "$arch" attention) req_attention=true fi - author_msg+=$author - deps_msg+=${deps// /, } - enabled_msg+=$enabled - installed_msg+=$installed - managed_msg+=$managed + author_msg=$(GenerateReportField N/A mute) + deps_msg=$(GenerateReportField "${deps// /, }" mute) + enabled_msg=$(GenerateReportField N/A mute) + installed_msg=$(GenerateReportField "$installed" mute) + managed_msg=$(GenerateReportField N/A mute) - if [[ $max_os_ok = true ]]; then - max_os_msg+=$max_os + if QpkgIsDatabaseMaxOSVerOk "$qpkg_name"; then + max_os_msg=$(GenerateReportField "$max_os" mute) else - max_os_msg=${r_chars_attention}${max_os} - req_attention=true + max_os_msg=$(GenerateReportField "$max_os" highlight) fi - if [[ $min_os_ok = true ]]; then - min_os_msg+=$min_os + if QpkgIsDatabaseMinOSVerOk "$qpkg_name"; then + if [[ $min_os != none ]]; then + min_os_msg=$(GenerateReportField "$min_os" mute) + else + min_os_msg=$(GenerateReportField "$min_os" highlight) + req_attention=true + fi else - min_os_msg=${r_chars_attention}${min_os} + min_os_msg=$(GenerateReportField "$min_os" highlight) req_attention=true fi - if [[ $min_ram_ok = true ]]; then - min_ram_msg+=$min_ram + if QpkgIsDatabaseMinRAMOk "$qpkg_name"; then + min_ram_msg=$(GenerateReportField "$min_ram" mute) else - min_ram_msg=${r_chars_attention}${min_ram} + min_ram_msg=$(GenerateReportField "$min_ram" highlight) req_attention=true fi - - # Highlight field messages. - - if [[ $arch = true ]]; then - arch_msg=$(TextDarkGrey "$arch_msg") - else - arch_msg=$(TextBrightOrange "$arch_msg") - fi - - author_msg=$(TextDarkGrey "$author_msg") - deps_msg=$(TextDarkGrey "$deps_msg") - enabled_msg=$(TextDarkGrey "$enabled_msg") - installed_msg=$(TextDarkGrey "$installed_msg") - managed_msg=$(TextDarkGrey "$managed_msg") - - if [[ $max_os_ok = true ]]; then - max_os_msg=$(TextDarkGrey "$max_os_msg") - else - max_os_msg=$(TextBrightOrange "$max_os_msg") - fi - - if [[ $min_os_ok = true ]]; then - min_os_msg=$(TextDarkGrey "$min_os_msg") - else - min_os_msg=$(TextBrightOrange "$min_os_msg") - fi - - if [[ $min_ram_ok = true ]]; then - min_ram_msg=$(TextDarkGrey "$min_ram_msg") - else - min_ram_msg=$(TextBrightOrange "$min_ram_msg") - fi ;; - normal) - # Set field values. - - QpkgIsDatabaseArchOK && arch=true - author_ok=true - QpkgIsInstalledEnabled && enabled=true - installed=true - QpkgIsInstalledRepoSelfManaged && managed=true - QpkgIsDatabaseMaxOSVerOk && max_os_ok=true - QpkgIsDatabaseMinOSVerOk && min_os_ok=true - QpkgIsDatabaseMinRAMOk && min_ram_ok=true - - # Assign field messages. - - if [[ $arch = true ]]; then - arch_msg+=$arch + *) + if QpkgIsDatabaseArchOK; then + arch_msg=$(GenerateReportField "$arch" highlight_ok) else - arch_msg=${r_chars_alert}${arch} + arch_msg=$(GenerateReportField "$arch" alert) req_alert=true fi - author_msg+=$author + author_msg=$(GenerateReportField "$author" highlight_ok) if [[ $deps_raw != none ]]; then + deps='' + for dep_name in $deps_raw; do [[ -n $deps ]] && deps+=' ' @@ -5615,105 +5564,77 @@ _GenerateDepsReportDataLine_() deps+=$(TextBrightGreen "$dep_name") else deps+=$(TextBrightRed "$dep_name") - deps_msg=$(TextBrightRed "$r_chars_alert") - req_alert=true + req_notice=true fi done else - deps+=$deps_raw - fi - - if [[ $enabled = true ]]; then - enabled_msg+=$enabled - else - enabled_msg=${r_chars_alert}${enabled} - req_alert=true + deps=$deps_raw fi - installed_msg+=$installed - managed_msg+=$managed + deps_msg=$(GenerateReportField "${deps// /, }") - if [[ $max_os_ok = true ]]; then - max_os_msg+=$max_os - else - max_os_msg=${r_chars_alert}${max_os} - req_alert=true - fi - - if [[ $min_os_ok = true ]]; then - min_os_msg+=$min_os - else - min_os_msg=${r_chars_alert}${min_os} - req_alert=true - fi - - if [[ $min_ram_ok = true ]]; then - min_ram_msg+=$min_ram - else - min_ram_msg=${r_chars_alert}${min_ram} - req_alert=true - fi - - # Highlight field messages. - - if [[ $arch = true ]]; then - arch_msg=$(TextBrightGreen "$arch_msg") - else - arch_msg=$(TextBrightRed "$arch_msg") - fi - - author_msg=$(TextBrightGreen "$author_msg") - deps_msg+=${deps// /, } - - if [[ $enabled = true ]]; then - enabled_msg=$(TextBrightGreen "$enabled_msg") + if QpkgIsInstalledEnabled; then + enabled_msg=$(GenerateReportField "$enabled" highlight_ok) else - enabled_msg=$(TextBrightRed "$enabled_msg") + enabled_msg=$(GenerateReportField "$enabled" notice) + req_notice=true fi - installed_msg=$(TextBrightGreen "$installed_msg") + installed_msg=$(GenerateReportField true highlight_ok) - if [[ $managed = true ]]; then - managed_msg=$(TextBrightGreen "$managed_msg") + if QpkgIsInstalledRepoSelfManaged; then + managed_msg=$(GenerateReportField "$managed" highlight_ok) else - managed_msg=$(TextBrightOrange "$managed_msg") + managed_msg=$(GenerateReportField "$managed" highlight) fi - if [[ $max_os_ok = true ]]; then + if QpkgIsDatabaseMaxOSVerOk; then if [[ $max_os != none ]]; then - max_os_msg=$(TextBrightGreen "$max_os_msg") + max_os_msg=$(GenerateReportField "$max_os" highlight_ok) + else + max_os_msg=$(GenerateReportField "$max_os") fi else - max_os_msg=$(TextBrightRed "$max_os_msg") + max_os_msg=$(GenerateReportField "$max_os" alert) + req_alert=true fi - if [[ $min_os_ok = true ]]; then + if QpkgIsDatabaseMinOSVerOk; then if [[ $min_os != none ]]; then - min_os_msg=$(TextBrightGreen "$min_os_msg") + min_os_msg=$(GenerateReportField "$min_os" highlight_ok) + else + min_os_msg=$(GenerateReportField "$min_os") fi else - min_os_msg=$(TextBrightRed "$min_os_msg") + min_os_msg=$(GenerateReportField "$min_os" alert) + req_alert=true fi - if [[ $min_ram_ok = true ]]; then + if QpkgIsDatabaseMinRAMOk; then if [[ $min_ram != none ]]; then - min_ram_msg=$(TextBrightGreen "$min_ram_msg") + min_ram_msg=$(GenerateReportField "$min_ram" highlight_ok) + else + min_ram_msg=$(GenerateReportField "$min_ram") fi else - min_ram_msg=$(TextBrightRed "$min_ram_msg") + min_ram_msg=$(GenerateReportField "$min_ram" alert) + req_alert=true fi esac if [[ $req_alert = true ]]; then /bin/touch "$r_report_flags_path"/req-alert - name_msg=${r_chars_blank}$(TextBrightRed "$qpkg_name") + name_msg=$(GenerateReportField "$name" alert) elif [[ $req_attention = true ]]; then /bin/touch "$r_report_flags_path"/req-attention - name_msg=${r_chars_blank}$(TextBrightOrange "$qpkg_name") + name_msg=$(GenerateReportField "$name" attention) + elif [[ $req_notice = true ]]; then + /bin/touch "$r_report_flags_path"/req-notice + name_msg=$(GenerateReportField "$name" notice) elif [[ $mode = mute ]]; then - name_msg+=$(TextDarkGrey "$qpkg_name") + name_msg=$(GenerateReportField "$name" mute) else - name_msg+=$qpkg_name + name_msg=$(GenerateReportField "$name") fi if OsIsSupportAutowidthTableColumns; then @@ -5743,6 +5664,7 @@ GenerateFeaturesReportTitleLine() # $r_report_qpkg_active_test_builtin_column_width # $r_report_qpkg_auto_update_column_width # $r_report_qpkg_is_compatible_column_width + # $r_report_qpkg_is_plugin_column_width # $r_report_qpkg_name_column_width # $r_report_qpkg_tier_column_width # $r_report_qpkg_supports_backup_column_width @@ -5750,7 +5672,7 @@ GenerateFeaturesReportTitleLine() # $r_report_qpkg_supports_start_to_update_column_width if OsIsSupportAutowidthTableColumns; then - printf 'QPKG name:|CanBack?|CanClean?|StartUpd?|AutoUpd?|LiveTest?|Independent?|ArchCompat?|Enhanced?|UniqueUnpack?' + printf 'QPKG name:|CanBack?|CanClean?|StartUpd?|AutoUpd?|LiveTest?|Independent?|ArchCompat?|Enhanced?|UniqueUnpack?|Plugin?' else GenerateReportLineItem 'QPKG name:' "$r_report_qpkg_name_column_width" GenerateReportLineItem 'CanBack?' "$r_report_qpkg_supports_backup_column_width" @@ -5762,6 +5684,7 @@ GenerateFeaturesReportTitleLine() GenerateReportLineItem 'ArchCompat?' "$r_report_qpkg_is_compatible_column_width" GenerateReportLineItem 'Enhanced?' "$r_report_lazy_column_width" GenerateReportLineItem 'UniqueUnpack?' "$r_report_lazy_column_width" + GenerateReportLineItem 'Plugin?' "$r_report_qpkg_is_plugin_column_width" fi printf '\n' @@ -5777,28 +5700,18 @@ _GenerateFeaturesReportDataLine_() # $qpkg_name # $r_report_flags_path - local active_test=false - local active_test_msg=$r_chars_blank - local arch_compatible=false - local arch_compatible_msg=$r_chars_blank - local autoupdate=false # Tri-state: true, false, N/A - local autoupdate_msg=$r_chars_blank - local backup=false - local backup_msg=$r_chars_blank - local clean=false - local clean_msg=$r_chars_blank - local independent=false - local independent_msg=$r_chars_blank + local a='' + local -a column_vars=(active_test arch_compatible autoupdate backup clean independent name plugin restart_to_update compatible uniqueunpack) local mode='' - local name_msg=$r_chars_blank local req_alert=false local req_attention=false - local restart_to_update=false - local restart_to_update_msg=$r_chars_blank - local sherpa_compatible=false - local sherpa_compatible_msg=$r_chars_blank - local uniqueunpack=false - local uniqueunpack_msg=$r_chars_blank + + for a in "${column_vars[@]}"; do + local ${a}=false + local ${a}_msg='' + done + + name=$qpkg_name if QpkgIsInstalledMissing; then mode=missing @@ -5815,22 +5728,16 @@ _GenerateFeaturesReportDataLine_() backup='incompatible author' req_attention=true - # Assign field messages. - backup_msg=${r_chars_attention}${backup} - - # Highlight field messages. - backup_msg=$(TextBrightOrange "$backup_msg") + # Assign & highlight field messages. + backup_msg=$(GenerateReportField "$backup" attention) ;; missing) # Set field values. backup=missing req_alert=true - # Assign field messages. - backup_msg=${r_chars_alert}${backup} - - # Highlight field messages. - backup_msg=$(TextBrightRedBlink "$backup_msg") + # Assign & highlight field messages. + backup_msg=$(GenerateReportField "$backup" alert) ;; mute) # Set field values. @@ -5843,44 +5750,27 @@ _GenerateFeaturesReportDataLine_() if QpkgIsDatabaseCanRestartToUpdate; then restart_to_update=true - elif [[ $qpkg_name = sherpa ]]; then + elif [[ $name = sherpa ]]; then restart_to_update=true # sherpa always auto-updates and this can't be disabled. fi - QpkgIsDatabaseSherpaCompatible && sherpa_compatible=true + QpkgIsDatabaseSherpaCompatible && compatible=true QpkgIsDatabaseUniqueUnpack && uniqueunpack=true - # Assign field messages. - active_test_msg+=$active_test - arch_compatible_msg+=$arch_compatible - autoupdate_msg+=$autoupdate - backup_msg+=$backup - clean_msg+=$clean - independent_msg+=$independent - restart_to_update_msg+=$restart_to_update - sherpa_compatible_msg+=$sherpa_compatible - uniqueunpack_msg+=$uniqueunpack - - # Highlight field messages. - active_test_msg=$(TextDarkGrey "$active_test_msg") - arch_compatible_msg=$(TextDarkGrey "$arch_compatible_msg") - autoupdate_msg=$(TextDarkGrey "$autoupdate_msg") - backup_msg=$(TextDarkGrey "$backup_msg") - clean_msg=$(TextDarkGrey "$clean_msg") - independent_msg=$(TextDarkGrey "$independent_msg") - restart_to_update_msg=$(TextDarkGrey "$restart_to_update_msg") - sherpa_compatible_msg=$(TextDarkGrey "$sherpa_compatible_msg") - uniqueunpack_msg=$(TextDarkGrey "$uniqueunpack_msg") + # Assign & highlight field messages. + + for a in "${column_vars[@]}"; do + local ${a}_msg="$(GenerateReportField "${!a}" mute)" + done ;; - normal) + *) # Set field values. [[ $(QpkgGetDatabaseActiveTest) = builtin ]] && active_test=true + QpkgIsDatabaseArchOK && arch_compatible=true if QpkgIsInstalled && QpkgIsDatabaseCanRestartToUpdate; then - if QpkgIsInstalledAutoUpdate; then - autoupdate=true - fi - elif [[ $qpkg_name = sherpa ]]; then + QpkgIsInstalledAutoUpdate && autoupdate=true + elif [[ $name = sherpa ]]; then autoupdate=true # sherpa always auto-updates and this can't be disabled. else autoupdate=N/A @@ -5889,100 +5779,45 @@ _GenerateFeaturesReportDataLine_() QpkgIsDatabaseCanBackup && backup=true QpkgIsDatabaseCanClean && clean=true - QpkgIsDatabaseArchOK && arch_compatible=true + QpkgIsDatabaseIndependent && independent=true + QpkgIsDatabasePlugin && plugin=true if QpkgIsDatabaseCanRestartToUpdate; then restart_to_update=true - elif [[ $qpkg_name = sherpa ]]; then + elif [[ $name = sherpa ]]; then restart_to_update=true # sherpa always auto-updates and this can't be disabled. fi - QpkgIsDatabaseSherpaCompatible && sherpa_compatible=true - QpkgIsDatabaseIndependent && independent=true + QpkgIsDatabaseSherpaCompatible && compatible=true QpkgIsDatabaseUniqueUnpack && uniqueunpack=true - # Assign field messages. - active_test_msg+=$active_test - arch_compatible_msg+=$arch_compatible - autoupdate_msg+=$autoupdate - backup_msg+=$backup - clean_msg+=$clean - independent_msg+=$independent - restart_to_update_msg+=$restart_to_update - sherpa_compatible_msg+=$sherpa_compatible - uniqueunpack_msg+=$uniqueunpack - - # Highlight field messages. - - if [[ $active_test = true ]]; then - : # active_test_msg=$(TextBrightGreen "$active_test_msg") - else - active_test_msg=$(TextBrightOrange "$active_test_msg") - fi - - if [[ $autoupdate = true ]]; then # Tri-state. - : # autoupdate_msg=$(TextBrightGreen "$autoupdate_msg") - elif [[ $autoupdate = false ]]; then - autoupdate_msg=$(TextBrightOrange "$autoupdate_msg") - fi - - if [[ $backup = true ]]; then - : # backup_msg=$(TextBrightGreen "$backup_msg") - else - backup_msg=$(TextBrightOrange "$backup_msg") - fi + # Assign & highlight field messages. - if [[ $clean = true ]]; then - : # clean_msg=$(TextBrightGreen "$clean_msg") - else - clean_msg=$(TextBrightOrange "$clean_msg") - fi - - if [[ $arch_compatible = true ]]; then - : # arch_compatible_msg=$(TextBrightGreen "$arch_compatible_msg") - else - arch_compatible_msg=$(TextBrightRed "$arch_compatible_msg") - fi - - if [[ $restart_to_update = true ]]; then - : # restart_to_update_msg=$(TextBrightGreen "$restart_to_update_msg") - else - restart_to_update_msg=$(TextBrightOrange "$restart_to_update_msg") - fi - - if [[ $sherpa_compatible = true ]]; then - : # sherpa_compatible_msg=$(TextBrightGreen "$sherpa_compatible_msg") - else - sherpa_compatible_msg=$(TextBrightOrange "$sherpa_compatible_msg") - fi - - if [[ $uniqueunpack = true ]]; then - : # uniqueunpack_msg=$(TextBrightGreen "$uniqueunpack_msg") - else - uniqueunpack_msg=$(TextBrightOrange "$uniqueunpack_msg") - fi - - if [[ $independent = true ]]; then - : # independent_msg=$(TextBrightGreen "$independent_msg") - else - independent_msg=$(TextBrightOrange "$independent_msg") - fi + for a in "${column_vars[@]}"; do + case ${!a} in + true) + local ${a}_msg="$(GenerateReportField "${!a}")" + ;; + *) + local ${a}_msg="$(GenerateReportField "${!a}" highlight)" + esac + done esac if [[ $req_alert = true ]]; then /bin/touch "$r_report_flags_path"/req-alert - name_msg=${r_chars_blank}$(TextBrightRed "$qpkg_name") + name_msg=$(GenerateReportField "$name" alert) elif [[ $req_attention = true ]]; then /bin/touch "$r_report_flags_path"/req-attention - name_msg=${r_chars_blank}$(TextBrightOrange "$qpkg_name") + name_msg=$(GenerateReportField "$name" attention) elif [[ $mode = mute ]]; then - name_msg+=$(TextDarkGrey "$qpkg_name") + name_msg=$(GenerateReportField "$name" mute) else - name_msg+=$qpkg_name + name_msg=$(GenerateReportField "$name") fi if OsIsSupportAutowidthTableColumns; then - printf '%s' "$name_msg|$backup_msg|$clean_msg|$restart_to_update_msg|$autoupdate_msg|$active_test_msg|$independent_msg|$arch_compatible_msg|$sherpa_compatible_msg|$uniqueunpack_msg" + printf '%s' "$name_msg|$backup_msg|$clean_msg|$restart_to_update_msg|$autoupdate_msg|$active_test_msg|$independent_msg|$arch_compatible_msg|$compatible_msg|$uniqueunpack_msg|$plugin_msg" else GenerateReportLineItem "$name_msg" "$r_report_qpkg_name_column_width" GenerateReportLineItem "$backup_msg" "$r_report_qpkg_supports_backup_column_width" @@ -5992,8 +5827,9 @@ _GenerateFeaturesReportDataLine_() GenerateReportLineItem "$active_test_msg" "$r_report_qpkg_active_test_builtin_column_width" GenerateReportLineItem "$independent_msg" "$r_report_qpkg_tier_column_width" GenerateReportLineItem "$arch_compatible_msg" "$r_report_qpkg_is_compatible_column_width" - GenerateReportLineItem "$sherpa_compatible_msg" "$r_report_lazy_column_width" + GenerateReportLineItem "$compatible_msg" "$r_report_lazy_column_width" GenerateReportLineItem "$uniqueunpack_msg" "$r_report_lazy_column_width" + GenerateReportLineItem "$plugin_msg" "$r_report_qpkg_is_plugin_column_width" fi printf '\n' @@ -7462,11 +7298,13 @@ ListQPKGsStates() BuildQPKGsTiers() { - # There are three tiers of package: `independent`, `auxiliary` and `dependent`. - # ... but only two tiers of QPKG: `independent` and `dependent`. + # There are 4 tiers of package: `plugin`, `independent`, `auxiliary`, and `dependent`. + # ... but only 2 tiers of QPKG: `independent`, and `dependent`. + # ... additionally, both QPKG tiers may have `plugins`. # `independent` QPKGs don't depend-on other QPKGs, but may be required for other QPKGs. They should be installed/activated before any `dependent` QPKGs. # `dependent` QPKGs depend-on other QPKGs. They should be installed/activated after all `independent` QPKGs. + # `plugin` QPKGs are optionally depended-upon by other QPKGs. They should be installed/activated before other QPKGs within the same tier, and deactivated after other QPKGs within the same tier. # Inputs: (global) # $qpkgs_tiers_built @@ -12439,6 +12277,42 @@ QpkgIsDatabaseCanClean() } +QpkgIsDatabasePlugin() + { + + # Is this QPKG a plugin for other QPKGs? + + # Inputs: (local) + # $1 (string, optional override for $qpkg_name) = QPKG name: if $1 is explicitly stated, lookup $1 in package lists, ignoring current $qpkg_name and $qpkg_index. + + # Inputs: (global) + # $qpkg_default_index + # $qpkg_index + # $r_qpkg_is_plugin[] + # $qpkg_name (default for $1) + + # Outputs: (local) + # $? = true/false + + local a='' + local -i i=0 + + if [[ -n ${1:-} ]]; then + for i in "${!r_qpkg_name[@]}"; do + [[ ${r_qpkg_name[$i]} = "$1" ]] || continue + a=${r_qpkg_is_plugin[$i]} # Always grab first found as default. + break + done + else + a=${r_qpkg_is_plugin[$qpkg_index]} + [[ $a = default ]] && a=${r_qpkg_is_plugin[$qpkg_default_index]} + fi + + [[ -n $a ]] || a=none + [[ $a = true ]] + + } + QpkgIsDatabaseSherpaCompatible() { @@ -14999,6 +14873,7 @@ LoadPackages() unset r_qpkg_depends_on unset r_qpkg_description unset r_qpkg_hash + unset r_qpkg_is_plugin unset r_qpkg_is_sherpa_compatible unset r_qpkg_is_unique_unpack unset r_qpkg_max_os_version @@ -15031,6 +14906,7 @@ LoadPackages() r_qpkg_depends_on+=('') # Require these QPKGs to be installed first. Use 'none' if package is independent. Separate alternatives with '|'. r_qpkg_description+=('') # QPKG description. r_qpkg_hash+=('') # MD5 checksum. + r_qpkg_is_plugin+=('') # 'true'/'false': QPKG is a "plugin" for another QPKG. It will be started before and stopped after other QPKGs but only if-installed. r_qpkg_is_sherpa_compatible+=('') # 'true'/'false': the service-script responds to enhanced sherpa actions. r_qpkg_is_unique_unpack+=('') # 'true'/'false': QPKG will self-extract contents to a unique path. Requires build with QDK 2.3.14 or-later. r_qpkg_max_os_version+=('') # The maximum QTS/QuTS version supported by this QPKG. @@ -15064,6 +14940,7 @@ LoadPackages() readonly r_qpkg_depends_on readonly r_qpkg_description readonly r_qpkg_hash + readonly r_qpkg_is_plugin readonly r_qpkg_is_sherpa_compatible readonly r_qpkg_is_unique_unpack readonly r_qpkg_max_os_version diff --git a/workshop/dep-manipulator.sh b/workshop/dep-manipulator.sh new file mode 100755 index 000000000..2ccb0ae14 --- /dev/null +++ b/workshop/dep-manipulator.sh @@ -0,0 +1,70 @@ +#!/usr/bin/env bash + +# Dependency = packageA:packageB:packageC + +# dep='packageA:packageB:packageC' +# +# echo "dep=[$dep]" +# +# target=packageB +# +# re=\\b${target}\\b +# +# output=$(sed "s|${re}||" <<< "$dep") +# echo "output=[$output]" +# +# output=$(tr -s ':' <<< $output) +# +# echo "output=[$output]" + +GetQPKGPostInstallDeps() + { + + # Inputs: (local) + # $1 = target QPKG name + + # Outputs: (local) + # stdout = target QPKG dependency list, colon-separated. + + [[ -n ${1:-} ]] || return + + /sbin/getcfg "$1" Dependency -f /etc/config/qpkg.conf + + } + +AddToQPKGPostInstallDeps() + { + + # Inputs: (local) + # $1 = target QPKG name. + # $2 = QPKG to add as a post-install dependency. + + /bin/grep -qw "$2" $(GetQPKGPostInstallDeps "$1") && return + + + } + +RemoveFromQPKGPostInstallDeps() + { + + # Inputs: (local) + # $1 = target QPKG name. + # $2 = QPKG to remove as a post-install dependency. + + # Dependency = packageA:packageB:packageC + + [[ -n ${1:-} && -n ${2:-} ]] || return + + local a='' + local re='' + + re=\\b${2}\\b + a=$(/bin/sed "s|${re}||" <<< "$(/sbin/getcfg "$1" Dependency -f /etc/config/qpkg.conf)") + a=$(/bin/tr -s ':' <<< "$a") + + /sbin/setcfg "$1" Dependency "$a" -f /etc/config/qpkg.conf + + } + +RemoveFromQPKGPostInstallDeps OTransmission test1 + diff --git a/workshop/ideas.txt b/workshop/ideas.txt index a01415473..d88b6bc47 100644 --- a/workshop/ideas.txt +++ b/workshop/ideas.txt @@ -1,3 +1,10 @@ +* Include option to display alternating line highlighting on reports? + - $alternating_report_lines + +* Add new QPKG field: r_qpkg_is_plugin+=(true) + - If true, then this QPKG is a plugin. This QPKG is optional and manually installed, is started before dependent QPKGs, and stopped after dependent QPKGs. + - Also add this QPKG as post-install dependency of listed QPKGs. Needed to ensure correct startup sequence in QTS 5.2.0+ + * Include QPKG signing method via default QTS Python and modules. - Won't require an sqlite binary. diff --git a/workshop/issues.txt b/workshop/issues.txt index 99429f74b..391d6fcbc 100644 --- a/workshop/issues.txt +++ b/workshop/issues.txt @@ -22,7 +22,9 @@ Observed issues: * Will need a new method to detect if QTS 5.2.0 is starting/stopping QPKGs due to async starts/stops. * Near the end of installing IPKs, monitored download path can remain at non-zero size while packages complete installation. - - Include a separate progress message when dir size stops increasing and shrinks instead? Maybe force increase to "100%" and stop monitoring? + - Include a separate progress message when dir size stops increasing and shrinks instead? + - Maybe force increase to "100%" and stop monitoring? + - Maybe change progress message to "installing"? * 'sherpa' and 'opkg' were not available after installing Entware. - Entware installation may be corrupt. diff --git a/workshop/test-loop-var-assignment.sh b/workshop/test-loop-var-assignment.sh new file mode 100755 index 000000000..ac6013837 --- /dev/null +++ b/workshop/test-loop-var-assignment.sh @@ -0,0 +1,44 @@ +#!/usr/bin/env bash + +init() + { + +active_test=false +local active_test_msg='active first' + +autoupdate=false +autoupdate_msg='auto second' + +backup=false +backup_msg='back third' + +clean=false +clean_msg='clen fourth' + +echo "before:" +echo -e "\t$active_test_msg" +echo -e "\t$autoupdate_msg" +echo -e "\t$backup_msg" +echo -e "\t$clean_msg" + +a='' +b='' + +for a in active_test autoupdate backup clean; do +# if [[ ${!a} = true ]]; then + : # "$a"_msg=$(TextBrightGreen "${!a}_msg") +# else + b=${a}_msg + local ${a}_msg="${!b} addendum" +# fi +done + +echo "after:" +echo -e "\t$active_test_msg" +echo -e "\t$autoupdate_msg" +echo -e "\t$backup_msg" +echo -e "\t$clean_msg" + + } + +init