| #!/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.50-compose-20190806" \ |
| $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.50-compose-20190806" \ |
| $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 |