cros_update_firmware: Append uris to srcuris if --project is set.

- The main use case is to do a fw uprev w/o having access to all
project repos. If the file is overwritten in this case, some uris
will be deleted.

- This will mean extra payloads are downloaded, but won't be
installed in the image.

- Only enable this if --project flag is set, so it likely won't
affect users that can see all projects. Add append_srcuris flag
to disable this with the --project flag if needed.

BUG=chromium:1131613
TEST=Ran with `--board=dedede`, see crrev.com/i/3286609.
TEST=Ran with `--board=dedede --project=waddledee`, see
crrev.com/i/3286694.

Change-Id: Ib65b8b579fab56136e824a926e7a4a7ef8bcf284
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/dev-util/+/2427451
Reviewed-by: YH Lin <yueherngl@chromium.org>
Commit-Queue: Andrew Lamb <andrewlamb@chromium.org>
Tested-by: Andrew Lamb <andrewlamb@chromium.org>
diff --git a/contrib/cros_update_firmware b/contrib/cros_update_firmware
index 8aaa5cc..e683727 100755
--- a/contrib/cros_update_firmware
+++ b/contrib/cros_update_firmware
@@ -26,6 +26,10 @@
 DEFINE_string board "${DEFAULT_BOARD}" "Which board the firmware is for" b
 DEFINE_string project "${DEFAULT_PROJECT}" "Which project this board is for" p
 DEFINE_boolean quiet "${FLAGS_FALSE}" "Reduce emerge build output" q
+DEFINE_boolean append_srcuris "${FLAGS_TRUE}" "Only applicable when the project
+flag is set. Append firmware uris to srcuris instead of overwriting. This is
+usually needed if you have limited access to project config repos, so
+overwriting would delete some uris."
 
 # Parse command line.
 FLAGS "$@" || exit 1
@@ -64,6 +68,7 @@
   local base ebuild srcuris cfg_bsp_pkg cfg_bsp_baseboard_pkg
   local current_workon_pkg_list start_pkg result i quiet
   [[ "$3" == "${FLAGS_TRUE}" ]] && quiet="--quiet-build"
+  local append_srcuris="$4"
 
   set -e
 
@@ -111,7 +116,21 @@
   fi
 
   "emerge-${board}" -j ${quiet} ${cfg_bsp_baseboard_pkg} "${cfg_bsp_pkg}" chromeos-config
-  cros_config_host -c "${yaml_config}" get-firmware-uris > "${srcuris}"
+
+  # If the append_srcuris and project flags are set, append uris that aren't
+  # already in srcuris. Otherwise, overwrite srcuris.
+  if [[ -n "${project}" && "${append_srcuris}" == "${FLAGS_TRUE}" ]]; then
+    for uri in $(cros_config_host -c "${yaml_config}" get-firmware-uris); do
+      if ! grep -q "${uri}" "${srcuris}"; then
+        # Append uri to the last line of srcuris (srcuris should be a file with
+        # a single line). Escape slashes in uri.
+        sed -i "$ s/$/ ${uri//\//\\/}/" "${srcuris}"
+      fi
+    done
+  else
+    cros_config_host -c "${yaml_config}" get-firmware-uris > "${srcuris}"
+  fi
+
   touch "${ebuild}"
 
   # Clean metadata cache to make sure SRC_URI is fetched from ${srcuris}
@@ -137,7 +156,7 @@
     die "-b or --board required."
   fi
 
-  update_firmware "${FLAGS_board}" "${FLAGS_project}" "${FLAGS_quiet}"
+  update_firmware "${FLAGS_board}" "${FLAGS_project}" "${FLAGS_quiet}" "${FLAGS_append_srcuris}"
 }
 
 main "$@"