blob: 8293f8fdacd5c3057b04544acec3cf4d7f84d7c0 [file] [log] [blame]
#!/bin/bash
set -e
set -m
# This is a wrapper script that runs the specific version of Android Studio that is recommended for developing in this repository.
# (This serves a similar purpose to gradlew)
#
# NOTE: if you are changing this file, consider applying the changes to ../studiow, used for the main AndroidX project.
function getPrebuiltStudioZipPath() {
version="$(grep "studio_version=" ${propertiesFile} | sed 's/[^=]*=//')"
ideaMajorVersion="$(grep "idea_major_version=" ${propertiesFile} | sed 's/[^=]*=//')"
buildNumber="$(grep "studio_build_number=" ${propertiesFile} | sed 's/[^=]*=//')"
osName="$1"
if [ "${osName}" == "linux" ]; then
extension="tar.gz"
else
extension="zip"
fi
echo "${scriptDir}/../../../prebuilts/androidx/studio/android-studio-ide-${ideaMajorVersion}.${buildNumber}-${osName}.${extension}"
}
acceptsLicenseAgreement="$1"
scriptDir="$(cd $(dirname $0) && pwd)"
projectDir=$scriptDir
tempDir="${scriptDir}/studio"
function getOsName() {
unameOutput="$(uname)"
osName=""
if [ "${unameOutput}" == "Linux" ]; then
osName="linux"
else
osName="mac"
fi
echo "${osName}"
}
osName="$(getOsName)"
propertiesFile="${scriptDir}/studio_versions.properties"
prebuiltStudioZipPath="$(getPrebuiltStudioZipPath $osName)"
studioDestName="$(basename ${prebuiltStudioZipPath})"
studioUnzippedPath="${tempDir}/${studioDestName}"
studioUnzippedPath="$(echo ${studioUnzippedPath} | sed 's/\.zip$//' | sed 's/\.tar.gz$//')"
# The version of AGP we should override with - may be empty if we should just use the default
# version specified in AndroidX. See ui/studio_versions.properties.
agp_override="$(grep "agp_override=" ${propertiesFile} | sed 's/[^=]*=//')"
# Set the env variable if we have a valid version to override with, else noop
GRADLE_PLUGIN_VERSION_OVERRIDE=""
[ ! -z "$agp_override" ] && GRADLE_PLUGIN_VERSION_OVERRIDE="GRADLE_PLUGIN_VERSION=${agp_override}"
function error_exit {
echo "$1" >&2 ## Send message to stderr.
exit 1
}
function downloadFile() {
fromUrl="$1"
destPath="$2"
tempPath="${destPath}.tmp"
if [ -f "${destPath}" ]; then
read -r -n 1 -p "File already exists. Do you want to delete and re-download? [Y/n]? " reply
if [ ! -z "${reply}" ]; then
# Fix missing newline
echo
fi
case "${reply}" in
[yY]|"")
rm "${destPath}"
;;
*)
esac
fi
if [ -f "${destPath}" ]; then
echo "Using existing file from ${destPath}"
else
echo "Downloading ${fromUrl} to ${destPath}"
curl "${fromUrl}" > "${tempPath}"
mv "${tempPath}" "${destPath}"
fi
}
function findStudioMacAppPath() {
echo "$(find "${studioUnzippedPath}" -type d -depth 1 -name "Android Studio*.app")"
}
function getLicensePath() {
if [ "${osName}" == "mac" ]; then
appPath="$(findStudioMacAppPath)"
echo "${appPath}/Contents/Resources/LICENSE.txt"
else
echo "${studioUnzippedPath}/android-studio/LICENSE.txt"
fi
}
function checkLicenseAgreement() {
# TODO: Is there a more official way to check that the user accepts the license?
licenseAcceptedPath="${studioUnzippedPath}/STUDIOW_LICENSE_ACCEPTED"
if [ ! -f "${licenseAcceptedPath}" ]; then
if [ "${acceptsLicenseAgreement}" == "-y" ]; then
touch "${licenseAcceptedPath}"
else
read -r -n 1 -p "Do you accept the license agreement at $(getLicensePath) [Y/n]? " reply
if [ ! -z "${reply}" ]; then
# Fix missing newline
echo
fi
case "${reply}" in
[yY]|"")
touch "${licenseAcceptedPath}"
;;
*)
exit 1
;;
esac
fi
fi
}
# Temporary fix. Remove this after fixing b/135183535
function updateJvmHeapSize() {
if [ "${osName}" == "mac" ]; then
sed -i '' 's/-Xmx.*/-Xmx8g/' "$(findStudioMacAppPath)/Contents/bin/studio.vmoptions"
else
sed -i 's/-Xmx.*/-Xmx8g/' "${studioUnzippedPath}/android-studio/bin/studio64.vmoptions"
sed -i 's/-Xmx.*/-Xmx4g/' "${studioUnzippedPath}/android-studio/bin/studio.vmoptions"
fi
}
function updateStudio() {
# skip if already up-to-date
if stat "${studioUnzippedPath}" >/dev/null 2>/dev/null; then
# already up-to-date
return
fi
mkdir -p "${tempDir}"
echo "Removing previous installations"
ls "${tempDir}" | grep -v "^${studioDestName}\$" | sed "s|^|${tempDir}/|" | xargs rm -rf
echo "Unzipping"
if [ "${osName}" == "linux" ]; then
mkdir $studioUnzippedPath
tar -xzf "${prebuiltStudioZipPath}" --directory "${studioUnzippedPath}"
else
unzip "${prebuiltStudioZipPath}" -d "${studioUnzippedPath}"
fi
}
# Copies the built compose-ide-plugin to the plugin directory of the studio installation. This
# ensures that the compose plugin is used at startup
function updateComposeIdePlugin() {
if [ "${osName}" == "mac" ]; then
composeIdePluginDirectory="$(findStudioMacAppPath)/Contents/plugins/compose-ide-plugin/"
else
composeIdePluginDirectory="${studioUnzippedPath}/android-studio/plugins/"
fi
# this is the idea sandbox directory that the compose ide plugin is located in
composePluginDirectory="${projectDir}/../../../out/ui/compose/compose-ide-plugin/build/idea-sandbox/plugins/compose-ide-plugin/"
echo ""
echo "Copying compose-ide-plugin to $composeIdePluginDirectory"
echo ""
mkdir -p "${composeIdePluginDirectory}"
cp -f -R "${composePluginDirectory}" "${composeIdePluginDirectory}"
}
function ensureCompose() {
# This gradle command will prepare a sandbox directory that we can point studio to that will
# have all of the correct structure to load the compose plugin
${scriptDir}/gradlew -p ${projectDir} :compose:compose-ide-plugin:prepareSandbox
}
# ANDROID_LINT_NULLNESS_IGNORE_DEPRECATED environment variable prevents Studio from showing IDE
# inspection warnings for nullability issues, if the context is deprecated
# This environment variable is consumed by InteroperabilityDetector.kt
function runStudioLinux() {
studioPath="${studioUnzippedPath}/android-studio/bin/studio.sh"
updateComposeIdePlugin
echo ""
echo "Launching Studio"
# Override AGP version overridden because compose studio is behind androidx studio
env STUDIO_PROPERTIES="${projectDir}/idea.properties" \
STUDIO_VM_OPTIONS="${projectDir}/../development/studio/studio.vmoptions" \
ANDROID_LINT_NULLNESS_IGNORE_DEPRECATED="true" \
KOTLIN_OVERRIDE="1.3.60-withExperimentalGoogleExtensions-20191010" \
$GRADLE_PLUGIN_VERSION_OVERRIDE \
"${studioPath}" "${projectDir}" &
}
function runStudioMac() {
appPath="$(findStudioMacAppPath)"
updateComposeIdePlugin
echo ""
echo "Launching Studio"
# Override AGP version overridden because compose studio is behind androidx studio
env STUDIO_PROPERTIES="${projectDir}/idea.properties" \
STUDIO_VM_OPTIONS="${projectDir}/../development/studio/studio.vmoptions" \
ANDROID_LINT_NULLNESS_IGNORE_DEPRECATED="true" \
KOTLIN_OVERRIDE="1.3.60-withExperimentalGoogleExtensions-20191010" \
$GRADLE_PLUGIN_VERSION_OVERRIDE \
open -a "${appPath}" "${projectDir}"
}
function runStudio() {
updateJvmHeapSize
if [ "${osName}" == "mac" ]; then
runStudioMac
else
runStudioLinux
fi
}
function main() {
updateStudio
ensureCompose
checkLicenseAgreement
runStudio
}
main