Move cog setup logic into shell_utils so it can be used when any of these commands are run:

- `m`
- `lunch`
- `source build/envsetup.sh`

this will set up the symlink properly regardless of the order of commands so users don't get stuck with a broken build

Bug: 362337892
Change-Id: Ibd3b262107dfc1024cd83ab8aeb33a299fb0ffb2
diff --git a/cogsetup.sh b/cogsetup.sh
deleted file mode 100644
index 5c64a06..0000000
--- a/cogsetup.sh
+++ /dev/null
@@ -1,71 +0,0 @@
-#
-# Copyright (C) 2023 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-# This file is executed by build/envsetup.sh, and can use anything
-# defined in envsetup.sh.
-function _create_out_symlink_for_cog() {
-  if [[ "${OUT_DIR}" == "" ]]; then
-    OUT_DIR="out"
-  fi
-
-  # getoutdir ensures paths are absolute. envsetup could be called from a
-  # directory other than the root of the source tree
-  local outdir=$(getoutdir)
-  if [[ -L "${outdir}" ]]; then
-    return
-  fi
-  if [ -d "${outdir}" ]; then
-    echo -e "\tOutput directory ${outdir} cannot be present in a Cog workspace."
-    echo -e "\tDelete \"${outdir}\" or create a symlink from \"${outdir}\" to a directory outside your workspace."
-    return 1
-  fi
-
-  DEFAULT_OUTPUT_DIR="${HOME}/.cog/android-build-out"
-  mkdir -p ${DEFAULT_OUTPUT_DIR}
-  ln -s ${DEFAULT_OUTPUT_DIR} ${outdir}
-}
-
-# This function sets up the build environment to be appropriate for Cog.
-function _setup_cog_env() {
-  _create_out_symlink_for_cog
-  if [ "$?" -eq "1" ]; then
-    echo -e "\e[0;33mWARNING:\e[00m Cog environment setup failed!"
-    return 1
-  fi
-
-  export ANDROID_BUILD_ENVIRONMENT_CONFIG="googler-cog"
-
-  # Running repo command within Cog workspaces is not supported, so override
-  # it with this function. If the user is running repo within a Cog workspace,
-  # we'll fail with an error, otherwise, we run the original repo command with
-  # the given args.
-  if ! ORIG_REPO_PATH=`which repo`; then
-    return 0
-  fi
-  function repo {
-    if [[ "${PWD}" == /google/cog/* ]]; then
-      echo -e "\e[01;31mERROR:\e[0mrepo command is disallowed within Cog workspaces."
-      return 1
-    fi
-    ${ORIG_REPO_PATH} "$@"
-  }
-}
-
-if [[ "${PWD}" != /google/cog/* ]]; then
-  echo -e "\e[01;31mERROR:\e[0m This script must be run from a Cog workspace."
-fi
-
-_setup_cog_env
diff --git a/envsetup.sh b/envsetup.sh
index 06dadd3..3fed5ae 100644
--- a/envsetup.sh
+++ b/envsetup.sh
@@ -442,6 +442,7 @@
 function lunch()
 {
     local answer
+    setup_cog_env_if_needed
 
     if [[ $# -gt 1 ]]; then
         echo "usage: lunch [target]" >&2
@@ -1079,10 +1080,7 @@
         done
     done
 
-    if [[ "${PWD}" == /google/cog/* ]]; then
-        f="build/make/cogsetup.sh"
-        echo "including $f"; . "$T/$f"
-    fi
+    setup_cog_env_if_needed
 }
 
 function showcommands() {
diff --git a/shell_utils.sh b/shell_utils.sh
index 86f3f49..6cc8c9e 100644
--- a/shell_utils.sh
+++ b/shell_utils.sh
@@ -63,6 +63,75 @@
 }
 fi
 
+# This function sets up the build environment to be appropriate for Cog.
+function setup_cog_env_if_needed() {
+  local top=$(gettop)
+
+  # return early if not in a cog workspace
+  if [[ ! "$top" =~ ^/google/cog ]]; then
+    return 0
+  fi
+
+  setup_cog_symlink
+
+  export ANDROID_BUILD_ENVIRONMENT_CONFIG="googler-cog"
+
+  # Running repo command within Cog workspaces is not supported, so override
+  # it with this function. If the user is running repo within a Cog workspace,
+  # we'll fail with an error, otherwise, we run the original repo command with
+  # the given args.
+  if ! ORIG_REPO_PATH=`which repo`; then
+    return 0
+  fi
+  function repo {
+    if [[ "${PWD}" == /google/cog/* ]]; then
+      echo -e "\e[01;31mERROR:\e[0mrepo command is disallowed within Cog workspaces."
+      kill -INT $$ # exits the script without exiting the user's shell
+    fi
+    ${ORIG_REPO_PATH} "$@"
+  }
+}
+
+# creates a symlink for the out/ dir when inside a cog workspace.
+function setup_cog_symlink() {
+  local out_dir=$(getoutdir)
+  local top=$(gettop)
+
+  # return early if out dir is already a symlink
+  if [[ -L "$out_dir" ]]; then
+    return 0
+  fi
+
+  # return early if out dir is not in the workspace
+  if [[ ! "$out_dir" =~ ^$top/ ]]; then
+    return 0
+  fi
+
+  local link_destination="${HOME}/.cog/android-build-out"
+
+  # if there's a local out/ dir, prompt the user to remove it.
+  # fail out if they say no.
+  local answer
+  if [[ -d "$out_dir" ]]; then
+    echo "Detected existing out/ directory in the Cog workspace which is not supported. Can we repair your workspace by removing it and creating the symlink to ~/.cog/android-build-out instead? (y/N): "
+    read -r answer
+    if [[ $answer =~ ^[Yy]$ ]]; then
+      rm -rf "$out_dir"
+    else
+      echo "Exiting due to unsupported out/ directory."
+      kill -INT $$ # exits the script without exiting the user's shell
+    fi
+  fi
+
+  # create symlink
+  echo "Creating symlink: $out_dir -> $link_destination"
+  mkdir -p ${link_destination}
+  if ! ln -s "$link_destination" "$out_dir"; then
+    echo "Failed to create cog symlink: $out_dir -> $link_destination" >&2
+    kill -INT $$ # exits the script without exiting the user's shell
+  fi
+}
+
 function getoutdir
 {
     local top=$(gettop)
diff --git a/tools/ide_query/ide_query.sh b/tools/ide_query/ide_query.sh
index 6f9b0c4..8dfffc1 100755
--- a/tools/ide_query/ide_query.sh
+++ b/tools/ide_query/ide_query.sh
@@ -19,7 +19,7 @@
 require_top
 
 # Ensure cogsetup (out/ will be symlink outside the repo)
-. ${TOP}/build/make/cogsetup.sh
+setup_cog_env_if_needed
 
 case $(uname -s) in
     Linux)