Add new simplified lunch function (lunch2)
Includes tests for envsetup.sh After we've tried this for a bit and are happy, this will be swapped out to become the new standard lunch and all of the menus and stuff will be removed. Test: build/make/tools/envsetup/run_envsetup_tests Change-Id: Idebeeb1153406238b6c32f3f564c7bc1e7ced7e6
This commit is contained in:
parent
d816a727b8
commit
590ae9f785
3 changed files with 385 additions and 9 deletions
131
envsetup.sh
131
envsetup.sh
|
@ -385,6 +385,7 @@ function addcompletions()
|
|||
complete -F _bazel__complete -o nospace b
|
||||
fi
|
||||
complete -F _lunch lunch
|
||||
complete -F _lunch_completion lunch2
|
||||
|
||||
complete -F _complete_android_module_names pathmod
|
||||
complete -F _complete_android_module_names gomod
|
||||
|
@ -496,9 +497,18 @@ function lunch()
|
|||
return 1
|
||||
fi
|
||||
|
||||
_lunch_meat $product $release $variant
|
||||
}
|
||||
|
||||
function _lunch_meat()
|
||||
{
|
||||
local product=$1
|
||||
local release=$2
|
||||
local variant=$3
|
||||
|
||||
TARGET_PRODUCT=$product \
|
||||
TARGET_BUILD_VARIANT=$variant \
|
||||
TARGET_RELEASE=$release \
|
||||
TARGET_BUILD_VARIANT=$variant \
|
||||
build_build_var_cache
|
||||
if [ $? -ne 0 ]
|
||||
then
|
||||
|
@ -519,14 +529,11 @@ function lunch()
|
|||
set_stuff_for_environment
|
||||
[[ -n "${ANDROID_QUIET_BUILD:-}" ]] || printconfig
|
||||
|
||||
if [ "${TARGET_BUILD_VARIANT}" = "userdebug" ] && [[ -z "${ANDROID_QUIET_BUILD}" ]]; then
|
||||
echo
|
||||
echo "Want FASTER LOCAL BUILDS? Use -eng instead of -userdebug (however for" \
|
||||
"performance benchmarking continue to use userdebug)"
|
||||
fi
|
||||
if [ $used_lunch_menu -eq 1 ]; then
|
||||
echo
|
||||
echo "Hint: next time you can simply run 'lunch $selection'"
|
||||
if [[ -z "${ANDROID_QUIET_BUILD}" ]]; then
|
||||
local spam_for_lunch=$(gettop)/build/make/tools/envsetup/spam_for_lunch
|
||||
if [[ -x $spam_for_lunch ]]; then
|
||||
$spam_for_lunch
|
||||
fi
|
||||
fi
|
||||
|
||||
destroy_build_var_cache
|
||||
|
@ -553,6 +560,112 @@ function _lunch()
|
|||
return 0
|
||||
}
|
||||
|
||||
function _lunch_usage()
|
||||
{
|
||||
(
|
||||
echo "The lunch command selects the configuration to use for subsequent"
|
||||
echo "Android builds."
|
||||
echo
|
||||
echo "Usage: lunch TARGET_PRODUCT [TARGET_RELEASE [TARGET_BUILD_VARIANT]]"
|
||||
echo
|
||||
echo " Choose the product, release and variant to use. If not"
|
||||
echo " supplied, TARGET_RELEASE will be 'trunk_staging' and"
|
||||
echo " TARGET_BUILD_VARIANT will be 'eng'"
|
||||
echo
|
||||
echo
|
||||
echo "Usage: lunch TARGET_PRODUCT-TARGET_RELEASE-TARGET_BUILD_VARIANT"
|
||||
echo
|
||||
echo " Chose the product, release and variant to use. This"
|
||||
echo " legacy format is maintained for compatibility."
|
||||
echo
|
||||
echo
|
||||
echo "Note that the previous interactive menu and list of hard-coded"
|
||||
echo "list of curated targets has been removed. If you would like the"
|
||||
echo "list of products, release configs for a particular product, or"
|
||||
echo "variants, run list_products, list_release_configs, list_variants"
|
||||
echo "respectively."
|
||||
echo
|
||||
) 1>&2
|
||||
}
|
||||
|
||||
function lunch2()
|
||||
{
|
||||
if [[ $# -eq 1 && $1 = "--help" ]]; then
|
||||
_lunch_usage
|
||||
return 0
|
||||
fi
|
||||
if [[ $# -eq 0 ]]; then
|
||||
echo "No target specified. See lunch --help" 1>&2
|
||||
return 1
|
||||
fi
|
||||
if [[ $# -gt 3 ]]; then
|
||||
echo "Too many parameters given. See lunch --help" 1>&2
|
||||
return 1
|
||||
fi
|
||||
|
||||
local product release variant
|
||||
|
||||
# Handle the legacy format
|
||||
local legacy=$(echo $1 | grep "-")
|
||||
if [[ $# -eq 1 && -n $legacy ]]; then
|
||||
IFS="-" read -r product release variant <<< "$1"
|
||||
if [[ -z "$product" ]] || [[ -z "$release" ]] || [[ -z "$variant" ]]; then
|
||||
echo "Invalid lunch combo: $1" 1>&2
|
||||
echo "Valid combos must be of the form <product>-<release>-<variant> when using" 1>&2
|
||||
echo "the legacy format. Run 'lunch --help' for usage." 1>&2
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# Handle the new format.
|
||||
if [[ -z $legacy ]]; then
|
||||
product=$1
|
||||
release=$2
|
||||
if [[ -z $release ]]; then
|
||||
release=trunk_staging
|
||||
fi
|
||||
variant=$3
|
||||
if [[ -z $variant ]]; then
|
||||
variant=eng
|
||||
fi
|
||||
fi
|
||||
|
||||
# Validate the selection and set all the environment stuff
|
||||
_lunch_meat $product $release $variant
|
||||
}
|
||||
|
||||
unset ANDROID_LUNCH_COMPLETION_PRODUCT_CACHE
|
||||
unset ANDROID_LUNCH_COMPLETION_CHOSEN_PRODUCT
|
||||
unset ANDROID_LUNCH_COMPLETION_RELEASE_CACHE
|
||||
# Tab completion for lunch.
|
||||
function _lunch_completion()
|
||||
{
|
||||
# Available products
|
||||
if [[ $COMP_CWORD -eq 1 ]] ; then
|
||||
if [[ -z $ANDROID_LUNCH_COMPLETION_PRODUCT_CACHE ]]; then
|
||||
ANDROID_LUNCH_COMPLETION_PRODUCT_CACHE=$(list_products)
|
||||
fi
|
||||
COMPREPLY=( $(compgen -W "${ANDROID_LUNCH_COMPLETION_PRODUCT_CACHE}" -- "${COMP_WORDS[COMP_CWORD]}") )
|
||||
fi
|
||||
|
||||
# Available release configs
|
||||
if [[ $COMP_CWORD -eq 2 ]] ; then
|
||||
if [[ -z $ANDROID_LUNCH_COMPLETION_RELEASE_CACHE || $ANDROID_LUNCH_COMPLETION_CHOSEN_PRODUCT != ${COMP_WORDS[1]} ]] ; then
|
||||
ANDROID_LUNCH_COMPLETION_RELEASE_CACHE=$(list_releases ${COMP_WORDS[1]})
|
||||
ANDROID_LUNCH_COMPLETION_CHOSEN_PRODUCT=${COMP_WORDS[1]}
|
||||
fi
|
||||
COMPREPLY=( $(compgen -W "${ANDROID_LUNCH_COMPLETION_RELEASE_CACHE}" -- "${COMP_WORDS[COMP_CWORD]}") )
|
||||
fi
|
||||
|
||||
# Available variants
|
||||
if [[ $COMP_CWORD -eq 3 ]] ; then
|
||||
COMPREPLY=(user userdebug eng)
|
||||
fi
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
|
||||
# Configures the build to build unbundled apps.
|
||||
# Run tapas with one or more app names (from LOCAL_PACKAGE_NAME)
|
||||
function tapas()
|
||||
|
|
229
tools/envsetup/run_envsetup_tests
Executable file
229
tools/envsetup/run_envsetup_tests
Executable file
|
@ -0,0 +1,229 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
# Copyright (C) 2024 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.
|
||||
|
||||
import os
|
||||
import pathlib
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
SOURCE_ENVSETUP="source build/make/envsetup.sh && "
|
||||
|
||||
def update_display():
|
||||
sys.stderr.write("passed\n")
|
||||
|
||||
def go_to_root():
|
||||
while True:
|
||||
if os.path.exists("build/make/envsetup.sh"):
|
||||
return
|
||||
if os.getcwd() == "/":
|
||||
sys.stderr.write("Can't find root of the source tree\n");
|
||||
print("\nFAILED")
|
||||
sys.exit(1)
|
||||
os.chdir("..")
|
||||
|
||||
def is_test(name, thing):
|
||||
if not callable(thing):
|
||||
return False
|
||||
if name == "test":
|
||||
return False
|
||||
return name.startswith("test")
|
||||
|
||||
|
||||
def test(shell, command, expected_return, expected_stdout, expected_stderr, expected_env):
|
||||
command += "; _rc=$?"
|
||||
for env in expected_env.keys():
|
||||
command += f"; echo ENV: {env}=\\\"${env}\\\""
|
||||
command += "; exit $_rc"
|
||||
|
||||
cmd = [shell, "-c", command]
|
||||
result = subprocess.run(cmd, capture_output=True, text=True)
|
||||
|
||||
status = True
|
||||
|
||||
if result.returncode != expected_return:
|
||||
print()
|
||||
print(f"Expected return code: {expected_return}")
|
||||
print(f"Actual return code: {result.returncode}")
|
||||
status = False
|
||||
|
||||
printed_stdout = False
|
||||
if expected_stdout and expected_stdout not in result.stdout:
|
||||
print()
|
||||
print(f"Expected stdout to contain:\n{expected_stdout}")
|
||||
print(f"\nActual stdout:\n{result.stdout}")
|
||||
printed_stdout = True
|
||||
status = False
|
||||
|
||||
if expected_stderr and expected_stderr not in result.stderr:
|
||||
print()
|
||||
print(f"Expected stderr to contain:\n{expected_stderr}")
|
||||
print(f"\nActual stderr:\n{result.stderr}")
|
||||
status = False
|
||||
|
||||
env_failure = False
|
||||
for k, v in expected_env.items():
|
||||
if f"{k}=\"{v}\"" not in result.stdout:
|
||||
print()
|
||||
print(f"Expected environment variable {k} to be: {v} --- {k}=\"{v}\"")
|
||||
env_failure = True
|
||||
status = False
|
||||
|
||||
if env_failure and not printed_stdout:
|
||||
print()
|
||||
print("See stdout:")
|
||||
print(result.stdout)
|
||||
|
||||
if not status:
|
||||
print()
|
||||
print("Command to reproduce:")
|
||||
print(command)
|
||||
print()
|
||||
|
||||
return status
|
||||
|
||||
NO_LUNCH = {
|
||||
"TARGET_PRODUCT": "",
|
||||
"TARGET_RELEASE": "",
|
||||
"TARGET_BUILD_VARIANT": "",
|
||||
}
|
||||
|
||||
def test_invalid_lunch_target(shell):
|
||||
return test(shell, SOURCE_ENVSETUP + "lunch invalid-trunk_staging-eng",
|
||||
expected_return=1, expected_stdout=None,
|
||||
expected_stderr="Cannot locate config makefile for product",
|
||||
expected_env=NO_LUNCH)
|
||||
|
||||
|
||||
def test_aosp_arm(shell):
|
||||
return test(shell, SOURCE_ENVSETUP + "lunch aosp_arm-trunk_staging-eng",
|
||||
expected_return=0, expected_stdout=None, expected_stderr=None,
|
||||
expected_env={
|
||||
"TARGET_PRODUCT": "aosp_arm",
|
||||
"TARGET_RELEASE": "trunk_staging",
|
||||
"TARGET_BUILD_VARIANT": "eng",
|
||||
})
|
||||
|
||||
|
||||
def test_lunch2_empty(shell):
|
||||
return test(shell, SOURCE_ENVSETUP + "lunch2",
|
||||
expected_return=1, expected_stdout=None,
|
||||
expected_stderr="No target specified. See lunch --help",
|
||||
expected_env=NO_LUNCH)
|
||||
|
||||
def test_lunch2_four_params(shell):
|
||||
return test(shell, SOURCE_ENVSETUP + "lunch2 a b c d",
|
||||
expected_return=1, expected_stdout=None,
|
||||
expected_stderr="Too many parameters given. See lunch --help",
|
||||
expected_env=NO_LUNCH)
|
||||
|
||||
def test_lunch2_aosp_arm(shell):
|
||||
return test(shell, SOURCE_ENVSETUP + "lunch2 aosp_arm",
|
||||
expected_return=0, expected_stdout="=========", expected_stderr=None,
|
||||
expected_env={
|
||||
"TARGET_PRODUCT": "aosp_arm",
|
||||
"TARGET_RELEASE": "trunk_staging",
|
||||
"TARGET_BUILD_VARIANT": "eng",
|
||||
})
|
||||
|
||||
def test_lunch2_aosp_arm_trunk_staging(shell):
|
||||
# Somewhat unfortunate because trunk_staging is the only config in
|
||||
# aosp so we can't really test that this isn't just getting the default
|
||||
return test(shell, SOURCE_ENVSETUP + "lunch2 aosp_arm trunk_staging",
|
||||
expected_return=0, expected_stdout="=========", expected_stderr=None,
|
||||
expected_env={
|
||||
"TARGET_PRODUCT": "aosp_arm",
|
||||
"TARGET_RELEASE": "trunk_staging",
|
||||
"TARGET_BUILD_VARIANT": "eng",
|
||||
})
|
||||
|
||||
def test_lunch2_aosp_arm_trunk_staging_userdebug(shell):
|
||||
return test(shell, SOURCE_ENVSETUP + "lunch2 aosp_arm trunk_staging userdebug",
|
||||
expected_return=0, expected_stdout="=========", expected_stderr=None,
|
||||
expected_env={
|
||||
"TARGET_PRODUCT": "aosp_arm",
|
||||
"TARGET_RELEASE": "trunk_staging",
|
||||
"TARGET_BUILD_VARIANT": "userdebug",
|
||||
})
|
||||
|
||||
def test_list_products(shell):
|
||||
return test(shell, "build/soong/bin/list_products",
|
||||
expected_return=0, expected_stdout="aosp_arm", expected_stderr=None,
|
||||
expected_env=NO_LUNCH)
|
||||
|
||||
def test_list_releases_param(shell):
|
||||
return test(shell, "build/soong/bin/list_releases aosp_arm",
|
||||
expected_return=0, expected_stdout="trunk_staging", expected_stderr=None,
|
||||
expected_env=NO_LUNCH)
|
||||
|
||||
def test_list_releases_env(shell):
|
||||
return test(shell, "TARGET_PRODUCT=aosp_arm build/soong/bin/list_releases",
|
||||
expected_return=0, expected_stdout="trunk_staging", expected_stderr=None,
|
||||
expected_env=NO_LUNCH)
|
||||
|
||||
def test_list_releases_no_product(shell):
|
||||
return test(shell, "build/soong/bin/list_releases",
|
||||
expected_return=1, expected_stdout=None, expected_stderr=None,
|
||||
expected_env=NO_LUNCH)
|
||||
|
||||
def test_list_variants(shell):
|
||||
return test(shell, "build/soong/bin/list_variants",
|
||||
expected_return=0, expected_stdout="userdebug", expected_stderr=None,
|
||||
expected_env=NO_LUNCH)
|
||||
|
||||
|
||||
def test_get_build_var_in_path(shell):
|
||||
return test(shell, SOURCE_ENVSETUP + "which get_build_var ",
|
||||
expected_return=0, expected_stdout="soong/bin", expected_stderr=None,
|
||||
expected_env=NO_LUNCH)
|
||||
|
||||
|
||||
|
||||
TESTS=sorted([(name, thing) for name, thing in locals().items() if is_test(name, thing)])
|
||||
|
||||
def main():
|
||||
if any([x.endswith("/soong/bin") for x in os.getenv("PATH").split(":")]):
|
||||
sys.stderr.write("run_envsetup_tests must be run in a shell that has not sourced"
|
||||
+ " envsetup.sh\n\nFAILED\n")
|
||||
return 1
|
||||
|
||||
go_to_root()
|
||||
|
||||
tests = TESTS
|
||||
if len(sys.argv) > 1:
|
||||
tests = [(name, func) for name, func in tests if name in sys.argv]
|
||||
|
||||
shells = ["/usr/bin/bash", "/usr/bin/zsh"]
|
||||
total_count = len(tests) * len(shells)
|
||||
index = 1
|
||||
failed_tests = 0
|
||||
|
||||
for name, func in tests:
|
||||
for shell in shells:
|
||||
sys.stdout.write(f"\33[2K\r{index} of {total_count}: {name} in {shell}")
|
||||
passed = func(shell)
|
||||
if not passed:
|
||||
failed_tests += 1
|
||||
index += 1
|
||||
|
||||
if failed_tests > 0:
|
||||
print(f"\n\nFAILED: {failed_tests} of {total_count}")
|
||||
return 1
|
||||
else:
|
||||
print("\n\nSUCCESS")
|
||||
return 0
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
34
tools/envsetup/spam_for_lunch
Executable file
34
tools/envsetup/spam_for_lunch
Executable file
|
@ -0,0 +1,34 @@
|
|||
#!/bin/bash
|
||||
|
||||
# Copyright 2024, 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 ad is kind of big, so only show it if this appears to be a clean build.
|
||||
source $(cd $(dirname $BASH_SOURCE) &> /dev/null && pwd)/../../shell_utils.sh
|
||||
if [[ ! -e $(getoutdir)/soong/build.${TARGET_PRODUCT}.ninja ]]; then
|
||||
echo
|
||||
echo "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
|
||||
echo " Wondering whether to use user, userdebug or eng?"
|
||||
echo
|
||||
echo " user The builds that ship to users. Reduced debugability."
|
||||
echo " userdebug High fidelity to user builds but with some debugging options"
|
||||
echo " enabled. Best suited for performance testing or day-to-day use"
|
||||
echo " with debugging enabled."
|
||||
echo " eng More debugging options enabled and faster build times, but"
|
||||
echo " runtime performance tradeoffs. Best suited for day-to-day"
|
||||
echo " local development when not doing performance testing."
|
||||
echo "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
|
||||
echo
|
||||
fi
|
||||
|
Loading…
Reference in a new issue