diff --git a/.bazelci/android-studio.yml b/.bazelci/android-studio.yml index 5bc832adade..f7239e5e3cf 100644 --- a/.bazelci/android-studio.yml +++ b/.bazelci/android-studio.yml @@ -2,7 +2,7 @@ tasks: Android-Studio-internal-stable: name: Android Studio Internal Stable - platform: ubuntu1804 + platform: ubuntu2204 build_flags: - --define=ij_product=android-studio-latest build_targets: @@ -14,7 +14,7 @@ tasks: - //:aswb_tests Android-Studio-internal-beta: name: Android Studio Internal Beta - platform: ubuntu1804 + platform: ubuntu2204 build_flags: - --define=ij_product=android-studio-beta build_targets: @@ -26,7 +26,7 @@ tasks: - //:aswb_tests Android-Studio-internal-canary: name: Android Studio Internal Canary - platform: ubuntu1804 + platform: ubuntu2204 build_flags: - --define=ij_product=android-studio-canary build_targets: @@ -40,7 +40,7 @@ tasks: - exit_status: 1 Android-Studio-OSS-oldest-stable: name: Android Studio OSS Oldest Stable - platform: ubuntu1804 + platform: ubuntu2204 build_flags: - --define=ij_product=android-studio-oss-oldest-stable build_targets: @@ -52,7 +52,7 @@ tasks: - //:aswb_tests Android-Studio-OSS-latest-stable: name: Android Studio OSS Latest Stable - platform: ubuntu1804 + platform: ubuntu2204 build_flags: - --define=ij_product=android-studio-oss-latest-stable build_targets: @@ -64,7 +64,7 @@ tasks: - //:aswb_tests Android-Studio-OSS-under-dev: name: Android Studio OSS Under Development - platform: ubuntu1804 + platform: ubuntu2204 build_flags: - --define=ij_product=android-studio-oss-under-dev build_targets: diff --git a/.bazelci/aspect.yml b/.bazelci/aspect.yml index 14afdca1bcf..f170a74bf13 100644 --- a/.bazelci/aspect.yml +++ b/.bazelci/aspect.yml @@ -1,52 +1,8 @@ --- tasks: - Aspect-internal-stable: - name: Aspect Tests for IJ Internal Stable - platform: ubuntu1804 - build_flags: - - --define=ij_product=intellij-latest - build_targets: - - //aspect:aspect_files - test_flags: - - --define=ij_product=intellij-latest - - --test_output=errors - - --notrim_test_configuration - test_targets: - - //aspect/testing/... - skip_use_bazel_version_for_test: true - Aspect-internal-beta: - name: Aspect Tests for IJ Internal Beta - platform: ubuntu1804 - build_flags: - - --define=ij_product=intellij-beta - build_targets: - - //aspect:aspect_files - test_flags: - - --define=ij_product=intellij-beta - - --test_output=errors - - --notrim_test_configuration - test_targets: - - //aspect/testing/... - skip_use_bazel_version_for_test: true - Aspect-internal-under-dev: - name: Aspect Tests for IJ Internal Under Development - platform: ubuntu1804 - build_flags: - - --define=ij_product=intellij-under-dev - build_targets: - - //aspect:aspect_files - test_flags: - - --define=ij_product=intellij-under-dev - - --test_output=errors - - --notrim_test_configuration - test_targets: - - //aspect/testing/... - soft_fail: - - exit_status: 1 - skip_use_bazel_version_for_test: true - Aspect-oss-oldest-stable: + Aspect-OSS-oldest-stable: name: Aspect Tests for IJ OSS Oldest Stable - platform: ubuntu1804 + platform: ubuntu2204 build_flags: - --define=ij_product=intellij-oss-oldest-stable build_targets: @@ -58,9 +14,9 @@ tasks: test_targets: - //aspect/testing/... skip_use_bazel_version_for_test: true - Aspect-oss-latest-stable: + Aspect-OSS-latest-stable: name: Aspect Tests for IJ OSS Latest Stable - platform: ubuntu1804 + platform: ubuntu2204 build_flags: - --define=ij_product=intellij-oss-latest-stable build_targets: @@ -72,9 +28,9 @@ tasks: test_targets: - //aspect/testing/... skip_use_bazel_version_for_test: true - Aspect-oss-under-dev: + Aspect-OSS-under-dev: name: Aspect Tests for IJ OSS Under Development - platform: ubuntu1804 + platform: ubuntu2204 build_flags: - --define=ij_product=intellij-oss-under-dev build_targets: diff --git a/.bazelci/clion.yml b/.bazelci/clion.yml index e1175d2579c..04261221c73 100644 --- a/.bazelci/clion.yml +++ b/.bazelci/clion.yml @@ -1,74 +1,121 @@ --- tasks: - CLion-internal-stable: - name: CLion Internal Stable - platform: ubuntu1804 + CLion-Linux-OSS-oldest-stable: + name: CLion Linux OSS Oldest Stable + platform: ubuntu2204 build_flags: - - --define=ij_product=clion-latest + - --define=ij_product=clion-oss-oldest-stable build_targets: - - //clwb/... + - //clwb:clwb_bazel_zip + - //:clwb_tests test_flags: - - --define=ij_product=clion-latest + - --define=ij_product=clion-oss-oldest-stable - --test_output=errors test_targets: - //:clwb_tests - CLion-internal-beta: - name: CLion Internal Beta - platform: ubuntu1804 + CLion-Linux-OSS-latest-stable: + name: CLion Linux OSS Latest Stable + platform: ubuntu2204 build_flags: - - --define=ij_product=clion-beta + - --define=ij_product=clion-oss-latest-stable build_targets: - - //clwb/... + - //clwb:clwb_bazel_zip + - //:clwb_tests test_flags: - - --define=ij_product=clion-beta + - --define=ij_product=clion-oss-latest-stable - --test_output=errors test_targets: - //:clwb_tests - CLion-internal-under-dev: - name: CLion Internal Under Development - platform: ubuntu1804 + CLion-Windows-OSS-oldest-stable: + name: CLion Windows OSS Oldest Stable + platform: windows build_flags: - - --define=ij_product=clion-under-dev + - --define=ij_product=clion-oss-oldest-stable build_targets: - - //clwb/... + - //clwb:clwb_bazel_zip + - //:clwb_tests test_flags: - - --define=ij_product=clion-under-dev + - --define=ij_product=clion-oss-oldest-stable - --test_output=errors test_targets: + - //clwb:integration_tests + CLion-Windows-OSS-latest-stable: + name: CLion Windows OSS Latest Stable + platform: windows + build_flags: + - --define=ij_product=clion-oss-latest-stable + build_targets: + - //clwb:clwb_bazel_zip - //:clwb_tests - soft_fail: - - exit_status: 1 - CLion-OSS-oldest-stable: - name: CLion OSS Oldest Stable - platform: ubuntu1804 + test_flags: + - --define=ij_product=clion-oss-latest-stable + - --test_output=errors + test_targets: + - //clwb:integration_tests + CLion-MacOS-OSS-oldest-stable: + name: CLion MacOS OSS Oldest Stable + platform: macos_arm64 build_flags: - --define=ij_product=clion-oss-oldest-stable build_targets: - - //clwb/... + - //clwb:clwb_bazel_zip + - //:clwb_tests test_flags: - --define=ij_product=clion-oss-oldest-stable - --test_output=errors test_targets: - //:clwb_tests - CLion-OSS-latest-stable: - name: CLion OSS Latest Stable - platform: ubuntu1804 + CLion-MacOS-OSS-latest-stable: + name: CLion MacOS OSS Latest Stable + platform: macos_arm64 build_flags: - --define=ij_product=clion-oss-latest-stable build_targets: - - //clwb/... + - //clwb:clwb_bazel_zip + - //:clwb_tests test_flags: - --define=ij_product=clion-oss-latest-stable - --test_output=errors test_targets: - //:clwb_tests - CLion-OSS-under-dev: - name: CLion OSS Under Development - platform: ubuntu1804 + CLion-Linux-OSS-under-dev: + name: CLion Linux OSS Under Development + platform: ubuntu2204 + build_flags: + - --define=ij_product=clion-oss-under-dev + build_targets: + - //clwb:clwb_bazel_zip + - //:clwb_tests + test_flags: + - --define=ij_product=clion-oss-under-dev + - --test_output=errors + test_targets: + - //:clwb_tests + soft_fail: + - exit_status: 1 + CLion-Windows-OSS-under-dev: + name: CLion Windows OSS Under Development + platform: windows build_flags: - --define=ij_product=clion-oss-under-dev build_targets: - - //clwb/... + - //clwb:clwb_bazel_zip + - //:clwb_tests + test_flags: + - --define=ij_product=clion-oss-under-dev + - --test_output=errors + test_targets: + - //clwb:integration_tests + soft_fail: + - exit_status: 1 + CLion-MacOS-OSS-under-dev: + name: CLion MacOS OSS Under Development + platform: macos_arm64 + build_flags: + - --define=ij_product=clion-oss-under-dev + build_targets: + - //clwb:clwb_bazel_zip + - //:clwb_tests test_flags: - --define=ij_product=clion-oss-under-dev - --test_output=errors diff --git a/.bazelci/intellij-ue.yml b/.bazelci/intellij-ue.yml index 817dbbcd74d..e045463efca 100644 --- a/.bazelci/intellij-ue.yml +++ b/.bazelci/intellij-ue.yml @@ -1,46 +1,8 @@ --- tasks: - IntelliJ-UE-internal-stable: - name: IntelliJ UE Internal Stable - platform: ubuntu1804 - build_flags: - - --define=ij_product=intellij-ue-latest - build_targets: - - //ijwb/... - test_flags: - - --define=ij_product=intellij-ue-latest - - --test_output=errors - test_targets: - - //:ijwb_ue_tests - IntelliJ-UE-internal-beta: - name: IntelliJ UE Internal Beta - platform: ubuntu1804 - build_flags: - - --define=ij_product=intellij-ue-beta - build_targets: - - //ijwb/... - test_flags: - - --define=ij_product=intellij-ue-beta - - --test_output=errors - test_targets: - - //:ijwb_ue_tests - IntelliJ-UE-internal-under-dev: - name: IntelliJ UE Internal Under Development - platform: ubuntu1804 - build_flags: - - --define=ij_product=intellij-ue-under-dev - build_targets: - - //ijwb/... - test_flags: - - --define=ij_product=intellij-ue-under-dev - - --test_output=errors - test_targets: - - //:ijwb_ue_tests - soft_fail: - - exit_status: 1 IntelliJ-UE-OSS-oldest-stable: name: IntelliJ UE OSS Oldest Stable - platform: ubuntu1804 + platform: ubuntu2204 build_flags: - --define=ij_product=intellij-ue-oss-oldest-stable build_targets: @@ -52,7 +14,7 @@ tasks: - //:ijwb_ue_tests IntelliJ-UE-OSS-latest-stable: name: IntelliJ UE OSS Latest Stable - platform: ubuntu1804 + platform: ubuntu2204 build_flags: - --define=ij_product=intellij-ue-oss-latest-stable build_targets: @@ -64,7 +26,7 @@ tasks: - //:ijwb_ue_tests IntelliJ-UE-OSS-under-dev: name: IntelliJ UE OSS Under Development - platform: ubuntu1804 + platform: ubuntu2204 build_flags: - --define=ij_product=intellij-ue-oss-under-dev build_targets: @@ -76,4 +38,24 @@ tasks: - //:ijwb_ue_tests soft_fail: - exit_status: 1 - + IntelliJ-UE-OSS-under-dev-windows: + name: IntelliJ UE OSS Under Development + platform: windows + build_flags: + - --define=ij_product=intellij-ue-oss-under-dev + build_targets: + - //ijwb/... + soft_fail: + - exit_status: 1 + Querysync: + name: Querysync Library + platform: ubuntu2204 + build_flags: + - --define=ij_product=intellij-ue-oss-under-dev + build_targets: + - //querysync/... + test_flags: + - --define=ij_product=intellij-ue-oss-under-dev + - --test_output=errors + test_targets: + - //querysync/... diff --git a/.bazelci/intellij.yml b/.bazelci/intellij.yml index 722bafbd29e..1d826389d83 100644 --- a/.bazelci/intellij.yml +++ b/.bazelci/intellij.yml @@ -1,46 +1,8 @@ --- tasks: - IntelliJ-CE-internal-stable: - name: IntelliJ CE Internal Stable - platform: ubuntu1804 - build_flags: - - --define=ij_product=intellij-latest - build_targets: - - //ijwb/... - test_flags: - - --define=ij_product=intellij-latest - - --test_output=errors - test_targets: - - //:ijwb_ce_tests - IntelliJ-CE-internal-beta: - name: IntelliJ CE Internal Beta - platform: ubuntu1804 - build_flags: - - --define=ij_product=intellij-beta - build_targets: - - //ijwb/... - test_flags: - - --define=ij_product=intellij-beta - - --test_output=errors - test_targets: - - //:ijwb_ce_tests - IntelliJ-CE-internal-under-dev: - name: IntelliJ CE Internal Under Development - platform: ubuntu1804 - build_flags: - - --define=ij_product=intellij-under-dev - build_targets: - - //ijwb/... - test_flags: - - --define=ij_product=intellij-under-dev - - --test_output=errors - test_targets: - - //:ijwb_ce_tests - soft_fail: - - exit_status: 1 IntelliJ-CE-OSS-oldest-stable: name: IntelliJ CE OSS Oldest Stable - platform: ubuntu1804 + platform: ubuntu2204 build_flags: - --define=ij_product=intellij-oss-oldest-stable build_targets: @@ -52,7 +14,7 @@ tasks: - //:ijwb_ce_tests IntelliJ-CE-OSS-latest-stable: name: IntelliJ CE OSS Latest Stable - platform: ubuntu1804 + platform: ubuntu2204 build_flags: - --define=ij_product=intellij-oss-latest-stable build_targets: @@ -64,7 +26,7 @@ tasks: - //:ijwb_ce_tests IntelliJ-CE-OSS-under-dev: name: IntelliJ CE OSS Under Development - platform: ubuntu1804 + platform: ubuntu2204 build_flags: - --define=ij_product=intellij-oss-under-dev build_targets: @@ -76,4 +38,13 @@ tasks: - //:ijwb_ce_tests soft_fail: - exit_status: 1 + IntelliJ-CE-OSS-under-dev-windows: + name: IntelliJ CE OSS Under Development + platform: windows + build_flags: + - --define=ij_product=intellij-oss-under-dev + build_targets: + - //ijwb/... + soft_fail: + - exit_status: 1 diff --git a/.bazelrc b/.bazelrc index 2dfae9d231c..ccd18f15a2f 100644 --- a/.bazelrc +++ b/.bazelrc @@ -1,6 +1,22 @@ -build --java_language_version=17 --javacopt=-source --javacopt=8 --javacopt=-target --javacopt=8 -test --java_language_version=17 --javacopt=-source --javacopt=8 --javacopt=-target --javacopt=8 --java_runtime_version=17 +build --java_language_version=17 --java_runtime_version=17 +build --tool_java_language_version=17 --tool_java_runtime_version=17 -# delete testdata package needed for bazel integration tests -build --deleted_packages=//aspect/testing/tests/src/com/google/idea/blaze/aspect/integration/testdata -query --deleted_packages=//aspect/testing/tests/src/com/google/idea/blaze/aspect/integration/testdata +# Delete test data packages, needed for bazel integration tests. Update by running the following command: +# bazel run @rules_bazel_integration_test//tools:update_deleted_packages +build --deleted_packages=aspect/testing/tests/src/com/google/idea/blaze/aspect/integration/testdata,clwb/tests/projects/simple/main,clwb/tests/projects/virtual_includes/lib/strip_absolut,clwb/tests/projects/virtual_includes/lib/strip_relative,clwb/tests/projects/virtual_includes/main,clwb/tests/projects/llvm_toolchain/main,clwb/tests/projects/external_includes/main,clwb/tests/projects/virtual_includes/lib/impl_deps +query --deleted_packages=aspect/testing/tests/src/com/google/idea/blaze/aspect/integration/testdata,clwb/tests/projects/simple/main,clwb/tests/projects/virtual_includes/lib/strip_absolut,clwb/tests/projects/virtual_includes/lib/strip_relative,clwb/tests/projects/virtual_includes/main,clwb/tests/projects/llvm_toolchain/main,clwb/tests/projects/external_includes/main,clwb/tests/projects/virtual_includes/lib/impl_deps + +common --enable_bzlmod +common --enable_workspace # to load rules_scala from WORKSPACE.bzlmod +common --android_sdk=@androidsdk//:sdk +common --noincompatible_disallow_empty_glob + +# Disabled by default in bazel 8, https://github.com/bazelbuild/bazel/issues/24578 +test --zip_undeclared_test_outputs + +# Enabled by default in bazel 8 +common --incompatible_use_plus_in_repo_names + +# Required for CLion integration tests on windows +startup --windows_enable_symlinks +build --enable_runfiles diff --git a/.bazelversion b/.bazelversion new file mode 100644 index 00000000000..fa5fce04b3c --- /dev/null +++ b/.bazelversion @@ -0,0 +1 @@ +8.0.0 \ No newline at end of file diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index 8579f9b86ec..121688bf0c2 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -1,5 +1,6 @@ name: Bug Report description: File a bug report +labels: ["type: bug", "awaiting-maintainer"] body: - type: markdown attributes: @@ -12,6 +13,18 @@ body: attributes: label: > Description of the bug: + - type: dropdown + id: subteam + attributes: + label: Which category does this issue belong to? + description: Help us triage this issue faster and more accurately to the relevant team(s). + multiple: true + options: + - Intellij + - GoLand + - CLion + - PyCharm + - Android Studio - type: textarea id: repro attributes: diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml index 80e4a398e48..c41a1fe443d 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.yml +++ b/.github/ISSUE_TEMPLATE/feature_request.yml @@ -1,5 +1,6 @@ name: Feature Request description: Suggest a new feature +labels: ["type: feature request", "awaiting-maintainer"] body: - type: markdown attributes: @@ -12,6 +13,18 @@ body: attributes: label: > Description of the feature request: + - type: dropdown + id: subteam + attributes: + label: Which category does this issue belong to? + description: Help us triage this issue faster and more accurately to the relevant team(s). + multiple: true + options: + - Intellij + - GoLand + - CLion + - PyCharm + - Android Studio - type: textarea id: problem attributes: diff --git a/.github/advanced-issue-labeler.yml b/.github/advanced-issue-labeler.yml new file mode 100644 index 00000000000..071ee485459 --- /dev/null +++ b/.github/advanced-issue-labeler.yml @@ -0,0 +1,17 @@ +--- + +policy: + - template: [bug_report.yml, feature_request.yml] + section: + - id: [subteam] + label: + - name: 'product: IntelliJ' + keys: ['Intellij'] + - name: 'product: GoLand' + keys: ['GoLand'] + - name: 'product: CLion' + keys: ['CLion'] + - name: 'product: PyCharm' + keys: ['PyCharm'] + - name: 'product: Android Studio' + keys: ['Android Studio'] diff --git a/.github/labeler.yml b/.github/labeler.yml new file mode 100644 index 00000000000..d071fd8222d --- /dev/null +++ b/.github/labeler.yml @@ -0,0 +1,53 @@ +# Add 'awaiting-review' to any PR opened +awaiting-review: + - changed-files: + - any-glob-to-any-file: ['**/*'] + +'product: CLion': + - changed-files: + - any-glob-to-any-file: [ + 'clwb/**/*', + 'cpp/**/*', + 'base/**/*', + 'examples/cpp/simple_project/**/*', + 'intellij_platform_sdk/BUILD.clion213', + 'intellij_platform_sdk/BUILD.clion221', + 'intellij_platform_sdk/BUILD.clion222', + 'intellij_platform_sdk/BUILD.clion223', + 'intellij_platform_sdk/BUILD.clion231', + 'intellij_platform_sdk/BUILD.clion232' + ] + +'product: IntelliJ': + - changed-files: + - any-glob-to-any-file: [ + 'base/**/*', + 'examples/java/greetings_project/**/*', + 'ijwb/**/*', + 'kotlin/**/*', + 'java/**/*', + 'examples/kotlin/**/*', + 'javascript/**/*', + 'python/**/*', + 'scala/**/*', + 'intellij_platform_sdk/BUILD.idea221', + 'intellij_platform_sdk/BUILD.idea222', + 'intellij_platform_sdk/BUILD.idea223', + 'intellij_platform_sdk/BUILD.idea231', + 'intellij_platform_sdk/BUILD.idea232', + 'intellij_platform_sdk/BUILD.ue213', + 'intellij_platform_sdk/BUILD.ue221', + 'intellij_platform_sdk/BUILD.ue222', + 'intellij_platform_sdk/BUILD.ue223', + 'intellij_platform_sdk/BUILD.ue231', + 'intellij_platform_sdk/BUILD.ue232' + ] + +'product: GoLand': + - changed-files: + - any-glob-to-any-file: [ + 'base/**/*', + 'examples/go/**/*', + 'gazelle/**/*', + 'golang/**/*' + ] diff --git a/.github/workflows/issue-assignee.yml b/.github/workflows/issue-assignee.yml new file mode 100644 index 00000000000..4c3fd2353b6 --- /dev/null +++ b/.github/workflows/issue-assignee.yml @@ -0,0 +1,59 @@ +name: Auto-add assignees to issues +on: + issues: + types: + - reopened + - opened +jobs: + add_label: + permissions: + contents: read + pull-requests: write + runs-on: ubuntu-latest + steps: + - uses: actions/labeler@v5 + add_assignee: + runs-on: ubuntu-latest + needs: add_label + permissions: + contents: read + issues: write + steps: + - name: Check out code + uses: actions/checkout@v4 + - name: Set assignees + uses: actions/github-script@v7 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + result-encoding: string + retries: 3 + retry-exempt-status-codes: 400,401 + script: | + let issue_number = context.payload.issue.number; + const labels = (await github.rest.issues.listLabelsOnIssue({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + })).data.map(label => label.name); + const labelToAssignees = { + 'product: CLion': ['ujohnny'], + 'product: IntelliJ': ['sellophane'], + 'product: GoLand': ['iliakondratev'], + 'product: Android Studio': ['mai93'], + 'product: PyCharm': ['agluszak'] + }; + const assignees = labels.some(label => label.startsWith('product:')) + ? labels.reduce((acc, label) => { + const assignee = label in labelToAssignees ? labelToAssignees[label] : []; + return acc.concat(assignee); + }, []) + : ['sgowroji', 'satyanandak', 'iancha1992']; + + if (assignees.length > 0) { + await github.rest.issues.addAssignees({ + issue_number, + owner: context.repo.owner, + repo: context.repo.repo, + assignees, + }); + } diff --git a/.github/workflows/issue-labeler.yml b/.github/workflows/issue-labeler.yml new file mode 100644 index 00000000000..d9a31d0e93c --- /dev/null +++ b/.github/workflows/issue-labeler.yml @@ -0,0 +1,33 @@ +--- + +name: Issue labeler +on: + issues: + types: [ opened ] + +jobs: + label-issues-policy: + runs-on: ubuntu-latest + permissions: + contents: read + issues: write + + strategy: + matrix: + template: [ bug_report.yml, feature_request.yml ] + + steps: + - uses: actions/checkout@v4 + + - name: Parse issue form + uses: stefanbuck/github-issue-parser@2d2ff50d4aae06ab58d26bf59468d98086605f11 # v3.2.1 + id: issue-parser + with: + template-path: .github/ISSUE_TEMPLATE/${{ matrix.template }} + + - name: Set labels based on policy + uses: redhat-plumbers-in-action/advanced-issue-labeler@d498805e5c7c0658e336948b3363480bcfd68da6 # v3.2.0 + with: + issue-form: ${{ steps.issue-parser.outputs.jsonString }} + template: ${{ matrix.template }} + token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/pr-label-and-assignee.yml b/.github/workflows/pr-label-and-assignee.yml new file mode 100644 index 00000000000..808d55b848e --- /dev/null +++ b/.github/workflows/pr-label-and-assignee.yml @@ -0,0 +1,58 @@ +name: Auto Add Labels and Assignees +on: + pull_request_target: + types: ["opened", "reopened", "ready_for_review"] + +jobs: + add_label: + permissions: + contents: read + pull-requests: write + runs-on: ubuntu-latest + steps: + - uses: actions/labeler@v5 + if: ${{ github.event.pull_request.draft == false }} + add_assignee: + runs-on: ubuntu-latest + needs: add_label + permissions: + contents: read + pull-requests: write + steps: + - name: Check out code + uses: actions/checkout@v4 + - name: Set Assignees + uses: actions/github-script@v7 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + result-encoding: string + retries: 3 + retry-exempt-status-codes: 400,401 + script: | + let issue_number = context.payload.pull_request.number; + const labels = (await github.rest.issues.listLabelsOnIssue({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + })).data.map(label => label.name); + const assignees = []; + const labelsToAssignees = { + 'product: CLion': ['ujohnny'], + 'product: IntelliJ': ['sellophane'], + 'product: GoLand': ['iliakondratev'], + 'product: Android Studio': ['mai93'], + 'product: PyCharm': ['agluszak'] + }; + for (const label of labels) { + if (label in labelsToAssignees) { + assignees.push(...labelsToAssignees[label]); + } + } + if (assignees.length > 0) { + await github.rest.issues.addAssignees({ + issue_number, + owner: context.repo.owner, + repo: context.repo.repo, + assignees + }); + } diff --git a/.github/workflows/remove-labels.yml b/.github/workflows/remove-labels.yml new file mode 100644 index 00000000000..9643cd40474 --- /dev/null +++ b/.github/workflows/remove-labels.yml @@ -0,0 +1,17 @@ +name: Remove PR Labels + +on: + pull_request_target: + types: ["closed", "merged"] + +jobs: + remove-label: + permissions: + contents: read + pull-requests: write + runs-on: ubuntu-latest + steps: + - uses: actions-ecosystem/action-remove-labels@v1 + with: + labels: | + awaiting-review diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml index 916fe58e133..8fd43f8abc6 100644 --- a/.github/workflows/stale.yml +++ b/.github/workflows/stale.yml @@ -20,7 +20,7 @@ jobs: steps: - name: Track and close stale issues/PRs - uses: actions/stale@v5 + uses: actions/stale@v9 with: repo-token: ${{ secrets.GITHUB_TOKEN }} days-before-issue-stale: 183 @@ -28,23 +28,17 @@ jobs: days-before-issue-close : 14 days-before-pr-close: 14 stale-issue-message: > - Thank you for contributing to the IntelliJ repository! + Thank you for contributing to the IntelliJ repository! This issue has been marked as stale since it has not had any activity in the last 6 months. It will be closed in the next 14 - days unless any other activity occurs or one of the following labels is added: "not stale", "awaiting-maintainer". Please reach out - to the triage team (`@bazelbuild/triage`) if you think this issue is still relevant or you are interested in getting the - issue resolved. + days unless any other activity occurs. If you think this issue is still relevant and should stay open, please post any comment here and the issue will no longer be marked as stale. close-issue-message: > - This issue has been automatically closed due to inactivity. If you're still interested in pursuing this, please reach out - to the triage team (`@bazelbuild/triage`). Thanks! + This issue has been automatically closed due to inactivity. If you're still interested in pursuing this, please post `@bazelbuild/triage` in a comment here and we'll take a look. Thanks! stale-pr-message: > Thank you for contributing to the IntelliJ repository! This pull request has been marked as stale since it has not had any activity in the last 6 months. It will be closed in the next - 14 days unless any other activity occurs or one of the following labels is added: "not stale", "awaiting-review". - Please reach out to the triage team (`@bazelbuild/triage`) if you think this PR is still relevant or you are interested in getting the - PR merged. + 14 days unless any other activity occurs. If you think this PR is still relevant and should stay open, please post any comment here and the PR will no longer be marked as stale. close-pr-message: > - This pull request has been automatically closed due to inactivity. If you're still interested in pursuing this, please reach out - to the triage team (`@bazelbuild/triage`). Thanks! + This pull request has been automatically closed due to inactivity. If you're still interested in pursuing this, please post `@bazelbuild/triage` in a comment here and we'll take a look. Thanks! stale-issue-label: 'stale' exempt-issue-labels: 'not stale,awaiting-maintainer,P0,P1' close-issue-reason: "not_planned" diff --git a/.gitignore b/.gitignore index 7e79f795f20..d7db09534b0 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,6 @@ bazel-* !bazel-buildifier .project -/.ijwb/ -/.aswb/ -/.clwb/ +.ijwb/ +.aswb/ +.clwb/ diff --git a/BUILD b/BUILD index 01f7c415e53..ebddd762d33 100644 --- a/BUILD +++ b/BUILD @@ -4,6 +4,7 @@ load( "//:build-visibility.bzl", "BAZEL_PLUGIN_SUBPACKAGES", + "DEFAULT_TEST_VISIBILITY", "create_plugin_packages_group", ) @@ -18,6 +19,7 @@ filegroup( visibility = BAZEL_PLUGIN_SUBPACKAGES, ) +# BEGIN-EXTERNAL # IJwB tests, run with an IntelliJ plugin SDK test_suite( name = "ijwb_common_tests", @@ -34,6 +36,7 @@ test_suite( "//plugin_dev:integration_tests", "//scala:integration_tests", "//scala:unit_tests", + "//skylark:unit_tests", ], ) @@ -63,38 +66,35 @@ test_suite( ], ) -# ASwB tests, run with an Android Studio plugin SDK +# CLwB tests, run with a CLion plugin SDK test_suite( - name = "aswb_tests", + name = "clwb_tests", tests = [ - "//aswb:integration_tests", - "//aswb:unit_tests", - "//base:integration_tests", "//base:unit_tests", - "//cpp:integration_tests", + "//clwb:unit_tests", + "//clwb:integration_tests", "//cpp:unit_tests", "//dart:unit_tests", - "//java:integration_tests", - "//java:unit_tests", - ], -) - -test_suite( - name = "aswb_python_tests", - tests = [ - "//python:integration_tests", "//python:unit_tests", + "//skylark:unit_tests", ], ) +# END-EXTERNAL -# CLwB tests, run with a CLion plugin SDK +# ASwB tests, run with an Android Studio plugin SDK test_suite( - name = "clwb_tests", + name = "aswb_tests", tests = [ + "//aswb:integration_tests", + "//aswb:unit_tests", + "//base:integration_tests", "//base:unit_tests", - "//clwb:unit_tests", + "//cpp:integration_tests", "//cpp:unit_tests", "//dart:unit_tests", - "//python:unit_tests", + "//java:integration_tests", + "//java:unit_tests", + "//skylark:unit_tests", ], + visibility = DEFAULT_TEST_VISIBILITY, ) diff --git a/CHANGELOG b/CHANGELOG index 36cb250151f..249e25c9d01 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,370 @@ +v2024.12.17 +=========== +Fixes: +* Keep bazel from automatically enabling curses with the old sync view #7143 +* Do not use curses with the old sync view #7139 +* Do not append \n for PROCESS since that output has all of the delim… #7146 +* clion: fix non-passed env vars for gdbserverless debugging #7167 +* handle non-valid project view file on reload #7159 +Features: +* Adds support for the google test run button in nova #7062 +* Add catch2 test support in CLion #7141 +* Adds support for the run button on main functions in nova #7100 +* Experimental: Basic qsync support in CLion for linux #7094 + +v2024.12.03 +=========== +Fixes: +* fix: NPE in WorkspaceHelper when project is not loaded yet #7036 +* fix issues with aspect templates not available in query sync mode #7048 +* fix: Don't require rules_java and rules_python for bazel 7 and older #7052 +* Reapply "fix: Support bazel 8 and --noenable_workspace mode (#6990)… #7045 +* Handle included MODULE.bazel files as well #7057 +* Fix indexing problem with Fix getPackageName which didn't respect "build ignore" #7034 +* Stop adding a trailing # when filtering tests for JUnit 5 #7060 +* fix(qsync): Include runtime_deps in the target graph #7081 +* Fix over-including when view_project_root is set. #7002 +* fix: remove strongInfoHolder flag, so users can choose which plugin t… #7092 +* Reload project view, and make sure that BazelImportSettings respect p… #7088 +* fix(qsync): Hightlighting level is always updated after 'enable analy… #7101 +Features: +* PTY enabled terminal for the new sync view #7001 +* Enable the new sync view for query sync #7037 + +v2024.11.19 +=========== +Features: +* Bazel Icon for Plugin Logo #6973 +* Query Sync: "Enable analysis" widget for Remote Development #6996 +* Starlark Debuger: Gutter icons to start debugging #6999 +Fixes: +* C++: Do not collide with CMake #6770 +* Make the BlazeImportProjectAction dumb aware #6985 +* Query Sync: Fix NPE when enabling analysis for a directory #6992 +* Bazel 8 support for Java (#6987 and #7006) +* Exception in the new QuerySyncNotificationProvider #7009 +* fix(qsync): Fix build_dependencies after AOSP merge #7027 +* disable warmup service #7029 +* fix(qsync): NPE in QuerySyncNotificationProvider #7032 + +v2024.11.05 +=========== +Features: +* C++: Use execroot for compiler working directory #6911 +* C++: CLion support for cc_library implementation deps #6919 +* C++: External includes support #6922 +* GoLand: cgo support #6891 +* GoLand: gotest support on Windows #6938 +* Query Sync: better syntax highlithting when analysis disabled #6941 +Fixes: +* Do not decorate tabs for BUILD files in non-bazel projects #6925 +* fix: NPE in location provider #6960 +* Query Sync: Use git info only when Expand to Working Set is enabled #6944 +* Query Sync: fix(qsync): IJ incorrectly recognizes files as external and asks to a… #6964 +* Query Sync: fix(qsync): Unhandled exception when trying to resolve external works… #6962 +* Query Sync: fix(qsync): NPE in "Add to project" panel action #6967 + +v2024.10.22 +=========== +Bug Fixes +* [fix] Fix python debugging #6847 +* Set runfiles vars to absolute paths when debugging Go tests #6883 +* Fix starlark debugger #6888 +* fix(querysync): affected packages calculator was broken when 'directories' contained '.' #6885 +* fix: fast test not working when main class is not set #6903 +* fix: fast sync with bazel 8 or when --incompatible_use_plus_in_repo_names is on #6901 +* BEP parse unknown targets in aborted event #6910 +Features +* Download Buildifier Binary #6625 +* Support for Python Rules that are Code Generators #6726 +* Decorate tabs for BUILD files with package name #6900 +* New Sync View #6813 +* feat: More descriptive location labels (instead of just .workspace) #6916 + +v2024.10.08 +=========== +Bug Fixes +* CLion Virtual Include Fixes #6759 +* Fixes for Query Sync (ready to use): #6833, #6834, #6835, #6841 +* [fix] Confirm if user wants to reimport instead of disallowing it #6839 +Features +* Implement JUnit5 support and parameterize tests #4473 +* [feature] Recognize WORKSPACE.bzlmod files #6853 + +v2024.09.24 +=========== +Bug Fixes +* Fix auto-import exception #6753 +* Fix unrecognized options by bazel mod command #6756 +* Set go DebugConfguration working directory for tests #6748 +Features +* CLion add support for additional_compiler_inputs #6774 +* Added completion support for external targets from modules. Needs --incompatible_use_plus_in_repo_names set (defaults to true in bazel 8.0+) to work optimally. (credits: @mtoader) + +v2024.09.10 +=========== +Bug Fixes +* Fix reading MatchedMatcher data in BlazePyTracebackParser #6693 +* Fix googletest integration with CLion 2024.2 #6741 + +v2024.08.27 +=========== +Features +* Added build folder action #6615 +* Invoke bazel build during sync using --target_pattern_fi… #6595 +Bug Fixes +* fix: Exception when opening a JavaScript project #6645 +* go: fix testify single test execution #6634 +* fix: Resolve collision between view_project_root and "directories: ." #6665 + +v2024.08.13 +=========== +## Features +- Python: Implemented `imports` Attribute Handling + Improved support for Python imports in Bazel projects. [#6606] + +- Python: Transition Rules Handling + Added handling for Bazel rules involving transitions, such as pinned Python interpreter targets, enhancing project configuration. [#6605] + +- C++: Project Status API Integration + Integrated the Project Status API with Bazel for CLion, improving project sync and status reporting. [#6585] + +## Bug Fixes +- Fixed an issue causing `NoClassDefFoundError: com/intellij/history/core/Paths` during project operations. [#6616] +- Stopped printing `AswbDumpVfs` logs. [#6617] +- Scala: Updated the plugin to correctly recognize `org_scala_lang_scala_library` as a valid Scala library name, improving Scala project support. [#6629] + +v2024.07.30 +=========== +Features: +* feat: enable view_project_root by default in auto import mode #6596 +* CLion MSVC Support #6500 +Bug Fixes: +* Fix wrong heuristic for when bazel uses a wrapper script #6592 +* use absolute directories paths while deriving targets #6544 +Performance Fixes: +* Don't build unnecessary jars. #5515 +* fix: Adjust executor threads based on device core count #6588 + +v2024.07.16 +=========== +Performance Fix +* Fixes after sync freeze on MacOS #6562 +* Improve performance when resolving the workspace root #6530 +Bug Fixes +* fix: Resolve query failure when there is a large number of files in t… #6537 +* Propagate build errors to UI #6546 + +v2024.07.02 +=========== +Performance fix: +* Use a global bounded threadpool when using persistent workers #6508 +Bug fixes: +* fix: Display "Coverage" tool window correctly after executing "run wi… #6502 +* Disable include hints (-ibazel) by default #6534 +* trusted project: respect intellij settings controlling project trustness #6521 +* clion: fix broken debug in 2024.2 #6538 +Internal changes: +* CI build on Windows #6494 + +v2024.06.18 +=========== +* fix: Missing directories when view_project_root is on #6493 +* fix: "Read access is allowed from inside read-action" exception when opening a file #6489 +* Add extension point to detect whether a module is to be orphaned or retained. #6467 +* Fix for wrong compiler executable when using custom toolchains #6419 +* fix(coverage): Account for SHA in lcov DA parsing #6463 +* fix: Mark saveAllFiles as a WriteAction #6459 +* fix: Rely on the bazel zipper instead of zip #6462 + +v2024.06.04-RC-2 +================ +* Address CVE-2024-5899 +* feat: Support JetBrains IDEs 2024.2 #6434 +* feat: Editor notification on bazel files if the project is not imported #6153 +* perf: perf: Pass --override_repository flag to all commands for faster analysis phase #6453 +* fix: Default to project name to workspace name instead of root directory #6458 + +v2024.06.04 +=========== +* feat: Support JetBrains IDEs 2024.2 #6434 +* feat: Editor notification on bazel files if the project is not imported #6153 +* perf: perf: Pass --override_repository flag to all commands for faster analysis phase #6453 +* fix: Default to project name to workspace name instead of root directory #6458 + +v2024.05.21 +=========== +* Plugin aspect now depends on @rules_java. If this breaks you, please update your @rules_java version to 5.3.5 or later. +* #6370 Add line numbers to sections and text-blocks #6371 +* Add 'View project root' flag #6422 +* Fixes: Test/Coverage throws exception NoClassDefFoundError in GoLand #2053 + +v2024.05.07 +=========== +* Plugin aspect now depends on @rules_java. If this breaks you, please update your @rules_java version to 5.3.5 or later. +* Internal cleanup + +v2024.04.23 +=========== +* Feature flags for resolve virtual includes using heuristics or clangd #6387 +* feat: create "Add package" EditorNotificationPanel if derive_targets_from_directories is on #6388 + +v2024.04.09 +=========== +* Fix imports for go modules named "external" #6325 +* Fix: Ensure .projectview exclusion rules apply only to specified directories #6376 +* Fix: Silence false positive "No such target" errors for files in the project root #6377 + +v2024.03.26 +=========== +* Fix "No such target" errors on incremental sync #6262 +* Reduced the logging level for the stack traces produced when resolving external artifacts. #6310 +* (rebase) Support embedded go_proto_library #6030 +* Improved error message for an unsupported workspace type #6257 + +v2024.03.12 +=========== +* fix(plugin_dev): Alert users they need the DevKit plugin to work on the codebase #6198 +* Followup for Pass path associations as special compiler flags #6007 +* fix: Try to make the default projectview file a bit more user-friendly #6175 +* Added MODULE.bazel to isBazelWorkspace in AutoImportProjectOpenProcessor #6155 +* Added registry key to disable fission flag #6041 + +v2024.02.27 +=========== +* perf: avoid scanning convenience symlink directories during initial import #6094 +* Added MODULE.bazel to valid workspace root files #6127 +* Use path to workspace root as pwd for buildifier #6158 + +v2024.02.13 +=========== +* fix: deadlock when more than one project is open and bazel.sync.detec… #5978 +* Changes to BlazeTargetFilter regex to match more target names #6021 +* Fix _virtual_includes handling for absolute strip_include_prefix paths #5969 + +v2024.01.30 +=========== +* feat: Allow environment variables in run configurations #5885 +* Support JetBrains IDEs 2024.1 #5960 + +v2024.01.16 +=========== +* Internal cleanup + +v2024.01.02 +=========== +* fix: Fix bazel sync errors when using non-default convenience symlinks #5910 +* fix: Fix warnings when syncing a workspace containing a bazelignore file #5873 + +v2023.12.19 +=========== +* feat: Allow to have non-existent import entries in projectview file #5689 +* feat: Pass environment variables from BlazeCidrLauncher down to bazel #5771 +* feat: Enable debugging the gazelle binary #5816 +* fix: Fix buildifier formatting for MODULE.bazel and WORKSPACE #5829 +* fix: Update glob validation to support allow_empty parameter #5855 +* fix: Don't throw "Non-blaze project is provided error" on source attachment #5864 + +v2023.12.05 +=========== +* Escape regex-relevant characters in test filter #5745 +* Mitigate StartupActivity warnings #5760 + +v2023.11.21 +=========== +* feat: Add support for Starlark float literals #5678 +* feat: Add visibility reference contributor #5650 +* fix: Work around NPE for toolwindow #5665 +* fix: Expect double-@-prefixed labels in Bazel output +* fix: Do not throw "Non-blaze project is provided" exception in various places #5704, #5706, #5658 +* fix: Do not complete ignored directories #5573 +* fix: Fix NPE when accessing xcodeProperties #5714 +* fix: Pass -include compilation flags down to OC language model #5645 +* fix: Rename 'fast' run configurations to 'Fast Run' and 'Fast Debug' … #5743 +* fix: Fast Test with Bzlmod enabled + +v2023.11.07 +=========== +* New feature: +* feat: Support gutter icons in java_test_suite #5579 +* Fixes: +* Fix go debugging #5585 +* fix: Allow multiple providers to contribute attribute specific references #5507 +* Fix "slow operations exception" in welcome screen #5598 +* Fix missing "Bazel" item in main menu. #5610 +* Fix "Non-blaze project is provided" error #5596 + + +v2023.10.24 +=========== +* Bump to newest EAPs #5522 +* Make //clwb(plugin) and //cpp(plugin) dependency on cidr.lang optional: plugin xmls split #5473 +* Adapt paths and line breaks for Windows #5471 +* Fix manual targets sync for target explicitly specified #5458 +* Make //cpp dependency on cidr.lang optional: remove dead code #5474 +* fix: Mark package with BUILD.bazel file in completion #5526 + +v2023.10.10 +=========== +* Fix a bug where C++ debugging is broken after IDE restart on Mac #5420 + +v2023.09.26 +=========== +* Resolve symbolic links from external workspace to workspace root #5228 +* More details on IJ timings in the log #5325 + +v2023.09.12 +=========== +* Handle null function returned from CLion code #5248 +* Add managed project to import wizard project view field #5227 +* Sync process optimizations #5219 + +v2023.08.29 +=========== +* Support embedded go_source rule type in go_test and go_library rules #5205 +* Proper check for git repository #5213 +* Make bazel run configurations dumbaware #5262 + +v2023.08.15 +=========== +* - Allow to suppress automatic Bazel project opening if .ijwb or so … #5208 +* Support BUILD.bazel files along BUILDin errors parsing #5206 +* Fix detecting custom test_suite macros #5184 +* Do not suggest to add .ijwb and others to project view. #5168 +* Fix the "No display name is specified' error #5196 +* Select source roots for library jars that have interim folders like `… #5117 + +v2023.08.01 +=========== +* Fix references for repo-relative labels in external workspaces #5164 +* Make the default projectview empty during autoimport and add some com… #5162 +* Allow manual tags to be synced to the project #5085 +* Folding builder #5110 + +v2023.07.18 +=========== +* We now support C++ strip_include_prefix parameter (done in Resolve _virtual_includes to local or external workspace #5059) +* "Build dependecies for open files" action adcfaae +* Aspect-sync to query-sync conversion 3f268d0 +* Open project view file after auto import of project #5088 + +v2023.07.04 +=========== +* fix(clion): Handle (possibly broken) CommandLineTools installations #5010 +* [query-sync] Support the "Build dependencies" action for directories and BUILD files. + +v2023.06.13 +=========== +* fix(cpp): Only register Xcode settings provider on macOS #4976 +* Fix path separator in run configuration generator #4846 +* Add associates to dep attributes #4915 +* Added a registry key to disable passing the extra compiler flags to Bazel when building a C/C++ target in debug mode. #4913 +* Move oldest supported Bazel version to 4.0.0 + +v2023.05.30 +=========== +* The plugin now supports Xcode toolchain, not only the Xcode Command Line Tools fix(clion): Add Xcode information to Cpp compiler wrapper #4651 + v2023.05.16 =========== * Improve performance of Java package parser by making it a Bazel worker #3686 diff --git a/CODEOWNERS b/CODEOWNERS index b5628c0f77b..798b705c3cc 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -1 +1 @@ -* @mai93 @jastice @tpasternak +* @mai93 @tpasternak @agluszak diff --git a/DEV_IDE_SETUP.md b/DEV_IDE_SETUP.md index fdf43715ba6..e3f38f3b057 100644 --- a/DEV_IDE_SETUP.md +++ b/DEV_IDE_SETUP.md @@ -1,41 +1,56 @@ # IntelliJ Development Instance Setup -## Determine which JDK you're running, and where it is +## DevKit Plugin -Inside IntelliJ, go to the SDK menu (`Cmd+;` or `Ctrl+;`). +For IntelliJ 2023.3 and newer, make sure you have DevKit plugin installed in your host IntelliJ. + +https://plugins.jetbrains.com/plugin/22851-plugin-devkit -Go to `Project`, and look under `SDK` to find the JDK you intend to use -to develop the plugin. +## Import the plugin project. -Press `Edit`, and make a note of `JDK home path`, as well as the version of the JDK. +Clone and import this repository as you would any other Bazel project. +When asked, use the bundled project view file (`ijwb/ijwb.bazelproject`). This will: + +- Set the plugin to build with the latest development version by default. +- Automatically import the relevant target, and exclude the irrelevant ones. + +Depending on which JetBrains product you're targeting, you may want to adjust the `--define` flag in the `build_flags` section. For more information on which values you can pass, please refer to [Building the Plugin](README.md#building-the-plugin) ## Download and Install the JetBrains Runtime SDK -Most of the time, the IntelliJ Platform Plugin SDK bundled with your IntelliJ installation shuould be enuogh to compile and run the plugin. +Most of the time, the IntelliJ Platform Plugin SDK bundled with your IntelliJ installation should be enough to compile and run the plugin. To install it, please head to the SDK menu (`Cmd+;` or `Ctrl+;`), and then to `Platform Settings -> SDKs`. -In the list of SDKs, press the `+` icon, then `Add IntelliJ Platform Plugin SDK`. A file explorer window should open in the `Contents` directory of your IntelliJ installation. Select that directory. +In the list of SDKs, press the `+` icon, then `Add IntelliJ Platform Plugin SDK`. -Make sure that the `Internal Java Platform` is set to the JDK you want to use to develop your plugin. +image -## Import the plugin project. +A file explorer window should open in the `Contents` directory of your IntelliJ installation. Select that directory. -Clone and import this repository as you would any other Bazel project. -When asked, use the bundled project view file (`ijwb/ijwb.bazelproject`). This will: +image -- Set the plugin to build with the latest development version by default. -- Automatically import the relevant target, and exclude the irrelevant ones. +Make sure that the `Internal Java Platform` is set to the JDK you want to use to develop your plugin. It is recommended to use JBR 17. -Depending on which JetBrains product you're targetting, you may want to adjust the `--define` flag in the `build_flags` section. For more information on which values you can pass, please refer to [Building the Plugin](README.md#building-the-plugin) +image + +## Set the project-wide SDK + +Inside IntelliJ, go to the SDK menu (`Cmd+;` or `Ctrl+;`). + +Go to `Project`, and look under `SDK` to find the JetBrains Runtime SDK installed in the previous step. + +image ## Create a run configuration and add appropriate flags Once the project is imported, create a new Run configuration: `Run -> Edit Configurations...`. -Click the `+` sign, and create a new `Bazel IntelliJ Plugin` run configuration. + +Click the `+` sign, and create a new `Bazel IntelliJ Plugin` run configuration (the Bazel IntelliJ plugin needs to be installed): + +image + Configure the `Plugin SDK` field to use the SDK you've just installed. -### If Using JDK17 +image -You'll need to add some additional flags to the VM Options to open the required modules. -You can find an up to date list in [the JetBrains/intellij-community repository](https://raw.githubusercontent.com/JetBrains/intellij-community/master/plugins/devkit/devkit-core/src/run/OpenedPackages.txt) diff --git a/MODULE.bazel b/MODULE.bazel new file mode 100644 index 00000000000..7defce5d88a --- /dev/null +++ b/MODULE.bazel @@ -0,0 +1,844 @@ +module( + bazel_compatibility = [">=7.0.0"], + repo_name = "intellij_with_bazel", +) + +register_toolchains("//third_party/kotlin:toolchain") + +bazel_dep( + name = "platforms", + version = "0.0.10", +) +bazel_dep( + name = "rules_java", + version = "8.3.1", +) +bazel_dep( + name = "rules_python", + version = "1.0.0", +) + +python = use_extension("@rules_python//python/extensions:python.bzl", "python") +python.toolchain( + configure_coverage_tool = True, + python_version = "3.12", +) +use_repo(python, "python_3_12", "python_versions") + +bazel_dep( + name = "rules_proto", + version = "7.0.2", +) +bazel_dep( + name = "protobuf", + version = "29.0", +) +bazel_dep( + name = "bazel_skylib", + version = "1.7.1", +) +bazel_dep( + name = "rules_pkg", + version = "1.0.1", +) +bazel_dep( + name = "rules_kotlin", + version = "2.0.0", +) + +remote_android_extensions = use_extension("@bazel_tools//tools/android:android_extensions.bzl", "remote_android_tools_extensions") +use_repo(remote_android_extensions, "android_gmaven_r8", "android_tools") + +bazel_dep( + name = "rules_bazel_integration_test", + version = "0.29.0", + dev_dependency = True, +) + +bazel_binaries = use_extension( + "@rules_bazel_integration_test//:extensions.bzl", + "bazel_binaries", + dev_dependency = True, +) +bazel_binaries.download(version = "5.4.1") +bazel_binaries.download(version = "6.5.0") +bazel_binaries.download( + current = True, + version = "7.4.0", +) +use_repo( + bazel_binaries, + "bazel_binaries", + "bazel_binaries_bazelisk", + "build_bazel_bazel_5_4_1", + "build_bazel_bazel_6_5_0", + "build_bazel_bazel_7_4_0", +) + +bazel_dep(name = "rules_jvm_external", version = "6.6") + +maven = use_extension("@rules_jvm_external//:extensions.bzl", "maven") +maven.install( + name = "maven", + artifacts = [ + "junit:junit:4.13.2", + "org.opentest4j:opentest4j:1.3.0", + "org.mockito:mockito-core:5.8.0", + "org.objenesis:objenesis:3.3", + "net.bytebuddy:byte-buddy:1.14.0", + "net.bytebuddy:byte-buddy-agent:1.14.10", + "com.google.flogger:flogger:0.8", + "com.google.flogger:flogger-system-backend:0.8", + "com.googlecode.java-diff-utils:diffutils:1.3.0", + # Usually, we'd get this from the JetBrains SDK, but the bundled one not aware of Bazel platforms, + # so it fails on certain setups. + "net.java.dev.jna:jna:5.14.0", + "com.google.auto.value:auto-value-annotations:1.10.2", + "com.google.auto.value:auto-value:1.10.4", + "com.google.code.findbugs:jsr305:3.0.2", + "com.google.code.gson:gson:2.10.1", + "com.google.errorprone:error_prone_annotations:2.20.0", + "com.google.guava:guava:33.3.1-jre", # changed to jre + "com.google.truth:truth:1.4.4", + "com.google.truth.extensions:truth-java8-extension:1.4.4", + "com.google.j2objc:j2objc-annotations:2.8", + "com.google.guava:failureaccess:1.0.2", + "org.hamcrest:hamcrest-core:3.0", + ], + fail_if_repin_required = True, + generate_compat_repositories = True, + lock_file = "//:maven_install.json", +) +use_repo( + maven, + "com_google_guava_failureaccess", + "com_google_guava_guava", + "com_google_j2objc_j2objc_annotations", + "maven", + "org_opentest4j_opentest4j", + "unpinned_maven", + auto_value = "com_google_auto_value_auto_value", + auto_value_annotations = "com_google_auto_value_auto_value_annotations", + bytebuddy = "net_bytebuddy_byte_buddy", + bytebuddy_agent = "net_bytebuddy_byte_buddy_agent", # Can it be `bytebuddy-agent`? (not a legal identifier) + diffutils = "com_googlecode_java_diff_utils_diffutils", + error_prone_annotations = "com_google_errorprone_error_prone_annotations", + flogger = "com_google_flogger_flogger", + flogger_system_backend = "com_google_flogger_flogger_system_backend", + gson = "com_google_code_gson_gson", + hamcrest = "org_hamcrest_hamcrest_core", + jna = "net_java_dev_jna_jna", + jsr305_annotations = "com_google_code_findbugs_jsr305", + junit = "junit_junit", + mockito = "org_mockito_mockito_core", + objenesis = "org_objenesis_objenesis", + truth = "com_google_truth_truth", + truth8 = "com_google_truth_extensions_truth_java8_extension", +) + +bazel_dep(name = "rules_go", version = "0.51.0", repo_name = "io_bazel_rules_go") +bazel_dep(name = "gazelle", version = "0.40.0", repo_name = "bazel_gazelle") + +go_repository = use_repo_rule("@bazel_gazelle//:deps.bzl", "go_repository") + +# gRPC is used to generate Go from proto in the aspect tests, in +# //aspect/testing/tests/src/com/google/idea/blaze/aspect/go/... +go_repository( + name = "org_golang_google_grpc", + build_file_proto_mode = "disable", + importpath = "google.golang.org/grpc", + sum = "h1:zvIju4sqAGvwKspUQOhwnpcqSbzi7/H6QomNNjTL4sk=", + version = "v1.27.1", +) + +http_archive = use_repo_rule("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") + +# Long-lived download links available at: https://www.jetbrains.com/intellij-repository/releases + +# The plugin api for intellij_ce_2022_3. This is required to build IJwB and run integration tests. +http_archive( + name = "intellij_ce_2022_3", + build_file = "@//intellij_platform_sdk:BUILD.idea223", + sha256 = "f6ea9aee6dec73b55ea405b37402394095be3c658d1c2707a8f30ac848974eac", + url = "https://www.jetbrains.com/intellij-repository/releases/com/jetbrains/intellij/idea/ideaIC/2022.3/ideaIC-2022.3.zip", +) + +# The plugin api for intellij_ce_2023_1. This is required to build IJwB and run integration tests. +IC_231_SHA = "4e1dbd508a3dc6394735ae864034aa3598d16ddd568c3de2a9d7a386f3508fff" + +IC_231_URL = "https://www.jetbrains.com/intellij-repository/releases/com/jetbrains/intellij/idea/ideaIC/2023.1.7/ideaIC-2023.1.7.zip" + +http_archive( + name = "intellij_ce_2023_1", + build_file = "@//intellij_platform_sdk:BUILD.idea231", + sha256 = IC_231_SHA, + url = IC_231_URL, +) + +# The plugin api for intellij_ce_2023_2. This is required to build IJwB and run integration tests. +IC_232_SHA = "d8ef9fe55f1c8084aa5da7b23f3858514bdbc5c0546a26e018b875976da04d5b" + +IC_232_URL = "https://www.jetbrains.com/intellij-repository/releases/com/jetbrains/intellij/idea/ideaIC/2023.2.8/ideaIC-2023.2.8.zip" + +http_archive( + name = "intellij_ce_2023_2", + build_file = "@//intellij_platform_sdk:BUILD.idea232", + sha256 = IC_232_SHA, + url = IC_232_URL, +) + +# The plugin api for intellij_ce_2023_2. This is required to build IJwB and run integration tests. +IC_233_SHA = "fe424303f34e52b8bbd867ebe839ec6006fdbace20e8dfb9bce702ef523a1f91" + +IC_233_URL = "https://www.jetbrains.com/intellij-repository/releases/com/jetbrains/intellij/idea/ideaIC/2023.3.8/ideaIC-2023.3.8.zip" + +http_archive( + name = "intellij_ce_2023_3", + build_file = "@//intellij_platform_sdk:BUILD.idea233", + sha256 = IC_233_SHA, + url = IC_233_URL, +) + +# The plugin api for intellij_ce_2024_1. This is required to build IJwB and run integration tests. +IC_241_SHA = "eb4da488ca2c8cf019fa69f7b97129bf76ab36b8acccf08b0673a8eed53ab432" + +IC_241_URL = "https://www.jetbrains.com/intellij-repository/releases/com/jetbrains/intellij/idea/ideaIC/2024.1.7/ideaIC-2024.1.7.zip" + +http_archive( + name = "intellij_ce_2024_1", + build_file = "@//intellij_platform_sdk:BUILD.idea241", + sha256 = IC_241_SHA, + url = IC_241_URL, +) + +# The plugin api for intellij_ce_2024_2. This is required to build IJwB and run integration tests. +IC_242_SHA = "67dc633ff20fadd702eae6d5b8e875c510791445a96e5f5a41ef902ab570966a" + +IC_242_URL = "https://www.jetbrains.com/intellij-repository/releases/com/jetbrains/intellij/idea/ideaIC/2024.2.5/ideaIC-2024.2.5.zip" + +http_archive( + name = "intellij_ce_2024_2", + build_file = "@//intellij_platform_sdk:BUILD.idea242", + sha256 = IC_242_SHA, + url = IC_242_URL, +) + +# The plugin api for intellij_ce_2024_2. This is required to build IJwB and run integration tests. +IC_243_SHA = "89087fb3c43f284b67d945945db4a60968c04e909eef849f36bc8ffc19e39aba" + +IC_243_URL = "https://www.jetbrains.com/intellij-repository/releases/com/jetbrains/intellij/idea/ideaIC/2024.3.1/ideaIC-2024.3.1.zip" + +http_archive( + name = "intellij_ce_2024_3", + build_file = "@//intellij_platform_sdk:BUILD.idea243", + sha256 = IC_243_SHA, + url = IC_243_URL, +) + +# The plugin api for intellij_ue_2022_3. This is required to run UE-specific integration tests. +http_archive( + name = "intellij_ue_2022_3", + build_file = "@//intellij_platform_sdk:BUILD.ue223", + sha256 = "0b17ea16e70290d912b6be246460907643c23f33ae2c22331084818025c2b297", + url = "https://www.jetbrains.com/intellij-repository/releases/com/jetbrains/intellij/idea/ideaIU/2022.3/ideaIU-2022.3.zip", +) + +# The plugin api for intellij_ue_2023_1. This is required to run UE-specific integration tests. +IU_231_SHA = "46900f8b8aa65a4b522e2b7eb365337e836bc7c49b00b23b47860170f5b95c07" + +IU_231_URL = "https://www.jetbrains.com/intellij-repository/releases/com/jetbrains/intellij/idea/ideaIU/2023.1.7/ideaIU-2023.1.7.zip" + +http_archive( + name = "intellij_ue_2023_1", + build_file = "@//intellij_platform_sdk:BUILD.ue231", + sha256 = IU_231_SHA, + url = IU_231_URL, +) + +# The plugin api for intellij_ue_2023_2. This is required to run UE-specific integration tests. +IU_232_SHA = "30c0bfce923087199cb1d8a3dc8120bc1e03d834a9cf236a3924a42f0351d910" + +IU_232_URL = "https://www.jetbrains.com/intellij-repository/releases/com/jetbrains/intellij/idea/ideaIU/2023.2.8/ideaIU-2023.2.8.zip" + +http_archive( + name = "intellij_ue_2023_2", + build_file = "@//intellij_platform_sdk:BUILD.ue232", + sha256 = IU_232_SHA, + url = IU_232_URL, +) + +IU_233_SHA = "27b011801301c0e7dfb903b447a2dacd5803d9734e45a97b0f6c5947c57a5699" + +IU_233_URL = "https://www.jetbrains.com/intellij-repository/releases/com/jetbrains/intellij/idea/ideaIU/2023.3.8/ideaIU-2023.3.8.zip" + +http_archive( + name = "intellij_ue_2023_3", + build_file = "@//intellij_platform_sdk:BUILD.ue233", + sha256 = IU_233_SHA, + url = IU_233_URL, +) + +IU_241_SHA = "346f94ca6ebd9f44b702714529bdae9bf9e42725edce7c447c7872d9bd94190d" + +IU_241_URL = "https://www.jetbrains.com/intellij-repository/releases/com/jetbrains/intellij/idea/ideaIU/2024.1.7/ideaIU-2024.1.7.zip" + +http_archive( + name = "intellij_ue_2024_1", + build_file = "@//intellij_platform_sdk:BUILD.ue241", + sha256 = IU_241_SHA, + url = IU_241_URL, +) + +IU_242_SHA = "6374538aeb34376c7501819b19804a30ee4a49547b5bfe3aa4aa80735191324e" + +IU_242_URL = "https://www.jetbrains.com/intellij-repository/releases/com/jetbrains/intellij/idea/ideaIU/2024.2.5/ideaIU-2024.2.5.zip" + +http_archive( + name = "intellij_ue_2024_2", + build_file = "@//intellij_platform_sdk:BUILD.ue242", + sha256 = IU_242_SHA, + url = IU_242_URL, +) + +IU_243_SHA = "31a8a3b46f124b9f8a50aa5f4e6ac0b9196321f2995ad6bda7777ef8cd1065d6" + +IU_243_URL = "https://www.jetbrains.com/intellij-repository/releases/com/jetbrains/intellij/idea/ideaIU/2024.3.1/ideaIU-2024.3.1.zip" + +http_archive( + name = "intellij_ue_2024_3", + build_file = "@//intellij_platform_sdk:BUILD.ue243", + sha256 = IU_243_SHA, + url = IU_243_URL, +) + +# The plugin api for clion_2022_3. This is required to build CLwB\, and run integration tests. +http_archive( + name = "clion_2022_3", + build_file = "@//intellij_platform_sdk:BUILD.clion223", + sha256 = "5c248465a99f7286e7863ccc4fbd6772af890b57d71a02690e20031aa16d7957", + url = "https://www.jetbrains.com/intellij-repository/releases/com/jetbrains/intellij/clion/clion/2022.3/clion-2022.3.zip", +) + +# The plugin api for clion_2023_1. This is required to build CLwB\, and run integration tests. +CLION_231_SHA = "2e94bfda121f54f96b7faf1a4df2da50d394c6ae46da6e98f37a731e2b50b189" + +CLION_231_URL = "https://www.jetbrains.com/intellij-repository/releases/com/jetbrains/intellij/clion/clion/2023.1.7/clion-2023.1.7.zip" + +http_archive( + name = "clion_2023_1", + build_file = "@//intellij_platform_sdk:BUILD.clion231", + sha256 = CLION_231_SHA, + url = CLION_231_URL, +) + +# The plugin api for clion_2023_2. This is required to build CLwB\, and run integration tests. +CLION_232_SHA = "542f805229177a97e5d1e7592397d017976fdba234b2229a85c86fe70b6dd352" + +CLION_232_URL = "https://www.jetbrains.com/intellij-repository/releases/com/jetbrains/intellij/clion/clion/2023.2.5/clion-2023.2.5.zip" + +http_archive( + name = "clion_2023_2", + build_file = "@//intellij_platform_sdk:BUILD.clion232", + sha256 = CLION_232_SHA, + url = CLION_232_URL, +) + +CLION_233_SHA = "6ebfe8e7fc2bf20e3d7d0738d39d1b3db3f7de5fe6b56ceb7f293ab53f23e2d5" + +CLION_233_URL = "https://www.jetbrains.com/intellij-repository/releases/com/jetbrains/intellij/clion/clion/2023.3.6/clion-2023.3.6.zip" + +http_archive( + name = "clion_2023_3", + build_file = "@//intellij_platform_sdk:BUILD.clion233", + sha256 = CLION_233_SHA, + url = CLION_233_URL, +) + +CLION_241_SHA = "8638829fbaba7f3974fd9ff8da18adc7e7c2ba08063082dbc8548deeb435ca5e" + +CLION_241_URL = "https://www.jetbrains.com/intellij-repository/releases/com/jetbrains/intellij/clion/clion/2024.1.6/clion-2024.1.6.zip" + +http_archive( + name = "clion_2024_1", + build_file = "@//intellij_platform_sdk:BUILD.clion241", + sha256 = CLION_241_SHA, + url = CLION_241_URL, +) + +CLION_242_SHA = "27029107088193b6ba0d3d888ce67fcdd1aae68f324c4c6ddadfdd4c3c90b87e" + +CLION_242_URL = "https://www.jetbrains.com/intellij-repository/releases/com/jetbrains/intellij/clion/clion/2024.2.4/clion-2024.2.4.zip" + +http_archive( + name = "clion_2024_2", + build_file = "@//intellij_platform_sdk:BUILD.clion242", + sha256 = CLION_242_SHA, + url = CLION_242_URL, +) + +CLION_243_SHA = "a25f835858a009abdbcd319ef5db7f73e7505f944fe1a1687a212ec2d8b05e8e" + +CLION_243_URL = "https://www.jetbrains.com/intellij-repository/releases/com/jetbrains/intellij/clion/clion/2024.3.1/clion-2024.3.1.zip" + +http_archive( + name = "clion_2024_3", + build_file = "@//intellij_platform_sdk:BUILD.clion243", + sha256 = CLION_243_SHA, + url = CLION_243_URL, +) + +DEVKIT_BUILD_FILE = """ +java_import( + name = "devkit", + jars = ["devkit/lib/devkit.jar"], + visibility = ["//visibility:public"], +) +""" + +DEVKIT_233_SHA = "e90a150070520c5344e65b33161738cd03186b5f2e23c942cba2f2cee5771e4e" + +DEVKIT_233_URL = "https://plugins.jetbrains.com/maven/com/jetbrains/plugins/DevKit/233.15619.17/DevKit-233.15619.17.zip" + +http_archive( + name = "devkit_2023_3", + build_file_content = DEVKIT_BUILD_FILE, + sha256 = DEVKIT_233_SHA, + url = DEVKIT_233_URL, +) + +DEVKIT_241_SHA = "3103f6de79a17a7740fef010d0152464acb32266d617cafa47c05d7561f11eb3" + +DEVKIT_241_URL = "https://plugins.jetbrains.com/maven/com/jetbrains/plugins/DevKit/241.19416.23/DevKit-241.19416.23.zip" + +http_archive( + name = "devkit_2024_1", + build_file_content = DEVKIT_BUILD_FILE, + sha256 = DEVKIT_241_SHA, + url = DEVKIT_241_URL, +) + +DEVKIT_243_SHA = "b3403b6a3c1dadd0eaaaa12cc21c910bc0e9c7264c55a9785a7ece188cba5ec6" + +DEVKIT_243_URL = "https://plugins.jetbrains.com/maven/com/jetbrains/plugins/DevKit/243.22562.145/DevKit-243.22562.145.zip" + +http_archive( + name = "devkit_2024_3", + build_file_content = DEVKIT_BUILD_FILE, + sha256 = DEVKIT_243_SHA, + url = DEVKIT_243_URL, +) + +DEVKIT_242_SHA = "628545e45a8b450527224105910deef6b2af568b084d2b3afbd1e8b75e561a70" + +DEVKIT_242_URL = "https://plugins.jetbrains.com/maven/com/jetbrains/plugins/DevKit/242.23726.103/DevKit-242.23726.103.zip" + +http_archive( + name = "devkit_2024_2", + build_file_content = DEVKIT_BUILD_FILE, + sha256 = DEVKIT_242_SHA, + url = DEVKIT_242_URL, +) + +_PYTHON_CE_BUILD_FILE = """ +java_import( + name = "python", + jars = ["python-ce/lib/python-ce.jar"], + visibility = ["//visibility:public"], +) +filegroup( + name = "python_helpers", + srcs = glob(["python-ce/helpers/**/*"]), + visibility = ["//visibility:public"], +) +""" + +#TODO(ymoh): remove with the removal of 2021.1 Python plugin +# Python plugin for IntelliJ CE. Required at compile-time for python-specific features. +http_archive( + name = "python_2021_1", + build_file_content = _PYTHON_CE_BUILD_FILE, + sha256 = "7d16cc9bf80c9e2c26d55d55564c1c174583a5e6900e6b7f13d5663275b07644", + url = "https://plugins.jetbrains.com/files/7322/125352/python-ce-211.7628.24.zip", +) + +http_archive( + name = "python_2022_3", + build_file_content = _PYTHON_CE_BUILD_FILE, + sha256 = "65db7c364a3f1756cf07fb161ff4eb67fd8f8612a8c3da812b2f9ba5b2d6e13d", + url = "https://plugins.jetbrains.com/maven/com/jetbrains/plugins/PythonCore/223.7571.182/PythonCore-223.7571.182.zip", +) + +PYTHON_PLUGIN_231_URL = "https://plugins.jetbrains.com/maven/com/jetbrains/plugins/PythonCore/231.9225.4/PythonCore-231.9225.4.zip" + +PYTHON_PLUGIN_231_SHA = "bb9fe55fc483b4da1f6062c764ebd076d0de9f913c924db295f2bd2f05353777" + +http_archive( + name = "python_2023_1", + build_file_content = _PYTHON_CE_BUILD_FILE, + sha256 = PYTHON_PLUGIN_231_SHA, + url = PYTHON_PLUGIN_231_URL, +) + +PYTHON_PLUGIN_232_URL = "https://plugins.jetbrains.com/maven/com/jetbrains/plugins/PythonCore/232.10300.40/PythonCore-232.10300.40.zip" + +PYTHON_PLUGIN_232_SHA = "eab4b343491772123cd7daa4c3924d81de29ecd3a74495679216c28cc1bd0005" + +http_archive( + name = "python_2023_2", + build_file_content = _PYTHON_CE_BUILD_FILE, + sha256 = PYTHON_PLUGIN_232_SHA, + url = PYTHON_PLUGIN_232_URL, +) + +PYTHON_PLUGIN_233_URL = "https://plugins.jetbrains.com/maven/com/jetbrains/plugins/PythonCore/233.14808.12/PythonCore-233.14808.12.zip" + +PYTHON_PLUGIN_233_SHA = "ce1c20372e558bc59076674eafc1a7fc55a3a3606116fd20f64032c02136091b" + +http_archive( + name = "python_2023_3", + build_file_content = _PYTHON_CE_BUILD_FILE, + sha256 = PYTHON_PLUGIN_233_SHA, + url = PYTHON_PLUGIN_233_URL, +) + +PYTHON_PLUGIN_241_URL = "https://plugins.jetbrains.com/maven/com/jetbrains/plugins/PythonCore/241.19416.15/PythonCore-241.19416.15.zip" + +PYTHON_PLUGIN_241_SHA = "c66bd035b38e4b037e0b7c454a056d62944782c051dfe6b8ea61c0beed506732" + +http_archive( + name = "python_2024_1", + build_file_content = _PYTHON_CE_BUILD_FILE, + sha256 = PYTHON_PLUGIN_241_SHA, + url = PYTHON_PLUGIN_241_URL, +) + +_PYTHON_CE_242_BUILD_FILE = """ +java_import( + name = "python", + jars = glob(["python-ce/lib/*.jar", "python-ce/lib/modules/*.jar"]), + visibility = ["//visibility:public"], +) +filegroup( + name = "python_helpers", + srcs = glob(["python-ce/helpers/**/*"]), + visibility = ["//visibility:public"], +) +""" + +PYTHON_PLUGIN_242_URL = "https://plugins.jetbrains.com/maven/com/jetbrains/plugins/PythonCore/242.24807.4/PythonCore-242.24807.4.zip" + +PYTHON_PLUGIN_242_SHA = "ac5ea796655322d5cc0a1579fbcc97ae57e558dde0a4bd6b78a20d10dcd374cf" + +http_archive( + name = "python_2024_2", + build_file_content = _PYTHON_CE_242_BUILD_FILE, + sha256 = PYTHON_PLUGIN_242_SHA, + url = PYTHON_PLUGIN_242_URL, +) + +PYTHON_PLUGIN_243_URL = "https://plugins.jetbrains.com/maven/com/jetbrains/plugins/PythonCore/243.22562.145/PythonCore-243.22562.145.zip" + +PYTHON_PLUGIN_243_SHA = "49d2ff442ddbedd40ab063b761ad6452fd0c0caaf4828256d5ce84da9b787e07" + +http_archive( + name = "python_2024_3", + build_file_content = _PYTHON_CE_242_BUILD_FILE, + sha256 = PYTHON_PLUGIN_243_SHA, + url = PYTHON_PLUGIN_243_URL, +) + +_GO_BUILD_FILE_223 = """ +java_import( + name = "go", + jars = glob(["go-plugin/lib/*.jar"]), + visibility = ["//visibility:public"], +) +""" + +http_archive( + name = "go_2022_3", + build_file_content = _GO_BUILD_FILE_223, + sha256 = "11d30e00aa21fc8c7aa47df3743c0180058556cbb73292c712e151a0c3d59908", + url = "https://plugins.jetbrains.com/maven/com/jetbrains/plugins/org.jetbrains.plugins.go/223.7571.182/org.jetbrains.plugins.go-223.7571.182.zip", +) + +GO_PLUGIN_231_SHA = "a8d277125ec1f6a2ba0190a7c456d6c39057e563596874ec432a8f278b3d6976" + +GO_PLUGIN_231_URL = "https://plugins.jetbrains.com/maven/com/jetbrains/plugins/org.jetbrains.plugins.go/231.9392.1/org.jetbrains.plugins.go-231.9392.1.zip" + +http_archive( + name = "go_2023_1", + build_file_content = _GO_BUILD_FILE_223, + sha256 = GO_PLUGIN_231_SHA, + url = GO_PLUGIN_231_URL, +) + +GO_PLUGIN_232_SHA = "6682325b13d66b716fc9bc719821f3f7bad16f21ac4504cc4656265fee74ceb4" + +GO_PLUGIN_232_URL = "https://plugins.jetbrains.com/maven/com/jetbrains/plugins/org.jetbrains.plugins.go/232.10203.2/org.jetbrains.plugins.go-232.10203.2.zip" + +http_archive( + name = "go_2023_2", + build_file_content = _GO_BUILD_FILE_223, + sha256 = GO_PLUGIN_232_SHA, + url = GO_PLUGIN_232_URL, +) + +GO_PLUGIN_233_SHA = "6ec43880bfbedaead564def4b9f40baa13de4167d7d7c7c0522f7e7c5dd77a77" + +GO_PLUGIN_233_URL = "https://plugins.jetbrains.com/maven/com/jetbrains/plugins/org.jetbrains.plugins.go/233.15026.9/org.jetbrains.plugins.go-233.15026.9.zip" + +http_archive( + name = "go_2023_3", + build_file_content = _GO_BUILD_FILE_223, + sha256 = GO_PLUGIN_233_SHA, + url = GO_PLUGIN_233_URL, +) + +GO_PLUGIN_241_SHA = "18f9b114a372730e3b869cc3bf99bc3e019611571aa0edfd0517f1d10b83e422" + +GO_PLUGIN_241_URL = "https://plugins.jetbrains.com/maven/com/jetbrains/plugins/org.jetbrains.plugins.go/241.18968.26/org.jetbrains.plugins.go-241.18968.26.zip" + +http_archive( + name = "go_2024_1", + build_file_content = _GO_BUILD_FILE_223, + sha256 = GO_PLUGIN_241_SHA, + url = GO_PLUGIN_241_URL, +) + +_GO_BUILD_FILE_242 = """ +java_import( + name = "go", + jars = glob(["go-plugin/lib/*.jar", "go-plugin/lib/modules/*.jar"]), + visibility = ["//visibility:public"], +) +""" + +GO_PLUGIN_242_SHA = "b65091c9189576b549698675c4e29f9a006660b9830c0d66c5169ee53a5e610d" + +GO_PLUGIN_242_URL = "https://plugins.jetbrains.com/maven/com/jetbrains/plugins/org.jetbrains.plugins.go/242.23726.16/org.jetbrains.plugins.go-242.23726.16.zip" + +http_archive( + name = "go_2024_2", + build_file_content = _GO_BUILD_FILE_242, + sha256 = GO_PLUGIN_242_SHA, + url = GO_PLUGIN_242_URL, +) + +GO_PLUGIN_243_SHA = "5b893719694c65c82bae4df6916d94a3961b6390a6aaa8a077a1daf7954041a9" + +GO_PLUGIN_243_URL = "https://plugins.jetbrains.com/maven/com/jetbrains/plugins/org.jetbrains.plugins.go/243.22562.145/org.jetbrains.plugins.go-243.22562.145.zip" + +http_archive( + name = "go_2024_3", + build_file_content = _GO_BUILD_FILE_242, + sha256 = GO_PLUGIN_243_SHA, + url = GO_PLUGIN_243_URL, +) + +_SCALA_BUILD_FILE = """ +java_import( + name = "scala", + jars = glob(["Scala/lib/*.jar", "Scala/lib/modules/*.jar"]), + visibility = ["//visibility:public"], +) +""" + +http_archive( + name = "scala_2022_3", + build_file_content = _SCALA_BUILD_FILE, + sha256 = "f028ac7263433c8692d9d4c92aaba9e114fc75f6299d4d86817db371409f74f3", + url = "https://plugins.jetbrains.com/maven/com/jetbrains/plugins/org.intellij.scala/2022.3.13/org.intellij.scala-2022.3.13.zip", +) + +SCALA_PLUGIN_231_URL = "https://plugins.jetbrains.com/maven/com/jetbrains/plugins/org.intellij.scala/2023.1.25/org.intellij.scala-2023.1.25.zip" + +SCALA_PLUGIN_231_SHA = "b45dbb95ed5a0001f11638e7f03dd858d9e243994ca554a64e1df6b7290b2b81" + +http_archive( + name = "scala_2023_1", + build_file_content = _SCALA_BUILD_FILE, + sha256 = SCALA_PLUGIN_231_SHA, + url = SCALA_PLUGIN_231_URL, +) + +SCALA_PLUGIN_232_URL = "https://plugins.jetbrains.com/maven/com/jetbrains/plugins/org.intellij.scala/2023.2.30/org.intellij.scala-2023.2.30.zip" + +SCALA_PLUGIN_232_SHA = "16896d256bea7f84343dbfec11808c8d9f861fdc99b0ca26d2eeb5d510398ba8" + +http_archive( + name = "scala_2023_2", + build_file_content = _SCALA_BUILD_FILE, + sha256 = SCALA_PLUGIN_232_SHA, + url = SCALA_PLUGIN_232_URL, +) + +SCALA_PLUGIN_233_URL = "https://plugins.jetbrains.com/maven/com/jetbrains/plugins/org.intellij.scala/2023.3.30/org.intellij.scala-2023.3.30.zip" + +SCALA_PLUGIN_233_SHA = "0c7ffd6f642face7d15d0f8aaa40430041c8a3d00d3b213659d17146f64e2052" + +http_archive( + name = "scala_2023_3", + build_file_content = _SCALA_BUILD_FILE, + sha256 = SCALA_PLUGIN_233_SHA, + url = SCALA_PLUGIN_233_URL, +) + +SCALA_PLUGIN_241_URL = "https://plugins.jetbrains.com/maven/com/jetbrains/plugins/org.intellij.scala/2024.1.25/org.intellij.scala-2024.1.25.zip" + +SCALA_PLUGIN_241_SHA = "3d550756eab61858618dc7d695283cd0569c47b680bf823f2d46fd9c130f5422" + +http_archive( + name = "scala_2024_1", + build_file_content = _SCALA_BUILD_FILE, + sha256 = SCALA_PLUGIN_241_SHA, + url = SCALA_PLUGIN_241_URL, +) + +SCALA_PLUGIN_242_URL = "https://plugins.jetbrains.com/maven/com/jetbrains/plugins/org.intellij.scala/2024.2.30/org.intellij.scala-2024.2.30.zip" + +SCALA_PLUGIN_242_SHA = "2b3ebb4377a59ef465a1b352d857d2feb4e407dd9fcae405ad0edfef833ae783" + +http_archive( + name = "scala_2024_2", + build_file_content = _SCALA_BUILD_FILE, + sha256 = SCALA_PLUGIN_242_SHA, + url = SCALA_PLUGIN_242_URL, +) + +SCALA_PLUGIN_243_URL = "https://plugins.jetbrains.com/maven/com/jetbrains/plugins/org.intellij.scala/2024.3.22/org.intellij.scala-2024.3.22.zip" + +SCALA_PLUGIN_243_SHA = "42fcbaca38919d95f718da620346122bead02e4a14c3c25f3b80a7aac8538c36" + +http_archive( + name = "scala_2024_3", + build_file_content = _SCALA_BUILD_FILE, + sha256 = SCALA_PLUGIN_243_SHA, + url = SCALA_PLUGIN_243_URL, +) + +_TOML_BUILD_FILE = """ +java_import( + name = "toml", + jars = ["toml/lib/toml.jar"], + visibility = ["//visibility:public"], +) +""" + +TOML_PLUGIN_241_URL = "https://plugins.jetbrains.com/maven/com/jetbrains/plugins/org.toml.lang/241.17011.8/org.toml.lang-241.17011.8.zip" + +TOML_PLUGIN_241_SHA = "17572527d9aa2f31cd9fa670de68054cb586af3aa2eca9cb204b0f33043e9839" + +# TOML required by Python since 241.13688.18 +http_archive( + name = "toml_2024_1", + build_file_content = _TOML_BUILD_FILE, + sha256 = TOML_PLUGIN_241_SHA, + url = TOML_PLUGIN_241_URL, +) + +TOML_PLUGIN_242_URL = "https://plugins.jetbrains.com/maven/com/jetbrains/plugins/org.toml.lang/242.20224.155/org.toml.lang-242.20224.155.zip" + +TOML_PLUGIN_242_SHA = "96bd1964b5b4bc7f778c87dddee11b8f7e3d08559a2a72e52909ce4d31be2d9c" + +# TOML required by Python since 242.13688.18 +http_archive( + name = "toml_2024_2", + build_file_content = _TOML_BUILD_FILE, + sha256 = TOML_PLUGIN_242_SHA, + url = TOML_PLUGIN_242_URL, +) + +TOML_PLUGIN_243_URL = "https://plugins.jetbrains.com/maven/com/jetbrains/plugins/org.toml.lang/243.21565.122/org.toml.lang-243.21565.122.zip" + +TOML_PLUGIN_243_SHA = "def1c13c6c3e9fefdae100a28b355c0f1267b6bfedaab4cffa22e992f2b76412" + +http_archive( + name = "toml_2024_3", + build_file_content = _TOML_BUILD_FILE, + sha256 = TOML_PLUGIN_243_SHA, + url = TOML_PLUGIN_243_URL, +) + +# The plugin api for android_studio_dev android_studio. This is required to build ASwB and run integration tests +http_archive( + name = "android_studio_dev", + build_file = "@//intellij_platform_sdk:BUILD.android_studiodev", + sha256 = "cb3f0494220f92dd85399adfb8655a1a2bd81b238d26e63a8bbd8bde95a0fccf", + url = "https://android-build", +) + +# The plugin api for android_studio_2023_2 android_studio. This is required to build ASwB and run integration tests +http_archive( + name = "android_studio_2023_2", + build_file = "@//intellij_platform_sdk:BUILD.android_studio232", + sha256 = "f2ccc445fb5c87525627ae81725241ab90d9707d577f5732563d3c5a49cba12f", + url = "https://dl.google.com/dl/android/studio/ide-zips/2023.2.1.14/android-studio-2023.2.1.14-linux.tar.gz", +) + +# The plugin api for android_studio_2023_1 android_studio. This is required to build ASwB and run integration tests +http_archive( + name = "android_studio_2023_1", + build_file = "@//intellij_platform_sdk:BUILD.android_studio231", + sha256 = "139d0dbb4909353b68fbf55c09b6d31a34512044a9d4f02ce0f1a9accca128f9", + url = "https://dl.google.com/dl/android/studio/ide-zips/2023.1.1.28/android-studio-2023.1.1.28-linux.tar.gz", +) + +# The plugin api for android_studio_2022_3 android_studio. This is required to build ASwB and run integration tests +http_archive( + name = "android_studio_2022_3", + build_file = "@//intellij_platform_sdk:BUILD.android_studio223", + sha256 = "250625dcab183e0c68ebf12ef8a522af7369527d76f1efc704f93c05b02ffa9e", + url = "https://dl.google.com/dl/android/studio/ide-zips/2022.3.1.19/android-studio-2022.3.1.19-linux.tar.gz", +) + +# needed for cpp tests +http_archive( + name = "com_google_absl", + sha256 = "f50e5ac311a81382da7fa75b97310e4b9006474f9560ac46f54a9967f07d4ae3", + strip_prefix = "abseil-cpp-20240722.0", + urls = [ + "https://github.com/abseil/abseil-cpp/archive/refs/tags/20240722.0.tar.gz", + ], +) + +_JARJAR_BUILD_FILE = """ +java_binary( + name = "jarjar_bin", + srcs = glob( + ["src/main/**/*.java"], + exclude = [ + "src/main/com/tonicsystems/jarjar/JarJarMojo.java", + "src/main/com/tonicsystems/jarjar/util/AntJarProcessor.java", + "src/main/com/tonicsystems/jarjar/JarJarTask.java", + ], + ), + main_class = "com.tonicsystems.jarjar.Main", + resources = [":help"], + use_launcher = False, + visibility = ["//visibility:public"], + deps = [":asm"], +) + +java_import( + name = "asm", + jars = glob(["lib/asm-*.jar"]), +) + +genrule( + name = "help", + srcs = ["src/main/com/tonicsystems/jarjar/help.txt"], + outs = ["com/tonicsystems/jarjar/help.txt"], + cmd = "cp $< $@", +) +""" + +new_git_repository = use_repo_rule("@bazel_tools//tools/build_defs/repo:git.bzl", "new_git_repository") + +new_git_repository( + name = "jarjar", + build_file_content = _JARJAR_BUILD_FILE, + commit = "38ff702d10baec78f30d5f57485ae452f0fe33b5", + remote = "https://github.com/google/jarjar", + shallow_since = "1518210648 -0800", +) diff --git a/MODULE.bazel.lock b/MODULE.bazel.lock new file mode 100644 index 00000000000..adb658134c0 --- /dev/null +++ b/MODULE.bazel.lock @@ -0,0 +1,3109 @@ +{ + "lockFileVersion": 16, + "registryFileHashes": { + "https://bcr.bazel.build/bazel_registry.json": "8a28e4aff06ee60aed2a8c281907fb8bcbf3b753c91fb5a5c57da3215d5b3497", + "https://bcr.bazel.build/modules/abseil-cpp/20210324.2/MODULE.bazel": "7cd0312e064fde87c8d1cd79ba06c876bd23630c83466e9500321be55c96ace2", + "https://bcr.bazel.build/modules/abseil-cpp/20211102.0/MODULE.bazel": "70390338f7a5106231d20620712f7cccb659cd0e9d073d1991c038eb9fc57589", + "https://bcr.bazel.build/modules/abseil-cpp/20230125.1/MODULE.bazel": "89047429cb0207707b2dface14ba7f8df85273d484c2572755be4bab7ce9c3a0", + "https://bcr.bazel.build/modules/abseil-cpp/20230802.0.bcr.1/MODULE.bazel": "1c8cec495288dccd14fdae6e3f95f772c1c91857047a098fad772034264cc8cb", + "https://bcr.bazel.build/modules/abseil-cpp/20230802.0/MODULE.bazel": "d253ae36a8bd9ee3c5955384096ccb6baf16a1b1e93e858370da0a3b94f77c16", + "https://bcr.bazel.build/modules/abseil-cpp/20230802.1/MODULE.bazel": "fa92e2eb41a04df73cdabeec37107316f7e5272650f81d6cc096418fe647b915", + "https://bcr.bazel.build/modules/abseil-cpp/20240116.1/MODULE.bazel": "37bcdb4440fbb61df6a1c296ae01b327f19e9bb521f9b8e26ec854b6f97309ed", + "https://bcr.bazel.build/modules/abseil-cpp/20240116.1/source.json": "9be551b8d4e3ef76875c0d744b5d6a504a27e3ae67bc6b28f46415fd2d2957da", + "https://bcr.bazel.build/modules/bazel_features/1.1.0/MODULE.bazel": "cfd42ff3b815a5f39554d97182657f8c4b9719568eb7fded2b9135f084bf760b", + "https://bcr.bazel.build/modules/bazel_features/1.1.1/MODULE.bazel": "27b8c79ef57efe08efccbd9dd6ef70d61b4798320b8d3c134fd571f78963dbcd", + "https://bcr.bazel.build/modules/bazel_features/1.11.0/MODULE.bazel": "f9382337dd5a474c3b7d334c2f83e50b6eaedc284253334cf823044a26de03e8", + "https://bcr.bazel.build/modules/bazel_features/1.15.0/MODULE.bazel": "d38ff6e517149dc509406aca0db3ad1efdd890a85e049585b7234d04238e2a4d", + "https://bcr.bazel.build/modules/bazel_features/1.17.0/MODULE.bazel": "039de32d21b816b47bd42c778e0454217e9c9caac4a3cf8e15c7231ee3ddee4d", + "https://bcr.bazel.build/modules/bazel_features/1.18.0/MODULE.bazel": "1be0ae2557ab3a72a57aeb31b29be347bcdc5d2b1eb1e70f39e3851a7e97041a", + "https://bcr.bazel.build/modules/bazel_features/1.19.0/MODULE.bazel": "59adcdf28230d220f0067b1f435b8537dd033bfff8db21335ef9217919c7fb58", + "https://bcr.bazel.build/modules/bazel_features/1.21.0/MODULE.bazel": "675642261665d8eea09989aa3b8afb5c37627f1be178382c320d1b46afba5e3b", + "https://bcr.bazel.build/modules/bazel_features/1.21.0/source.json": "3e8379efaaef53ce35b7b8ba419df829315a880cb0a030e5bb45c96d6d5ecb5f", + "https://bcr.bazel.build/modules/bazel_features/1.4.1/MODULE.bazel": "e45b6bb2350aff3e442ae1111c555e27eac1d915e77775f6fdc4b351b758b5d7", + "https://bcr.bazel.build/modules/bazel_features/1.9.1/MODULE.bazel": "8f679097876a9b609ad1f60249c49d68bfab783dd9be012faf9d82547b14815a", + "https://bcr.bazel.build/modules/bazel_skylib/1.0.3/MODULE.bazel": "bcb0fd896384802d1ad283b4e4eb4d718eebd8cb820b0a2c3a347fb971afd9d8", + "https://bcr.bazel.build/modules/bazel_skylib/1.1.1/MODULE.bazel": "1add3e7d93ff2e6998f9e118022c84d163917d912f5afafb3058e3d2f1545b5e", + "https://bcr.bazel.build/modules/bazel_skylib/1.2.0/MODULE.bazel": "44fe84260e454ed94ad326352a698422dbe372b21a1ac9f3eab76eb531223686", + "https://bcr.bazel.build/modules/bazel_skylib/1.2.1/MODULE.bazel": "f35baf9da0efe45fa3da1696ae906eea3d615ad41e2e3def4aeb4e8bc0ef9a7a", + "https://bcr.bazel.build/modules/bazel_skylib/1.3.0/MODULE.bazel": "20228b92868bf5cfc41bda7afc8a8ba2a543201851de39d990ec957b513579c5", + "https://bcr.bazel.build/modules/bazel_skylib/1.4.1/MODULE.bazel": "a0dcb779424be33100dcae821e9e27e4f2901d9dfd5333efe5ac6a8d7ab75e1d", + "https://bcr.bazel.build/modules/bazel_skylib/1.4.2/MODULE.bazel": "3bd40978e7a1fac911d5989e6b09d8f64921865a45822d8b09e815eaa726a651", + "https://bcr.bazel.build/modules/bazel_skylib/1.5.0/MODULE.bazel": "32880f5e2945ce6a03d1fbd588e9198c0a959bb42297b2cfaf1685b7bc32e138", + "https://bcr.bazel.build/modules/bazel_skylib/1.6.1/MODULE.bazel": "8fdee2dbaace6c252131c00e1de4b165dc65af02ea278476187765e1a617b917", + "https://bcr.bazel.build/modules/bazel_skylib/1.7.0/MODULE.bazel": "0db596f4563de7938de764cc8deeabec291f55e8ec15299718b93c4423e9796d", + "https://bcr.bazel.build/modules/bazel_skylib/1.7.1/MODULE.bazel": "3120d80c5861aa616222ec015332e5f8d3171e062e3e804a2a0253e1be26e59b", + "https://bcr.bazel.build/modules/bazel_skylib/1.7.1/source.json": "f121b43eeefc7c29efbd51b83d08631e2347297c95aac9764a701f2a6a2bb953", + "https://bcr.bazel.build/modules/buildifier_prebuilt/6.0.0.1/MODULE.bazel": "5d23708e6a5527ab4f151da7accabc22808cb5fb579c8cc4cd4a292da57a5c97", + "https://bcr.bazel.build/modules/buildifier_prebuilt/6.1.2/MODULE.bazel": "2ef4962c8b0b6d8d21928a89190755619254459bc67f870dc0ccb9ba9952d444", + "https://bcr.bazel.build/modules/buildifier_prebuilt/6.1.2/source.json": "19fb45ed3f0d55cbff94e402c39512940833ae3a68f9cbfd9518a1926b609c7c", + "https://bcr.bazel.build/modules/buildozer/7.1.2/MODULE.bazel": "2e8dd40ede9c454042645fd8d8d0cd1527966aa5c919de86661e62953cd73d84", + "https://bcr.bazel.build/modules/buildozer/7.1.2/source.json": "c9028a501d2db85793a6996205c8de120944f50a0d570438fcae0457a5f9d1f8", + "https://bcr.bazel.build/modules/cgrindel_bazel_starlib/0.18.0/MODULE.bazel": "1d548f0c383ec8fce15c14b42b7f5f4fc29e910fb747d54b40d8c949a5dea09c", + "https://bcr.bazel.build/modules/cgrindel_bazel_starlib/0.18.0/source.json": "bb5421fffcf03965cb192a7dfa857c4cfc2d5ed7788d8b97da30f6b9d5706c9e", + "https://bcr.bazel.build/modules/gazelle/0.32.0/MODULE.bazel": "b499f58a5d0d3537f3cf5b76d8ada18242f64ec474d8391247438bf04f58c7b8", + "https://bcr.bazel.build/modules/gazelle/0.33.0/MODULE.bazel": "a13a0f279b462b784fb8dd52a4074526c4a2afe70e114c7d09066097a46b3350", + "https://bcr.bazel.build/modules/gazelle/0.34.0/MODULE.bazel": "abdd8ce4d70978933209db92e436deb3a8b737859e9354fb5fd11fb5c2004c8a", + "https://bcr.bazel.build/modules/gazelle/0.36.0/MODULE.bazel": "e375d5d6e9a6ca59b0cb38b0540bc9a05b6aa926d322f2de268ad267a2ee74c0", + "https://bcr.bazel.build/modules/gazelle/0.40.0/MODULE.bazel": "42ba5378ebe845fca43989a53186ab436d956db498acde790685fe0e8f9c6146", + "https://bcr.bazel.build/modules/gazelle/0.40.0/source.json": "1e5ef6e4d8b9b6836d93273c781e78ff829ea2e077afef7a57298040fa4f010a", + "https://bcr.bazel.build/modules/google_benchmark/1.8.2/MODULE.bazel": "a70cf1bba851000ba93b58ae2f6d76490a9feb74192e57ab8e8ff13c34ec50cb", + "https://bcr.bazel.build/modules/googletest/1.11.0/MODULE.bazel": "3a83f095183f66345ca86aa13c58b59f9f94a2f81999c093d4eeaa2d262d12f4", + "https://bcr.bazel.build/modules/googletest/1.14.0.bcr.1/MODULE.bazel": "22c31a561553727960057361aa33bf20fb2e98584bc4fec007906e27053f80c6", + "https://bcr.bazel.build/modules/googletest/1.14.0.bcr.1/source.json": "41e9e129f80d8c8bf103a7acc337b76e54fad1214ac0a7084bf24f4cd924b8b4", + "https://bcr.bazel.build/modules/googletest/1.14.0/MODULE.bazel": "cfbcbf3e6eac06ef9d85900f64424708cc08687d1b527f0ef65aa7517af8118f", + "https://bcr.bazel.build/modules/jsoncpp/1.9.5/MODULE.bazel": "31271aedc59e815656f5736f282bb7509a97c7ecb43e927ac1a37966e0578075", + "https://bcr.bazel.build/modules/jsoncpp/1.9.5/source.json": "4108ee5085dd2885a341c7fab149429db457b3169b86eb081fa245eadf69169d", + "https://bcr.bazel.build/modules/libpfm/4.11.0/MODULE.bazel": "45061ff025b301940f1e30d2c16bea596c25b176c8b6b3087e92615adbd52902", + "https://bcr.bazel.build/modules/platforms/0.0.10/MODULE.bazel": "8cb8efaf200bdeb2150d93e162c40f388529a25852b332cec879373771e48ed5", + "https://bcr.bazel.build/modules/platforms/0.0.10/source.json": "f22828ff4cf021a6b577f1bf6341cb9dcd7965092a439f64fc1bb3b7a5ae4bd5", + "https://bcr.bazel.build/modules/platforms/0.0.4/MODULE.bazel": "9b328e31ee156f53f3c416a64f8491f7eb731742655a47c9eec4703a71644aee", + "https://bcr.bazel.build/modules/platforms/0.0.5/MODULE.bazel": "5733b54ea419d5eaf7997054bb55f6a1d0b5ff8aedf0176fef9eea44f3acda37", + "https://bcr.bazel.build/modules/platforms/0.0.6/MODULE.bazel": "ad6eeef431dc52aefd2d77ed20a4b353f8ebf0f4ecdd26a807d2da5aa8cd0615", + "https://bcr.bazel.build/modules/platforms/0.0.7/MODULE.bazel": "72fd4a0ede9ee5c021f6a8dd92b503e089f46c227ba2813ff183b71616034814", + "https://bcr.bazel.build/modules/platforms/0.0.8/MODULE.bazel": "9f142c03e348f6d263719f5074b21ef3adf0b139ee4c5133e2aa35664da9eb2d", + "https://bcr.bazel.build/modules/protobuf/21.7/MODULE.bazel": "a5a29bb89544f9b97edce05642fac225a808b5b7be74038ea3640fae2f8e66a7", + "https://bcr.bazel.build/modules/protobuf/27.0/MODULE.bazel": "7873b60be88844a0a1d8f80b9d5d20cfbd8495a689b8763e76c6372998d3f64c", + "https://bcr.bazel.build/modules/protobuf/27.1/MODULE.bazel": "703a7b614728bb06647f965264967a8ef1c39e09e8f167b3ca0bb1fd80449c0d", + "https://bcr.bazel.build/modules/protobuf/29.0-rc2/MODULE.bazel": "6241d35983510143049943fc0d57937937122baf1b287862f9dc8590fc4c37df", + "https://bcr.bazel.build/modules/protobuf/29.0/MODULE.bazel": "319dc8bf4c679ff87e71b1ccfb5a6e90a6dbc4693501d471f48662ac46d04e4e", + "https://bcr.bazel.build/modules/protobuf/29.0/source.json": "b857f93c796750eef95f0d61ee378f3420d00ee1dd38627b27193aa482f4f981", + "https://bcr.bazel.build/modules/protobuf/3.19.0/MODULE.bazel": "6b5fbb433f760a99a22b18b6850ed5784ef0e9928a72668b66e4d7ccd47db9b0", + "https://bcr.bazel.build/modules/protobuf/3.19.2/MODULE.bazel": "532ffe5f2186b69fdde039efe6df13ba726ff338c6bc82275ad433013fa10573", + "https://bcr.bazel.build/modules/protobuf/3.19.6/MODULE.bazel": "9233edc5e1f2ee276a60de3eaa47ac4132302ef9643238f23128fea53ea12858", + "https://bcr.bazel.build/modules/pybind11_bazel/2.11.1/MODULE.bazel": "88af1c246226d87e65be78ed49ecd1e6f5e98648558c14ce99176da041dc378e", + "https://bcr.bazel.build/modules/pybind11_bazel/2.11.1/source.json": "be4789e951dd5301282729fe3d4938995dc4c1a81c2ff150afc9f1b0504c6022", + "https://bcr.bazel.build/modules/re2/2023-09-01/MODULE.bazel": "cb3d511531b16cfc78a225a9e2136007a48cf8a677e4264baeab57fe78a80206", + "https://bcr.bazel.build/modules/re2/2023-09-01/source.json": "e044ce89c2883cd957a2969a43e79f7752f9656f6b20050b62f90ede21ec6eb4", + "https://bcr.bazel.build/modules/rules_android/0.1.1/MODULE.bazel": "48809ab0091b07ad0182defb787c4c5328bd3a278938415c00a7b69b50c4d3a8", + "https://bcr.bazel.build/modules/rules_android/0.1.1/source.json": "e6986b41626ee10bdc864937ffb6d6bf275bb5b9c65120e6137d56e6331f089e", + "https://bcr.bazel.build/modules/rules_bazel_integration_test/0.27.0/MODULE.bazel": "66b85a47d4aa51686c3e43befc7442b5be84415b12296954929ba199d46823be", + "https://bcr.bazel.build/modules/rules_bazel_integration_test/0.27.0/source.json": "28bd34e4cbbe78a826aa513cf555d9cb52f0fe589b64d20ca812b8e3fbca572f", + "https://bcr.bazel.build/modules/rules_cc/0.0.1/MODULE.bazel": "cb2aa0747f84c6c3a78dad4e2049c154f08ab9d166b1273835a8174940365647", + "https://bcr.bazel.build/modules/rules_cc/0.0.10/MODULE.bazel": "ec1705118f7eaedd6e118508d3d26deba2a4e76476ada7e0e3965211be012002", + "https://bcr.bazel.build/modules/rules_cc/0.0.13/MODULE.bazel": "0e8529ed7b323dad0775ff924d2ae5af7640b23553dfcd4d34344c7e7a867191", + "https://bcr.bazel.build/modules/rules_cc/0.0.14/MODULE.bazel": "5e343a3aac88b8d7af3b1b6d2093b55c347b8eefc2e7d1442f7a02dc8fea48ac", + "https://bcr.bazel.build/modules/rules_cc/0.0.15/MODULE.bazel": "6704c35f7b4a72502ee81f61bf88706b54f06b3cbe5558ac17e2e14666cd5dcc", + "https://bcr.bazel.build/modules/rules_cc/0.0.16/MODULE.bazel": "7661303b8fc1b4d7f532e54e9d6565771fea666fbdf839e0a86affcd02defe87", + "https://bcr.bazel.build/modules/rules_cc/0.0.16/source.json": "227e83737046aa4f50015da48e98e0d8ab42fd0ec74d8d653b6cc9f9a357f200", + "https://bcr.bazel.build/modules/rules_cc/0.0.2/MODULE.bazel": "6915987c90970493ab97393024c156ea8fb9f3bea953b2f3ec05c34f19b5695c", + "https://bcr.bazel.build/modules/rules_cc/0.0.6/MODULE.bazel": "abf360251023dfe3efcef65ab9d56beefa8394d4176dd29529750e1c57eaa33f", + "https://bcr.bazel.build/modules/rules_cc/0.0.8/MODULE.bazel": "964c85c82cfeb6f3855e6a07054fdb159aced38e99a5eecf7bce9d53990afa3e", + "https://bcr.bazel.build/modules/rules_cc/0.0.9/MODULE.bazel": "836e76439f354b89afe6a911a7adf59a6b2518fafb174483ad78a2a2fde7b1c5", + "https://bcr.bazel.build/modules/rules_foreign_cc/0.9.0/MODULE.bazel": "c9e8c682bf75b0e7c704166d79b599f93b72cfca5ad7477df596947891feeef6", + "https://bcr.bazel.build/modules/rules_fuzzing/0.5.2/MODULE.bazel": "40c97d1144356f52905566c55811f13b299453a14ac7769dfba2ac38192337a8", + "https://bcr.bazel.build/modules/rules_fuzzing/0.5.2/source.json": "c8b1e2c717646f1702290959a3302a178fb639d987ab61d548105019f11e527e", + "https://bcr.bazel.build/modules/rules_go/0.41.0/MODULE.bazel": "55861d8e8bb0e62cbd2896f60ff303f62ffcb0eddb74ecb0e5c0cbe36fc292c8", + "https://bcr.bazel.build/modules/rules_go/0.42.0/MODULE.bazel": "8cfa875b9aa8c6fce2b2e5925e73c1388173ea3c32a0db4d2b4804b453c14270", + "https://bcr.bazel.build/modules/rules_go/0.46.0/MODULE.bazel": "3477df8bdcc49e698b9d25f734c4f3a9f5931ff34ee48a2c662be168f5f2d3fd", + "https://bcr.bazel.build/modules/rules_go/0.50.1/MODULE.bazel": "b91a308dc5782bb0a8021ad4330c81fea5bda77f96b9e4c117b9b9c8f6665ee0", + "https://bcr.bazel.build/modules/rules_go/0.51.0/MODULE.bazel": "b6920f505935bfd69381651c942496d99b16e2a12f3dd5263b90ded16f3b4d0f", + "https://bcr.bazel.build/modules/rules_go/0.51.0/source.json": "473c0263360b1ae3aca71758e001d257a638620b2e2a36e3a2721fdae04377ec", + "https://bcr.bazel.build/modules/rules_java/4.0.0/MODULE.bazel": "5a78a7ae82cd1a33cef56dc578c7d2a46ed0dca12643ee45edbb8417899e6f74", + "https://bcr.bazel.build/modules/rules_java/5.3.5/MODULE.bazel": "a4ec4f2db570171e3e5eb753276ee4b389bae16b96207e9d3230895c99644b86", + "https://bcr.bazel.build/modules/rules_java/6.0.0/MODULE.bazel": "8a43b7df601a7ec1af61d79345c17b31ea1fedc6711fd4abfd013ea612978e39", + "https://bcr.bazel.build/modules/rules_java/6.4.0/MODULE.bazel": "e986a9fe25aeaa84ac17ca093ef13a4637f6107375f64667a15999f77db6c8f6", + "https://bcr.bazel.build/modules/rules_java/6.5.2/MODULE.bazel": "1d440d262d0e08453fa0c4d8f699ba81609ed0e9a9a0f02cd10b3e7942e61e31", + "https://bcr.bazel.build/modules/rules_java/7.10.0/MODULE.bazel": "530c3beb3067e870561739f1144329a21c851ff771cd752a49e06e3dc9c2e71a", + "https://bcr.bazel.build/modules/rules_java/7.12.2/MODULE.bazel": "579c505165ee757a4280ef83cda0150eea193eed3bef50b1004ba88b99da6de6", + "https://bcr.bazel.build/modules/rules_java/7.2.0/MODULE.bazel": "06c0334c9be61e6cef2c8c84a7800cef502063269a5af25ceb100b192453d4ab", + "https://bcr.bazel.build/modules/rules_java/7.3.2/MODULE.bazel": "50dece891cfdf1741ea230d001aa9c14398062f2b7c066470accace78e412bc2", + "https://bcr.bazel.build/modules/rules_java/7.6.1/MODULE.bazel": "2f14b7e8a1aa2f67ae92bc69d1ec0fa8d9f827c4e17ff5e5f02e91caa3b2d0fe", + "https://bcr.bazel.build/modules/rules_java/8.3.1/MODULE.bazel": "6df154d6cd5f9ede100d40621cc2f487071017f539caee021b24ecd91cf21034", + "https://bcr.bazel.build/modules/rules_java/8.6.1/MODULE.bazel": "f4808e2ab5b0197f094cabce9f4b006a27766beb6a9975931da07099560ca9c2", + "https://bcr.bazel.build/modules/rules_java/8.6.1/source.json": "f18d9ad3c4c54945bf422ad584fa6c5ca5b3116ff55a5b1bc77e5c1210be5960", + "https://bcr.bazel.build/modules/rules_jvm_external/4.4.2/MODULE.bazel": "a56b85e418c83eb1839819f0b515c431010160383306d13ec21959ac412d2fe7", + "https://bcr.bazel.build/modules/rules_jvm_external/5.1/MODULE.bazel": "33f6f999e03183f7d088c9be518a63467dfd0be94a11d0055fe2d210f89aa909", + "https://bcr.bazel.build/modules/rules_jvm_external/5.2/MODULE.bazel": "d9351ba35217ad0de03816ef3ed63f89d411349353077348a45348b096615036", + "https://bcr.bazel.build/modules/rules_jvm_external/5.3/MODULE.bazel": "bf93870767689637164657731849fb887ad086739bd5d360d90007a581d5527d", + "https://bcr.bazel.build/modules/rules_jvm_external/6.1/MODULE.bazel": "75b5fec090dbd46cf9b7d8ea08cf84a0472d92ba3585b476f44c326eda8059c4", + "https://bcr.bazel.build/modules/rules_jvm_external/6.3/MODULE.bazel": "c998e060b85f71e00de5ec552019347c8bca255062c990ac02d051bb80a38df0", + "https://bcr.bazel.build/modules/rules_jvm_external/6.6/MODULE.bazel": "153042249c7060536dc95b6bb9f9bb8063b8a0b0cb7acdb381bddbc2374aed55", + "https://bcr.bazel.build/modules/rules_jvm_external/6.6/source.json": "b1d7ffc3877e5a76e6e48e6bce459cbb1712c90eba14861b112bd299587a534d", + "https://bcr.bazel.build/modules/rules_kotlin/1.9.0/MODULE.bazel": "ef85697305025e5a61f395d4eaede272a5393cee479ace6686dba707de804d59", + "https://bcr.bazel.build/modules/rules_kotlin/1.9.6/MODULE.bazel": "d269a01a18ee74d0335450b10f62c9ed81f2321d7958a2934e44272fe82dcef3", + "https://bcr.bazel.build/modules/rules_kotlin/2.0.0/MODULE.bazel": "623488d3c43cacaf6ab1c0935b875d527d2746be906bb3cb063cd1f9713bcf19", + "https://bcr.bazel.build/modules/rules_kotlin/2.0.0/source.json": "baad7a06ace3a0d3a3608b700b151c221458a877bb2e435ccb2ea242895166e1", + "https://bcr.bazel.build/modules/rules_license/0.0.3/MODULE.bazel": "627e9ab0247f7d1e05736b59dbb1b6871373de5ad31c3011880b4133cafd4bd0", + "https://bcr.bazel.build/modules/rules_license/0.0.7/MODULE.bazel": "088fbeb0b6a419005b89cf93fe62d9517c0a2b8bb56af3244af65ecfe37e7d5d", + "https://bcr.bazel.build/modules/rules_license/1.0.0/MODULE.bazel": "a7fda60eefdf3d8c827262ba499957e4df06f659330bbe6cdbdb975b768bb65c", + "https://bcr.bazel.build/modules/rules_license/1.0.0/source.json": "a52c89e54cc311196e478f8382df91c15f7a2bfdf4c6cd0e2675cc2ff0b56efb", + "https://bcr.bazel.build/modules/rules_pkg/0.7.0/MODULE.bazel": "df99f03fc7934a4737122518bb87e667e62d780b610910f0447665a7e2be62dc", + "https://bcr.bazel.build/modules/rules_pkg/1.0.1/MODULE.bazel": "5b1df97dbc29623bccdf2b0dcd0f5cb08e2f2c9050aab1092fd39a41e82686ff", + "https://bcr.bazel.build/modules/rules_pkg/1.0.1/source.json": "bd82e5d7b9ce2d31e380dd9f50c111d678c3bdaca190cb76b0e1c71b05e1ba8a", + "https://bcr.bazel.build/modules/rules_proto/4.0.0/MODULE.bazel": "a7a7b6ce9bee418c1a760b3d84f83a299ad6952f9903c67f19e4edd964894e06", + "https://bcr.bazel.build/modules/rules_proto/5.3.0-21.7/MODULE.bazel": "e8dff86b0971688790ae75528fe1813f71809b5afd57facb44dad9e8eca631b7", + "https://bcr.bazel.build/modules/rules_proto/6.0.0/MODULE.bazel": "b531d7f09f58dce456cd61b4579ce8c86b38544da75184eadaf0a7cb7966453f", + "https://bcr.bazel.build/modules/rules_proto/6.0.2/MODULE.bazel": "ce916b775a62b90b61888052a416ccdda405212b6aaeb39522f7dc53431a5e73", + "https://bcr.bazel.build/modules/rules_proto/7.0.2/MODULE.bazel": "bf81793bd6d2ad89a37a40693e56c61b0ee30f7a7fdbaf3eabbf5f39de47dea2", + "https://bcr.bazel.build/modules/rules_proto/7.0.2/source.json": "1e5e7260ae32ef4f2b52fd1d0de8d03b606a44c91b694d2f1afb1d3b28a48ce1", + "https://bcr.bazel.build/modules/rules_python/0.10.2/MODULE.bazel": "cc82bc96f2997baa545ab3ce73f196d040ffb8756fd2d66125a530031cd90e5f", + "https://bcr.bazel.build/modules/rules_python/0.19.0/MODULE.bazel": "4dd47e473edf092240cb9835238762289028e58c691920ef5b92b6240d8db17a", + "https://bcr.bazel.build/modules/rules_python/0.23.1/MODULE.bazel": "49ffccf0511cb8414de28321f5fcf2a31312b47c40cc21577144b7447f2bf300", + "https://bcr.bazel.build/modules/rules_python/0.25.0/MODULE.bazel": "72f1506841c920a1afec76975b35312410eea3aa7b63267436bfb1dd91d2d382", + "https://bcr.bazel.build/modules/rules_python/0.28.0/MODULE.bazel": "cba2573d870babc976664a912539b320cbaa7114cd3e8f053c720171cde331ed", + "https://bcr.bazel.build/modules/rules_python/0.31.0/MODULE.bazel": "93a43dc47ee570e6ec9f5779b2e64c1476a6ce921c48cc9a1678a91dd5f8fd58", + "https://bcr.bazel.build/modules/rules_python/0.4.0/MODULE.bazel": "9208ee05fd48bf09ac60ed269791cf17fb343db56c8226a720fbb1cdf467166c", + "https://bcr.bazel.build/modules/rules_python/0.40.0/MODULE.bazel": "9d1a3cd88ed7d8e39583d9ffe56ae8a244f67783ae89b60caafc9f5cf318ada7", + "https://bcr.bazel.build/modules/rules_python/0.40.0/source.json": "939d4bd2e3110f27bfb360292986bb79fd8dcefb874358ccd6cdaa7bda029320", + "https://bcr.bazel.build/modules/rules_shell/0.2.0/MODULE.bazel": "fda8a652ab3c7d8fee214de05e7a9916d8b28082234e8d2c0094505c5268ed3c", + "https://bcr.bazel.build/modules/rules_shell/0.3.0/MODULE.bazel": "de4402cd12f4cc8fda2354fce179fdb068c0b9ca1ec2d2b17b3e21b24c1a937b", + "https://bcr.bazel.build/modules/rules_shell/0.3.0/source.json": "c55ed591aa5009401ddf80ded9762ac32c358d2517ee7820be981e2de9756cf3", + "https://bcr.bazel.build/modules/stardoc/0.5.1/MODULE.bazel": "1a05d92974d0c122f5ccf09291442580317cdd859f07a8655f1db9a60374f9f8", + "https://bcr.bazel.build/modules/stardoc/0.5.3/MODULE.bazel": "c7f6948dae6999bf0db32c1858ae345f112cacf98f174c7a8bb707e41b974f1c", + "https://bcr.bazel.build/modules/stardoc/0.5.6/MODULE.bazel": "c43dabc564990eeab55e25ed61c07a1aadafe9ece96a4efabb3f8bf9063b71ef", + "https://bcr.bazel.build/modules/stardoc/0.7.0/MODULE.bazel": "05e3d6d30c099b6770e97da986c53bd31844d7f13d41412480ea265ac9e8079c", + "https://bcr.bazel.build/modules/stardoc/0.7.1/MODULE.bazel": "3548faea4ee5dda5580f9af150e79d0f6aea934fc60c1cc50f4efdd9420759e7", + "https://bcr.bazel.build/modules/stardoc/0.7.1/source.json": "b6500ffcd7b48cd72c29bb67bcac781e12701cc0d6d55d266a652583cfcdab01", + "https://bcr.bazel.build/modules/upb/0.0.0-20220923-a547704/MODULE.bazel": "7298990c00040a0e2f121f6c32544bab27d4452f80d9ce51349b1a28f3005c43", + "https://bcr.bazel.build/modules/zlib/1.2.11/MODULE.bazel": "07b389abc85fdbca459b69e2ec656ae5622873af3f845e1c9d80fe179f3effa0", + "https://bcr.bazel.build/modules/zlib/1.2.12/MODULE.bazel": "3b1a8834ada2a883674be8cbd36ede1b6ec481477ada359cd2d3ddc562340b27", + "https://bcr.bazel.build/modules/zlib/1.3.1.bcr.3/MODULE.bazel": "af322bc08976524477c79d1e45e241b6efbeb918c497e8840b8ab116802dda79", + "https://bcr.bazel.build/modules/zlib/1.3.1.bcr.3/source.json": "2be409ac3c7601245958cd4fcdff4288be79ed23bd690b4b951f500d54ee6e7d", + "https://bcr.bazel.build/modules/zlib/1.3.1/MODULE.bazel": "751c9940dcfe869f5f7274e1295422a34623555916eb98c174c1e945594bf198" + }, + "selectedYankedVersions": {}, + "moduleExtensions": { + "@@buildifier_prebuilt+//:defs.bzl%buildifier_prebuilt_deps_extension": { + "general": { + "bzlTransitiveDigest": "BQ67MS38sDZxeQEfUs4vghLhs3+m4IXU/i7XC50fl9s=", + "usagesDigest": "JCqhJg+TeFVLBlrKVGI0Npi9RChNqkZQAh9TYfbAobs=", + "recordedFileInputs": {}, + "recordedDirentsInputs": {}, + "envVariables": {}, + "generatedRepoSpecs": { + "buildifier_darwin_amd64": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_file", + "attributes": { + "urls": [ + "https://github.com/bazelbuild/buildtools/releases/download/v6.1.2/buildifier-darwin-amd64" + ], + "downloaded_file_path": "buildifier", + "executable": true, + "sha256": "e2f4a67691c5f55634fbfb3850eb97dd91be0edd059d947b6c83d120682e0216" + } + }, + "buildifier_darwin_arm64": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_file", + "attributes": { + "urls": [ + "https://github.com/bazelbuild/buildtools/releases/download/v6.1.2/buildifier-darwin-arm64" + ], + "downloaded_file_path": "buildifier", + "executable": true, + "sha256": "7549b5f535219ac957aa2a6069d46fbfc9ea3f74abd85fd3d460af4b1a2099a6" + } + }, + "buildifier_linux_amd64": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_file", + "attributes": { + "urls": [ + "https://github.com/bazelbuild/buildtools/releases/download/v6.1.2/buildifier-linux-amd64" + ], + "downloaded_file_path": "buildifier", + "executable": true, + "sha256": "51bc947dabb7b14ec6fb1224464fbcf7a7cb138f1a10a3b328f00835f72852ce" + } + }, + "buildifier_linux_arm64": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_file", + "attributes": { + "urls": [ + "https://github.com/bazelbuild/buildtools/releases/download/v6.1.2/buildifier-linux-arm64" + ], + "downloaded_file_path": "buildifier", + "executable": true, + "sha256": "0ba6e8e3208b5a029164e542ddb5509e618f87b639ffe8cc2f54770022853080" + } + }, + "buildifier_windows_amd64": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_file", + "attributes": { + "urls": [ + "https://github.com/bazelbuild/buildtools/releases/download/v6.1.2/buildifier-windows-amd64.exe" + ], + "downloaded_file_path": "buildifier.exe", + "executable": true, + "sha256": "92bdd284fbc6766fc3e300b434ff9e68ac4d76a06cb29d1bdefe79a102a8d135" + } + }, + "buildozer_darwin_amd64": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_file", + "attributes": { + "urls": [ + "https://github.com/bazelbuild/buildtools/releases/download/v6.1.2/buildozer-darwin-amd64" + ], + "downloaded_file_path": "buildozer", + "executable": true, + "sha256": "4014751a4cc5e91a7dc4b64be7b30c565bd9014ae6d1879818dc624562a1d431" + } + }, + "buildozer_darwin_arm64": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_file", + "attributes": { + "urls": [ + "https://github.com/bazelbuild/buildtools/releases/download/v6.1.2/buildozer-darwin-arm64" + ], + "downloaded_file_path": "buildozer", + "executable": true, + "sha256": "e78bd5357f2356067d4b0d49ec4e4143dd9b1308746afc6ff11b55b952f462d7" + } + }, + "buildozer_linux_amd64": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_file", + "attributes": { + "urls": [ + "https://github.com/bazelbuild/buildtools/releases/download/v6.1.2/buildozer-linux-amd64" + ], + "downloaded_file_path": "buildozer", + "executable": true, + "sha256": "2aef0f1ef80a0140b8fe6e6a8eb822e14827d8855bfc6681532c7530339ea23b" + } + }, + "buildozer_linux_arm64": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_file", + "attributes": { + "urls": [ + "https://github.com/bazelbuild/buildtools/releases/download/v6.1.2/buildozer-linux-arm64" + ], + "downloaded_file_path": "buildozer", + "executable": true, + "sha256": "586e27630cbc242e8bd6fe8e24485eca8dcadea6410cc13cbe059202655980ac" + } + }, + "buildozer_windows_amd64": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_file", + "attributes": { + "urls": [ + "https://github.com/bazelbuild/buildtools/releases/download/v6.1.2/buildozer-windows-amd64.exe" + ], + "downloaded_file_path": "buildozer.exe", + "executable": true, + "sha256": "07664d5d08ee099f069cd654070cabf2708efaae9f52dc83921fa400c67a868b" + } + }, + "buildifier_prebuilt_toolchains": { + "repoRuleId": "@@buildifier_prebuilt+//:defs.bzl%_buildifier_toolchain_setup", + "attributes": { + "assets_json": "[{\"arch\":\"amd64\",\"name\":\"buildifier\",\"platform\":\"darwin\",\"sha256\":\"e2f4a67691c5f55634fbfb3850eb97dd91be0edd059d947b6c83d120682e0216\",\"version\":\"v6.1.2\"},{\"arch\":\"arm64\",\"name\":\"buildifier\",\"platform\":\"darwin\",\"sha256\":\"7549b5f535219ac957aa2a6069d46fbfc9ea3f74abd85fd3d460af4b1a2099a6\",\"version\":\"v6.1.2\"},{\"arch\":\"amd64\",\"name\":\"buildifier\",\"platform\":\"linux\",\"sha256\":\"51bc947dabb7b14ec6fb1224464fbcf7a7cb138f1a10a3b328f00835f72852ce\",\"version\":\"v6.1.2\"},{\"arch\":\"arm64\",\"name\":\"buildifier\",\"platform\":\"linux\",\"sha256\":\"0ba6e8e3208b5a029164e542ddb5509e618f87b639ffe8cc2f54770022853080\",\"version\":\"v6.1.2\"},{\"arch\":\"amd64\",\"name\":\"buildifier\",\"platform\":\"windows\",\"sha256\":\"92bdd284fbc6766fc3e300b434ff9e68ac4d76a06cb29d1bdefe79a102a8d135\",\"version\":\"v6.1.2\"},{\"arch\":\"amd64\",\"name\":\"buildozer\",\"platform\":\"darwin\",\"sha256\":\"4014751a4cc5e91a7dc4b64be7b30c565bd9014ae6d1879818dc624562a1d431\",\"version\":\"v6.1.2\"},{\"arch\":\"arm64\",\"name\":\"buildozer\",\"platform\":\"darwin\",\"sha256\":\"e78bd5357f2356067d4b0d49ec4e4143dd9b1308746afc6ff11b55b952f462d7\",\"version\":\"v6.1.2\"},{\"arch\":\"amd64\",\"name\":\"buildozer\",\"platform\":\"linux\",\"sha256\":\"2aef0f1ef80a0140b8fe6e6a8eb822e14827d8855bfc6681532c7530339ea23b\",\"version\":\"v6.1.2\"},{\"arch\":\"arm64\",\"name\":\"buildozer\",\"platform\":\"linux\",\"sha256\":\"586e27630cbc242e8bd6fe8e24485eca8dcadea6410cc13cbe059202655980ac\",\"version\":\"v6.1.2\"},{\"arch\":\"amd64\",\"name\":\"buildozer\",\"platform\":\"windows\",\"sha256\":\"07664d5d08ee099f069cd654070cabf2708efaae9f52dc83921fa400c67a868b\",\"version\":\"v6.1.2\"}]" + } + } + }, + "recordedRepoMappingEntries": [ + [ + "buildifier_prebuilt+", + "bazel_skylib", + "bazel_skylib+" + ], + [ + "buildifier_prebuilt+", + "bazel_tools", + "bazel_tools" + ] + ] + } + }, + "@@platforms//host:extension.bzl%host_platform": { + "general": { + "bzlTransitiveDigest": "xelQcPZH8+tmuOHVjL9vDxMnnQNMlwj0SlvgoqBkm4U=", + "usagesDigest": "SeQiIN/f8/Qt9vYQk7qcXp4I4wJeEC0RnQDiaaJ4tb8=", + "recordedFileInputs": {}, + "recordedDirentsInputs": {}, + "envVariables": {}, + "generatedRepoSpecs": { + "host_platform": { + "repoRuleId": "@@platforms//host:extension.bzl%host_platform_repo", + "attributes": {} + } + }, + "recordedRepoMappingEntries": [] + } + }, + "@@pybind11_bazel+//:python_configure.bzl%extension": { + "general": { + "bzlTransitiveDigest": "d4N/SZrl3ONcmzE98rcV0Fsro0iUbjNQFTIiLiGuH+k=", + "usagesDigest": "fycyB39YnXIJkfWCIXLUKJMZzANcuLy9ZE73hRucjFk=", + "recordedFileInputs": { + "@@pybind11_bazel+//MODULE.bazel": "88af1c246226d87e65be78ed49ecd1e6f5e98648558c14ce99176da041dc378e" + }, + "recordedDirentsInputs": {}, + "envVariables": {}, + "generatedRepoSpecs": { + "local_config_python": { + "repoRuleId": "@@pybind11_bazel+//:python_configure.bzl%python_configure", + "attributes": {} + }, + "pybind11": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "build_file": "@@pybind11_bazel+//:pybind11.BUILD", + "strip_prefix": "pybind11-2.11.1", + "urls": [ + "https://github.com/pybind/pybind11/archive/v2.11.1.zip" + ] + } + } + }, + "recordedRepoMappingEntries": [ + [ + "pybind11_bazel+", + "bazel_tools", + "bazel_tools" + ] + ] + } + }, + "@@rules_bazel_integration_test+//:extensions.bzl%bazel_binaries": { + "general": { + "bzlTransitiveDigest": "AbxPRYKjvVlRo+B89EHqsi8N7gdOjCmT7VEr6YYQxqg=", + "usagesDigest": "yDij5mbQdyGVKQfeNbJAtUENtDjd89nSxaTgwm93zOc=", + "recordedFileInputs": {}, + "recordedDirentsInputs": {}, + "envVariables": {}, + "generatedRepoSpecs": { + "bazel_binaries_bazelisk": { + "repoRuleId": "@@rules_bazel_integration_test+//bazel_integration_test/private:bazel_binaries.bzl%bazelisk_binary", + "attributes": { + "version": "1.18.0" + } + }, + "build_bazel_bazel_5_4_1": { + "repoRuleId": "@@rules_bazel_integration_test+//bazel_integration_test/private:bazel_binaries.bzl%bazel_binary", + "attributes": { + "version": "5.4.1", + "bazelisk": "@bazel_binaries_bazelisk//:bazelisk" + } + }, + "build_bazel_bazel_6_5_0": { + "repoRuleId": "@@rules_bazel_integration_test+//bazel_integration_test/private:bazel_binaries.bzl%bazel_binary", + "attributes": { + "version": "6.5.0", + "bazelisk": "@bazel_binaries_bazelisk//:bazelisk" + } + }, + "build_bazel_bazel_7_4_0": { + "repoRuleId": "@@rules_bazel_integration_test+//bazel_integration_test/private:bazel_binaries.bzl%bazel_binary", + "attributes": { + "version": "7.4.0", + "bazelisk": "@bazel_binaries_bazelisk//:bazelisk" + } + }, + "bazel_binaries": { + "repoRuleId": "@@rules_bazel_integration_test+//bazel_integration_test/bzlmod:bazel_binaries.bzl%_bazel_binaries_helper", + "attributes": { + "version_to_repo": { + "5.4.1": "build_bazel_bazel_5_4_1", + "6.5.0": "build_bazel_bazel_6_5_0", + "7.4.0": "build_bazel_bazel_7_4_0" + }, + "current_version": "7.4.0" + } + } + }, + "moduleExtensionMetadata": { + "explicitRootModuleDirectDeps": [], + "explicitRootModuleDirectDevDeps": [ + "bazel_binaries_bazelisk", + "build_bazel_bazel_5_4_1", + "build_bazel_bazel_6_5_0", + "build_bazel_bazel_7_4_0", + "bazel_binaries" + ], + "useAllRepos": "NO", + "reproducible": false + }, + "recordedRepoMappingEntries": [ + [ + "rules_bazel_integration_test+", + "bazel_skylib", + "bazel_skylib+" + ], + [ + "rules_bazel_integration_test+", + "cgrindel_bazel_starlib", + "cgrindel_bazel_starlib+" + ] + ] + } + }, + "@@rules_fuzzing+//fuzzing/private:extensions.bzl%non_module_dependencies": { + "general": { + "bzlTransitiveDigest": "mGiTB79hRNjmeDTQdzkpCHyzXhErMbufeAmySBt7s5s=", + "usagesDigest": "wy6ISK6UOcBEjj/mvJ/S3WeXoO67X+1llb9yPyFtPgc=", + "recordedFileInputs": {}, + "recordedDirentsInputs": {}, + "envVariables": {}, + "generatedRepoSpecs": { + "platforms": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "urls": [ + "https://mirror.bazel.build/github.com/bazelbuild/platforms/releases/download/0.0.8/platforms-0.0.8.tar.gz", + "https://github.com/bazelbuild/platforms/releases/download/0.0.8/platforms-0.0.8.tar.gz" + ], + "sha256": "8150406605389ececb6da07cbcb509d5637a3ab9a24bc69b1101531367d89d74" + } + }, + "rules_python": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "sha256": "d70cd72a7a4880f0000a6346253414825c19cdd40a28289bdf67b8e6480edff8", + "strip_prefix": "rules_python-0.28.0", + "url": "https://github.com/bazelbuild/rules_python/releases/download/0.28.0/rules_python-0.28.0.tar.gz" + } + }, + "bazel_skylib": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "sha256": "cd55a062e763b9349921f0f5db8c3933288dc8ba4f76dd9416aac68acee3cb94", + "urls": [ + "https://mirror.bazel.build/github.com/bazelbuild/bazel-skylib/releases/download/1.5.0/bazel-skylib-1.5.0.tar.gz", + "https://github.com/bazelbuild/bazel-skylib/releases/download/1.5.0/bazel-skylib-1.5.0.tar.gz" + ] + } + }, + "com_google_absl": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "urls": [ + "https://github.com/abseil/abseil-cpp/archive/refs/tags/20240116.1.zip" + ], + "strip_prefix": "abseil-cpp-20240116.1", + "integrity": "sha256-7capMWOvWyoYbUaHF/b+I2U6XLMaHmky8KugWvfXYuk=" + } + }, + "rules_fuzzing_oss_fuzz": { + "repoRuleId": "@@rules_fuzzing+//fuzzing/private/oss_fuzz:repository.bzl%oss_fuzz_repository", + "attributes": {} + }, + "honggfuzz": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "build_file": "@@rules_fuzzing+//:honggfuzz.BUILD", + "sha256": "6b18ba13bc1f36b7b950c72d80f19ea67fbadc0ac0bb297ec89ad91f2eaa423e", + "url": "https://github.com/google/honggfuzz/archive/2.5.zip", + "strip_prefix": "honggfuzz-2.5" + } + }, + "rules_fuzzing_jazzer": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_jar", + "attributes": { + "sha256": "ee6feb569d88962d59cb59e8a31eb9d007c82683f3ebc64955fd5b96f277eec2", + "url": "https://repo1.maven.org/maven2/com/code-intelligence/jazzer/0.20.1/jazzer-0.20.1.jar" + } + }, + "rules_fuzzing_jazzer_api": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_jar", + "attributes": { + "sha256": "f5a60242bc408f7fa20fccf10d6c5c5ea1fcb3c6f44642fec5af88373ae7aa1b", + "url": "https://repo1.maven.org/maven2/com/code-intelligence/jazzer-api/0.20.1/jazzer-api-0.20.1.jar" + } + } + }, + "recordedRepoMappingEntries": [ + [ + "rules_fuzzing+", + "bazel_tools", + "bazel_tools" + ] + ] + } + }, + "@@rules_java+//java:rules_java_deps.bzl%compatibility_proxy": { + "general": { + "bzlTransitiveDigest": "84xJEZ1jnXXwo8BXMprvBm++rRt4jsTu9liBxz0ivps=", + "usagesDigest": "jTQDdLDxsS43zuRmg1faAjIEPWdLAbDAowI1pInQSoo=", + "recordedFileInputs": {}, + "recordedDirentsInputs": {}, + "envVariables": {}, + "generatedRepoSpecs": { + "compatibility_proxy": { + "repoRuleId": "@@rules_java+//java:rules_java_deps.bzl%_compatibility_proxy_repo_rule", + "attributes": {} + } + }, + "recordedRepoMappingEntries": [ + [ + "rules_java+", + "bazel_tools", + "bazel_tools" + ] + ] + } + }, + "@@rules_kotlin+//src/main/starlark/core/repositories:bzlmod_setup.bzl%rules_kotlin_extensions": { + "general": { + "bzlTransitiveDigest": "NJOdnPIgUWy9k+k+aFuTY7QCyBVT9AhxZlDRNiOx61Q=", + "usagesDigest": "sA7eQq8ArVESgE7FiiD5tkjPB23LatMrbrQHa3AWPV8=", + "recordedFileInputs": {}, + "recordedDirentsInputs": {}, + "envVariables": {}, + "generatedRepoSpecs": { + "com_github_jetbrains_kotlin_git": { + "repoRuleId": "@@rules_kotlin+//src/main/starlark/core/repositories:compiler.bzl%kotlin_compiler_git_repository", + "attributes": { + "urls": [ + "https://github.com/JetBrains/kotlin/releases/download/v2.0.10/kotlin-compiler-2.0.10.zip" + ], + "sha256": "88d7d8bad362ae4e114a8b9668c6887b8c85f48e340883db0e317e47c8dc2f4f" + } + }, + "com_github_jetbrains_kotlin": { + "repoRuleId": "@@rules_kotlin+//src/main/starlark/core/repositories:compiler.bzl%kotlin_capabilities_repository", + "attributes": { + "git_repository_name": "com_github_jetbrains_kotlin_git", + "compiler_version": "2.0.10" + } + }, + "com_github_google_ksp": { + "repoRuleId": "@@rules_kotlin+//src/main/starlark/core/repositories:ksp.bzl%ksp_compiler_plugin_repository", + "attributes": { + "urls": [ + "https://github.com/google/ksp/releases/download/2.0.10-1.0.24/artifacts.zip" + ], + "sha256": "e6a79e649ee383b372fa982be89686c10ee42b25e60147b3271a70fd75a9eb19", + "strip_version": "2.0.10-1.0.24" + } + }, + "com_github_pinterest_ktlint": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_file", + "attributes": { + "sha256": "a9f923be58fbd32670a17f0b729b1df804af882fa57402165741cb26e5440ca1", + "urls": [ + "https://github.com/pinterest/ktlint/releases/download/1.3.1/ktlint" + ], + "executable": true + } + }, + "kotlinx_serialization_core_jvm": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_jar", + "attributes": { + "sha256": "29c821a8d4e25cbfe4f2ce96cdd4526f61f8f4e69a135f9612a34a81d93b65f1", + "urls": [ + "https://repo1.maven.org/maven2/org/jetbrains/kotlinx/kotlinx-serialization-core-jvm/1.6.3/kotlinx-serialization-core-jvm-1.6.3.jar" + ] + } + }, + "kotlinx_serialization_json": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_jar", + "attributes": { + "sha256": "8c0016890a79ab5980dd520a5ab1a6738023c29aa3b6437c482e0e5fdc06dab1", + "urls": [ + "https://repo1.maven.org/maven2/org/jetbrains/kotlinx/kotlinx-serialization-json/1.6.3/kotlinx-serialization-json-1.6.3.jar" + ] + } + }, + "kotlinx_serialization_json_jvm": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_jar", + "attributes": { + "sha256": "d3234179bcff1886d53d67c11eca47f7f3cf7b63c349d16965f6db51b7f3dd9a", + "urls": [ + "https://repo1.maven.org/maven2/org/jetbrains/kotlinx/kotlinx-serialization-json-jvm/1.6.3/kotlinx-serialization-json-jvm-1.6.3.jar" + ] + } + } + }, + "recordedRepoMappingEntries": [ + [ + "rules_kotlin+", + "bazel_tools", + "bazel_tools" + ] + ] + } + }, + "@@rules_python+//python/private/pypi:pip.bzl%pip_internal": { + "general": { + "bzlTransitiveDigest": "3uu4so4hkTi4ZxhYLGQQobOhKPOASmYbXTJKJhhpkD0=", + "usagesDigest": "OLoIStnzNObNalKEMRq99FqenhPGLFZ5utVLV4sz7OI=", + "recordedFileInputs": { + "@@rules_python+//tools/publish/requirements_darwin.txt": "2994136eab7e57b083c3de76faf46f70fad130bc8e7360a7fed2b288b69e79dc", + "@@rules_python+//tools/publish/requirements_linux.txt": "8175b4c8df50ae2f22d1706961884beeb54e7da27bd2447018314a175981997d", + "@@rules_python+//tools/publish/requirements_windows.txt": "7673adc71dc1a81d3661b90924d7a7c0fc998cd508b3cb4174337cef3f2de556" + }, + "recordedDirentsInputs": {}, + "envVariables": { + "RULES_PYTHON_REPO_DEBUG": null, + "RULES_PYTHON_REPO_DEBUG_VERBOSITY": null + }, + "generatedRepoSpecs": { + "rules_python_publish_deps_311_backports_tarfile_py3_none_any_77e284d7": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "filename": "backports.tarfile-1.2.0-py3-none-any.whl", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "backports-tarfile==1.2.0", + "sha256": "77e284d754527b01fb1e6fa8a1afe577858ebe4e9dad8919e34c862cb399bc34", + "urls": [ + "https://files.pythonhosted.org/packages/b9/fa/123043af240e49752f1c4bd24da5053b6bd00cad78c2be53c0d1e8b975bc/backports.tarfile-1.2.0-py3-none-any.whl" + ] + } + }, + "rules_python_publish_deps_311_backports_tarfile_sdist_d75e02c2": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "extra_pip_args": [ + "--index-url", + "https://pypi.org/simple" + ], + "filename": "backports_tarfile-1.2.0.tar.gz", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "backports-tarfile==1.2.0", + "sha256": "d75e02c268746e1b8144c278978b6e98e85de6ad16f8e4b0844a154557eca991", + "urls": [ + "https://files.pythonhosted.org/packages/86/72/cd9b395f25e290e633655a100af28cb253e4393396264a98bd5f5951d50f/backports_tarfile-1.2.0.tar.gz" + ] + } + }, + "rules_python_publish_deps_311_certifi_py3_none_any_922820b5": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "filename": "certifi-2024.8.30-py3-none-any.whl", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "certifi==2024.8.30", + "sha256": "922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8", + "urls": [ + "https://files.pythonhosted.org/packages/12/90/3c9ff0512038035f59d279fddeb79f5f1eccd8859f06d6163c58798b9487/certifi-2024.8.30-py3-none-any.whl" + ] + } + }, + "rules_python_publish_deps_311_certifi_sdist_bec941d2": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "extra_pip_args": [ + "--index-url", + "https://pypi.org/simple" + ], + "filename": "certifi-2024.8.30.tar.gz", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "certifi==2024.8.30", + "sha256": "bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9", + "urls": [ + "https://files.pythonhosted.org/packages/b0/ee/9b19140fe824b367c04c5e1b369942dd754c4c5462d5674002f75c4dedc1/certifi-2024.8.30.tar.gz" + ] + } + }, + "rules_python_publish_deps_311_cffi_cp311_cp311_manylinux_2_17_aarch64_a1ed2dd2": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64" + ], + "filename": "cffi-1.17.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "cffi==1.17.1", + "sha256": "a1ed2dd2972641495a3ec98445e09766f077aee98a1c896dcb4ad0d303628e41", + "urls": [ + "https://files.pythonhosted.org/packages/2e/ea/70ce63780f096e16ce8588efe039d3c4f91deb1dc01e9c73a287939c79a6/cffi-1.17.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl" + ] + } + }, + "rules_python_publish_deps_311_cffi_cp311_cp311_manylinux_2_17_ppc64le_46bf4316": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64" + ], + "filename": "cffi-1.17.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "cffi==1.17.1", + "sha256": "46bf43160c1a35f7ec506d254e5c890f3c03648a4dbac12d624e4490a7046cd1", + "urls": [ + "https://files.pythonhosted.org/packages/1c/a0/a4fa9f4f781bda074c3ddd57a572b060fa0df7655d2a4247bbe277200146/cffi-1.17.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl" + ] + } + }, + "rules_python_publish_deps_311_cffi_cp311_cp311_manylinux_2_17_s390x_a24ed04c": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64" + ], + "filename": "cffi-1.17.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "cffi==1.17.1", + "sha256": "a24ed04c8ffd54b0729c07cee15a81d964e6fee0e3d4d342a27b020d22959dc6", + "urls": [ + "https://files.pythonhosted.org/packages/62/12/ce8710b5b8affbcdd5c6e367217c242524ad17a02fe5beec3ee339f69f85/cffi-1.17.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl" + ] + } + }, + "rules_python_publish_deps_311_cffi_cp311_cp311_manylinux_2_17_x86_64_610faea7": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64" + ], + "filename": "cffi-1.17.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "cffi==1.17.1", + "sha256": "610faea79c43e44c71e1ec53a554553fa22321b65fae24889706c0a84d4ad86d", + "urls": [ + "https://files.pythonhosted.org/packages/ff/6b/d45873c5e0242196f042d555526f92aa9e0c32355a1be1ff8c27f077fd37/cffi-1.17.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl" + ] + } + }, + "rules_python_publish_deps_311_cffi_cp311_cp311_musllinux_1_1_aarch64_a9b15d49": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64" + ], + "filename": "cffi-1.17.1-cp311-cp311-musllinux_1_1_aarch64.whl", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "cffi==1.17.1", + "sha256": "a9b15d491f3ad5d692e11f6b71f7857e7835eb677955c00cc0aefcd0669adaf6", + "urls": [ + "https://files.pythonhosted.org/packages/1a/52/d9a0e523a572fbccf2955f5abe883cfa8bcc570d7faeee06336fbd50c9fc/cffi-1.17.1-cp311-cp311-musllinux_1_1_aarch64.whl" + ] + } + }, + "rules_python_publish_deps_311_cffi_cp311_cp311_musllinux_1_1_x86_64_fc48c783": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64" + ], + "filename": "cffi-1.17.1-cp311-cp311-musllinux_1_1_x86_64.whl", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "cffi==1.17.1", + "sha256": "fc48c783f9c87e60831201f2cce7f3b2e4846bf4d8728eabe54d60700b318a0b", + "urls": [ + "https://files.pythonhosted.org/packages/f8/4a/34599cac7dfcd888ff54e801afe06a19c17787dfd94495ab0c8d35fe99fb/cffi-1.17.1-cp311-cp311-musllinux_1_1_x86_64.whl" + ] + } + }, + "rules_python_publish_deps_311_cffi_sdist_1c39c601": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64" + ], + "extra_pip_args": [ + "--index-url", + "https://pypi.org/simple" + ], + "filename": "cffi-1.17.1.tar.gz", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "cffi==1.17.1", + "sha256": "1c39c6016c32bc48dd54561950ebd6836e1670f2ae46128f67cf49e789c52824", + "urls": [ + "https://files.pythonhosted.org/packages/fc/97/c783634659c2920c3fc70419e3af40972dbaf758daa229a7d6ea6135c90d/cffi-1.17.1.tar.gz" + ] + } + }, + "rules_python_publish_deps_311_charset_normalizer_cp311_cp311_macosx_10_9_universal2_0d99dd8f": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "filename": "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_universal2.whl", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "charset-normalizer==3.4.0", + "sha256": "0d99dd8ff461990f12d6e42c7347fd9ab2532fb70e9621ba520f9e8637161d7c", + "urls": [ + "https://files.pythonhosted.org/packages/9c/61/73589dcc7a719582bf56aae309b6103d2762b526bffe189d635a7fcfd998/charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_universal2.whl" + ] + } + }, + "rules_python_publish_deps_311_charset_normalizer_cp311_cp311_macosx_10_9_x86_64_c57516e5": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "filename": "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_x86_64.whl", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "charset-normalizer==3.4.0", + "sha256": "c57516e58fd17d03ebe67e181a4e4e2ccab1168f8c2976c6a334d4f819fe5944", + "urls": [ + "https://files.pythonhosted.org/packages/77/d5/8c982d58144de49f59571f940e329ad6e8615e1e82ef84584c5eeb5e1d72/charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_x86_64.whl" + ] + } + }, + "rules_python_publish_deps_311_charset_normalizer_cp311_cp311_macosx_11_0_arm64_6dba5d19": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "filename": "charset_normalizer-3.4.0-cp311-cp311-macosx_11_0_arm64.whl", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "charset-normalizer==3.4.0", + "sha256": "6dba5d19c4dfab08e58d5b36304b3f92f3bd5d42c1a3fa37b5ba5cdf6dfcbcee", + "urls": [ + "https://files.pythonhosted.org/packages/bf/19/411a64f01ee971bed3231111b69eb56f9331a769072de479eae7de52296d/charset_normalizer-3.4.0-cp311-cp311-macosx_11_0_arm64.whl" + ] + } + }, + "rules_python_publish_deps_311_charset_normalizer_cp311_cp311_manylinux_2_17_aarch64_bf4475b8": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "filename": "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "charset-normalizer==3.4.0", + "sha256": "bf4475b82be41b07cc5e5ff94810e6a01f276e37c2d55571e3fe175e467a1a1c", + "urls": [ + "https://files.pythonhosted.org/packages/4c/92/97509850f0d00e9f14a46bc751daabd0ad7765cff29cdfb66c68b6dad57f/charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl" + ] + } + }, + "rules_python_publish_deps_311_charset_normalizer_cp311_cp311_manylinux_2_17_ppc64le_ce031db0": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "filename": "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "charset-normalizer==3.4.0", + "sha256": "ce031db0408e487fd2775d745ce30a7cd2923667cf3b69d48d219f1d8f5ddeb6", + "urls": [ + "https://files.pythonhosted.org/packages/e2/29/d227805bff72ed6d6cb1ce08eec707f7cfbd9868044893617eb331f16295/charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl" + ] + } + }, + "rules_python_publish_deps_311_charset_normalizer_cp311_cp311_manylinux_2_17_s390x_8ff4e7cd": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "filename": "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "charset-normalizer==3.4.0", + "sha256": "8ff4e7cdfdb1ab5698e675ca622e72d58a6fa2a8aa58195de0c0061288e6e3ea", + "urls": [ + "https://files.pythonhosted.org/packages/13/bc/87c2c9f2c144bedfa62f894c3007cd4530ba4b5351acb10dc786428a50f0/charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl" + ] + } + }, + "rules_python_publish_deps_311_charset_normalizer_cp311_cp311_manylinux_2_17_x86_64_3710a975": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "filename": "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "charset-normalizer==3.4.0", + "sha256": "3710a9751938947e6327ea9f3ea6332a09bf0ba0c09cae9cb1f250bd1f1549bc", + "urls": [ + "https://files.pythonhosted.org/packages/eb/5b/6f10bad0f6461fa272bfbbdf5d0023b5fb9bc6217c92bf068fa5a99820f5/charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl" + ] + } + }, + "rules_python_publish_deps_311_charset_normalizer_cp311_cp311_musllinux_1_2_aarch64_47334db7": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "filename": "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_aarch64.whl", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "charset-normalizer==3.4.0", + "sha256": "47334db71978b23ebcf3c0f9f5ee98b8d65992b65c9c4f2d34c2eaf5bcaf0594", + "urls": [ + "https://files.pythonhosted.org/packages/d7/a1/493919799446464ed0299c8eef3c3fad0daf1c3cd48bff9263c731b0d9e2/charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_aarch64.whl" + ] + } + }, + "rules_python_publish_deps_311_charset_normalizer_cp311_cp311_musllinux_1_2_ppc64le_f1a2f519": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "filename": "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_ppc64le.whl", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "charset-normalizer==3.4.0", + "sha256": "f1a2f519ae173b5b6a2c9d5fa3116ce16e48b3462c8b96dfdded11055e3d6365", + "urls": [ + "https://files.pythonhosted.org/packages/75/d2/0ab54463d3410709c09266dfb416d032a08f97fd7d60e94b8c6ef54ae14b/charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_ppc64le.whl" + ] + } + }, + "rules_python_publish_deps_311_charset_normalizer_cp311_cp311_musllinux_1_2_s390x_63bc5c4a": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "filename": "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_s390x.whl", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "charset-normalizer==3.4.0", + "sha256": "63bc5c4ae26e4bc6be6469943b8253c0fd4e4186c43ad46e713ea61a0ba49129", + "urls": [ + "https://files.pythonhosted.org/packages/8d/c9/27e41d481557be53d51e60750b85aa40eaf52b841946b3cdeff363105737/charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_s390x.whl" + ] + } + }, + "rules_python_publish_deps_311_charset_normalizer_cp311_cp311_musllinux_1_2_x86_64_bcb4f8ea": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "filename": "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_x86_64.whl", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "charset-normalizer==3.4.0", + "sha256": "bcb4f8ea87d03bc51ad04add8ceaf9b0f085ac045ab4d74e73bbc2dc033f0236", + "urls": [ + "https://files.pythonhosted.org/packages/ee/44/4f62042ca8cdc0cabf87c0fc00ae27cd8b53ab68be3605ba6d071f742ad3/charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_x86_64.whl" + ] + } + }, + "rules_python_publish_deps_311_charset_normalizer_cp311_cp311_win_amd64_cee4373f": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "filename": "charset_normalizer-3.4.0-cp311-cp311-win_amd64.whl", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "charset-normalizer==3.4.0", + "sha256": "cee4373f4d3ad28f1ab6290684d8e2ebdb9e7a1b74fdc39e4c211995f77bec27", + "urls": [ + "https://files.pythonhosted.org/packages/0b/6e/b13bd47fa9023b3699e94abf565b5a2f0b0be6e9ddac9812182596ee62e4/charset_normalizer-3.4.0-cp311-cp311-win_amd64.whl" + ] + } + }, + "rules_python_publish_deps_311_charset_normalizer_py3_none_any_fe9f97fe": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "filename": "charset_normalizer-3.4.0-py3-none-any.whl", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "charset-normalizer==3.4.0", + "sha256": "fe9f97feb71aa9896b81973a7bbada8c49501dc73e58a10fcef6663af95e5079", + "urls": [ + "https://files.pythonhosted.org/packages/bf/9b/08c0432272d77b04803958a4598a51e2a4b51c06640af8b8f0f908c18bf2/charset_normalizer-3.4.0-py3-none-any.whl" + ] + } + }, + "rules_python_publish_deps_311_charset_normalizer_sdist_223217c3": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "extra_pip_args": [ + "--index-url", + "https://pypi.org/simple" + ], + "filename": "charset_normalizer-3.4.0.tar.gz", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "charset-normalizer==3.4.0", + "sha256": "223217c3d4f82c3ac5e29032b3f1c2eb0fb591b72161f86d93f5719079dae93e", + "urls": [ + "https://files.pythonhosted.org/packages/f2/4f/e1808dc01273379acc506d18f1504eb2d299bd4131743b9fc54d7be4df1e/charset_normalizer-3.4.0.tar.gz" + ] + } + }, + "rules_python_publish_deps_311_cryptography_cp39_abi3_manylinux_2_17_aarch64_846da004": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64" + ], + "filename": "cryptography-43.0.3-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "cryptography==43.0.3", + "sha256": "846da004a5804145a5f441b8530b4bf35afbf7da70f82409f151695b127213d5", + "urls": [ + "https://files.pythonhosted.org/packages/2f/78/55356eb9075d0be6e81b59f45c7b48df87f76a20e73893872170471f3ee8/cryptography-43.0.3-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl" + ] + } + }, + "rules_python_publish_deps_311_cryptography_cp39_abi3_manylinux_2_17_x86_64_0f996e72": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64" + ], + "filename": "cryptography-43.0.3-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "cryptography==43.0.3", + "sha256": "0f996e7268af62598f2fc1204afa98a3b5712313a55c4c9d434aef49cadc91d4", + "urls": [ + "https://files.pythonhosted.org/packages/2a/2c/488776a3dc843f95f86d2f957ca0fc3407d0242b50bede7fad1e339be03f/cryptography-43.0.3-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl" + ] + } + }, + "rules_python_publish_deps_311_cryptography_cp39_abi3_manylinux_2_28_aarch64_f7b178f1": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64" + ], + "filename": "cryptography-43.0.3-cp39-abi3-manylinux_2_28_aarch64.whl", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "cryptography==43.0.3", + "sha256": "f7b178f11ed3664fd0e995a47ed2b5ff0a12d893e41dd0494f406d1cf555cab7", + "urls": [ + "https://files.pythonhosted.org/packages/7c/04/2345ca92f7a22f601a9c62961741ef7dd0127c39f7310dffa0041c80f16f/cryptography-43.0.3-cp39-abi3-manylinux_2_28_aarch64.whl" + ] + } + }, + "rules_python_publish_deps_311_cryptography_cp39_abi3_manylinux_2_28_x86_64_c2e6fc39": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64" + ], + "filename": "cryptography-43.0.3-cp39-abi3-manylinux_2_28_x86_64.whl", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "cryptography==43.0.3", + "sha256": "c2e6fc39c4ab499049df3bdf567f768a723a5e8464816e8f009f121a5a9f4405", + "urls": [ + "https://files.pythonhosted.org/packages/ac/25/e715fa0bc24ac2114ed69da33adf451a38abb6f3f24ec207908112e9ba53/cryptography-43.0.3-cp39-abi3-manylinux_2_28_x86_64.whl" + ] + } + }, + "rules_python_publish_deps_311_cryptography_cp39_abi3_musllinux_1_2_aarch64_e1be4655": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64" + ], + "filename": "cryptography-43.0.3-cp39-abi3-musllinux_1_2_aarch64.whl", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "cryptography==43.0.3", + "sha256": "e1be4655c7ef6e1bbe6b5d0403526601323420bcf414598955968c9ef3eb7d16", + "urls": [ + "https://files.pythonhosted.org/packages/21/ce/b9c9ff56c7164d8e2edfb6c9305045fbc0df4508ccfdb13ee66eb8c95b0e/cryptography-43.0.3-cp39-abi3-musllinux_1_2_aarch64.whl" + ] + } + }, + "rules_python_publish_deps_311_cryptography_cp39_abi3_musllinux_1_2_x86_64_df6b6c6d": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64" + ], + "filename": "cryptography-43.0.3-cp39-abi3-musllinux_1_2_x86_64.whl", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "cryptography==43.0.3", + "sha256": "df6b6c6d742395dd77a23ea3728ab62f98379eff8fb61be2744d4679ab678f73", + "urls": [ + "https://files.pythonhosted.org/packages/2a/33/b3682992ab2e9476b9c81fff22f02c8b0a1e6e1d49ee1750a67d85fd7ed2/cryptography-43.0.3-cp39-abi3-musllinux_1_2_x86_64.whl" + ] + } + }, + "rules_python_publish_deps_311_cryptography_sdist_315b9001": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64" + ], + "extra_pip_args": [ + "--index-url", + "https://pypi.org/simple" + ], + "filename": "cryptography-43.0.3.tar.gz", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "cryptography==43.0.3", + "sha256": "315b9001266a492a6ff443b61238f956b214dbec9910a081ba5b6646a055a805", + "urls": [ + "https://files.pythonhosted.org/packages/0d/05/07b55d1fa21ac18c3a8c79f764e2514e6f6a9698f1be44994f5adf0d29db/cryptography-43.0.3.tar.gz" + ] + } + }, + "rules_python_publish_deps_311_docutils_py3_none_any_dafca5b9": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "filename": "docutils-0.21.2-py3-none-any.whl", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "docutils==0.21.2", + "sha256": "dafca5b9e384f0e419294eb4d2ff9fa826435bf15f15b7bd45723e8ad76811b2", + "urls": [ + "https://files.pythonhosted.org/packages/8f/d7/9322c609343d929e75e7e5e6255e614fcc67572cfd083959cdef3b7aad79/docutils-0.21.2-py3-none-any.whl" + ] + } + }, + "rules_python_publish_deps_311_docutils_sdist_3a6b1873": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "extra_pip_args": [ + "--index-url", + "https://pypi.org/simple" + ], + "filename": "docutils-0.21.2.tar.gz", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "docutils==0.21.2", + "sha256": "3a6b18732edf182daa3cd12775bbb338cf5691468f91eeeb109deff6ebfa986f", + "urls": [ + "https://files.pythonhosted.org/packages/ae/ed/aefcc8cd0ba62a0560c3c18c33925362d46c6075480bfa4df87b28e169a9/docutils-0.21.2.tar.gz" + ] + } + }, + "rules_python_publish_deps_311_idna_py3_none_any_946d195a": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "filename": "idna-3.10-py3-none-any.whl", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "idna==3.10", + "sha256": "946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3", + "urls": [ + "https://files.pythonhosted.org/packages/76/c6/c88e154df9c4e1a2a66ccf0005a88dfb2650c1dffb6f5ce603dfbd452ce3/idna-3.10-py3-none-any.whl" + ] + } + }, + "rules_python_publish_deps_311_idna_sdist_12f65c9b": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "extra_pip_args": [ + "--index-url", + "https://pypi.org/simple" + ], + "filename": "idna-3.10.tar.gz", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "idna==3.10", + "sha256": "12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9", + "urls": [ + "https://files.pythonhosted.org/packages/f1/70/7703c29685631f5a7590aa73f1f1d3fa9a380e654b86af429e0934a32f7d/idna-3.10.tar.gz" + ] + } + }, + "rules_python_publish_deps_311_importlib_metadata_py3_none_any_45e54197": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "filename": "importlib_metadata-8.5.0-py3-none-any.whl", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "importlib-metadata==8.5.0", + "sha256": "45e54197d28b7a7f1559e60b95e7c567032b602131fbd588f1497f47880aa68b", + "urls": [ + "https://files.pythonhosted.org/packages/a0/d9/a1e041c5e7caa9a05c925f4bdbdfb7f006d1f74996af53467bc394c97be7/importlib_metadata-8.5.0-py3-none-any.whl" + ] + } + }, + "rules_python_publish_deps_311_importlib_metadata_sdist_71522656": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "extra_pip_args": [ + "--index-url", + "https://pypi.org/simple" + ], + "filename": "importlib_metadata-8.5.0.tar.gz", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "importlib-metadata==8.5.0", + "sha256": "71522656f0abace1d072b9e5481a48f07c138e00f079c38c8f883823f9c26bd7", + "urls": [ + "https://files.pythonhosted.org/packages/cd/12/33e59336dca5be0c398a7482335911a33aa0e20776128f038019f1a95f1b/importlib_metadata-8.5.0.tar.gz" + ] + } + }, + "rules_python_publish_deps_311_jaraco_classes_py3_none_any_f662826b": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "filename": "jaraco.classes-3.4.0-py3-none-any.whl", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "jaraco-classes==3.4.0", + "sha256": "f662826b6bed8cace05e7ff873ce0f9283b5c924470fe664fff1c2f00f581790", + "urls": [ + "https://files.pythonhosted.org/packages/7f/66/b15ce62552d84bbfcec9a4873ab79d993a1dd4edb922cbfccae192bd5b5f/jaraco.classes-3.4.0-py3-none-any.whl" + ] + } + }, + "rules_python_publish_deps_311_jaraco_classes_sdist_47a024b5": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "extra_pip_args": [ + "--index-url", + "https://pypi.org/simple" + ], + "filename": "jaraco.classes-3.4.0.tar.gz", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "jaraco-classes==3.4.0", + "sha256": "47a024b51d0239c0dd8c8540c6c7f484be3b8fcf0b2d85c13825780d3b3f3acd", + "urls": [ + "https://files.pythonhosted.org/packages/06/c0/ed4a27bc5571b99e3cff68f8a9fa5b56ff7df1c2251cc715a652ddd26402/jaraco.classes-3.4.0.tar.gz" + ] + } + }, + "rules_python_publish_deps_311_jaraco_context_py3_none_any_f797fc48": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "filename": "jaraco.context-6.0.1-py3-none-any.whl", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "jaraco-context==6.0.1", + "sha256": "f797fc481b490edb305122c9181830a3a5b76d84ef6d1aef2fb9b47ab956f9e4", + "urls": [ + "https://files.pythonhosted.org/packages/ff/db/0c52c4cf5e4bd9f5d7135ec7669a3a767af21b3a308e1ed3674881e52b62/jaraco.context-6.0.1-py3-none-any.whl" + ] + } + }, + "rules_python_publish_deps_311_jaraco_context_sdist_9bae4ea5": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "extra_pip_args": [ + "--index-url", + "https://pypi.org/simple" + ], + "filename": "jaraco_context-6.0.1.tar.gz", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "jaraco-context==6.0.1", + "sha256": "9bae4ea555cf0b14938dc0aee7c9f32ed303aa20a3b73e7dc80111628792d1b3", + "urls": [ + "https://files.pythonhosted.org/packages/df/ad/f3777b81bf0b6e7bc7514a1656d3e637b2e8e15fab2ce3235730b3e7a4e6/jaraco_context-6.0.1.tar.gz" + ] + } + }, + "rules_python_publish_deps_311_jaraco_functools_py3_none_any_ad159f13": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "filename": "jaraco.functools-4.1.0-py3-none-any.whl", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "jaraco-functools==4.1.0", + "sha256": "ad159f13428bc4acbf5541ad6dec511f91573b90fba04df61dafa2a1231cf649", + "urls": [ + "https://files.pythonhosted.org/packages/9f/4f/24b319316142c44283d7540e76c7b5a6dbd5db623abd86bb7b3491c21018/jaraco.functools-4.1.0-py3-none-any.whl" + ] + } + }, + "rules_python_publish_deps_311_jaraco_functools_sdist_70f7e0e2": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "extra_pip_args": [ + "--index-url", + "https://pypi.org/simple" + ], + "filename": "jaraco_functools-4.1.0.tar.gz", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "jaraco-functools==4.1.0", + "sha256": "70f7e0e2ae076498e212562325e805204fc092d7b4c17e0e86c959e249701a9d", + "urls": [ + "https://files.pythonhosted.org/packages/ab/23/9894b3df5d0a6eb44611c36aec777823fc2e07740dabbd0b810e19594013/jaraco_functools-4.1.0.tar.gz" + ] + } + }, + "rules_python_publish_deps_311_jeepney_py3_none_any_c0a454ad": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64" + ], + "filename": "jeepney-0.8.0-py3-none-any.whl", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "jeepney==0.8.0", + "sha256": "c0a454ad016ca575060802ee4d590dd912e35c122fa04e70306de3d076cce755", + "urls": [ + "https://files.pythonhosted.org/packages/ae/72/2a1e2290f1ab1e06f71f3d0f1646c9e4634e70e1d37491535e19266e8dc9/jeepney-0.8.0-py3-none-any.whl" + ] + } + }, + "rules_python_publish_deps_311_jeepney_sdist_5efe48d2": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64" + ], + "extra_pip_args": [ + "--index-url", + "https://pypi.org/simple" + ], + "filename": "jeepney-0.8.0.tar.gz", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "jeepney==0.8.0", + "sha256": "5efe48d255973902f6badc3ce55e2aa6c5c3b3bc642059ef3a91247bcfcc5806", + "urls": [ + "https://files.pythonhosted.org/packages/d6/f4/154cf374c2daf2020e05c3c6a03c91348d59b23c5366e968feb198306fdf/jeepney-0.8.0.tar.gz" + ] + } + }, + "rules_python_publish_deps_311_keyring_py3_none_any_5426f817": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "filename": "keyring-25.4.1-py3-none-any.whl", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "keyring==25.4.1", + "sha256": "5426f817cf7f6f007ba5ec722b1bcad95a75b27d780343772ad76b17cb47b0bf", + "urls": [ + "https://files.pythonhosted.org/packages/83/25/e6d59e5f0a0508d0dca8bb98c7f7fd3772fc943ac3f53d5ab18a218d32c0/keyring-25.4.1-py3-none-any.whl" + ] + } + }, + "rules_python_publish_deps_311_keyring_sdist_b07ebc55": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "extra_pip_args": [ + "--index-url", + "https://pypi.org/simple" + ], + "filename": "keyring-25.4.1.tar.gz", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "keyring==25.4.1", + "sha256": "b07ebc55f3e8ed86ac81dd31ef14e81ace9dd9c3d4b5d77a6e9a2016d0d71a1b", + "urls": [ + "https://files.pythonhosted.org/packages/a5/1c/2bdbcfd5d59dc6274ffb175bc29aa07ecbfab196830e0cfbde7bd861a2ea/keyring-25.4.1.tar.gz" + ] + } + }, + "rules_python_publish_deps_311_markdown_it_py_py3_none_any_35521684": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "filename": "markdown_it_py-3.0.0-py3-none-any.whl", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "markdown-it-py==3.0.0", + "sha256": "355216845c60bd96232cd8d8c40e8f9765cc86f46880e43a8fd22dc1a1a8cab1", + "urls": [ + "https://files.pythonhosted.org/packages/42/d7/1ec15b46af6af88f19b8e5ffea08fa375d433c998b8a7639e76935c14f1f/markdown_it_py-3.0.0-py3-none-any.whl" + ] + } + }, + "rules_python_publish_deps_311_markdown_it_py_sdist_e3f60a94": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "extra_pip_args": [ + "--index-url", + "https://pypi.org/simple" + ], + "filename": "markdown-it-py-3.0.0.tar.gz", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "markdown-it-py==3.0.0", + "sha256": "e3f60a94fa066dc52ec76661e37c851cb232d92f9886b15cb560aaada2df8feb", + "urls": [ + "https://files.pythonhosted.org/packages/38/71/3b932df36c1a044d397a1f92d1cf91ee0a503d91e470cbd670aa66b07ed0/markdown-it-py-3.0.0.tar.gz" + ] + } + }, + "rules_python_publish_deps_311_mdurl_py3_none_any_84008a41": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "filename": "mdurl-0.1.2-py3-none-any.whl", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "mdurl==0.1.2", + "sha256": "84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8", + "urls": [ + "https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl" + ] + } + }, + "rules_python_publish_deps_311_mdurl_sdist_bb413d29": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "extra_pip_args": [ + "--index-url", + "https://pypi.org/simple" + ], + "filename": "mdurl-0.1.2.tar.gz", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "mdurl==0.1.2", + "sha256": "bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba", + "urls": [ + "https://files.pythonhosted.org/packages/d6/54/cfe61301667036ec958cb99bd3efefba235e65cdeb9c84d24a8293ba1d90/mdurl-0.1.2.tar.gz" + ] + } + }, + "rules_python_publish_deps_311_more_itertools_py3_none_any_037b0d32": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "filename": "more_itertools-10.5.0-py3-none-any.whl", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "more-itertools==10.5.0", + "sha256": "037b0d3203ce90cca8ab1defbbdac29d5f993fc20131f3664dc8d6acfa872aef", + "urls": [ + "https://files.pythonhosted.org/packages/48/7e/3a64597054a70f7c86eb0a7d4fc315b8c1ab932f64883a297bdffeb5f967/more_itertools-10.5.0-py3-none-any.whl" + ] + } + }, + "rules_python_publish_deps_311_more_itertools_sdist_5482bfef": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "extra_pip_args": [ + "--index-url", + "https://pypi.org/simple" + ], + "filename": "more-itertools-10.5.0.tar.gz", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "more-itertools==10.5.0", + "sha256": "5482bfef7849c25dc3c6dd53a6173ae4795da2a41a80faea6700d9f5846c5da6", + "urls": [ + "https://files.pythonhosted.org/packages/51/78/65922308c4248e0eb08ebcbe67c95d48615cc6f27854b6f2e57143e9178f/more-itertools-10.5.0.tar.gz" + ] + } + }, + "rules_python_publish_deps_311_nh3_cp37_abi3_macosx_10_12_x86_64_14c5a72e": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "filename": "nh3-0.2.18-cp37-abi3-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "nh3==0.2.18", + "sha256": "14c5a72e9fe82aea5fe3072116ad4661af5cf8e8ff8fc5ad3450f123e4925e86", + "urls": [ + "https://files.pythonhosted.org/packages/b3/89/1daff5d9ba5a95a157c092c7c5f39b8dd2b1ddb4559966f808d31cfb67e0/nh3-0.2.18-cp37-abi3-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl" + ] + } + }, + "rules_python_publish_deps_311_nh3_cp37_abi3_macosx_10_12_x86_64_7b7c2a3c": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "filename": "nh3-0.2.18-cp37-abi3-macosx_10_12_x86_64.whl", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "nh3==0.2.18", + "sha256": "7b7c2a3c9eb1a827d42539aa64091640bd275b81e097cd1d8d82ef91ffa2e811", + "urls": [ + "https://files.pythonhosted.org/packages/2c/b6/42fc3c69cabf86b6b81e4c051a9b6e249c5ba9f8155590222c2622961f58/nh3-0.2.18-cp37-abi3-macosx_10_12_x86_64.whl" + ] + } + }, + "rules_python_publish_deps_311_nh3_cp37_abi3_manylinux_2_17_aarch64_42c64511": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "filename": "nh3-0.2.18-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "nh3==0.2.18", + "sha256": "42c64511469005058cd17cc1537578eac40ae9f7200bedcfd1fc1a05f4f8c200", + "urls": [ + "https://files.pythonhosted.org/packages/45/b9/833f385403abaf0023c6547389ec7a7acf141ddd9d1f21573723a6eab39a/nh3-0.2.18-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl" + ] + } + }, + "rules_python_publish_deps_311_nh3_cp37_abi3_manylinux_2_17_armv7l_0411beb0": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "filename": "nh3-0.2.18-cp37-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "nh3==0.2.18", + "sha256": "0411beb0589eacb6734f28d5497ca2ed379eafab8ad8c84b31bb5c34072b7164", + "urls": [ + "https://files.pythonhosted.org/packages/05/2b/85977d9e11713b5747595ee61f381bc820749daf83f07b90b6c9964cf932/nh3-0.2.18-cp37-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl" + ] + } + }, + "rules_python_publish_deps_311_nh3_cp37_abi3_manylinux_2_17_ppc64_5f36b271": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "filename": "nh3-0.2.18-cp37-abi3-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "nh3==0.2.18", + "sha256": "5f36b271dae35c465ef5e9090e1fdaba4a60a56f0bb0ba03e0932a66f28b9189", + "urls": [ + "https://files.pythonhosted.org/packages/72/f2/5c894d5265ab80a97c68ca36f25c8f6f0308abac649aaf152b74e7e854a8/nh3-0.2.18-cp37-abi3-manylinux_2_17_ppc64.manylinux2014_ppc64.whl" + ] + } + }, + "rules_python_publish_deps_311_nh3_cp37_abi3_manylinux_2_17_ppc64le_34c03fa7": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "filename": "nh3-0.2.18-cp37-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "nh3==0.2.18", + "sha256": "34c03fa78e328c691f982b7c03d4423bdfd7da69cd707fe572f544cf74ac23ad", + "urls": [ + "https://files.pythonhosted.org/packages/ab/a7/375afcc710dbe2d64cfbd69e31f82f3e423d43737258af01f6a56d844085/nh3-0.2.18-cp37-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl" + ] + } + }, + "rules_python_publish_deps_311_nh3_cp37_abi3_manylinux_2_17_s390x_19aaba96": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "filename": "nh3-0.2.18-cp37-abi3-manylinux_2_17_s390x.manylinux2014_s390x.whl", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "nh3==0.2.18", + "sha256": "19aaba96e0f795bd0a6c56291495ff59364f4300d4a39b29a0abc9cb3774a84b", + "urls": [ + "https://files.pythonhosted.org/packages/c2/a8/3bb02d0c60a03ad3a112b76c46971e9480efa98a8946677b5a59f60130ca/nh3-0.2.18-cp37-abi3-manylinux_2_17_s390x.manylinux2014_s390x.whl" + ] + } + }, + "rules_python_publish_deps_311_nh3_cp37_abi3_manylinux_2_17_x86_64_de3ceed6": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "filename": "nh3-0.2.18-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "nh3==0.2.18", + "sha256": "de3ceed6e661954871d6cd78b410213bdcb136f79aafe22aa7182e028b8c7307", + "urls": [ + "https://files.pythonhosted.org/packages/1b/63/6ab90d0e5225ab9780f6c9fb52254fa36b52bb7c188df9201d05b647e5e1/nh3-0.2.18-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl" + ] + } + }, + "rules_python_publish_deps_311_nh3_cp37_abi3_musllinux_1_2_aarch64_f0eca9ca": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "filename": "nh3-0.2.18-cp37-abi3-musllinux_1_2_aarch64.whl", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "nh3==0.2.18", + "sha256": "f0eca9ca8628dbb4e916ae2491d72957fdd35f7a5d326b7032a345f111ac07fe", + "urls": [ + "https://files.pythonhosted.org/packages/a3/da/0c4e282bc3cff4a0adf37005fa1fb42257673fbc1bbf7d1ff639ec3d255a/nh3-0.2.18-cp37-abi3-musllinux_1_2_aarch64.whl" + ] + } + }, + "rules_python_publish_deps_311_nh3_cp37_abi3_musllinux_1_2_armv7l_3a157ab1": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "filename": "nh3-0.2.18-cp37-abi3-musllinux_1_2_armv7l.whl", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "nh3==0.2.18", + "sha256": "3a157ab149e591bb638a55c8c6bcb8cdb559c8b12c13a8affaba6cedfe51713a", + "urls": [ + "https://files.pythonhosted.org/packages/de/81/c291231463d21da5f8bba82c8167a6d6893cc5419b0639801ee5d3aeb8a9/nh3-0.2.18-cp37-abi3-musllinux_1_2_armv7l.whl" + ] + } + }, + "rules_python_publish_deps_311_nh3_cp37_abi3_musllinux_1_2_x86_64_36c95d4b": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "filename": "nh3-0.2.18-cp37-abi3-musllinux_1_2_x86_64.whl", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "nh3==0.2.18", + "sha256": "36c95d4b70530b320b365659bb5034341316e6a9b30f0b25fa9c9eff4c27a204", + "urls": [ + "https://files.pythonhosted.org/packages/eb/61/73a007c74c37895fdf66e0edcd881f5eaa17a348ff02f4bb4bc906d61085/nh3-0.2.18-cp37-abi3-musllinux_1_2_x86_64.whl" + ] + } + }, + "rules_python_publish_deps_311_nh3_cp37_abi3_win_amd64_8ce0f819": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "filename": "nh3-0.2.18-cp37-abi3-win_amd64.whl", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "nh3==0.2.18", + "sha256": "8ce0f819d2f1933953fca255db2471ad58184a60508f03e6285e5114b6254844", + "urls": [ + "https://files.pythonhosted.org/packages/26/8d/53c5b19c4999bdc6ba95f246f4ef35ca83d7d7423e5e38be43ad66544e5d/nh3-0.2.18-cp37-abi3-win_amd64.whl" + ] + } + }, + "rules_python_publish_deps_311_nh3_sdist_94a16692": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "extra_pip_args": [ + "--index-url", + "https://pypi.org/simple" + ], + "filename": "nh3-0.2.18.tar.gz", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "nh3==0.2.18", + "sha256": "94a166927e53972a9698af9542ace4e38b9de50c34352b962f4d9a7d4c927af4", + "urls": [ + "https://files.pythonhosted.org/packages/62/73/10df50b42ddb547a907deeb2f3c9823022580a7a47281e8eae8e003a9639/nh3-0.2.18.tar.gz" + ] + } + }, + "rules_python_publish_deps_311_pkginfo_py3_none_any_889a6da2": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "filename": "pkginfo-1.10.0-py3-none-any.whl", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "pkginfo==1.10.0", + "sha256": "889a6da2ed7ffc58ab5b900d888ddce90bce912f2d2de1dc1c26f4cb9fe65097", + "urls": [ + "https://files.pythonhosted.org/packages/56/09/054aea9b7534a15ad38a363a2bd974c20646ab1582a387a95b8df1bfea1c/pkginfo-1.10.0-py3-none-any.whl" + ] + } + }, + "rules_python_publish_deps_311_pkginfo_sdist_5df73835": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "extra_pip_args": [ + "--index-url", + "https://pypi.org/simple" + ], + "filename": "pkginfo-1.10.0.tar.gz", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "pkginfo==1.10.0", + "sha256": "5df73835398d10db79f8eecd5cd86b1f6d29317589ea70796994d49399af6297", + "urls": [ + "https://files.pythonhosted.org/packages/2f/72/347ec5be4adc85c182ed2823d8d1c7b51e13b9a6b0c1aae59582eca652df/pkginfo-1.10.0.tar.gz" + ] + } + }, + "rules_python_publish_deps_311_pycparser_py3_none_any_c3702b6d": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64" + ], + "filename": "pycparser-2.22-py3-none-any.whl", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "pycparser==2.22", + "sha256": "c3702b6d3dd8c7abc1afa565d7e63d53a1d0bd86cdc24edd75470f4de499cfcc", + "urls": [ + "https://files.pythonhosted.org/packages/13/a3/a812df4e2dd5696d1f351d58b8fe16a405b234ad2886a0dab9183fb78109/pycparser-2.22-py3-none-any.whl" + ] + } + }, + "rules_python_publish_deps_311_pycparser_sdist_491c8be9": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64" + ], + "extra_pip_args": [ + "--index-url", + "https://pypi.org/simple" + ], + "filename": "pycparser-2.22.tar.gz", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "pycparser==2.22", + "sha256": "491c8be9c040f5390f5bf44a5b07752bd07f56edf992381b05c701439eec10f6", + "urls": [ + "https://files.pythonhosted.org/packages/1d/b2/31537cf4b1ca988837256c910a668b553fceb8f069bedc4b1c826024b52c/pycparser-2.22.tar.gz" + ] + } + }, + "rules_python_publish_deps_311_pygments_py3_none_any_b8e6aca0": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "filename": "pygments-2.18.0-py3-none-any.whl", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "pygments==2.18.0", + "sha256": "b8e6aca0523f3ab76fee51799c488e38782ac06eafcf95e7ba832985c8e7b13a", + "urls": [ + "https://files.pythonhosted.org/packages/f7/3f/01c8b82017c199075f8f788d0d906b9ffbbc5a47dc9918a945e13d5a2bda/pygments-2.18.0-py3-none-any.whl" + ] + } + }, + "rules_python_publish_deps_311_pygments_sdist_786ff802": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "extra_pip_args": [ + "--index-url", + "https://pypi.org/simple" + ], + "filename": "pygments-2.18.0.tar.gz", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "pygments==2.18.0", + "sha256": "786ff802f32e91311bff3889f6e9a86e81505fe99f2735bb6d60ae0c5004f199", + "urls": [ + "https://files.pythonhosted.org/packages/8e/62/8336eff65bcbc8e4cb5d05b55faf041285951b6e80f33e2bff2024788f31/pygments-2.18.0.tar.gz" + ] + } + }, + "rules_python_publish_deps_311_pywin32_ctypes_py3_none_any_8a151337": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_windows_x86_64" + ], + "filename": "pywin32_ctypes-0.2.3-py3-none-any.whl", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "pywin32-ctypes==0.2.3", + "sha256": "8a1513379d709975552d202d942d9837758905c8d01eb82b8bcc30918929e7b8", + "urls": [ + "https://files.pythonhosted.org/packages/de/3d/8161f7711c017e01ac9f008dfddd9410dff3674334c233bde66e7ba65bbf/pywin32_ctypes-0.2.3-py3-none-any.whl" + ] + } + }, + "rules_python_publish_deps_311_pywin32_ctypes_sdist_d162dc04": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_windows_x86_64" + ], + "extra_pip_args": [ + "--index-url", + "https://pypi.org/simple" + ], + "filename": "pywin32-ctypes-0.2.3.tar.gz", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "pywin32-ctypes==0.2.3", + "sha256": "d162dc04946d704503b2edc4d55f3dba5c1d539ead017afa00142c38b9885755", + "urls": [ + "https://files.pythonhosted.org/packages/85/9f/01a1a99704853cb63f253eea009390c88e7131c67e66a0a02099a8c917cb/pywin32-ctypes-0.2.3.tar.gz" + ] + } + }, + "rules_python_publish_deps_311_readme_renderer_py3_none_any_2fbca89b": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "filename": "readme_renderer-44.0-py3-none-any.whl", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "readme-renderer==44.0", + "sha256": "2fbca89b81a08526aadf1357a8c2ae889ec05fb03f5da67f9769c9a592166151", + "urls": [ + "https://files.pythonhosted.org/packages/e1/67/921ec3024056483db83953ae8e48079ad62b92db7880013ca77632921dd0/readme_renderer-44.0-py3-none-any.whl" + ] + } + }, + "rules_python_publish_deps_311_readme_renderer_sdist_8712034e": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "extra_pip_args": [ + "--index-url", + "https://pypi.org/simple" + ], + "filename": "readme_renderer-44.0.tar.gz", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "readme-renderer==44.0", + "sha256": "8712034eabbfa6805cacf1402b4eeb2a73028f72d1166d6f5cb7f9c047c5d1e1", + "urls": [ + "https://files.pythonhosted.org/packages/5a/a9/104ec9234c8448c4379768221ea6df01260cd6c2ce13182d4eac531c8342/readme_renderer-44.0.tar.gz" + ] + } + }, + "rules_python_publish_deps_311_requests_py3_none_any_70761cfe": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "filename": "requests-2.32.3-py3-none-any.whl", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "requests==2.32.3", + "sha256": "70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6", + "urls": [ + "https://files.pythonhosted.org/packages/f9/9b/335f9764261e915ed497fcdeb11df5dfd6f7bf257d4a6a2a686d80da4d54/requests-2.32.3-py3-none-any.whl" + ] + } + }, + "rules_python_publish_deps_311_requests_sdist_55365417": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "extra_pip_args": [ + "--index-url", + "https://pypi.org/simple" + ], + "filename": "requests-2.32.3.tar.gz", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "requests==2.32.3", + "sha256": "55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760", + "urls": [ + "https://files.pythonhosted.org/packages/63/70/2bf7780ad2d390a8d301ad0b550f1581eadbd9a20f896afe06353c2a2913/requests-2.32.3.tar.gz" + ] + } + }, + "rules_python_publish_deps_311_requests_toolbelt_py2_none_any_cccfdd66": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "filename": "requests_toolbelt-1.0.0-py2.py3-none-any.whl", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "requests-toolbelt==1.0.0", + "sha256": "cccfdd665f0a24fcf4726e690f65639d272bb0637b9b92dfd91a5568ccf6bd06", + "urls": [ + "https://files.pythonhosted.org/packages/3f/51/d4db610ef29373b879047326cbf6fa98b6c1969d6f6dc423279de2b1be2c/requests_toolbelt-1.0.0-py2.py3-none-any.whl" + ] + } + }, + "rules_python_publish_deps_311_requests_toolbelt_sdist_7681a0a3": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "extra_pip_args": [ + "--index-url", + "https://pypi.org/simple" + ], + "filename": "requests-toolbelt-1.0.0.tar.gz", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "requests-toolbelt==1.0.0", + "sha256": "7681a0a3d047012b5bdc0ee37d7f8f07ebe76ab08caeccfc3921ce23c88d5bc6", + "urls": [ + "https://files.pythonhosted.org/packages/f3/61/d7545dafb7ac2230c70d38d31cbfe4cc64f7144dc41f6e4e4b78ecd9f5bb/requests-toolbelt-1.0.0.tar.gz" + ] + } + }, + "rules_python_publish_deps_311_rfc3986_py2_none_any_50b1502b": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "filename": "rfc3986-2.0.0-py2.py3-none-any.whl", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "rfc3986==2.0.0", + "sha256": "50b1502b60e289cb37883f3dfd34532b8873c7de9f49bb546641ce9cbd256ebd", + "urls": [ + "https://files.pythonhosted.org/packages/ff/9a/9afaade874b2fa6c752c36f1548f718b5b83af81ed9b76628329dab81c1b/rfc3986-2.0.0-py2.py3-none-any.whl" + ] + } + }, + "rules_python_publish_deps_311_rfc3986_sdist_97aacf9d": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "extra_pip_args": [ + "--index-url", + "https://pypi.org/simple" + ], + "filename": "rfc3986-2.0.0.tar.gz", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "rfc3986==2.0.0", + "sha256": "97aacf9dbd4bfd829baad6e6309fa6573aaf1be3f6fa735c8ab05e46cecb261c", + "urls": [ + "https://files.pythonhosted.org/packages/85/40/1520d68bfa07ab5a6f065a186815fb6610c86fe957bc065754e47f7b0840/rfc3986-2.0.0.tar.gz" + ] + } + }, + "rules_python_publish_deps_311_rich_py3_none_any_9836f509": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "filename": "rich-13.9.3-py3-none-any.whl", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "rich==13.9.3", + "sha256": "9836f5096eb2172c9e77df411c1b009bace4193d6a481d534fea75ebba758283", + "urls": [ + "https://files.pythonhosted.org/packages/9a/e2/10e9819cf4a20bd8ea2f5dabafc2e6bf4a78d6a0965daeb60a4b34d1c11f/rich-13.9.3-py3-none-any.whl" + ] + } + }, + "rules_python_publish_deps_311_rich_sdist_bc1e01b8": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "extra_pip_args": [ + "--index-url", + "https://pypi.org/simple" + ], + "filename": "rich-13.9.3.tar.gz", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "rich==13.9.3", + "sha256": "bc1e01b899537598cf02579d2b9f4a415104d3fc439313a7a2c165d76557a08e", + "urls": [ + "https://files.pythonhosted.org/packages/d9/e9/cf9ef5245d835065e6673781dbd4b8911d352fb770d56cf0879cf11b7ee1/rich-13.9.3.tar.gz" + ] + } + }, + "rules_python_publish_deps_311_secretstorage_py3_none_any_f356e662": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64" + ], + "filename": "SecretStorage-3.3.3-py3-none-any.whl", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "secretstorage==3.3.3", + "sha256": "f356e6628222568e3af06f2eba8df495efa13b3b63081dafd4f7d9a7b7bc9f99", + "urls": [ + "https://files.pythonhosted.org/packages/54/24/b4293291fa1dd830f353d2cb163295742fa87f179fcc8a20a306a81978b7/SecretStorage-3.3.3-py3-none-any.whl" + ] + } + }, + "rules_python_publish_deps_311_secretstorage_sdist_2403533e": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64" + ], + "extra_pip_args": [ + "--index-url", + "https://pypi.org/simple" + ], + "filename": "SecretStorage-3.3.3.tar.gz", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "secretstorage==3.3.3", + "sha256": "2403533ef369eca6d2ba81718576c5e0f564d5cca1b58f73a8b23e7d4eeebd77", + "urls": [ + "https://files.pythonhosted.org/packages/53/a4/f48c9d79cb507ed1373477dbceaba7401fd8a23af63b837fa61f1dcd3691/SecretStorage-3.3.3.tar.gz" + ] + } + }, + "rules_python_publish_deps_311_twine_py3_none_any_215dbe7b": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "filename": "twine-5.1.1-py3-none-any.whl", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "twine==5.1.1", + "sha256": "215dbe7b4b94c2c50a7315c0275d2258399280fbb7d04182c7e55e24b5f93997", + "urls": [ + "https://files.pythonhosted.org/packages/5d/ec/00f9d5fd040ae29867355e559a94e9a8429225a0284a3f5f091a3878bfc0/twine-5.1.1-py3-none-any.whl" + ] + } + }, + "rules_python_publish_deps_311_twine_sdist_9aa08251": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "extra_pip_args": [ + "--index-url", + "https://pypi.org/simple" + ], + "filename": "twine-5.1.1.tar.gz", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "twine==5.1.1", + "sha256": "9aa0825139c02b3434d913545c7b847a21c835e11597f5255842d457da2322db", + "urls": [ + "https://files.pythonhosted.org/packages/77/68/bd982e5e949ef8334e6f7dcf76ae40922a8750aa2e347291ae1477a4782b/twine-5.1.1.tar.gz" + ] + } + }, + "rules_python_publish_deps_311_urllib3_py3_none_any_ca899ca0": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "filename": "urllib3-2.2.3-py3-none-any.whl", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "urllib3==2.2.3", + "sha256": "ca899ca043dcb1bafa3e262d73aa25c465bfb49e0bd9dd5d59f1d0acba2f8fac", + "urls": [ + "https://files.pythonhosted.org/packages/ce/d9/5f4c13cecde62396b0d3fe530a50ccea91e7dfc1ccf0e09c228841bb5ba8/urllib3-2.2.3-py3-none-any.whl" + ] + } + }, + "rules_python_publish_deps_311_urllib3_sdist_e7d814a8": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "extra_pip_args": [ + "--index-url", + "https://pypi.org/simple" + ], + "filename": "urllib3-2.2.3.tar.gz", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "urllib3==2.2.3", + "sha256": "e7d814a81dad81e6caf2ec9fdedb284ecc9c73076b62654547cc64ccdcae26e9", + "urls": [ + "https://files.pythonhosted.org/packages/ed/63/22ba4ebfe7430b76388e7cd448d5478814d3032121827c12a2cc287e2260/urllib3-2.2.3.tar.gz" + ] + } + }, + "rules_python_publish_deps_311_zipp_py3_none_any_a817ac80": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "filename": "zipp-3.20.2-py3-none-any.whl", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "zipp==3.20.2", + "sha256": "a817ac80d6cf4b23bf7f2828b7cabf326f15a001bea8b1f9b49631780ba28350", + "urls": [ + "https://files.pythonhosted.org/packages/62/8b/5ba542fa83c90e09eac972fc9baca7a88e7e7ca4b221a89251954019308b/zipp-3.20.2-py3-none-any.whl" + ] + } + }, + "rules_python_publish_deps_311_zipp_sdist_bc9eb26f": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "extra_pip_args": [ + "--index-url", + "https://pypi.org/simple" + ], + "filename": "zipp-3.20.2.tar.gz", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "zipp==3.20.2", + "sha256": "bc9eb26f4506fda01b81bcde0ca78103b6e62f991b381fec825435c836edbc29", + "urls": [ + "https://files.pythonhosted.org/packages/54/bf/5c0000c44ebc80123ecbdddba1f5dcd94a5ada602a9c225d84b5aaa55e86/zipp-3.20.2.tar.gz" + ] + } + }, + "rules_python_publish_deps": { + "repoRuleId": "@@rules_python+//python/private/pypi:hub_repository.bzl%hub_repository", + "attributes": { + "repo_name": "rules_python_publish_deps", + "extra_hub_aliases": {}, + "whl_map": { + "backports_tarfile": "[{\"filename\":\"backports.tarfile-1.2.0-py3-none-any.whl\",\"repo\":\"rules_python_publish_deps_311_backports_tarfile_py3_none_any_77e284d7\",\"version\":\"3.11\"},{\"filename\":\"backports_tarfile-1.2.0.tar.gz\",\"repo\":\"rules_python_publish_deps_311_backports_tarfile_sdist_d75e02c2\",\"version\":\"3.11\"}]", + "certifi": "[{\"filename\":\"certifi-2024.8.30-py3-none-any.whl\",\"repo\":\"rules_python_publish_deps_311_certifi_py3_none_any_922820b5\",\"version\":\"3.11\"},{\"filename\":\"certifi-2024.8.30.tar.gz\",\"repo\":\"rules_python_publish_deps_311_certifi_sdist_bec941d2\",\"version\":\"3.11\"}]", + "cffi": "[{\"filename\":\"cffi-1.17.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl\",\"repo\":\"rules_python_publish_deps_311_cffi_cp311_cp311_manylinux_2_17_aarch64_a1ed2dd2\",\"version\":\"3.11\"},{\"filename\":\"cffi-1.17.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl\",\"repo\":\"rules_python_publish_deps_311_cffi_cp311_cp311_manylinux_2_17_ppc64le_46bf4316\",\"version\":\"3.11\"},{\"filename\":\"cffi-1.17.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl\",\"repo\":\"rules_python_publish_deps_311_cffi_cp311_cp311_manylinux_2_17_s390x_a24ed04c\",\"version\":\"3.11\"},{\"filename\":\"cffi-1.17.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl\",\"repo\":\"rules_python_publish_deps_311_cffi_cp311_cp311_manylinux_2_17_x86_64_610faea7\",\"version\":\"3.11\"},{\"filename\":\"cffi-1.17.1-cp311-cp311-musllinux_1_1_aarch64.whl\",\"repo\":\"rules_python_publish_deps_311_cffi_cp311_cp311_musllinux_1_1_aarch64_a9b15d49\",\"version\":\"3.11\"},{\"filename\":\"cffi-1.17.1-cp311-cp311-musllinux_1_1_x86_64.whl\",\"repo\":\"rules_python_publish_deps_311_cffi_cp311_cp311_musllinux_1_1_x86_64_fc48c783\",\"version\":\"3.11\"},{\"filename\":\"cffi-1.17.1.tar.gz\",\"repo\":\"rules_python_publish_deps_311_cffi_sdist_1c39c601\",\"version\":\"3.11\"}]", + "charset_normalizer": "[{\"filename\":\"charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_universal2.whl\",\"repo\":\"rules_python_publish_deps_311_charset_normalizer_cp311_cp311_macosx_10_9_universal2_0d99dd8f\",\"version\":\"3.11\"},{\"filename\":\"charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_x86_64.whl\",\"repo\":\"rules_python_publish_deps_311_charset_normalizer_cp311_cp311_macosx_10_9_x86_64_c57516e5\",\"version\":\"3.11\"},{\"filename\":\"charset_normalizer-3.4.0-cp311-cp311-macosx_11_0_arm64.whl\",\"repo\":\"rules_python_publish_deps_311_charset_normalizer_cp311_cp311_macosx_11_0_arm64_6dba5d19\",\"version\":\"3.11\"},{\"filename\":\"charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl\",\"repo\":\"rules_python_publish_deps_311_charset_normalizer_cp311_cp311_manylinux_2_17_aarch64_bf4475b8\",\"version\":\"3.11\"},{\"filename\":\"charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl\",\"repo\":\"rules_python_publish_deps_311_charset_normalizer_cp311_cp311_manylinux_2_17_ppc64le_ce031db0\",\"version\":\"3.11\"},{\"filename\":\"charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl\",\"repo\":\"rules_python_publish_deps_311_charset_normalizer_cp311_cp311_manylinux_2_17_s390x_8ff4e7cd\",\"version\":\"3.11\"},{\"filename\":\"charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl\",\"repo\":\"rules_python_publish_deps_311_charset_normalizer_cp311_cp311_manylinux_2_17_x86_64_3710a975\",\"version\":\"3.11\"},{\"filename\":\"charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_aarch64.whl\",\"repo\":\"rules_python_publish_deps_311_charset_normalizer_cp311_cp311_musllinux_1_2_aarch64_47334db7\",\"version\":\"3.11\"},{\"filename\":\"charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_ppc64le.whl\",\"repo\":\"rules_python_publish_deps_311_charset_normalizer_cp311_cp311_musllinux_1_2_ppc64le_f1a2f519\",\"version\":\"3.11\"},{\"filename\":\"charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_s390x.whl\",\"repo\":\"rules_python_publish_deps_311_charset_normalizer_cp311_cp311_musllinux_1_2_s390x_63bc5c4a\",\"version\":\"3.11\"},{\"filename\":\"charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_x86_64.whl\",\"repo\":\"rules_python_publish_deps_311_charset_normalizer_cp311_cp311_musllinux_1_2_x86_64_bcb4f8ea\",\"version\":\"3.11\"},{\"filename\":\"charset_normalizer-3.4.0-cp311-cp311-win_amd64.whl\",\"repo\":\"rules_python_publish_deps_311_charset_normalizer_cp311_cp311_win_amd64_cee4373f\",\"version\":\"3.11\"},{\"filename\":\"charset_normalizer-3.4.0-py3-none-any.whl\",\"repo\":\"rules_python_publish_deps_311_charset_normalizer_py3_none_any_fe9f97fe\",\"version\":\"3.11\"},{\"filename\":\"charset_normalizer-3.4.0.tar.gz\",\"repo\":\"rules_python_publish_deps_311_charset_normalizer_sdist_223217c3\",\"version\":\"3.11\"}]", + "cryptography": "[{\"filename\":\"cryptography-43.0.3-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl\",\"repo\":\"rules_python_publish_deps_311_cryptography_cp39_abi3_manylinux_2_17_aarch64_846da004\",\"version\":\"3.11\"},{\"filename\":\"cryptography-43.0.3-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl\",\"repo\":\"rules_python_publish_deps_311_cryptography_cp39_abi3_manylinux_2_17_x86_64_0f996e72\",\"version\":\"3.11\"},{\"filename\":\"cryptography-43.0.3-cp39-abi3-manylinux_2_28_aarch64.whl\",\"repo\":\"rules_python_publish_deps_311_cryptography_cp39_abi3_manylinux_2_28_aarch64_f7b178f1\",\"version\":\"3.11\"},{\"filename\":\"cryptography-43.0.3-cp39-abi3-manylinux_2_28_x86_64.whl\",\"repo\":\"rules_python_publish_deps_311_cryptography_cp39_abi3_manylinux_2_28_x86_64_c2e6fc39\",\"version\":\"3.11\"},{\"filename\":\"cryptography-43.0.3-cp39-abi3-musllinux_1_2_aarch64.whl\",\"repo\":\"rules_python_publish_deps_311_cryptography_cp39_abi3_musllinux_1_2_aarch64_e1be4655\",\"version\":\"3.11\"},{\"filename\":\"cryptography-43.0.3-cp39-abi3-musllinux_1_2_x86_64.whl\",\"repo\":\"rules_python_publish_deps_311_cryptography_cp39_abi3_musllinux_1_2_x86_64_df6b6c6d\",\"version\":\"3.11\"},{\"filename\":\"cryptography-43.0.3.tar.gz\",\"repo\":\"rules_python_publish_deps_311_cryptography_sdist_315b9001\",\"version\":\"3.11\"}]", + "docutils": "[{\"filename\":\"docutils-0.21.2-py3-none-any.whl\",\"repo\":\"rules_python_publish_deps_311_docutils_py3_none_any_dafca5b9\",\"version\":\"3.11\"},{\"filename\":\"docutils-0.21.2.tar.gz\",\"repo\":\"rules_python_publish_deps_311_docutils_sdist_3a6b1873\",\"version\":\"3.11\"}]", + "idna": "[{\"filename\":\"idna-3.10-py3-none-any.whl\",\"repo\":\"rules_python_publish_deps_311_idna_py3_none_any_946d195a\",\"version\":\"3.11\"},{\"filename\":\"idna-3.10.tar.gz\",\"repo\":\"rules_python_publish_deps_311_idna_sdist_12f65c9b\",\"version\":\"3.11\"}]", + "importlib_metadata": "[{\"filename\":\"importlib_metadata-8.5.0-py3-none-any.whl\",\"repo\":\"rules_python_publish_deps_311_importlib_metadata_py3_none_any_45e54197\",\"version\":\"3.11\"},{\"filename\":\"importlib_metadata-8.5.0.tar.gz\",\"repo\":\"rules_python_publish_deps_311_importlib_metadata_sdist_71522656\",\"version\":\"3.11\"}]", + "jaraco_classes": "[{\"filename\":\"jaraco.classes-3.4.0-py3-none-any.whl\",\"repo\":\"rules_python_publish_deps_311_jaraco_classes_py3_none_any_f662826b\",\"version\":\"3.11\"},{\"filename\":\"jaraco.classes-3.4.0.tar.gz\",\"repo\":\"rules_python_publish_deps_311_jaraco_classes_sdist_47a024b5\",\"version\":\"3.11\"}]", + "jaraco_context": "[{\"filename\":\"jaraco.context-6.0.1-py3-none-any.whl\",\"repo\":\"rules_python_publish_deps_311_jaraco_context_py3_none_any_f797fc48\",\"version\":\"3.11\"},{\"filename\":\"jaraco_context-6.0.1.tar.gz\",\"repo\":\"rules_python_publish_deps_311_jaraco_context_sdist_9bae4ea5\",\"version\":\"3.11\"}]", + "jaraco_functools": "[{\"filename\":\"jaraco.functools-4.1.0-py3-none-any.whl\",\"repo\":\"rules_python_publish_deps_311_jaraco_functools_py3_none_any_ad159f13\",\"version\":\"3.11\"},{\"filename\":\"jaraco_functools-4.1.0.tar.gz\",\"repo\":\"rules_python_publish_deps_311_jaraco_functools_sdist_70f7e0e2\",\"version\":\"3.11\"}]", + "jeepney": "[{\"filename\":\"jeepney-0.8.0-py3-none-any.whl\",\"repo\":\"rules_python_publish_deps_311_jeepney_py3_none_any_c0a454ad\",\"version\":\"3.11\"},{\"filename\":\"jeepney-0.8.0.tar.gz\",\"repo\":\"rules_python_publish_deps_311_jeepney_sdist_5efe48d2\",\"version\":\"3.11\"}]", + "keyring": "[{\"filename\":\"keyring-25.4.1-py3-none-any.whl\",\"repo\":\"rules_python_publish_deps_311_keyring_py3_none_any_5426f817\",\"version\":\"3.11\"},{\"filename\":\"keyring-25.4.1.tar.gz\",\"repo\":\"rules_python_publish_deps_311_keyring_sdist_b07ebc55\",\"version\":\"3.11\"}]", + "markdown_it_py": "[{\"filename\":\"markdown-it-py-3.0.0.tar.gz\",\"repo\":\"rules_python_publish_deps_311_markdown_it_py_sdist_e3f60a94\",\"version\":\"3.11\"},{\"filename\":\"markdown_it_py-3.0.0-py3-none-any.whl\",\"repo\":\"rules_python_publish_deps_311_markdown_it_py_py3_none_any_35521684\",\"version\":\"3.11\"}]", + "mdurl": "[{\"filename\":\"mdurl-0.1.2-py3-none-any.whl\",\"repo\":\"rules_python_publish_deps_311_mdurl_py3_none_any_84008a41\",\"version\":\"3.11\"},{\"filename\":\"mdurl-0.1.2.tar.gz\",\"repo\":\"rules_python_publish_deps_311_mdurl_sdist_bb413d29\",\"version\":\"3.11\"}]", + "more_itertools": "[{\"filename\":\"more-itertools-10.5.0.tar.gz\",\"repo\":\"rules_python_publish_deps_311_more_itertools_sdist_5482bfef\",\"version\":\"3.11\"},{\"filename\":\"more_itertools-10.5.0-py3-none-any.whl\",\"repo\":\"rules_python_publish_deps_311_more_itertools_py3_none_any_037b0d32\",\"version\":\"3.11\"}]", + "nh3": "[{\"filename\":\"nh3-0.2.18-cp37-abi3-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl\",\"repo\":\"rules_python_publish_deps_311_nh3_cp37_abi3_macosx_10_12_x86_64_14c5a72e\",\"version\":\"3.11\"},{\"filename\":\"nh3-0.2.18-cp37-abi3-macosx_10_12_x86_64.whl\",\"repo\":\"rules_python_publish_deps_311_nh3_cp37_abi3_macosx_10_12_x86_64_7b7c2a3c\",\"version\":\"3.11\"},{\"filename\":\"nh3-0.2.18-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl\",\"repo\":\"rules_python_publish_deps_311_nh3_cp37_abi3_manylinux_2_17_aarch64_42c64511\",\"version\":\"3.11\"},{\"filename\":\"nh3-0.2.18-cp37-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl\",\"repo\":\"rules_python_publish_deps_311_nh3_cp37_abi3_manylinux_2_17_armv7l_0411beb0\",\"version\":\"3.11\"},{\"filename\":\"nh3-0.2.18-cp37-abi3-manylinux_2_17_ppc64.manylinux2014_ppc64.whl\",\"repo\":\"rules_python_publish_deps_311_nh3_cp37_abi3_manylinux_2_17_ppc64_5f36b271\",\"version\":\"3.11\"},{\"filename\":\"nh3-0.2.18-cp37-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl\",\"repo\":\"rules_python_publish_deps_311_nh3_cp37_abi3_manylinux_2_17_ppc64le_34c03fa7\",\"version\":\"3.11\"},{\"filename\":\"nh3-0.2.18-cp37-abi3-manylinux_2_17_s390x.manylinux2014_s390x.whl\",\"repo\":\"rules_python_publish_deps_311_nh3_cp37_abi3_manylinux_2_17_s390x_19aaba96\",\"version\":\"3.11\"},{\"filename\":\"nh3-0.2.18-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl\",\"repo\":\"rules_python_publish_deps_311_nh3_cp37_abi3_manylinux_2_17_x86_64_de3ceed6\",\"version\":\"3.11\"},{\"filename\":\"nh3-0.2.18-cp37-abi3-musllinux_1_2_aarch64.whl\",\"repo\":\"rules_python_publish_deps_311_nh3_cp37_abi3_musllinux_1_2_aarch64_f0eca9ca\",\"version\":\"3.11\"},{\"filename\":\"nh3-0.2.18-cp37-abi3-musllinux_1_2_armv7l.whl\",\"repo\":\"rules_python_publish_deps_311_nh3_cp37_abi3_musllinux_1_2_armv7l_3a157ab1\",\"version\":\"3.11\"},{\"filename\":\"nh3-0.2.18-cp37-abi3-musllinux_1_2_x86_64.whl\",\"repo\":\"rules_python_publish_deps_311_nh3_cp37_abi3_musllinux_1_2_x86_64_36c95d4b\",\"version\":\"3.11\"},{\"filename\":\"nh3-0.2.18-cp37-abi3-win_amd64.whl\",\"repo\":\"rules_python_publish_deps_311_nh3_cp37_abi3_win_amd64_8ce0f819\",\"version\":\"3.11\"},{\"filename\":\"nh3-0.2.18.tar.gz\",\"repo\":\"rules_python_publish_deps_311_nh3_sdist_94a16692\",\"version\":\"3.11\"}]", + "pkginfo": "[{\"filename\":\"pkginfo-1.10.0-py3-none-any.whl\",\"repo\":\"rules_python_publish_deps_311_pkginfo_py3_none_any_889a6da2\",\"version\":\"3.11\"},{\"filename\":\"pkginfo-1.10.0.tar.gz\",\"repo\":\"rules_python_publish_deps_311_pkginfo_sdist_5df73835\",\"version\":\"3.11\"}]", + "pycparser": "[{\"filename\":\"pycparser-2.22-py3-none-any.whl\",\"repo\":\"rules_python_publish_deps_311_pycparser_py3_none_any_c3702b6d\",\"version\":\"3.11\"},{\"filename\":\"pycparser-2.22.tar.gz\",\"repo\":\"rules_python_publish_deps_311_pycparser_sdist_491c8be9\",\"version\":\"3.11\"}]", + "pygments": "[{\"filename\":\"pygments-2.18.0-py3-none-any.whl\",\"repo\":\"rules_python_publish_deps_311_pygments_py3_none_any_b8e6aca0\",\"version\":\"3.11\"},{\"filename\":\"pygments-2.18.0.tar.gz\",\"repo\":\"rules_python_publish_deps_311_pygments_sdist_786ff802\",\"version\":\"3.11\"}]", + "pywin32_ctypes": "[{\"filename\":\"pywin32-ctypes-0.2.3.tar.gz\",\"repo\":\"rules_python_publish_deps_311_pywin32_ctypes_sdist_d162dc04\",\"version\":\"3.11\"},{\"filename\":\"pywin32_ctypes-0.2.3-py3-none-any.whl\",\"repo\":\"rules_python_publish_deps_311_pywin32_ctypes_py3_none_any_8a151337\",\"version\":\"3.11\"}]", + "readme_renderer": "[{\"filename\":\"readme_renderer-44.0-py3-none-any.whl\",\"repo\":\"rules_python_publish_deps_311_readme_renderer_py3_none_any_2fbca89b\",\"version\":\"3.11\"},{\"filename\":\"readme_renderer-44.0.tar.gz\",\"repo\":\"rules_python_publish_deps_311_readme_renderer_sdist_8712034e\",\"version\":\"3.11\"}]", + "requests": "[{\"filename\":\"requests-2.32.3-py3-none-any.whl\",\"repo\":\"rules_python_publish_deps_311_requests_py3_none_any_70761cfe\",\"version\":\"3.11\"},{\"filename\":\"requests-2.32.3.tar.gz\",\"repo\":\"rules_python_publish_deps_311_requests_sdist_55365417\",\"version\":\"3.11\"}]", + "requests_toolbelt": "[{\"filename\":\"requests-toolbelt-1.0.0.tar.gz\",\"repo\":\"rules_python_publish_deps_311_requests_toolbelt_sdist_7681a0a3\",\"version\":\"3.11\"},{\"filename\":\"requests_toolbelt-1.0.0-py2.py3-none-any.whl\",\"repo\":\"rules_python_publish_deps_311_requests_toolbelt_py2_none_any_cccfdd66\",\"version\":\"3.11\"}]", + "rfc3986": "[{\"filename\":\"rfc3986-2.0.0-py2.py3-none-any.whl\",\"repo\":\"rules_python_publish_deps_311_rfc3986_py2_none_any_50b1502b\",\"version\":\"3.11\"},{\"filename\":\"rfc3986-2.0.0.tar.gz\",\"repo\":\"rules_python_publish_deps_311_rfc3986_sdist_97aacf9d\",\"version\":\"3.11\"}]", + "rich": "[{\"filename\":\"rich-13.9.3-py3-none-any.whl\",\"repo\":\"rules_python_publish_deps_311_rich_py3_none_any_9836f509\",\"version\":\"3.11\"},{\"filename\":\"rich-13.9.3.tar.gz\",\"repo\":\"rules_python_publish_deps_311_rich_sdist_bc1e01b8\",\"version\":\"3.11\"}]", + "secretstorage": "[{\"filename\":\"SecretStorage-3.3.3-py3-none-any.whl\",\"repo\":\"rules_python_publish_deps_311_secretstorage_py3_none_any_f356e662\",\"version\":\"3.11\"},{\"filename\":\"SecretStorage-3.3.3.tar.gz\",\"repo\":\"rules_python_publish_deps_311_secretstorage_sdist_2403533e\",\"version\":\"3.11\"}]", + "twine": "[{\"filename\":\"twine-5.1.1-py3-none-any.whl\",\"repo\":\"rules_python_publish_deps_311_twine_py3_none_any_215dbe7b\",\"version\":\"3.11\"},{\"filename\":\"twine-5.1.1.tar.gz\",\"repo\":\"rules_python_publish_deps_311_twine_sdist_9aa08251\",\"version\":\"3.11\"}]", + "urllib3": "[{\"filename\":\"urllib3-2.2.3-py3-none-any.whl\",\"repo\":\"rules_python_publish_deps_311_urllib3_py3_none_any_ca899ca0\",\"version\":\"3.11\"},{\"filename\":\"urllib3-2.2.3.tar.gz\",\"repo\":\"rules_python_publish_deps_311_urllib3_sdist_e7d814a8\",\"version\":\"3.11\"}]", + "zipp": "[{\"filename\":\"zipp-3.20.2-py3-none-any.whl\",\"repo\":\"rules_python_publish_deps_311_zipp_py3_none_any_a817ac80\",\"version\":\"3.11\"},{\"filename\":\"zipp-3.20.2.tar.gz\",\"repo\":\"rules_python_publish_deps_311_zipp_sdist_bc9eb26f\",\"version\":\"3.11\"}]" + }, + "packages": [ + "backports_tarfile", + "certifi", + "charset_normalizer", + "docutils", + "idna", + "importlib_metadata", + "jaraco_classes", + "jaraco_context", + "jaraco_functools", + "keyring", + "markdown_it_py", + "mdurl", + "more_itertools", + "nh3", + "pkginfo", + "pygments", + "readme_renderer", + "requests", + "requests_toolbelt", + "rfc3986", + "rich", + "twine", + "urllib3", + "zipp" + ], + "groups": {} + } + } + }, + "recordedRepoMappingEntries": [ + [ + "bazel_features+", + "bazel_features_globals", + "bazel_features++version_extension+bazel_features_globals" + ], + [ + "bazel_features+", + "bazel_features_version", + "bazel_features++version_extension+bazel_features_version" + ], + [ + "rules_python+", + "bazel_features", + "bazel_features+" + ], + [ + "rules_python+", + "bazel_skylib", + "bazel_skylib+" + ], + [ + "rules_python+", + "bazel_tools", + "bazel_tools" + ], + [ + "rules_python+", + "pypi__build", + "rules_python++internal_deps+pypi__build" + ], + [ + "rules_python+", + "pypi__click", + "rules_python++internal_deps+pypi__click" + ], + [ + "rules_python+", + "pypi__colorama", + "rules_python++internal_deps+pypi__colorama" + ], + [ + "rules_python+", + "pypi__importlib_metadata", + "rules_python++internal_deps+pypi__importlib_metadata" + ], + [ + "rules_python+", + "pypi__installer", + "rules_python++internal_deps+pypi__installer" + ], + [ + "rules_python+", + "pypi__more_itertools", + "rules_python++internal_deps+pypi__more_itertools" + ], + [ + "rules_python+", + "pypi__packaging", + "rules_python++internal_deps+pypi__packaging" + ], + [ + "rules_python+", + "pypi__pep517", + "rules_python++internal_deps+pypi__pep517" + ], + [ + "rules_python+", + "pypi__pip", + "rules_python++internal_deps+pypi__pip" + ], + [ + "rules_python+", + "pypi__pip_tools", + "rules_python++internal_deps+pypi__pip_tools" + ], + [ + "rules_python+", + "pypi__pyproject_hooks", + "rules_python++internal_deps+pypi__pyproject_hooks" + ], + [ + "rules_python+", + "pypi__setuptools", + "rules_python++internal_deps+pypi__setuptools" + ], + [ + "rules_python+", + "pypi__tomli", + "rules_python++internal_deps+pypi__tomli" + ], + [ + "rules_python+", + "pypi__wheel", + "rules_python++internal_deps+pypi__wheel" + ], + [ + "rules_python+", + "pypi__zipp", + "rules_python++internal_deps+pypi__zipp" + ], + [ + "rules_python+", + "pythons_hub", + "rules_python++python+pythons_hub" + ], + [ + "rules_python++python+pythons_hub", + "python_3_10_host", + "rules_python++python+python_3_10_host" + ], + [ + "rules_python++python+pythons_hub", + "python_3_11_host", + "rules_python++python+python_3_11_host" + ], + [ + "rules_python++python+pythons_hub", + "python_3_12_host", + "rules_python++python+python_3_12_host" + ], + [ + "rules_python++python+pythons_hub", + "python_3_8_host", + "rules_python++python+python_3_8_host" + ], + [ + "rules_python++python+pythons_hub", + "python_3_9_host", + "rules_python++python+python_3_9_host" + ] + ] + } + } + } +} diff --git a/README.md b/README.md index e968e94d023..2fc5b487657 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,7 @@ # An IntelliJ plugin for [Bazel](http://bazel.build) projects +This project uses binary bundles licensed under JetBrains User Agreement (https://www.jetbrains.com/legal/docs/toolbox/user/). + This is an early-access version of our Bazel plugins for IntelliJ, Android Studio, and CLion. @@ -16,10 +18,22 @@ how to join the discussion can be found in the [SIG charter](https://github.com/ ## Support -See the [documentation entry](https://ij.bazel.build/docs/bazel-support.html) +See the [documentation entry](https://github.com/bazelbuild/intellij/blob/master/docs/index.md) on the plugin support across JetBrains products, languages, and operating systems. +## Source Code Locations + +The Bazel plugins for IntelliJ and CLion are built and released from the [master branch](https://github.com/bazelbuild/intellij) of this repository. An external team of maintainers addresses IntelliJ and CLion plugin issues and pull requests. + +The Bazel plugin for Android Studio is built and released from [AOSP](https://android.googlesource.com/platform/tools/adt/idea/+/refs/heads/mirror-goog-studio-main/aswb/). The [google branch](https://github.com/bazelbuild/intellij/tree/google) is now deprecated. + +Although the code in this repository and in AOSP share the same structure and core components, they have diverged from each other. + +- Changes for IntelliJ and CLion plugins are *only* merged into the master branch of this repository. Users can request that certain fixes which are also needed for the Android Studio plugin get merged into the AOSP project. This will require the internal teams’ approval. +- Changes made by the internal Google teams are automatically exported to AOSP. These commits will regularly be cherry-picked to the master branch. +- The master branch is not intended to be used to build the Android Studio with Bazel plugin; failures of the Android Studio plugin built from the master branch will not be addressed. + ## Installation You can find our plugin in the [JetBrains Marketplace](https://plugins.jetbrains.com/plugin/8609-bazel) @@ -36,12 +50,28 @@ Beta versions are usually uploaded to the Beta channel 2 weeks before they becom - Android Studio -> `https://plugins.jetbrains.com/plugins/beta/9185` ## Usage +We recommend watching [this video](https://www.youtube.com/watch?v=GV_KwWK3Qy8) to familiarize yourself with the plugin's features. To import an existing Bazel project, choose `Import Bazel Project`, and follow the instructions in the project import wizard. -Detailed docs are available [here](http://ij.bazel.build). +Detailed docs are available [here](https://github.com/bazelbuild/intellij/blob/master/docs/index.md). + +## Known issues + +### Python debugging +Please read this comment https://github.com/bazelbuild/intellij/issues/4745#issue-1668398619 + +### Mixed Python & Java projects +In order to get correct python highlighting, please try to open "Project Structure" window and set "Python facet" there +### Remote Development +To properly set up Remote Development (https://www.jetbrains.com/remote-development/), follow these steps: +1. Create an empty project on the remote machine (this can be just an empty directory). +2. Import the project using Remote Development. +3. Install the Bazel Plugin on the host machine. +4. Close the project. +5. Open the initially intended project. ## Building the plugin @@ -59,6 +89,7 @@ If the IDE refuses to load the plugin because of version issues, specify the correct `ij_product`. These are in the form `-oss-` with * `` being one of `intellij-ue, intellij, clion, android-studio`, * `` being one of `oldest-stable, latest-stable, under-dev`. +Alternatevely, for you can set `ij_product` to direct IntelliJ or CLion versions, for example `clion-2023.2`, `intellij-2023.2` or `intellij-ue-2023.2` Note that there is a difference between `intellij` and `intellij-ue`. `ue` stands for IntelliJ Ultimate Edition and contains additional diff --git a/WORKSPACE b/WORKSPACE deleted file mode 100644 index c9ed46da797..00000000000 --- a/WORKSPACE +++ /dev/null @@ -1,669 +0,0 @@ -workspace(name = "intellij_with_bazel") - -load("@bazel_tools//tools/build_defs/repo:git.bzl", "new_git_repository") -load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") -load("@bazel_tools//tools/build_defs/repo:jvm.bzl", "jvm_maven_import_external") - -# Long-lived download links available at: https://www.jetbrains.com/intellij-repository/releases - -# The plugin api for IntelliJ 2021.2. This is required to build IJwB, -# and run integration tests. -http_archive( - name = "intellij_ce_2021_2", - build_file = "@//intellij_platform_sdk:BUILD.idea212", - sha256 = "aa38bf2f86b570ce9cac14b01f7e3bf8f592d05641384e7ecedde13cbfa6491a", - url = "https://www.jetbrains.com/intellij-repository/releases/com/jetbrains/intellij/idea/ideaIC/2021.2.4/ideaIC-2021.2.4.zip", -) - -# The plugin api for intellij_ce_2021_3. This is required to build IJwB and run integration tests. -http_archive( - name = "intellij_ce_2021_3", - build_file = "@//intellij_platform_sdk:BUILD.idea213", - sha256 = "7686d43fe0ea621718c1c9816460028146586ec10de1420500fc847edc603bb9", - url = "https://www.jetbrains.com/intellij-repository/releases/com/jetbrains/intellij/idea/ideaIC/2021.3.3/ideaIC-2021.3.3.zip", -) - -# The plugin api for intellij_ce_2022_1. This is required to build IJwB and run integration tests. -http_archive( - name = "intellij_ce_2022_1", - build_file = "@//intellij_platform_sdk:BUILD.idea221", - sha256 = "dc45e4c689a76c3022191a96fc3461333f177d62ab8d3e57e2cb2cc916ed9080", - url = "https://www.jetbrains.com/intellij-repository/releases/com/jetbrains/intellij/idea/ideaIC/2022.1.3/ideaIC-2022.1.3.zip", -) - -# The plugin api for intellij_ce_2022_2. This is required to build IJwB and run integration tests. -http_archive( - name = "intellij_ce_2022_2", - build_file = "@//intellij_platform_sdk:BUILD.idea222", - sha256 = "4f300d17c1a82db38fcff5168144422617913d541e395912651120aa43a07411", - url = "https://www.jetbrains.com/intellij-repository/releases/com/jetbrains/intellij/idea/ideaIC/2022.2/ideaIC-2022.2.zip", -) - -# The plugin api for intellij_ce_2022_3. This is required to build IJwB and run integration tests. -http_archive( - name = "intellij_ce_2022_3", - build_file = "@//intellij_platform_sdk:BUILD.idea223", - sha256 = "f6ea9aee6dec73b55ea405b37402394095be3c658d1c2707a8f30ac848974eac", - url = "https://www.jetbrains.com/intellij-repository/releases/com/jetbrains/intellij/idea/ideaIC/2022.3/ideaIC-2022.3.zip", -) - -# The plugin api for intellij_ce_2023_1. This is required to build IJwB and run integration tests. -IC_231_SHA = "d693dd44a900341d1362f105fea1adc79f0e04bc6f52f783883e75bf88f76793" - -IC_231_URL = "https://www.jetbrains.com/intellij-repository/releases/com/jetbrains/intellij/idea/ideaIC/231.8109.175/ideaIC-231.8109.175.zip" - -http_archive( - name = "intellij_ce_2023_1", - build_file = "@//intellij_platform_sdk:BUILD.idea231", - sha256 = IC_231_SHA, - url = IC_231_URL, -) - -# The plugin api for IntelliJ UE 2021.2. This is required to run UE-specific -# integration tests. -http_archive( - name = "intellij_ue_2021_2", - build_file = "@//intellij_platform_sdk:BUILD.ue212", - sha256 = "f5e942e090693c139dda22e798823285e22d7b31aaad5d52c23a370a6e91ec7d", - url = "https://www.jetbrains.com/intellij-repository/releases/com/jetbrains/intellij/idea/ideaIU/2021.2.4/ideaIU-2021.2.4.zip", -) - -# The plugin api for intellij_ue_2021_3. This is required to run UE-specific integration tests. -http_archive( - name = "intellij_ue_2021_3", - build_file = "@//intellij_platform_sdk:BUILD.ue213", - sha256 = "fc5ce48e614d5c083270a892cd5b38c9300f18aac41e1e0c7d15c518e978e96a", - url = "https://www.jetbrains.com/intellij-repository/releases/com/jetbrains/intellij/idea/ideaIU/2021.3.3/ideaIU-2021.3.3.zip", -) - -# The plugin api for intellij_ue_2022_1. This is required to run UE-specific integration tests. -http_archive( - name = "intellij_ue_2022_1", - build_file = "@//intellij_platform_sdk:BUILD.ue221", - sha256 = "598e085c98283c3206d9b755e6ef5f3321a3a11b1e5affa740276e9e3b0bd1f0", - url = "https://www.jetbrains.com/intellij-repository/releases/com/jetbrains/intellij/idea/ideaIU/2022.1.3/ideaIU-2022.1.3.zip", -) - -# The plugin api for intellij_ue_2022_2. This is required to run UE-specific integration tests. -http_archive( - name = "intellij_ue_2022_2", - build_file = "@//intellij_platform_sdk:BUILD.ue222", - sha256 = "36f4924055cf27cc4d9567d059ade32cf1ae511239b081e6929e62672eff107a", - url = "https://www.jetbrains.com/intellij-repository/releases/com/jetbrains/intellij/idea/ideaIU/2022.2/ideaIU-2022.2.zip", -) - -# The plugin api for intellij_ue_2022_3. This is required to run UE-specific integration tests. -http_archive( - name = "intellij_ue_2022_3", - build_file = "@//intellij_platform_sdk:BUILD.ue223", - sha256 = "0b17ea16e70290d912b6be246460907643c23f33ae2c22331084818025c2b297", - url = "https://www.jetbrains.com/intellij-repository/releases/com/jetbrains/intellij/idea/ideaIU/2022.3/ideaIU-2022.3.zip", -) - -# The plugin api for intellij_ue_2022_3. This is required to run UE-specific integration tests. -IU_231_SHA = "1caf5be854d932c4e3932deeb7ac1bfb2392eef4cc6c88f5f5f9ad97f8a5b231" - -IU_231_URL = "https://www.jetbrains.com/intellij-repository/releases/com/jetbrains/intellij/idea/ideaIU/231.8109.175/ideaIU-231.8109.175.zip" - -http_archive( - name = "intellij_ue_2023_1", - build_file = "@//intellij_platform_sdk:BUILD.ue231", - sha256 = IU_231_SHA, - url = IU_231_URL, -) - -# The plugin api for clion_2021_2. This is required to build CLwB, and run integration tests. -http_archive( - name = "clion_2021_2", - build_file = "@//intellij_platform_sdk:BUILD.clion212", - sha256 = "1b9a882aa703303dead8b9459bd8d4f2572bd977d46dce99af96c1647231da2c", - url = "https://download.jetbrains.com/cpp/CLion-2021.2.4.tar.gz", -) - -# The plugin api for clion_2021_3. This is required to build CLwB, and run integration tests. -http_archive( - name = "clion_2021_3", - build_file = "@//intellij_platform_sdk:BUILD.clion213", - sha256 = "f3b0b9e0dd0cd4aebef5d424e7a22868c732daad47d6c94f73630cef449ccf78", - url = "https://download.jetbrains.com/cpp/CLion-2021.3.4.tar.gz", -) - -# The plugin api for clion_2022_1. This is required to build CLwB\, and run integration tests. -http_archive( - name = "clion_2022_1", - build_file = "@//intellij_platform_sdk:BUILD.clion221", - sha256 = "6f0234d41c4ca1cf8eaa4ea5585ba4cfc17d86c16c78edc59501e0ca05a80d56", - url = "https://download.jetbrains.com/cpp/CLion-2022.1.3.tar.gz", -) - -# The plugin api for clion_2022_2. This is required to build CLwB\, and run integration tests. -http_archive( - name = "clion_2022_2", - build_file = "@//intellij_platform_sdk:BUILD.clion222", - sha256 = "94ffbdf82606f2f90618c1fdb89432d627e7f24ae158b36a591da2c303047436", - url = "https://download.jetbrains.com/cpp/CLion-2022.2.tar.gz", -) - -# The plugin api for clion_2022_3. This is required to build CLwB\, and run integration tests. -http_archive( - name = "clion_2022_3", - build_file = "@//intellij_platform_sdk:BUILD.clion223", - sha256 = "5c248465a99f7286e7863ccc4fbd6772af890b57d71a02690e20031aa16d7957", - url = "https://www.jetbrains.com/intellij-repository/releases/com/jetbrains/intellij/clion/clion/2022.3/clion-2022.3.zip", -) - -CLION_231_SHA = "db234643bbd7b09e2af45e589447c6a00a058744378641a36d818aaf7f76fcbf" - -CLION_231_URL = "https://www.jetbrains.com/intellij-repository/releases/com/jetbrains/intellij/clion/clion/2023.1/clion-2023.1.zip" - -http_archive( - name = "clion_2023_1", - build_file = "@//intellij_platform_sdk:BUILD.clion231", - sha256 = CLION_231_SHA, - url = CLION_231_URL, -) - -_PYTHON_CE_BUILD_FILE = """ -java_import( - name = "python", - jars = ["python-ce/lib/python-ce.jar"], - visibility = ["//visibility:public"], -) -filegroup( - name = "python_helpers", - srcs = glob(["python-ce/helpers/**/*"]), - visibility = ["//visibility:public"], -) -""" - -#TODO(ymoh): remove with the removal of 2021.1 Python plugin -# Python plugin for IntelliJ CE. Required at compile-time for python-specific features. -http_archive( - name = "python_2021_1", - build_file_content = _PYTHON_CE_BUILD_FILE, - sha256 = "7d16cc9bf80c9e2c26d55d55564c1c174583a5e6900e6b7f13d5663275b07644", - url = "https://plugins.jetbrains.com/files/7322/125352/python-ce-211.7628.24.zip", -) - -# Python plugin for IntelliJ CE. Required at compile-time for python-specific features. -http_archive( - name = "python_2021_2", - build_file_content = _PYTHON_CE_BUILD_FILE, - sha256 = "ce110ae1a5d3787bc85ae88d67fa2faa2be959a3e8acfc3567f8ed7b64c9151a", - url = "https://plugins.jetbrains.com/files/7322/151370/python-ce-212.5712.43.zip", -) - -# Python plugin for IntelliJ CE. Required at compile-time for python-specific features. -http_archive( - name = "python_2021_3", - build_file_content = _PYTHON_CE_BUILD_FILE, - sha256 = "47df4c32a19354efcc2d8171de85083e8e43b849c066bb979ed313b6309de08b", - url = "https://plugins.jetbrains.com/files/7322/162748/python-ce-213.7172.26.zip", -) - -# Python plugin for IntelliJ CE. Required at compile-time for python-specific features. -http_archive( - name = "python_2022_1", - build_file_content = _PYTHON_CE_BUILD_FILE, - sha256 = "1b0fb6824a7db252dfe3fd4eb638470bb96db4712bf1347560acee20eac1e8bc", - url = "https://plugins.jetbrains.com/files/7322/187811/python-ce-221.5921.27.zip", -) - -http_archive( - name = "python_2022_2", - build_file_content = _PYTHON_CE_BUILD_FILE, - sha256 = "1bca17ee017762a47d97acd17cfd16966825a75c625c51a851cc439040fca103", - url = "https://plugins.jetbrains.com/files/7322/201922/python-ce-222.3345.131.zip", -) - -http_archive( - name = "python_2022_3", - build_file_content = _PYTHON_CE_BUILD_FILE, - sha256 = "65db7c364a3f1756cf07fb161ff4eb67fd8f8612a8c3da812b2f9ba5b2d6e13d", - url = "https://plugins.jetbrains.com/maven/com/jetbrains/plugins/PythonCore/223.7571.182/PythonCore-223.7571.182.zip", -) - -PYTHON_PLUGIN_231_URL = "https://plugins.jetbrains.com/maven/com/jetbrains/plugins/PythonCore/231.8109.144/PythonCore-231.8109.144.zip" - -PYTHON_PLUGIN_231_SHA = "90b75d0e4919f424fabc81e83cc83da9305ed73b60d73a4653353685ec89f47f" - -http_archive( - name = "python_2023_1", - build_file_content = _PYTHON_CE_BUILD_FILE, - sha256 = PYTHON_PLUGIN_231_SHA, - url = PYTHON_PLUGIN_231_URL, -) - -_GO_BUILD_FILE = """ -java_import( - name = "go", - jars = glob(["go/lib/*.jar"]), - visibility = ["//visibility:public"], -) -""" - -# Go plugin for IntelliJ UE. Required at compile-time for Bazel integration. -http_archive( - name = "go_2021_2", - build_file_content = _GO_BUILD_FILE, - sha256 = "5c868f2be8feb552aa4f9edb2a3c48db68193eb49ba50ca0a0976f4b9de82c67", - url = "https://plugins.jetbrains.com/files/9568/149614/go-212.5712.14.zip", -) - -# Go plugin for IntelliJ UE. Required at compile-time for Bazel integration. -http_archive( - name = "go_2021_3", - build_file_content = _GO_BUILD_FILE, - sha256 = "12c3acf0e75f8d7fb5655e9400faa26bbc7b314c515c4a3ca9e6bb8c3a130a58", - url = "https://plugins.jetbrains.com/files/9568/160433/go-213.7172.6.zip", -) - -# Go plugin for IntelliJ UE. Required at compile-time for Bazel integration. -http_archive( - name = "go_2022_1", - build_file_content = _GO_BUILD_FILE, - sha256 = "4219a3b76c985ad1066d4ff99f516422bcbbfda2feba6a950e8bb6c5e544e3ea", - url = "https://plugins.jetbrains.com/files/9568/185980/go-221.5921.16.zip", -) - -http_archive( - name = "go_2022_2", - build_file_content = _GO_BUILD_FILE, - sha256 = "e7bfbfe3412d6bba675288d696d749b336eb5c81c003581b0a2d84565b98fd32", - url = "https://plugins.jetbrains.com/files/9568/200544/go-222.3345.118.zip", -) - -_GO_BUILD_FILE_223 = """ -java_import( - name = "go", - jars = glob(["go-plugin/lib/*.jar"]), - visibility = ["//visibility:public"], -) -""" - -http_archive( - name = "go_2022_3", - build_file_content = _GO_BUILD_FILE_223, - sha256 = "11d30e00aa21fc8c7aa47df3743c0180058556cbb73292c712e151a0c3d59908", - url = "https://plugins.jetbrains.com/maven/com/jetbrains/plugins/org.jetbrains.plugins.go/223.7571.182/org.jetbrains.plugins.go-223.7571.182.zip", -) - -GO_PLUGIN_231_SHA = "648c78f15ee1ad940139d904a2d3e51dae100a04d5c5af23da9b8000ae109639" - -GO_PLUGIN_231_URL = "https://plugins.jetbrains.com/maven/com/jetbrains/plugins/org.jetbrains.plugins.go/231.8109.175/org.jetbrains.plugins.go-231.8109.175.zip" - -http_archive( - name = "go_2023_1", - build_file_content = _GO_BUILD_FILE_223, - sha256 = GO_PLUGIN_231_SHA, - url = GO_PLUGIN_231_URL, -) - -_SCALA_BUILD_FILE = """ -java_import( - name = "scala", - jars = glob(["Scala/lib/*.jar"]), - visibility = ["//visibility:public"], -) -""" - -# Scala plugin for IntelliJ CE. Required at compile-time for scala-specific features. -http_archive( - name = "scala_2021_2", - build_file_content = _SCALA_BUILD_FILE, - sha256 = "8d9c2831920fb69a52898598dc7f78c455001b3ebd1956b972757ffae7c0f056", - url = "https://plugins.jetbrains.com/files/1347/153522/scala-intellij-bin-2021.2.30.zip", -) - -# Scala plugin for IntelliJ CE. Required at compile-time for scala-specific features. -http_archive( - name = "scala_2021_3", - build_file_content = _SCALA_BUILD_FILE, - sha256 = "c14a15321060260360c3b8d41e9ef4080b5e552d2d0eb30ce6b141da08ee4764", - url = "https://plugins.jetbrains.com/files/1347/160380/scala-intellij-bin-2021.3.20.zip", -) - -# Scala plugin for IntelliJ CE. Required at compile-time for scala-specific features. -http_archive( - name = "scala_2022_1", - build_file_content = _SCALA_BUILD_FILE, - sha256 = "27d2ce5c1cddf497c685d30bcbc13b7e0d6691704fbfcc01fb8f4d832f0be9a1", - url = "https://plugins.jetbrains.com/files/1347/182909/scala-intellij-bin-2022.1.16.zip", -) - -http_archive( - name = "scala_2022_2", - build_file_content = _SCALA_BUILD_FILE, - sha256 = "67e0634b4a1c9431fde6f804da9714c935382c1442f541000e7dcd598d74bde7", - url = "https://plugins.jetbrains.com/files/1347/202220/scala-intellij-bin-2022.2.659.zip", -) - -http_archive( - name = "scala_2022_3", - build_file_content = _SCALA_BUILD_FILE, - sha256 = "f028ac7263433c8692d9d4c92aaba9e114fc75f6299d4d86817db371409f74f3", - url = "https://plugins.jetbrains.com/maven/com/jetbrains/plugins/org.intellij.scala/2022.3.13/org.intellij.scala-2022.3.13.zip", -) - -SCALA_PLUGIN_231_URL = "https://plugins.jetbrains.com/maven/com/jetbrains/plugins/org.intellij.scala/2023.1.15/org.intellij.scala-2023.1.15.zip" - -SCALA_PLUGIN_231_SHA = "40b794766439cce7a939a4fa50135f98facf0b103721ddb969cb09256d46c8af" - -http_archive( - name = "scala_2023_1", - build_file_content = _SCALA_BUILD_FILE, - sha256 = SCALA_PLUGIN_231_SHA, - url = SCALA_PLUGIN_231_URL, -) - -# The plugin api for android_studio_2022_2 android_studio. This is required to build ASwB and run integration tests -http_archive( - name = "android_studio_2022_2", - build_file = "@//intellij_platform_sdk:BUILD.android_studio222", - sha256 = "cdd852c4499b5f7402df44dfc69e8ca418ffc9a684caab34047476fd2cb24efc", - url = "https://dl.google.com/dl/android/studio/ide-zips/2022.2.1.18/android-studio-2022.2.1.18-linux.tar.gz", -) - -# The plugin api for android_studio_dev android_studio. This is required to build ASwB and run integration tests -http_archive( - name = "android_studio_dev", - build_file = "@//intellij_platform_sdk:BUILD.android_studiodev", - sha256 = "15e07cf08d7d1ccfaa122b4357a97279c850cc85af54de7bfb73f9916d84531d", - url = "https://android-build", -) - -# The plugin api for android_studio_2023_1 android_studio. This is required to build ASwB and run integration tests -http_archive( - name = "android_studio_2023_1", - build_file = "@//intellij_platform_sdk:BUILD.android_studio231", - sha256 = "6624d301853f2e3f3b53f464ad7ed3851df54ad691dd3d79bd6bea467fb00c5b", - url = "https://dl.google.com/dl/android/studio/ide-zips/2023.1.1.1/android-studio-2023.1.1.1-linux.tar.gz", -) - -# The plugin api for android_studio_2022_3 android_studio. This is required to build ASwB and run integration tests -http_archive( - name = "android_studio_2022_3", - build_file = "@//intellij_platform_sdk:BUILD.android_studio223", - sha256 = "5b2e6289fb1c2f52a8ed9227c7fb80bf2272338712e8b7d3616c5d25b664ea9a", - url = "https://dl.google.com/dl/android/studio/ide-zips/2022.3.1.12/android-studio-2022.3.1.12-linux.tar.gz", -) - -# LICENSE: Common Public License 1.0 -jvm_maven_import_external( - name = "junit", - artifact = "junit:junit:4.12", - artifact_sha256 = "59721f0805e223d84b90677887d9ff567dc534d7c502ca903c0c2b17f05c116a", - licenses = ["notice"], # Common Public License 1.0 - server_urls = ["https://repo1.maven.org/maven2"], -) - -jvm_maven_import_external( - name = "jsr305_annotations", - artifact = "com.google.code.findbugs:jsr305:3.0.2", - artifact_sha256 = "766ad2a0783f2687962c8ad74ceecc38a28b9f72a2d085ee438b7813e928d0c7", - licenses = ["notice"], # Apache 2.0 - server_urls = ["https://repo1.maven.org/maven2"], -) - -jvm_maven_import_external( - name = "truth", - artifact = "com.google.truth:truth:0.42", - artifact_sha256 = "dd652bdf0c4427c59848ac0340fd6b6d20c2cbfaa3c569a8366604dbcda5214c", - licenses = ["notice"], # Apache 2.0 - server_urls = ["https://repo1.maven.org/maven2"], -) - -jvm_maven_import_external( - name = "truth8", - artifact = "com.google.truth.extensions:truth-java8-extension:0.42", - artifact_sha256 = "cf9e095a6763bc33633b8844c3ebadffe3b082c81dd97a4d79b64ad88d305bc1", - licenses = ["notice"], # Apache 2.0 - server_urls = ["https://repo1.maven.org/maven2"], -) - -jvm_maven_import_external( - name = "mockito", - artifact = "org.mockito:mockito-core:3.3.0", - artifact_sha256 = "fc1a1f2d1d64566bc31ee36d8214059f2adbe303d9109e5cc0e99685741c57c2", - licenses = ["notice"], # Apache 2.0 - server_urls = ["https://repo1.maven.org/maven2"], -) - -jvm_maven_import_external( - name = "bytebuddy", - artifact = "net.bytebuddy:byte-buddy:1.10.5", - artifact_sha256 = "3c9c603970bb9d68572c1aa29e9ae6b477d602922977a04bfa5f3b5465d7d1f4", - licenses = ["notice"], # Apache 2.0 - server_urls = ["https://repo1.maven.org/maven2"], -) - -jvm_maven_import_external( - name = "bytebuddy-agent", - artifact = "net.bytebuddy:byte-buddy-agent:1.10.5", - artifact_sha256 = "290c9930965ef5810ddb15baf3b3647ce952f40fa2f0af82d5f669e04ba87e5b", - licenses = ["notice"], # Apache 2.0 - server_urls = ["https://repo1.maven.org/maven2"], -) - -jvm_maven_import_external( - name = "auto_value", - artifact = "com.google.auto.value:auto-value:1.6.2", - artifact_sha256 = "edbe65a5c53e3d4f5cb10b055d4884ae7705a7cd697be4b2a5d8427761b8ba12", - licenses = ["notice"], # Apache 2.0 - server_urls = ["https://repo1.maven.org/maven2"], -) - -jvm_maven_import_external( - name = "auto_value_annotations", - artifact = "com.google.auto.value:auto-value-annotations:1.6.2", - artifact_sha256 = "b48b04ddba40e8ac33bf036f06fc43995fc5084bd94bdaace807ce27d3bea3fb", - licenses = ["notice"], # Apache 2.0 - server_urls = ["https://repo1.maven.org/maven2"], -) - -jvm_maven_import_external( - name = "error_prone_annotations", - artifact = "com.google.errorprone:error_prone_annotations:2.13.1", - artifact_sha256 = "f5ee2aac2ee6443789e1dee0f96e3c35d9f3c78891f54ed83f3cf918a1cde6d1", - licenses = ["notice"], # Apache 2.0 - server_urls = ["https://repo1.maven.org/maven2"], -) - -jvm_maven_import_external( - name = "com_google_guava_guava", - artifact = "com.google.guava:guava:31.1-jre", - artifact_sha256 = "a42edc9cab792e39fe39bb94f3fca655ed157ff87a8af78e1d6ba5b07c4a00ab", - server_urls = [ - "https://repo1.maven.org/maven2", - ], -) - -jvm_maven_import_external( - name = "gson", - artifact = "com.google.code.gson:gson:2.9.1", - artifact_sha256 = "378534e339e6e6d50b1736fb3abb76f1c15d1be3f4c13cec6d536412e23da603", - server_urls = [ - "https://repo1.maven.org/maven2", - ], -) - -_JARJAR_BUILD_FILE = """ -java_binary( - name = "jarjar_bin", - srcs = glob( - ["src/main/**/*.java"], - exclude = [ - "src/main/com/tonicsystems/jarjar/JarJarMojo.java", - "src/main/com/tonicsystems/jarjar/util/AntJarProcessor.java", - "src/main/com/tonicsystems/jarjar/JarJarTask.java", - ], - ), - main_class = "com.tonicsystems.jarjar.Main", - resources = [":help"], - use_launcher = False, - visibility = ["//visibility:public"], - deps = [":asm"], -) - -java_import( - name = "asm", - jars = glob(["lib/asm-*.jar"]), -) - -genrule( - name = "help", - srcs = ["src/main/com/tonicsystems/jarjar/help.txt"], - outs = ["com/tonicsystems/jarjar/help.txt"], - cmd = "cp $< $@", -) -""" - -new_git_repository( - name = "jarjar", - build_file_content = _JARJAR_BUILD_FILE, - commit = "38ff702d10baec78f30d5f57485ae452f0fe33b5", - remote = "https://github.com/google/jarjar", - shallow_since = "1518210648 -0800", -) - -http_archive( - name = "rules_python", - sha256 = "ffc7b877c95413c82bfd5482c017edcf759a6250d8b24e82f41f3c8b8d9e287e", - strip_prefix = "rules_python-0.19.0", - url = "https://github.com/bazelbuild/rules_python/releases/download/0.19.0/rules_python-0.19.0.tar.gz", -) - -load("@rules_python//python:repositories.bzl", "py_repositories") - -py_repositories() - -http_archive( - name = "bazel_skylib", - sha256 = "74d544d96f4a5bb630d465ca8bbcfe231e3594e5aae57e1edbf17a6eb3ca2506", - urls = [ - "https://mirror.bazel.build/github.com/bazelbuild/bazel-skylib/releases/download/1.3.0/bazel-skylib-1.3.0.tar.gz", - "https://github.com/bazelbuild/bazel-skylib/releases/download/1.3.0/bazel-skylib-1.3.0.tar.gz", - ], -) - -# specify a minimum version for bazel otherwise users on old versions may see -# unexpressive errors when new features are used -load("@bazel_skylib//lib:versions.bzl", "versions") - -versions.check(minimum_bazel_version = "5.2.0") - -load("@bazel_skylib//:workspace.bzl", "bazel_skylib_workspace") - -bazel_skylib_workspace() - -http_archive( - name = "contrib_rules_bazel_integration_test", - sha256 = "20d670bb614d311a2a0fc8af53760439214731c3d5be2d9b0a197dccc19583f5", - strip_prefix = "rules_bazel_integration_test-0.9.0", - urls = [ - "http://github.com/bazel-contrib/rules_bazel_integration_test/archive/v0.9.0.tar.gz", - ], -) - -load("@contrib_rules_bazel_integration_test//bazel_integration_test:deps.bzl", "bazel_integration_test_rules_dependencies") - -bazel_integration_test_rules_dependencies() - -load("@contrib_rules_bazel_integration_test//bazel_integration_test:defs.bzl", "bazel_binaries") - -bazel_binaries(versions = [ - "1.2.0", - "6.0.0", -]) - -# LICENSE: The Apache Software License, Version 2.0 -http_archive( - name = "rules_proto", - sha256 = "dc3fb206a2cb3441b485eb1e423165b231235a1ea9b031b4433cf7bc1fa460dd", - strip_prefix = "rules_proto-5.3.0-21.7", - urls = [ - "https://github.com/bazelbuild/rules_proto/archive/refs/tags/5.3.0-21.7.tar.gz", - ], -) - -load("@rules_proto//proto:repositories.bzl", "rules_proto_dependencies", "rules_proto_toolchains") - -rules_proto_dependencies() - -rules_proto_toolchains() - -# LICENSE: The Apache Software License, Version 2.0 -rules_scala_version = "a0235fda820c635732d0d7cce86710eec92909ef" - -http_archive( - name = "io_bazel_rules_scala", - sha256 = "8981e4c5bb0f854b1c5da738876093249cf16b4b533cfec2d87dcdd1c867ffee", - strip_prefix = "rules_scala-%s" % rules_scala_version, - type = "zip", - url = "https://github.com/bazelbuild/rules_scala/archive/%s.zip" % rules_scala_version, -) - -load("@io_bazel_rules_scala//:scala_config.bzl", "scala_config") - -scala_config() - -load("@io_bazel_rules_scala//scala:scala.bzl", "scala_repositories") - -scala_repositories() - -load("@io_bazel_rules_scala//scala:toolchains.bzl", "scala_register_toolchains") - -scala_register_toolchains() - -load("@io_bazel_rules_scala//testing:scalatest.bzl", "scalatest_repositories", "scalatest_toolchain") - -scalatest_repositories() - -scalatest_toolchain() - -# LICENSE: The Apache Software License, Version 2.0 -rules_kotlin_version = "1.7.0-RC-1" - -rules_kotlin_sha = "68b910730026921814d3a504ccbe9adaac9938983d940e626523e6e4ecfb0355" - -http_archive( - name = "io_bazel_rules_kotlin", - sha256 = rules_kotlin_sha, - urls = ["https://github.com/bazelbuild/rules_kotlin/releases/download/v%s/rules_kotlin_release.tgz" % rules_kotlin_version], -) - -load("@io_bazel_rules_kotlin//kotlin:repositories.bzl", "kotlin_repositories") - -kotlin_repositories() - -load("@io_bazel_rules_kotlin//kotlin:core.bzl", "kt_register_toolchains") - -kt_register_toolchains() - -# Without this dependency, when a test that uses Google truth fails, instead of -# the textual difference we get java.lang.NoClassDefFoundError: difflib/DiffUtils -jvm_maven_import_external( - name = "diffutils", - artifact = "com.googlecode.java-diff-utils:diffutils:1.2.1", - artifact_sha256 = "c98697c3b8dd745353cd0a83b109c1c999fec43b4a5cedb2f579452d8da2c171", - licenses = ["notice"], # Apache 2.0 - server_urls = ["https://repo1.maven.org/maven2"], -) - -# Dependency needed for kotlin coroutines library -jvm_maven_import_external( - name = "kotlinx_coroutines", - artifact = "org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.6.2", - artifact_sha256 = "09aac136027678db2d3c2696696202719af9213ba17ae076f4c4421008885bcb", - licenses = ["notice"], # Apache 2.0 - server_urls = ["https://repo1.maven.org/maven2"], -) - -# Dependency needed for kotlin coroutines test library -jvm_maven_import_external( - name = "kotlinx_coroutines_test", - artifact = "org.jetbrains.kotlinx:kotlinx-coroutines-test-jvm:1.6.2", - artifact_sha256 = "6eb5c29f60fcacde882b1d393bf9a2fe9535bece1c707396fdbd755559dc043d", - licenses = ["notice"], # Apache 2.0 - server_urls = ["https://repo1.maven.org/maven2"], -) diff --git a/WORKSPACE.bzlmod b/WORKSPACE.bzlmod new file mode 100644 index 00000000000..75668b4f3d9 --- /dev/null +++ b/WORKSPACE.bzlmod @@ -0,0 +1,44 @@ +workspace(name = "intellij_with_bazel") + +load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") + +# LICENSE: The Apache Software License, Version 2.0 +rules_scala_version = "8f255cd1fecfe4d43934b161b3edda58bdb2e8f4" + +load("@rules_java//java:rules_java_deps.bzl", "rules_java_dependencies") +rules_java_dependencies() +load("@com_google_protobuf//:protobuf_deps.bzl", "protobuf_deps") +protobuf_deps() + +http_archive( + name = "io_bazel_rules_scala", + sha256 = "14797e907c5614387452c42412d755ad7e343ea12540a53da1430be3301c8b4b", + strip_prefix = "rules_scala-%s" % rules_scala_version, + type = "zip", + url = "https://github.com/bazelbuild/rules_scala/archive/%s.zip" % rules_scala_version, +) + +load("@io_bazel_rules_scala//:scala_config.bzl", "scala_config") + +scala_config() + +load("@io_bazel_rules_scala//scala:scala.bzl", "scala_repositories") + +scala_repositories() + +load("@io_bazel_rules_scala//scala:toolchains.bzl", "scala_register_toolchains") + +scala_register_toolchains() + +load("@io_bazel_rules_scala//testing:scalatest.bzl", "scalatest_repositories", "scalatest_toolchain") + +scalatest_repositories() + +scalatest_toolchain() + +load("@bazel_tools//tools/build_defs/repo:local.bzl", "local_repository") + +local_repository( + name = "intellij_aspect_template", + path = "aspect_template" +) diff --git a/aspect/BUILD b/aspect/BUILD index 72d6b962cee..9f7690b40a8 100644 --- a/aspect/BUILD +++ b/aspect/BUILD @@ -3,7 +3,7 @@ # load( - ":intellij_info_impl.bzl", + ":flag_hack.bzl", "define_flag_hack", ) @@ -28,16 +28,37 @@ filegroup( # the aspect files that will be bundled with the final plugin zip filegroup( name = "aspect_files", + srcs = [ + ":aspect_files_only", + ":aspect_tools", + ], + visibility = ["//visibility:public"], +) + +# Separate different targets as they are put into different directories +filegroup( + name = "aspect_files_only", srcs = [ "WORKSPACE", "artifacts.bzl", + "build_compose_dependencies.bzl", "build_dependencies.bzl", + "build_dependencies_deps.bzl", "fast_build_info_bundled.bzl", + "flag_hack.bzl", + "intellij_info.bzl", "intellij_info_bundled.bzl", "intellij_info_impl_bundled.bzl", "java_classpath.bzl", "make_variables.bzl", ":BUILD.bazel", + ], + visibility = ["//visibility:public"], +) + +filegroup( + name = "aspect_tools", + srcs = [ "//aspect/tools:CreateAar", "//aspect/tools:JarFilter_deploy.jar", "//aspect/tools:PackageParser_deploy.jar", @@ -80,7 +101,9 @@ genrule( srcs = ["intellij_info_impl.bzl"], outs = ["intellij_info_impl_bundled.bzl"], cmd = "cat $(SRCS) >$@ && " + - "sed -i -e '/BUNDLED-IGNORE-BEGIN/,/BUNDLED-IGNORE-END/d' $@", + "sed -i -e '/BUNDLED-IGNORE-BEGIN/,/BUNDLED-IGNORE-END/d' $@ && " + + "sed -i -e '/BUNDLED-INCLUDE-BEGIN/,/BUNDLED-INCLUDE-END/{s/^[#][#]//;}' $@ &&" + + "sed -i -e 's,load(\".*/rules_java/,load(\"@rules_java//', $@", ) # Makes bundled fast_build_info.bzl use bundled intellij_info_impl.bzl @@ -92,4 +115,11 @@ genrule( "sed -i -e 's,:intellij_info_impl.bzl,:intellij_info_impl_bundled.bzl,g' $@", ) +genrule( + name = "create_workspace_file", + outs = ["WORKSPACE"], + srcs = [], + cmd = r"""echo 'workspace(name = "intellij_aspect")' > $@""" +) + define_flag_hack() diff --git a/aspect/BUILD.aspect b/aspect/BUILD.aspect index 70f85a82c12..85caf6afb91 100644 --- a/aspect/BUILD.aspect +++ b/aspect/BUILD.aspect @@ -5,7 +5,7 @@ licenses(["notice"]) # Apache 2.0 -load(":intellij_info_impl_bundled.bzl", +load(":flag_hack.bzl", "define_flag_hack") java_binary( diff --git a/aspect/WORKSPACE b/aspect/WORKSPACE deleted file mode 100644 index e11b4032122..00000000000 --- a/aspect/WORKSPACE +++ /dev/null @@ -1 +0,0 @@ -workspace(name = "intellij_aspect") \ No newline at end of file diff --git a/aspect/build_compose_dependencies.bzl b/aspect/build_compose_dependencies.bzl new file mode 100644 index 00000000000..f83873f2569 --- /dev/null +++ b/aspect/build_compose_dependencies.bzl @@ -0,0 +1,37 @@ +"""Aspects to build and collect project's compose dependencies.""" + +load("//third_party/bazel_rules/rules_java/java:defs.bzl", "JavaInfo") + +ComposeDependenciesInfo = provider( + "The compose dependencies", + fields = { + "render_jars": "a list of render jars generated for project files and external dependencies", + }, +) + +def _package_compose_dependencies_impl(target, ctx): # @unused + return [OutputGroupInfo( + render_jars = target[ComposeDependenciesInfo].render_jars.to_list(), + )] + +package_compose_dependencies = aspect( + implementation = _package_compose_dependencies_impl, + required_aspect_providers = [[ComposeDependenciesInfo]], +) + +def _collect_compose_dependencies_impl(target, ctx): # @unused + if JavaInfo not in target: + return [ComposeDependenciesInfo( + render_jars = depset(), + )] + return [ + ComposeDependenciesInfo( + render_jars = depset([], transitive = [target[JavaInfo].transitive_runtime_jars]), + ), + ] + +collect_compose_dependencies = aspect( + implementation = _collect_compose_dependencies_impl, + provides = [ComposeDependenciesInfo], + attr_aspects = ["deps", "exports", "_android_sdk"], +) diff --git a/aspect/build_dependencies.bzl b/aspect/build_dependencies.bzl index 090d0f6bcfe..4d0bae6a8f5 100644 --- a/aspect/build_dependencies.bzl +++ b/aspect/build_dependencies.bzl @@ -1,48 +1,303 @@ """Aspects to build and collect project dependencies.""" +# Load external dependencies of this aspect. These are loaded in a separate file and re-exported as necessary +# to make supporting other versions of bazel easier, by replacing build_dependencies_deps.bzl. +load( + ":build_dependencies_deps.bzl", + "ANDROID_IDE_INFO", + "ZIP_TOOL_LABEL", + _ide_cc_not_validated = "IDE_CC", + _ide_java_not_validated = "IDE_JAVA", + _ide_kotlin_not_validated = "IDE_KOTLIN", +) + +ALWAYS_BUILD_RULES = "java_proto_library,java_lite_proto_library,java_mutable_proto_library,kt_proto_library_helper,_java_grpc_library,_java_lite_grpc_library,kt_grpc_library_helper,java_stubby_library,kt_stubby_library_helper,aar_import,java_import" + +PROTO_RULE_KINDS = [ + "java_proto_library", + "java_lite_proto_library", + "java_mutable_proto_library", + "kt_proto_library_helper", +] + +def _rule_function( + rule): # @unused + return [] + +def _target_rule_function( + target, # @unused + rule): # @unused + return [] + +def _unique(values): + return {k: None for k in values}.keys() + +def _validate_ide(unvalidated, template): + "Basic validation that a provided implementation conforms to a given template" + for a in dir(template): + if not hasattr(unvalidated, a): + fail("attribute missing: ", a, unvalidated) + elif type(getattr(unvalidated, a)) != type(getattr(template, a)): + fail("attribute type mismatch: ", a, type(getattr(unvalidated, a)), type(getattr(template, a))) + return struct(**{a: getattr(unvalidated, a) for a in dir(template) if a not in dir(struct())}) + +IDE_JAVA = _validate_ide( + _ide_java_not_validated, + template = struct( + srcs_attributes = [], # Additional srcs like attributes. + get_java_info = _target_rule_function, # A function that takes a rule and returns a JavaInfo like structure (or the provider itself). + ), +) + +IDE_KOTLIN = _validate_ide( + _ide_kotlin_not_validated, + template = struct( + srcs_attributes = [], # Additional srcs like attributes. + follow_attributes = [], # Additional attributes for the aspect to follow and request DependenciesInfo provider. + follow_additional_attributes = [], # Additional attributes for the aspect to follow without requesting DependenciesInfo provider. + followed_dependencies = _rule_function, # A function that takes a rule and returns a list of dependencies (targets or toolchain containers). + toolchains_aspects = [], # Toolchain types for the aspect to follow. + ), +) + +IDE_CC = _validate_ide( + _ide_cc_not_validated, + template = struct( + c_compile_action_name = "", # An action named to be used with cc_common.get_memory_inefficient_command_line or similar. + cpp_compile_action_name = "", # An action named to be used with cc_common.get_memory_inefficient_command_line or similar. + follow_attributes = ["_cc_toolchain"], # Additional attributes for the aspect to follow and request DependenciesInfo provider. + toolchains_aspects = [], # Toolchain types for the aspect to follow. + toolchain_target = _rule_function, # A function that takes a rule and returns a toolchain target (or a toolchain container). + ), +) + +JVM_SRC_ATTRS = _unique(["srcs"] + IDE_JAVA.srcs_attributes + IDE_KOTLIN.srcs_attributes) + def _package_dependencies_impl(target, ctx): - file_name = target.label.name + ".target-info.txt" + java_info_file = _write_java_target_info(target, ctx) + cc_info_file = _write_cc_target_info(target, ctx) + + dep_info = target[DependenciesInfo] + return [OutputGroupInfo( + qsync_jars = dep_info.compile_time_jars.to_list() if dep_info.compile_time_jars else [], + artifact_info_file = java_info_file, + qsync_aars = dep_info.aars.to_list() if dep_info.aars else [], + qsync_gensrcs = dep_info.gensrcs.to_list() if dep_info.gensrcs else [], + cc_headers = dep_info.cc_headers.to_list() if dep_info.cc_headers else [], + cc_info_file = cc_info_file + ([dep_info.cc_toolchain_info.file] if dep_info.cc_toolchain_info else []), + )] + +def _write_java_target_info(target, ctx, custom_prefix = ""): + """Write java target info to a file in proto format. + + The proto format used is defined by proto bazel.intellij.JavaArtifacts. + """ + target_to_artifacts = target[DependenciesInfo].target_to_artifacts + if not target_to_artifacts: + return [] + file_name = custom_prefix + target.label.name + ".java-info.txt" artifact_info_file = ctx.actions.declare_file(file_name) ctx.actions.write( artifact_info_file, - _encode_target_info_proto(target), + _encode_target_info_proto(target_to_artifacts), ) + return [artifact_info_file] - return [OutputGroupInfo( - qsync_jars = target[DependenciesInfo].compile_time_jars.to_list(), - artifact_info_file = [artifact_info_file], - qsync_aars = target[DependenciesInfo].aars.to_list(), - qsync_gensrcs = target[DependenciesInfo].gensrcs.to_list(), - )] +def _write_cc_target_info(target, ctx): + """Write CC target info to a file in proto format. + + The proto format used defined by proto bazel.intellij.CcCompilationInfo. + """ + if not target[DependenciesInfo].cc_compilation_info: + return [] + cc_info_file_name = target.label.name + ".cc-info.txt" + cc_info_file = ctx.actions.declare_file(cc_info_file_name) + ctx.actions.write( + cc_info_file, + _encode_cc_compilation_info_proto(target.label, target[DependenciesInfo].cc_compilation_info), + ) + return [cc_info_file] DependenciesInfo = provider( "The out-of-project dependencies", fields = { + "label": "the label of a target it describes", "compile_time_jars": "a list of jars generated by targets", "target_to_artifacts": "a map between a target and all its artifacts", "aars": "a list of aars with resource files", "gensrcs": "a list of sources generated by project targets", + "expand_sources": "boolean, true if the sources for this target should be expanded when it appears inside another rules srcs list", + "cc_compilation_info": "a structure containing info required to compile cc sources", + "cc_headers": "a depset of generated headers required to compile cc sources", + "cc_toolchain_info": "struct containing cc toolchain info, with keys file (the output file) and id (unique ID for the toolchain info, referred to from elsewhere)", + "test_mode_own_files": "a structure describing Java artifacts required when the target is requested within the project scope", + "test_mode_cc_src_deps": "a list of sources (e.g. headers) required to compile cc sources in integratrion tests", }, ) -def _encode_target_info_proto(target): +def create_dependencies_info( + label, + compile_time_jars = depset(), + target_to_artifacts = {}, + aars = depset(), + gensrcs = depset(), + expand_sources = False, + cc_compilation_info = None, + cc_headers = depset(), + cc_toolchain_info = None, + test_mode_own_files = None, + test_mode_cc_src_deps = depset()): + """A helper function to create a DependenciesInfo provider instance.""" + return DependenciesInfo( + label = label, + compile_time_jars = compile_time_jars, + target_to_artifacts = target_to_artifacts, + aars = aars, + gensrcs = gensrcs, + expand_sources = expand_sources, + cc_compilation_info = cc_compilation_info, + cc_headers = cc_headers, + cc_toolchain_info = cc_toolchain_info, + test_mode_own_files = test_mode_own_files, + test_mode_cc_src_deps = test_mode_cc_src_deps, + ) + +def create_java_dependencies_info( + compile_time_jars, + target_to_artifacts, + aars, + gensrcs, + expand_sources, + test_mode_own_files): + """A helper function to create a DependenciesInfo provider instance.""" + return struct( + compile_time_jars = compile_time_jars, + target_to_artifacts = target_to_artifacts, + aars = aars, + gensrcs = gensrcs, + expand_sources = expand_sources, + test_mode_own_files = test_mode_own_files, + ) + +def create_cc_dependencies_info( + cc_compilation_info = None, + cc_headers = depset(), + cc_toolchain_info = None, + test_mode_cc_src_deps = depset()): + """A helper function to create a DependenciesInfo provider instance.""" + return struct( + cc_compilation_info = cc_compilation_info, + cc_headers = cc_headers, + cc_toolchain_info = cc_toolchain_info, + test_mode_cc_src_deps = test_mode_cc_src_deps, + ) + +def create_cc_toolchain_info( + cc_toolchain_info = None, + test_mode_cc_src_deps = depset()): + """A helper function to create a DependenciesInfo provider instance.""" + return struct( + cc_toolchain_info = cc_toolchain_info, + test_mode_cc_src_deps = test_mode_cc_src_deps, + ) + +def merge_dependencies_info(target, ctx, java_dep_info, cc_dep_info, cc_toolchain_dep_info): + """Merge multiple DependenciesInfo providers into one. + + Depsets and dicts are merged. For members such as `cc_compilation_info`, we require that at most one of the + DependenciesInfo's defines this which should always be the case. + """ + + if not java_dep_info and not cc_dep_info and not cc_toolchain_dep_info: + return [] + + if cc_dep_info and cc_toolchain_dep_info: + test_mode_cc_src_deps = depset(transitive = [cc_dep_info.test_mode_cc_src_deps, cc_toolchain_dep_info.test_mode_cc_src_deps]) + cc_toolchain_info = cc_toolchain_dep_info.cc_toolchain_info + elif cc_dep_info: + test_mode_cc_src_deps = cc_dep_info.test_mode_cc_src_deps + cc_toolchain_info = cc_dep_info.cc_toolchain_info + elif cc_toolchain_dep_info: + test_mode_cc_src_deps = cc_toolchain_dep_info.test_mode_cc_src_deps + cc_toolchain_info = cc_toolchain_dep_info.cc_toolchain_info + else: + test_mode_cc_src_deps = None + cc_toolchain_info = None + + merged = create_dependencies_info( + label = target.label, + compile_time_jars = java_dep_info.compile_time_jars if java_dep_info else None, + target_to_artifacts = java_dep_info.target_to_artifacts if java_dep_info else None, + aars = java_dep_info.aars if java_dep_info else None, + gensrcs = java_dep_info.gensrcs if java_dep_info else None, + expand_sources = java_dep_info.expand_sources if java_dep_info else None, + cc_compilation_info = cc_dep_info.cc_compilation_info if cc_dep_info else None, + cc_headers = cc_dep_info.cc_headers if cc_dep_info else None, + cc_toolchain_info = cc_toolchain_info, + test_mode_own_files = java_dep_info.test_mode_own_files if java_dep_info else None, + test_mode_cc_src_deps = test_mode_cc_src_deps, + ) + return merged + +def one_of(a, b): + """Returns whichever of a or b is not None, None if both are, or fails if neither are.""" + if a == None: + return b + if b == None: + return a + fail("Expected at most one, but got both", a, b) + +def _encode_target_info_proto(target_to_artifacts): contents = [] - for label, artifacts_paths in target[DependenciesInfo].target_to_artifacts.items(): + for label, target_info in target_to_artifacts.items(): contents.append( - struct(target = label, artifact_paths = artifacts_paths), + struct( + target = label, + jars = _encode_file_list(target_info["jars"]) if "jars" in target_info else [], + ide_aars = _encode_file_list(target_info["ide_aars"]), + gen_srcs = _encode_file_list(target_info["gen_srcs"]), + srcs = target_info["srcs"], + srcjars = target_info["srcjars"], + android_resources_package = target_info["android_resources_package"], + ), ) return proto.encode_text(struct(artifacts = contents)) +def _encode_file_list(files): + """Encodes a list of files as a struct. + + Returns: + A list fo structs matching the bazel.intellij.OutputArtifact proto message. + """ + r = [] + for f in files: + if f.is_directory: + r.append(struct(directory = f.path)) + else: + r.append(struct(file = f.path)) + return r + +def _encode_cc_compilation_info_proto(label, cc_compilation_info): + return proto.encode_text( + struct(targets = [ + struct( + label = str(label), + defines = cc_compilation_info.transitive_defines, + include_directories = cc_compilation_info.transitive_include_directory, + quote_include_directories = cc_compilation_info.transitive_quote_include_directory, + system_include_directories = cc_compilation_info.transitive_system_include_directory, + framework_include_directories = cc_compilation_info.framework_include_directory, + gen_hdrs = _encode_file_list(cc_compilation_info.gen_headers), + toolchain_id = cc_compilation_info.toolchain_id, + ), + ]), + ) + package_dependencies = aspect( implementation = _package_dependencies_impl, required_aspect_providers = [[DependenciesInfo]], ) -def generates_idl_jar(target): - if AndroidIdeInfo not in target: - return False - return target[AndroidIdeInfo].idl_class_jar != None - def declares_android_resources(target, ctx): """ Returns true if the target has resource files and an android provider. @@ -57,10 +312,49 @@ def declares_android_resources(target, ctx): Returns: True if the target has resource files and an android provider. """ - if AndroidIdeInfo not in target: + if _get_android_provider(target) == None: return False return hasattr(ctx.rule.attr, "resource_files") and len(ctx.rule.attr.resource_files) > 0 +def _get_android_provider(target): + if ANDROID_IDE_INFO and ANDROID_IDE_INFO in target: + return target[ANDROID_IDE_INFO] + elif hasattr(android_common, "AndroidIdeInfo"): + if android_common.AndroidIdeInfo in target: + return target[android_common.AndroidIdeInfo] + else: + return None + elif hasattr(target, "android"): + # Backwards compatibility: supports android struct provider + legacy_android = getattr(target, "android") + + # Transform into AndroidIdeInfo form + return struct( + aar = legacy_android.aar, + java_package = legacy_android.java_package, + manifest = legacy_android.manifest, + idl_source_jar = getattr(legacy_android.idl.output, "source_jar", None), + idl_class_jar = getattr(legacy_android.idl.output, "class_jar", None), + defines_android_resources = legacy_android.defines_resources, + idl_import_root = getattr(legacy_android.idl, "import_root", None), + idl_generated_java_files = getattr(legacy_android.idl, "generated_java_files", []), + resource_jar = legacy_android.resource_jar, + signed_apk = legacy_android.apk, + apks_under_test = legacy_android.apks_under_test, + ) + return None + +def declares_aar_import(ctx): + """ + Returns true if the target has aar and is aar_import rule. + + Args: + ctx: the context. + Returns: + True if the target has aar and is aar_import rule. + """ + return ctx.rule.kind == "aar_import" and hasattr(ctx.rule.attr, "aar") + def _collect_dependencies_impl(target, ctx): return _collect_dependencies_core_impl( target, @@ -69,6 +363,8 @@ def _collect_dependencies_impl(target, ctx): ctx.attr.exclude, ctx.attr.always_build_rules, ctx.attr.generate_aidl_classes, + ctx.attr.use_generated_srcjars, + test_mode = False, ) def _collect_all_dependencies_for_tests_impl(target, ctx): @@ -77,128 +373,531 @@ def _collect_all_dependencies_for_tests_impl(target, ctx): ctx, include = None, exclude = None, - always_build_rules = None, + always_build_rules = ALWAYS_BUILD_RULES, generate_aidl_classes = None, + use_generated_srcjars = True, + test_mode = True, ) -def _collect_dependencies_core_impl( +def collect_dependencies_for_test(target, ctx, include = []): + return _collect_dependencies_core_impl( target, ctx, - include, - exclude, - always_build_rules, - generate_aidl_classes): - if JavaInfo not in target: - return [DependenciesInfo( - compile_time_jars = depset(), - target_to_artifacts = {}, - aars = depset(), - gensrcs = depset(), - )] - label = str(target.label) - - must_build = True - - # include can only be empty when used from collect_all_dependencies_for_tests - # aspect, which is meant to be used in tests only. + include = ",".join(include), + exclude = "", + always_build_rules = ALWAYS_BUILD_RULES, + generate_aidl_classes = None, + use_generated_srcjars = True, + test_mode = False, + ) + +def _package_prefix_match(package, prefix): + if (package == prefix): + return True + if package.startswith(prefix) and package[len(prefix)] == "/": + return True + return False + +def _get_repo_name(label): + # The API to get the repo name changed between bazel versions. Use whichever exists: + return label.repo_name if "repo_name" in dir(label) else label.workspace_name + +def _target_within_project_scope(label, include, exclude): + repo = _get_repo_name(label) + package = label.package + result = False + if repo != "": + return False # We don't support external includes, so all external repos are outside the project scope if include: for inc in include.split(","): - if label.startswith(inc): - if label[len(inc)] in [":", "/"]: - must_build = False - break - if not must_build and len(exclude) > 0: + # This is not a valid label, but can be passed to aspect when `directories: .` is set in the projectview + if (inc == "//"): + result = True + break + + inc = Label(inc) + if _get_repo_name(inc) == repo and _package_prefix_match(package, inc.package): + result = True + break + + if result and len(exclude) > 0: for exc in exclude.split(","): - if label.startswith(exc): - if label[len(exc)] in [":", "/"]: - must_build = True - break + # Same as for includes + if (exc == "//"): + result = False + break + + exc = Label(exc) + if _get_repo_name(exc) == repo and _package_prefix_match(package, exc.package): + result = False + break - if not must_build and ctx.rule.kind in always_build_rules.split(","): - must_build = True + return result +def _get_dependency_attribute(rule, attr): + if hasattr(rule.attr, attr): + to_add = getattr(rule.attr, attr) + if type(to_add) == "list": + return [t for t in to_add if type(t) == "Target"] + elif type(to_add) == "Target": + return [to_add] + return [] + +def _get_followed_java_proto_dependencies(rule): + deps = [] + if rule.kind in ["proto_lang_toolchain", "java_rpc_toolchain"]: + deps.extend(_get_dependency_attribute(rule, "runtime")) + if rule.kind in ["_java_grpc_library", "_java_lite_grpc_library"]: + deps.extend(_get_dependency_attribute(rule, "_toolchain")) + return deps + +def _get_followed_java_dependency_infos(rule): deps = [] - if hasattr(ctx.rule.attr, "deps"): - deps += ctx.rule.attr.deps - if hasattr(ctx.rule.attr, "exports"): - deps += ctx.rule.attr.exports - if hasattr(ctx.rule.attr, "_junit"): - deps.append(ctx.rule.attr._junit) - - info_deps = [dep[DependenciesInfo] for dep in deps if DependenciesInfo in dep and dep[DependenciesInfo].target_to_artifacts] - - trs = [] - aar_files = [] - aar_trs = [] - gensrc_files = [] - gensrc_trs = [] - - if must_build: + for attr in FOLLOW_JAVA_ATTRIBUTES: + deps.extend(_get_dependency_attribute(rule, attr)) + + deps.extend(_get_followed_java_proto_dependencies(rule)) + deps.extend(IDE_KOTLIN.followed_dependencies(rule)) + + return { + str(dep[DependenciesInfo].label): dep[DependenciesInfo] # NOTE: This handles duplicates. + for dep in deps + if DependenciesInfo in dep and dep[DependenciesInfo].target_to_artifacts + } + +def _collect_own_java_artifacts( + target, + ctx, + can_follow_dependencies, + always_build_rules, + generate_aidl_classes, + use_generated_srcjars, + target_is_within_project_scope): + rule = ctx.rule + + must_build_main_artifacts = ( + not target_is_within_project_scope or rule.kind in always_build_rules.split(",") + ) + + own_jar_files = [] + own_jar_depsets = [] + own_ide_aar_files = [] + own_gensrc_files = [] + own_src_files = [] + own_srcjar_files = [] + resource_package = "" + + java_info = IDE_JAVA.get_java_info(target, ctx.rule) + + if must_build_main_artifacts: # For rules that we do not follow dependencies of (either because they don't # have further dependencies with JavaInfo or do so in attributes we don't care) # we gather all their transitive dependencies. If they have dependencies, we # only gather their own compile jars and continue down the tree. - # This is done primarily for rules like proto, where they don't have dependencies - # and add their "toolchain" classes to transitive deps. - if info_deps: - trs = [target[JavaInfo].compile_jars] - else: - trs = [target[JavaInfo].transitive_compile_time_jars] + # This is done primarily for rules like proto, whose toolchain classes + # are collected via attribute traversal, but still requires jars for any + # proto deps of the underlying proto_library. + if java_info: + if can_follow_dependencies: + own_jar_depsets.append(java_info.compile_jars) + else: + own_jar_depsets.append(java_info.transitive_compile_time_jars) + if declares_android_resources(target, ctx): ide_aar = _get_ide_aar_file(target, ctx) if ide_aar: - aar_files.append(ide_aar) + # TODO(mathewi) - handle source aars + if not ide_aar.is_source: + own_ide_aar_files.append(ide_aar) + elif declares_aar_import(ctx): + ide_aar = rule.attr.aar.files.to_list()[0] + + # TODO(mathewi) - handle source aars + if not ide_aar.is_source: + own_ide_aar_files.append(ide_aar) else: - if generate_aidl_classes and generates_idl_jar(target): - idl_jar = target[AndroidIdeInfo].idl_class_jar - trs.append(depset([idl_jar])) + android = _get_android_provider(target) + if android != None: + resource_package = android.java_package + + if generate_aidl_classes: + add_base_idl_jar = False + idl_jar = android.idl_class_jar + if idl_jar != None: + own_jar_files.append(idl_jar) + add_base_idl_jar = True + + generated_java_files = android.idl_generated_java_files + if generated_java_files: + own_gensrc_files += generated_java_files + add_base_idl_jar = True - # An AIDL base jar needed for resolving base classes for aidl generated stubs, - if hasattr(ctx.rule.attr, "_android_sdk"): - android_sdk_info = getattr(ctx.rule.attr, "_android_sdk")[AndroidSdkInfo] - trs.append(android_sdk_info.aidl_lib.files) - must_build = True + # An AIDL base jar needed for resolving base classes for aidl generated stubs. + if add_base_idl_jar: + if hasattr(rule.attr, "_aidl_lib"): + own_jar_depsets.append(rule.attr._aidl_lib.files) + elif hasattr(rule.attr, "_android_sdk") and hasattr(android_common, "AndroidSdkInfo"): + android_sdk_info = getattr(rule.attr, "_android_sdk")[android_common.AndroidSdkInfo] + own_jar_depsets.append(android_sdk_info.aidl_lib.files) - # Add generated java_outputs (e.g. from annotation processing + # Add generated java_outputs (e.g. from annotation processing) generated_class_jars = [] - for java_output in target[JavaInfo].java_outputs: - if java_output.generated_class_jar: - generated_class_jars.append(java_output.generated_class_jar) + if java_info: + for java_output in java_info.java_outputs: + # Prefer source jars if they exist and are requested: + if use_generated_srcjars and java_output.generated_source_jar: + own_gensrc_files.append(java_output.generated_source_jar) + elif java_output.generated_class_jar: + generated_class_jars.append(java_output.generated_class_jar) + else: + for src_attr in JVM_SRC_ATTRS: + # unfortunately, in cases where we have non-cource + # src attribute, we had to add full output jar + # to avoid red code + # We would need jar filtering to handle it well + if hasattr(rule.attr, src_attr): + for src in getattr(rule.attr, src_attr): + for file in src.files.to_list(): + if not file.is_source: + generated_class_jars.append(java_output.class_jar) + if generated_class_jars: - trs.append(depset(generated_class_jars)) - must_build = True + own_jar_files += generated_class_jars # Add generated sources for included targets - if hasattr(ctx.rule.attr, "srcs"): - for src in ctx.rule.attr.srcs: - for file in src.files.to_list(): - if not file.is_source: - gensrc_files.append(file) - must_build = True + for src_attr in JVM_SRC_ATTRS: + if hasattr(rule.attr, src_attr): + for src in getattr(rule.attr, src_attr): + # If the target that generates this source specifies that + # the sources should be expanded, we ignore the generated + # sources - the IDE will substitute the target sources + # themselves instead. + if not (DependenciesInfo in src and src[DependenciesInfo].expand_sources): + for file in src.files.to_list(): + if not file.is_source: + own_gensrc_files.append(file) + + if not target_is_within_project_scope: + for src_attr in JVM_SRC_ATTRS: + if hasattr(rule.attr, src_attr): + for src in getattr(rule.attr, src_attr): + for file in src.files.to_list(): + if file.is_source: + own_src_files.append(file.path) + else: + own_gensrc_files.append(file) + if hasattr(rule.attr, "srcjar"): + if rule.attr.srcjar and type(rule.attr.srcjar) == "Target": + for file in rule.attr.srcjar.files.to_list(): + if file.is_source: + own_srcjar_files.append(file.path) + else: + own_gensrc_files.append(file) + + return struct( + jars = own_jar_files, + jar_depsets = own_jar_depsets, + ide_aars = own_ide_aar_files, + gensrcs = own_gensrc_files, + srcs = own_src_files, + srcjars = own_srcjar_files, + android_resources_package = resource_package, + ) + +def _target_to_artifact_entry( + jars = [], + ide_aars = [], + gen_srcs = [], + srcs = [], + srcjars = [], + android_resources_package = ""): + return { + "jars": jars, + "ide_aars": ide_aars, + "gen_srcs": gen_srcs, + "srcs": srcs, + "srcjars": srcjars, + "android_resources_package": android_resources_package, + } + +def _can_follow_dependencies(ctx): + # Toolchains are collected for proto targets via aspect traversal, but jars + # produced for proto deps of the underlying proto_library are not + return not ctx.rule.kind in PROTO_RULE_KINDS + +def _collect_own_and_dependency_java_artifacts( + target, + ctx, + dependency_infos, + always_build_rules, + generate_aidl_classes, + use_generated_srcjars, + target_is_within_project_scope): + can_follow_dependencies = _can_follow_dependencies(ctx) + + own_files = _collect_own_java_artifacts( + target, + ctx, + can_follow_dependencies, + always_build_rules, + generate_aidl_classes, + use_generated_srcjars, + target_is_within_project_scope, + ) + + has_own_artifacts = ( + len(own_files.jars) + + len(own_files.jar_depsets) + + len(own_files.ide_aars) + + len(own_files.gensrcs) + + len(own_files.srcs) + + len(own_files.srcjars) + + (1 if own_files.android_resources_package else 0) + ) > 0 target_to_artifacts = {} - if must_build: - artifacts = depset(gensrc_files + aar_files, transitive = trs).to_list() - target_to_artifacts[label] = [_output_relative_path(file.path) for file in artifacts] + if has_own_artifacts: + # Pass the following lists through depset() to to remove any duplicates. + jars = depset(own_files.jars, transitive = own_files.jar_depsets).to_list() + ide_aars = depset(own_files.ide_aars).to_list() + gen_srcs = depset(own_files.gensrcs).to_list() + target_to_artifacts[str(target.label)] = _target_to_artifact_entry( + jars = jars, + ide_aars = ide_aars, + gen_srcs = gen_srcs, + srcs = own_files.srcs, + srcjars = own_files.srcjars, + android_resources_package = own_files.android_resources_package, + ) + elif target_is_within_project_scope: + target_to_artifacts[str(target.label)] = _target_to_artifact_entry() + + own_and_transitive_jar_depsets = list(own_files.jar_depsets) # Copy to prevent changes to own_jar_depsets. + own_and_transitive_ide_aar_depsets = [] + own_and_transitive_gensrc_depsets = [] - for info in info_deps: - trs.append(info.compile_time_jars) + for info in dependency_infos.values(): target_to_artifacts.update(info.target_to_artifacts) - aar_trs.append(info.aars) - gensrc_trs.append(info.gensrcs) - - cj = depset([], transitive = trs) - aars = depset(aar_files, transitive = aar_trs) - gensrcs = depset(gensrc_files, transitive = gensrc_trs) - return [ - DependenciesInfo( - compile_time_jars = cj, - target_to_artifacts = target_to_artifacts, - aars = aars, - gensrcs = gensrcs, + own_and_transitive_jar_depsets.append(info.compile_time_jars) + own_and_transitive_ide_aar_depsets.append(info.aars) + own_and_transitive_gensrc_depsets.append(info.gensrcs) + + return ( + target_to_artifacts, + depset(own_files.jars, transitive = own_and_transitive_jar_depsets), + depset(own_files.ide_aars, transitive = own_and_transitive_ide_aar_depsets), + depset(own_files.gensrcs, transitive = own_and_transitive_gensrc_depsets), + ) + +def _get_cc_toolchain_dependency_info(rule): + cc_toolchain_target = IDE_CC.toolchain_target(rule) + if cc_toolchain_target and DependenciesInfo in cc_toolchain_target: + return cc_toolchain_target[DependenciesInfo] + return None + +def _collect_own_and_dependency_cc_info(target, rule, test_mode): + dependency_info = _get_cc_toolchain_dependency_info(rule) + compilation_context = target[CcInfo].compilation_context + cc_toolchain_info = None + test_mode_cc_src_deps = depset() + if dependency_info: + cc_toolchain_info = dependency_info.cc_toolchain_info + if test_mode: + test_mode_cc_src_deps = dependency_info.test_mode_cc_src_deps + + gen_headers = depset() + compilation_info = None + if compilation_context: + gen_headers = depset([f for f in compilation_context.headers.to_list() if not f.is_source]) + + if test_mode: + test_mode_cc_src_deps = depset( + [f for f in compilation_context.headers.to_list() if f.is_source], + transitive = [test_mode_cc_src_deps], + ) + + compilation_info = struct( + transitive_defines = compilation_context.defines.to_list(), + transitive_include_directory = compilation_context.includes.to_list(), + transitive_quote_include_directory = compilation_context.quote_includes.to_list(), + transitive_system_include_directory = ( + compilation_context.system_includes.to_list() + ( + # external_includes was added in newer versions of bazel + compilation_context.external_includes.to_list() if hasattr(compilation_context, "external_includes") else [] + ) + ), + framework_include_directory = compilation_context.framework_includes.to_list(), + gen_headers = gen_headers.to_list(), + toolchain_id = cc_toolchain_info.id if cc_toolchain_info else None, + ) + return struct( + compilation_info = compilation_info, + gen_headers = gen_headers, + test_mode_cc_src_deps = test_mode_cc_src_deps, + cc_toolchain_info = cc_toolchain_info, + ) + +def _collect_dependencies_core_impl( + target, + ctx, + include, + exclude, + always_build_rules, + generate_aidl_classes, + use_generated_srcjars, + test_mode): + java_dep_info = _collect_java_dependencies_core_impl( + target, + ctx, + include, + exclude, + always_build_rules, + generate_aidl_classes, + use_generated_srcjars, + test_mode, + ) + cc_dep_info = None + if CcInfo in target: + cc_dep_info = _collect_cc_dependencies_core_impl(target, ctx, test_mode) + cc_toolchain_dep_info = None + if cc_common.CcToolchainInfo in target: + cc_toolchain_dep_info = _collect_cc_toolchain_info(target, ctx) + return merge_dependencies_info(target, ctx, java_dep_info, cc_dep_info, cc_toolchain_dep_info) + +def _collect_java_dependencies_core_impl( + target, + ctx, + include, + exclude, + always_build_rules, + generate_aidl_classes, + use_generated_srcjars, + test_mode): + target_is_within_project_scope = _target_within_project_scope(target.label, include, exclude) and not test_mode + dependency_infos = _get_followed_java_dependency_infos(ctx.rule) + + target_to_artifacts, compile_jars, aars, gensrcs = _collect_own_and_dependency_java_artifacts( + target, + ctx, + dependency_infos, + always_build_rules, + generate_aidl_classes, + use_generated_srcjars, + target_is_within_project_scope, + ) + + test_mode_own_files = None + if test_mode: + can_follow_dependencies = _can_follow_dependencies(ctx) + within_scope_own_files = _collect_own_java_artifacts( + target, + ctx, + can_follow_dependencies, + always_build_rules, + generate_aidl_classes, + use_generated_srcjars, + target_is_within_project_scope = True, + ) + test_mode_own_files = struct( + test_mode_within_scope_own_jar_files = depset(within_scope_own_files.jars, transitive = within_scope_own_files.jar_depsets).to_list(), + test_mode_within_scope_own_ide_aar_files = within_scope_own_files.ide_aars, + test_mode_within_scope_own_gensrc_files = within_scope_own_files.gensrcs, + ) + + expand_sources = False + if hasattr(ctx.rule.attr, "tags"): + if "ij-ignore-source-transform" in ctx.rule.attr.tags: + expand_sources = True + + return create_java_dependencies_info( + target_to_artifacts = target_to_artifacts, + compile_time_jars = compile_jars, + aars = aars, + gensrcs = gensrcs, + expand_sources = expand_sources, + test_mode_own_files = test_mode_own_files, + ) + +def _collect_cc_dependencies_core_impl(target, ctx, test_mode): + cc_info = _collect_own_and_dependency_cc_info(target, ctx.rule, test_mode) + + return create_cc_dependencies_info( + cc_compilation_info = cc_info.compilation_info, + cc_headers = cc_info.gen_headers, + cc_toolchain_info = cc_info.cc_toolchain_info, + test_mode_cc_src_deps = cc_info.test_mode_cc_src_deps, + ) + +def _collect_cc_toolchain_info(target, ctx): + toolchain_info = target[cc_common.CcToolchainInfo] + + cpp_fragment = ctx.fragments.cpp + + # TODO(b/301235884): This logic is not quite right. `ctx` here is the context for the + # cc_toolchain target itself, so the `features` and `disabled_features` were using here are + # for the cc_toolchain, not the individual targets that this information will ultimately be + # used for. Instead, we should attach `toolchain_info` itself to the `DependenciesInfo` + # provider, and execute this logic once per top level cc target that we're building, to ensure + # that the right features are used. + feature_config = cc_common.configure_features( + ctx = ctx, + cc_toolchain = toolchain_info, + requested_features = ctx.features, + unsupported_features = ctx.disabled_features + [ + # Note: module_maps appears to be necessary here to ensure the API works + # in all cases, and to avoid the error: + # Invalid toolchain configuration: Cannot find variable named 'module_name' + # yaqs/3227912151964319744 + "module_maps", + ], + ) + c_variables = cc_common.create_compile_variables( + feature_configuration = feature_config, + cc_toolchain = toolchain_info, + user_compile_flags = cpp_fragment.copts + cpp_fragment.conlyopts, + ) + cpp_variables = cc_common.create_compile_variables( + feature_configuration = feature_config, + cc_toolchain = toolchain_info, + user_compile_flags = cpp_fragment.copts + cpp_fragment.cxxopts, + ) + c_options = cc_common.get_memory_inefficient_command_line( + feature_configuration = feature_config, + action_name = IDE_CC.c_compile_action_name, + variables = c_variables, + ) + cpp_options = cc_common.get_memory_inefficient_command_line( + feature_configuration = feature_config, + action_name = IDE_CC.cpp_compile_action_name, + variables = cpp_variables, + ) + toolchain_id = str(target.label) + "%" + toolchain_info.target_gnu_system_name + + cc_toolchain_info = struct( + id = toolchain_id, + compiler_executable = toolchain_info.compiler_executable, + cpu = toolchain_info.cpu, + compiler = toolchain_info.compiler, + target_name = toolchain_info.target_gnu_system_name, + built_in_include_directories = toolchain_info.built_in_include_directories, + c_options = c_options, + cpp_options = cpp_options, + ) + + cc_toolchain_file_name = target.label.name + "." + cc_toolchain_info.target_name + ".txt" + cc_toolchain_file = ctx.actions.declare_file(cc_toolchain_file_name) + ctx.actions.write( + cc_toolchain_file, + proto.encode_text( + struct(toolchains = cc_toolchain_info), ), - ] + ) + + return create_cc_toolchain_info( + cc_toolchain_info = struct(file = cc_toolchain_file, id = toolchain_id), + test_mode_cc_src_deps = depset([f for f in toolchain_info.all_files.to_list() if f.is_source]), + ) def _get_ide_aar_file(target, ctx): """ @@ -211,10 +910,11 @@ def _get_ide_aar_file(target, ctx): The function builds a minimalistic .aar file that contains resources and the manifest only. """ - full_aar = target[AndroidIdeInfo].aar + android = _get_android_provider(target) + full_aar = android.aar if full_aar: resource_files = _collect_resource_files(ctx) - resource_map = _build_aar_file_map(target[AndroidIdeInfo].manifest, resource_files) + resource_map = _build_ide_aar_file_map(android.manifest, resource_files) aar = ctx.actions.declare_file(full_aar.short_path.removesuffix(".aar") + "_ide/" + full_aar.basename) _package_ide_aar(ctx, aar, resource_map) return aar @@ -240,7 +940,7 @@ def _collect_resource_files(ctx): resource_files.append(f) return resource_files -def _build_aar_file_map(manifest_file, resource_files): +def _build_ide_aar_file_map(manifest_file, resource_files): """ Build the list of files and their paths as they have to appear in .aar. """ @@ -255,54 +955,50 @@ def _build_aar_file_map(manifest_file, resource_files): file_map[res_dir_path] = f return file_map -_CONTROL_FILE_ENTRY = '''entry { - zip_path: "%s" - exec_path: "%s" -}''' - def _package_ide_aar(ctx, aar, file_map): """ Declares a file and defines actions to build .aar according to file_map. - - The IDE.aar file is produces by an aspect and therefore it cannot define - additional targets and thus cannot use genzip() rule. This function reuses - //tools/genzip:build_zip tool, which is used by getzip() rule. """ - actions = ctx.actions - control_file = actions.declare_file(".control", sibling = aar) - control_content = ['output_filename: "%s"' % aar.path] + files_map_args = [] files = [] for aar_dir_path, f in file_map.items(): files.append(f) - control_content.append(_CONTROL_FILE_ENTRY % (aar_dir_path, f.path)) - control_content.append("compression: STORED") - actions.write(control_file, "\n".join(control_content)) - actions.run( + files_map_args.append("%s=%s" % (aar_dir_path, f.path)) + + ctx.actions.run( mnemonic = "GenerateIdeAar", executable = ctx.executable._build_zip, - inputs = files + [control_file], + inputs = files, outputs = [aar], - arguments = ["--control", control_file.path], + arguments = ["c", aar.path] + files_map_args, ) -def _output_relative_path(path): - """Get file path relative to the output path. +# List of tuples containing: +# 1. An attribute for the aspect to traverse +# 2. A list of rule kinds to specify which rules for which the attribute labels +# need to be added as dependencies. If empty, the attribute is followed for +# all rules. +FOLLOW_JAVA_ATTRIBUTES = [ + "deps", + "exports", + "srcs", + "_junit", + "_aspect_proto_toolchain_for_javalite", + "_aspect_java_proto_toolchain", +] + IDE_KOTLIN.follow_attributes - Args: - path: path of artifact path = (../repo_name)? + (root_fragment)? + relative_path +FOLLOW_CC_ATTRIBUTES = IDE_CC.follow_attributes - Returns: - path relative to the output path - """ - if (path.startswith("blaze-out/")) or (path.startswith("bazel-out/")): - # len("blaze-out/") or len("bazel-out/") - path = path[10:] - return path +FOLLOW_ADDITIONAL_ATTRIBUTES = ["runtime", "_toolchain"] + IDE_KOTLIN.follow_additional_attributes + +FOLLOW_ATTRIBUTES = _unique(FOLLOW_JAVA_ATTRIBUTES + FOLLOW_CC_ATTRIBUTES + FOLLOW_ADDITIONAL_ATTRIBUTES) + +TOOLCHAINS_ASPECTS = IDE_KOTLIN.toolchains_aspects + IDE_CC.toolchains_aspects collect_dependencies = aspect( implementation = _collect_dependencies_impl, provides = [DependenciesInfo], - attr_aspects = ["deps", "exports", "_junit"], + attr_aspects = FOLLOW_ATTRIBUTES, attrs = { "include": attr.string( doc = "Comma separated list of workspace paths included in the project as source. Any targets inside here will not be built.", @@ -320,13 +1016,21 @@ collect_dependencies = aspect( doc = "If True, generates classes for aidl files included as source for the project targets", default = False, ), + "use_generated_srcjars": attr.bool( + doc = "If True, collects generated source jars for a target instead of compiled jar", + default = False, + ), "_build_zip": attr.label( allow_files = True, cfg = "exec", executable = True, - default = "@//tools/genzip:build_zip", + default = ZIP_TOOL_LABEL, ), }, + fragments = ["cpp"], + **{ + "toolchains_aspects": TOOLCHAINS_ASPECTS, + } if TOOLCHAINS_ASPECTS else {} ) collect_all_dependencies_for_tests = aspect( @@ -340,13 +1044,78 @@ collect_all_dependencies_for_tests = aspect( """, implementation = _collect_all_dependencies_for_tests_impl, provides = [DependenciesInfo], - attr_aspects = ["deps", "exports", "_junit"], + attr_aspects = FOLLOW_ATTRIBUTES, attrs = { "_build_zip": attr.label( allow_files = True, cfg = "exec", executable = True, - default = "@//tools/genzip:build_zip", + default = ZIP_TOOL_LABEL, ), }, + fragments = ["cpp"], ) + +def _write_java_info_txt_impl(ctx): + info_txt_files = [] + for dep in ctx.attr.deps: + info_txt_files.extend(_write_java_target_info(dep, ctx, custom_prefix = ctx.label.name + ".")) + return DefaultInfo(files = depset(info_txt_files)) + +def collect_dependencies_aspect_for_tests(custom_aspect_impl): + """Creates a custom aspect for use in test code. + + This is used to run the `collect_dependencies` aspect with a custom set of project includes. + It's necessary to create a custom aspect to do this, as when invoking as aspect from a build + rule it's not possible to give arbitrary values to their parameters. + + This is necessary as bazel requires that all aspects are assigned to top level build vars. + + Args: + custom_aspect_impl: A method that invokes `collect_dependencies_for_test` passing the + required set of project includes. This should be defined thus: + + def custom_aspect_impl(target, ctx): + return collect_dependencies_for_test(target, ctx, include=[ + "//package/path/to/include", + ]) + + The `includes` are bazel packages corresponding to the `directories` in a `.bazelproject`. + + Returns: + An aspect for use with `write_java_info_txt_rule_for_tests`. + """ + return aspect( + implementation = custom_aspect_impl, + attr_aspects = FOLLOW_ATTRIBUTES, + provides = [DependenciesInfo], + ) + +def write_java_info_txt_rule_for_tests(aspect_name): + """Create a rule to run the aspect for use in test code. + + This is used in conjunction with `collect_dependencies_aspect_for_tests` to run the collect + dependencies aspect and write the resulting `.java-info.txt` files to an artifact. + + Args: + aspect_name: The name that the return value from `write_java_info_txt_aspect_for_tests` + as written to. + + Returns: + A custom run implementation that should be assigned to a variable inside a `.bzl` file + and them subsequently used thus: + + custom_aspect_rule( + name = "java_info", + deps = [":my_target"], + ) + + This will run the aspect as if an "enable analysis" action was run from the IDE on the + targets given in `deps`. + """ + return rule( + implementation = _write_java_info_txt_impl, + attrs = { + "deps": attr.label_list(aspects = [aspect_name]), + }, + ) diff --git a/aspect/build_dependencies_deps.bzl b/aspect/build_dependencies_deps.bzl new file mode 100644 index 00000000000..8015dea2bc4 --- /dev/null +++ b/aspect/build_dependencies_deps.bzl @@ -0,0 +1,77 @@ +"""Loads and re-exports dependencies of build_dependencies.bzl to support different versions of bazel""" + +load( + "@@bazel_tools//tools/build_defs/cc:action_names.bzl", + _CPP_COMPILE_ACTION_NAME = "CPP_COMPILE_ACTION_NAME", + _C_COMPILE_ACTION_NAME = "C_COMPILE_ACTION_NAME", +) + +ZIP_TOOL_LABEL = "@@bazel_tools//tools/zip:zipper" + +ANDROID_IDE_INFO = None + +# JAVA + +def _get_java_info(target, rule): + if not JavaInfo in target: + return None + p = target[JavaInfo] + return struct( + compile_jars = p.compile_jars, + transitive_compile_time_jars = p.transitive_compile_time_jars, + java_outputs = p.java_outputs, + ) + +IDE_JAVA = struct( + srcs_attributes = ["java_srcs", "java_test_srcs"], + get_java_info = _get_java_info, +) + +# KOTLIN + +def _get_dependency_attribute(rule, attr): + if hasattr(rule.attr, attr): + to_add = getattr(rule.attr, attr) + if type(to_add) == "list": + return [t for t in to_add if type(t) == "Target"] + elif type(to_add) == "Target": + return [to_add] + return [] + +def _get_followed_kotlin_dependencies(rule): + deps = [] + if rule.kind in ["kt_jvm_library_helper", "kt_android_library", "android_library"]: + deps.extend(_get_dependency_attribute(rule, "_toolchain")) + if rule.kind in ["kt_jvm_toolchain"]: + deps.extend(_get_dependency_attribute(rule, "kotlin_libs")) + return deps + +IDE_KOTLIN = struct( + srcs_attributes = [ + "kotlin_srcs", + "kotlin_test_srcs", + "common_srcs", + ], + follow_attributes = [], + follow_additional_attributes = [ + "_toolchain", + "kotlin_libs", + ], + followed_dependencies = _get_followed_kotlin_dependencies, + toolchains_aspects = [], +) + +# CC + +def _get_cc_toolchain_target(rule): + if hasattr(rule.attr, "_cc_toolchain"): + return getattr(rule.attr, "_cc_toolchain") + return None + +IDE_CC = struct( + c_compile_action_name = _C_COMPILE_ACTION_NAME, + cpp_compile_action_name = _CPP_COMPILE_ACTION_NAME, + follow_attributes = ["_cc_toolchain"], + toolchains_aspects = [], + toolchain_target = _get_cc_toolchain_target, +) diff --git a/aspect/fast_build_info.bzl b/aspect/fast_build_info.bzl index db99e951c32..4e40ac3df39 100644 --- a/aspect/fast_build_info.bzl +++ b/aspect/fast_build_info.bzl @@ -10,9 +10,17 @@ load( ":intellij_info_impl.bzl", "stringify_label", ) +load("@intellij_aspect_template//:java_info.bzl", "get_java_info") _DEP_ATTRS = ["deps", "exports", "runtime_deps", "_java_toolchain"] +def _get_android_ide_info(target): + if hasattr(android_common, "AndroidIdeInfo") and android_common.AndroidIdeInfo in target: + return target[android_common.AndroidIdeInfo] + if hasattr(target, "android"): + return target.android + return None + def _fast_build_info_impl(target, ctx): dep_targets = _get_all_dep_targets(target, ctx) dep_outputs = _get_all_dep_outputs(dep_targets) @@ -59,12 +67,16 @@ def _fast_build_info_impl(target, ctx): source_version = toolchain.source_version, target_version = toolchain.target_version, ) - if JavaInfo in target: + java_info = get_java_info(target) + if java_info: write_output = True launcher = None if hasattr(ctx.rule.attr, "use_launcher") and not ctx.rule.attr.use_launcher: launcher = None + elif hasattr(ctx.rule.attr, "launcher") and ctx.rule.attr.launcher: + launcher = stringify_label(ctx.rule.attr.launcher.label) elif hasattr(ctx.rule.attr, "_java_launcher") and ctx.rule.attr._java_launcher: + # TODO: b/295221112 - remove _java_launcher when it's removed from Java rules launcher = stringify_label(ctx.rule.attr._java_launcher.label) elif hasattr(ctx.rule.attr, "_javabase") and ctx.rule.attr._javabase: launcher = stringify_label(ctx.rule.attr._javabase.label) @@ -75,6 +87,7 @@ def _fast_build_info_impl(target, ctx): "launcher": launcher, "swigdeps": getattr(ctx.rule.attr, "swigdeps", True), "jvm_flags": getattr(ctx.rule.attr, "jvm_flags", []), + "main_class": getattr(ctx.rule.attr, "main_class", None), } annotation_processing = target[JavaInfo].annotation_processing if annotation_processing: @@ -84,17 +97,22 @@ def _fast_build_info_impl(target, ctx): for t in annotation_processing.processor_classpath.to_list() ] info["java_info"] = struct_omit_none(**java_info) - if hasattr(target, "android"): + + android_ide_info = _get_android_ide_info(target) + if android_ide_info: write_output = True android_info = struct_omit_none( - aar = artifact_location(target.android.aar), - merged_manifest = artifact_location(target.android.merged_manifest), + aar = artifact_location(android_ide_info.aar), + merged_manifest = artifact_location( + getattr(android_ide_info, "generated_manifest", None) or + getattr(android_ide_info, "merged_manifest", None), + ), ) info["android_info"] = android_info if write_output: output_file = ctx.actions.declare_file(target.label.name + ".ide-fast-build-info.txt") - ctx.actions.write(output_file, struct_omit_none(**info).to_proto()) + ctx.actions.write(output_file, proto.encode_text(struct_omit_none(**info))) output_files += [output_file] output_groups = depset(output_files, transitive = dep_outputs) diff --git a/aspect/flag_hack.bzl b/aspect/flag_hack.bzl new file mode 100644 index 00000000000..8d4494f63e6 --- /dev/null +++ b/aspect/flag_hack.bzl @@ -0,0 +1,32 @@ +##### Begin bazel-flag-hack +# The flag hack stuff below is a way to detect flags that bazel has been invoked with from the +# aspect. Once PY3-as-default is stable, it can be removed. When removing, also remove the +# define_flag_hack() call in BUILD and the "_flag_hack" attr on the aspect below. See +# "PY3-as-default" in: +# https://github.com/bazelbuild/bazel/blob/master/src/main/java/com/google/devtools/build/lib/rules/python/PythonConfiguration.java + +FlagHackInfo = provider(fields = ["incompatible_py2_outputs_are_suffixed"]) + +def _flag_hack_impl(ctx): + return [FlagHackInfo(incompatible_py2_outputs_are_suffixed = ctx.attr.incompatible_py2_outputs_are_suffixed)] + +_flag_hack_rule = rule( + attrs = {"incompatible_py2_outputs_are_suffixed": attr.bool()}, + implementation = _flag_hack_impl, +) + +def define_flag_hack(): + native.config_setting( + name = "incompatible_py2_outputs_are_suffixed_setting", + values = {"incompatible_py2_outputs_are_suffixed": "true"}, + ) + _flag_hack_rule( + name = "flag_hack", + incompatible_py2_outputs_are_suffixed = select({ + ":incompatible_py2_outputs_are_suffixed_setting": True, + "//conditions:default": False, + }), + visibility = ["//visibility:public"], + ) + +##### End bazel-flag-hack diff --git a/aspect/intellij_info.bzl b/aspect/intellij_info.bzl index 54a2be601b9..652b83c95a4 100644 --- a/aspect/intellij_info.bzl +++ b/aspect/intellij_info.bzl @@ -8,6 +8,8 @@ load( EXTRA_DEPS = [ "embed", # From go rules (bazel only) + "_cc_toolchain", # From rules_cc (bazel only) + "_kt_toolchain", # From rules_kotlin (bazel only) ] def tool_label(tool_name): diff --git a/aspect/intellij_info_impl.bzl b/aspect/intellij_info_impl.bzl index dbb2e8da9ef..19fd46e40c7 100644 --- a/aspect/intellij_info_impl.bzl +++ b/aspect/intellij_info_impl.bzl @@ -1,5 +1,9 @@ """Implementation of IntelliJ-specific information collecting aspect.""" +load( + "@bazel_tools//tools/build_defs/cc:action_names.bzl", + "ACTION_NAMES", +) load( ":artifacts.bzl", "artifact_location", @@ -9,11 +13,29 @@ load( "struct_omit_none", "to_artifact_location", ) +load(":flag_hack.bzl", "FlagHackInfo") + +load("@intellij_aspect_template//:java_info.bzl", "get_java_info", "java_info_in_target", "java_info_reference") + +load("@intellij_aspect_template//:python_info.bzl", "get_py_info", "py_info_in_target") + +load("@intellij_aspect_template//:code_generator_info.bzl", "CODE_GENERATOR_RULE_NAMES") + load( ":make_variables.bzl", "expand_make_variables", ) +IntelliJInfo = provider( + doc = "Collected information about the targets visited by the aspect.", + fields = [ + "export_deps", + "kind", + "output_groups", + "target_key", + ], +) + # Defensive list of features that can appear in the C++ toolchain, but which we # definitely don't want to enable (when enabled, they'd contribute command line # flags that don't make sense in the context of intellij info). @@ -27,9 +49,9 @@ UNSUPPORTED_FEATURES = [ # Compile-time dependency attributes, grouped by type. DEPS = [ - "_cc_toolchain", # From cc rules "_stl", # From cc rules "malloc", # From cc_binary rules + "implementation_deps", # From cc_library rules "_java_toolchain", # From java rules "deps", "jars", # from java_import rules @@ -42,6 +64,7 @@ DEPS = [ "instruments", # android_instrumentation_test "tests", # From test_suite "compilers", # From go_proto_library + "associates", # From kotlin rules ] # Run-time dependency attributes, grouped by type. @@ -61,39 +84,6 @@ PY2 = 1 PY3 = 2 -##### Begin bazel-flag-hack -# The flag hack stuff below is a way to detect flags that bazel has been invoked with from the -# aspect. Once PY3-as-default is stable, it can be removed. When removing, also remove the -# define_flag_hack() call in BUILD and the "_flag_hack" attr on the aspect below. See -# "PY3-as-default" in: -# https://github.com/bazelbuild/bazel/blob/master/src/main/java/com/google/devtools/build/lib/rules/python/PythonConfiguration.java - -FlagHackInfo = provider(fields = ["incompatible_py2_outputs_are_suffixed"]) - -def _flag_hack_impl(ctx): - return [FlagHackInfo(incompatible_py2_outputs_are_suffixed = ctx.attr.incompatible_py2_outputs_are_suffixed)] - -_flag_hack_rule = rule( - attrs = {"incompatible_py2_outputs_are_suffixed": attr.bool()}, - implementation = _flag_hack_impl, -) - -def define_flag_hack(): - native.config_setting( - name = "incompatible_py2_outputs_are_suffixed_setting", - values = {"incompatible_py2_outputs_are_suffixed": "true"}, - ) - _flag_hack_rule( - name = "flag_hack", - incompatible_py2_outputs_are_suffixed = select({ - ":incompatible_py2_outputs_are_suffixed_setting": True, - "//conditions:default": False, - }), - visibility = ["//visibility:public"], - ) - -##### End bazel-flag-hack - # PythonCompatVersion enum; must match PyIdeInfo.PythonSrcsVersion SRC_PY2 = 1 @@ -107,6 +97,27 @@ SRC_PY3ONLY = 5 ##### Helpers +def get_code_generator_rule_names(ctx, language_name): + """Supplies a list of Rule names for code generation for the language specified + + For some languages, it is possible to specify Rules' names that are interpreted as + code-generators for the language. These Rules' names are specified as attrs and are provided to + the aspect using the `AspectStrategy#AspectParameter` in the plugin logic. + """ + + if not language_name: + fail("the `language_name` must be provided") + + if hasattr(CODE_GENERATOR_RULE_NAMES, language_name): + return getattr(CODE_GENERATOR_RULE_NAMES, language_name) + + return [] + +def get_registry_flag(ctx, name): + """Registry flags are passed to aspects using defines. See CppAspectArgsProvider.""" + + return ctx.var.get(name) == "true" + def source_directory_tuple(resource_file): """Creates a tuple of (exec_path, root_exec_path_fragment, is_source, is_external).""" relative_path = str(android_common.resource_source_directory(resource_file)) @@ -137,15 +148,21 @@ def get_res_artifacts(resources): def build_file_artifact_location(ctx): """Creates an ArtifactLocation proto representing a location of a given BUILD file.""" return to_artifact_location( - ctx.build_file_path, - ctx.build_file_path, + ctx.label.package + "/BUILD", + ctx.label.package + "/BUILD", True, is_external_artifact(ctx.label), ) +# https://github.com/bazelbuild/bazel/issues/18966 +def _list_or_depset_to_list(list_or_depset): + if hasattr(list_or_depset, "to_list"): + return list_or_depset.to_list() + return list_or_depset + def get_source_jars(output): if hasattr(output, "source_jars"): - return output.source_jars + return _list_or_depset_to_list(output.source_jars) if hasattr(output, "source_jar"): return [output.source_jar] return [] @@ -181,9 +198,10 @@ def jars_from_output(output): """Collect jars for intellij-resolve-files from Java output.""" if output == None: return [] + source_jars = get_source_jars(output) return [ jar - for jar in ([output.class_jar, output.ijar] + get_source_jars(output)) + for jar in ([output.ijar if len(source_jars) > 0 and output.ijar else output.class_jar] + source_jars) if jar != None and not jar.is_source ] @@ -205,21 +223,23 @@ def collect_targets_from_attrs(rule_attrs, attrs): _collect_target_from_attr(rule_attrs, attr_name, result) return [target for target in result if is_valid_aspect_target(target)] +def targets_to_labels(targets): + """Returns a set of label strings for the given targets.""" + return depset([str(target.label) for target in targets]) + def list_omit_none(value): """Returns a list of the value, or the empty list if None.""" return [value] if value else [] def is_valid_aspect_target(target): """Returns whether the target has had the aspect run on it.""" - return hasattr(target, "intellij_info") + return IntelliJInfo in target -def get_aspect_ids(ctx, target): +def get_aspect_ids(ctx): """Returns the all aspect ids, filtering out self.""" aspect_ids = None if hasattr(ctx, "aspect_ids"): aspect_ids = ctx.aspect_ids - elif hasattr(target, "aspect_ids"): - aspect_ids = target.aspect_ids else: return None return [aspect_id for aspect_id in aspect_ids if "intellij_info_aspect" not in aspect_id] @@ -228,7 +248,7 @@ def _is_language_specific_proto_library(ctx, target, semantics): """Returns True if the target is a proto library with attached language-specific aspect.""" if ctx.rule.kind != "proto_library": return False - if JavaInfo in target: + if java_info_in_target(target): return True if CcInfo in target: return True @@ -255,7 +275,7 @@ def make_dep(dep, dependency_type): """Returns a Dependency proto struct.""" return struct( dependency_type = dependency_type, - target = dep.intellij_info.target_key, + target = dep[IntelliJInfo].target_key, ) def make_deps(deps, dependency_type): @@ -290,7 +310,7 @@ def update_set_in_dict(input_dict, key, other_set): def _get_output_mnemonic(ctx): """Gives the output directory mnemonic for some target context.""" - return ctx.configuration.bin_dir.path.split("/")[1] + return ctx.bin_dir.path.split("/")[1] def _get_python_version(ctx): if ctx.attr._flag_hack[FlagHackInfo].incompatible_py2_outputs_are_suffixed: @@ -327,7 +347,7 @@ def _do_starlark_string_expansion(ctx, name, strings, extra_targets = []): def collect_py_info(target, ctx, semantics, ide_info, ide_info_file, output_groups): """Updates Python-specific output groups, returns false if not a Python target.""" - if not PyInfo in target or _is_language_specific_proto_library(ctx, target, semantics): + if not py_info_in_target(target) or _is_language_specific_proto_library(ctx, target, semantics): return False py_semantics = getattr(semantics, "py", None) @@ -337,10 +357,68 @@ def collect_py_info(target, ctx, semantics, ide_info, ide_info_file, output_grou py_launcher = None sources = sources_from_target(ctx) - to_build = target[PyInfo].transitive_sources + to_build = get_py_info(target).transitive_sources args = getattr(ctx.rule.attr, "args", []) data_deps = getattr(ctx.rule.attr, "data", []) args = _do_starlark_string_expansion(ctx, "args", args, data_deps) + imports = getattr(ctx.rule.attr, "imports", []) + is_code_generator = False + + # If there are apparently no sources found from `srcs` and the target has a rule name which is + # one of the ones pre-specified to the aspect as being a code-generator for Python then + # interpret the outputs of the target specified in the PyInfo as being sources. + + if 0 == len(sources) and ctx.rule.kind in get_code_generator_rule_names(ctx, "python"): + def provider_import_to_attr_import(provider_import): + """\ + Remaps the imports from PyInfo + + The imports that are supplied on the `PyInfo` are relative to the runfiles and so are + not the same as those which might be supplied on an attribute of `py_library`. This + function will remap those back so they look as if they were `imports` attributes on + the rule. The form of the runfiles import is `//`. + The actual `workspace_name` is not interesting such that the first part can be simply + stripped. Next the package to the Label is stripped leaving a path that would have been + supplied on an `imports` attribute to a Rule. + """ + + # Other code in this file appears to assume *NIX path component separators? + + provider_import_parts = [p for p in provider_import.split("/")] + package_parts = [p for p in ctx.label.package.split("/")] + + if 0 == len(provider_import_parts): + return None + + scratch_parts = provider_import_parts[1:] # remove the workspace name or _main + + for p in package_parts: + if 0 != len(provider_import_parts) and scratch_parts[0] == p: + scratch_parts = scratch_parts[1:] + else: + return None + + return "/".join(scratch_parts) + + def provider_imports_to_attr_imports(): + result = [] + + for provider_import in get_py_info(target).imports.to_list(): + attr_import = provider_import_to_attr_import(provider_import) + if attr_import: + result.append(attr_import) + + return result + + if get_py_info(target).imports: + imports.extend(provider_imports_to_attr_imports()) + + runfiles = target[DefaultInfo].default_runfiles + + if runfiles and runfiles.files: + sources.extend([artifact_location(f) for f in runfiles.files.to_list()]) + + is_code_generator = True ide_info["py_ide_info"] = struct_omit_none( launcher = py_launcher, @@ -348,6 +426,8 @@ def collect_py_info(target, ctx, semantics, ide_info, ide_info_file, output_grou sources = sources, srcs_version = _get_python_srcs_version(ctx), args = args, + imports = imports, + is_code_generator = is_code_generator, ) update_sync_output_groups(output_groups, "intellij-info-py", depset([ide_info_file])) @@ -366,18 +446,21 @@ def collect_go_info(target, ctx, semantics, ide_info, ide_info_file, output_grou """Updates Go-specific output groups, returns false if not a recognized Go target.""" sources = [] generated = [] + cgo = False # currently there's no Go Skylark API, with the only exception being proto_library targets if ctx.rule.kind in [ "go_binary", "go_library", "go_test", + "go_source", "go_appengine_binary", "go_appengine_library", "go_appengine_test", ]: sources = [f for src in getattr(ctx.rule.attr, "srcs", []) for f in src.files.to_list()] generated = [f for f in sources if not f.is_source] + cgo = getattr(ctx.rule.attr, "cgo", False) elif ctx.rule.kind == "go_wrap_cc": genfiles = target.files.to_list() go_genfiles = [f for f in genfiles if f.basename.endswith(".go")] @@ -400,16 +483,23 @@ def collect_go_info(target, ctx, semantics, ide_info, ide_info_file, output_grou import_path = go_semantics.get_import_path(ctx) library_labels = [] - if ctx.rule.kind == "go_test" or ctx.rule.kind == "go_appengine_test": + if ctx.rule.kind in ("go_test", "go_library", "go_appengine_test"): if getattr(ctx.rule.attr, "library", None) != None: library_labels = [stringify_label(ctx.rule.attr.library.label)] elif getattr(ctx.rule.attr, "embed", None) != None: - library_labels = [stringify_label(library.label) for library in ctx.rule.attr.embed] + for library in ctx.rule.attr.embed: + if library[IntelliJInfo].kind == "go_source" or library[IntelliJInfo].kind == "go_proto_library": + l = library[IntelliJInfo].output_groups["intellij-sources-go-outputs"].to_list() + sources += l + generated += [f for f in l if not f.is_source] + else: + library_labels.append(stringify_label(library.label)) ide_info["go_ide_info"] = struct_omit_none( import_path = import_path, library_labels = library_labels, sources = [artifact_location(f) for f in sources], + cgo = cgo, ) compile_files = target[OutputGroupInfo].compilation_outputs if hasattr(target[OutputGroupInfo], "compilation_outputs") else depset([]) @@ -418,6 +508,7 @@ def collect_go_info(target, ctx, semantics, ide_info, ide_info_file, output_grou update_sync_output_groups(output_groups, "intellij-info-go", depset([ide_info_file])) update_sync_output_groups(output_groups, "intellij-compile-go", compile_files) update_sync_output_groups(output_groups, "intellij-resolve-go", depset(generated)) + update_sync_output_groups(output_groups, "intellij-sources-go", depset(sources)) return True def collect_cpp_info(target, ctx, semantics, ide_info, ide_info_file, output_groups): @@ -441,13 +532,27 @@ def collect_cpp_info(target, ctx, semantics, ide_info, ide_info_file, output_gro target_copts = [] if hasattr(ctx.rule.attr, "copts"): target_copts += ctx.rule.attr.copts + extra_targets = [] + if hasattr(ctx.rule.attr, "additional_compiler_inputs"): + extra_targets += ctx.rule.attr.additional_compiler_inputs if hasattr(semantics, "cc") and hasattr(semantics.cc, "get_default_copts"): target_copts += semantics.cc.get_default_copts(ctx) - target_copts = _do_starlark_string_expansion(ctx, "copt", target_copts) + target_copts = _do_starlark_string_expansion(ctx, "copt", target_copts, extra_targets) compilation_context = target[CcInfo].compilation_context + # Merge current compilation context with context of implementation dependencies. + if hasattr(ctx.rule.attr, "implementation_deps"): + implementation_deps = ctx.rule.attr.implementation_deps + compilation_context = cc_common.merge_compilation_contexts( + compilation_contexts = + [compilation_context] + [impl[CcInfo].compilation_context for impl in implementation_deps], + ) + + # external_includes available since bazel 7 + external_includes = getattr(compilation_context, "external_includes", depset()).to_list() + c_info = struct_omit_none( header = headers, source = sources, @@ -456,7 +561,10 @@ def collect_cpp_info(target, ctx, semantics, ide_info, ide_info_file, output_gro transitive_define = compilation_context.defines.to_list(), transitive_include_directory = compilation_context.includes.to_list(), transitive_quote_include_directory = compilation_context.quote_includes.to_list(), - transitive_system_include_directory = compilation_context.system_includes.to_list(), + # both system and external includes are add using `-isystem` + transitive_system_include_directory = compilation_context.system_includes.to_list() + external_includes, + include_prefix = getattr(ctx.rule.attr, "include_prefix", None), + strip_include_prefix = getattr(ctx.rule.attr, "strip_include_prefix", None), ) ide_info["c_ide_info"] = c_info resolve_files = compilation_context.headers @@ -489,57 +597,56 @@ def collect_c_toolchain_info(target, ctx, semantics, ide_info, ide_info_file, ou # cpp fragment to access bazel options cpp_fragment = ctx.fragments.cpp - # Enabled in Bazel 0.16 - if hasattr(cc_common, "get_memory_inefficient_command_line"): - # Enabled in Bazel 0.17 - if hasattr(cpp_fragment, "copts"): - copts = cpp_fragment.copts - cxxopts = cpp_fragment.cxxopts - conlyopts = cpp_fragment.conlyopts - else: - copts = [] - cxxopts = [] - conlyopts = [] - feature_configuration = cc_common.configure_features( - ctx = ctx, - cc_toolchain = cpp_toolchain, - requested_features = ctx.features, - unsupported_features = ctx.disabled_features + UNSUPPORTED_FEATURES, - ) - c_variables = cc_common.create_compile_variables( - feature_configuration = feature_configuration, - cc_toolchain = cpp_toolchain, - user_compile_flags = copts + conlyopts, - ) - cpp_variables = cc_common.create_compile_variables( - feature_configuration = feature_configuration, - cc_toolchain = cpp_toolchain, - add_legacy_cxx_options = True, - user_compile_flags = copts + cxxopts, - ) - c_options = cc_common.get_memory_inefficient_command_line( + copts = cpp_fragment.copts + cxxopts = cpp_fragment.cxxopts + conlyopts = cpp_fragment.conlyopts + + feature_configuration = cc_common.configure_features( + ctx = ctx, + cc_toolchain = cpp_toolchain, + requested_features = ctx.features, + unsupported_features = ctx.disabled_features + UNSUPPORTED_FEATURES, + ) + c_variables = cc_common.create_compile_variables( + feature_configuration = feature_configuration, + cc_toolchain = cpp_toolchain, + user_compile_flags = copts + conlyopts, + ) + cpp_variables = cc_common.create_compile_variables( + feature_configuration = feature_configuration, + cc_toolchain = cpp_toolchain, + user_compile_flags = copts + cxxopts, + ) + c_options = cc_common.get_memory_inefficient_command_line( + feature_configuration = feature_configuration, + action_name = ACTION_NAMES.c_compile, + variables = c_variables, + ) + cpp_options = cc_common.get_memory_inefficient_command_line( + feature_configuration = feature_configuration, + action_name = ACTION_NAMES.cpp_compile, + variables = cpp_variables, + ) + + if (get_registry_flag(ctx, "_cpp_use_get_tool_for_action")): + c_compiler = cc_common.get_tool_for_action( feature_configuration = feature_configuration, - # TODO(#391): Use constants from action_names.bzl - action_name = "c-compile", - variables = c_variables, + action_name = ACTION_NAMES.c_compile, ) - cpp_options = cc_common.get_memory_inefficient_command_line( + cpp_compiler = cc_common.get_tool_for_action( feature_configuration = feature_configuration, - # TODO(#391): Use constants from action_names.bzl - action_name = "c++-compile", - variables = cpp_variables, + action_name = ACTION_NAMES.cpp_compile, ) else: - # See the plugin's BazelVersionChecker. We should have checked that we are Bazel 0.16+, - # so get_memory_inefficient_command_line should be available. - c_options = [] - cpp_options = [] + c_compiler = str(cpp_toolchain.compiler_executable) + cpp_compiler = str(cpp_toolchain.compiler_executable) c_toolchain_info = struct_omit_none( built_in_include_directory = [str(d) for d in cpp_toolchain.built_in_include_directories], c_option = c_options, - cpp_executable = str(cpp_toolchain.compiler_executable), cpp_option = cpp_options, + c_compiler = c_compiler, + cpp_compiler = cpp_compiler, target_name = cpp_toolchain.target_gnu_system_name, ) ide_info["c_toolchain_ide_info"] = c_toolchain_info @@ -549,15 +656,14 @@ def collect_c_toolchain_info(target, ctx, semantics, ide_info, ide_info_file, ou def get_java_provider(target): """Find a provider exposing java compilation/outputs data.""" - # Check for scala and kt providers before JavaInfo. e.g. scala targets have - # JavaInfo, but their data lives in the "scala" provider and not JavaInfo. + # Check for kt providers before JavaInfo. e.g. kt targets have + # JavaInfo, but their data lives in the "kt" provider and not JavaInfo. # See https://github.com/bazelbuild/intellij/pull/1202 - if hasattr(target, "scala"): - return target.scala if hasattr(target, "kt") and hasattr(target.kt, "outputs"): return target.kt - if JavaInfo in target: - return target[JavaInfo] + java_info = get_java_info(target) + if java_info: + return java_info if hasattr(java_common, "JavaPluginInfo") and java_common.JavaPluginInfo in target: return target[java_common.JavaPluginInfo] return None @@ -635,7 +741,7 @@ def collect_java_info(target, ctx, semantics, ide_info, ide_info_file, output_gr package_manifest = None if java_sources: package_manifest = build_java_package_manifest(ctx, target, java_sources, ".java-manifest") - ide_info_files += [package_manifest] + ide_info_files.append(package_manifest) filtered_gen_jar = None if java_sources and (gen_java_sources or srcjars): @@ -675,7 +781,7 @@ def collect_java_info(target, ctx, semantics, ide_info, ide_info_file, output_gr ) ide_info["java_ide_info"] = java_info - ide_info_files += [ide_info_file] + ide_info_files.append(ide_info_file) update_sync_output_groups(output_groups, "intellij-info-java", depset(ide_info_files)) update_sync_output_groups(output_groups, "intellij-compile-java", depset(compile_files)) update_sync_output_groups(output_groups, "intellij-resolve-java", depset(resolve_files)) @@ -687,8 +793,9 @@ def collect_java_info(target, ctx, semantics, ide_info, ide_info_file, output_gr return True def _android_lint_plugin_jars(target): - if JavaInfo in target: - return target[JavaInfo].transitive_runtime_jars.to_list() + java_info = get_java_info(target) + if java_info: + return java_info.transitive_runtime_jars.to_list() else: return [] @@ -745,10 +852,13 @@ def _build_filtered_gen_jar(ctx, target, java_outputs, gen_java_sources, srcjars elif jar.class_jar: jar_artifacts.append(jar.class_jar) if hasattr(jar, "source_jars") and jar.source_jars: - source_jar_artifacts.extend(jar.source_jars) + source_jar_artifacts.extend(_list_or_depset_to_list(jar.source_jars)) elif hasattr(jar, "source_jar") and jar.source_jar: source_jar_artifacts.append(jar.source_jar) + if len(source_jar_artifacts) == 0 or len(jar_artifacts) == 0: + jar_artifacts.extend([jar.class_jar for jar in java_outputs if jar.class_jar]) + filtered_jar = ctx.actions.declare_file(target.label.name + "-filtered-gen.jar") filtered_source_jar = ctx.actions.declare_file(target.label.name + "-filtered-gen-src.jar") args = [] @@ -814,17 +924,47 @@ def collect_android_info(target, ctx, semantics, ide_info, ide_info_file, output return handled def _collect_android_ide_info(target, ctx, semantics, ide_info, ide_info_file, output_groups): - """Updates ide_info proto with android_ide_info, and intellij_resolve_android with android resolve files. Returns false if target doesn't contain android attribute.""" - if not hasattr(target, "android"): + """Populates ide_info proto and intellij_resolve_android output group + + Updates ide_info proto with android_ide_info, and intellij_resolve_android with android + resolve files. It returns false on android_library and android_binary targets, as this preserves + consistent functionality with the previous condition of the presence of the .android legacy + provider. + """ + if ctx.rule.kind not in ["android_library", "android_binary", "kt_android_library"]: return False android_semantics = semantics.android if hasattr(semantics, "android") else None extra_ide_info = android_semantics.extra_ide_info(target, ctx) if android_semantics else {} - android = target.android + if hasattr(android_common, "AndroidIdeInfo"): + android = target[android_common.AndroidIdeInfo] + else: + # Backwards compatibility: supports android struct provider + legacy_android = getattr(target, "android") + + # Transform into AndroidIdeInfo form + android = struct( + java_package = legacy_android.java_package, + manifest = legacy_android.manifest, + idl_source_jar = getattr(legacy_android.idl.output, "source_jar", None), + idl_class_jar = getattr(legacy_android.idl.output, "class_jar", None), + defines_android_resources = legacy_android.defines_resources, + idl_import_root = getattr(legacy_android.idl, "import_root", None), + resource_jar = legacy_android.resource_jar, + signed_apk = legacy_android.apk, + apks_under_test = legacy_android.apks_under_test, + ) + + output_jar = struct( + class_jar = android.idl_class_jar, + ijar = None, + source_jar = android.idl_source_jar, + ) if android.idl_class_jar else None + resources = [] res_folders = [] - resolve_files = jars_from_output(android.idl.output) + resolve_files = jars_from_output(output_jar) if hasattr(ctx.rule.attr, "resource_files"): for artifact_path_fragments, res_files in get_res_artifacts(ctx.rule.attr.resource_files).items(): # Generate unique ArtifactLocation for resource directories. @@ -874,14 +1014,14 @@ def _collect_android_ide_info(target, ctx, semantics, ide_info, ide_info_file, o android_info = struct_omit_none( java_package = android.java_package, - idl_import_root = android.idl.import_root if hasattr(android.idl, "import_root") else None, + idl_import_root = getattr(android, "idl_import_root", None), manifest = artifact_location(android.manifest), manifest_values = [struct_omit_none(key = key, value = value) for key, value in ctx.rule.attr.manifest_values.items()] if hasattr(ctx.rule.attr, "manifest_values") else None, - apk = artifact_location(android.apk), + apk = artifact_location(android.signed_apk), dependency_apk = [artifact_location(apk) for apk in android.apks_under_test], - has_idl_sources = android.idl.output != None, - idl_jar = library_artifact(android.idl.output), - generate_resource_class = android.defines_resources, + has_idl_sources = android.idl_class_jar != None, + idl_jar = library_artifact(output_jar), + generate_resource_class = android.defines_android_resources, resources = resources, res_folders = res_folders, resource_jar = library_artifact(android.resource_jar), @@ -891,7 +1031,7 @@ def _collect_android_ide_info(target, ctx, semantics, ide_info, ide_info_file, o ) if android.manifest and not android.manifest.is_source: - resolve_files += [android.manifest] + resolve_files.append(android.manifest) # b/176209293: expose resource jar to make sure empty library # knows they are remote output artifact @@ -977,17 +1117,21 @@ def collect_java_toolchain_info(target, ide_info, ide_info_file, output_groups): def artifact_to_path(artifact): return artifact.root_execution_path_fragment + "/" + artifact.relative_path -def collect_kotlin_toolchain_info(target, ide_info, ide_info_file, output_groups): +def collect_kotlin_toolchain_info(target, ctx, ide_info, ide_info_file, output_groups): """Updates kotlin_toolchain-relevant output groups, returns false if not a kotlin_toolchain target.""" - if not hasattr(target, "kt"): + if ctx.rule.kind == "_kt_toolchain" and platform_common.ToolchainInfo in target: + kt = target[platform_common.ToolchainInfo] + elif hasattr(target, "kt") and hasattr(target.kt, "language_version"): + kt = target.kt # Legacy struct provider mechanism + else: return False - kt = target.kt + if not hasattr(kt, "language_version"): return False ide_info["kt_toolchain_ide_info"] = struct( language_version = kt.language_version, ) - update_sync_output_groups(output_groups, "intellij-info-kotlin", depset([ide_info_file])) + update_sync_output_groups(output_groups, "intellij-info-kt", depset([ide_info_file])) return True def _is_proto_library_wrapper(target, ctx): @@ -997,7 +1141,7 @@ def _is_proto_library_wrapper(target, ctx): # treat any *proto_library rule with a single proto_library dep as a shim deps = collect_targets_from_attrs(ctx.rule.attr, ["deps"]) - return len(deps) == 1 and deps[0].intellij_info and deps[0].intellij_info.kind == "proto_library" + return len(deps) == 1 and IntelliJInfo in deps[0] and deps[0][IntelliJInfo].kind == "proto_library" def _get_forwarded_deps(target, ctx): """Returns the list of deps of this target to forward. @@ -1036,12 +1180,22 @@ def intellij_info_aspect_impl(target, ctx, semantics): rule_attrs, semantics_extra_deps(DEPS, semantics, "extra_deps"), ) + + # Collect direct toolchain type-based dependencies + if hasattr(semantics, "toolchains_propagation"): + direct_dep_targets.extend( + semantics.toolchains_propagation.collect_toolchain_deps( + ctx, + semantics.toolchains_propagation.toolchain_types, + ), + ) + direct_deps = make_deps(direct_dep_targets, COMPILE_TIME) # Add exports from direct dependencies exported_deps_from_deps = [] for dep in direct_dep_targets: - exported_deps_from_deps = exported_deps_from_deps + dep.intellij_info.export_deps + exported_deps_from_deps = exported_deps_from_deps + dep[IntelliJInfo].export_deps # Combine into all compile time deps compiletime_deps = direct_deps + exported_deps_from_deps @@ -1049,15 +1203,15 @@ def intellij_info_aspect_impl(target, ctx, semantics): # Propagate my own exports export_deps = [] direct_exports = [] - if JavaInfo in target: + if java_info_in_target(target): direct_exports = collect_targets_from_attrs(rule_attrs, ["exports"]) export_deps.extend(make_deps(direct_exports, COMPILE_TIME)) # Collect transitive exports for export in direct_exports: - export_deps.extend(export.intellij_info.export_deps) + export_deps.extend(export[IntelliJInfo].export_deps) - if ctx.rule.kind == "android_library": + if ctx.rule.kind == "android_library" or ctx.rule.kind == "kt_android_library": # Empty android libraries export all their dependencies. if not hasattr(rule_attrs, "srcs") or not ctx.rule.attr.srcs: export_deps.extend(compiletime_deps) @@ -1085,7 +1239,7 @@ def intellij_info_aspect_impl(target, ctx, semantics): prerequisites = direct_dep_targets + runtime_dep_targets + extra_prerequisite_targets + direct_exports output_groups = dict() for dep in prerequisites: - for k, v in dep.intellij_info.output_groups.items(): + for k, v in dep[IntelliJInfo].output_groups.items(): if dep in forwarded_deps: # unconditionally roll up deps for these targets output_groups[k] = output_groups[k] + [v] if k in output_groups else [v] @@ -1115,7 +1269,7 @@ def intellij_info_aspect_impl(target, ctx, semantics): # bazel allows target names differing only by case, so append a hash to support # case-insensitive file systems file_name = file_name + "-" + str(hash(file_name)) - aspect_ids = get_aspect_ids(ctx, target) + aspect_ids = get_aspect_ids(ctx) if aspect_ids: aspect_hash = hash(".".join(aspect_ids)) file_name = file_name + "-" + str(aspect_hash) @@ -1143,7 +1297,7 @@ def intellij_info_aspect_impl(target, ctx, semantics): handled = collect_java_info(target, ctx, semantics, ide_info, ide_info_file, output_groups) or handled handled = collect_java_toolchain_info(target, ide_info, ide_info_file, output_groups) or handled handled = collect_android_info(target, ctx, semantics, ide_info, ide_info_file, output_groups) or handled - handled = collect_kotlin_toolchain_info(target, ide_info, ide_info_file, output_groups) or handled + handled = collect_kotlin_toolchain_info(target, ctx, ide_info, ide_info_file, output_groups) or handled # Any extra ide info if hasattr(semantics, "extra_ide_info"): @@ -1155,18 +1309,18 @@ def intellij_info_aspect_impl(target, ctx, semantics): # Output the ide information file. info = struct_omit_none(**ide_info) - ctx.actions.write(ide_info_file, info.to_proto()) + ctx.actions.write(ide_info_file, proto.encode_text(info)) # Return providers. - return struct_omit_none( - intellij_info = struct( + return [ + IntelliJInfo( export_deps = export_deps, kind = ctx.rule.kind, output_groups = output_groups, target_key = target_key, ), - output_groups = output_groups, - ) + OutputGroupInfo(**output_groups), + ] def semantics_extra_deps(base, semantics, name): if not hasattr(semantics, name): @@ -1174,7 +1328,7 @@ def semantics_extra_deps(base, semantics, name): extra_deps = getattr(semantics, name) return base + extra_deps -def make_intellij_info_aspect(aspect_impl, semantics): +def make_intellij_info_aspect(aspect_impl, semantics, **kwargs): """Creates the aspect given the semantics.""" tool_label = semantics.tool_label flag_hack_label = semantics.flag_hack_label @@ -1216,6 +1370,7 @@ def make_intellij_info_aspect(aspect_impl, semantics): attr_aspects = attr_aspects, attrs = attrs, fragments = ["cpp"], - required_aspect_providers = [[JavaInfo], [CcInfo], ["dart"]] + semantics.extra_required_aspect_providers, + required_aspect_providers = [java_info_reference(), [CcInfo]] + semantics.extra_required_aspect_providers, implementation = aspect_impl, + **kwargs ) diff --git a/aspect/java_classpath.bzl b/aspect/java_classpath.bzl index be3dfb648c6..789b622514e 100644 --- a/aspect/java_classpath.bzl +++ b/aspect/java_classpath.bzl @@ -1,5 +1,7 @@ """An aspect which extracts the runtime classpath from a java target.""" +load("@intellij_aspect_template//:java_info.bzl", "get_java_info", "java_info_in_target") + def _runtime_classpath_impl(target, ctx): """The top level aspect implementation function. @@ -18,15 +20,16 @@ def _runtime_classpath_impl(target, ctx): }) def _get_runtime_jars(target): - if JavaInfo not in target: + java_info = get_java_info(target) + if not java_info: return depset() - if target[JavaInfo].compilation_info: - return target[JavaInfo].compilation_info.runtime_classpath + if java_info.compilation_info: + return java_info.compilation_info.runtime_classpath # JavaInfo constructor doesn't fill in compilation info, so just return the # full transitive set of runtime jars # https://github.com/bazelbuild/bazel/issues/10170 - return target[JavaInfo].transitive_runtime_jars + return java_info.transitive_runtime_jars def _aspect_def(impl): return aspect(implementation = impl) diff --git a/aspect/testing/BUILD b/aspect/testing/BUILD index 3c237657221..b4831afd6e1 100644 --- a/aspect/testing/BUILD +++ b/aspect/testing/BUILD @@ -1,5 +1,7 @@ # Integration tests for the plugin's Skylark aspect +load("@rules_java//java:defs.bzl", "java_library") + licenses(["notice"]) # To prevent versioning conflicts when developing internally, we always use the same diff --git a/aspect/testing/rules/BUILD b/aspect/testing/rules/BUILD index 7053c7a1e08..88401028b64 100644 --- a/aspect/testing/rules/BUILD +++ b/aspect/testing/rules/BUILD @@ -1,5 +1,8 @@ # Testing infrastructure for the plugin's Skylark aspect +load("@protobuf//bazel:java_proto_library.bzl", "java_proto_library") +load("@protobuf//bazel:proto_library.bzl", "proto_library") +load("@rules_java//java:defs.bzl", "java_binary", "java_library") load( "//:build-visibility.bzl", "ASPECT_TEST_RULES_VISIBILITY_TO_ALL", @@ -29,7 +32,7 @@ java_binary( ":intellij_aspect_test_fixture_java_proto", "//aspect/testing:guava", "//proto:intellij_ide_info_java_proto", - "@com_google_protobuf//:protobuf_java", + "@protobuf//:protobuf_java", ], ) @@ -44,7 +47,7 @@ java_library( "//intellij_platform_sdk:jsr305", "//proto:common_java_proto", "//proto:intellij_ide_info_java_proto", - "@junit//jar", + "//third_party/java/junit", ], ) @@ -71,7 +74,7 @@ java_binary( ":fast_build_aspect_test_fixture_java_proto", "//aspect/testing:guava", "//proto:fast_build_info_java_proto", - "@com_google_protobuf//:protobuf_java", + "@protobuf//:protobuf_java", ], ) @@ -83,6 +86,6 @@ java_library( deps = [ ":fast_build_aspect_test_fixture_java_proto", "//aspect/testing:guava", - "@junit//jar", + "//third_party/java/junit", ], ) diff --git a/aspect/testing/rules/fast_build_aspect_test_fixture.bzl b/aspect/testing/rules/fast_build_aspect_test_fixture.bzl index a5fabc0a7ad..6db5767419f 100644 --- a/aspect/testing/rules/fast_build_aspect_test_fixture.bzl +++ b/aspect/testing/rules/fast_build_aspect_test_fixture.bzl @@ -29,7 +29,7 @@ def _impl(ctx): mnemonic = "FastBuildAspectTestFixtureBuilder", progress_message = "Building Fast Build Aspect Test Fixture", ) - return struct( + return DefaultInfo( files = depset([output]), runfiles = ctx.runfiles( files = [output], diff --git a/aspect/testing/rules/fast_build_aspect_test_fixture.proto b/aspect/testing/rules/fast_build_aspect_test_fixture.proto index 47b5d51cc99..5ea4fe91eee 100644 --- a/aspect/testing/rules/fast_build_aspect_test_fixture.proto +++ b/aspect/testing/rules/fast_build_aspect_test_fixture.proto @@ -22,4 +22,4 @@ option java_package = "com.google.devtools.intellij.aspect"; message FastBuildAspectTestFixture { repeated FastBuildBlazeData target = 1; -} +} \ No newline at end of file diff --git a/aspect/testing/rules/intellij_aspect_test_fixture.bzl b/aspect/testing/rules/intellij_aspect_test_fixture.bzl index 937ee8d8b68..cb0bccebb7f 100644 --- a/aspect/testing/rules/intellij_aspect_test_fixture.bzl +++ b/aspect/testing/rules/intellij_aspect_test_fixture.bzl @@ -6,6 +6,7 @@ load( ) load( "//aspect:intellij_info_impl.bzl", + "IntelliJInfo", "update_set_in_dict", ) @@ -13,9 +14,9 @@ def _impl(ctx): """Implementation method for _intellij_aspect_test_fixture.""" output_groups = dict() inputs = depset() - deps = [dep for dep in ctx.attr.deps if hasattr(dep, "intellij_info")] + deps = [dep for dep in ctx.attr.deps if IntelliJInfo in dep] for dep in deps: - for k, v in dep.intellij_info.output_groups.items(): + for k, v in dep[IntelliJInfo].output_groups.items(): update_set_in_dict(output_groups, k, v) inputs = depset( [f for f in v.to_list() if f.short_path.endswith(".intellij-info.txt")], @@ -43,7 +44,7 @@ def _impl(ctx): mnemonic = "IntellijAspectTestFixtureBuilder", progress_message = "Building Intellij Aspect Test Fixture", ) - return struct( + return DefaultInfo( files = depset([output]), runfiles = ctx.runfiles( files = [output], @@ -64,12 +65,13 @@ _intellij_aspect_test_fixture = rule( }, ) -def intellij_aspect_test_fixture(name, deps): +def intellij_aspect_test_fixture(name, deps, transitive_configs = []): _intellij_aspect_test_fixture( name = name, output = name + ".intellij-aspect-test-fixture", deps = deps, testonly = 1, + transitive_configs = transitive_configs, ) def test_sources(outs): diff --git a/aspect/testing/tests/src/com/google/idea/blaze/aspect/cpp/ccbinary/BUILD b/aspect/testing/tests/src/com/google/idea/blaze/aspect/cpp/ccbinary/BUILD index e2a44429daa..2e2c0361ef6 100644 --- a/aspect/testing/tests/src/com/google/idea/blaze/aspect/cpp/ccbinary/BUILD +++ b/aspect/testing/tests/src/com/google/idea/blaze/aspect/cpp/ccbinary/BUILD @@ -1,5 +1,6 @@ licenses(["notice"]) +load("@rules_java//java:defs.bzl", "java_test") load( "//aspect/testing/rules:intellij_aspect_test_fixture.bzl", "intellij_aspect_test_fixture", @@ -26,6 +27,6 @@ java_test( "//aspect/testing/rules:intellij_aspect_test_fixture_java_proto", "//intellij_platform_sdk:test_libs", "//proto:intellij_ide_info_java_proto", - "@junit//jar", + "//third_party/java/junit", ], ) diff --git a/aspect/testing/tests/src/com/google/idea/blaze/aspect/cpp/cclibrary/BUILD b/aspect/testing/tests/src/com/google/idea/blaze/aspect/cpp/cclibrary/BUILD index 0faff2a1bc0..3e4aa18673f 100644 --- a/aspect/testing/tests/src/com/google/idea/blaze/aspect/cpp/cclibrary/BUILD +++ b/aspect/testing/tests/src/com/google/idea/blaze/aspect/cpp/cclibrary/BUILD @@ -1,5 +1,6 @@ licenses(["notice"]) +load("@rules_java//java:defs.bzl", "java_test") load( "//aspect/testing/rules:intellij_aspect_test_fixture.bzl", "intellij_aspect_test_fixture", @@ -65,6 +66,6 @@ java_test( "//aspect/testing/rules:intellij_aspect_test_fixture_java_proto", "//intellij_platform_sdk:test_libs", "//proto:intellij_ide_info_java_proto", - "@junit//jar", + "//third_party/java/junit", ], ) diff --git a/aspect/testing/tests/src/com/google/idea/blaze/aspect/cpp/cctest/BUILD b/aspect/testing/tests/src/com/google/idea/blaze/aspect/cpp/cctest/BUILD index b3d191f5f10..74e091f576c 100644 --- a/aspect/testing/tests/src/com/google/idea/blaze/aspect/cpp/cctest/BUILD +++ b/aspect/testing/tests/src/com/google/idea/blaze/aspect/cpp/cctest/BUILD @@ -1,5 +1,6 @@ licenses(["notice"]) +load("@rules_java//java:defs.bzl", "java_test") load( "//aspect/testing/rules:intellij_aspect_test_fixture.bzl", "intellij_aspect_test_fixture", @@ -12,6 +13,7 @@ cc_test( intellij_aspect_test_fixture( name = "simple_fixture", + transitive_configs = ["//command_line_option/fragment:test"], deps = [":simple"], ) @@ -26,6 +28,6 @@ java_test( "//aspect/testing/rules:intellij_aspect_test_fixture_java_proto", "//intellij_platform_sdk:test_libs", "//proto:intellij_ide_info_java_proto", - "@junit//jar", + "//third_party/java/junit", ], ) diff --git a/aspect/testing/tests/src/com/google/idea/blaze/aspect/cpp/cctoolchain/BUILD b/aspect/testing/tests/src/com/google/idea/blaze/aspect/cpp/cctoolchain/BUILD index d87c58ee8ba..61bd16d4221 100644 --- a/aspect/testing/tests/src/com/google/idea/blaze/aspect/cpp/cctoolchain/BUILD +++ b/aspect/testing/tests/src/com/google/idea/blaze/aspect/cpp/cctoolchain/BUILD @@ -1,5 +1,6 @@ licenses(["notice"]) +load("@rules_java//java:defs.bzl", "java_test") load( "//aspect/testing/rules:intellij_aspect_test_fixture.bzl", "intellij_aspect_test_fixture", @@ -27,6 +28,6 @@ java_test( "//aspect/testing/rules:intellij_aspect_test_fixture_java_proto", "//intellij_platform_sdk:test_libs", "//proto:intellij_ide_info_java_proto", - "@junit//jar", + "//third_party/java/junit", ], ) diff --git a/aspect/testing/tests/src/com/google/idea/blaze/aspect/cpp/cctoolchain/CcToolchainTest.java b/aspect/testing/tests/src/com/google/idea/blaze/aspect/cpp/cctoolchain/CcToolchainTest.java index 208d6ff9783..24045782d3f 100644 --- a/aspect/testing/tests/src/com/google/idea/blaze/aspect/cpp/cctoolchain/CcToolchainTest.java +++ b/aspect/testing/tests/src/com/google/idea/blaze/aspect/cpp/cctoolchain/CcToolchainTest.java @@ -40,7 +40,8 @@ public void testCcToolchain() throws Exception { for (TargetIdeInfo toolchain : toolchains) { CToolchainIdeInfo toolchainInfo = toolchain.getCToolchainIdeInfo(); assertThat(toolchainInfo.getBuiltInIncludeDirectoryList()).isNotEmpty(); - assertThat(toolchainInfo.getCppExecutable()).isNotEmpty(); + assertThat(toolchainInfo.getCCompiler()).isNotEmpty(); + assertThat(toolchainInfo.getCppCompiler()).isNotEmpty(); assertThat(toolchainInfo.getTargetName()).isNotEmpty(); assertThat(toolchainInfo.getCOptionList()).isNotEmpty(); assertThat(toolchainInfo.getCppOptionList()).isNotEmpty(); @@ -78,10 +79,6 @@ public void testCcToolchain() throws Exception { && !dir.contains("clang/") && dir.endsWith("include"))) .isTrue(); - assertThat( - toolchainInfo.getBuiltInIncludeDirectoryList().stream() - .anyMatch(dir -> dir.contains("c++"))) - .isTrue(); } } diff --git a/aspect/testing/tests/src/com/google/idea/blaze/aspect/cpp/coptsmakevars/BUILD b/aspect/testing/tests/src/com/google/idea/blaze/aspect/cpp/coptsmakevars/BUILD index ec7df3b5406..e3b260faee4 100644 --- a/aspect/testing/tests/src/com/google/idea/blaze/aspect/cpp/coptsmakevars/BUILD +++ b/aspect/testing/tests/src/com/google/idea/blaze/aspect/cpp/coptsmakevars/BUILD @@ -1,5 +1,6 @@ licenses(["notice"]) +load("@rules_java//java:defs.bzl", "java_test") load( "//aspect/testing/rules:intellij_aspect_test_fixture.bzl", "intellij_aspect_test_fixture", @@ -32,6 +33,6 @@ java_test( "//aspect/testing/rules:intellij_aspect_test_fixture_java_proto", "//intellij_platform_sdk:test_libs", "//proto:intellij_ide_info_java_proto", - "@junit//jar", + "//third_party/java/junit", ], ) diff --git a/aspect/testing/tests/src/com/google/idea/blaze/aspect/cpp/coptsmakevars/CoptsMakeVarsTest.java b/aspect/testing/tests/src/com/google/idea/blaze/aspect/cpp/coptsmakevars/CoptsMakeVarsTest.java index db3e69db4a1..009ee245e53 100644 --- a/aspect/testing/tests/src/com/google/idea/blaze/aspect/cpp/coptsmakevars/CoptsMakeVarsTest.java +++ b/aspect/testing/tests/src/com/google/idea/blaze/aspect/cpp/coptsmakevars/CoptsMakeVarsTest.java @@ -42,7 +42,7 @@ public void testCoptsPrefinedMakeVars() throws Exception { assertThat(cTargetIdeInfo.getTargetCoptList()).hasSize(2); // These predefined variables' values are dependent on build system and configuration. assertThat(cTargetIdeInfo.getTargetCoptList().get(0)) - .containsMatch("^-DPREFINED_BINDIR=(blaze|bazel)-out/[-0-9a-z]+/bin$"); + .containsMatch("^-DPREFINED_BINDIR=(blaze|bazel)-out/[0-9a-z_-]+/bin$"); assertThat(cTargetIdeInfo.getTargetCoptList().get(1)).isEqualTo("-DPREFINED_BINDIR2=$(BINDIR)"); } } diff --git a/aspect/testing/tests/src/com/google/idea/blaze/aspect/general/alias/BUILD b/aspect/testing/tests/src/com/google/idea/blaze/aspect/general/alias/BUILD index 4154f240787..61c07bf6706 100644 --- a/aspect/testing/tests/src/com/google/idea/blaze/aspect/general/alias/BUILD +++ b/aspect/testing/tests/src/com/google/idea/blaze/aspect/general/alias/BUILD @@ -1,5 +1,6 @@ licenses(["notice"]) +load("@rules_java//java:defs.bzl", "java_library", "java_test") load( "//aspect/testing/rules:intellij_aspect_test_fixture.bzl", "intellij_aspect_test_fixture", @@ -42,6 +43,6 @@ java_test( "//aspect/testing/rules:intellij_aspect_test_fixture_java_proto", "//intellij_platform_sdk:test_libs", "//proto:intellij_ide_info_java_proto", - "@junit//jar", + "//third_party/java/junit", ], ) diff --git a/aspect/testing/tests/src/com/google/idea/blaze/aspect/general/analysistest/BUILD b/aspect/testing/tests/src/com/google/idea/blaze/aspect/general/analysistest/BUILD index f10ee99e9ca..06c3059cdcf 100644 --- a/aspect/testing/tests/src/com/google/idea/blaze/aspect/general/analysistest/BUILD +++ b/aspect/testing/tests/src/com/google/idea/blaze/aspect/general/analysistest/BUILD @@ -1,3 +1,4 @@ +load("@rules_java//java:defs.bzl", "java_library", "java_test") load( "//aspect/testing/rules:intellij_aspect_test_fixture.bzl", "intellij_aspect_test_fixture", @@ -34,6 +35,6 @@ java_test( "//aspect/testing:BazelIntellijAspectTest", "//aspect/testing/rules:intellij_aspect_test_fixture_java_proto", "//intellij_platform_sdk:test_libs", - "@junit//jar", + "//third_party/java/junit", ], ) diff --git a/aspect/testing/tests/src/com/google/idea/blaze/aspect/general/artifacts/BUILD b/aspect/testing/tests/src/com/google/idea/blaze/aspect/general/artifacts/BUILD index 61e9ab81cbb..18c02783c95 100644 --- a/aspect/testing/tests/src/com/google/idea/blaze/aspect/general/artifacts/BUILD +++ b/aspect/testing/tests/src/com/google/idea/blaze/aspect/general/artifacts/BUILD @@ -1,3 +1,4 @@ +load("@rules_java//java:defs.bzl", "java_library", "java_test") load( "//aspect/testing/rules:intellij_aspect_test_fixture.bzl", "intellij_aspect_test_fixture", @@ -42,6 +43,6 @@ java_test( "//aspect/testing/rules:intellij_aspect_test_fixture_java_proto", "//intellij_platform_sdk:test_libs", "//proto:intellij_ide_info_java_proto", - "@junit//jar", + "//third_party/java/junit", ], ) diff --git a/aspect/testing/tests/src/com/google/idea/blaze/aspect/general/build/BUILD b/aspect/testing/tests/src/com/google/idea/blaze/aspect/general/build/BUILD index fd824d0725e..e2fbeb4c3e3 100644 --- a/aspect/testing/tests/src/com/google/idea/blaze/aspect/general/build/BUILD +++ b/aspect/testing/tests/src/com/google/idea/blaze/aspect/general/build/BUILD @@ -1,5 +1,6 @@ licenses(["notice"]) +load("@rules_java//java:defs.bzl", "java_library", "java_test") load( "//aspect/testing/rules:intellij_aspect_test_fixture.bzl", "intellij_aspect_test_fixture", @@ -26,6 +27,6 @@ java_test( "//aspect/testing/rules:intellij_aspect_test_fixture_java_proto", "//intellij_platform_sdk:test_libs", "//proto:intellij_ide_info_java_proto", - "@junit//jar", + "//third_party/java/junit", ], ) diff --git a/aspect/testing/tests/src/com/google/idea/blaze/aspect/general/noide/BUILD b/aspect/testing/tests/src/com/google/idea/blaze/aspect/general/noide/BUILD index 2a0eec7d269..9078a67ed7c 100644 --- a/aspect/testing/tests/src/com/google/idea/blaze/aspect/general/noide/BUILD +++ b/aspect/testing/tests/src/com/google/idea/blaze/aspect/general/noide/BUILD @@ -1,5 +1,6 @@ licenses(["notice"]) +load("@rules_java//java:defs.bzl", "java_library", "java_test") load( "//aspect/testing/rules:intellij_aspect_test_fixture.bzl", "intellij_aspect_test_fixture", @@ -34,7 +35,9 @@ intellij_aspect_test_fixture( java_test( name = "NoIdeTest", srcs = ["NoIdeTest.java"], - data = [":noide_fixture"], + data = [ + ":noide_fixture", + ], deps = [ "//aspect/testing:BazelIntellijAspectTest", "//aspect/testing:guava", @@ -42,6 +45,6 @@ java_test( "//aspect/testing/rules:intellij_aspect_test_fixture_java_proto", "//intellij_platform_sdk:test_libs", "//proto:intellij_ide_info_java_proto", - "@junit//jar", + "//third_party/java/junit", ], ) diff --git a/aspect/testing/tests/src/com/google/idea/blaze/aspect/general/noide/NoIdeTest.java b/aspect/testing/tests/src/com/google/idea/blaze/aspect/general/noide/NoIdeTest.java index d5d356cb8d0..05d977d43b0 100644 --- a/aspect/testing/tests/src/com/google/idea/blaze/aspect/general/noide/NoIdeTest.java +++ b/aspect/testing/tests/src/com/google/idea/blaze/aspect/general/noide/NoIdeTest.java @@ -34,11 +34,10 @@ public void testNoIde() throws Exception { assertThat(findTarget(testFixture, ":baz")).isNull(); assertThat(getOutputGroupFiles(testFixture, "intellij-info-java")) - .containsAllOf( + .containsAtLeast( testRelative("foo.java-manifest"), testRelative(intellijInfoFileName("foo"))); assertThat(getOutputGroupFiles(testFixture, "intellij-resolve-java")) .containsExactly( - testRelative("libfoo.jar"), testRelative("libfoo-hjar.jar"), testRelative("libfoo-src.jar"), testRelative("libfoo.jdeps")); diff --git a/aspect/testing/tests/src/com/google/idea/blaze/aspect/general/tags/BUILD b/aspect/testing/tests/src/com/google/idea/blaze/aspect/general/tags/BUILD index edffde06ef4..819cd78e3d0 100644 --- a/aspect/testing/tests/src/com/google/idea/blaze/aspect/general/tags/BUILD +++ b/aspect/testing/tests/src/com/google/idea/blaze/aspect/general/tags/BUILD @@ -1,5 +1,6 @@ licenses(["notice"]) +load("@rules_java//java:defs.bzl", "java_library", "java_test") load( "//aspect/testing/rules:intellij_aspect_test_fixture.bzl", "intellij_aspect_test_fixture", @@ -34,6 +35,6 @@ java_test( "//aspect/testing/rules:intellij_aspect_test_fixture_java_proto", "//intellij_platform_sdk:test_libs", "//proto:intellij_ide_info_java_proto", - "@junit//jar", + "//third_party/java/junit", ], ) diff --git a/aspect/testing/tests/src/com/google/idea/blaze/aspect/go/go_proto_library/BUILD b/aspect/testing/tests/src/com/google/idea/blaze/aspect/go/go_proto_library/BUILD new file mode 100644 index 00000000000..1234310d8c7 --- /dev/null +++ b/aspect/testing/tests/src/com/google/idea/blaze/aspect/go/go_proto_library/BUILD @@ -0,0 +1,51 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") +load("@io_bazel_rules_go//proto:def.bzl", "go_proto_library") +load("@protobuf//bazel:proto_library.bzl", "proto_library") + +load( + "//aspect/testing/rules:intellij_aspect_test_fixture.bzl", + "intellij_aspect_test_fixture", +) + +proto_library( + name = "fooproto_proto", + srcs = ["fooserver.proto"], + visibility = ["//visibility:public"], + deps = ["@protobuf//:empty_proto"], +) + +go_proto_library( + name = "fooproto_go_proto", + compilers = ["@io_bazel_rules_go//proto:go_grpc"], + importpath = "github.com/bazelbuild/intellij/examples/go/with_proto/proto", + proto = ":fooproto_proto", + visibility = ["//visibility:public"], +) + +go_library( + name = "proto", + srcs = ["translators.go"], + embed = [":fooproto_go_proto"], + importpath = "github.com/bazelbuild/intellij/examples/go/with_proto/proto", + visibility = ["//visibility:public"], +) + +intellij_aspect_test_fixture( + name = "simple_fixture", + deps = [":proto"], +) + +java_test( + name = "GoTest", + srcs = ["GoTest.java"], + data = [":simple_fixture"], + deps = [ + "//aspect/testing:BazelIntellijAspectTest", + "//aspect/testing:guava", + "//aspect/testing/rules:IntellijAspectTest", + "//aspect/testing/rules:intellij_aspect_test_fixture_java_proto", + "//intellij_platform_sdk:test_libs", + "//proto:intellij_ide_info_java_proto", + "//third_party/java/junit", + ], +) diff --git a/aspect/testing/tests/src/com/google/idea/blaze/aspect/go/go_proto_library/GoTest.java b/aspect/testing/tests/src/com/google/idea/blaze/aspect/go/go_proto_library/GoTest.java new file mode 100644 index 00000000000..58358f81226 --- /dev/null +++ b/aspect/testing/tests/src/com/google/idea/blaze/aspect/go/go_proto_library/GoTest.java @@ -0,0 +1,45 @@ +/* + * Copyright 2024 The Bazel Authors. All rights reserved. + * + * 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. + */ +package com.google.idea.blaze.aspect.go.go_proto_library; + +import static com.google.common.truth.Truth.assertThat; + +import com.google.devtools.intellij.IntellijAspectTestFixtureOuterClass.IntellijAspectTestFixture; +import com.google.devtools.intellij.ideinfo.IntellijIdeInfo.TargetIdeInfo; +import com.google.idea.blaze.BazelIntellijAspectTest; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + + +/** Tests go_proto_library */ +@RunWith(JUnit4.class) +public class GoTest extends BazelIntellijAspectTest { + @Test + public void testGoTest() throws Exception { + IntellijAspectTestFixture testFixture = loadTestFixture(":simple_fixture"); + TargetIdeInfo target = findTarget(testFixture, ":proto"); + assertThat(target.getKindString()).isEqualTo("go_library"); + assertThat(relativePathsForArtifacts(target.getGoIdeInfo().getSourcesList())) + .contains(testRelative("translators.go")); + assertThat(relativePathsForArtifacts(target.getGoIdeInfo().getSourcesList())) + .contains(testRelative("fooproto_go_proto_/github.com/bazelbuild/intellij/examples/go/with_proto/proto/fooserver.pb.go")); + } +} diff --git a/aspect/testing/tests/src/com/google/idea/blaze/aspect/go/go_proto_library/fooserver.proto b/aspect/testing/tests/src/com/google/idea/blaze/aspect/go/go_proto_library/fooserver.proto new file mode 100644 index 00000000000..ab63c861d34 --- /dev/null +++ b/aspect/testing/tests/src/com/google/idea/blaze/aspect/go/go_proto_library/fooserver.proto @@ -0,0 +1,27 @@ +syntax = "proto3"; + +package fooproto; + +import "google/protobuf/empty.proto"; + +service FooService { + rpc SayHello (HelloRequest) returns (HelloReply) {} + // This function exists to validate that the well known types (such as google.protobuf.Empty) + // are picked up by the plugin. + // To validate that they are working, navigate to "External Libraries" > "Go Libraries" > + // "github.com/bazelbuild/intellij/examples/go/with_proto/proto/fooserver.pb.go", + // and validate that "google.golang.org/protobuf/types/known/emptypb" is resolved correctly. + rpc EmptyFunction (google.protobuf.Empty) returns (google.protobuf.Empty); +} + +message HelloRequest { + optional string name = 1; +} + +message HelloReply { + optional string message = 1; +} + +message Time { + string value = 1; +} diff --git a/aspect/testing/tests/src/com/google/idea/blaze/aspect/go/go_proto_library/translators.go b/aspect/testing/tests/src/com/google/idea/blaze/aspect/go/go_proto_library/translators.go new file mode 100644 index 00000000000..f79720cb504 --- /dev/null +++ b/aspect/testing/tests/src/com/google/idea/blaze/aspect/go/go_proto_library/translators.go @@ -0,0 +1,11 @@ +package proto + +import ( + "time" +) + +// Time translation functions. + +func ToProtoTime(t time.Time) Time { + return Time{Value: t.Format(time.RFC3339Nano)} +} diff --git a/aspect/testing/tests/src/com/google/idea/blaze/aspect/integration/BUILD b/aspect/testing/tests/src/com/google/idea/blaze/aspect/integration/BUILD index b2308fe1d7a..ac2031cb31e 100644 --- a/aspect/testing/tests/src/com/google/idea/blaze/aspect/integration/BUILD +++ b/aspect/testing/tests/src/com/google/idea/blaze/aspect/integration/BUILD @@ -1,7 +1,8 @@ load( - "@contrib_rules_bazel_integration_test//bazel_integration_test:defs.bzl", + "@rules_bazel_integration_test//bazel_integration_test:defs.bzl", "bazel_integration_tests", ) +load("@bazel_binaries//:defs.bzl", "bazel_binaries") java_binary( name = "BazelInvokingIntegrationTestRunner", @@ -9,6 +10,7 @@ java_binary( srcs = ["BazelInvokingIntegrationTestRunner.java"], data = [ "//aspect:aspect_files", + "//aspect_template:aspect_files", ], main_class = "com.google.idea.blaze.aspect.integration.BazelInvokingIntegrationTestRunner", deps = [ @@ -19,10 +21,7 @@ java_binary( bazel_integration_tests( name = "bazel_invocation_integration_tests", - bazel_versions = [ - "1.2.0", - "6.0.0", - ], + bazel_versions = bazel_binaries.versions.all, # set tags = [] because otherwise bazel_integration_tests sets # tags = ["manual"] and the target is not be detected via test //pkg/... tags = [], diff --git a/aspect/testing/tests/src/com/google/idea/blaze/aspect/integration/BazelInvokingIntegrationTestRunner.java b/aspect/testing/tests/src/com/google/idea/blaze/aspect/integration/BazelInvokingIntegrationTestRunner.java index 1cf314d07bc..9d6a68b1393 100644 --- a/aspect/testing/tests/src/com/google/idea/blaze/aspect/integration/BazelInvokingIntegrationTestRunner.java +++ b/aspect/testing/tests/src/com/google/idea/blaze/aspect/integration/BazelInvokingIntegrationTestRunner.java @@ -22,6 +22,7 @@ import com.google.idea.blaze.base.sync.aspects.strategy.AspectStrategy; import com.google.idea.blaze.base.sync.aspects.strategy.AspectStrategy.OutputGroup; import com.google.idea.blaze.base.sync.aspects.strategy.AspectStrategyBazel; +import com.google.idea.blaze.base.sync.aspects.strategy.OverrideFlags; import java.io.File; import java.nio.file.Paths; import java.util.Collection; @@ -51,12 +52,18 @@ public static void main(String[] a) throws Exception { // Flags for wiring up the plugin aspect from the external @intellij_aspect repository. ImmutableList aspectFlags = ImmutableList.of( - aspectStrategyBazel.getAspectFlag(), + aspectStrategyBazel.getAspectFlag().get(), String.format( "%s=%s/%s/aspect", - AspectStrategyBazel.OVERRIDE_REPOSITORY_FLAG, + OverrideFlags.overrideRepositoryFlag(false), System.getenv("TEST_SRCDIR"), - System.getenv("TEST_WORKSPACE"))); + System.getenv("TEST_WORKSPACE")), + String.format( + "%s=%s/%s/aspect_template", + OverrideFlags.overrideRepositoryTemplateFlag(false), + System.getenv("TEST_SRCDIR"), + System.getenv("TEST_WORKSPACE")) + ); if (bazelVersion.isAtLeast(6, 0, 0) && !aspectFlags.contains( @@ -138,6 +145,13 @@ private static BazelVersion getBazelVersion() { return null; } String bazelDir = new File(bazelBinaryPath).getParentFile().getName(); + // Get the part after last ~ or + (becase of canonicalization with bzlmod) + if (bazelDir.contains("~")) { + bazelDir = bazelDir.substring(bazelDir.lastIndexOf("~") + 1); + } else if (bazelDir.contains("+")) { + bazelDir = bazelDir.substring(bazelDir.lastIndexOf("+") + 1); + } + String[] parts = bazelDir.split("_|-"); if (parts.length < 6) { return null; diff --git a/aspect/testing/tests/src/com/google/idea/blaze/aspect/integration/testdata/WORKSPACE b/aspect/testing/tests/src/com/google/idea/blaze/aspect/integration/testdata/WORKSPACE index 92e376e8d0c..eae2adb1da5 100644 --- a/aspect/testing/tests/src/com/google/idea/blaze/aspect/integration/testdata/WORKSPACE +++ b/aspect/testing/tests/src/com/google/idea/blaze/aspect/integration/testdata/WORKSPACE @@ -1 +1,8 @@ workspace(name = "testdata") + +load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") +http_archive( + name = "rules_java", + url = "https://github.com/bazelbuild/rules_java/releases/download/5.3.5/rules_java-5.3.5.tar.gz", + sha256 = "c73336802d0b4882e40770666ad055212df4ea62cfa6edf9cb0f9d29828a0934", +) diff --git a/aspect/testing/tests/src/com/google/idea/blaze/aspect/java/dependencies/BUILD b/aspect/testing/tests/src/com/google/idea/blaze/aspect/java/dependencies/BUILD index 6089b7a7ea7..8fbf89ea801 100644 --- a/aspect/testing/tests/src/com/google/idea/blaze/aspect/java/dependencies/BUILD +++ b/aspect/testing/tests/src/com/google/idea/blaze/aspect/java/dependencies/BUILD @@ -1,5 +1,6 @@ licenses(["notice"]) +load("@rules_java//java:defs.bzl", "java_library", "java_test") load( "//aspect/testing/rules:intellij_aspect_test_fixture.bzl", "intellij_aspect_test_fixture", @@ -114,6 +115,6 @@ java_test( "//aspect/testing/rules:intellij_aspect_test_fixture_java_proto", "//intellij_platform_sdk:test_libs", "//proto:intellij_ide_info_java_proto", - "@junit//jar", + "//third_party/java/junit", ], ) diff --git a/aspect/testing/tests/src/com/google/idea/blaze/aspect/java/dependencies/DependenciesTest.java b/aspect/testing/tests/src/com/google/idea/blaze/aspect/java/dependencies/DependenciesTest.java index d109b3801af..e28dbc2e9bf 100644 --- a/aspect/testing/tests/src/com/google/idea/blaze/aspect/java/dependencies/DependenciesTest.java +++ b/aspect/testing/tests/src/com/google/idea/blaze/aspect/java/dependencies/DependenciesTest.java @@ -45,26 +45,32 @@ public void testJavaLibraryWithTransitiveDependencies() throws Exception { assertThat(dependenciesForTarget(target)).contains(dep(":single_dep")); assertThat(getOutputGroupFiles(testFixture, "intellij-info-java")) - .containsAllOf( + .containsAtLeast( testRelative("foo.java-manifest"), testRelative(intellijInfoFileName("foo")), testRelative("single_dep.java-manifest"), testRelative(intellijInfoFileName("single_dep")), testRelative("transitive_dep.java-manifest"), testRelative(intellijInfoFileName("transitive_dep"))); - assertThat(getOutputGroupFiles(testFixture, "intellij-resolve-java")) - .containsAllOf( - testRelative("libfoo.jar"), + + var intellijResolveJava = getOutputGroupFiles(testFixture, "intellij-resolve-java"); + assertThat(intellijResolveJava) + .containsAtLeast( testRelative("libfoo-hjar.jar"), testRelative("libfoo-src.jar"), - testRelative("libsingle_dep.jar"), testRelative("libsingle_dep-hjar.jar"), testRelative("libsingle_dep-src.jar"), - testRelative("libtransitive_dep.jar"), testRelative("libtransitive_dep-hjar.jar"), testRelative("libtransitive_dep-src.jar")); + assertThat(intellijResolveJava) + .doesNotContain(testRelative("libfoo.jar")); + assertThat(intellijResolveJava) + .doesNotContain(testRelative("libsingle_dep.jar")); + assertThat(intellijResolveJava) + .doesNotContain(testRelative("libtransitive_dep.jar")); + assertThat(getOutputGroupFiles(testFixture, "intellij-compile-java")) - .containsAllOf( + .containsAtLeast( testRelative("libfoo.jar"), testRelative("libsingle_dep.jar"), testRelative("libtransitive_dep.jar")); @@ -77,7 +83,7 @@ public void testJavaLibraryWithDiamondDependencies() throws Exception { IntellijAspectTestFixture testFixture = loadTestFixture(":diamond_dep_fixture"); TargetIdeInfo target = findTarget(testFixture, ":diamond_dep"); assertThat(dependenciesForTarget(target)) - .containsAllOf(dep(":single_dep"), dep(":single_dep_sibling")); + .containsAtLeast(dep(":single_dep"), dep(":single_dep_sibling")); } @Test @@ -91,29 +97,35 @@ public void testJavaLibraryWithExports() throws Exception { assertThat(dependenciesForTarget(fooExporter)).contains(dep(":foo")); assertThat(dependenciesForTarget(exportConsumer)) - .containsAllOf(dep(":foo_exporter"), dep(":foo")); + .containsAtLeast(dep(":foo_exporter"), dep(":foo")); assertThat(getOutputGroupFiles(testFixture, "intellij-info-java")) - .containsAllOf( + .containsAtLeast( testRelative("foo.java-manifest"), testRelative(intellijInfoFileName("foo")), testRelative("foo_exporter.java-manifest"), testRelative(intellijInfoFileName("foo_exporter")), testRelative("export_consumer.java-manifest"), testRelative(intellijInfoFileName("export_consumer"))); - assertThat(getOutputGroupFiles(testFixture, "intellij-resolve-java")) - .containsAllOf( - testRelative("libfoo.jar"), + + var intellijResolveJava = getOutputGroupFiles(testFixture, "intellij-resolve-java"); + assertThat(intellijResolveJava) + .containsAtLeast( testRelative("libfoo-hjar.jar"), testRelative("libfoo-src.jar"), - testRelative("libfoo_exporter.jar"), testRelative("libfoo_exporter-hjar.jar"), testRelative("libfoo_exporter-src.jar"), - testRelative("libexport_consumer.jar"), testRelative("libexport_consumer-hjar.jar"), testRelative("libexport_consumer-src.jar")); + assertThat(intellijResolveJava) + .doesNotContain(testRelative("libfoo.jar")); + assertThat(intellijResolveJava) + .doesNotContain(testRelative("libfoo_exporter.jar")); + assertThat(intellijResolveJava) + .doesNotContain(testRelative("libexport_consumer.jar")); + assertThat(getOutputGroupFiles(testFixture, "intellij-compile-java")) - .containsAllOf( + .containsAtLeast( testRelative("libfoo.jar"), testRelative("libfoo_exporter.jar"), testRelative("libexport_consumer.jar")); @@ -125,7 +137,7 @@ public void testJavaLibraryWithTransitiveExports() throws Exception { TargetIdeInfo transitiveExportConsumer = findTarget(testFixture, ":transitive_export_consumer"); assertThat(dependenciesForTarget(transitiveExportConsumer)) - .containsAllOf(dep(":foo"), dep(":foo_exporter"), dep(":foo_exporter_exporter")); + .containsAtLeast(dep(":foo"), dep(":foo_exporter"), dep(":foo_exporter_exporter")); } @Test diff --git a/aspect/testing/tests/src/com/google/idea/blaze/aspect/java/filteredgenjar/BUILD b/aspect/testing/tests/src/com/google/idea/blaze/aspect/java/filteredgenjar/BUILD index a3299506065..8ec7d53d767 100644 --- a/aspect/testing/tests/src/com/google/idea/blaze/aspect/java/filteredgenjar/BUILD +++ b/aspect/testing/tests/src/com/google/idea/blaze/aspect/java/filteredgenjar/BUILD @@ -1,3 +1,4 @@ +load("@rules_java//java:defs.bzl", "java_library", "java_test") load( "//aspect/testing/rules:intellij_aspect_test_fixture.bzl", "intellij_aspect_test_fixture", @@ -59,6 +60,6 @@ java_test( "//aspect/testing/rules:intellij_aspect_test_fixture_java_proto", "//intellij_platform_sdk:test_libs", "//proto:intellij_ide_info_java_proto", - "@junit//jar", + "//third_party/java/junit", ], ) diff --git a/aspect/testing/tests/src/com/google/idea/blaze/aspect/java/genjars/BUILD b/aspect/testing/tests/src/com/google/idea/blaze/aspect/java/genjars/BUILD index 9d234eeeb6b..576c6ea8c6b 100644 --- a/aspect/testing/tests/src/com/google/idea/blaze/aspect/java/genjars/BUILD +++ b/aspect/testing/tests/src/com/google/idea/blaze/aspect/java/genjars/BUILD @@ -1,5 +1,6 @@ licenses(["notice"]) +load("@rules_java//java:defs.bzl", "java_library", "java_test") load( "//aspect/testing/rules:intellij_aspect_test_fixture.bzl", "intellij_aspect_test_fixture", @@ -18,7 +19,7 @@ intellij_aspect_test_fixture( java_library( name = "has_plugin", srcs = ["Foo.java"], - deps = ["//third_party/auto_value"], + deps = ["//third_party/java/auto_value"], ) intellij_aspect_test_fixture( @@ -40,6 +41,6 @@ java_test( "//aspect/testing/rules:intellij_aspect_test_fixture_java_proto", "//intellij_platform_sdk:test_libs", "//proto:intellij_ide_info_java_proto", - "@junit//jar", + "//third_party/java/junit", ], ) diff --git a/aspect/testing/tests/src/com/google/idea/blaze/aspect/java/genjars/GenJarsTest.java b/aspect/testing/tests/src/com/google/idea/blaze/aspect/java/genjars/GenJarsTest.java index 0918fa58229..35629a3c513 100644 --- a/aspect/testing/tests/src/com/google/idea/blaze/aspect/java/genjars/GenJarsTest.java +++ b/aspect/testing/tests/src/com/google/idea/blaze/aspect/java/genjars/GenJarsTest.java @@ -55,14 +55,14 @@ public void testJavaLibraryWithGeneratedSourcesHasGenJars() throws Exception { testRelative("libhas_plugin-gensrc.jar"))); assertThat(getOutputGroupFiles(testFixture, "intellij-info-java")) - .containsAllOf( + .containsAtLeast( testRelative("has_plugin.java-manifest"), testRelative(intellijInfoFileName("has_plugin"))); assertThat(getOutputGroupFiles(testFixture, "intellij-resolve-java")) - .containsAllOf( + .containsAtLeast( testRelative("libhas_plugin-gen.jar"), testRelative("libhas_plugin-gensrc.jar")); assertThat(getOutputGroupFiles(testFixture, "intellij-compile-java")) - .containsAllOf(testRelative("libhas_plugin.jar"), testRelative("libhas_plugin-gen.jar")); + .containsAtLeast(testRelative("libhas_plugin.jar"), testRelative("libhas_plugin-gen.jar")); assertThat(getOutputGroupFiles(testFixture, "intellij-info-generic")).isEmpty(); } diff --git a/aspect/testing/tests/src/com/google/idea/blaze/aspect/java/javabinary/BUILD b/aspect/testing/tests/src/com/google/idea/blaze/aspect/java/javabinary/BUILD index 22b1430d12c..bf77b0823a6 100644 --- a/aspect/testing/tests/src/com/google/idea/blaze/aspect/java/javabinary/BUILD +++ b/aspect/testing/tests/src/com/google/idea/blaze/aspect/java/javabinary/BUILD @@ -1,5 +1,6 @@ licenses(["notice"]) +load("@rules_java//java:defs.bzl", "java_binary", "java_library", "java_test") load( "//aspect/testing/rules:intellij_aspect_test_fixture.bzl", "intellij_aspect_test_fixture", @@ -33,6 +34,6 @@ java_test( "//aspect/testing/rules:intellij_aspect_test_fixture_java_proto", "//intellij_platform_sdk:test_libs", "//proto:intellij_ide_info_java_proto", - "@junit//jar", + "//third_party/java/junit", ], ) diff --git a/aspect/testing/tests/src/com/google/idea/blaze/aspect/java/javabinary/JavaBinaryTest.java b/aspect/testing/tests/src/com/google/idea/blaze/aspect/java/javabinary/JavaBinaryTest.java index e9026a549eb..538f822ba56 100644 --- a/aspect/testing/tests/src/com/google/idea/blaze/aspect/java/javabinary/JavaBinaryTest.java +++ b/aspect/testing/tests/src/com/google/idea/blaze/aspect/java/javabinary/JavaBinaryTest.java @@ -51,18 +51,19 @@ public void testJavaBinary() throws Exception { assertThat(binaryInfo.getJavaIdeInfo().getMainClass()).isEqualTo("com.google.MyMainClass"); assertThat(getOutputGroupFiles(testFixture, "intellij-info-java")) - .containsAllOf( + .containsAtLeast( testRelative("foolib.java-manifest"), testRelative(intellijInfoFileName("foolib")), testRelative("foo.java-manifest"), testRelative(intellijInfoFileName("foo"))); assertThat(getOutputGroupFiles(testFixture, "intellij-resolve-java")) - .containsAllOf( - testRelative("libfoolib.jar"), + .containsAtLeast( testRelative("libfoolib-hjar.jar"), testRelative("libfoolib-src.jar"), testRelative("foo.jar"), testRelative("foo-src.jar")); + assertThat(getOutputGroupFiles(testFixture, "intellij-resolve-java")) + .doesNotContain(testRelative("libfoolib.jar")); assertThat(getOutputGroupFiles(testFixture, "intellij-compile-java")) .containsExactly(testRelative("libfoolib.jar"), testRelative("foo.jar")); diff --git a/aspect/testing/tests/src/com/google/idea/blaze/aspect/java/javalibrary/BUILD b/aspect/testing/tests/src/com/google/idea/blaze/aspect/java/javalibrary/BUILD index 132a6cb00b9..ca3b0c87b85 100644 --- a/aspect/testing/tests/src/com/google/idea/blaze/aspect/java/javalibrary/BUILD +++ b/aspect/testing/tests/src/com/google/idea/blaze/aspect/java/javalibrary/BUILD @@ -1,3 +1,4 @@ +load("@rules_java//java:defs.bzl", "java_library", "java_test") load( "//aspect/testing/rules:intellij_aspect_test_fixture.bzl", "intellij_aspect_test_fixture", @@ -63,7 +64,7 @@ java_test( name = "JavaLibraryTest", srcs = ["JavaLibraryTest.java"], data = [ - "foo_exports_fixture", + ":foo_exports_fixture", ":foo_fixture", ], deps = [ @@ -72,6 +73,6 @@ java_test( "//aspect/testing/rules:intellij_aspect_test_fixture_java_proto", "//intellij_platform_sdk:test_libs", "//proto:intellij_ide_info_java_proto", - "@junit//jar", + "//third_party/java/junit", ], ) diff --git a/aspect/testing/tests/src/com/google/idea/blaze/aspect/java/javalibrary/JavaLibraryTest.java b/aspect/testing/tests/src/com/google/idea/blaze/aspect/java/javalibrary/JavaLibraryTest.java index 82e7e9aa9ff..97350cc5e6b 100644 --- a/aspect/testing/tests/src/com/google/idea/blaze/aspect/java/javalibrary/JavaLibraryTest.java +++ b/aspect/testing/tests/src/com/google/idea/blaze/aspect/java/javalibrary/JavaLibraryTest.java @@ -37,13 +37,13 @@ public void testExports() throws Exception { // transitive exports should be rolled up into direct deps assertThat(target.getDepsList()) - .containsAllOf( + .containsAtLeast( dep(":exports_direct"), dep(":direct"), dep(":exports_indirect"), dep(":indirect")); assertThat(target.getDepsList()).doesNotContain(dep(":distant")); // intellij-info groups assertThat(getOutputGroupFiles(testFixture, "intellij-info-java")) - .containsAllOf( + .containsAtLeast( testRelative("foo_exports.java-manifest"), testRelative(intellijInfoFileName("foo_exports")), testRelative(intellijInfoFileName("exports_direct")), @@ -61,7 +61,7 @@ public void testExports() throws Exception { testRelative(intellijInfoFileName("foo_exports"))); assertThat(getOutputGroupFiles(testFixture, "intellij-info-java-direct-deps")) - .containsAllOf( + .containsAtLeast( testRelative("foo_exports.java-manifest"), testRelative(intellijInfoFileName("foo_exports")), testRelative(intellijInfoFileName("exports_direct")), @@ -100,7 +100,7 @@ public void testJavaLibrary() throws Exception { // intellij-info groups assertThat(getOutputGroupFiles(testFixture, "intellij-info-java")) - .containsAllOf( + .containsAtLeast( testRelative("foo.java-manifest"), testRelative(intellijInfoFileName("foo")), testRelative("direct.java-manifest"), testRelative(intellijInfoFileName("direct")), testRelative("indirect.java-manifest"), testRelative(intellijInfoFileName("indirect")), @@ -111,7 +111,7 @@ public void testJavaLibrary() throws Exception { testRelative("foo.java-manifest"), testRelative(intellijInfoFileName("foo"))); assertThat(getOutputGroupFiles(testFixture, "intellij-info-java-direct-deps")) - .containsAllOf( + .containsAtLeast( testRelative("foo.java-manifest"), testRelative(intellijInfoFileName("foo")), testRelative("direct.java-manifest"), testRelative(intellijInfoFileName("direct"))); assertThat(getOutputGroupFiles(testFixture, "intellij-info-java-direct-deps")) @@ -123,40 +123,33 @@ public void testJavaLibrary() throws Exception { assertThat(getOutputGroupFiles(testFixture, "intellij-resolve-java")) .containsExactly( // foo - testRelative("libfoo.jar"), testRelative("libfoo-hjar.jar"), testRelative("libfoo-src.jar"), testRelative("libfoo.jdeps"), // direct - testRelative("libdirect.jar"), testRelative("libdirect-hjar.jar"), testRelative("libdirect-src.jar"), testRelative("libdirect.jdeps"), // indirect - testRelative("libindirect.jar"), testRelative("libindirect-hjar.jar"), testRelative("libindirect-src.jar"), testRelative("libindirect.jdeps"), // distant - testRelative("libdistant.jar"), testRelative("libdistant-hjar.jar"), testRelative("libdistant-src.jar"), testRelative("libdistant.jdeps")); assertThat(getOutputGroupFiles(testFixture, "intellij-resolve-java-outputs")) .containsExactly( - testRelative("libfoo.jar"), testRelative("libfoo-hjar.jar"), testRelative("libfoo-src.jar"), testRelative("libfoo.jdeps")); assertThat(getOutputGroupFiles(testFixture, "intellij-resolve-java-direct-deps")) .containsExactly( // foo - testRelative("libfoo.jar"), testRelative("libfoo-hjar.jar"), testRelative("libfoo-src.jar"), testRelative("libfoo.jdeps"), // direct - testRelative("libdirect.jar"), testRelative("libdirect-hjar.jar"), testRelative("libdirect-src.jar"), testRelative("libdirect.jdeps"), diff --git a/aspect/testing/tests/src/com/google/idea/blaze/aspect/java/javaplugin/BUILD b/aspect/testing/tests/src/com/google/idea/blaze/aspect/java/javaplugin/BUILD index 7c19c70c615..f2a1d193534 100644 --- a/aspect/testing/tests/src/com/google/idea/blaze/aspect/java/javaplugin/BUILD +++ b/aspect/testing/tests/src/com/google/idea/blaze/aspect/java/javaplugin/BUILD @@ -1,5 +1,6 @@ licenses(["notice"]) +load("@rules_java//java:defs.bzl", "java_plugin", "java_test") load( "//aspect/testing/rules:intellij_aspect_test_fixture.bzl", "intellij_aspect_test_fixture", @@ -27,6 +28,6 @@ java_test( "//aspect/testing/rules:intellij_aspect_test_fixture_java_proto", "//intellij_platform_sdk:test_libs", "//proto:intellij_ide_info_java_proto", - "@junit//jar", + "//third_party/java/junit", ], ) diff --git a/aspect/testing/tests/src/com/google/idea/blaze/aspect/java/javatest/BUILD b/aspect/testing/tests/src/com/google/idea/blaze/aspect/java/javatest/BUILD index 287825b2025..094ebf0bad8 100644 --- a/aspect/testing/tests/src/com/google/idea/blaze/aspect/java/javatest/BUILD +++ b/aspect/testing/tests/src/com/google/idea/blaze/aspect/java/javatest/BUILD @@ -1,5 +1,6 @@ licenses(["notice"]) +load("@rules_java//java:defs.bzl", "java_test") load( "//aspect/testing/rules:intellij_aspect_test_fixture.bzl", "intellij_aspect_test_fixture", @@ -13,7 +14,7 @@ java_test( name = "FooTest", size = "large", srcs = ["FooTest.java"], - deps = ["@junit//jar"], + deps = ["//third_party/java/junit"], ) intellij_aspect_test_fixture( @@ -32,7 +33,7 @@ java_test( "//aspect/testing/rules:intellij_aspect_test_fixture_java_proto", "//intellij_platform_sdk:test_libs", "//proto:intellij_ide_info_java_proto", - "@junit//jar", + "//third_party/java/junit", ], ) @@ -40,7 +41,7 @@ java_test( name = "FooTestNoLauncher", srcs = ["FooTest.java"], test_class = "com.google.idea.blaze.aspect.java.javatest.FooTest", - deps = ["@junit//jar"], + deps = ["//third_party/java/junit"], ) fast_build_aspect_test_fixture( @@ -58,7 +59,7 @@ java_test( srcs = ["FooTest.java"], launcher = ":custom_java_launcher", test_class = "com.google.idea.blaze.aspect.java.javatest.FooTest", - deps = ["@junit//jar"], + deps = ["//third_party/java/junit"], ) fast_build_aspect_test_fixture( @@ -66,12 +67,27 @@ fast_build_aspect_test_fixture( deps = [":FooTestWithCustomLauncher"], ) +java_test( + name = "FooTestWithCustomMainClass", + srcs = ["FooTest.java"], + main_class = "com.google.idea.blaze.aspect.java.javatest.fake.TestRunner", + tags = ["manual"], # This test is not meant to be ran on its own. The main class represents a custom test runner. + test_class = "com.google.idea.blaze.aspect.java.javatest.FooTest", + deps = ["//third_party/java/junit"], +) + +fast_build_aspect_test_fixture( + name = "footest_with_custom_main_class_fast_build_fixture", + deps = [":FooTestWithCustomMainClass"], +) + java_test( name = "JavaTestFastBuildAspectTest", srcs = ["JavaTestFastBuildAspectTest.java"], data = [ ":footest_no_launcher_fast_build_fixture", ":footest_with_custom_launcher_fast_build_fixture", + ":footest_with_custom_main_class_fast_build_fixture", ], deps = [ "//aspect/testing:guava", @@ -79,6 +95,6 @@ java_test( "//aspect/testing/rules:fast_build_aspect_test_fixture_java_proto", "//intellij_platform_sdk:test_libs", "//proto:fast_build_info_java_proto", - "@junit//jar", + "//third_party/java/junit", ], ) diff --git a/aspect/testing/tests/src/com/google/idea/blaze/aspect/java/javatest/JavaTestFastBuildAspectTest.java b/aspect/testing/tests/src/com/google/idea/blaze/aspect/java/javatest/JavaTestFastBuildAspectTest.java index 7a5c361d751..a3b2f233f74 100644 --- a/aspect/testing/tests/src/com/google/idea/blaze/aspect/java/javatest/JavaTestFastBuildAspectTest.java +++ b/aspect/testing/tests/src/com/google/idea/blaze/aspect/java/javatest/JavaTestFastBuildAspectTest.java @@ -31,6 +31,7 @@ public final class JavaTestFastBuildAspectTest { private static final String NO_LAUNCHER_TARGET = ""; + private static final String LAUNCHER_ALIAS = "@@bazel_tools//tools/jdk:launcher_flag_alias"; @Rule public FastBuildAspectRule aspectLoader = @@ -45,7 +46,8 @@ public void testNoJavaLauncherSpecified() throws Exception { aspectLoader.loadTestFixture(":footest_no_launcher_fast_build_fixture"); FastBuildBlazeData data = getDataForTarget(aspectLoader.testRelative(":FooTestNoLauncher"), fixture); - assertThat(data.getJavaInfo().getLauncher()).isEqualTo(NO_LAUNCHER_TARGET); + // TODO: b/295221112 - remove LAUNCHER_ALIAS once label_flag is used + assertThat(data.getJavaInfo().getLauncher()).isAnyOf(NO_LAUNCHER_TARGET, LAUNCHER_ALIAS); } @Test @@ -58,6 +60,16 @@ public void testCustomJavaLauncher() throws Exception { .isEqualTo(aspectLoader.testRelative(":custom_java_launcher")); } + @Test + public void testCustomMainClass() throws Exception { + FastBuildAspectTestFixture fixture = + aspectLoader.loadTestFixture(":footest_with_custom_main_class_fast_build_fixture"); + FastBuildBlazeData data = + getDataForTarget(aspectLoader.testRelative(":FooTestWithCustomMainClass"), fixture); + assertThat(data.getJavaInfo().getMainClass()) + .isEqualTo("com.google.idea.blaze.aspect.java.javatest.fake.TestRunner"); + } + private FastBuildBlazeData getDataForTarget(String target, FastBuildAspectTestFixture fixture) { return fixture.getTargetList().stream() diff --git a/aspect/testing/tests/src/com/google/idea/blaze/aspect/java/javatest/JavaTestTest.java b/aspect/testing/tests/src/com/google/idea/blaze/aspect/java/javatest/JavaTestTest.java index 6ddbde79dbc..59e7d67b0fd 100644 --- a/aspect/testing/tests/src/com/google/idea/blaze/aspect/java/javatest/JavaTestTest.java +++ b/aspect/testing/tests/src/com/google/idea/blaze/aspect/java/javatest/JavaTestTest.java @@ -50,10 +50,10 @@ public void testJavaTest() throws Exception { // intellij-info groups assertThat(getOutputGroupFiles(testFixture, "intellij-info-generic")).isEmpty(); assertThat(getOutputGroupFiles(testFixture, "intellij-info-java")) - .containsAllOf( + .containsAtLeast( testRelative("FooTest.java-manifest"), testRelative(intellijInfoFileName("FooTest"))); assertThat(getOutputGroupFiles(testFixture, "intellij-info-java-direct-deps")) - .containsAllOf( + .containsAtLeast( testRelative("FooTest.java-manifest"), testRelative(intellijInfoFileName("FooTest"))); assertThat(getOutputGroupFiles(testFixture, "intellij-info-java-outputs")) .containsExactly( @@ -61,12 +61,12 @@ public void testJavaTest() throws Exception { // intellij-resolve groups assertThat(getOutputGroupFiles(testFixture, "intellij-resolve-java")) - .containsAllOf( + .containsAtLeast( testRelative("FooTest.jar"), testRelative("FooTest-src.jar"), testRelative("FooTest.jdeps")); assertThat(getOutputGroupFiles(testFixture, "intellij-resolve-java-direct-deps")) - .containsAllOf( + .containsAtLeast( testRelative("FooTest.jar"), testRelative("FooTest-src.jar"), testRelative("FooTest.jdeps")); diff --git a/aspect/testing/tests/src/com/google/idea/blaze/aspect/java/pluginprocessorjars/BUILD b/aspect/testing/tests/src/com/google/idea/blaze/aspect/java/pluginprocessorjars/BUILD index 1999af193ba..2cbe4043170 100644 --- a/aspect/testing/tests/src/com/google/idea/blaze/aspect/java/pluginprocessorjars/BUILD +++ b/aspect/testing/tests/src/com/google/idea/blaze/aspect/java/pluginprocessorjars/BUILD @@ -13,13 +13,13 @@ java_library( java_library( name = "has_plugin", srcs = ["Foo.java"], - plugins = ["//third_party/auto_value:auto_value_plugin"], + deps = ["//third_party/java/auto_value"], ) java_library( name = "has_plugin_deps", srcs = ["Foo.java"], - deps = ["//third_party/auto_value"], + deps = ["//third_party/java/auto_value"], ) intellij_aspect_test_fixture( @@ -57,6 +57,6 @@ java_test( "//aspect/testing/rules:intellij_aspect_test_fixture_java_proto", "//intellij_platform_sdk:test_libs", "//proto:intellij_ide_info_java_proto", - "@junit//jar", + "//third_party/java/junit", ], ) diff --git a/aspect/testing/tests/src/com/google/idea/blaze/aspect/java/pluginprocessorjars/BazelPluginProcessorJarTest.java b/aspect/testing/tests/src/com/google/idea/blaze/aspect/java/pluginprocessorjars/BazelPluginProcessorJarTest.java index 21007ca917e..08570c64d27 100644 --- a/aspect/testing/tests/src/com/google/idea/blaze/aspect/java/pluginprocessorjars/BazelPluginProcessorJarTest.java +++ b/aspect/testing/tests/src/com/google/idea/blaze/aspect/java/pluginprocessorjars/BazelPluginProcessorJarTest.java @@ -32,10 +32,10 @@ */ @RunWith(JUnit4.class) public class BazelPluginProcessorJarTest extends BazelIntellijAspectTest { - // blaze and bazel have different annotation processor paths & names. + // The external repository name in these paths is simplified, actual paths will be mapped to match them. private static final String JAR_STR = - jarString("auto-value-1.6.2.jar", /*iJar=*/ null, /*sourceJar=*/ null); - private static final String OUTPUT_GROUP_FILES = "../auto_value/auto-value-1.6.2.jar"; + jarString("external/maven/com/google/auto/value/auto-value/1.10.4/processed_auto-value-1.10.4.jar", /*iJar=*/ null, /*sourceJar=*/ null); + private static final String OUTPUT_GROUP_FILES = "../maven/com/google/auto/value/auto-value/1.10.4/processed_auto-value-1.10.4.jar"; @Test public void ruleWithNoPlugins() throws Exception { @@ -52,10 +52,14 @@ public void ruleWithPlugins_createsPluginProcessorJars() throws Exception { assertThat( targetIdeInfo.getJavaIdeInfo().getPluginProcessorJarsList().stream() .map(IntellijAspectTest::libraryArtifactToString) + .map(p -> simplifyPath(p)) .collect(toList())) .contains(JAR_STR); - assertThat(getOutputGroupFiles(testFixture, "intellij-resolve-java")) + assertThat( + getOutputGroupFiles(testFixture, "intellij-resolve-java").stream() + .map(p -> simplifyPath(p)) + .collect(toList())) .contains(OUTPUT_GROUP_FILES); } @@ -67,9 +71,23 @@ public void ruleWithDeps_createsPluginProcessorJars() throws Exception { assertThat( targetIdeInfo.getJavaIdeInfo().getPluginProcessorJarsList().stream() .map(IntellijAspectTest::libraryArtifactToString) + .map(p -> simplifyPath(p)) .collect(toList())) .contains(JAR_STR); - assertThat(getOutputGroupFiles(testFixture, "intellij-resolve-java")) + + assertThat( + getOutputGroupFiles(testFixture, "intellij-resolve-java").stream() + .map(p -> simplifyPath(p)) + .collect(toList())) .contains(OUTPUT_GROUP_FILES); } + + /** Simplify external dependencies paths by simplifying the repository name part + * For example, + * `external/rules_jvm_external~5.3~maven~com_google_guava_guava/jar` will be + * `external/com_google_guava_guava/jar` + */ + private static String simplifyPath(String path) { + return path.replaceAll("/.*~", "/").replaceAll("/.*\\+", "/"); + } } diff --git a/aspect/testing/tests/src/com/google/idea/blaze/aspect/proto/jpl/BUILD b/aspect/testing/tests/src/com/google/idea/blaze/aspect/proto/jpl/BUILD index 8123e817c52..60a447e2974 100644 --- a/aspect/testing/tests/src/com/google/idea/blaze/aspect/proto/jpl/BUILD +++ b/aspect/testing/tests/src/com/google/idea/blaze/aspect/proto/jpl/BUILD @@ -1,5 +1,8 @@ licenses(["notice"]) +load("@protobuf//bazel:java_proto_library.bzl", "java_proto_library") +load("@protobuf//bazel:proto_library.bzl", "proto_library") +load("@rules_java//java:defs.bzl", "java_library", "java_test") load( "//aspect/testing/rules:intellij_aspect_test_fixture.bzl", "intellij_aspect_test_fixture", @@ -45,6 +48,6 @@ java_test( "//aspect/testing/rules:intellij_aspect_test_fixture_java_proto", "//intellij_platform_sdk:test_libs", "//proto:intellij_ide_info_java_proto", - "@junit//jar", + "//third_party/java/junit", ], ) diff --git a/aspect/testing/tests/src/com/google/idea/blaze/aspect/proto/jpl/JavaProtoLibraryTest.java b/aspect/testing/tests/src/com/google/idea/blaze/aspect/proto/jpl/JavaProtoLibraryTest.java index c144ab85783..1d45553a2c8 100644 --- a/aspect/testing/tests/src/com/google/idea/blaze/aspect/proto/jpl/JavaProtoLibraryTest.java +++ b/aspect/testing/tests/src/com/google/idea/blaze/aspect/proto/jpl/JavaProtoLibraryTest.java @@ -84,7 +84,7 @@ public void testJavaProtoLibrary() throws Exception { // intellij-info groups assertThat(getOutputGroupFiles(testFixture, "intellij-info-java")) - .containsAllOf( + .containsAtLeast( testRelative("lib.java-manifest"), testRelative(intellijInfoFileName("lib")), testRelative(intellijInfoFileName("bar_java_proto")), @@ -96,7 +96,7 @@ public void testJavaProtoLibrary() throws Exception { testRelative("lib.java-manifest"), testRelative(intellijInfoFileName("lib"))); assertThat(getOutputGroupFiles(testFixture, "intellij-info-java-direct-deps")) - .containsAllOf( + .containsAtLeast( testRelative("lib.java-manifest"), testRelative(intellijInfoFileName("lib")), testRelative(intellijInfoFileName("bar_java_proto")), @@ -108,37 +108,35 @@ public void testJavaProtoLibrary() throws Exception { assertThat(getOutputGroupFiles(testFixture, "intellij-resolve-java")) .containsExactly( // lib - testRelative("liblib.jar"), testRelative("liblib-hjar.jar"), testRelative("liblib-src.jar"), testRelative("liblib.jdeps"), // bar_proto - testRelative("libbar_proto-speed.jar"), testRelative("libbar_proto-speed-hjar.jar"), testRelative("bar_proto-speed-src.jar"), // foo_proto - testRelative("libfoo_proto-speed.jar"), testRelative("libfoo_proto-speed-hjar.jar"), testRelative("foo_proto-speed-src.jar")); assertThat(getOutputGroupFiles(testFixture, "intellij-resolve-java-outputs")) .containsExactly( - testRelative("liblib.jar"), testRelative("liblib-hjar.jar"), testRelative("liblib-src.jar"), testRelative("liblib.jdeps")); assertThat(getOutputGroupFiles(testFixture, "intellij-resolve-java-direct-deps")) - .containsAllOf( + .containsAtLeast( // lib - testRelative("liblib.jar"), testRelative("liblib-hjar.jar"), testRelative("liblib-src.jar"), testRelative("liblib.jdeps"), // bar_proto - testRelative("libbar_proto-speed.jar"), testRelative("libbar_proto-speed-hjar.jar"), testRelative("bar_proto-speed-src.jar"), // foo_proto (only hjar) testRelative("libfoo_proto-speed-hjar.jar")); + assertThat(getOutputGroupFiles(testFixture, "intellij-resolve-java-direct-deps")) + .doesNotContain(testRelative("liblib.jar")); + assertThat(getOutputGroupFiles(testFixture, "intellij-resolve-java-direct-deps")) + .doesNotContain(testRelative("libbar_proto-speed.jar")); // intellij-compile groups assertThat(getOutputGroupFiles(testFixture, "intellij-compile-java")) diff --git a/aspect/testing/tests/src/com/google/idea/blaze/aspect/python/pybinary/BUILD b/aspect/testing/tests/src/com/google/idea/blaze/aspect/python/pybinary/BUILD index 979f781f208..46d4afe70f0 100644 --- a/aspect/testing/tests/src/com/google/idea/blaze/aspect/python/pybinary/BUILD +++ b/aspect/testing/tests/src/com/google/idea/blaze/aspect/python/pybinary/BUILD @@ -1,3 +1,5 @@ +load("@rules_java//java:defs.bzl", "java_test") +load("@rules_python//python:defs.bzl", "py_binary") load( "//aspect/testing/rules:intellij_aspect_test_fixture.bzl", "intellij_aspect_test_fixture", @@ -92,6 +94,6 @@ java_test( "//aspect/testing/rules:intellij_aspect_test_fixture_java_proto", "//intellij_platform_sdk:test_libs", "//proto:intellij_ide_info_java_proto", - "@junit//jar", + "//third_party/java/junit", ], ) diff --git a/aspect/testing/tests/src/com/google/idea/blaze/aspect/python/pylibrary/BUILD b/aspect/testing/tests/src/com/google/idea/blaze/aspect/python/pylibrary/BUILD index a7c591eb5b3..b5063b3f691 100644 --- a/aspect/testing/tests/src/com/google/idea/blaze/aspect/python/pylibrary/BUILD +++ b/aspect/testing/tests/src/com/google/idea/blaze/aspect/python/pylibrary/BUILD @@ -1,3 +1,5 @@ +load("@rules_java//java:defs.bzl", "java_test") +load("@rules_python//python:defs.bzl", "py_library") load( "//aspect/testing/rules:intellij_aspect_test_fixture.bzl", "intellij_aspect_test_fixture", @@ -27,6 +29,6 @@ java_test( "//aspect/testing/rules:intellij_aspect_test_fixture_java_proto", "//intellij_platform_sdk:test_libs", "//proto:intellij_ide_info_java_proto", - "@junit//jar", + "//third_party/java/junit", ], ) diff --git a/aspect/testing/tests/src/com/google/idea/blaze/aspect/python/pytest/BUILD b/aspect/testing/tests/src/com/google/idea/blaze/aspect/python/pytest/BUILD index 277f6a1970a..4b25c8187cf 100644 --- a/aspect/testing/tests/src/com/google/idea/blaze/aspect/python/pytest/BUILD +++ b/aspect/testing/tests/src/com/google/idea/blaze/aspect/python/pytest/BUILD @@ -1,3 +1,5 @@ +load("@rules_java//java:defs.bzl", "java_test") +load("@rules_python//python:defs.bzl", "py_test") load( "//aspect/testing/rules:intellij_aspect_test_fixture.bzl", "intellij_aspect_test_fixture", @@ -28,6 +30,6 @@ java_test( "//aspect/testing/rules:intellij_aspect_test_fixture_java_proto", "//intellij_platform_sdk:test_libs", "//proto:intellij_ide_info_java_proto", - "@junit//jar", + "//third_party/java/junit", ], ) diff --git a/aspect/testing/tests/src/com/google/idea/blaze/aspect/scala/scalabinary/BUILD b/aspect/testing/tests/src/com/google/idea/blaze/aspect/scala/scalabinary/BUILD index 485aacdd2b2..3e8c4c7699f 100644 --- a/aspect/testing/tests/src/com/google/idea/blaze/aspect/scala/scalabinary/BUILD +++ b/aspect/testing/tests/src/com/google/idea/blaze/aspect/scala/scalabinary/BUILD @@ -38,6 +38,6 @@ java_test( "//aspect/testing/rules:intellij_aspect_test_fixture_java_proto", "//intellij_platform_sdk:test_libs", "//proto:intellij_ide_info_java_proto", - "@junit//jar", + "//third_party/java/junit", ], ) diff --git a/aspect/testing/tests/src/com/google/idea/blaze/aspect/scala/scalabinary/ScalaBinaryTest.java b/aspect/testing/tests/src/com/google/idea/blaze/aspect/scala/scalabinary/ScalaBinaryTest.java index a5521e7aea7..69149e8e986 100644 --- a/aspect/testing/tests/src/com/google/idea/blaze/aspect/scala/scalabinary/ScalaBinaryTest.java +++ b/aspect/testing/tests/src/com/google/idea/blaze/aspect/scala/scalabinary/ScalaBinaryTest.java @@ -44,13 +44,15 @@ public void testScalaBinary() throws Exception { assertThat(binaryInfo.getJavaIdeInfo().getMainClass()).isEqualTo("com.google.MyMainClass"); assertThat(getOutputGroupFiles(testFixture, "intellij-info-java")) - .containsAllOf( + .containsAtLeast( testRelative(intellijInfoFileName("foolib")), testRelative(intellijInfoFileName("foo"))); assertThat(getOutputGroupFiles(testFixture, "intellij-resolve-java")) - .containsAllOf(testRelative("foolib.jar"), testRelative("foo.jar")); + .contains(testRelative("foo.jar")); + assertThat(getOutputGroupFiles(testFixture, "intellij-resolve-java")) + .doesNotContain(testRelative("libfoo.jar")); assertThat(getOutputGroupFiles(testFixture, "intellij-compile-java")) - .containsAllOf(testRelative("foolib.jar"), testRelative("foo.jar")); + .containsAtLeast(testRelative("foolib.jar"), testRelative("foo.jar")); assertThat(getOutputGroupFiles(testFixture, "intellij-info-generic")).isEmpty(); } } diff --git a/aspect/testing/tests/src/com/google/idea/blaze/aspect/scala/scalalibrary/BUILD b/aspect/testing/tests/src/com/google/idea/blaze/aspect/scala/scalalibrary/BUILD index 19b71b77b12..d067a7ebc29 100644 --- a/aspect/testing/tests/src/com/google/idea/blaze/aspect/scala/scalalibrary/BUILD +++ b/aspect/testing/tests/src/com/google/idea/blaze/aspect/scala/scalalibrary/BUILD @@ -29,6 +29,6 @@ java_test( "//aspect/testing/rules:intellij_aspect_test_fixture_java_proto", "//intellij_platform_sdk:test_libs", "//proto:intellij_ide_info_java_proto", - "@junit//jar", + "//third_party/java/junit", ], ) diff --git a/aspect/testing/tests/src/com/google/idea/blaze/aspect/scala/scalalibrary/ScalaLibraryTest.java b/aspect/testing/tests/src/com/google/idea/blaze/aspect/scala/scalalibrary/ScalaLibraryTest.java index 35b6b6bccb0..40f3d3ee10f 100644 --- a/aspect/testing/tests/src/com/google/idea/blaze/aspect/scala/scalalibrary/ScalaLibraryTest.java +++ b/aspect/testing/tests/src/com/google/idea/blaze/aspect/scala/scalalibrary/ScalaLibraryTest.java @@ -45,7 +45,7 @@ public void testScalaLibrary() throws Exception { // Also contains ijars for scala-library. // Also contains jars + srcjars for liblibrary. assertThat(getOutputGroupFiles(testFixture, "intellij-resolve-java")) - .contains(testRelative("simple.jar")); + .containsAnyOf(testRelative("simple-srcjar.jar"), testRelative("simple-ijar.jar")); assertThat(getOutputGroupFiles(testFixture, "intellij-info-java")) .contains(testRelative(intellijInfoFileName("simple"))); diff --git a/aspect/testing/tests/src/com/google/idea/blaze/aspect/scala/scalamacrolibrary/BUILD b/aspect/testing/tests/src/com/google/idea/blaze/aspect/scala/scalamacrolibrary/BUILD index 3e77908a74c..a899a0c5f90 100644 --- a/aspect/testing/tests/src/com/google/idea/blaze/aspect/scala/scalamacrolibrary/BUILD +++ b/aspect/testing/tests/src/com/google/idea/blaze/aspect/scala/scalamacrolibrary/BUILD @@ -29,6 +29,6 @@ java_test( "//aspect/testing/rules:intellij_aspect_test_fixture_java_proto", "//intellij_platform_sdk:test_libs", "//proto:intellij_ide_info_java_proto", - "@junit//jar", + "//third_party/java/junit", ], ) diff --git a/aspect/testing/tests/src/com/google/idea/blaze/aspect/scala/scalatest/BUILD b/aspect/testing/tests/src/com/google/idea/blaze/aspect/scala/scalatest/BUILD index 058fbdde30d..41cc5c75d05 100644 --- a/aspect/testing/tests/src/com/google/idea/blaze/aspect/scala/scalatest/BUILD +++ b/aspect/testing/tests/src/com/google/idea/blaze/aspect/scala/scalatest/BUILD @@ -31,6 +31,6 @@ java_test( "//aspect/testing/rules:intellij_aspect_test_fixture_java_proto", "//intellij_platform_sdk:test_libs", "//proto:intellij_ide_info_java_proto", - "@junit//jar", + "//third_party/java/junit", ], ) diff --git a/aspect/tools/BUILD b/aspect/tools/BUILD index 56f95de380d..2f7a47a4e99 100644 --- a/aspect/tools/BUILD +++ b/aspect/tools/BUILD @@ -3,6 +3,8 @@ # Tools needed by the bazel plugin's aspect. # +load("@rules_java//java:defs.bzl", "java_binary", "java_library", "java_test") + package(default_visibility = ["//aspect:__pkg__"]) licenses(["notice"]) @@ -12,17 +14,18 @@ licenses(["notice"]) java_library( name = "guava", visibility = ["//visibility:private"], - exports = ["//intellij_platform_sdk:guava_for_external_binaries"], + exports = ["//intellij_platform_sdk:guava"], ) java_library( name = "lib", srcs = glob(["src/**/*.java"]), + javacopts = ["-source 8 -target 8"], deps = [ ":guava", - "//proto:proto_deps", - "@jsr305_annotations//jar", "//third_party/bazel/src/main/protobuf:worker_protocol_java_proto", + "@jsr305_annotations//jar", + "//proto:proto_deps", ], ) @@ -60,10 +63,10 @@ java_library( exports = [ ":guava", ":lib", + "//proto:proto_deps", + "//third_party/java/junit", "//intellij_platform_sdk:jsr305", "//intellij_platform_sdk:truth", - "//proto:proto_deps", - "@junit//jar", ], ) @@ -82,6 +85,7 @@ java_test( test_class = "com.google.idea.blaze.aspect.PackageParserTest", deps = [ ":test_lib", + "//intellij_platform_sdk:plugin_api", "@error_prone_annotations//jar", ], ) diff --git a/aspect/tools/src/com/google/idea/blaze/aspect/PackageParser.java b/aspect/tools/src/com/google/idea/blaze/aspect/PackageParser.java index 92fbc6c41cb..e55cb8b46ec 100644 --- a/aspect/tools/src/com/google/idea/blaze/aspect/PackageParser.java +++ b/aspect/tools/src/com/google/idea/blaze/aspect/PackageParser.java @@ -37,6 +37,7 @@ import java.util.List; import java.util.Map; import java.util.Map.Entry; +import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.logging.Level; import java.util.logging.Logger; @@ -113,8 +114,9 @@ private static void runPersistentWorker(PackageParser parser) throws IOException } public static void main(String[] args) throws Exception { + ExecutorService executorService = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors()); PackageParserOptions options = parseArgs(args); - PackageParser parser = new PackageParser(PackageParserIoProvider.INSTANCE); + PackageParser parser = new PackageParser(PackageParserIoProvider.INSTANCE, executorService); try { if (isWorkerMode(args)) { @@ -150,9 +152,12 @@ private static String[] parseParamFileIfUsed(String[] args) { private final PackageParserIoProvider ioProvider; + private final ExecutorService executorService; + @VisibleForTesting - PackageParser(PackageParserIoProvider ioProvider) { + PackageParser(PackageParserIoProvider ioProvider, ExecutorService executorService) { this.ioProvider = ioProvider; + this.executorService = executorService; } @VisibleForTesting @@ -180,8 +185,7 @@ Map parsePackageStrings(List sources throws Exception { ListeningExecutorService executorService = - MoreExecutors.listeningDecorator( - Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors())); + MoreExecutors.listeningDecorator(this.executorService); Map> futures = Maps.newHashMap(); for (final ArtifactLocation source : sources) { diff --git a/aspect/tools/tests/unittests/com/google/idea/blaze/aspect/ArtifactLocationParserTest.java b/aspect/tools/tests/unittests/com/google/idea/blaze/aspect/ArtifactLocationParserTest.java index 3f0e338e90d..f7178b2b06e 100644 --- a/aspect/tools/tests/unittests/com/google/idea/blaze/aspect/ArtifactLocationParserTest.java +++ b/aspect/tools/tests/unittests/com/google/idea/blaze/aspect/ArtifactLocationParserTest.java @@ -116,7 +116,7 @@ private void assertFails(String input, String expectedError) { ArtifactLocationParser.parse(input); fail(); } catch (IllegalArgumentException e) { - assertThat(e).hasMessage(expectedError); + assertThat(e).hasMessageThat().isEqualTo(expectedError); } } } diff --git a/aspect/tools/tests/unittests/com/google/idea/blaze/aspect/OptionParserTest.java b/aspect/tools/tests/unittests/com/google/idea/blaze/aspect/OptionParserTest.java index 37f18c49c8d..e91ccd08055 100644 --- a/aspect/tools/tests/unittests/com/google/idea/blaze/aspect/OptionParserTest.java +++ b/aspect/tools/tests/unittests/com/google/idea/blaze/aspect/OptionParserTest.java @@ -49,7 +49,7 @@ public void testParseSingleOption() throws Exception { OptionParser.parseSingleOption(new String[] {"--foo", "1", "--bar"}, "bar", String::toString); fail("Expected failure"); } catch (IllegalArgumentException e) { - assertThat(e).hasMessage("Expected value after --bar"); + assertThat(e).hasMessageThat().isEqualTo("Expected value after --bar"); } // Test that a single-value flag should not appear multiple times. try { @@ -57,7 +57,7 @@ public void testParseSingleOption() throws Exception { new String[] {"--foo", "1", "--foo", "2"}, "foo", String::toString); fail("Expected failure"); } catch (IllegalArgumentException e) { - assertThat(e).hasMessage("Expected --foo to appear at most once"); + assertThat(e).hasMessageThat().isEqualTo("Expected --foo to appear at most once"); } } @@ -89,7 +89,7 @@ public void testParseMultiOption() throws Exception { new String[] {"--foo", "1", "--bar", "2", "--foo"}, "foo", String::toString); fail("Expected failure"); } catch (IllegalArgumentException e) { - assertThat(e).hasMessage("Expected value after --foo"); + assertThat(e).hasMessageThat().isEqualTo("Expected value after --foo"); } } } diff --git a/aspect/tools/tests/unittests/com/google/idea/blaze/aspect/PackageParserTest.java b/aspect/tools/tests/unittests/com/google/idea/blaze/aspect/PackageParserTest.java index 18a6b0ee88e..9fa8d6a1cea 100644 --- a/aspect/tools/tests/unittests/com/google/idea/blaze/aspect/PackageParserTest.java +++ b/aspect/tools/tests/unittests/com/google/idea/blaze/aspect/PackageParserTest.java @@ -38,6 +38,8 @@ import java.nio.file.Paths; import java.util.List; import java.util.Map; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -107,13 +109,15 @@ public void writeProto(MessageLite message, Path file) throws IOException { .setIsSource(false) .build(); + private ExecutorService executorService; private MockPackageParserIoProvider mockIoProvider; private PackageParser parser; @Before public void setUp() { + executorService = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors()); mockIoProvider = new MockPackageParserIoProvider(); - parser = new PackageParser(mockIoProvider); + parser = new PackageParser(mockIoProvider, executorService); } private Map parsePackageStrings() throws Exception { diff --git a/aspect_template/BUILD b/aspect_template/BUILD new file mode 100644 index 00000000000..0ce268dbb73 --- /dev/null +++ b/aspect_template/BUILD @@ -0,0 +1,54 @@ +filegroup( + name = "aspect_files", + srcs = [ + "BUILD.bazel", + "WORKSPACE", + "code_generator_info.bzl", + "code_generator_info.template.bzl", + "java_info.bzl", + "java_info.template.bzl", + "python_info.bzl", + "python_info.template.bzl" + ], + visibility = ["//visibility:public"], +) + +STRIP_TEMPLATE_SCRIPT = """cat $(SRCS) >$@ && +sed -i -e '/TEMPLATE-IGNORE-BEGIN/,/TEMPLATE-IGNORE-END/d' $@ && +sed -i -e '/TEMPLATE-INCLUDE-BEGIN/,/TEMPLATE-INCLUDE-END/{s/^[#][#]//;}' $@ +""" + +genrule( + name = "generate_java_info_template", + srcs = ["java_info.bzl"], + outs = ["java_info.template.bzl"], + cmd = STRIP_TEMPLATE_SCRIPT, +) + +genrule( + name = "generate_py_info_template", + srcs = ["python_info.bzl"], + outs = ["python_info.template.bzl"], + cmd = STRIP_TEMPLATE_SCRIPT, +) + +genrule( + name = "generate_code_generator_info_template", + srcs = ["code_generator_info.bzl"], + outs = ["code_generator_info.template.bzl"], + cmd = STRIP_TEMPLATE_SCRIPT, +) + +genrule( + name = "rename_files", + srcs = ["BUILD.aspect"], + outs = ["BUILD.bazel"], + cmd = "cp $< $@", +) + +genrule( + name = "create_workspace_file", + outs = ["WORKSPACE"], + srcs = [], + cmd = r"""echo 'workspace(name = "intellij_aspect_template")' > $@""" +) \ No newline at end of file diff --git a/aspect_template/BUILD.aspect b/aspect_template/BUILD.aspect new file mode 100644 index 00000000000..e69de29bb2d diff --git a/aspect_template/MODULE.bazel b/aspect_template/MODULE.bazel new file mode 100644 index 00000000000..e69de29bb2d diff --git a/aspect_template/code_generator_info.bzl b/aspect_template/code_generator_info.bzl new file mode 100644 index 00000000000..5702f507381 --- /dev/null +++ b/aspect_template/code_generator_info.bzl @@ -0,0 +1,18 @@ +"""Data required for the code-generator system""" + +# The following is a list of the languages to the set of Rule names +# which can be considered code-generators for that language. Look +# for the `get_code_generator_rule_names` function in the aspect +# logic that integrates with this constant. + +CODE_GENERATOR_RULE_NAMES = struct( +# TEMPLATE-INCLUDE-BEGIN +###foreach( $aLanguageClassRuleNames in $languageClassRuleNames ) +## $aLanguageClassRuleNames.languageClass.name = [ +###foreach ( $aRuleName in $aLanguageClassRuleNames.ruleNames ) +## "$aRuleName", +###end +## ], +###end +# TEMPLATE-INCLUDE-END +) diff --git a/aspect_template/java_info.bzl b/aspect_template/java_info.bzl new file mode 100644 index 00000000000..7d545c7dc7d --- /dev/null +++ b/aspect_template/java_info.bzl @@ -0,0 +1,50 @@ +# TEMPLATE-INCLUDE-BEGIN +###if( $isJavaEnabled == "true" && $bazel8OrAbove == "true" ) +##load("@rules_java//java/common:java_info.bzl", "JavaInfo") +###end +# TEMPLATE-INCLUDE-END + +def java_info_in_target(target): +# TEMPLATE-IGNORE-BEGIN + return JavaInfo in target +# TEMPLATE-IGNORE-END + +# TEMPLATE-INCLUDE-BEGIN +## #if( $isJavaEnabled == "true" ) +## return JavaInfo in target +## #else +## return None +## #end +# TEMPLATE-INCLUDE-END + +def get_java_info(target): +# TEMPLATE-IGNORE-BEGIN + if JavaInfo in target: + return target[JavaInfo] + else: + return None +# TEMPLATE-IGNORE-END + +# TEMPLATE-INCLUDE-BEGIN +## #if( $isJavaEnabled == "true" ) +## if JavaInfo in target: +## return target[JavaInfo] +## else: +## return None +## #else +## return None +## #end +# TEMPLATE-INCLUDE-END + +def java_info_reference(): +# TEMPLATE-IGNORE-BEGIN + return [JavaInfo] +# TEMPLATE-IGNORE-END + +# TEMPLATE-INCLUDE-BEGIN +## #if( $isJavaEnabled == "true" ) +## return [JavaInfo] +## #else +## return [] +## #end +# TEMPLATE-INCLUDE-END diff --git a/aspect_template/python_info.bzl b/aspect_template/python_info.bzl new file mode 100644 index 00000000000..90aaca19d3d --- /dev/null +++ b/aspect_template/python_info.bzl @@ -0,0 +1,37 @@ +# TEMPLATE-INCLUDE-BEGIN +###if( $isPythonEnabled == "true" && $bazel8OrAbove == "true" ) +##load("@rules_python//python:defs.bzl", "PyInfo") +###end +# TEMPLATE-INCLUDE-END + +def py_info_in_target(target): +# TEMPLATE-IGNORE-BEGIN + return PyInfo in target +# TEMPLATE-IGNORE-END + +# TEMPLATE-INCLUDE-BEGIN +## #if( $isPythonEnabled == "true" ) +## return PyInfo in target +## #else +## return None +## #end +# TEMPLATE-INCLUDE-END + +def get_py_info(target): +# TEMPLATE-IGNORE-BEGIN + if PyInfo in target: + return target[PyInfo] + else: + return None +# TEMPLATE-IGNORE-END + +# TEMPLATE-INCLUDE-BEGIN +## #if( $isPythonEnabled == "true" ) +## if PyInfo in target: +## return target[PyInfo] +## else: +## return None +## #else +## return None +## #end +# TEMPLATE-INCLUDE-END \ No newline at end of file diff --git a/aswb/BUILD b/aswb/BUILD index d2644422481..c7ddae541bc 100644 --- a/aswb/BUILD +++ b/aswb/BUILD @@ -2,8 +2,18 @@ # Description: Builds ASwB for blaze and bazel # +load("@bazel_skylib//rules:build_test.bzl", "build_test") +load( + "//:build-visibility.bzl", + "ASWB_PACKAGES_VISIBILITY", + "ASWB_PLUGIN_PACKAGES_VISIBILITY", + "ASWB_SUBPACKAGES_VISIBILITY", + "DEFAULT_TEST_VISIBILITY", + "TEST_ASWB_SUBPACKAGES_VISIBILITY", +) load( "//build_defs:build_defs.bzl", + "combine_visibilities", "intellij_plugin", "intellij_plugin_library", "optional_plugin_xml", @@ -11,34 +21,25 @@ load( "repackaged_files", "stamped_plugin_xml", ) + +# BEGIN-REPO load( - "//build_defs:intellij_plugin_debug_target.bzl", - "intellij_plugin_debug_target", -) -load("//:version.bzl", "VERSION") -load( - "//intellij_platform_sdk:build_defs.bzl", - "combine_visibilities", - "select_for_plugin_api", + "//build_defs:restrictions.bzl", + "ALLOWED_EXTERNAL_TEST_DEPENDENCIES", + "EXISTING_EXTERNAL_TEST_VIOLATIONS", + "validate_test_dependencies", ) + +# END-REPO load( "//testing:test_defs.bzl", "intellij_integration_test_suite", "intellij_unit_test_suite", ) -load( - "//:build-visibility.bzl", - "ASWB_PACKAGES_VISIBILITY", - "ASWB_PLUGIN_PACKAGES_VISIBILITY", - "ASWB_SUBPACKAGES_VISIBILITY", - "TEST_ASWB_SUBPACKAGES_VISIBILITY", -) - -licenses(["notice"]) optional_plugin_xml( name = "optional_ndk_xml", - module = "com.android.tools.ndk", + module = ["com.android.tools.ndk"], plugin_xml = "src/META-INF/ndk_contents.xml", ) @@ -60,27 +61,14 @@ stamped_plugin_xml( since_build_numbers = {"212": "212.5080.55"}, stamp_since_build = True, stamp_until_build = True, - version = VERSION, + version_file = ":plugin_version.txt", ) java_library( name = "unit_test_utils", testonly = 1, - srcs = glob(["tests/utils/unit/**/*.java"]) + select_for_plugin_api({ - "android-studio-2022.2": [ - "tests/utils/sdkcompat/as222/com/android/tools/idea/rendering/RenderResultCompat.java", - ], - "android-studio-2022.3": [ - "tests/utils/sdkcompat/as223/com/android/tools/idea/rendering/RenderResultCompat.java", - ], - "android-studio-2023.1": [ - "tests/utils/sdkcompat/as231/com/android/tools/idea/rendering/RenderResultCompat.java", - ], - "android-studio-dev": [ - "tests/utils/sdkcompat/asdev/com/android/tools/idea/rendering/RenderResultCompat.java", - ], - }), - visibility = TEST_ASWB_SUBPACKAGES_VISIBILITY, + srcs = glob(["tests/utils/unit/**/*.java"]), + visibility = combine_visibilities(TEST_ASWB_SUBPACKAGES_VISIBILITY, DEFAULT_TEST_VISIBILITY), deps = [ ":aswb_lib", "//base", @@ -93,55 +81,34 @@ java_library( java_library( name = "integration_test_utils", testonly = 1, - srcs = glob(["tests/utils/integration/**/*.java"]) + select_for_plugin_api({ - "android-studio-2022.2": [ - "tests/utils/sdkcompat/as222/com/android/tools/idea/sdk/IdeSdksCompat.java", - "tests/utils/sdkcompat/as222/com/google/idea/blaze/android/functional/AndroidDeviceCompat.java", - "tests/utils/sdkcompat/as222/com/google/idea/blaze/android/tools/idea/run/editor/AndroidDebuggerCompat.java", - ], - "android-studio-2022.3": [ - "tests/utils/sdkcompat/as223/com/android/tools/idea/sdk/IdeSdksCompat.java", - "tests/utils/sdkcompat/as223/com/google/idea/blaze/android/functional/AndroidDeviceCompat.java", - "tests/utils/sdkcompat/as223/com/google/idea/blaze/android/tools/idea/run/editor/AndroidDebuggerCompat.java", - ], - "android-studio-2023.1": [ - "tests/utils/sdkcompat/as231/com/android/tools/idea/sdk/IdeSdksCompat.java", - "tests/utils/sdkcompat/as231/com/google/idea/blaze/android/functional/AndroidDeviceCompat.java", - "tests/utils/sdkcompat/as231/com/google/idea/blaze/android/tools/idea/run/editor/AndroidDebuggerCompat.java", - ], - "android-studio-dev": [ - "tests/utils/sdkcompat/asdev/com/android/tools/idea/sdk/IdeSdksCompat.java", - "tests/utils/sdkcompat/asdev/com/google/idea/blaze/android/functional/AndroidDeviceCompat.java", - "tests/utils/sdkcompat/asdev/com/google/idea/blaze/android/tools/idea/run/editor/AndroidDebuggerCompat.java", - ], - }), + srcs = glob(["tests/utils/integration/**/*.java"]), visibility = TEST_ASWB_SUBPACKAGES_VISIBILITY, deps = [ ":aswb_lib", - ":unit_test_utils", "//base", "//base:integration_test_utils", "//base:unit_test_utils", "//cpp", + "//java", + "//shared:artifact", + "//testing:lib", + "//third_party/java/junit", + "//intellij_platform_sdk:plugin_api", "//intellij_platform_sdk:jsr305", "//intellij_platform_sdk:plugin_api_for_tests", # unuseddeps: keep "//intellij_platform_sdk:test_libs", - "//java", - "//testing:lib", "@com_google_guava_guava//jar", - "@error_prone_annotations//jar", - "@junit//jar", ], ) java_library( name = "aswb_lib", - srcs = glob(["src/**/*.java"]) + select_for_plugin_api({ - "android-studio-2022.2": glob(["sdkcompat/as222/**/*.java"]), - "android-studio-2022.3": glob(["sdkcompat/as223/**/*.java"]), - "android-studio-2023.1": glob(["sdkcompat/as231/**/*.java"]), - "android-studio-dev": glob(["sdkcompat/asdev/**/*.java"]), - }), + srcs = glob( + [ + "src/**/*.java", + "src/com/google/idea/blaze/android/run/binary/tasks/*.java", + ], + ), resources = glob(["resources/**/*"]), visibility = combine_visibilities( ASWB_SUBPACKAGES_VISIBILITY, @@ -150,14 +117,16 @@ java_library( deps = [ "//base", "//common/experiments", - "//intellij_platform_sdk:jsr305", # unuseddeps: keep - "//intellij_platform_sdk:kotlin", - "//intellij_platform_sdk:plugin_api", + "//cpp", "//java", "//proto:proto_deps", + "//querysync", "//shared", - "//third_party/auto_value", - "@gson//jar", + "//shared:artifact", + "//third_party/java/auto_value", + "//intellij_platform_sdk:plugin_api", + "//intellij_platform_sdk:jsr305", # unuseddeps: keep + "//intellij_platform_sdk:kotlin", ], ) @@ -165,9 +134,13 @@ intellij_unit_test_suite( name = "unit_tests", srcs = glob( ["tests/unittests/**/*.java"], - exclude = ["tests/unittests/com/google/idea/blaze/android/sync/model/idea/BlazeClassJarProviderTest.java"], # b/145809318 + exclude = [ + "tests/unittests/com/google/idea/blaze/android/sync/model/idea/BlazeClassJarProviderTest.java", # b/145809318 + ], ), + tags = ["noci:studio-win"], test_package_root = "com.google.idea.blaze.android", + visibility = DEFAULT_TEST_VISIBILITY, deps = [ ":aswb_lib", ":unit_test_utils", @@ -175,15 +148,16 @@ intellij_unit_test_suite( "//base:unit_test_utils", "//common/experiments", "//common/experiments:unit_test_utils", - "//intellij_platform_sdk:jsr305", - "//intellij_platform_sdk:plugin_api_for_tests", - "//intellij_platform_sdk:test_libs", "//java", "//proto:proto_deps", "//shared", + "//shared:artifact", "//testing:lib", + "//third_party/java/junit", + "//intellij_platform_sdk:jsr305", + "//intellij_platform_sdk:plugin_api_for_tests", + "//intellij_platform_sdk:test_libs", "@com_google_guava_guava//jar", - "@junit//jar", ], ) @@ -193,6 +167,7 @@ test_suite( #b/139825934 ":NdkDependenciesTest", ":normal_integration_tests", ], + visibility = DEFAULT_TEST_VISIBILITY, ) intellij_integration_test_suite( @@ -203,23 +178,17 @@ intellij_integration_test_suite( ], exclude = [ "tests/integrationtests/com/google/idea/blaze/android/plugin/NdkDependenciesTest.java", # Extracted to separate target - "tests/integrationtests/com/google/idea/blaze/android/functional/AswbRenderTaskTest.java", # b/177371104 "tests/integrationtests/com/google/idea/blaze/android/functional/AswbMergedManifestTest.java", #b/222322106 ], ), - additional_class_rules = select_for_plugin_api({ - "android-studio-2022.2": ["com.google.idea.blaze.android.NormalIntegrationTestSetupRule"], - "android-studio-2022.3": ["com.google.idea.blaze.android.NormalIntegrationTestSetupRule"], - "android-studio-2023.1": ["com.google.idea.blaze.android.NormalIntegrationTestSetupRule"], - "android-studio-dev": ["com.google.idea.blaze.android.NormalIntegrationTestSetupRule"], - "default": [], - }), + additional_class_rules = [], data = [ "testdata/golden.png", "testdata/ic_banner.png", "tools/adt/idea/android/annotations/empty_file", ], - required_plugins = "com.google.idea.bazel.aswb", + required_plugins = "com.google.idea.bazel.aswb,com.android.tools.ndk", + tags = ["noci:studio-win"], test_package_root = "com.google.idea.blaze.android", runtime_deps = [ ":aswb_bazel", @@ -236,14 +205,15 @@ intellij_integration_test_suite( "//common/experiments", "//common/experiments:unit_test_utils", "//cpp", + "//java", + "//proto:proto_deps", + "//shared:artifact", + "//third_party/java/junit", + "//intellij_platform_sdk:plugin_api", "//intellij_platform_sdk:jsr305", "//intellij_platform_sdk:plugin_api_for_tests", "//intellij_platform_sdk:test_libs", - "//java", - "//proto:proto_deps", "@com_google_guava_guava//jar", - "@gson//jar", - "@junit//jar", ], ) @@ -251,6 +221,7 @@ intellij_integration_test_suite( name = "NdkDependenciesTest", srcs = ["tests/integrationtests/com/google/idea/blaze/android/plugin/NdkDependenciesTest.java"], required_plugins = "com.google.idea.bazel.aswb", + tags = ["noci:studio-win"], test_package_root = "com.google.idea.blaze.android", runtime_deps = [ ":aswb_bazel", @@ -262,10 +233,10 @@ intellij_integration_test_suite( "//base", "//base:integration_test_utils", "//base:unit_test_utils", + "//proto:proto_deps", + "//third_party/java/junit", "//intellij_platform_sdk:plugin_api_for_tests", "//intellij_platform_sdk:test_libs", - "//proto:proto_deps", - "@junit//jar", ], ) @@ -283,7 +254,6 @@ intellij_plugin( "//java:plugin_library", "//kotlin:plugin_library", "//plugin_dev:plugin_library", - "//python:plugin_library", "//skylark:plugin_library", "//terminal:plugin_library", ], @@ -298,40 +268,70 @@ repackaged_files( repackaged_files( name = "aspect_directory", srcs = ["//aspect:aspect_files"], + # Build aspect tools with Java 8 so they can work with any Java version in users workspace. + java_copts = [ + "-source", + "8", + "-target", + "8", + ], prefix = "aswb/aspect", strip_prefix = "/aspect", visibility = ASWB_PACKAGES_VISIBILITY, ) -repackaged_files( - name = "fast_build_javac", - srcs = ["//java:fast_build_javac"], - prefix = "aswb/lib", - visibility = ASWB_PACKAGES_VISIBILITY, -) - -intellij_plugin_debug_target( - name = "aswb_bazel_dev", - deps = [ - ":aspect_directory", - ":fast_build_javac", - ":plugin_jar", - ], -) - plugin_deploy_zip( name = "aswb_bazel_zip", srcs = [ ":aspect_directory", - ":fast_build_javac", ":plugin_jar", ], visibility = ["//visibility:public"], zip_filename = "aswb_bazel.zip", ) +build_test( + name = "aswb_bazel_build_test", + targets = [ + ":aswb_bazel_zip", + ], +) + genrule( name = "create_empty_annotations_folder", outs = ["tools/adt/idea/android/annotations/empty_file"], cmd = "echo \"No contents\" > $@", ) + +# BEGIN-REPO +validate_test_dependencies( + name = "validate_test_dependencies", + allowed_external_dependencies = ALLOWED_EXTERNAL_TEST_DEPENDENCIES, + existing_external_violations = EXISTING_EXTERNAL_TEST_VIOLATIONS, + deps = [ + "//:aswb_tests", + "//aswb:aswb_bazel_build_test", + "//common/experiments:unit_tests", + "//common/ui/properties:unit_tests", + "//common/util:CommandLineTaskTest", + "//querysync:cli_tools_build_test", + "//shared:tests", + ], +) +# END-REPO + +# Dump the plugin version to a file to be used in stamping the plugin xml +genrule( + name = "plugin_version", + outs = ["plugin_version.txt"], + cmd = """ +# bazel-out/stable-status.txt is created when stamp = True +# Value of BUILD_EMBED_LABEL key comes from --embed_label on the command line +version="$$(grep BUILD_EMBED_LABEL bazel-out/stable-status.txt | cut -d ' ' -f 2)" +# Set a default version if --embed_label was not specified +if [ -z "$$version" ]; then version="9999"; fi + +echo "$$version" > $@ +""", + stamp = True, +) diff --git a/aswb/aswb.bazelproject b/aswb/aswb.bazelproject index 96d6a6a7271..015b3e045d8 100644 --- a/aswb/aswb.bazelproject +++ b/aswb/aswb.bazelproject @@ -22,3 +22,7 @@ test_sources: */testcompat/unittests* */testcompat/integrationtests* */testcompat/utils/integration* + +additional_languages: + kotlin + diff --git a/aswb/aswb.iml b/aswb/aswb.iml deleted file mode 100644 index 37230b3044b..00000000000 --- a/aswb/aswb.iml +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/aswb/sdkcompat/as222/com/android/tools/idea/BaseAsCompat.java b/aswb/sdkcompat/as222/com/android/tools/idea/BaseAsCompat.java deleted file mode 100644 index e43e7f4dea4..00000000000 --- a/aswb/sdkcompat/as222/com/android/tools/idea/BaseAsCompat.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright 2022 The Bazel Authors. All rights reserved. - * - * 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. - */ -package com.android.tools.idea; - -import com.android.tools.idea.run.tasks.LaunchResult; - -/** Simple compat utilities across various versions of AS plugin SDK. */ -public class BaseAsCompat { - // #api212 - public static boolean wasSuccessfulLaunch(LaunchResult launchResult) { - return launchResult.getResult() == LaunchResult.Result.SUCCESS; - } - - private BaseAsCompat() {} -} diff --git a/aswb/sdkcompat/as222/com/android/tools/idea/model/AndroidManifestIndexCompat.java b/aswb/sdkcompat/as222/com/android/tools/idea/model/AndroidManifestIndexCompat.java deleted file mode 100644 index 82eb27bee0c..00000000000 --- a/aswb/sdkcompat/as222/com/android/tools/idea/model/AndroidManifestIndexCompat.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright 2022 The Bazel Authors. All rights reserved. - * - * 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. - */ -package com.android.tools.idea.model; - -/** Compat class for {@link com.android.tools.idea.model.AndroidManifestIndex}. */ -public class AndroidManifestIndexCompat { - - private AndroidManifestIndexCompat() {} - - /** {@code indexEnabled} was removed in Studio 2021.2. #api211 */ - public static boolean indexEnabled() { - return true; - } -} diff --git a/aswb/sdkcompat/as222/com/android/tools/idea/progress/StudioLoggerProgressIndicatorCompat.java b/aswb/sdkcompat/as222/com/android/tools/idea/progress/StudioLoggerProgressIndicatorCompat.java deleted file mode 100644 index 7f9654b2ccf..00000000000 --- a/aswb/sdkcompat/as222/com/android/tools/idea/progress/StudioLoggerProgressIndicatorCompat.java +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright 2022 The Bazel Authors. All rights reserved. - * - * 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. - */ -package com.android.tools.idea.progress; - -/** Compat layer for StudioLoggerProgressIndicator which moved packages in 2021.2. #api211 */ -public class StudioLoggerProgressIndicatorCompat extends StudioLoggerProgressIndicator { - public StudioLoggerProgressIndicatorCompat(Class c) { - super(c); - } -} diff --git a/aswb/sdkcompat/as222/com/android/tools/idea/run/AndroidSessionInfoCompat.java b/aswb/sdkcompat/as222/com/android/tools/idea/run/AndroidSessionInfoCompat.java deleted file mode 100644 index 783ad5d39e4..00000000000 --- a/aswb/sdkcompat/as222/com/android/tools/idea/run/AndroidSessionInfoCompat.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright 2022 The Bazel Authors. All rights reserved. - * - * 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. - */ -package com.android.tools.idea.run; - -import com.android.ddmlib.Client; -import com.android.tools.idea.execution.common.AndroidSessionInfo; -import com.intellij.debugger.engine.RemoteDebugProcessHandler; -import com.intellij.execution.ExecutionTarget; -import com.intellij.execution.configurations.RunConfiguration; -import com.intellij.execution.process.ProcessHandler; -import com.intellij.execution.ui.RunContentDescriptor; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -/** Compat class for AndroidSessionInfo */ -public class AndroidSessionInfoCompat { - - private AndroidSessionInfoCompat() {} - - public static AndroidSessionInfo create( - @NotNull ProcessHandler processHandler, - @NotNull RunContentDescriptor descriptor, - @Nullable RunConfiguration runConfiguration, - @NotNull String executorId, - @NotNull String executorActionName, - @NotNull ExecutionTarget executionTarget) { - return AndroidSessionInfo.create(processHandler, runConfiguration, executorId, executionTarget); - } - - @Nullable - public static RunContentDescriptor getDescriptor(AndroidSessionInfo session) { - return null; - } - - public static void putAndroidDebugClient(RemoteDebugProcessHandler handler, Client client) {} -} diff --git a/aswb/sdkcompat/as222/com/android/tools/idea/run/ValidationErrorCompat.java b/aswb/sdkcompat/as222/com/android/tools/idea/run/ValidationErrorCompat.java deleted file mode 100644 index fdd0f36cf47..00000000000 --- a/aswb/sdkcompat/as222/com/android/tools/idea/run/ValidationErrorCompat.java +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright 2023 The Bazel Authors. All rights reserved. - * - * 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. - */ -package com.android.tools.idea.run; - -/** Compat class for {@link ValidationError} */ -public class ValidationErrorCompat { - private ValidationErrorCompat() {} - - public static ValidationError fatal(String message, Runnable quickFick) { - return ValidationError.fatal(message, quickFick); - } -} diff --git a/aswb/sdkcompat/as222/com/android/tools/idea/run/editor/DeployTargetCompat.java b/aswb/sdkcompat/as222/com/android/tools/idea/run/editor/DeployTargetCompat.java deleted file mode 100644 index faa6faec6fe..00000000000 --- a/aswb/sdkcompat/as222/com/android/tools/idea/run/editor/DeployTargetCompat.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright 2022 The Bazel Authors. All rights reserved. - * - * 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. - */ -package com.android.tools.idea.run.editor; - -import com.android.tools.idea.run.DeviceFutures; -import com.intellij.openapi.project.Project; -import org.jetbrains.android.facet.AndroidFacet; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -/** SDK Compat class for {@link DeployTarget#getDevices}. */ -public class DeployTargetCompat { - - private DeployTargetCompat() {} - - @Nullable - public static DeviceFutures getDevices( - DeployTarget target, AndroidFacet facet, @NotNull Project project) { - return target.getDevices(project); - } -} diff --git a/aswb/sdkcompat/as222/com/android/tools/idea/run/tasks/DeployTasksCompat.java b/aswb/sdkcompat/as222/com/android/tools/idea/run/tasks/DeployTasksCompat.java deleted file mode 100644 index 3365e2bc5e0..00000000000 --- a/aswb/sdkcompat/as222/com/android/tools/idea/run/tasks/DeployTasksCompat.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright 2020 The Bazel Authors. All rights reserved. - * - * 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. - */ -package com.android.tools.idea.run.tasks; - -import com.android.tools.idea.deploy.DeploymentConfiguration; -import com.android.tools.idea.run.ApkInfo; -import com.android.tools.idea.run.LaunchOptions; -import com.android.tools.idea.run.util.SwapInfo; -import com.android.tools.idea.run.util.SwapInfo.SwapType; -import com.google.idea.blaze.android.run.BlazeAndroidDeploymentService; -import com.google.idea.common.experiments.BoolExperiment; -import com.intellij.execution.runners.ExecutionEnvironment; -import com.intellij.openapi.project.Project; -import java.util.Collection; - -/** Compat class for {@link DeployTask} */ -public class DeployTasksCompat { - private static final BoolExperiment updateCodeViaJvmti = - new BoolExperiment("android.apply.changes", false); - - private DeployTasksCompat() {} - - public static LaunchTask createDeployTask( - Project project, Collection packages, LaunchOptions launchOptions) { - // We don't have a device information, fallback to the most conservative - // install option. - return new DeployTask( - project, - packages, - launchOptions.getPmInstallOptions(/*device=*/ null), - launchOptions.getInstallOnAllUsers(), - launchOptions.getAlwaysInstallWithPm()); - } - - public static LaunchTask getDeployTask( - Project project, - ExecutionEnvironment env, - LaunchOptions launchOptions, - Collection packages) { - if (updateCodeViaJvmti.getValue()) { - // Set the appropriate action based on which deployment we're doing. - SwapInfo swapInfo = env.getUserData(SwapInfo.SWAP_INFO_KEY); - SwapInfo.SwapType swapType = swapInfo == null ? null : swapInfo.getType(); - if (swapType == SwapType.APPLY_CHANGES) { - return new ApplyChangesTask( - project, - packages, - DeploymentConfiguration.getInstance().APPLY_CHANGES_FALLBACK_TO_RUN, - false); - } else if (swapType == SwapType.APPLY_CODE_CHANGES) { - return new ApplyCodeChangesTask( - project, - packages, - DeploymentConfiguration.getInstance().APPLY_CODE_CHANGES_FALLBACK_TO_RUN, - false); - } - } - return BlazeAndroidDeploymentService.getInstance(project) - .getDeployTask(packages, launchOptions); - } -} diff --git a/aswb/sdkcompat/as222/com/android/tools/rendering/HtmlLinkManagerCompat.java b/aswb/sdkcompat/as222/com/android/tools/rendering/HtmlLinkManagerCompat.java deleted file mode 100644 index 594132f69af..00000000000 --- a/aswb/sdkcompat/as222/com/android/tools/rendering/HtmlLinkManagerCompat.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright 2023 The Bazel Authors. All rights reserved. - * - * 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. - */ -package com.android.tools.rendering; - -import com.android.tools.idea.rendering.HtmlLinkManager; -import java.io.File; -import org.jetbrains.annotations.NotNull; - -/** Compat class for {@link HtmlLinkManager} */ -public final class HtmlLinkManagerCompat { - public static String createFilePositionUrl(@NotNull File file, int line, int column) { - return HtmlLinkManager.createFilePositionUrl(file, line, column); - } - - private HtmlLinkManagerCompat() {} -} diff --git a/aswb/sdkcompat/as222/com/google/idea/blaze/android/cppimpl/debug/BlazeAutoAndroidDebugger.java b/aswb/sdkcompat/as222/com/google/idea/blaze/android/cppimpl/debug/BlazeAutoAndroidDebugger.java deleted file mode 100644 index b4104672fca..00000000000 --- a/aswb/sdkcompat/as222/com/google/idea/blaze/android/cppimpl/debug/BlazeAutoAndroidDebugger.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright 2016 The Bazel Authors. All rights reserved. - * - * 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. - */ -package com.google.idea.blaze.android.cppimpl.debug; - -import com.android.ddmlib.Client; -import com.android.tools.ndk.run.editor.AutoAndroidDebuggerState; -import com.intellij.openapi.project.Project; -import com.intellij.xdebugger.XDebugSession; -import org.jetbrains.concurrency.Promise; - -/** Shim for #api212 compat. */ -public class BlazeAutoAndroidDebugger extends BlazeAutoAndroidDebuggerBase { - @Override - public Promise attachToClient( - Project project, Client client, AutoAndroidDebuggerState state) { - if (isNativeProject(project)) { - log.info("Project has native development enabled. Attaching native debugger."); - return nativeDebugger.attachToClient(project, client, state); - } else { - return super.attachToClient(project, client, state); - } - } -} diff --git a/aswb/sdkcompat/as222/com/google/idea/blaze/android/cppimpl/debug/BlazeNativeAndroidDebugger.java b/aswb/sdkcompat/as222/com/google/idea/blaze/android/cppimpl/debug/BlazeNativeAndroidDebugger.java deleted file mode 100644 index 92d21b91a71..00000000000 --- a/aswb/sdkcompat/as222/com/google/idea/blaze/android/cppimpl/debug/BlazeNativeAndroidDebugger.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright 2018 The Bazel Authors. All rights reserved. - * - * 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. - */ -package com.google.idea.blaze.android.cppimpl.debug; - -/** - * API compat of {@link BlazeNativeAndroidDebuggerBase} with the following additions: - * - *
    - *
  • Creates a run-config setting using {@link BlazeAndroidNativeAttachConfiguration} instead of - * {@link com.android.tools.ndk.run.attach.AndroidNativeAttachConfiguration} to override - * counterproductive validations. - *
- * - * #api4.0 - */ -public class BlazeNativeAndroidDebugger extends BlazeNativeAndroidDebuggerBase {} diff --git a/aswb/sdkcompat/as222/com/google/idea/blaze/android/cppimpl/debug/BlazeNativeAndroidDebuggerBase.java b/aswb/sdkcompat/as222/com/google/idea/blaze/android/cppimpl/debug/BlazeNativeAndroidDebuggerBase.java deleted file mode 100644 index 911d90b7711..00000000000 --- a/aswb/sdkcompat/as222/com/google/idea/blaze/android/cppimpl/debug/BlazeNativeAndroidDebuggerBase.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright 2020 The Bazel Authors. All rights reserved. - * - * 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. - */ -package com.google.idea.blaze.android.cppimpl.debug; - -import com.android.tools.ndk.run.editor.NativeAndroidDebugger; -import com.google.idea.blaze.base.model.BlazeProjectData; -import com.google.idea.blaze.base.model.primitives.LanguageClass; -import com.google.idea.blaze.base.settings.Blaze; -import com.google.idea.blaze.base.sync.data.BlazeProjectDataManager; -import com.intellij.openapi.project.Project; - -/** - * Extension of {@link NativeAndroidDebugger} with the following key differences compared to {@link - * NativeAndroidDebugger}. - * - *
    - *
  • Overrides {@link #supportsProject} so native debugger is only enabled for native support is - * enabled. - *
- */ -public class BlazeNativeAndroidDebuggerBase extends NativeAndroidDebugger { - /** - * This ID needs to be lexicographically larger than "Java" so it come after the "Java" debugger - * when sorted lexicographically in the "Attach Debugger to Android Process" dialog. See {@link - * org.jetbrains.android.actions.AndroidProcessChooserDialog#populateDebuggerTypeCombo}. - */ - public static final String ID = "Native" + Blaze.defaultBuildSystemName(); - - @Override - public String getId() { - return ID; - } - - @Override - public String getDisplayName() { - return "Native Only"; - } - - @Override - public boolean supportsProject(Project project) { - BlazeProjectData blazeProjectData = - BlazeProjectDataManager.getInstance(project).getBlazeProjectData(); - return blazeProjectData != null - && blazeProjectData.getWorkspaceLanguageSettings().isLanguageActive(LanguageClass.C); - } -} diff --git a/aswb/sdkcompat/as222/com/google/idea/blaze/android/npw/project/BlazeAndroidModuleTemplate.java b/aswb/sdkcompat/as222/com/google/idea/blaze/android/npw/project/BlazeAndroidModuleTemplate.java deleted file mode 100644 index 5f357dfe99e..00000000000 --- a/aswb/sdkcompat/as222/com/google/idea/blaze/android/npw/project/BlazeAndroidModuleTemplate.java +++ /dev/null @@ -1,188 +0,0 @@ -/* - * Copyright 2017 The Bazel Authors. All rights reserved. - * - * 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. - */ -package com.google.idea.blaze.android.npw.project; - -import com.android.tools.idea.projectsystem.AndroidModulePaths; -import com.android.tools.idea.projectsystem.IdeaSourceProvider; -import com.android.tools.idea.projectsystem.NamedModuleTemplate; -import com.android.tools.idea.projectsystem.SourceProviderManager; -import com.google.common.collect.Streams; -import com.intellij.openapi.module.Module; -import com.intellij.openapi.project.Project; -import com.intellij.openapi.roots.ModuleRootManager; -import com.intellij.openapi.vfs.VfsUtilCore; -import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.psi.JavaDirectoryService; -import com.intellij.psi.PsiDirectory; -import com.intellij.psi.PsiManager; -import com.intellij.psi.PsiPackage; -import java.io.File; -import java.util.Collections; -import java.util.List; -import java.util.stream.Collectors; -import javax.annotation.Nullable; -import org.jetbrains.android.facet.AndroidFacet; - -/** - * Project paths for a Blaze Android project. - * - *

We mostly just take whatever directory the user specified and put the new component there. - * Unlike Gradle, Blaze has no strict requirements regarding the structure of an Android project, - * but there are some common conventions: - * - *

- * google3/
- * |-java/com/google/foo/bar/... (module root)
- * | |-BUILD
- * | |-AndroidManifest.xml (manifest directory)
- * | |-Baz.java (source directory of com.google.foo.bar.Baz)
- * | |-Baz.aidl (aidl directory, option 1)
- * | |-aidl/
- * | | `-com/google/foo/bar/Baz.aidl (aidl directory, option 2)
- * | `-res/... (res directory, one of the few things required by the build system)
- * `-javatest/com/google/foo/bar/...
- *   |-BUILD
- *   `-BazTest.java (test directory of com.google.foo.bar.BazTest)
- * 
- * - * However, this is also possible (package name unrelated to directory structure): - * - *
- * google3/experimental/users/foo/my/own/project/
- * |-Baz.java (com.google.foo.bar.Baz)
- * `-BazTest.java (com.google.foo.bar.BazTest)
- * 
- * - * So is this (versioned paths that aren't reflected by the package name): - * - *
- * google3/third_party/com/google/foo/bar/
- * |-v1/Baz.java (com.google.foo.bar.Baz)
- * `-v2/Baz.java (com.google.foo.bar.Baz)
- * 
- */ -public class BlazeAndroidModuleTemplate implements AndroidModulePaths { - @Nullable private File moduleRoot; - @Nullable private File srcDirectory; - private List resDirectories = Collections.emptyList(); - - @Nullable - @Override - public File getModuleRoot() { - return moduleRoot; - } - - @Nullable - @Override - public File getSrcDirectory(@Nullable String packageName) { - return srcDirectory; - } - - @Nullable - @Override - public File getTestDirectory(@Nullable String packageName) { - return srcDirectory; - } - - @Nullable - @Override - public File getUnitTestDirectory(@Nullable String packageName) { - return srcDirectory; - } - - @Override - public List getResDirectories() { - return resDirectories; - } - - @Nullable - @Override - public File getAidlDirectory(@Nullable String packageName) { - return srcDirectory; - } - - @Nullable - @Override - public File getManifestDirectory() { - return srcDirectory; - } - - /** - * The new component wizard uses {@link NamedModuleTemplate#getName()} for the default package - * name of the new component. If we can figure it out from the target directory here, then we can - * pass it to the new component wizard. - */ - private static String getPackageName(Project project, VirtualFile targetDirectory) { - PsiDirectory psiDirectory = PsiManager.getInstance(project).findDirectory(targetDirectory); - if (psiDirectory == null) { - return null; - } - PsiPackage psiPackage = JavaDirectoryService.getInstance().getPackage(psiDirectory); - if (psiPackage == null) { - return null; - } - return psiPackage.getQualifiedName(); - } - - public static List getTemplates( - Module module, @Nullable VirtualFile targetDirectory) { - AndroidFacet androidFacet = AndroidFacet.getInstance(module); - if (androidFacet == null) { - return Collections.emptyList(); - } - return getTemplates(androidFacet, targetDirectory); - } - - public static List getTemplates( - AndroidFacet androidFacet, @Nullable VirtualFile targetDirectory) { - - Module module = androidFacet.getModule(); - BlazeAndroidModuleTemplate paths = new BlazeAndroidModuleTemplate(); - VirtualFile[] roots = ModuleRootManager.getInstance(module).getContentRoots(); - if (roots.length > 0) { - paths.moduleRoot = VfsUtilCore.virtualToIoFile(roots[0]); - } - - IdeaSourceProvider sourceProvider = - SourceProviderManager.getInstance(androidFacet).getSources(); - - // If this happens to be a resource package, - // the module name (resource package) would be more descriptive than the facet name (Android). - // Otherwise, .workspace is still better than (Android). - String name = androidFacet.getModule().getName(); - if (targetDirectory != null) { - String packageName = getPackageName(module.getProject(), targetDirectory); - if (packageName != null) { - name = packageName; - } - paths.srcDirectory = VfsUtilCore.virtualToIoFile(targetDirectory); - } else { - // People usually put the manifest file with their sources. - //noinspection OptionalGetWithoutIsPresent - paths.srcDirectory = - Streams.stream(sourceProvider.getManifestDirectoryUrls()) - .map(it -> new File(VfsUtilCore.urlToPath(it))) - .findFirst() - .get(); - } - // We have a res dir if this happens to be a resource module. - paths.resDirectories = - Streams.stream(sourceProvider.getResDirectoryUrls()) - .map(it -> new File(VfsUtilCore.urlToPath(it))) - .collect(Collectors.toList()); - return Collections.singletonList(new NamedModuleTemplate(name, paths)); - } -} diff --git a/aswb/sdkcompat/as222/com/google/idea/blaze/android/projectsystem/BlazeProjectSystem.java b/aswb/sdkcompat/as222/com/google/idea/blaze/android/projectsystem/BlazeProjectSystem.java deleted file mode 100755 index 2ba73637e0d..00000000000 --- a/aswb/sdkcompat/as222/com/google/idea/blaze/android/projectsystem/BlazeProjectSystem.java +++ /dev/null @@ -1,214 +0,0 @@ -/* - * Copyright 2017 The Bazel Authors. All rights reserved. - * - * 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. - */ -package com.google.idea.blaze.android.projectsystem; - -import static com.android.tools.idea.projectsystem.SourceProvidersKt.emptySourceProvider; -import static org.jetbrains.android.facet.SourceProviderUtil.createSourceProvidersForLegacyModule; - -import com.android.tools.apk.analyzer.AaptInvoker; -import com.android.tools.idea.log.LogWrapper; -import com.android.tools.idea.model.AndroidModel; -import com.android.tools.idea.model.ClassJarProvider; -import com.android.tools.idea.projectsystem.AndroidModuleSystem; -import com.android.tools.idea.projectsystem.AndroidProjectSystem; -import com.android.tools.idea.projectsystem.NamedIdeaSourceProvider; -import com.android.tools.idea.projectsystem.ProjectSystemBuildManager; -import com.android.tools.idea.projectsystem.ProjectSystemSyncManager; -import com.android.tools.idea.projectsystem.ScopeType; -import com.android.tools.idea.projectsystem.SourceProviderManager; -import com.android.tools.idea.projectsystem.SourceProviders; -import com.android.tools.idea.projectsystem.SourceProvidersFactory; -import com.android.tools.idea.projectsystem.SourceProvidersImpl; -import com.android.tools.idea.res.AndroidInnerClassFinder; -import com.android.tools.idea.res.AndroidResourceClassPsiElementFinder; -import com.android.tools.idea.sdk.AndroidSdks; -import com.google.common.collect.ImmutableList; -import com.google.idea.blaze.android.resources.BlazeLightResourceClassService; -import com.google.idea.blaze.android.sync.model.idea.BlazeAndroidModel; -import com.google.idea.blaze.android.sync.model.idea.BlazeClassJarProvider; -import com.google.idea.blaze.base.build.BlazeBuildService; -import com.google.idea.blaze.base.qsync.QuerySync; -import com.intellij.facet.ProjectFacetManager; -import com.intellij.openapi.module.Module; -import com.intellij.openapi.project.Project; -import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.psi.PsiElementFinder; -import com.intellij.psi.search.GlobalSearchScope; -import java.nio.file.Path; -import java.util.Arrays; -import java.util.Collection; -import java.util.List; -import java.util.stream.Collectors; -import javax.annotation.Nullable; -import org.jetbrains.android.facet.AndroidFacet; - -/** - * Base class to implement common methods in {@link AndroidProjectSystem} for blaze with different - * sdk - */ -public class BlazeProjectSystem implements AndroidProjectSystem { - protected final Project project; - protected final ProjectSystemSyncManager syncManager; - protected final List myFinders; - private final BlazeProjectSystemBuildManager buildManager; - - public BlazeProjectSystem(Project project) { - this.project = project; - syncManager = new BlazeProjectSystemSyncManager(project); - buildManager = new BlazeProjectSystemBuildManager(project); - - myFinders = - Arrays.asList( - AndroidInnerClassFinder.INSTANCE, - new AndroidResourceClassPsiElementFinder(getLightResourceClassService())); - } - - @Override - public boolean allowsFileCreation() { - return true; - } - - @Nullable - @Override - public VirtualFile getDefaultApkFile() { - return null; - } - - @Override - public Path getPathToAapt() { - return AaptInvoker.getPathToAapt( - AndroidSdks.getInstance().tryToChooseSdkHandler(), - new LogWrapper(BlazeProjectSystem.class)); - } - - // @Override #api42 - public void buildProject() { - BlazeBuildService.getInstance(project).buildProject(); - } - - // @Override #api42 - public ProjectSystemBuildManager getBuildManager() { - return buildManager; - } - - @Override - public AndroidModuleSystem getModuleSystem(Module module) { - return BlazeModuleSystem.getInstance(module); - } - - @Override - public ProjectSystemSyncManager getSyncManager() { - return syncManager; - } - - @Override - public Collection getPsiElementFinders() { - return myFinders; - } - - @Override - public BlazeLightResourceClassService getLightResourceClassService() { - return BlazeLightResourceClassService.getInstance(project); - } - - @Override - public SourceProvidersFactory getSourceProvidersFactory() { - return new SourceProvidersFactory() { - @Override - public SourceProviders createSourceProvidersFor(AndroidFacet facet) { - BlazeAndroidModel model = ((BlazeAndroidModel) AndroidModel.get(facet)); - if (model != null) { - return createForModel(model); - } else { - return createSourceProvidersForLegacyModule(facet); - } - } - - private SourceProviders createForModel(BlazeAndroidModel model) { - NamedIdeaSourceProvider mainSourceProvider = model.getDefaultSourceProvider(); - if (QuerySync.isEnabled()) { - return new SourceProvidersImpl( - mainSourceProvider, - ImmutableList.of(mainSourceProvider), - ImmutableList.of(), - ImmutableList.of(), - ImmutableList.of(), - ImmutableList.of(mainSourceProvider), - ImmutableList.of(mainSourceProvider), - emptySourceProvider(ScopeType.MAIN), - emptySourceProvider(ScopeType.UNIT_TEST), - emptySourceProvider(ScopeType.ANDROID_TEST), - emptySourceProvider(ScopeType.TEST_FIXTURES)); - } else { - return new SourceProvidersImpl( - mainSourceProvider, - ImmutableList.of(mainSourceProvider), - ImmutableList.of(mainSourceProvider), - ImmutableList.of(mainSourceProvider), - ImmutableList.of(mainSourceProvider), - ImmutableList.of(mainSourceProvider), - ImmutableList.of(mainSourceProvider), - emptySourceProvider(ScopeType.MAIN), - emptySourceProvider(ScopeType.UNIT_TEST), - emptySourceProvider(ScopeType.ANDROID_TEST), - emptySourceProvider(ScopeType.TEST_FIXTURES)); - } - } - }; - } - - // @Override #api212 - public ClassJarProvider getClassJarProvider() { - return new BlazeClassJarProvider(project); - } - - @Override - public Collection getAndroidFacetsWithPackageName( - Project project, String packageName) { - return getAndroidFacetsWithPackageName( - project, packageName, GlobalSearchScope.projectScope(project)); - } - - private Collection getAndroidFacetsWithPackageName( - Project project, String packageName, GlobalSearchScope scope) { - List facets = ProjectFacetManager.getInstance(project).getFacets(AndroidFacet.ID); - return facets.stream() - .filter(facet -> hasPackageName(facet, packageName)) - .filter( - facet -> { - VirtualFile file = SourceProviderManager.getInstance(facet).getMainManifestFile(); - if (file == null) { - return false; - } else { - return scope.contains(file); - } - }) - .collect(Collectors.toList()); - } - - @Override - public Collection getSubmodules() { - return ImmutableList.of(); - } - - private static boolean hasPackageName(AndroidFacet facet, String packageName) { - String nameFromFacet = PackageNameUtils.getPackageName(facet.getModule()); - if (nameFromFacet == null) { - return false; - } - return nameFromFacet.equals(packageName); - } -} diff --git a/aswb/sdkcompat/as222/com/google/idea/blaze/android/projectsystem/PackageNameUtils.java b/aswb/sdkcompat/as222/com/google/idea/blaze/android/projectsystem/PackageNameUtils.java deleted file mode 100644 index 83a7fcd9b20..00000000000 --- a/aswb/sdkcompat/as222/com/google/idea/blaze/android/projectsystem/PackageNameUtils.java +++ /dev/null @@ -1,139 +0,0 @@ -/* - * Copyright 2018 The Bazel Authors. All rights reserved. - * - * 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. - */ -package com.google.idea.blaze.android.projectsystem; - -import com.android.manifmerger.ManifestSystemProperty; -import com.android.tools.idea.model.AndroidManifestIndex; -import com.android.tools.idea.model.AndroidManifestIndexCompat; -import com.android.tools.idea.model.AndroidManifestRawText; -import com.android.tools.idea.model.MergedManifestModificationTracker; -import com.android.tools.idea.projectsystem.ManifestOverrides; -import com.android.tools.idea.projectsystem.SourceProviderManager; -import com.google.common.annotations.VisibleForTesting; -import com.google.idea.common.experiments.BoolExperiment; -import com.intellij.openapi.module.Module; -import com.intellij.openapi.project.DumbService; -import com.intellij.openapi.project.IndexNotReadyException; -import com.intellij.openapi.project.Project; -import com.intellij.openapi.util.text.StringUtil; -import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.psi.util.CachedValueProvider; -import com.intellij.psi.util.CachedValuesManager; -import org.jetbrains.android.dom.manifest.AndroidManifestUtils; -import org.jetbrains.android.dom.manifest.AndroidManifestXmlFile; -import org.jetbrains.android.facet.AndroidFacet; -import org.jetbrains.annotations.Nullable; - -/** Utilities to obtain the package name for a given module. */ -public class PackageNameUtils { - /** - * Determines whether we use the {@link AndroidManifestIndex} to obtain the raw text package name - * from a module's primary manifest. Note that we still won't use the index if {@link - * AndroidManifestIndex#indexEnabled()} returns false. - * - * @see PackageNameUtils#getPackageName(Module) - * @see PackageNameUtils#doGetPackageName(AndroidFacet, boolean) - */ - private static final BoolExperiment USE_ANDROID_MANIFEST_INDEX = - new BoolExperiment("use.android.manifest.index", true); - - @Nullable - public static String getPackageName(Module module) { - AndroidFacet facet = AndroidFacet.getInstance(module); - assert facet != null; - return CachedValuesManager.getManager(module.getProject()) - .getCachedValue( - facet, - () -> { - boolean useIndex = - AndroidManifestIndexCompat.indexEnabled() - && USE_ANDROID_MANIFEST_INDEX.getValue(); - String packageName = doGetPackageName(facet, useIndex); - return CachedValueProvider.Result.create( - StringUtil.nullize(packageName, true), - MergedManifestModificationTracker.getInstance(module)); - }); - } - - /** - * Returns the package name from an Android module's merged manifest without actually computing - * the whole merged manifest. This is either - * - *
    - *
  1. The {@link ManifestSystemProperty#PACKAGE} manifest override if one is specified by the - * corresponding BUILD target, or - *
  2. The result of applying placeholder substitution to the raw package name from the module's - * primary manifest - *
- * - * In the second case, we try to obtain the raw package name using the {@link - * AndroidManifestIndex} if {@code useIndex} is true. If {@code useIndex} is false or querying the - * index fails for some reason (e.g. this method is called in a read action but not a *smart* read - * action), then we resort to parsing the PSI of the module's primary manifest to get the raw - * package name. - * - * @see AndroidModuleSystem#getManifestOverrides() - * @see AndroidModuleSystem#getPackageName() - */ - @Nullable - @VisibleForTesting - static String doGetPackageName(AndroidFacet facet, boolean useIndex) { - ManifestOverrides manifestOverrides = - BlazeModuleSystem.getInstance(facet.getModule()).getManifestOverrides(); - String packageOverride = - ManifestValueProcessor.getPackageOverride(manifestOverrides.getDirectOverrides()); - if (packageOverride != null) { - return packageOverride; - } - String rawPackageName = null; - if (useIndex) { - rawPackageName = getRawPackageNameFromIndex(facet); - } - if (rawPackageName == null) { - rawPackageName = getRawPackageNameFromPsi(facet); - } - return rawPackageName == null ? null : manifestOverrides.resolvePlaceholders(rawPackageName); - } - - @Nullable - private static String getRawPackageNameFromIndex(AndroidFacet facet) { - VirtualFile primaryManifest = SourceProviderManager.getInstance(facet).getMainManifestFile(); - if (primaryManifest == null) { - return null; - } - Project project = facet.getModule().getProject(); - try { - AndroidManifestRawText manifestRawText = - DumbService.getInstance(project) - .runReadActionInSmartMode( - () -> AndroidManifestIndex.getDataForManifestFile(project, primaryManifest)); - return manifestRawText == null ? null : manifestRawText.getPackageName(); - } catch (IndexNotReadyException e) { - // TODO(142681129): runReadActionInSmartMode doesn't work if we already have read access. - // We need to refactor the callers of AndroidManifestUtils#getPackage to require a *smart* - // read action, at which point we can remove this try-catch. - return null; - } - } - - @Nullable - private static String getRawPackageNameFromPsi(AndroidFacet facet) { - AndroidManifestXmlFile primaryManifest = AndroidManifestUtils.getPrimaryManifestXml(facet); - return primaryManifest == null ? null : primaryManifest.getPackageName(); - } - - private PackageNameUtils() {} -} diff --git a/aswb/sdkcompat/as222/com/google/idea/blaze/android/resources/BlazeRClass.java b/aswb/sdkcompat/as222/com/google/idea/blaze/android/resources/BlazeRClass.java deleted file mode 100644 index a5ff2881bc5..00000000000 --- a/aswb/sdkcompat/as222/com/google/idea/blaze/android/resources/BlazeRClass.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright 2018 The Bazel Authors. All rights reserved. - * - * 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. - */ -package com.google.idea.blaze.android.resources; - -import static org.jetbrains.android.AndroidResolveScopeEnlarger.LIGHT_CLASS_KEY; -import static org.jetbrains.android.AndroidResolveScopeEnlarger.MODULE_POINTER_KEY; - -import com.android.ide.common.rendering.api.ResourceNamespace; -import com.android.tools.idea.res.LocalResourceRepository; -import com.android.tools.idea.res.ResourceRepositoryManager; -import com.android.tools.idea.res.ResourceRepositoryRClass; -import com.intellij.openapi.module.Module; -import com.intellij.openapi.module.ModulePointerManager; -import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.psi.PsiManager; -import org.jetbrains.android.augment.AndroidLightField; -import org.jetbrains.android.facet.AndroidFacet; - -/** Blaze implementation of an R class based on resource repositories. */ -public class BlazeRClass extends ResourceRepositoryRClass { - - private final AndroidFacet androidFacet; - - public BlazeRClass(PsiManager psiManager, AndroidFacet androidFacet, String packageName) { - super( - psiManager, - new ResourcesSource() { - @Override - public String getPackageName() { - return packageName; - } - - @Override - public Transitivity getTransitivity() { - return Transitivity.TRANSITIVE; - } - - @Override - public ResourceRepositoryManager getResourceRepositoryManager() { - return ResourceRepositoryManager.getInstance(androidFacet); - } - - @Override - public LocalResourceRepository getResourceRepository() { - return ResourceRepositoryManager.getAppResources(androidFacet); - } - - @Override - public ResourceNamespace getResourceNamespace() { - return ResourceNamespace.RES_AUTO; - } - - @Override - public AndroidLightField.FieldModifier getFieldModifier() { - return AndroidLightField.FieldModifier.NON_FINAL; - } - }); - this.androidFacet = androidFacet; - setModuleInfo(getModule(), false); - VirtualFile virtualFile = myFile.getViewProvider().getVirtualFile(); - virtualFile.putUserData( - MODULE_POINTER_KEY, ModulePointerManager.getInstance(getProject()).create(getModule())); - virtualFile.putUserData(LIGHT_CLASS_KEY, ResourceRepositoryRClass.class); - } - - public Module getModule() { - return androidFacet.getModule(); - } -} diff --git a/aswb/sdkcompat/as222/com/google/idea/blaze/android/run/BlazeAndroidDeploymentService.java b/aswb/sdkcompat/as222/com/google/idea/blaze/android/run/BlazeAndroidDeploymentService.java deleted file mode 100644 index ddf5adeb9b2..00000000000 --- a/aswb/sdkcompat/as222/com/google/idea/blaze/android/run/BlazeAndroidDeploymentService.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright 2020 The Bazel Authors. All rights reserved. - * - * 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. - */ -package com.google.idea.blaze.android.run; - -import com.android.tools.idea.run.ApkInfo; -import com.android.tools.idea.run.LaunchOptions; -import com.android.tools.idea.run.tasks.DeployTask; -import com.android.tools.idea.run.tasks.DeployTasksCompat; -import com.android.tools.idea.run.tasks.LaunchTask; -import com.intellij.openapi.project.Project; -import java.util.Collection; - -/** A service that provides {@link DeployTask}. */ -public interface BlazeAndroidDeploymentService { - static BlazeAndroidDeploymentService getInstance(Project project) { - return project.getService(BlazeAndroidDeploymentService.class); - } - - /** Returns a {@link DeployTask} to deploy the given files and launch options. */ - LaunchTask getDeployTask(Collection packages, LaunchOptions launchOptions); - - /** A default implementation that uses {@link DeployTasksCompat#createDeployTask}. */ - class DefaultDeploymentService implements BlazeAndroidDeploymentService { - private final Project project; - - public DefaultDeploymentService(Project project) { - this.project = project; - } - - @Override - public LaunchTask getDeployTask(Collection packages, LaunchOptions launchOptions) { - return DeployTasksCompat.createDeployTask(project, packages, launchOptions); - } - } -} diff --git a/aswb/sdkcompat/as222/com/google/idea/blaze/android/run/BlazeAndroidRunState.java b/aswb/sdkcompat/as222/com/google/idea/blaze/android/run/BlazeAndroidRunState.java deleted file mode 100644 index b9301460027..00000000000 --- a/aswb/sdkcompat/as222/com/google/idea/blaze/android/run/BlazeAndroidRunState.java +++ /dev/null @@ -1,159 +0,0 @@ -/* - * Copyright 2019 The Bazel Authors. All rights reserved. - * - * 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. - */ -package com.google.idea.blaze.android.run; - -import com.android.tools.idea.execution.common.processhandler.AndroidProcessHandler; -import com.android.tools.idea.run.ApkProvisionException; -import com.android.tools.idea.run.ApplicationIdProvider; -import com.android.tools.idea.run.DeviceFutures; -import com.android.tools.idea.run.LaunchOptions; -import com.android.tools.idea.run.LaunchTaskRunner; -import com.android.tools.idea.run.tasks.LaunchTasksProvider; -import com.android.tools.idea.run.util.SwapInfo; -import com.android.tools.idea.stats.RunStats; -import com.google.common.annotations.VisibleForTesting; -import com.google.idea.blaze.android.run.runner.BlazeAndroidDeviceSelector.DeviceSession; -import com.google.idea.blaze.android.run.runner.BlazeAndroidRunContext; -import com.google.idea.blaze.base.run.smrunner.SmRunnerUtils; -import com.intellij.execution.DefaultExecutionResult; -import com.intellij.execution.ExecutionException; -import com.intellij.execution.ExecutionResult; -import com.intellij.execution.Executor; -import com.intellij.execution.configurations.RunProfileState; -import com.intellij.execution.process.ProcessHandler; -import com.intellij.execution.runners.ExecutionEnvironment; -import com.intellij.execution.runners.ProgramRunner; -import com.intellij.execution.ui.ConsoleView; -import com.intellij.execution.ui.RunContentDescriptor; -import com.intellij.execution.ui.RunContentManager; -import com.intellij.openapi.progress.ProgressManager; -import com.intellij.openapi.util.Key; -import javax.annotation.Nullable; - -/** State for android_binary and android_test runs. */ -public final class BlazeAndroidRunState implements RunProfileState { - private static final Key CONSOLE_VIEW_KEY = - new Key<>("android.run.state.consoleview"); - - private final ExecutionEnvironment env; - private final String launchConfigName; - private final DeviceSession deviceSession; - private final BlazeAndroidRunContext runContext; - private final LaunchOptions.Builder launchOptionsBuilder; - - public BlazeAndroidRunState( - ExecutionEnvironment env, - LaunchOptions.Builder launchOptionsBuilder, - DeviceSession deviceSession, - BlazeAndroidRunContext runContext) { - this.env = env; - this.launchConfigName = env.getRunProfile().getName(); - this.deviceSession = deviceSession; - this.runContext = runContext; - this.launchOptionsBuilder = launchOptionsBuilder; - } - - @Nullable - @Override - public ExecutionResult execute(Executor executor, ProgramRunner runner) - throws ExecutionException { - DefaultExecutionResult result = executeInner(executor, runner); - if (result == null) { - return null; - } - return SmRunnerUtils.attachRerunFailedTestsAction(result); - } - - @Nullable - private DefaultExecutionResult executeInner(Executor executor, ProgramRunner runner) - throws ExecutionException { - ProcessHandler processHandler; - ConsoleView console; - - ApplicationIdProvider applicationIdProvider = runContext.getApplicationIdProvider(); - - String applicationId; - try { - applicationId = applicationIdProvider.getPackageName(); - } catch (ApkProvisionException e) { - throw new ExecutionException("Unable to obtain application id", e); - } - - LaunchTasksProvider launchTasksProvider = - runContext.getLaunchTasksProvider(launchOptionsBuilder); - - DeviceFutures deviceFutures = deviceSession.deviceFutures; - assert deviceFutures != null; - ProcessHandler previousSessionProcessHandler = - deviceSession.sessionInfo != null ? deviceSession.sessionInfo.getProcessHandler() : null; - - boolean isSwap = env.getUserData(SwapInfo.SWAP_INFO_KEY) != null; - if (!isSwap) { - // In the case of cold swap, there is an existing process that is connected, - // but we are going to launch a new one. - // Detach the previous process handler so that we don't end up with - // 2 run tabs for the same launch (the existing one and the new one). - if (previousSessionProcessHandler != null) { - RunContentManager manager = RunContentManager.getInstance(env.getProject()); - RunContentDescriptor descriptor = - manager.findContentDescriptor(executor, previousSessionProcessHandler); - if (descriptor != null) { - manager.removeRunContent(executor, descriptor); - } - previousSessionProcessHandler.detachProcess(); - } - - processHandler = new AndroidProcessHandler(env.getProject(), applicationId); - console = - runContext - .getConsoleProvider() - .createAndAttach(env.getProject(), processHandler, executor); - // Stash the console. When we swap, we need the console, as that has the method to print a - // hyperlink. - // (If we only need normal text output, we can call ProcessHandler#notifyTextAvailable - // instead.) - processHandler.putCopyableUserData(CONSOLE_VIEW_KEY, console); - } else { - assert previousSessionProcessHandler != null - : "No process handler from previous session, yet current tasks don't create one"; - processHandler = previousSessionProcessHandler; - console = processHandler.getCopyableUserData(CONSOLE_VIEW_KEY); - assert console != null; - } - - LaunchTaskRunner task = - new LaunchTaskRunner( - env.getProject(), - launchConfigName, - applicationId, - env.getExecutionTarget().getDisplayName(), - env, - processHandler, - deviceFutures, - launchTasksProvider, - RunStats.from(env), - console::printHyperlink); - - ProgressManager.getInstance().run(task); - - return console == null ? null : new DefaultExecutionResult(console, processHandler); - } - - @VisibleForTesting - public BlazeAndroidRunContext getRunContext() { - return runContext; - } -} diff --git a/aswb/sdkcompat/as222/com/google/idea/blaze/android/run/binary/BlazeAndroidBinaryApplicationLaunchTaskProvider.java b/aswb/sdkcompat/as222/com/google/idea/blaze/android/run/binary/BlazeAndroidBinaryApplicationLaunchTaskProvider.java deleted file mode 100644 index abfe50ccd8d..00000000000 --- a/aswb/sdkcompat/as222/com/google/idea/blaze/android/run/binary/BlazeAndroidBinaryApplicationLaunchTaskProvider.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright 2016 The Bazel Authors. All rights reserved. - * - * 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. - */ -package com.google.idea.blaze.android.run.binary; - -import com.android.tools.idea.run.ApkProvisionException; -import com.android.tools.idea.run.ApplicationIdProvider; -import com.android.tools.idea.run.activity.StartActivityFlagsProvider; -import com.android.tools.idea.run.tasks.AndroidDeepLinkLaunchTask; -import com.android.tools.idea.run.tasks.DefaultActivityLaunchTask; -import com.android.tools.idea.run.tasks.LaunchTask; -import com.android.tools.idea.run.tasks.SpecificActivityLaunchTask; -import com.android.tools.idea.run.util.LaunchStatus; -import com.google.idea.blaze.android.manifest.ManifestParser; -import com.intellij.openapi.diagnostic.Logger; - -/** Provides the launch task for android_binary */ -public class BlazeAndroidBinaryApplicationLaunchTaskProvider { - private static final Logger LOG = - Logger.getInstance(BlazeAndroidBinaryApplicationLaunchTaskProvider.class); - - public static LaunchTask getApplicationLaunchTask( - ApplicationIdProvider applicationIdProvider, - ManifestParser.ParsedManifest mergedManifestParsedManifest, - BlazeAndroidBinaryRunConfigurationState configState, - StartActivityFlagsProvider startActivityFlagsProvider, - LaunchStatus launchStatus) { - try { - String applicationId = applicationIdProvider.getPackageName(); - - final LaunchTask launchTask; - - switch (configState.getMode()) { - case BlazeAndroidBinaryRunConfigurationState.LAUNCH_DEFAULT_ACTIVITY: - BlazeDefaultActivityLocator activityLocator = - new BlazeDefaultActivityLocator(mergedManifestParsedManifest); - launchTask = - new DefaultActivityLaunchTask( - applicationId, activityLocator, startActivityFlagsProvider); - break; - case BlazeAndroidBinaryRunConfigurationState.LAUNCH_SPECIFIC_ACTIVITY: - launchTask = - new SpecificActivityLaunchTask( - applicationId, configState.getActivityClass(), startActivityFlagsProvider); - break; - case BlazeAndroidBinaryRunConfigurationState.LAUNCH_DEEP_LINK: - launchTask = - new AndroidDeepLinkLaunchTask(configState.getDeepLink(), startActivityFlagsProvider); - break; - case BlazeAndroidBinaryRunConfigurationState.DO_NOTHING: - default: - launchTask = null; - break; - } - return launchTask; - } catch (ApkProvisionException e) { - LOG.error(e); - launchStatus.terminateLaunch("Unable to identify application id", true); - return null; - } - } -} diff --git a/aswb/sdkcompat/as222/com/google/idea/blaze/android/run/binary/BlazeAndroidBinaryNormalBuildRunContext.java b/aswb/sdkcompat/as222/com/google/idea/blaze/android/run/binary/BlazeAndroidBinaryNormalBuildRunContext.java deleted file mode 100644 index 914fb9cf9c3..00000000000 --- a/aswb/sdkcompat/as222/com/google/idea/blaze/android/run/binary/BlazeAndroidBinaryNormalBuildRunContext.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright 2019 The Bazel Authors. All rights reserved. - * - * 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. - */ -package com.google.idea.blaze.android.run.binary; - -import com.android.tools.idea.run.ApkProvisionException; -import com.android.tools.idea.run.LaunchOptions; -import com.android.tools.idea.run.activity.DefaultStartActivityFlagsProvider; -import com.android.tools.idea.run.activity.StartActivityFlagsProvider; -import com.android.tools.idea.run.tasks.LaunchTask; -import com.android.tools.idea.run.util.LaunchStatus; -import com.google.idea.blaze.android.run.deployinfo.BlazeAndroidDeployInfo; -import com.google.idea.blaze.android.run.runner.ApkBuildStep; -import com.intellij.execution.ExecutionException; -import com.intellij.execution.Executor; -import com.intellij.execution.configurations.RunConfiguration; -import com.intellij.execution.runners.ExecutionEnvironment; -import com.intellij.openapi.project.Project; -import javax.annotation.Nullable; -import org.jetbrains.android.facet.AndroidFacet; - -/** Compat for #api212 */ -public abstract class BlazeAndroidBinaryNormalBuildRunContext - extends BlazeAndroidBinaryNormalBuildRunContextBase { - BlazeAndroidBinaryNormalBuildRunContext( - Project project, - AndroidFacet facet, - RunConfiguration runConfiguration, - ExecutionEnvironment env, - BlazeAndroidBinaryRunConfigurationState configState, - ApkBuildStep buildStep, - String launchId) { - super(project, facet, runConfiguration, env, configState, buildStep, launchId); - } - - @Override - public LaunchTask getApplicationLaunchTask( - LaunchOptions launchOptions, - @Nullable Integer userId, - String contributorsAmStartOptions, - LaunchStatus launchStatus) - throws ExecutionException { - String extraFlags = UserIdHelper.getFlagsFromUserId(userId); - if (!contributorsAmStartOptions.isEmpty()) { - extraFlags += (extraFlags.isEmpty() ? "" : " ") + contributorsAmStartOptions; - } - - final StartActivityFlagsProvider startActivityFlagsProvider = - new DefaultStartActivityFlagsProvider(launchOptions.isDebug(), extraFlags); - - BlazeAndroidDeployInfo deployInfo; - try { - deployInfo = buildStep.getDeployInfo(); - } catch (ApkProvisionException e) { - throw new ExecutionException(e); - } - - return BlazeAndroidBinaryApplicationLaunchTaskProvider.getApplicationLaunchTask( - applicationIdProvider, - deployInfo.getMergedManifest(), - configState, - startActivityFlagsProvider, - launchStatus); - } - - @Override - public Executor getExecutor() { - return env.getExecutor(); - } -} diff --git a/aswb/sdkcompat/as222/com/google/idea/blaze/android/run/binary/BlazeAndroidBinaryNormalBuildRunContextBase.java b/aswb/sdkcompat/as222/com/google/idea/blaze/android/run/binary/BlazeAndroidBinaryNormalBuildRunContextBase.java deleted file mode 100644 index 97648704f1b..00000000000 --- a/aswb/sdkcompat/as222/com/google/idea/blaze/android/run/binary/BlazeAndroidBinaryNormalBuildRunContextBase.java +++ /dev/null @@ -1,179 +0,0 @@ -/* - * Copyright 2016 The Bazel Authors. All rights reserved. - * - * 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. - */ -package com.google.idea.blaze.android.run.binary; - -import static com.google.idea.blaze.android.run.runner.BlazeAndroidLaunchTasksProvider.NATIVE_DEBUGGING_ENABLED; - -import com.android.ddmlib.IDevice; -import com.android.tools.idea.gradle.util.DynamicAppUtils; -import com.android.tools.idea.run.ApkFileUnit; -import com.android.tools.idea.run.ApkInfo; -import com.android.tools.idea.run.ApkProvider; -import com.android.tools.idea.run.ApkProvisionException; -import com.android.tools.idea.run.ApplicationIdProvider; -import com.android.tools.idea.run.ConsolePrinter; -import com.android.tools.idea.run.ConsoleProvider; -import com.android.tools.idea.run.LaunchOptions; -import com.android.tools.idea.run.editor.ProfilerState; -import com.android.tools.idea.run.tasks.DeployTasksCompat; -import com.android.tools.idea.run.tasks.LaunchTask; -import com.android.tools.idea.run.tasks.LaunchTasksProvider; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; -import com.google.idea.blaze.android.run.deployinfo.BlazeApkProviderService; -import com.google.idea.blaze.android.run.runner.ApkBuildStep; -import com.google.idea.blaze.android.run.runner.BlazeAndroidDeviceSelector; -import com.google.idea.blaze.android.run.runner.BlazeAndroidLaunchTasksProvider; -import com.google.idea.blaze.android.run.runner.BlazeAndroidRunContext; -import com.intellij.execution.ExecutionException; -import com.intellij.execution.configurations.RunConfiguration; -import com.intellij.execution.runners.ExecutionEnvironment; -import com.intellij.openapi.project.Project; -import java.util.Collection; -import java.util.List; -import java.util.stream.Collectors; -import javax.annotation.Nullable; -import org.jetbrains.android.facet.AndroidFacet; -import org.jetbrains.annotations.NotNull; - -/** Run context for android_binary. */ -public abstract class BlazeAndroidBinaryNormalBuildRunContextBase - implements BlazeAndroidRunContext { - protected final Project project; - protected final AndroidFacet facet; - protected final RunConfiguration runConfiguration; - protected final ExecutionEnvironment env; - protected final BlazeAndroidBinaryRunConfigurationState configState; - protected final ConsoleProvider consoleProvider; - protected final ApkBuildStep buildStep; - protected final ApkProvider apkProvider; - protected final ApplicationIdProvider applicationIdProvider; - private final String launchId; - - BlazeAndroidBinaryNormalBuildRunContextBase( - Project project, - AndroidFacet facet, - RunConfiguration runConfiguration, - ExecutionEnvironment env, - BlazeAndroidBinaryRunConfigurationState configState, - ApkBuildStep buildStep, - String launchId) { - this.project = project; - this.facet = facet; - this.runConfiguration = runConfiguration; - this.env = env; - this.configState = configState; - this.consoleProvider = new BlazeAndroidBinaryConsoleProvider(project); - this.buildStep = buildStep; - this.apkProvider = BlazeApkProviderService.getInstance().getApkProvider(project, buildStep); - this.applicationIdProvider = new BlazeAndroidBinaryApplicationIdProvider(buildStep); - this.launchId = launchId; - } - - @Override - public BlazeAndroidDeviceSelector getDeviceSelector() { - return new BlazeAndroidDeviceSelector.NormalDeviceSelector(); - } - - @Override - public void augmentLaunchOptions(LaunchOptions.Builder options) { - options.setDeploy(true).setOpenLogcatAutomatically(configState.showLogcatAutomatically()); - options.addExtraOptions( - ImmutableMap.of( - "android.profilers.state", // Not used after #api211 - configState.getProfilerState(), - NATIVE_DEBUGGING_ENABLED, - configState.getCommonState().isNativeDebuggingEnabled())); - } - - @Override - public ConsoleProvider getConsoleProvider() { - return consoleProvider; - } - - @Override - public ApplicationIdProvider getApplicationIdProvider() throws ExecutionException { - return applicationIdProvider; - } - - @Override - public ApkBuildStep getBuildStep() { - return buildStep; - } - - @Nullable - @Override - public Integer getUserId(IDevice device, ConsolePrinter consolePrinter) - throws ExecutionException { - return UserIdHelper.getUserIdFromConfigurationState(device, consolePrinter, configState); - } - - @Override - public LaunchTasksProvider getLaunchTasksProvider(LaunchOptions.Builder launchOptionsBuilder) - throws ExecutionException { - return new BlazeAndroidLaunchTasksProvider( - project, this, applicationIdProvider, launchOptionsBuilder); - } - - @Override - public String getAmStartOptions() { - return configState.getAmStartOptions(); - } - - @Override - public ProfilerState getProfileState() { - return configState.getProfilerState(); - } - - @Nullable - @Override - public ImmutableList getDeployTasks(IDevice device, LaunchOptions launchOptions) - throws ExecutionException { - LaunchTask deployTask = - DeployTasksCompat.getDeployTask( - project, env, launchOptions, getApkInfoToInstall(device, launchOptions, apkProvider)); - return ImmutableList.of(new DeploymentTimingReporterTask(launchId, deployTask)); - } - - /** Returns a list of APKs excluding any APKs for features that are disabled. */ - public static List getApkInfoToInstall( - IDevice device, LaunchOptions launchOptions, ApkProvider apkProvider) - throws ExecutionException { - Collection apks; - try { - apks = apkProvider.getApks(device); - } catch (ApkProvisionException e) { - throw new ExecutionException(e); - } - List disabledFeatures = launchOptions.getDisabledDynamicFeatures(); - return apks.stream() - .map(apk -> getApkInfoToInstall(apk, disabledFeatures)) - .collect(Collectors.toList()); - } - - @NotNull - private static ApkInfo getApkInfoToInstall(ApkInfo apkInfo, List disabledFeatures) { - if (apkInfo.getFiles().size() > 1) { - List filteredApks = - apkInfo.getFiles().stream() - .filter(feature -> DynamicAppUtils.isFeatureEnabled(disabledFeatures, feature)) - .collect(Collectors.toList()); - return new ApkInfo(filteredApks, apkInfo.getApplicationId()); - } else { - return apkInfo; - } - } -} diff --git a/aswb/sdkcompat/as222/com/google/idea/blaze/android/run/binary/BlazeAndroidBinaryNormalBuildRunContextCompat.java b/aswb/sdkcompat/as222/com/google/idea/blaze/android/run/binary/BlazeAndroidBinaryNormalBuildRunContextCompat.java deleted file mode 100644 index f98cc8969ac..00000000000 --- a/aswb/sdkcompat/as222/com/google/idea/blaze/android/run/binary/BlazeAndroidBinaryNormalBuildRunContextCompat.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright 2022 The Bazel Authors. All rights reserved. - * - * 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. - */ -package com.google.idea.blaze.android.run.binary; - -import static com.android.tools.idea.run.tasks.DefaultConnectDebuggerTaskKt.getBaseDebuggerTask; - -import com.android.tools.idea.execution.common.debug.AndroidDebugger; -import com.android.tools.idea.execution.common.debug.AndroidDebuggerState; -import com.android.tools.idea.run.tasks.ConnectDebuggerTask; -import com.google.idea.blaze.android.run.runner.ApkBuildStep; -import com.intellij.execution.ExecutionException; -import com.intellij.execution.configurations.RunConfiguration; -import com.intellij.execution.runners.ExecutionEnvironment; -import com.intellij.openapi.project.Project; -import javax.annotation.Nullable; -import org.jetbrains.android.facet.AndroidFacet; - -/** Compat class for {@link BlazeAndroidBinaryNormalBuildRunContext}. */ -public class BlazeAndroidBinaryNormalBuildRunContextCompat - extends BlazeAndroidBinaryNormalBuildRunContext { - - BlazeAndroidBinaryNormalBuildRunContextCompat( - Project project, - AndroidFacet facet, - RunConfiguration runConfiguration, - ExecutionEnvironment env, - BlazeAndroidBinaryRunConfigurationState configState, - ApkBuildStep buildStep, - String launchId) { - super(project, facet, runConfiguration, env, configState, buildStep, launchId); - } - - @Nullable - @Override - @SuppressWarnings("unchecked") - public ConnectDebuggerTask getDebuggerTask( - AndroidDebugger androidDebugger, AndroidDebuggerState androidDebuggerState) - throws ExecutionException { - return getBaseDebuggerTask( - androidDebugger, androidDebuggerState, env, facet, applicationIdProvider); - } -} diff --git a/aswb/sdkcompat/as222/com/google/idea/blaze/android/run/binary/BlazeAndroidBinaryProgramRunner.java b/aswb/sdkcompat/as222/com/google/idea/blaze/android/run/binary/BlazeAndroidBinaryProgramRunner.java deleted file mode 100644 index d2a10dddd58..00000000000 --- a/aswb/sdkcompat/as222/com/google/idea/blaze/android/run/binary/BlazeAndroidBinaryProgramRunner.java +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright 2016 The Bazel Authors. All rights reserved. - * - * 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. - */ -package com.google.idea.blaze.android.run.binary; - - -import com.android.tools.idea.profilers.ProfileRunExecutor; -import com.android.tools.idea.run.AndroidProgramRunner; -import com.android.tools.idea.run.AndroidSessionInfoCompat; -import com.google.idea.blaze.android.run.BlazeAndroidRunConfigurationHandler; -import com.intellij.execution.ExecutionException; -import com.intellij.execution.ExecutionResult; -import com.intellij.execution.configurations.RunConfiguration; -import com.intellij.execution.configurations.RunProfile; -import com.intellij.execution.configurations.RunProfileState; -import com.intellij.execution.executors.DefaultDebugExecutor; -import com.intellij.execution.executors.DefaultRunExecutor; -import com.intellij.execution.process.ProcessHandler; -import com.intellij.execution.runners.ExecutionEnvironment; -import com.intellij.execution.runners.RunContentBuilder; -import com.intellij.execution.ui.RunContentDescriptor; -import com.intellij.openapi.fileEditor.FileDocumentManager; - -/** Program runner for configurations from {@link BlazeAndroidBinaryRunConfigurationHandler}. */ -public class BlazeAndroidBinaryProgramRunner extends AndroidProgramRunner { - @Override - public boolean canRun(String executorId, RunProfile profile) { - BlazeAndroidRunConfigurationHandler handler = - BlazeAndroidRunConfigurationHandler.getHandlerFrom(profile); - if (!(handler instanceof BlazeAndroidBinaryRunConfigurationHandler)) { - return false; - } - return (DefaultDebugExecutor.EXECUTOR_ID.equals(executorId) - || DefaultRunExecutor.EXECUTOR_ID.equals(executorId) - || ProfileRunExecutor.EXECUTOR_ID.equals(executorId)); - } - - @Override - protected boolean canRunWithMultipleDevices(String executorId) { - return false; - } - - @Override - protected RunContentDescriptor doExecute( - final RunProfileState state, final ExecutionEnvironment env) throws ExecutionException { - FileDocumentManager.getInstance().saveAllDocuments(); - ExecutionResult result = state.execute(env.getExecutor(), this); - RunContentDescriptor descriptor = - new RunContentBuilder(result, env).showRunContent(env.getContentToReuse()); - - if (descriptor != null) { - ProcessHandler processHandler = descriptor.getProcessHandler(); - assert processHandler != null; - - RunProfile runProfile = env.getRunProfile(); - RunConfiguration runConfiguration = - (runProfile instanceof RunConfiguration) ? (RunConfiguration) runProfile : null; - - // The created AndroidSessionInfo is already added to userdata by #create. - AndroidSessionInfoCompat.create( - processHandler, - descriptor, - runConfiguration, - env.getExecutor().getId(), - env.getExecutor().getActionName(), - env.getExecutionTarget()); - } - - return descriptor; - } - - @Override - public String getRunnerId() { - return "AndroidBinaryProgramRunner"; - } -} diff --git a/aswb/sdkcompat/as222/com/google/idea/blaze/android/run/binary/DeploymentTimingReporterTask.java b/aswb/sdkcompat/as222/com/google/idea/blaze/android/run/binary/DeploymentTimingReporterTask.java deleted file mode 100644 index 4774361d534..00000000000 --- a/aswb/sdkcompat/as222/com/google/idea/blaze/android/run/binary/DeploymentTimingReporterTask.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright 2021 The Bazel Authors. All rights reserved. - * - * 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. - */ -package com.google.idea.blaze.android.run.binary; - -import com.android.tools.idea.BaseAsCompat; -import com.android.tools.idea.run.ApkInfo; -import com.android.tools.idea.run.tasks.LaunchContext; -import com.android.tools.idea.run.tasks.LaunchResult; -import com.android.tools.idea.run.tasks.LaunchTask; -import com.google.common.base.Stopwatch; -import com.google.idea.blaze.android.run.LaunchMetrics; -import com.google.wireless.android.sdk.stats.LaunchTaskDetail; -import java.util.Collection; -import org.jetbrains.annotations.TestOnly; - -/** A wrapper launch task that wraps the given deployment task and logs the deployment latency. */ -public class DeploymentTimingReporterTask implements LaunchTask { - private final LaunchTask deployTask; - private final String launchId; - - public DeploymentTimingReporterTask(String launchId, LaunchTask deployTask) { - this.launchId = launchId; - this.deployTask = deployTask; - } - - @Override - public String getDescription() { - return deployTask.getDescription(); - } - - @Override - public int getDuration() { - return deployTask.getDuration(); - } - - @Override - public boolean shouldRun(LaunchContext launchContext) { - return deployTask.shouldRun(launchContext); - } - - @Override - public LaunchResult run(LaunchContext launchContext) { - Stopwatch s = Stopwatch.createStarted(); - LaunchResult launchResult = deployTask.run(launchContext); - LaunchMetrics.logDeploymentTime( - launchId, s.elapsed(), BaseAsCompat.wasSuccessfulLaunch(launchResult)); - return launchResult; - } - - @Override - public String getId() { - return deployTask.getId(); - } - - @Override - public Collection getApkInfos() { - return deployTask.getApkInfos(); - } - - @Override - public Collection getSubTaskDetails() { - return deployTask.getSubTaskDetails(); - } - - @TestOnly - public LaunchTask getWrappedTask() { - return deployTask; - } -} diff --git a/aswb/sdkcompat/as222/com/google/idea/blaze/android/run/binary/UserIdHelper.java b/aswb/sdkcompat/as222/com/google/idea/blaze/android/run/binary/UserIdHelper.java deleted file mode 100644 index 4ed8326b0c3..00000000000 --- a/aswb/sdkcompat/as222/com/google/idea/blaze/android/run/binary/UserIdHelper.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright 2016 The Bazel Authors. All rights reserved. - * - * 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. - */ -package com.google.idea.blaze.android.run.binary; - -import com.android.ddmlib.AdbCommandRejectedException; -import com.android.ddmlib.CollectingOutputReceiver; -import com.android.ddmlib.IDevice; -import com.android.ddmlib.ShellCommandUnresponsiveException; -import com.android.ddmlib.TimeoutException; -import com.android.tools.idea.run.ConsolePrinter; -import com.intellij.execution.ExecutionException; -import java.io.IOException; -import java.util.regex.Matcher; -import java.util.regex.Pattern; -import javax.annotation.Nullable; - -/** Helpers for user id */ -public final class UserIdHelper { - private static final Pattern USER_ID_REGEX = - Pattern.compile("UserInfo\\{([0-9]+):Work profile:[0-9]+\\}"); - - @Nullable - public static Integer getUserIdFromConfigurationState( - IDevice device, ConsolePrinter consolePrinter, BlazeAndroidBinaryRunConfigurationState state) - throws ExecutionException { - if (state.useWorkProfileIfPresent()) { - try { - Integer userId = getWorkProfileId(device); - if (userId == null) { - consolePrinter.stderr( - "Could not locate work profile on selected device. Launching default user.\n"); - } - return userId; - } catch (TimeoutException - | AdbCommandRejectedException - | ShellCommandUnresponsiveException - | IOException e) { - throw new ExecutionException(e); - } - } - return state.getUserId(); - } - - @Nullable - public static Integer getWorkProfileId(IDevice device) - throws TimeoutException, AdbCommandRejectedException, ShellCommandUnresponsiveException, - IOException { - CollectingOutputReceiver receiver = new CollectingOutputReceiver(); - device.executeShellCommand("pm list users", receiver); - String result = receiver.getOutput(); - Matcher matcher = USER_ID_REGEX.matcher(result); - if (matcher.find()) { - return Integer.parseInt(matcher.group(1)); - } - return null; - } - - public static String getFlagsFromUserId(@Nullable Integer userId) { - return userId != null ? ("--user " + userId.intValue()) : ""; - } -} diff --git a/aswb/sdkcompat/as222/com/google/idea/blaze/android/run/binary/mobileinstall/BlazeAndroidBinaryMobileInstallRunContext.java b/aswb/sdkcompat/as222/com/google/idea/blaze/android/run/binary/mobileinstall/BlazeAndroidBinaryMobileInstallRunContext.java deleted file mode 100644 index e1d75630285..00000000000 --- a/aswb/sdkcompat/as222/com/google/idea/blaze/android/run/binary/mobileinstall/BlazeAndroidBinaryMobileInstallRunContext.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright 2016 The Bazel Authors. All rights reserved. - * - * 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. - */ -package com.google.idea.blaze.android.run.binary.mobileinstall; - - -import com.android.tools.idea.run.ApkProvisionException; -import com.android.tools.idea.run.LaunchOptions; -import com.android.tools.idea.run.activity.DefaultStartActivityFlagsProvider; -import com.android.tools.idea.run.activity.StartActivityFlagsProvider; -import com.android.tools.idea.run.tasks.LaunchTask; -import com.android.tools.idea.run.util.LaunchStatus; -import com.google.idea.blaze.android.run.binary.BlazeAndroidBinaryApplicationLaunchTaskProvider; -import com.google.idea.blaze.android.run.binary.BlazeAndroidBinaryRunConfigurationState; -import com.google.idea.blaze.android.run.binary.UserIdHelper; -import com.google.idea.blaze.android.run.deployinfo.BlazeAndroidDeployInfo; -import com.google.idea.blaze.android.run.runner.ApkBuildStep; -import com.intellij.execution.ExecutionException; -import com.intellij.execution.Executor; -import com.intellij.execution.configurations.RunConfiguration; -import com.intellij.execution.runners.ExecutionEnvironment; -import com.intellij.openapi.project.Project; -import javax.annotation.Nullable; -import org.jetbrains.android.facet.AndroidFacet; - -/** Run Context for mobile install launches, #api4.0 compat. */ -public abstract class BlazeAndroidBinaryMobileInstallRunContext - extends BlazeAndroidBinaryMobileInstallRunContextBase { - public BlazeAndroidBinaryMobileInstallRunContext( - Project project, - AndroidFacet facet, - RunConfiguration runConfiguration, - ExecutionEnvironment env, - BlazeAndroidBinaryRunConfigurationState configState, - ApkBuildStep buildStep, - String launchId) { - super(project, facet, runConfiguration, env, configState, buildStep, launchId); - } - - @Override - public LaunchTask getApplicationLaunchTask( - LaunchOptions launchOptions, - @Nullable Integer userId, - String contributorsAmStartOptions, - LaunchStatus launchStatus) - throws ExecutionException { - - String extraFlags = UserIdHelper.getFlagsFromUserId(userId); - if (!contributorsAmStartOptions.isEmpty()) { - extraFlags += (extraFlags.isEmpty() ? "" : " ") + contributorsAmStartOptions; - } - - final StartActivityFlagsProvider startActivityFlagsProvider = - new DefaultStartActivityFlagsProvider(launchOptions.isDebug(), extraFlags); - BlazeAndroidDeployInfo deployInfo; - try { - deployInfo = buildStep.getDeployInfo(); - } catch (ApkProvisionException e) { - throw new ExecutionException(e); - } - - return BlazeAndroidBinaryApplicationLaunchTaskProvider.getApplicationLaunchTask( - applicationIdProvider, - deployInfo.getMergedManifest(), - configState, - startActivityFlagsProvider, - launchStatus); - } - - @Override - public Executor getExecutor() { - return env.getExecutor(); - } -} diff --git a/aswb/sdkcompat/as222/com/google/idea/blaze/android/run/binary/mobileinstall/BlazeAndroidBinaryMobileInstallRunContextBase.java b/aswb/sdkcompat/as222/com/google/idea/blaze/android/run/binary/mobileinstall/BlazeAndroidBinaryMobileInstallRunContextBase.java deleted file mode 100644 index 89e9796e172..00000000000 --- a/aswb/sdkcompat/as222/com/google/idea/blaze/android/run/binary/mobileinstall/BlazeAndroidBinaryMobileInstallRunContextBase.java +++ /dev/null @@ -1,168 +0,0 @@ -/* - * Copyright 2016 The Bazel Authors. All rights reserved. - * - * 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. - */ -package com.google.idea.blaze.android.run.binary.mobileinstall; - -import com.android.ddmlib.IDevice; -import com.android.tools.idea.run.ApkFileUnit; -import com.android.tools.idea.run.ApkInfo; -import com.android.tools.idea.run.ApkProvisionException; -import com.android.tools.idea.run.ApplicationIdProvider; -import com.android.tools.idea.run.ConsolePrinter; -import com.android.tools.idea.run.ConsoleProvider; -import com.android.tools.idea.run.LaunchOptions; -import com.android.tools.idea.run.editor.ProfilerState; -import com.android.tools.idea.run.tasks.LaunchTask; -import com.android.tools.idea.run.tasks.LaunchTasksProvider; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; -import com.google.idea.blaze.android.run.BlazeAndroidDeploymentService; -import com.google.idea.blaze.android.run.binary.BlazeAndroidBinaryApplicationIdProvider; -import com.google.idea.blaze.android.run.binary.BlazeAndroidBinaryConsoleProvider; -import com.google.idea.blaze.android.run.binary.BlazeAndroidBinaryRunConfigurationState; -import com.google.idea.blaze.android.run.binary.DeploymentTimingReporterTask; -import com.google.idea.blaze.android.run.binary.UserIdHelper; -import com.google.idea.blaze.android.run.deployinfo.BlazeAndroidDeployInfo; -import com.google.idea.blaze.android.run.runner.ApkBuildStep; -import com.google.idea.blaze.android.run.runner.BlazeAndroidDeviceSelector; -import com.google.idea.blaze.android.run.runner.BlazeAndroidLaunchTasksProvider; -import com.google.idea.blaze.android.run.runner.BlazeAndroidRunContext; -import com.google.idea.blaze.base.sync.data.BlazeDataStorage; -import com.intellij.execution.ExecutionException; -import com.intellij.execution.configurations.RunConfiguration; -import com.intellij.execution.runners.ExecutionEnvironment; -import com.intellij.openapi.project.Project; -import java.util.Collections; -import java.util.stream.Collectors; -import javax.annotation.Nullable; -import org.jetbrains.android.facet.AndroidFacet; - -/** Run context for android_binary. */ -abstract class BlazeAndroidBinaryMobileInstallRunContextBase implements BlazeAndroidRunContext { - protected final Project project; - protected final AndroidFacet facet; - protected final RunConfiguration runConfiguration; - protected final ExecutionEnvironment env; - protected final BlazeAndroidBinaryRunConfigurationState configState; - protected final ConsoleProvider consoleProvider; - protected final ApplicationIdProvider applicationIdProvider; - protected final ApkBuildStep buildStep; - private final String launchId; - - public BlazeAndroidBinaryMobileInstallRunContextBase( - Project project, - AndroidFacet facet, - RunConfiguration runConfiguration, - ExecutionEnvironment env, - BlazeAndroidBinaryRunConfigurationState configState, - ApkBuildStep buildStep, - String launchId) { - this.project = project; - this.facet = facet; - this.runConfiguration = runConfiguration; - this.env = env; - this.configState = configState; - this.consoleProvider = new BlazeAndroidBinaryConsoleProvider(project); - this.buildStep = buildStep; - this.applicationIdProvider = new BlazeAndroidBinaryApplicationIdProvider(buildStep); - this.launchId = launchId; - } - - @Override - public BlazeAndroidDeviceSelector getDeviceSelector() { - return new BlazeAndroidDeviceSelector.NormalDeviceSelector(); - } - - @Override - public void augmentLaunchOptions(LaunchOptions.Builder options) { - options - .setDeploy(buildStep.needsIdeDeploy()) - .setOpenLogcatAutomatically(configState.showLogcatAutomatically()); - // This is needed for compatibility with #api211 - options.addExtraOptions( - ImmutableMap.of("android.profilers.state", configState.getProfilerState())); - } - - @Override - public ConsoleProvider getConsoleProvider() { - return consoleProvider; - } - - @Override - public ApplicationIdProvider getApplicationIdProvider() throws ExecutionException { - return applicationIdProvider; - } - - @Override - public ApkBuildStep getBuildStep() { - return buildStep; - } - - @Override - public ProfilerState getProfileState() { - return configState.getProfilerState(); - } - - @Override - public ImmutableList getDeployTasks(IDevice device, LaunchOptions launchOptions) - throws ExecutionException { - if (!buildStep.needsIdeDeploy()) { - return ImmutableList.of(); - } - - BlazeAndroidDeployInfo deployInfo; - try { - deployInfo = buildStep.getDeployInfo(); - } catch (ApkProvisionException e) { - throw new ExecutionException(e); - } - - String packageName = deployInfo.getMergedManifest().packageName; - if (packageName == null) { - throw new ExecutionException("Could not determine package name from deploy info"); - } - - ApkInfo info = - new ApkInfo( - deployInfo.getApksToDeploy().stream() - .map(file -> new ApkFileUnit(BlazeDataStorage.WORKSPACE_MODULE_NAME, file)) - .collect(Collectors.toList()), - packageName); - - LaunchTask deployTask = - BlazeAndroidDeploymentService.getInstance(project) - .getDeployTask(Collections.singletonList(info), launchOptions); - return ImmutableList.of(new DeploymentTimingReporterTask(launchId, deployTask)); - } - - @Nullable - @Override - public Integer getUserId(IDevice device, ConsolePrinter consolePrinter) - throws ExecutionException { - return UserIdHelper.getUserIdFromConfigurationState(device, consolePrinter, configState); - } - - @Override - public LaunchTasksProvider getLaunchTasksProvider(LaunchOptions.Builder launchOptionsBuilder) - throws ExecutionException { - return new BlazeAndroidLaunchTasksProvider( - project, this, applicationIdProvider, launchOptionsBuilder); - } - - @Override - public String getAmStartOptions() { - return configState.getAmStartOptions(); - } -} diff --git a/aswb/sdkcompat/as222/com/google/idea/blaze/android/run/binary/mobileinstall/BlazeAndroidBinaryMobileInstallRunContextCompat.java b/aswb/sdkcompat/as222/com/google/idea/blaze/android/run/binary/mobileinstall/BlazeAndroidBinaryMobileInstallRunContextCompat.java deleted file mode 100644 index fac1ddfc774..00000000000 --- a/aswb/sdkcompat/as222/com/google/idea/blaze/android/run/binary/mobileinstall/BlazeAndroidBinaryMobileInstallRunContextCompat.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright 2022 The Bazel Authors. All rights reserved. - * - * 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. - */ -package com.google.idea.blaze.android.run.binary.mobileinstall; - -import static com.android.tools.idea.run.tasks.DefaultConnectDebuggerTaskKt.getBaseDebuggerTask; - -import com.android.tools.idea.execution.common.debug.AndroidDebugger; -import com.android.tools.idea.execution.common.debug.AndroidDebuggerState; -import com.android.tools.idea.run.tasks.ConnectDebuggerTask; -import com.google.idea.blaze.android.run.binary.BlazeAndroidBinaryRunConfigurationState; -import com.google.idea.blaze.android.run.runner.ApkBuildStep; -import com.google.idea.blaze.base.run.BlazeCommandRunConfiguration; -import com.intellij.execution.ExecutionException; -import com.intellij.execution.runners.ExecutionEnvironment; -import com.intellij.openapi.project.Project; -import javax.annotation.Nullable; -import org.jetbrains.android.facet.AndroidFacet; - -/** Compatct class for {@link BlazeAndroidBinaryMobileInstallRunContext}. */ -public class BlazeAndroidBinaryMobileInstallRunContextCompat - extends BlazeAndroidBinaryMobileInstallRunContext { - - public BlazeAndroidBinaryMobileInstallRunContextCompat( - Project project, - AndroidFacet facet, - BlazeCommandRunConfiguration configuration, - ExecutionEnvironment env, - BlazeAndroidBinaryRunConfigurationState configState, - ApkBuildStep buildStep, - String launchId) { - super(project, facet, configuration, env, configState, buildStep, launchId); - } - - @Nullable - @Override - @SuppressWarnings("unchecked") - public ConnectDebuggerTask getDebuggerTask( - AndroidDebugger androidDebugger, AndroidDebuggerState androidDebuggerState) - throws ExecutionException { - return getBaseDebuggerTask( - androidDebugger, androidDebuggerState, env, facet, applicationIdProvider); - } -} diff --git a/aswb/sdkcompat/as222/com/google/idea/blaze/android/run/runner/BlazeAndroidDebuggerService.java b/aswb/sdkcompat/as222/com/google/idea/blaze/android/run/runner/BlazeAndroidDebuggerService.java deleted file mode 100644 index c8658223baa..00000000000 --- a/aswb/sdkcompat/as222/com/google/idea/blaze/android/run/runner/BlazeAndroidDebuggerService.java +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Copyright 2016 The Bazel Authors. All rights reserved. - * - * 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. - */ -package com.google.idea.blaze.android.run.runner; - -import com.android.tools.idea.execution.common.debug.AndroidDebugger; -import com.android.tools.idea.execution.common.debug.AndroidDebuggerState; -import com.android.tools.idea.execution.common.debug.impl.java.AndroidJavaDebugger; -import com.android.tools.ndk.run.editor.AutoAndroidDebuggerState; -import com.google.common.collect.ImmutableList; -import com.google.idea.blaze.android.cppimpl.debug.BlazeAutoAndroidDebugger; -import com.google.idea.blaze.android.run.deployinfo.BlazeAndroidDeployInfo; -import com.google.idea.blaze.base.model.primitives.WorkspaceRoot; -import com.intellij.ide.plugins.PluginManagerCore; -import com.intellij.openapi.project.Project; -import javax.annotation.Nullable; - -/** Provides android debuggers and debugger states for blaze projects. */ -public interface BlazeAndroidDebuggerService { - - static BlazeAndroidDebuggerService getInstance(Project project) { - return project.getService(BlazeAndroidDebuggerService.class); - } - - /** Returns the standard debugger for non-native (Java) debugging. */ - AndroidDebugger getDebugger(); - - /** Returns the standard debugger for native (C++) debugging. */ - AndroidDebugger getNativeDebugger(); - - /** - * Performs additional necessary setup for native debugging, incorporating info from {@link - * BlazeAndroidDeployInfo}. - */ - void configureNativeDebugger( - AndroidDebuggerState state, @Nullable BlazeAndroidDeployInfo deployInfo); - - /** Default debugger service. */ - class DefaultDebuggerService implements BlazeAndroidDebuggerService { - private final Project project; - - public DefaultDebuggerService(Project project) { - this.project = project; - } - - @Override - public AndroidDebugger getDebugger() { - return new AndroidJavaDebugger(); - } - - @Override - public AndroidDebugger getNativeDebugger() { - return new BlazeAutoAndroidDebugger(); - } - - @Override - public void configureNativeDebugger( - AndroidDebuggerState rawState, @Nullable BlazeAndroidDeployInfo deployInfo) { - if (!isNdkPluginLoaded() && !(rawState instanceof AutoAndroidDebuggerState)) { - return; - } - AutoAndroidDebuggerState state = (AutoAndroidDebuggerState) rawState; - - // Source code is always relative to the workspace root in a blaze project. - String workingDirPath = WorkspaceRoot.fromProject(project).directory().getPath(); - state.setWorkingDir(workingDirPath); - - // Remote built binaries may use /proc/self/cwd to represent the working directory, - // so we manually map /proc/self/cwd to the workspace root. We used to use - // `plugin.symbol-file.dwarf.comp-dir-symlink-paths = "/proc/self/cwd"` - // to automatically resolve this, but it's no longer supported in newer versions of - // LLDB. - String sourceMapToWorkspaceRootCommand = - "settings append target.source-map /proc/self/cwd/ " + workingDirPath; - - ImmutableList startupCommands = - ImmutableList.builder() - .addAll(state.getUserStartupCommands()) - .add(sourceMapToWorkspaceRootCommand) - .build(); - state.setUserStartupCommands(startupCommands); - - // NDK plugin will pass symbol directories to LLDB as `settings append - // target.exec-search-paths`. - if (deployInfo != null) { - state.setSymbolDirs( - deployInfo.getSymbolFiles().stream() - .map(symbol -> symbol.getParentFile().getAbsolutePath()) - .collect(ImmutableList.toImmutableList())); - } - } - } - - static boolean isNdkPluginLoaded() { - return PluginManagerCore.getLoadedPlugins().stream() - .anyMatch( - d -> d.isEnabled() && d.getPluginId().getIdString().equals("com.android.tools.ndk")); - } -} diff --git a/aswb/sdkcompat/as222/com/google/idea/blaze/android/run/runner/BlazeAndroidDeviceSelector.java b/aswb/sdkcompat/as222/com/google/idea/blaze/android/run/runner/BlazeAndroidDeviceSelector.java deleted file mode 100644 index bc82d504278..00000000000 --- a/aswb/sdkcompat/as222/com/google/idea/blaze/android/run/runner/BlazeAndroidDeviceSelector.java +++ /dev/null @@ -1,173 +0,0 @@ -/* - * Copyright 2018 The Bazel Authors. All rights reserved. - * - * 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. - */ -package com.google.idea.blaze.android.run.runner; - -import com.android.tools.idea.execution.common.AndroidSessionInfo; -import com.android.tools.idea.run.DeviceFutures; -import com.android.tools.idea.run.editor.DeployTarget; -import com.android.tools.idea.run.editor.DeployTargetCompat; -import com.intellij.execution.ExecutionException; -import com.intellij.execution.Executor; -import com.intellij.execution.runners.ExecutionEnvironment; -import com.intellij.icons.AllIcons; -import com.intellij.openapi.diagnostic.Logger; -import com.intellij.openapi.project.Project; -import com.intellij.openapi.ui.DialogWrapper; -import com.intellij.openapi.ui.Messages; -import javax.annotation.Nullable; -import org.jetbrains.android.facet.AndroidFacet; - -/** Selects a device. */ -public interface BlazeAndroidDeviceSelector { - - /** A device session */ - class DeviceSession { - @Nullable public final DeployTarget deployTarget; - @Nullable public final DeviceFutures deviceFutures; - @Nullable public final AndroidSessionInfo sessionInfo; - - public DeviceSession( - @Nullable DeployTarget deployTarget, - @Nullable DeviceFutures deviceFutures, - @Nullable AndroidSessionInfo sessionInfo) { - this.deployTarget = deployTarget; - this.deviceFutures = deviceFutures; - this.sessionInfo = sessionInfo; - } - } - - @Nullable - DeviceSession getDevice( - Project project, - AndroidFacet facet, - Executor executor, - ExecutionEnvironment env, - AndroidSessionInfo info, - boolean debug, - int runConfigId) - throws ExecutionException; - - /** Standard device selector */ - class NormalDeviceSelector implements BlazeAndroidDeviceSelector { - - private static final DialogWrapper.DoNotAskOption ourKillLaunchOption = - new KillLaunchDialogOption(); - private static final Logger LOG = Logger.getInstance(NormalDeviceSelector.class); - - static class KillLaunchDialogOption implements DialogWrapper.DoNotAskOption { - private boolean show; - - @Override - public boolean isToBeShown() { - return !show; - } - - @Override - public void setToBeShown(boolean toBeShown, int exitCode) { - show = !toBeShown; - } - - @Override - public boolean canBeHidden() { - return true; - } - - @Override - public boolean shouldSaveOptionsOnCancel() { - return true; - } - - @Override - public String getDoNotShowMessage() { - return "Do not ask again"; - } - } - - @Override - @Nullable - public DeviceSession getDevice( - Project project, - AndroidFacet facet, - Executor executor, - ExecutionEnvironment env, - AndroidSessionInfo info, - boolean debug, - int runConfigId) - throws ExecutionException { - // If there is an existing session, then terminate those sessions - if (info != null) { - boolean continueLaunch = promptAndKillSession(executor, project, info); - if (!continueLaunch) { - return null; - } - } - - DeployTarget deployTarget = BlazeDeployTargetService.getInstance(project).getDeployTarget(); - if (deployTarget == null) { - return null; - } - - DeviceFutures deviceFutures = null; - if (!deployTarget.hasCustomRunProfileState(executor)) { - deviceFutures = DeployTargetCompat.getDevices(deployTarget, facet, project); - } - return new DeviceSession(deployTarget, deviceFutures, info); - } - - private boolean promptAndKillSession( - Executor executor, Project project, AndroidSessionInfo info) { - String previousExecutor = info.getExecutorId(); - String currentExecutor = executor.getId(); - - if (ourKillLaunchOption.isToBeShown()) { - String msg; - String noText; - if (previousExecutor.equals(currentExecutor)) { - msg = - String.format( - "Restart App?\nThe app is already running. " - + "Would you like to kill it and restart the session?"); - noText = "Cancel"; - } else { - msg = - String.format( - "To switch from %1$s to %2$s, the app has to restart. Continue?", - previousExecutor, currentExecutor); - noText = "Cancel " + currentExecutor; - } - - String targetName = info.getExecutionTarget().getDisplayName(); - String title = "Launching " + targetName; - String yesText = "Restart " + targetName; - if (Messages.NO - == Messages.showYesNoDialog( - project, - msg, - title, - yesText, - noText, - AllIcons.General.QuestionDialog, - ourKillLaunchOption)) { - return false; - } - } - - LOG.info("Disconnecting existing session of the same launch configuration"); - info.getProcessHandler().detachProcess(); - return true; - } - } -} diff --git a/aswb/sdkcompat/as222/com/google/idea/blaze/android/run/runner/BlazeAndroidLaunchTasksProvider.java b/aswb/sdkcompat/as222/com/google/idea/blaze/android/run/runner/BlazeAndroidLaunchTasksProvider.java deleted file mode 100644 index 6b23eabcdba..00000000000 --- a/aswb/sdkcompat/as222/com/google/idea/blaze/android/run/runner/BlazeAndroidLaunchTasksProvider.java +++ /dev/null @@ -1,224 +0,0 @@ -/* - * Copyright 2022 The Bazel Authors. All rights reserved. - * - * 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. - */ -package com.google.idea.blaze.android.run.runner; - -import static com.android.tools.idea.profilers.AndroidProfilerLaunchTaskContributor.isProfilerLaunch; - -import com.android.ddmlib.IDevice; -import com.android.tools.deployer.ApkVerifierTracker; -import com.android.tools.idea.editors.literals.LiveEditService; -import com.android.tools.idea.execution.common.debug.AndroidDebugger; -import com.android.tools.idea.execution.common.debug.AndroidDebuggerState; -import com.android.tools.idea.profilers.AndroidProfilerLaunchTaskContributor; -import com.android.tools.idea.run.ApkProvisionException; -import com.android.tools.idea.run.ApplicationIdProvider; -import com.android.tools.idea.run.ConsolePrinter; -import com.android.tools.idea.run.LaunchOptions; -import com.android.tools.idea.run.tasks.ClearLogcatTask; -import com.android.tools.idea.run.tasks.ConnectDebuggerTask; -import com.android.tools.idea.run.tasks.DismissKeyguardTask; -import com.android.tools.idea.run.tasks.LaunchTask; -import com.android.tools.idea.run.tasks.LaunchTasksProvider; -import com.android.tools.idea.run.tasks.ShowLogcatTask; -import com.android.tools.idea.run.tasks.StartLiveUpdateMonitoringTask; -import com.android.tools.idea.run.util.LaunchStatus; -import com.android.tools.ndk.run.editor.AutoAndroidDebuggerState; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.Lists; -import com.google.idea.blaze.android.run.binary.UserIdHelper; -import com.google.idea.blaze.android.run.deployinfo.BlazeAndroidDeployInfo; -import com.google.idea.common.experiments.BoolExperiment; -import com.intellij.execution.ExecutionException; -import com.intellij.openapi.diagnostic.Logger; -import com.intellij.openapi.project.Project; -import java.util.List; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -/** Normal launch tasks provider. #api4.1 */ -public class BlazeAndroidLaunchTasksProvider implements LaunchTasksProvider { - public static final String NATIVE_DEBUGGING_ENABLED = "NATIVE_DEBUGGING_ENABLED"; - private static final Logger LOG = Logger.getInstance(BlazeAndroidLaunchTasksProvider.class); - private static final BoolExperiment isLiveEditEnabled = - new BoolExperiment("aswb.live.edit.enabled", false); - - private final Project project; - private final BlazeAndroidRunContext runContext; - private final ApplicationIdProvider applicationIdProvider; - private final LaunchOptions.Builder launchOptionsBuilder; - - public BlazeAndroidLaunchTasksProvider( - Project project, - BlazeAndroidRunContext runContext, - ApplicationIdProvider applicationIdProvider, - LaunchOptions.Builder launchOptionsBuilder) { - this.project = project; - this.runContext = runContext; - this.applicationIdProvider = applicationIdProvider; - this.launchOptionsBuilder = launchOptionsBuilder; - } - - @NotNull - @Override - public List getTasks( - @NotNull IDevice device, - @NotNull LaunchStatus launchStatus, - @NotNull ConsolePrinter consolePrinter) - throws ExecutionException { - final List launchTasks = Lists.newArrayList(); - - String packageName; - try { - packageName = applicationIdProvider.getPackageName(); - } catch (ApkProvisionException e) { - LOG.error(e); - launchStatus.terminateLaunch("Unable to determine application id: " + e, true); - return ImmutableList.of(); - } - - Integer userId = runContext.getUserId(device, consolePrinter); - String userIdFlags = UserIdHelper.getFlagsFromUserId(userId); - String skipVerification = - ApkVerifierTracker.getSkipVerificationInstallationFlag(device, packageName); - String pmInstallOption; - if (skipVerification != null) { - pmInstallOption = userIdFlags + " " + skipVerification; - } else { - pmInstallOption = userIdFlags; - } - launchOptionsBuilder.setPmInstallOptions(d -> pmInstallOption); - - LaunchOptions launchOptions = launchOptionsBuilder.build(); - - // NOTE: Task for opening the profiler tool-window should come before deployment - // to ensure the tool-window opens correctly. This is required because starting - // the profiler session requires the tool-window to be open. - if (isProfilerLaunch(runContext.getExecutor())) { - launchTasks.add(new BlazeAndroidOpenProfilerWindowTask(project)); - } - - if (launchOptions.isClearLogcatBeforeStart()) { - launchTasks.add(new ClearLogcatTask(project)); - } - - launchTasks.add(new DismissKeyguardTask()); - - if (launchOptions.isDeploy()) { - ImmutableList deployTasks = runContext.getDeployTasks(device, launchOptions); - launchTasks.addAll(deployTasks); - } - if (launchStatus.isLaunchTerminated()) { - return ImmutableList.copyOf(launchTasks); - } - - try { - if (launchOptions.isDebug()) { - launchTasks.add(new CheckApkDebuggableTask(runContext.getBuildStep().getDeployInfo())); - } - - ImmutableList.Builder amStartOptions = ImmutableList.builder(); - amStartOptions.add(runContext.getAmStartOptions()); - if (isProfilerLaunch(runContext.getExecutor())) { - amStartOptions.add( - AndroidProfilerLaunchTaskContributor.getAmStartOptions( - project, - packageName, - runContext.getProfileState(), - device, - runContext.getExecutor())); - launchTasks.add( - new AndroidProfilerLaunchTaskContributor.AndroidProfilerToolWindowLaunchTask( - project, packageName)); - } - - LaunchTask appLaunchTask = - runContext.getApplicationLaunchTask( - launchOptions, userId, String.join(" ", amStartOptions.build()), launchStatus); - if (appLaunchTask != null) { - launchTasks.add(appLaunchTask); - if (isLiveEditEnabled.getValue()) { - launchTasks.add( - new StartLiveUpdateMonitoringTask( - LiveEditService.getInstance(project).getCallback(packageName, device))); - } - } - } catch (ApkProvisionException e) { - LOG.error(e); - launchStatus.terminateLaunch("Unable to determine application id: " + e, true); - return ImmutableList.of(); - } catch (ExecutionException e) { - launchStatus.terminateLaunch(e.getMessage(), true); - return ImmutableList.of(); - } - - if (launchOptions.isOpenLogcatAutomatically()) { - launchTasks.add(new ShowLogcatTask(project, packageName)); - } - - return ImmutableList.copyOf(launchTasks); - } - - @Override - @Nullable - public ConnectDebuggerTask getConnectDebuggerTask() { - LaunchOptions launchOptions = launchOptionsBuilder.build(); - if (!launchOptions.isDebug()) { - return null; - } - - BlazeAndroidDeployInfo deployInfo; - try { - deployInfo = runContext.getBuildStep().getDeployInfo(); - } catch (ApkProvisionException e) { - LOG.error(e); - deployInfo = null; - } - - BlazeAndroidDebuggerService debuggerService = BlazeAndroidDebuggerService.getInstance(project); - if (isNativeDebuggingEnabled(launchOptions)) { - AndroidDebugger debugger = debuggerService.getNativeDebugger(); - // The below state type should be AutoAndroidDebuggerState, but referencing it will crash the - // task if the NDK plugin is not loaded. - AndroidDebuggerState state = debugger.createState(); - debuggerService.configureNativeDebugger(state, deployInfo); - return getConnectDebuggerTask(debugger, state); - } else { - AndroidDebugger debugger = debuggerService.getDebugger(); - return getConnectDebuggerTask(debugger, debugger.createState()); - } - } - - @Nullable - private ConnectDebuggerTask getConnectDebuggerTask( - @NotNull AndroidDebugger debugger, @NotNull /* S */ AndroidDebuggerState debuggerState) { - try { - return runContext.getDebuggerTask(debugger, debuggerState); - } catch (ExecutionException e) { - LOG.warn("Cannot get debugger task", e); - return null; - } - } - - @Override - public String getLaunchTypeDisplayName() { - return "Launch"; - } - - private boolean isNativeDebuggingEnabled(LaunchOptions launchOptions) { - Object flag = launchOptions.getExtraOption(NATIVE_DEBUGGING_ENABLED); - return flag instanceof Boolean && (Boolean) flag; - } -} diff --git a/aswb/sdkcompat/as222/com/google/idea/blaze/android/run/runner/BlazeAndroidOpenProfilerWindowTask.java b/aswb/sdkcompat/as222/com/google/idea/blaze/android/run/runner/BlazeAndroidOpenProfilerWindowTask.java deleted file mode 100644 index 47a02f53f2c..00000000000 --- a/aswb/sdkcompat/as222/com/google/idea/blaze/android/run/runner/BlazeAndroidOpenProfilerWindowTask.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (C) 2019 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. - */ -package com.google.idea.blaze.android.run.runner; - -import com.android.tools.idea.profilers.ProfilerProgramRunner; -import com.android.tools.idea.run.tasks.LaunchContext; -import com.android.tools.idea.run.tasks.LaunchResult; -import com.android.tools.idea.run.tasks.LaunchTask; -import com.android.tools.idea.run.tasks.LaunchTaskDurations; -import com.intellij.openapi.application.ApplicationManager; -import com.intellij.openapi.project.Project; - -/** Opens the profiler tool window. */ -public class BlazeAndroidOpenProfilerWindowTask implements LaunchTask { - private static final String ID = "OPEN_PROFILER_TOOLWINDOW"; - private final Project project; - - public BlazeAndroidOpenProfilerWindowTask(Project project) { - this.project = project; - } - - @Override - public String getDescription() { - return "Open the Profiler Tool Window"; - } - - @Override - public int getDuration() { - return LaunchTaskDurations.LAUNCH_ACTIVITY; - } - - @Override - public String getId() { - return ID; - } - - @Override - public LaunchResult run(LaunchContext launchContext) { - ApplicationManager.getApplication() - .invokeLater(() -> ProfilerProgramRunner.createProfilerToolWindow(project, null)); - return LaunchResult.success(); - } -} diff --git a/aswb/sdkcompat/as222/com/google/idea/blaze/android/run/runner/BlazeAndroidRunConfigurationRunner.java b/aswb/sdkcompat/as222/com/google/idea/blaze/android/run/runner/BlazeAndroidRunConfigurationRunner.java deleted file mode 100644 index 099f5694e73..00000000000 --- a/aswb/sdkcompat/as222/com/google/idea/blaze/android/run/runner/BlazeAndroidRunConfigurationRunner.java +++ /dev/null @@ -1,222 +0,0 @@ -/* - * Copyright 2016 The Bazel Authors. All rights reserved. - * - * 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. - */ - -package com.google.idea.blaze.android.run.runner; - -import com.android.ddmlib.IDevice; -import com.android.tools.idea.execution.common.AndroidSessionInfo; -import com.android.tools.idea.run.DeviceFutures; -import com.android.tools.idea.run.LaunchOptions; -import com.android.tools.idea.run.editor.DeployTarget; -import com.android.tools.idea.run.editor.DeployTargetState; -import com.android.tools.idea.run.util.LaunchUtils; -import com.google.common.util.concurrent.Futures; -import com.google.common.util.concurrent.ListenableFuture; -import com.google.idea.blaze.android.run.BlazeAndroidRunState; -import com.google.idea.blaze.base.async.executor.ProgressiveTaskWithProgressIndicator; -import com.google.idea.blaze.base.command.BlazeInvocationContext.ContextType; -import com.google.idea.blaze.base.experiments.ExperimentScope; -import com.google.idea.blaze.base.issueparser.BlazeIssueParser; -import com.google.idea.blaze.base.model.primitives.WorkspaceRoot; -import com.google.idea.blaze.base.run.BlazeCommandRunConfiguration; -import com.google.idea.blaze.base.run.confighandler.BlazeCommandRunConfigurationRunner; -import com.google.idea.blaze.base.scope.BlazeContext; -import com.google.idea.blaze.base.scope.Scope; -import com.google.idea.blaze.base.scope.ScopedTask; -import com.google.idea.blaze.base.scope.output.IssueOutput; -import com.google.idea.blaze.base.scope.scopes.IdeaLogScope; -import com.google.idea.blaze.base.scope.scopes.ProblemsViewScope; -import com.google.idea.blaze.base.scope.scopes.ToolWindowScope; -import com.google.idea.blaze.base.settings.Blaze; -import com.google.idea.blaze.base.settings.BlazeUserSettings; -import com.google.idea.blaze.base.toolwindow.Task; -import com.intellij.execution.ExecutionException; -import com.intellij.execution.Executor; -import com.intellij.execution.configurations.RunProfileState; -import com.intellij.execution.executors.DefaultDebugExecutor; -import com.intellij.execution.runners.ExecutionEnvironment; -import com.intellij.openapi.diagnostic.Logger; -import com.intellij.openapi.module.Module; -import com.intellij.openapi.project.Project; -import com.intellij.openapi.util.Key; -import java.util.concurrent.CancellationException; -import javax.annotation.Nullable; -import org.jetbrains.android.facet.AndroidFacet; -import org.jetbrains.android.util.AndroidBundle; - -/** - * Supports the execution. Used by both android_binary and android_test. - * - *

Builds the APK and installs it, launches and debug tasks, etc. - * - *

Any indirection between android_binary/android_test, mobile-install, InstantRun etc. should - * come via the strategy class. - */ -public final class BlazeAndroidRunConfigurationRunner - implements BlazeCommandRunConfigurationRunner { - - private static final Logger LOG = Logger.getInstance(BlazeAndroidRunConfigurationRunner.class); - - private static final Key RUN_CONTEXT_KEY = - Key.create("blaze.run.context"); - public static final Key DEVICE_SESSION_KEY = - Key.create("blaze.device.session"); - - private final Module module; - private final BlazeAndroidRunContext runContext; - private final BlazeCommandRunConfiguration runConfig; - - public BlazeAndroidRunConfigurationRunner( - Module module, BlazeAndroidRunContext runContext, BlazeCommandRunConfiguration runConfig) { - this.module = module; - this.runContext = runContext; - this.runConfig = runConfig; - } - - @Override - @Nullable - public final RunProfileState getRunProfileState(final Executor executor, ExecutionEnvironment env) - throws ExecutionException { - - final AndroidFacet facet = AndroidFacet.getInstance(module); - assert facet != null : "Enforced by fatal validation check in createRunner."; - final Project project = env.getProject(); - - boolean isDebug = executor instanceof DefaultDebugExecutor; - AndroidSessionInfo info = - AndroidSessionInfo.findOldSession(project, null, runConfig, env.getExecutionTarget()); - - BlazeAndroidDeviceSelector deviceSelector = runContext.getDeviceSelector(); - BlazeAndroidDeviceSelector.DeviceSession deviceSession = - deviceSelector.getDevice( - project, facet, executor, env, info, isDebug, runConfig.getUniqueID()); - if (deviceSession == null) { - return null; - } - - DeployTarget deployTarget = deviceSession.deployTarget; - if (deployTarget != null && deployTarget.hasCustomRunProfileState(executor)) { - return deployTarget.getRunProfileState(executor, env, DeployTargetState.DEFAULT_STATE); - } - - DeviceFutures deviceFutures = deviceSession.deviceFutures; - if (deviceFutures == null) { - // The user deliberately canceled, or some error was encountered and exposed by the chooser. - // Quietly exit. - return null; - } - - if (deviceFutures.get().isEmpty()) { - throw new ExecutionException(AndroidBundle.message("deployment.target.not.found")); - } - - if (isDebug) { - String error = canDebug(deviceFutures, facet, module.getName()); - if (error != null) { - throw new ExecutionException(error); - } - } - - LaunchOptions.Builder launchOptionsBuilder = getDefaultLaunchOptions().setDebug(isDebug); - runContext.augmentLaunchOptions(launchOptionsBuilder); - - // Store the run context on the execution environment so before-run tasks can access it. - env.putCopyableUserData(RUN_CONTEXT_KEY, runContext); - env.putCopyableUserData(DEVICE_SESSION_KEY, deviceSession); - - return new BlazeAndroidRunState(env, launchOptionsBuilder, deviceSession, runContext); - } - - @Nullable - private static String canDebug( - DeviceFutures deviceFutures, AndroidFacet facet, String moduleName) { - // If we are debugging on a device, then the app needs to be debuggable - for (ListenableFuture future : deviceFutures.get()) { - if (!future.isDone()) { - // this is an emulator, and we assume that all emulators are debuggable - continue; - } - IDevice device = Futures.getUnchecked(future); - if (!LaunchUtils.canDebugAppOnDevice(facet, device)) { - return AndroidBundle.message( - "android.cannot.debug.noDebugPermissions", moduleName, device.getName()); - } - } - return null; - } - - private static LaunchOptions.Builder getDefaultLaunchOptions() { - return LaunchOptionsCompat.getDefaultLaunchOptions(); - } - - @Override - public boolean executeBeforeRunTask(ExecutionEnvironment env) { - final Project project = env.getProject(); - BlazeUserSettings settings = BlazeUserSettings.getInstance(); - return Scope.root( - context -> { - context - .push(new ProblemsViewScope(project, settings.getShowProblemsViewOnRun())) - .push(new ExperimentScope()) - .push( - new ToolWindowScope.Builder( - project, new Task(project, "Build apk", Task.Type.BEFORE_LAUNCH)) - .setPopupBehavior(settings.getShowBlazeConsoleOnRun()) - .setIssueParsers( - BlazeIssueParser.defaultIssueParsers( - project, - WorkspaceRoot.fromProject(project), - ContextType.BeforeRunTask)) - .build()) - .push(new IdeaLogScope()); - - BlazeAndroidRunContext runContext = env.getCopyableUserData(RUN_CONTEXT_KEY); - if (runContext == null) { - IssueOutput.error("Could not find run context. Please try again").submit(context); - return false; - } - BlazeAndroidDeviceSelector.DeviceSession deviceSession = - env.getCopyableUserData(DEVICE_SESSION_KEY); - - ApkBuildStep buildStep = runContext.getBuildStep(); - ScopedTask buildTask = - new ScopedTask(context) { - @Override - protected Void execute(BlazeContext context) { - buildStep.build(context, deviceSession); - return null; - } - }; - - try { - ListenableFuture buildFuture = - ProgressiveTaskWithProgressIndicator.builder( - project, - String.format("Executing %s apk build", Blaze.buildSystemName(project))) - .submitTaskWithResult(buildTask); - Futures.getChecked(buildFuture, ExecutionException.class); - } catch (ExecutionException e) { - context.setHasError(); - } catch (CancellationException e) { - context.setCancelled(); - } catch (Exception e) { - LOG.error(e); - return false; - } - return context.shouldContinue(); - }); - } -} diff --git a/aswb/sdkcompat/as222/com/google/idea/blaze/android/run/runner/BlazeAndroidRunContext.java b/aswb/sdkcompat/as222/com/google/idea/blaze/android/run/runner/BlazeAndroidRunContext.java deleted file mode 100644 index a35a0cdaa46..00000000000 --- a/aswb/sdkcompat/as222/com/google/idea/blaze/android/run/runner/BlazeAndroidRunContext.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright 2016 The Bazel Authors. All rights reserved. - * - * 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. - */ -package com.google.idea.blaze.android.run.runner; - -import com.android.ddmlib.IDevice; -import com.android.tools.idea.execution.common.debug.AndroidDebugger; -import com.android.tools.idea.execution.common.debug.AndroidDebuggerState; -import com.android.tools.idea.run.ApplicationIdProvider; -import com.android.tools.idea.run.ConsolePrinter; -import com.android.tools.idea.run.ConsoleProvider; -import com.android.tools.idea.run.LaunchOptions; -import com.android.tools.idea.run.editor.ProfilerState; -import com.android.tools.idea.run.tasks.ConnectDebuggerTask; -import com.android.tools.idea.run.tasks.LaunchTask; -import com.android.tools.idea.run.tasks.LaunchTasksProvider; -import com.android.tools.idea.run.util.LaunchStatus; -import com.google.common.collect.ImmutableList; -import com.intellij.execution.ExecutionException; -import com.intellij.execution.Executor; -import javax.annotation.Nullable; -import org.jetbrains.annotations.NotNull; - -/** Instantiated when the configuration wants to run. */ -public interface BlazeAndroidRunContext { - - BlazeAndroidDeviceSelector getDeviceSelector(); - - void augmentLaunchOptions(LaunchOptions.Builder options); - - ConsoleProvider getConsoleProvider(); - - ApkBuildStep getBuildStep(); - - ApplicationIdProvider getApplicationIdProvider() throws ExecutionException; - - LaunchTasksProvider getLaunchTasksProvider(LaunchOptions.Builder launchOptionsBuilder) - throws ExecutionException; - - /** Returns the tasks to deploy the application. */ - ImmutableList getDeployTasks(IDevice device, LaunchOptions launchOptions) - throws ExecutionException; - - /** Returns the task to launch the application. */ - @Nullable - LaunchTask getApplicationLaunchTask( - LaunchOptions launchOptions, - @Nullable Integer userId, - @NotNull String contributorsAmStartOptions, - LaunchStatus launchStatus) - throws ExecutionException; - - /** Returns the task to connect the debugger. */ - @Nullable - ConnectDebuggerTask getDebuggerTask( - AndroidDebugger androidDebugger, AndroidDebuggerState androidDebuggerState) - throws ExecutionException; - - @Nullable - Integer getUserId(IDevice device, ConsolePrinter consolePrinter) throws ExecutionException; - - String getAmStartOptions(); - - Executor getExecutor(); - - ProfilerState getProfileState(); -} diff --git a/aswb/sdkcompat/as222/com/google/idea/blaze/android/run/runner/CheckApkDebuggableTask.java b/aswb/sdkcompat/as222/com/google/idea/blaze/android/run/runner/CheckApkDebuggableTask.java deleted file mode 100644 index e912e81538c..00000000000 --- a/aswb/sdkcompat/as222/com/google/idea/blaze/android/run/runner/CheckApkDebuggableTask.java +++ /dev/null @@ -1,153 +0,0 @@ -/* - * Copyright 2020 The Bazel Authors. All rights reserved. - * - * 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. - */ -package com.google.idea.blaze.android.run.runner; - -import static com.google.common.collect.ImmutableList.toImmutableList; - -import com.android.ddmlib.IDevice; -import com.android.tools.idea.run.ConsolePrinter; -import com.android.tools.idea.run.tasks.LaunchContext; -import com.android.tools.idea.run.tasks.LaunchResult; -import com.android.tools.idea.run.tasks.LaunchTask; -import com.google.common.annotations.VisibleForTesting; -import com.google.common.collect.ImmutableList; -import com.google.devrel.gmscore.tools.apk.arsc.BinaryResourceFile; -import com.google.devrel.gmscore.tools.apk.arsc.Chunk; -import com.google.devrel.gmscore.tools.apk.arsc.XmlAttribute; -import com.google.devrel.gmscore.tools.apk.arsc.XmlChunk; -import com.google.devrel.gmscore.tools.apk.arsc.XmlStartElementChunk; -import com.google.idea.blaze.android.run.deployinfo.BlazeAndroidDeployInfo; -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.util.List; -import java.util.zip.ZipFile; -import org.jetbrains.annotations.NotNull; - -/** Checks APKs to see if they are debuggable and warn the user if they aren't. */ -public class CheckApkDebuggableTask implements LaunchTask { - private static final String ID = "APK_DEBUGGABILITY_CHECKER"; - private final BlazeAndroidDeployInfo deployInfo; - - public CheckApkDebuggableTask(BlazeAndroidDeployInfo deployInfo) { - this.deployInfo = deployInfo; - } - - @Override - public String getDescription() { - return "Checking debug attribute in APKs"; - } - - @Override - public int getDuration() { - return 2; // See com.android.tools.idea.run.tasks.LaunchTaskDurations for related magic numbers. - } - - @Override - public String getId() { - return ID; - } - - @Override - public LaunchResult run(@NotNull LaunchContext launchContext) { - checkApkDebuggableTaskDelegate( - deployInfo, launchContext.getDevice(), launchContext.getConsolePrinter()); - return LaunchResult.success(); // Don't block deployment. - } - - /** - * Checks if all APKs in the deploy info are debuggable and output an error message to console if - * any of them aren't. This check doesn't apply if the target device is a running a debug build - * android (e.g. userdebug build) and will simply return. - */ - @VisibleForTesting - public static void checkApkDebuggableTaskDelegate( - BlazeAndroidDeployInfo deployInfo, IDevice device, ConsolePrinter consolePrinter) { - if (isDebugDevice(device)) { - return; - } - try { - ImmutableList nonDebuggableApkNames = - getNonDebuggableDeployApks(deployInfo).stream() - .map(File::getName) - .collect(toImmutableList()); - if (nonDebuggableApkNames.isEmpty()) { - return; - } - // Use "and" as delimiter because there won't be more than 2 APKs, so "and" makes more sense. - String message = - "The \"android:debuggable\" attribute is not set to \"true\" in " - + String.join(" and ", nonDebuggableApkNames) - + ". Debugger may not attach properly or attach at all." - + " Please ensure \"android:debuggable\" attribute is set to true or" - + " overridden to true via manifest overrides."; - consolePrinter.stderr(message); - } catch (IOException e) { - consolePrinter.stderr("Could not read deploy apks: " + e.getMessage()); - } - } - - private static ImmutableList getNonDebuggableDeployApks(BlazeAndroidDeployInfo deployInfo) - throws IOException { - ImmutableList.Builder nonDebuggableApks = ImmutableList.builder(); - for (File apk : deployInfo.getApksToDeploy()) { - if (!isApkDebuggable(apk)) { - nonDebuggableApks.add(apk); - } - } - return nonDebuggableApks.build(); - } - - /** Returns true if the device is a debug build device. */ - private static boolean isDebugDevice(IDevice device) { - String roDebuggable = device.getProperty("ro.debuggable"); - return (roDebuggable != null && roDebuggable.equals("1")); - } - - @VisibleForTesting - public static boolean isApkDebuggable(File apk) throws IOException { - try (ZipFile zipFile = new ZipFile(apk); - InputStream stream = zipFile.getInputStream(zipFile.getEntry("AndroidManifest.xml"))) { - BinaryResourceFile file = BinaryResourceFile.fromInputStream(stream); - List chunks = file.getChunks(); - - if (chunks.isEmpty()) { - throw new IllegalArgumentException("Invalid APK, empty manifest"); - } - - if (!(chunks.get(0) instanceof XmlChunk)) { - throw new IllegalArgumentException("APK manifest chunk[0] != XmlChunk"); - } - - XmlChunk xmlChunk = (XmlChunk) chunks.get(0); - for (Chunk chunk : xmlChunk.getChunks().values()) { - if (!(chunk instanceof XmlStartElementChunk)) { - continue; - } - - XmlStartElementChunk startChunk = (XmlStartElementChunk) chunk; - if (startChunk.getName().equals("application")) { - for (XmlAttribute attribute : startChunk.getAttributes()) { - if (attribute.name().equals("debuggable")) { - return true; - } - } - } - } - } - return false; - } -} diff --git a/aswb/sdkcompat/as222/com/google/idea/blaze/android/run/runner/LaunchOptionsCompat.java b/aswb/sdkcompat/as222/com/google/idea/blaze/android/run/runner/LaunchOptionsCompat.java deleted file mode 100644 index 5a606a8a2ea..00000000000 --- a/aswb/sdkcompat/as222/com/google/idea/blaze/android/run/runner/LaunchOptionsCompat.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright 2022 The Bazel Authors. All rights reserved. - * - * 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. - */ -package com.google.idea.blaze.android.run.runner; - -import com.android.tools.idea.run.LaunchOptions; - -/** Compat class for LunchOptions.Builder. */ -public class LaunchOptionsCompat { - - private LaunchOptionsCompat() {} - - /** Create default launch options to maintain compatibility with #api211. */ - public static LaunchOptions.Builder getDefaultLaunchOptions() { - return LaunchOptions.builder().setClearLogcatBeforeStart(false); - } -} diff --git a/aswb/sdkcompat/as222/com/google/idea/blaze/android/run/test/BlazeAndroidTestLaunchTask.java b/aswb/sdkcompat/as222/com/google/idea/blaze/android/run/test/BlazeAndroidTestLaunchTask.java deleted file mode 100644 index 3e4fbaed099..00000000000 --- a/aswb/sdkcompat/as222/com/google/idea/blaze/android/run/test/BlazeAndroidTestLaunchTask.java +++ /dev/null @@ -1,296 +0,0 @@ -/* - * Copyright 2016 The Bazel Authors. All rights reserved. - * - * 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. - */ -package com.google.idea.blaze.android.run.test; - -import com.android.tools.idea.run.ConsolePrinter; -import com.android.tools.idea.run.tasks.LaunchContext; -import com.android.tools.idea.run.tasks.LaunchResult; -import com.android.tools.idea.run.tasks.LaunchTask; -import com.android.tools.idea.run.tasks.LaunchTaskDurations; -import com.android.tools.idea.run.util.LaunchStatus; -import com.android.tools.idea.run.util.ProcessHandlerLaunchStatus; -import com.google.common.util.concurrent.ListenableFuture; -import com.google.idea.blaze.base.async.executor.BlazeExecutor; -import com.google.idea.blaze.base.async.process.ExternalTask; -import com.google.idea.blaze.base.async.process.LineProcessingOutputStream; -import com.google.idea.blaze.base.command.BlazeCommand; -import com.google.idea.blaze.base.command.BlazeCommandName; -import com.google.idea.blaze.base.command.BlazeFlags; -import com.google.idea.blaze.base.command.buildresult.BuildResultHelper; -import com.google.idea.blaze.base.command.buildresult.BuildResultHelper.GetArtifactsException; -import com.google.idea.blaze.base.command.buildresult.BuildResultHelperBep; -import com.google.idea.blaze.base.filecache.FileCaches; -import com.google.idea.blaze.base.ideinfo.AndroidInstrumentationInfo; -import com.google.idea.blaze.base.ideinfo.TargetIdeInfo; -import com.google.idea.blaze.base.ideinfo.TargetKey; -import com.google.idea.blaze.base.model.BlazeProjectData; -import com.google.idea.blaze.base.model.primitives.Label; -import com.google.idea.blaze.base.model.primitives.WorkspaceRoot; -import com.google.idea.blaze.base.projectview.ProjectViewManager; -import com.google.idea.blaze.base.projectview.ProjectViewSet; -import com.google.idea.blaze.base.run.testlogs.BlazeTestResultHolder; -import com.google.idea.blaze.base.scope.Scope; -import com.google.idea.blaze.base.scope.output.IssueOutput; -import com.google.idea.blaze.base.settings.Blaze; -import com.google.idea.blaze.base.sync.aspects.BlazeBuildOutputs; -import com.google.idea.blaze.base.sync.aspects.BuildResult; -import com.google.idea.blaze.base.sync.data.BlazeProjectDataManager; -import com.google.idea.blaze.base.util.SaveUtil; -import com.google.idea.blaze.java.AndroidBlazeRules.RuleTypes; -import com.intellij.execution.process.ProcessAdapter; -import com.intellij.execution.process.ProcessEvent; -import com.intellij.execution.process.ProcessHandler; -import com.intellij.openapi.diagnostic.Logger; -import com.intellij.openapi.project.Project; -import java.util.List; -import java.util.Optional; -import java.util.concurrent.CancellationException; -import java.util.concurrent.ExecutionException; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.ide.PooledThreadExecutor; - -/** - * An Android application launcher that invokes `blaze test` on an android_test target, and sets up - * process handling and debugging for the test run. - */ -public class BlazeAndroidTestLaunchTask implements LaunchTask { - private static final String ID = "BLAZE_ANDROID_TEST"; - - // Uses a local device/emulator attached to adb to run an android_test. - public static final String TEST_LOCAL_DEVICE = - BlazeFlags.TEST_ARG + "--device_broker_type=LOCAL_ADB_SERVER"; - // Uses a local device/emulator attached to adb to run an android_test. - public static final String TEST_DEBUG = BlazeFlags.TEST_ARG + "--enable_debug"; - // Specifies the serial number for a local test device. - private static final String TEST_DEVICE_SERIAL = "--device_serial_number="; - private static final Logger LOG = Logger.getInstance(BlazeAndroidTestLaunchTask.class); - - private final Project project; - private final Label target; - private final List buildFlags; - private final BlazeAndroidTestFilter testFilter; - private final BlazeTestResultHolder testResultsHolder; - - private ListenableFuture blazeResult; - - private final BlazeAndroidTestRunContext runContext; - - private final boolean debug; - - public BlazeAndroidTestLaunchTask( - Project project, - Label target, - List buildFlags, - BlazeAndroidTestFilter testFilter, - BlazeAndroidTestRunContext runContext, - boolean debug, - BlazeTestResultHolder testResultsHolder) { - this.project = project; - this.target = target; - this.buildFlags = buildFlags; - this.testFilter = testFilter; - this.runContext = runContext; - this.debug = debug; - this.testResultsHolder = testResultsHolder; - } - - @NotNull - @Override - public String getDescription() { - return String.format("Running %s tests", Blaze.buildSystemName(project)); - } - - @Override - public int getDuration() { - return LaunchTaskDurations.LAUNCH_ACTIVITY; - } - - @Override - public LaunchResult run(@NotNull LaunchContext launchContext) { - BlazeExecutor blazeExecutor = BlazeExecutor.getInstance(); - - ProcessHandlerLaunchStatus processHandlerLaunchStatus = - (ProcessHandlerLaunchStatus) launchContext.getLaunchStatus(); - final ProcessHandler processHandler = processHandlerLaunchStatus.getProcessHandler(); - - blazeResult = - blazeExecutor.submit( - () -> - Scope.root( - context -> { - SaveUtil.saveAllFiles(); - - ProjectViewSet projectViewSet = - ProjectViewManager.getInstance(project).getProjectViewSet(); - if (projectViewSet == null) { - IssueOutput.error("Could not load project view. Please resync project.") - .submit(context); - return false; - } - - BlazeProjectData projectData = - BlazeProjectDataManager.getInstance(project).getBlazeProjectData(); - TargetIdeInfo targetInfo = - projectData.getTargetMap().get(TargetKey.forPlainTarget(target)); - if (targetInfo == null - || targetInfo.getKind() - != RuleTypes.ANDROID_INSTRUMENTATION_TEST.getKind()) { - IssueOutput.error( - "Unable to identify target \"" - + target - + "\". If this is a newly added target, please sync the" - + " project and try again.") - .submit(context); - return null; - } - AndroidInstrumentationInfo testInstrumentationInfo = - targetInfo.getAndroidInstrumentationInfo(); - if (testInstrumentationInfo == null) { - IssueOutput.error( - "Required target data missing for \"" - + target - + "\". Has the target definition changed recently? Please" - + " sync the project and try again.") - .submit(context); - return null; - } - - BlazeCommand.Builder commandBuilder = - BlazeCommand.builder( - Blaze.getBuildSystemProvider(project) - .getBuildSystem() - .getBuildInvoker(project, context), - BlazeCommandName.TEST) - .addTargets(target); - // Build flags must match BlazeBeforeRunTask. - commandBuilder.addBlazeFlags(buildFlags); - - // Run the test on the selected local device/emulator if no target device is - // specified. - Label targetDevice = testInstrumentationInfo.getTargetDevice(); - if (targetDevice == null) { - commandBuilder - .addBlazeFlags(TEST_LOCAL_DEVICE, BlazeFlags.TEST_OUTPUT_STREAMED) - .addBlazeFlags( - testDeviceSerialFlags(launchContext.getDevice().getSerialNumber())) - .addBlazeFlags(testFilter.getBlazeFlags()); - } - - if (debug) { - commandBuilder.addBlazeFlags(TEST_DEBUG, BlazeFlags.NO_CACHE_TEST_RESULTS); - } - - ConsolePrinter printer = launchContext.getConsolePrinter(); - LineProcessingOutputStream.LineProcessor stdoutLineProcessor = - line -> { - printer.stdout(line); - return true; - }; - LineProcessingOutputStream.LineProcessor stderrLineProcessor = - line -> { - printer.stderr(line); - return true; - }; - - printer.stdout( - String.format("Starting %s test...\n", Blaze.buildSystemName(project))); - - int retVal; - try (BuildResultHelper buildResultHelper = new BuildResultHelperBep()) { - commandBuilder.addBlazeFlags(buildResultHelper.getBuildFlags()); - BlazeCommand command = commandBuilder.build(); - printer.stdout(command + "\n"); - - retVal = - ExternalTask.builder(WorkspaceRoot.fromProject(project)) - .addBlazeCommand(command) - .context(context) - .stdout(LineProcessingOutputStream.of(stdoutLineProcessor)) - .stderr(LineProcessingOutputStream.of(stderrLineProcessor)) - .build() - .run(); - - if (retVal != 0) { - context.setHasError(); - } else { - testResultsHolder.setTestResults( - buildResultHelper.getTestResults(Optional.empty())); - } - ListenableFuture unusedFuture = - FileCaches.refresh( - project, - context, - BlazeBuildOutputs.noOutputs(BuildResult.fromExitCode(retVal))); - } catch (GetArtifactsException e) { - LOG.error(e.getMessage()); - } - return !context.hasErrors(); - })); - - blazeResult.addListener(runContext::onLaunchTaskComplete, PooledThreadExecutor.INSTANCE); - - // The debug case is set up in ConnectBlazeTestDebuggerTask - if (!debug) { - waitAndSetUpForKillingBlazeOnStop(processHandler, launchContext.getLaunchStatus()); - } - return LaunchResult.success(); - } - - @NotNull - @Override - public String getId() { - return ID; - } - - /** - * Hooks up the Blaze process to be killed if the user hits the 'Stop' button, then waits for the - * Blaze process to stop. In non-debug mode, we wait for test execution to finish before returning - * from launch() (this matches the behavior of the stock ddmlib runner). - */ - @SuppressWarnings("Interruption") - private void waitAndSetUpForKillingBlazeOnStop( - @NotNull final ProcessHandler processHandler, @NotNull final LaunchStatus launchStatus) { - processHandler.addProcessListener( - new ProcessAdapter() { - @Override - public void processWillTerminate(ProcessEvent event, boolean willBeDestroyed) { - blazeResult.cancel(true /* mayInterruptIfRunning */); - launchStatus.terminateLaunch("Test run stopped.\n", true); - } - }); - - try { - blazeResult.get(); - launchStatus.terminateLaunch("Tests ran to completion.\n", true); - } catch (CancellationException e) { - // The user has canceled the test. - launchStatus.terminateLaunch("Test run stopped.\n", true); - } catch (InterruptedException e) { - // We've been interrupted - cancel the underlying Blaze process. - blazeResult.cancel(true /* mayInterruptIfRunning */); - launchStatus.terminateLaunch("Test run stopped.\n", true); - } catch (ExecutionException e) { - LOG.error(e); - launchStatus.terminateLaunch( - "Test run stopped due to internal exception. Please file a bug report.\n", true); - } - } - - @NotNull - private static String testDeviceSerialFlags(@NotNull String serial) { - return BlazeFlags.TEST_ARG + TEST_DEVICE_SERIAL + serial; - } -} diff --git a/aswb/sdkcompat/as222/com/google/idea/blaze/android/run/test/BlazeAndroidTestProgramRunner.java b/aswb/sdkcompat/as222/com/google/idea/blaze/android/run/test/BlazeAndroidTestProgramRunner.java deleted file mode 100644 index 024033c74af..00000000000 --- a/aswb/sdkcompat/as222/com/google/idea/blaze/android/run/test/BlazeAndroidTestProgramRunner.java +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright 2018 The Bazel Authors. All rights reserved. - * - * 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. - */ -package com.google.idea.blaze.android.run.test; - -import com.android.tools.idea.execution.common.AndroidSessionInfo; -import com.android.tools.idea.run.AndroidProgramRunner; -import com.android.tools.idea.run.AndroidSessionInfoCompat; -import com.google.idea.blaze.android.run.BlazeAndroidRunConfigurationHandler; -import com.google.idea.blaze.base.run.BlazeCommandRunConfiguration; -import com.intellij.execution.ExecutionException; -import com.intellij.execution.ExecutionResult; -import com.intellij.execution.configurations.RunConfiguration; -import com.intellij.execution.configurations.RunProfile; -import com.intellij.execution.configurations.RunProfileState; -import com.intellij.execution.executors.DefaultDebugExecutor; -import com.intellij.execution.executors.DefaultRunExecutor; -import com.intellij.execution.process.ProcessHandler; -import com.intellij.execution.runners.ExecutionEnvironment; -import com.intellij.execution.runners.RunContentBuilder; -import com.intellij.execution.ui.RunContentDescriptor; -import com.intellij.openapi.fileEditor.FileDocumentManager; - -/** Program runner for configurations from {@link BlazeAndroidTestRunConfigurationHandler}. */ -public class BlazeAndroidTestProgramRunner extends AndroidProgramRunner { - @Override - public boolean canRun(String executorId, RunProfile profile) { - BlazeAndroidRunConfigurationHandler handler = - BlazeAndroidRunConfigurationHandler.getHandlerFrom(profile); - if (!(handler instanceof BlazeAndroidTestRunConfigurationHandler)) { - return false; - } - if (!(profile instanceof BlazeCommandRunConfiguration)) { - return false; - } - return DefaultRunExecutor.EXECUTOR_ID.equals(executorId) - || DefaultDebugExecutor.EXECUTOR_ID.equals(executorId); - } - - @Override - protected boolean canRunWithMultipleDevices(String executorId) { - return false; - } - - @Override - protected RunContentDescriptor doExecute( - final RunProfileState state, final ExecutionEnvironment env) throws ExecutionException { - FileDocumentManager.getInstance().saveAllDocuments(); - ExecutionResult result = state.execute(env.getExecutor(), this); - RunContentDescriptor descriptor = - new RunContentBuilder(result, env).showRunContent(env.getContentToReuse()); - if (descriptor != null) { - ProcessHandler processHandler = descriptor.getProcessHandler(); - assert processHandler != null; - RunProfile runProfile = env.getRunProfile(); - RunConfiguration runConfiguration = - (runProfile instanceof RunConfiguration) ? (RunConfiguration) runProfile : null; - AndroidSessionInfo sessionInfo = - AndroidSessionInfoCompat.create( - processHandler, - descriptor, - runConfiguration, - env.getExecutor().getId(), - env.getExecutor().getActionName(), - env.getExecutionTarget()); - processHandler.putUserData(AndroidSessionInfo.KEY, sessionInfo); - } - return descriptor; - } - - @Override - public String getRunnerId() { - return "AndroidTestProgramRunner"; - } -} diff --git a/aswb/sdkcompat/as222/com/google/idea/blaze/android/run/test/BlazeAndroidTestRunConfigurationHandler.java b/aswb/sdkcompat/as222/com/google/idea/blaze/android/run/test/BlazeAndroidTestRunConfigurationHandler.java deleted file mode 100644 index 050ddc03fee..00000000000 --- a/aswb/sdkcompat/as222/com/google/idea/blaze/android/run/test/BlazeAndroidTestRunConfigurationHandler.java +++ /dev/null @@ -1,224 +0,0 @@ -/* - * Copyright 2016 The Bazel Authors. All rights reserved. - * - * 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. - */ -package com.google.idea.blaze.android.run.test; - -import static com.android.tools.idea.run.deployment.DeviceAndSnapshotComboBoxAction.DEPLOYS_TO_LOCAL_DEVICE; - -import com.android.tools.idea.run.ValidationError; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.Lists; -import com.google.idea.blaze.android.run.ApkBuildStepProvider; -import com.google.idea.blaze.android.run.BlazeAndroidRunConfigurationCommonState; -import com.google.idea.blaze.android.run.BlazeAndroidRunConfigurationHandler; -import com.google.idea.blaze.android.run.BlazeAndroidRunConfigurationValidationUtil; -import com.google.idea.blaze.android.run.LaunchMetrics; -import com.google.idea.blaze.android.run.runner.ApkBuildStep; -import com.google.idea.blaze.android.run.runner.BlazeAndroidRunConfigurationRunner; -import com.google.idea.blaze.android.run.runner.BlazeAndroidRunContext; -import com.google.idea.blaze.android.run.runner.FullApkBuildStep; -import com.google.idea.blaze.android.run.test.BlazeAndroidTestLaunchMethodsProvider.AndroidTestLaunchMethod; -import com.google.idea.blaze.base.command.BlazeCommandName; -import com.google.idea.blaze.base.command.BlazeInvocationContext; -import com.google.idea.blaze.base.model.primitives.Label; -import com.google.idea.blaze.base.model.primitives.TargetExpression; -import com.google.idea.blaze.base.projectview.ProjectViewManager; -import com.google.idea.blaze.base.projectview.ProjectViewSet; -import com.google.idea.blaze.base.run.BlazeCommandRunConfiguration; -import com.google.idea.blaze.base.run.BlazeConfigurationNameBuilder; -import com.google.idea.blaze.base.run.ExecutorType; -import com.google.idea.blaze.base.run.confighandler.BlazeCommandRunConfigurationRunner; -import com.google.idea.blaze.base.settings.Blaze; -import com.google.idea.blaze.base.sync.data.BlazeDataStorage; -import com.google.idea.blaze.base.sync.projectstructure.ModuleFinder; -import com.google.idea.blaze.java.AndroidBlazeRules; -import com.intellij.execution.ExecutionException; -import com.intellij.execution.Executor; -import com.intellij.execution.JavaExecutionUtil; -import com.intellij.execution.configurations.RuntimeConfigurationException; -import com.intellij.execution.runners.ExecutionEnvironment; -import com.intellij.openapi.module.Module; -import com.intellij.openapi.project.Project; -import java.util.List; -import javax.annotation.Nullable; -import org.jetbrains.android.facet.AndroidFacet; - -/** - * {@link com.google.idea.blaze.base.run.confighandler.BlazeCommandRunConfigurationHandler} for - * android_test targets. - */ -public class BlazeAndroidTestRunConfigurationHandler - implements BlazeAndroidRunConfigurationHandler { - private final Project project; - private final BlazeAndroidTestRunConfigurationState configState; - - BlazeAndroidTestRunConfigurationHandler(BlazeCommandRunConfiguration configuration) { - this.project = configuration.getProject(); - this.configState = - new BlazeAndroidTestRunConfigurationState( - Blaze.buildSystemName(configuration.getProject())); - configuration.putUserData(DEPLOYS_TO_LOCAL_DEVICE, true); - } - - @Override - public BlazeAndroidTestRunConfigurationState getState() { - return configState; - } - - @Override - public BlazeAndroidRunConfigurationCommonState getCommonState() { - return configState.getCommonState(); - } - - @Override - public BlazeCommandRunConfigurationRunner createRunner( - Executor executor, ExecutionEnvironment env) throws ExecutionException { - Project project = env.getProject(); - BlazeCommandRunConfiguration configuration = - BlazeAndroidRunConfigurationHandler.getCommandConfig(env); - - BlazeAndroidRunConfigurationValidationUtil.validate(project); - Module module = - ModuleFinder.getInstance(env.getProject()) - .findModuleByName(BlazeDataStorage.WORKSPACE_MODULE_NAME); - AndroidFacet facet = module != null ? AndroidFacet.getInstance(module) : null; - ProjectViewSet projectViewSet = ProjectViewManager.getInstance(project).getProjectViewSet(); - - ImmutableList blazeFlags = - configState - .getCommonState() - .getExpandedBuildFlags( - project, - projectViewSet, - BlazeCommandName.TEST, - BlazeInvocationContext.runConfigContext( - ExecutorType.fromExecutor(env.getExecutor()), configuration.getType(), false)); - ImmutableList exeFlags = - ImmutableList.copyOf( - configState.getCommonState().getExeFlagsState().getFlagsForExternalProcesses()); - - // We collect metrics from a few different locations. In order to tie them all - // together, we create a unique launch id. - String launchId = LaunchMetrics.newLaunchId(); - Label label = Label.create(configuration.getSingleTarget().toString()); - - ApkBuildStep buildStep = - getTestBuildStep( - project, configState, configuration, blazeFlags, exeFlags, launchId, label); - - BlazeAndroidRunContext runContext = - new BlazeAndroidTestRunContext( - project, facet, configuration, env, configState, label, blazeFlags, buildStep); - - LaunchMetrics.logTestLaunch( - launchId, configState.getLaunchMethod().name(), env.getExecutor().getId()); - - return new BlazeAndroidRunConfigurationRunner(module, runContext, configuration); - } - - private static ApkBuildStep getTestBuildStep( - Project project, - BlazeAndroidTestRunConfigurationState configState, - BlazeCommandRunConfiguration configuration, - ImmutableList blazeFlags, - ImmutableList exeFlags, - String launchId, - Label label) - throws ExecutionException { - if (configuration.getTargetKind() - == AndroidBlazeRules.RuleTypes.ANDROID_INSTRUMENTATION_TEST.getKind()) { - boolean useMobileInstall = - AndroidTestLaunchMethod.MOBILE_INSTALL.equals(configState.getLaunchMethod()); - return ApkBuildStepProvider.getInstance(Blaze.getBuildSystemName(project)) - .getAitBuildStep( - project, - useMobileInstall, - /* nativeDebuggingEnabled= */ false, - label, - blazeFlags, - exeFlags, - launchId); - } else { - // TODO(b/248317444): This path is only invoked for the deprecated {@code android_test} - // targets, and should eventually be removed. - return new FullApkBuildStep(project, label, blazeFlags, /* nativeDebuggingEnabled= */ false); - } - } - - @Override - public final void checkConfiguration() throws RuntimeConfigurationException { - BlazeAndroidRunConfigurationValidationUtil.throwTopConfigurationError(validate()); - } - - /** - * We collect errors rather than throwing to avoid missing fatal errors by exiting early for a - * warning. We use a separate method for the collection so the compiler prevents us from - * accidentally throwing. - */ - private List validate() { - List errors = Lists.newArrayList(); - errors.addAll(BlazeAndroidRunConfigurationValidationUtil.validateWorkspaceModule(project)); - errors.addAll(configState.validate(project)); - return errors; - } - - @Override - @Nullable - public String suggestedName(BlazeCommandRunConfiguration configuration) { - TargetExpression target = configuration.getSingleTarget(); - if (target == null) { - return null; - } - BlazeConfigurationNameBuilder nameBuilder = new BlazeConfigurationNameBuilder(configuration); - - boolean isClassTest = - configState.getTestingType() == BlazeAndroidTestRunConfigurationState.TEST_CLASS; - boolean isMethodTest = - configState.getTestingType() == BlazeAndroidTestRunConfigurationState.TEST_METHOD; - if ((isClassTest || isMethodTest) && configState.getClassName() != null) { - // Get the class name without the package. - String className = JavaExecutionUtil.getPresentableClassName(configState.getClassName()); - if (className != null) { - String targetString = className; - if (isMethodTest) { - targetString += "#" + configState.getMethodName(); - } - - if (getState().getLaunchMethod().equals(AndroidTestLaunchMethod.NON_BLAZE)) { - return targetString; - } else { - return nameBuilder.setTargetString(targetString).build(); - } - } - } - return nameBuilder.build(); - } - - @Override - @Nullable - public BlazeCommandName getCommandName() { - if (getState().getLaunchMethod().equals(AndroidTestLaunchMethod.BLAZE_TEST)) { - return BlazeCommandName.TEST; - } else if (getState().getLaunchMethod().equals(AndroidTestLaunchMethod.MOBILE_INSTALL)) { - return BlazeCommandName.MOBILE_INSTALL; - } - return null; - } - - @Override - public String getHandlerName() { - return "Android Test Handler"; - } -} diff --git a/aswb/sdkcompat/as222/com/google/idea/blaze/android/run/test/BlazeAndroidTestRunContext.java b/aswb/sdkcompat/as222/com/google/idea/blaze/android/run/test/BlazeAndroidTestRunContext.java deleted file mode 100644 index 9701159d71a..00000000000 --- a/aswb/sdkcompat/as222/com/google/idea/blaze/android/run/test/BlazeAndroidTestRunContext.java +++ /dev/null @@ -1,238 +0,0 @@ -/* - * Copyright 2016 The Bazel Authors. All rights reserved. - * - * 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. - */ -package com.google.idea.blaze.android.run.test; - -import static com.android.tools.idea.run.tasks.DefaultConnectDebuggerTaskKt.getBaseDebuggerTask; -import static com.google.idea.blaze.android.run.binary.BlazeAndroidBinaryNormalBuildRunContextBase.getApkInfoToInstall; - -import com.android.ddmlib.IDevice; -import com.android.tools.idea.execution.common.debug.AndroidDebugger; -import com.android.tools.idea.execution.common.debug.AndroidDebuggerState; -import com.android.tools.idea.run.ApkProvider; -import com.android.tools.idea.run.ApkProvisionException; -import com.android.tools.idea.run.ApplicationIdProvider; -import com.android.tools.idea.run.ConsolePrinter; -import com.android.tools.idea.run.ConsoleProvider; -import com.android.tools.idea.run.LaunchOptions; -import com.android.tools.idea.run.editor.ProfilerState; -import com.android.tools.idea.run.tasks.ConnectDebuggerTask; -import com.android.tools.idea.run.tasks.LaunchTask; -import com.android.tools.idea.run.tasks.LaunchTasksProvider; -import com.android.tools.idea.run.util.LaunchStatus; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.Lists; -import com.google.idea.blaze.android.run.BlazeAndroidDeploymentService; -import com.google.idea.blaze.android.run.deployinfo.BlazeAndroidDeployInfo; -import com.google.idea.blaze.android.run.deployinfo.BlazeApkProviderService; -import com.google.idea.blaze.android.run.runner.ApkBuildStep; -import com.google.idea.blaze.android.run.runner.BlazeAndroidDeviceSelector; -import com.google.idea.blaze.android.run.runner.BlazeAndroidLaunchTasksProvider; -import com.google.idea.blaze.android.run.runner.BlazeAndroidRunContext; -import com.google.idea.blaze.android.run.test.BlazeAndroidTestLaunchMethodsProvider.AndroidTestLaunchMethod; -import com.google.idea.blaze.base.model.primitives.Label; -import com.google.idea.blaze.base.run.BlazeCommandRunConfiguration; -import com.google.idea.blaze.base.run.smrunner.BlazeTestUiSession; -import com.google.idea.blaze.base.run.testlogs.BlazeTestResultHolder; -import com.intellij.execution.ExecutionException; -import com.intellij.execution.Executor; -import com.intellij.execution.runners.ExecutionEnvironment; -import com.intellij.openapi.project.Project; -import java.util.List; -import javax.annotation.Nullable; -import org.jetbrains.android.facet.AndroidFacet; - -/** Run context for android_test. */ -public class BlazeAndroidTestRunContext implements BlazeAndroidRunContext { - protected final Project project; - protected final AndroidFacet facet; - protected final BlazeCommandRunConfiguration runConfiguration; - protected final ExecutionEnvironment env; - protected final BlazeAndroidTestRunConfigurationState configState; - protected final Label label; - protected final ImmutableList blazeFlags; - protected final List launchTaskCompleteListeners = Lists.newArrayList(); - protected final ConsoleProvider consoleProvider; - protected final ApkBuildStep buildStep; - protected final ApplicationIdProvider applicationIdProvider; - protected final ApkProvider apkProvider; - private final BlazeTestResultHolder testResultsHolder = new BlazeTestResultHolder(); - - public BlazeAndroidTestRunContext( - Project project, - AndroidFacet facet, - BlazeCommandRunConfiguration runConfiguration, - ExecutionEnvironment env, - BlazeAndroidTestRunConfigurationState configState, - Label label, - ImmutableList blazeFlags, - ApkBuildStep buildStep) { - this.project = project; - this.facet = facet; - this.runConfiguration = runConfiguration; - this.env = env; - this.label = label; - this.configState = configState; - this.buildStep = buildStep; - this.blazeFlags = blazeFlags; - - switch (configState.getLaunchMethod()) { - case MOBILE_INSTALL: - case NON_BLAZE: - consoleProvider = new AitIdeTestConsoleProvider(runConfiguration, configState); - break; - case BLAZE_TEST: - BlazeTestUiSession session = - BlazeTestUiSession.create(ImmutableList.of(), testResultsHolder); - this.consoleProvider = new AitBlazeTestConsoleProvider(project, runConfiguration, session); - break; - default: - throw new IllegalStateException( - "Unsupported launch method " + configState.getLaunchMethod()); - } - - applicationIdProvider = new BlazeAndroidTestApplicationIdProvider(buildStep); - apkProvider = BlazeApkProviderService.getInstance().getApkProvider(project, buildStep); - } - - @Override - public BlazeAndroidDeviceSelector getDeviceSelector() { - return new BlazeAndroidDeviceSelector.NormalDeviceSelector(); - } - - @Override - public void augmentLaunchOptions(LaunchOptions.Builder options) { - options.setDeploy(!configState.getLaunchMethod().equals(AndroidTestLaunchMethod.BLAZE_TEST)); - } - - @Override - public ConsoleProvider getConsoleProvider() { - return consoleProvider; - } - - @Override - public ApplicationIdProvider getApplicationIdProvider() throws ExecutionException { - return applicationIdProvider; - } - - @Nullable - @Override - public ApkBuildStep getBuildStep() { - return buildStep; - } - - @Override - public ProfilerState getProfileState() { - return null; - } - - @Override - public LaunchTasksProvider getLaunchTasksProvider(LaunchOptions.Builder launchOptionsBuilder) { - return new BlazeAndroidLaunchTasksProvider( - project, this, applicationIdProvider, launchOptionsBuilder); - } - - @Override - public ImmutableList getDeployTasks(IDevice device, LaunchOptions launchOptions) - throws ExecutionException { - if (configState.getLaunchMethod() != AndroidTestLaunchMethod.NON_BLAZE) { - return ImmutableList.of(); - } - - return ImmutableList.of( - BlazeAndroidDeploymentService.getInstance(project) - .getDeployTask(getApkInfoToInstall(device, launchOptions, apkProvider), launchOptions)); - } - - @Override - @Nullable - public LaunchTask getApplicationLaunchTask( - LaunchOptions launchOptions, - @Nullable Integer userId, - String contributorsAmStartOptions, - LaunchStatus launchStatus) - throws ExecutionException { - switch (configState.getLaunchMethod()) { - case BLAZE_TEST: - BlazeAndroidTestFilter testFilter = - new BlazeAndroidTestFilter( - configState.getTestingType(), - configState.getClassName(), - configState.getMethodName(), - configState.getPackageName()); - return new BlazeAndroidTestLaunchTask( - project, - label, - blazeFlags, - testFilter, - this, - launchOptions.isDebug(), - testResultsHolder); - case NON_BLAZE: - case MOBILE_INSTALL: - BlazeAndroidDeployInfo deployInfo; - try { - deployInfo = buildStep.getDeployInfo(); - } catch (ApkProvisionException e) { - throw new ExecutionException(e); - } - return StockAndroidTestLaunchTask.getStockTestLaunchTask( - configState, applicationIdProvider, launchOptions.isDebug(), deployInfo, launchStatus); - } - throw new AssertionError(); - } - - @Override - @SuppressWarnings({"unchecked", "rawtypes"}) // Raw type from upstream. - public ConnectDebuggerTask getDebuggerTask( - AndroidDebugger androidDebugger, AndroidDebuggerState androidDebuggerState) - throws ExecutionException { - switch (configState.getLaunchMethod()) { - case BLAZE_TEST: - return new ConnectBlazeTestDebuggerTask(this, androidDebugger, androidDebuggerState); - case NON_BLAZE: - case MOBILE_INSTALL: - return getBaseDebuggerTask( - androidDebugger, androidDebuggerState, env, facet, applicationIdProvider); - } - throw new AssertionError(); - } - - void onLaunchTaskComplete() { - for (Runnable runnable : launchTaskCompleteListeners) { - runnable.run(); - } - } - - void addLaunchTaskCompleteListener(Runnable runnable) { - launchTaskCompleteListeners.add(runnable); - } - - @Override - public Executor getExecutor() { - return env.getExecutor(); - } - - @Nullable - @Override - public Integer getUserId(IDevice device, ConsolePrinter consolePrinter) { - return null; - } - - @Override - public String getAmStartOptions() { - return ""; - } -} diff --git a/aswb/sdkcompat/as222/com/google/idea/blaze/android/run/test/ConnectBlazeTestDebuggerTask.java b/aswb/sdkcompat/as222/com/google/idea/blaze/android/run/test/ConnectBlazeTestDebuggerTask.java deleted file mode 100644 index 06a644fb496..00000000000 --- a/aswb/sdkcompat/as222/com/google/idea/blaze/android/run/test/ConnectBlazeTestDebuggerTask.java +++ /dev/null @@ -1,134 +0,0 @@ -/* - * Copyright 2016 The Bazel Authors. All rights reserved. - * - * 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. - */ -package com.google.idea.blaze.android.run.test; - -import com.android.ddmlib.IDevice; -import com.android.tools.idea.execution.common.debug.AndroidDebugger; -import com.android.tools.idea.execution.common.debug.AndroidDebuggerState; -import com.android.tools.idea.execution.common.debug.DebugSessionStarter; -import com.android.tools.idea.run.tasks.ConnectDebuggerTask; -import com.intellij.execution.ExecutionException; -import com.intellij.execution.process.ProcessHandler; -import com.intellij.execution.process.ProcessOutputTypes; -import com.intellij.execution.runners.ExecutionEnvironment; -import com.intellij.execution.runners.ExecutionUtil; -import com.intellij.openapi.diagnostic.Logger; -import com.intellij.openapi.wm.ToolWindowId; -import com.intellij.xdebugger.impl.XDebugSessionImpl; -import java.io.OutputStream; -import java.util.function.Function; -import kotlin.Unit; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import org.jetbrains.concurrency.Promise; - -/** Connects the blaze debugger during execution. */ -class ConnectBlazeTestDebuggerTask implements ConnectDebuggerTask { - private static final Logger LOG = Logger.getInstance(ConnectBlazeTestDebuggerTask.class); - - private final BlazeAndroidTestRunContext runContext; - private final AndroidDebugger myAndroidDebugger; - private final S myAndroidDebuggerState; - - public ConnectBlazeTestDebuggerTask( - BlazeAndroidTestRunContext runContext, - AndroidDebugger androidDebugger, - S androidDebuggerState) { - this.runContext = runContext; - myAndroidDebugger = androidDebugger; - myAndroidDebuggerState = androidDebuggerState; - } - - /** - * Wires up listeners to automatically reconnect the debugger for each test method. When you - * `blaze test` an android_test in debug mode, it kills the instrumentation process between each - * test method, disconnecting the debugger. We listen for the start of a new method waiting for a - * debugger, and reconnect. TODO: Support stopping Blaze from the UI. This is hard because we have - * no way to distinguish process handler termination/debug session ending initiated by the user. - * - * @return Promise with debug session or error - */ - @Override - public @NotNull Promise perform( - @NotNull IDevice device, - @NotNull String applicationId, - @NotNull ExecutionEnvironment environment, - @NotNull ProcessHandler oldProcessHandler) { - final ProcessHandler masterProcessHandler = - new ProcessHandler() { - - @Override - protected void destroyProcessImpl() { - notifyProcessTerminated(0); - } - - @Override - protected void detachProcessImpl() { - notifyProcessDetached(); - } - - @Override - public boolean detachIsDefault() { - return false; - } - - @Override - public @Nullable OutputStream getProcessInput() { - return null; - } - }; - Promise debugSessionPromise = - DebugSessionStarter.INSTANCE - .attachReattachingDebuggerToStartedProcess( - device, - applicationId, - masterProcessHandler, - environment, - myAndroidDebugger, - myAndroidDebuggerState, - /* destroyRunningProcess= */ x -> Unit.INSTANCE, - null, - Long.MAX_VALUE) - .onSuccess( - session -> { - oldProcessHandler.detachProcess(); - session.showSessionTab(); - }) - .onError( - it -> { - if (it instanceof ExecutionException) { - ExecutionUtil.handleExecutionError( - environment.getProject(), - ToolWindowId.DEBUG, - it, - "Error running " + environment.getRunProfile().getName(), - it.getMessage(), - Function.identity(), - null); - } else { - Logger.getInstance(this.getClass()).error(it); - } - }); - - runContext.addLaunchTaskCompleteListener( - () -> { - masterProcessHandler.notifyTextAvailable( - "Test run completed.\n", ProcessOutputTypes.STDOUT); - masterProcessHandler.detachProcess(); - }); - return debugSessionPromise; - } -} diff --git a/aswb/sdkcompat/as222/com/google/idea/blaze/android/run/test/StockAndroidTestLaunchTask.java b/aswb/sdkcompat/as222/com/google/idea/blaze/android/run/test/StockAndroidTestLaunchTask.java deleted file mode 100644 index d557d37b010..00000000000 --- a/aswb/sdkcompat/as222/com/google/idea/blaze/android/run/test/StockAndroidTestLaunchTask.java +++ /dev/null @@ -1,226 +0,0 @@ -/* - * Copyright 2016 The Bazel Authors. All rights reserved. - * - * 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. - */ -package com.google.idea.blaze.android.run.test; - -import com.android.ddmlib.testrunner.RemoteAndroidTestRunner; -import com.android.tools.idea.execution.common.processhandler.AndroidProcessHandler; -import com.android.tools.idea.run.ApkProvisionException; -import com.android.tools.idea.run.ApplicationIdProvider; -import com.android.tools.idea.run.ConsolePrinter; -import com.android.tools.idea.run.tasks.LaunchContext; -import com.android.tools.idea.run.tasks.LaunchResult; -import com.android.tools.idea.run.tasks.LaunchTask; -import com.android.tools.idea.run.util.LaunchStatus; -import com.android.tools.idea.testartifacts.instrumented.AndroidTestListener; -import com.google.common.collect.ImmutableList; -import com.google.idea.blaze.android.manifest.ManifestParser; -import com.google.idea.blaze.android.run.deployinfo.BlazeAndroidDeployInfo; -import com.intellij.execution.process.ProcessHandler; -import com.intellij.openapi.application.ApplicationManager; -import com.intellij.openapi.diagnostic.Logger; -import com.intellij.openapi.util.Computable; -import com.intellij.openapi.util.text.StringUtil; -import java.util.List; -import javax.annotation.Nullable; -import org.jetbrains.annotations.NotNull; - -class StockAndroidTestLaunchTask implements LaunchTask { - private static final String ID = "STOCK_ANDROID_TEST"; - - private static final Logger LOG = Logger.getInstance(StockAndroidTestLaunchTask.class); - - private final BlazeAndroidTestRunConfigurationState configState; - private final String instrumentationTestRunner; - private final String testApplicationId; - private final boolean waitForDebugger; - - StockAndroidTestLaunchTask( - BlazeAndroidTestRunConfigurationState configState, - String runner, - String testPackage, - boolean waitForDebugger) { - this.configState = configState; - this.instrumentationTestRunner = runner; - this.waitForDebugger = waitForDebugger; - this.testApplicationId = testPackage; - } - - @Nullable - public static LaunchTask getStockTestLaunchTask( - BlazeAndroidTestRunConfigurationState configState, - ApplicationIdProvider applicationIdProvider, - boolean waitForDebugger, - BlazeAndroidDeployInfo deployInfo, - LaunchStatus launchStatus) { - String testPackage; - try { - testPackage = applicationIdProvider.getTestPackageName(); - if (testPackage == null) { - launchStatus.terminateLaunch("Unable to determine test package name", true); - return null; - } - } catch (ApkProvisionException e) { - launchStatus.terminateLaunch("Unable to determine test package name", true); - return null; - } - - List availableRunners = getRunnersFromManifest(deployInfo); - if (availableRunners.isEmpty()) { - launchStatus.terminateLaunch( - String.format( - "No instrumentation test runner is defined in the manifest.\n" - + "At least one instrumentation tag must be defined for the\n" - + "\"%1$s\" package in the AndroidManifest.xml, e.g.:\n" - + "\n" - + "\n" - + "\n" - + " \n" - + " \n" - + "\n" - + "", - testPackage), - true); - // Note: Gradle users will never see the above message, so don't mention Gradle here. - // Even if no runners are defined in build.gradle, Gradle will add a default to the manifest. - return null; - } - String runner = configState.getInstrumentationRunnerClass(); - if (!StringUtil.isEmpty(runner)) { - if (!availableRunners.contains(runner)) { - launchStatus.terminateLaunch( - String.format( - "Instrumentation test runner \"%2$s\"\n" - + "is not defined for the \"%1$s\" package in the manifest.\n" - + "Clear the 'Specific instrumentation runner' field in your configuration\n" - + "to default to \"%3$s\",\n" - + "or add the runner to your AndroidManifest.xml:\n" - + "\n" - + "\n" - + "\n" - + " \n" - + " \n" - + "\n" - + "", - testPackage, runner, availableRunners.get(0)), - true); - return null; - } - } else { - // Default to the first available runner. - runner = availableRunners.get(0); - } - - return new StockAndroidTestLaunchTask(configState, runner, testPackage, waitForDebugger); - } - - private static ImmutableList getRunnersFromManifest( - final BlazeAndroidDeployInfo deployInfo) { - if (!ApplicationManager.getApplication().isReadAccessAllowed()) { - return ApplicationManager.getApplication() - .runReadAction( - (Computable>) () -> getRunnersFromManifest(deployInfo)); - } - - ManifestParser.ParsedManifest parsedManifest = deployInfo.getMergedManifest(); - if (parsedManifest != null) { - return ImmutableList.copyOf(parsedManifest.instrumentationClassNames); - } - return ImmutableList.of(); - } - - @Override - public String getDescription() { - return "Launching instrumentation runner"; - } - - @Override - public int getDuration() { - return 2; - } - - @Override - public LaunchResult run(@NotNull LaunchContext launchContext) { - ConsolePrinter printer = launchContext.getConsolePrinter(); - printer.stdout("Running tests\n"); - - final RemoteAndroidTestRunner runner = - new RemoteAndroidTestRunner( - testApplicationId, instrumentationTestRunner, launchContext.getDevice()); - switch (configState.getTestingType()) { - case BlazeAndroidTestRunConfigurationState.TEST_ALL_IN_MODULE: - break; - case BlazeAndroidTestRunConfigurationState.TEST_ALL_IN_PACKAGE: - runner.setTestPackageName(configState.getPackageName()); - break; - case BlazeAndroidTestRunConfigurationState.TEST_CLASS: - runner.setClassName(configState.getClassName()); - break; - case BlazeAndroidTestRunConfigurationState.TEST_METHOD: - runner.setMethodName(configState.getClassName(), configState.getMethodName()); - break; - default: - LOG.error(String.format("Unrecognized testing type: %d", configState.getTestingType())); - return LaunchResult.error("", getDescription()); - } - runner.setDebug(waitForDebugger); - runner.setRunOptions(configState.getExtraOptions()); - - printer.stdout("$ adb shell " + runner.getAmInstrumentCommand()); - - // run in a separate thread as this will block until the tests complete - ApplicationManager.getApplication() - .executeOnPooledThread( - () -> { - try { - // This issues "am instrument" command and blocks execution. - runner.run(new AndroidTestListener(printer)); - - // Detach the device from the android process handler manually as soon as "am - // instrument" command finishes. This is required because the android process - // handler may overlook target process especially when the test - // runs really fast (~10ms). Because the android process handler discovers new - // processes by polling, this race condition happens easily. By detaching the device - // manually, we can avoid the android process handler waiting for (already finished) - // process to show up until it times out (10 secs). - // Note: this is a copy of ag/9593981, but it is worth figuring out a better - // strategy here if the behavior of AndroidTestListener is not guaranteed. - ProcessHandler processHandler = launchContext.getProcessHandler(); - if (processHandler instanceof AndroidProcessHandler) { - ((AndroidProcessHandler) processHandler).detachDevice(launchContext.getDevice()); - } - } catch (Exception e) { - LOG.info(e); - printer.stderr("Error: Unexpected exception while running tests: " + e); - } - }); - - return LaunchResult.success(); - } - - @NotNull - @Override - public String getId() { - return ID; - } -} diff --git a/aswb/sdkcompat/as222/com/google/idea/blaze/android/sync/model/idea/BlazeAndroidModel.java b/aswb/sdkcompat/as222/com/google/idea/blaze/android/sync/model/idea/BlazeAndroidModel.java deleted file mode 100644 index 00a9e4a94c9..00000000000 --- a/aswb/sdkcompat/as222/com/google/idea/blaze/android/sync/model/idea/BlazeAndroidModel.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright 2020 The Bazel Authors. All rights reserved. - * - * 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. - */ -package com.google.idea.blaze.android.sync.model.idea; - -import com.android.tools.idea.model.AndroidModel; -import com.android.tools.idea.model.Namespacing; -import com.android.tools.idea.projectsystem.NamedIdeaSourceProvider; -import com.google.common.util.concurrent.ListenableFuture; -import com.intellij.openapi.project.Project; -import java.io.File; - -/** Blaze model for an android project. #api42. */ -public class BlazeAndroidModel extends BlazeAndroidModelBase { - private final NamedIdeaSourceProvider sourceProvider; - - public BlazeAndroidModel( - Project project, - File rootDirPath, - NamedIdeaSourceProvider sourceProvider, - ListenableFuture applicationId, - int minSdkVersion, - boolean desugarJava8Libs) { - super(project, rootDirPath, applicationId, minSdkVersion, desugarJava8Libs); - this.sourceProvider = sourceProvider; - } - - public NamedIdeaSourceProvider getDefaultSourceProvider() { - return sourceProvider; - } - - @Override - public Namespacing getNamespacing() { - return Namespacing.DISABLED; - } - - @Override - protected String uninitializedApplicationId() { - return AndroidModel.UNINITIALIZED_APPLICATION_ID; - } -} diff --git a/aswb/sdkcompat/as222/org/jetbrains/android/facet/AndroidFacetPropertiesCompat.java b/aswb/sdkcompat/as222/org/jetbrains/android/facet/AndroidFacetPropertiesCompat.java deleted file mode 100644 index fff25619e8a..00000000000 --- a/aswb/sdkcompat/as222/org/jetbrains/android/facet/AndroidFacetPropertiesCompat.java +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright 2022 The Bazel Authors. All rights reserved. - * - * 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. - */ -package org.jetbrains.android.facet; - -/** Compat class for AndroidFacetProperties. */ -public class AndroidFacetPropertiesCompat { - - private AndroidFacetPropertiesCompat() {} - - public static void enableSourcesAutogeneration(AndroidFacetProperties props, boolean enable) {} -} diff --git a/aswb/sdkcompat/as222/org/jetbrains/android/sdk/AndroidPlatformCompat.java b/aswb/sdkcompat/as222/org/jetbrains/android/sdk/AndroidPlatformCompat.java deleted file mode 100644 index 77fdbc6bcf1..00000000000 --- a/aswb/sdkcompat/as222/org/jetbrains/android/sdk/AndroidPlatformCompat.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright 2023 The Bazel Authors. All rights reserved. - * - * 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. - */ -package org.jetbrains.android.sdk; - -import com.android.sdklib.BuildToolInfo; -import com.intellij.openapi.projectRoots.Sdk; - -/** Compat class for {@link AndroidPlatform} */ -public class AndroidPlatformCompat { - AndroidPlatform androidPlatform; - - public AndroidPlatformCompat(AndroidPlatform androidPlatform) { - this.androidPlatform = androidPlatform; - } - - public BuildToolInfo getLatestBuildTool(boolean allowBuildTool) { - return androidPlatform.getSdkData().getLatestBuildTool(allowBuildTool); - } - - public int getApiLevel() { - return androidPlatform.getApiLevel(); - } - - public static int getApiLevel(Sdk sdk) { - int androidSdkApiLevel = 1; - AndroidSdkAdditionalData additionalData = (AndroidSdkAdditionalData) sdk.getSdkAdditionalData(); - if (additionalData != null) { - AndroidPlatform androidPlatform = additionalData.getAndroidPlatform(); - if (androidPlatform != null) { - androidSdkApiLevel = androidPlatform.getApiLevel(); - } - } - return androidSdkApiLevel; - } -} diff --git a/aswb/sdkcompat/as222/org/jetbrains/android/sdk/AndroidPlatformsCompat.java b/aswb/sdkcompat/as222/org/jetbrains/android/sdk/AndroidPlatformsCompat.java deleted file mode 100644 index 3548e0aeb71..00000000000 --- a/aswb/sdkcompat/as222/org/jetbrains/android/sdk/AndroidPlatformsCompat.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright 2023 The Bazel Authors. All rights reserved. - * - * 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. - */ -package org.jetbrains.android.sdk; - -import com.intellij.openapi.module.Module; -import com.intellij.openapi.projectRoots.Sdk; - -/** Compat shim class for {@link AndroidPlatforms} */ -public class AndroidPlatformsCompat { - private AndroidPlatformsCompat() {} - - public static AndroidPlatformCompat getInstance(Sdk sdk) { - return new AndroidPlatformCompat(AndroidPlatform.getInstance(sdk)); - } - - public static AndroidPlatformCompat getInstance(Module module) { - return new AndroidPlatformCompat(AndroidPlatform.getInstance(module)); - } -} diff --git a/aswb/sdkcompat/as222/org/jetbrains/android/sdk/AndroidSdkAdditionalDataCompat.java b/aswb/sdkcompat/as222/org/jetbrains/android/sdk/AndroidSdkAdditionalDataCompat.java deleted file mode 100644 index d9033a9b7b8..00000000000 --- a/aswb/sdkcompat/as222/org/jetbrains/android/sdk/AndroidSdkAdditionalDataCompat.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright 2023 The Bazel Authors. All rights reserved. - * - * 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. - */ -package org.jetbrains.android.sdk; - -import com.android.tools.idea.sdk.AndroidSdks; -import com.intellij.openapi.projectRoots.Sdk; - -/** Compat shim class for {@link AndroidSdkAdditionalData} */ -public class AndroidSdkAdditionalDataCompat { - private AndroidSdkAdditionalDataCompat() {} - - public static AndroidSdkAdditionalData from(Sdk sdk) { - return AndroidSdks.getInstance().getAndroidSdkAdditionalData(sdk); - } -} diff --git a/aswb/sdkcompat/as222/org/jetbrains/android/sdk/AndroidSdkDataCompat.java b/aswb/sdkcompat/as222/org/jetbrains/android/sdk/AndroidSdkDataCompat.java deleted file mode 100644 index 990b4b409fe..00000000000 --- a/aswb/sdkcompat/as222/org/jetbrains/android/sdk/AndroidSdkDataCompat.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright 2023 The Bazel Authors. All rights reserved. - * - * 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. - */ -package org.jetbrains.android.sdk; - -import com.android.sdklib.IAndroidTarget; -import com.google.errorprone.annotations.CanIgnoreReturnValue; -import java.io.File; - -/** Compat class for {@link AndroidSdkData} */ -public class AndroidSdkDataCompat { - AndroidSdkData androidSdkData; - - private AndroidSdkDataCompat(File sdkLocation, boolean forceReparse) { - androidSdkData = AndroidSdkData.getSdkData(sdkLocation, forceReparse); - } - - public static AndroidSdkDataCompat getSdkData(String sdkHomepath) { - return new AndroidSdkDataCompat(new File(sdkHomepath), false); - } - - @CanIgnoreReturnValue - public static AndroidSdkDataCompat getSdkData(File sdkLocation, boolean forceReparse) { - return new AndroidSdkDataCompat(sdkLocation, forceReparse); - } - - public IAndroidTarget[] getTargets() { - return androidSdkData.getTargets(); - } -} diff --git a/aswb/sdkcompat/as223/com/android/tools/idea/model/AndroidManifestIndexCompat.java b/aswb/sdkcompat/as223/com/android/tools/idea/model/AndroidManifestIndexCompat.java deleted file mode 100644 index 82eb27bee0c..00000000000 --- a/aswb/sdkcompat/as223/com/android/tools/idea/model/AndroidManifestIndexCompat.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright 2022 The Bazel Authors. All rights reserved. - * - * 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. - */ -package com.android.tools.idea.model; - -/** Compat class for {@link com.android.tools.idea.model.AndroidManifestIndex}. */ -public class AndroidManifestIndexCompat { - - private AndroidManifestIndexCompat() {} - - /** {@code indexEnabled} was removed in Studio 2021.2. #api211 */ - public static boolean indexEnabled() { - return true; - } -} diff --git a/aswb/sdkcompat/as223/com/android/tools/idea/progress/StudioLoggerProgressIndicatorCompat.java b/aswb/sdkcompat/as223/com/android/tools/idea/progress/StudioLoggerProgressIndicatorCompat.java deleted file mode 100644 index 7f9654b2ccf..00000000000 --- a/aswb/sdkcompat/as223/com/android/tools/idea/progress/StudioLoggerProgressIndicatorCompat.java +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright 2022 The Bazel Authors. All rights reserved. - * - * 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. - */ -package com.android.tools.idea.progress; - -/** Compat layer for StudioLoggerProgressIndicator which moved packages in 2021.2. #api211 */ -public class StudioLoggerProgressIndicatorCompat extends StudioLoggerProgressIndicator { - public StudioLoggerProgressIndicatorCompat(Class c) { - super(c); - } -} diff --git a/aswb/sdkcompat/as223/com/android/tools/idea/run/AndroidSessionInfoCompat.java b/aswb/sdkcompat/as223/com/android/tools/idea/run/AndroidSessionInfoCompat.java deleted file mode 100644 index 783ad5d39e4..00000000000 --- a/aswb/sdkcompat/as223/com/android/tools/idea/run/AndroidSessionInfoCompat.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright 2022 The Bazel Authors. All rights reserved. - * - * 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. - */ -package com.android.tools.idea.run; - -import com.android.ddmlib.Client; -import com.android.tools.idea.execution.common.AndroidSessionInfo; -import com.intellij.debugger.engine.RemoteDebugProcessHandler; -import com.intellij.execution.ExecutionTarget; -import com.intellij.execution.configurations.RunConfiguration; -import com.intellij.execution.process.ProcessHandler; -import com.intellij.execution.ui.RunContentDescriptor; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -/** Compat class for AndroidSessionInfo */ -public class AndroidSessionInfoCompat { - - private AndroidSessionInfoCompat() {} - - public static AndroidSessionInfo create( - @NotNull ProcessHandler processHandler, - @NotNull RunContentDescriptor descriptor, - @Nullable RunConfiguration runConfiguration, - @NotNull String executorId, - @NotNull String executorActionName, - @NotNull ExecutionTarget executionTarget) { - return AndroidSessionInfo.create(processHandler, runConfiguration, executorId, executionTarget); - } - - @Nullable - public static RunContentDescriptor getDescriptor(AndroidSessionInfo session) { - return null; - } - - public static void putAndroidDebugClient(RemoteDebugProcessHandler handler, Client client) {} -} diff --git a/aswb/sdkcompat/as223/com/android/tools/idea/run/editor/DeployTargetCompat.java b/aswb/sdkcompat/as223/com/android/tools/idea/run/editor/DeployTargetCompat.java deleted file mode 100644 index faa6faec6fe..00000000000 --- a/aswb/sdkcompat/as223/com/android/tools/idea/run/editor/DeployTargetCompat.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright 2022 The Bazel Authors. All rights reserved. - * - * 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. - */ -package com.android.tools.idea.run.editor; - -import com.android.tools.idea.run.DeviceFutures; -import com.intellij.openapi.project.Project; -import org.jetbrains.android.facet.AndroidFacet; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -/** SDK Compat class for {@link DeployTarget#getDevices}. */ -public class DeployTargetCompat { - - private DeployTargetCompat() {} - - @Nullable - public static DeviceFutures getDevices( - DeployTarget target, AndroidFacet facet, @NotNull Project project) { - return target.getDevices(project); - } -} diff --git a/aswb/sdkcompat/as223/com/android/tools/idea/run/tasks/DeployTasksCompat.java b/aswb/sdkcompat/as223/com/android/tools/idea/run/tasks/DeployTasksCompat.java deleted file mode 100644 index 500a6786340..00000000000 --- a/aswb/sdkcompat/as223/com/android/tools/idea/run/tasks/DeployTasksCompat.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2020 The Bazel Authors. All rights reserved. - * - * 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. - */ -package com.android.tools.idea.run.tasks; - -import com.android.tools.idea.run.ApkInfo; -import com.android.tools.idea.run.LaunchOptions; -import com.android.tools.idea.run.blaze.BlazeLaunchTask; -import com.android.tools.idea.run.blaze.BlazeLaunchTaskWrapper; -import com.google.idea.common.experiments.BoolExperiment; -import com.intellij.openapi.project.Project; -import java.util.Collection; - -/** Compat class for {@link DeployTask} */ -public class DeployTasksCompat { - private static final BoolExperiment updateCodeViaJvmti = - new BoolExperiment("android.apply.changes", false); - - private DeployTasksCompat() {} - - public static BlazeLaunchTask createDeployTask( - Project project, Collection packages, LaunchOptions launchOptions) { - // We don't have a device information, fallback to the most conservative - // install option. - return new BlazeLaunchTaskWrapper( - new DeployTask( - project, - packages, - launchOptions.getPmInstallOptions(/* device= */ null), - launchOptions.getInstallOnAllUsers(), - launchOptions.getAlwaysInstallWithPm())); - } -} - diff --git a/aswb/sdkcompat/as223/com/android/tools/rendering/HtmlLinkManagerCompat.java b/aswb/sdkcompat/as223/com/android/tools/rendering/HtmlLinkManagerCompat.java deleted file mode 100644 index 594132f69af..00000000000 --- a/aswb/sdkcompat/as223/com/android/tools/rendering/HtmlLinkManagerCompat.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright 2023 The Bazel Authors. All rights reserved. - * - * 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. - */ -package com.android.tools.rendering; - -import com.android.tools.idea.rendering.HtmlLinkManager; -import java.io.File; -import org.jetbrains.annotations.NotNull; - -/** Compat class for {@link HtmlLinkManager} */ -public final class HtmlLinkManagerCompat { - public static String createFilePositionUrl(@NotNull File file, int line, int column) { - return HtmlLinkManager.createFilePositionUrl(file, line, column); - } - - private HtmlLinkManagerCompat() {} -} diff --git a/aswb/sdkcompat/as223/com/google/idea/blaze/android/cppimpl/debug/BlazeAutoAndroidDebugger.java b/aswb/sdkcompat/as223/com/google/idea/blaze/android/cppimpl/debug/BlazeAutoAndroidDebugger.java deleted file mode 100644 index 167fd4433a9..00000000000 --- a/aswb/sdkcompat/as223/com/google/idea/blaze/android/cppimpl/debug/BlazeAutoAndroidDebugger.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright 2016 The Bazel Authors. All rights reserved. - * - * 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. - */ -package com.google.idea.blaze.android.cppimpl.debug; - -import com.android.ddmlib.Client; -import com.android.tools.ndk.run.editor.AutoAndroidDebuggerState; -import com.intellij.execution.ExecutionException; -import com.intellij.openapi.project.Project; -import com.intellij.xdebugger.XDebugSession; - -/** Shim for #api212 compat. */ -public class BlazeAutoAndroidDebugger extends BlazeAutoAndroidDebuggerBase { - @Override - public XDebugSession attachToClient( - Project project, Client client, AutoAndroidDebuggerState state) throws ExecutionException { - if (isNativeProject(project)) { - log.info("Project has native development enabled. Attaching native debugger."); - return nativeDebugger.attachToClient(project, client, state); - } else { - return super.attachToClient(project, client, state); - } - } -} diff --git a/aswb/sdkcompat/as223/com/google/idea/blaze/android/cppimpl/debug/BlazeNativeAndroidDebugger.java b/aswb/sdkcompat/as223/com/google/idea/blaze/android/cppimpl/debug/BlazeNativeAndroidDebugger.java deleted file mode 100644 index e92afddc27c..00000000000 --- a/aswb/sdkcompat/as223/com/google/idea/blaze/android/cppimpl/debug/BlazeNativeAndroidDebugger.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright 2018 The Bazel Authors. All rights reserved. - * - * 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. - */ -package com.google.idea.blaze.android.cppimpl.debug; - -/** - * API compat of {@link BlazeNativeAndroidDebuggerBase} with the following additions: - * - *

    - *
  • Creates a run-config setting using {@link BlazeAndroidNativeAttachConfiguration} instead of - * {@link AndroidNativeAttachConfiguration} to override counterproductive validations. - *
- * - * #api4.0 - */ -public class BlazeNativeAndroidDebugger extends BlazeNativeAndroidDebuggerBase {} diff --git a/aswb/sdkcompat/as223/com/google/idea/blaze/android/cppimpl/debug/BlazeNativeAndroidDebuggerBase.java b/aswb/sdkcompat/as223/com/google/idea/blaze/android/cppimpl/debug/BlazeNativeAndroidDebuggerBase.java deleted file mode 100644 index 911d90b7711..00000000000 --- a/aswb/sdkcompat/as223/com/google/idea/blaze/android/cppimpl/debug/BlazeNativeAndroidDebuggerBase.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright 2020 The Bazel Authors. All rights reserved. - * - * 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. - */ -package com.google.idea.blaze.android.cppimpl.debug; - -import com.android.tools.ndk.run.editor.NativeAndroidDebugger; -import com.google.idea.blaze.base.model.BlazeProjectData; -import com.google.idea.blaze.base.model.primitives.LanguageClass; -import com.google.idea.blaze.base.settings.Blaze; -import com.google.idea.blaze.base.sync.data.BlazeProjectDataManager; -import com.intellij.openapi.project.Project; - -/** - * Extension of {@link NativeAndroidDebugger} with the following key differences compared to {@link - * NativeAndroidDebugger}. - * - *
    - *
  • Overrides {@link #supportsProject} so native debugger is only enabled for native support is - * enabled. - *
- */ -public class BlazeNativeAndroidDebuggerBase extends NativeAndroidDebugger { - /** - * This ID needs to be lexicographically larger than "Java" so it come after the "Java" debugger - * when sorted lexicographically in the "Attach Debugger to Android Process" dialog. See {@link - * org.jetbrains.android.actions.AndroidProcessChooserDialog#populateDebuggerTypeCombo}. - */ - public static final String ID = "Native" + Blaze.defaultBuildSystemName(); - - @Override - public String getId() { - return ID; - } - - @Override - public String getDisplayName() { - return "Native Only"; - } - - @Override - public boolean supportsProject(Project project) { - BlazeProjectData blazeProjectData = - BlazeProjectDataManager.getInstance(project).getBlazeProjectData(); - return blazeProjectData != null - && blazeProjectData.getWorkspaceLanguageSettings().isLanguageActive(LanguageClass.C); - } -} diff --git a/aswb/sdkcompat/as223/com/google/idea/blaze/android/projectsystem/BlazeProjectSystem.java b/aswb/sdkcompat/as223/com/google/idea/blaze/android/projectsystem/BlazeProjectSystem.java deleted file mode 100755 index b5b20a1b2a7..00000000000 --- a/aswb/sdkcompat/as223/com/google/idea/blaze/android/projectsystem/BlazeProjectSystem.java +++ /dev/null @@ -1,228 +0,0 @@ -/* - * Copyright 2017 The Bazel Authors. All rights reserved. - * - * 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. - */ -package com.google.idea.blaze.android.projectsystem; - -import static com.android.tools.idea.projectsystem.SourceProvidersKt.emptySourceProvider; -import static org.jetbrains.android.facet.SourceProviderUtil.createSourceProvidersForLegacyModule; - -import com.android.tools.apk.analyzer.AaptInvoker; -import com.android.tools.idea.log.LogWrapper; -import com.android.tools.idea.model.AndroidModel; -import com.android.tools.idea.model.ClassJarProvider; -import com.android.tools.idea.projectsystem.AndroidModuleSystem; -import com.android.tools.idea.projectsystem.AndroidProjectSystem; -import com.android.tools.idea.projectsystem.NamedIdeaSourceProvider; -import com.android.tools.idea.projectsystem.ProjectSystemBuildManager; -import com.android.tools.idea.projectsystem.ProjectSystemSyncManager; -import com.android.tools.idea.projectsystem.ScopeType; -import com.android.tools.idea.projectsystem.SourceProviderManager; -import com.android.tools.idea.projectsystem.SourceProviders; -import com.android.tools.idea.projectsystem.SourceProvidersFactory; -import com.android.tools.idea.projectsystem.SourceProvidersImpl; -import com.android.tools.idea.res.AndroidInnerClassFinder; -import com.android.tools.idea.res.AndroidResourceClassPsiElementFinder; -import com.android.tools.idea.sdk.AndroidSdks; -import com.google.common.collect.ImmutableList; -import com.google.idea.blaze.android.resources.BlazeLightResourceClassService; -import com.google.idea.blaze.android.sync.model.idea.BlazeAndroidModel; -import com.google.idea.blaze.android.sync.model.idea.BlazeClassJarProvider; -import com.google.idea.blaze.base.build.BlazeBuildService; -import com.google.idea.blaze.base.qsync.QuerySync; -import com.intellij.facet.ProjectFacetManager; -import com.intellij.openapi.module.Module; -import com.intellij.openapi.project.Project; -import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.psi.PsiElementFinder; -import com.intellij.psi.search.GlobalSearchScope; -import java.io.File; -import java.nio.file.Path; -import java.util.Arrays; -import java.util.Collection; -import java.util.List; -import java.util.stream.Collectors; -import javax.annotation.Nullable; -import org.jetbrains.android.facet.AndroidFacet; -import org.jetbrains.annotations.NotNull; - -/** - * Base class to implement common methods in {@link AndroidProjectSystem} for blaze with different - * sdk - */ -public class BlazeProjectSystem implements AndroidProjectSystem { - protected final Project project; - protected final ProjectSystemSyncManager syncManager; - protected final List myFinders; - private final BlazeProjectSystemBuildManager buildManager; - - public BlazeProjectSystem(Project project) { - this.project = project; - syncManager = new BlazeProjectSystemSyncManager(project); - buildManager = new BlazeProjectSystemBuildManager(project); - - myFinders = - Arrays.asList( - AndroidInnerClassFinder.INSTANCE, - new AndroidResourceClassPsiElementFinder(getLightResourceClassService())); - } - - @Override - public boolean allowsFileCreation() { - return true; - } - - @Nullable - @Override - public VirtualFile getDefaultApkFile() { - return null; - } - - @Override - public Path getPathToAapt() { - return AaptInvoker.getPathToAapt( - AndroidSdks.getInstance().tryToChooseSdkHandler(), - new LogWrapper(BlazeProjectSystem.class)); - } - - // @Override #api42 - public void buildProject() { - BlazeBuildService.getInstance(project).buildProject(); - } - - // @Override #api42 - public ProjectSystemBuildManager getBuildManager() { - return buildManager; - } - - @Override - public AndroidModuleSystem getModuleSystem(Module module) { - return BlazeModuleSystem.getInstance(module); - } - - @Override - public ProjectSystemSyncManager getSyncManager() { - return syncManager; - } - - @Override - public Collection getPsiElementFinders() { - return myFinders; - } - - @Override - public BlazeLightResourceClassService getLightResourceClassService() { - return BlazeLightResourceClassService.getInstance(project); - } - - @Override - public SourceProvidersFactory getSourceProvidersFactory() { - return new SourceProvidersFactory() { - @Override - public SourceProviders createSourceProvidersFor(AndroidFacet facet) { - BlazeAndroidModel model = ((BlazeAndroidModel) AndroidModel.get(facet)); - if (model != null) { - return createForModel(model); - } else { - return createSourceProvidersForLegacyModule(facet); - } - } - - private SourceProviders createForModel(BlazeAndroidModel model) { - NamedIdeaSourceProvider mainSourceProvider = model.getDefaultSourceProvider(); - if (QuerySync.isEnabled()) { - return new SourceProvidersImpl( - mainSourceProvider, - ImmutableList.of(mainSourceProvider), - ImmutableList.of(), - ImmutableList.of(), - ImmutableList.of(), - ImmutableList.of(mainSourceProvider), - ImmutableList.of(mainSourceProvider), - emptySourceProvider(ScopeType.MAIN), - emptySourceProvider(ScopeType.UNIT_TEST), - emptySourceProvider(ScopeType.ANDROID_TEST), - emptySourceProvider(ScopeType.TEST_FIXTURES)); - } else { - return new SourceProvidersImpl( - mainSourceProvider, - ImmutableList.of(mainSourceProvider), - ImmutableList.of(mainSourceProvider), - ImmutableList.of(mainSourceProvider), - ImmutableList.of(mainSourceProvider), - ImmutableList.of(mainSourceProvider), - ImmutableList.of(mainSourceProvider), - emptySourceProvider(ScopeType.MAIN), - emptySourceProvider(ScopeType.UNIT_TEST), - emptySourceProvider(ScopeType.ANDROID_TEST), - emptySourceProvider(ScopeType.TEST_FIXTURES)); - } - } - }; - } - - // @Override #api212 - public ClassJarProvider getClassJarProvider() { - return new BlazeClassJarProvider(project); - } - - @Override - public Collection getAndroidFacetsWithPackageName( - Project project, String packageName) { - return getAndroidFacetsWithPackageName( - project, packageName, GlobalSearchScope.projectScope(project)); - } - - private Collection getAndroidFacetsWithPackageName( - Project project, String packageName, GlobalSearchScope scope) { - List facets = ProjectFacetManager.getInstance(project).getFacets(AndroidFacet.ID); - return facets.stream() - .filter(facet -> hasPackageName(facet, packageName)) - .filter( - facet -> { - VirtualFile file = SourceProviderManager.getInstance(facet).getMainManifestFile(); - if (file == null) { - return false; - } else { - return scope.contains(file); - } - }) - .collect(Collectors.toList()); - } - - @Override - public Collection getSubmodules() { - return ImmutableList.of(); - } - - @Override - public Collection getBootClasspath(@NotNull Module module) { - // TODO: b/266586669 - return ImmutableList.of(); - } - - private static boolean hasPackageName(AndroidFacet facet, String packageName) { - String nameFromFacet = PackageNameUtils.getPackageName(facet.getModule()); - if (nameFromFacet == null) { - return false; - } - return nameFromFacet.equals(packageName); - } - - @NotNull - // @Override #api223 - public List desugarLibraryConfigFiles(@NotNull Project project) { - return ImmutableList.of(); - } -} diff --git a/aswb/sdkcompat/as223/com/google/idea/blaze/android/projectsystem/PackageNameUtils.java b/aswb/sdkcompat/as223/com/google/idea/blaze/android/projectsystem/PackageNameUtils.java deleted file mode 100644 index 83a7fcd9b20..00000000000 --- a/aswb/sdkcompat/as223/com/google/idea/blaze/android/projectsystem/PackageNameUtils.java +++ /dev/null @@ -1,139 +0,0 @@ -/* - * Copyright 2018 The Bazel Authors. All rights reserved. - * - * 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. - */ -package com.google.idea.blaze.android.projectsystem; - -import com.android.manifmerger.ManifestSystemProperty; -import com.android.tools.idea.model.AndroidManifestIndex; -import com.android.tools.idea.model.AndroidManifestIndexCompat; -import com.android.tools.idea.model.AndroidManifestRawText; -import com.android.tools.idea.model.MergedManifestModificationTracker; -import com.android.tools.idea.projectsystem.ManifestOverrides; -import com.android.tools.idea.projectsystem.SourceProviderManager; -import com.google.common.annotations.VisibleForTesting; -import com.google.idea.common.experiments.BoolExperiment; -import com.intellij.openapi.module.Module; -import com.intellij.openapi.project.DumbService; -import com.intellij.openapi.project.IndexNotReadyException; -import com.intellij.openapi.project.Project; -import com.intellij.openapi.util.text.StringUtil; -import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.psi.util.CachedValueProvider; -import com.intellij.psi.util.CachedValuesManager; -import org.jetbrains.android.dom.manifest.AndroidManifestUtils; -import org.jetbrains.android.dom.manifest.AndroidManifestXmlFile; -import org.jetbrains.android.facet.AndroidFacet; -import org.jetbrains.annotations.Nullable; - -/** Utilities to obtain the package name for a given module. */ -public class PackageNameUtils { - /** - * Determines whether we use the {@link AndroidManifestIndex} to obtain the raw text package name - * from a module's primary manifest. Note that we still won't use the index if {@link - * AndroidManifestIndex#indexEnabled()} returns false. - * - * @see PackageNameUtils#getPackageName(Module) - * @see PackageNameUtils#doGetPackageName(AndroidFacet, boolean) - */ - private static final BoolExperiment USE_ANDROID_MANIFEST_INDEX = - new BoolExperiment("use.android.manifest.index", true); - - @Nullable - public static String getPackageName(Module module) { - AndroidFacet facet = AndroidFacet.getInstance(module); - assert facet != null; - return CachedValuesManager.getManager(module.getProject()) - .getCachedValue( - facet, - () -> { - boolean useIndex = - AndroidManifestIndexCompat.indexEnabled() - && USE_ANDROID_MANIFEST_INDEX.getValue(); - String packageName = doGetPackageName(facet, useIndex); - return CachedValueProvider.Result.create( - StringUtil.nullize(packageName, true), - MergedManifestModificationTracker.getInstance(module)); - }); - } - - /** - * Returns the package name from an Android module's merged manifest without actually computing - * the whole merged manifest. This is either - * - *
    - *
  1. The {@link ManifestSystemProperty#PACKAGE} manifest override if one is specified by the - * corresponding BUILD target, or - *
  2. The result of applying placeholder substitution to the raw package name from the module's - * primary manifest - *
- * - * In the second case, we try to obtain the raw package name using the {@link - * AndroidManifestIndex} if {@code useIndex} is true. If {@code useIndex} is false or querying the - * index fails for some reason (e.g. this method is called in a read action but not a *smart* read - * action), then we resort to parsing the PSI of the module's primary manifest to get the raw - * package name. - * - * @see AndroidModuleSystem#getManifestOverrides() - * @see AndroidModuleSystem#getPackageName() - */ - @Nullable - @VisibleForTesting - static String doGetPackageName(AndroidFacet facet, boolean useIndex) { - ManifestOverrides manifestOverrides = - BlazeModuleSystem.getInstance(facet.getModule()).getManifestOverrides(); - String packageOverride = - ManifestValueProcessor.getPackageOverride(manifestOverrides.getDirectOverrides()); - if (packageOverride != null) { - return packageOverride; - } - String rawPackageName = null; - if (useIndex) { - rawPackageName = getRawPackageNameFromIndex(facet); - } - if (rawPackageName == null) { - rawPackageName = getRawPackageNameFromPsi(facet); - } - return rawPackageName == null ? null : manifestOverrides.resolvePlaceholders(rawPackageName); - } - - @Nullable - private static String getRawPackageNameFromIndex(AndroidFacet facet) { - VirtualFile primaryManifest = SourceProviderManager.getInstance(facet).getMainManifestFile(); - if (primaryManifest == null) { - return null; - } - Project project = facet.getModule().getProject(); - try { - AndroidManifestRawText manifestRawText = - DumbService.getInstance(project) - .runReadActionInSmartMode( - () -> AndroidManifestIndex.getDataForManifestFile(project, primaryManifest)); - return manifestRawText == null ? null : manifestRawText.getPackageName(); - } catch (IndexNotReadyException e) { - // TODO(142681129): runReadActionInSmartMode doesn't work if we already have read access. - // We need to refactor the callers of AndroidManifestUtils#getPackage to require a *smart* - // read action, at which point we can remove this try-catch. - return null; - } - } - - @Nullable - private static String getRawPackageNameFromPsi(AndroidFacet facet) { - AndroidManifestXmlFile primaryManifest = AndroidManifestUtils.getPrimaryManifestXml(facet); - return primaryManifest == null ? null : primaryManifest.getPackageName(); - } - - private PackageNameUtils() {} -} diff --git a/aswb/sdkcompat/as223/com/google/idea/blaze/android/resources/BlazeRClass.java b/aswb/sdkcompat/as223/com/google/idea/blaze/android/resources/BlazeRClass.java deleted file mode 100644 index 5a8cbf8e450..00000000000 --- a/aswb/sdkcompat/as223/com/google/idea/blaze/android/resources/BlazeRClass.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright 2018 The Bazel Authors. All rights reserved. - * - * 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. - */ -package com.google.idea.blaze.android.resources; - -import static org.jetbrains.android.AndroidResolveScopeEnlarger.LIGHT_CLASS_KEY; -import static org.jetbrains.android.AndroidResolveScopeEnlarger.MODULE_POINTER_KEY; - -import com.android.ide.common.rendering.api.ResourceNamespace; -import com.android.tools.idea.res.LocalResourceRepository; -import com.android.tools.idea.res.ResourceRepositoryRClass; -import com.android.tools.idea.res.StudioResourceRepositoryManager; -import com.intellij.openapi.module.Module; -import com.intellij.openapi.module.ModulePointerManager; -import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.psi.PsiManager; -import org.jetbrains.android.augment.AndroidLightField; -import org.jetbrains.android.facet.AndroidFacet; - -/** Blaze implementation of an R class based on resource repositories. */ -public class BlazeRClass extends ResourceRepositoryRClass { - - private final AndroidFacet androidFacet; - - public BlazeRClass(PsiManager psiManager, AndroidFacet androidFacet, String packageName) { - super( - psiManager, - new ResourcesSource() { - @Override - public String getPackageName() { - return packageName; - } - - @Override - public Transitivity getTransitivity() { - return Transitivity.TRANSITIVE; - } - - @Override - public StudioResourceRepositoryManager getResourceRepositoryManager() { - return StudioResourceRepositoryManager.getInstance(androidFacet); - } - - @Override - public LocalResourceRepository getResourceRepository() { - return StudioResourceRepositoryManager.getAppResources(androidFacet); - } - - @Override - public ResourceNamespace getResourceNamespace() { - return ResourceNamespace.RES_AUTO; - } - - @Override - public AndroidLightField.FieldModifier getFieldModifier() { - return AndroidLightField.FieldModifier.NON_FINAL; - } - }); - this.androidFacet = androidFacet; - setModuleInfo(getModule(), false); - VirtualFile virtualFile = myFile.getViewProvider().getVirtualFile(); - virtualFile.putUserData( - MODULE_POINTER_KEY, ModulePointerManager.getInstance(getProject()).create(getModule())); - virtualFile.putUserData(LIGHT_CLASS_KEY, ResourceRepositoryRClass.class); - } - - public Module getModule() { - return androidFacet.getModule(); - } -} diff --git a/aswb/sdkcompat/as223/com/google/idea/blaze/android/run/BlazeAndroidDeploymentService.java b/aswb/sdkcompat/as223/com/google/idea/blaze/android/run/BlazeAndroidDeploymentService.java deleted file mode 100644 index 6cc3a63459e..00000000000 --- a/aswb/sdkcompat/as223/com/google/idea/blaze/android/run/BlazeAndroidDeploymentService.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright 2020 The Bazel Authors. All rights reserved. - * - * 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. - */ -package com.google.idea.blaze.android.run; - -import com.android.tools.idea.run.ApkInfo; -import com.android.tools.idea.run.LaunchOptions; -import com.android.tools.idea.run.blaze.BlazeLaunchTask; -import com.android.tools.idea.run.tasks.DeployTask; -import com.android.tools.idea.run.tasks.DeployTasksCompat; -import com.intellij.openapi.project.Project; -import java.util.Collection; - -/** A service that provides {@link DeployTask}. */ -public interface BlazeAndroidDeploymentService { - static BlazeAndroidDeploymentService getInstance(Project project) { - return project.getService(BlazeAndroidDeploymentService.class); - } - - /** Returns a {@link DeployTask} to deploy the given files and launch options. */ - BlazeLaunchTask getDeployTask(Collection packages, LaunchOptions launchOptions); - - /** A default implementation that uses {@link DeployTasksCompat#createDeployTask}. */ - class DefaultDeploymentService implements BlazeAndroidDeploymentService { - private final Project project; - - public DefaultDeploymentService(Project project) { - this.project = project; - } - - @Override - public BlazeLaunchTask getDeployTask( - Collection packages, LaunchOptions launchOptions) { - return DeployTasksCompat.createDeployTask(project, packages, launchOptions); - } - } -} diff --git a/aswb/sdkcompat/as223/com/google/idea/blaze/android/run/BlazeCommandAndroidDebuggerInfoProvider.java b/aswb/sdkcompat/as223/com/google/idea/blaze/android/run/BlazeCommandAndroidDebuggerInfoProvider.java deleted file mode 100644 index 03dd9f80da7..00000000000 --- a/aswb/sdkcompat/as223/com/google/idea/blaze/android/run/BlazeCommandAndroidDebuggerInfoProvider.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright (C) 2020 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. - */ -package com.google.idea.blaze.android.run; - -import com.android.tools.idea.execution.common.debug.AndroidDebugger; -import com.android.tools.idea.execution.common.debug.AndroidDebuggerState; -import com.android.tools.idea.execution.common.debug.impl.java.AndroidJavaDebugger; -import com.android.tools.idea.run.editor.AndroidDebuggerInfoProvider; -import com.google.idea.blaze.android.cppimpl.debug.BlazeNativeAndroidDebugger; -import com.google.idea.blaze.android.run.binary.BlazeAndroidBinaryRunConfigurationState; -import com.google.idea.blaze.android.run.test.BlazeAndroidTestRunConfigurationState; -import com.google.idea.blaze.base.model.BlazeProjectData; -import com.google.idea.blaze.base.run.BlazeCommandRunConfiguration; -import com.google.idea.blaze.base.sync.data.BlazeProjectDataManager; -import com.intellij.execution.configurations.RunConfiguration; -import com.intellij.openapi.project.Project; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import org.jetbrains.annotations.Nullable; - -/** Provider of blaze project compatible android debuggers. */ -public class BlazeCommandAndroidDebuggerInfoProvider implements AndroidDebuggerInfoProvider { - @Override - public boolean supportsProject(Project project) { - BlazeProjectData blazeProjectData = - BlazeProjectDataManager.getInstance(project).getBlazeProjectData(); - return blazeProjectData != null; - } - - @Override - @SuppressWarnings("rawtypes") // List includes multiple AndroidDebuggerState types. - public List getAndroidDebuggers(RunConfiguration configuration) { - if (getCommonState(configuration) != null) { - return Arrays.asList(new BlazeNativeAndroidDebugger(), new AndroidJavaDebugger()); - } - return Collections.emptyList(); - } - - @Nullable - @Override - public AndroidDebugger getSelectedAndroidDebugger( - RunConfiguration configuration) { - // b/170159822 Always return java debugger because BlazeAutoAndroidDebugger doesn't work and - // users likely want the java debugger not the native debugger. - return new AndroidJavaDebugger(); - } - - @Nullable - @Override - public AndroidDebuggerState getSelectedAndroidDebuggerState(RunConfiguration configuration) { - AndroidDebugger debugger = getSelectedAndroidDebugger(configuration); - if (debugger == null) { - return null; - } - return debugger.createState(); - } - - @Nullable - private BlazeAndroidRunConfigurationCommonState getCommonState(RunConfiguration configuration) { - if (!(configuration instanceof BlazeCommandRunConfiguration)) { - return null; - } - BlazeCommandRunConfiguration blazeRunConfig = (BlazeCommandRunConfiguration) configuration; - BlazeAndroidBinaryRunConfigurationState binaryState = - blazeRunConfig.getHandlerStateIfType(BlazeAndroidBinaryRunConfigurationState.class); - if (binaryState != null) { - return binaryState.getCommonState(); - } - BlazeAndroidTestRunConfigurationState testState = - blazeRunConfig.getHandlerStateIfType(BlazeAndroidTestRunConfigurationState.class); - if (testState != null) { - return testState.getCommonState(); - } - return null; - } -} diff --git a/aswb/sdkcompat/as223/com/google/idea/blaze/android/run/binary/BlazeAndroidBinaryApplicationLaunchTaskProvider.java b/aswb/sdkcompat/as223/com/google/idea/blaze/android/run/binary/BlazeAndroidBinaryApplicationLaunchTaskProvider.java deleted file mode 100644 index 8a74f3d458f..00000000000 --- a/aswb/sdkcompat/as223/com/google/idea/blaze/android/run/binary/BlazeAndroidBinaryApplicationLaunchTaskProvider.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright 2016 The Bazel Authors. All rights reserved. - * - * 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. - */ -package com.google.idea.blaze.android.run.binary; - -import com.android.tools.idea.run.ApkProvisionException; -import com.android.tools.idea.run.ApplicationIdProvider; -import com.android.tools.idea.run.activity.StartActivityFlagsProvider; -import com.android.tools.idea.run.blaze.BlazeLaunchTask; -import com.android.tools.idea.run.blaze.BlazeLaunchTaskWrapper; -import com.android.tools.idea.run.tasks.AndroidDeepLinkLaunchTask; -import com.android.tools.idea.run.tasks.DefaultActivityLaunchTask; -import com.android.tools.idea.run.tasks.SpecificActivityLaunchTask; -import com.google.idea.blaze.android.manifest.ManifestParser; -import com.intellij.execution.ExecutionException; -import com.intellij.openapi.diagnostic.Logger; - -/** Provides the launch task for android_binary */ -public class BlazeAndroidBinaryApplicationLaunchTaskProvider { - private static final Logger LOG = - Logger.getInstance(BlazeAndroidBinaryApplicationLaunchTaskProvider.class); - - public static BlazeLaunchTask getApplicationLaunchTask( - ApplicationIdProvider applicationIdProvider, - ManifestParser.ParsedManifest mergedManifestParsedManifest, - BlazeAndroidBinaryRunConfigurationState configState, - StartActivityFlagsProvider startActivityFlagsProvider) - throws ExecutionException { - try { - String applicationId = applicationIdProvider.getPackageName(); - - switch (configState.getMode()) { - case BlazeAndroidBinaryRunConfigurationState.LAUNCH_DEFAULT_ACTIVITY: - BlazeDefaultActivityLocator activityLocator = - new BlazeDefaultActivityLocator(mergedManifestParsedManifest); - return new BlazeLaunchTaskWrapper( - new DefaultActivityLaunchTask( - applicationId, activityLocator, startActivityFlagsProvider)); - case BlazeAndroidBinaryRunConfigurationState.LAUNCH_SPECIFIC_ACTIVITY: - return new BlazeLaunchTaskWrapper( - new SpecificActivityLaunchTask( - applicationId, configState.getActivityClass(), startActivityFlagsProvider)); - case BlazeAndroidBinaryRunConfigurationState.LAUNCH_DEEP_LINK: - return new BlazeLaunchTaskWrapper( - new AndroidDeepLinkLaunchTask(configState.getDeepLink(), startActivityFlagsProvider)); - case BlazeAndroidBinaryRunConfigurationState.DO_NOTHING: - default: - return null; - } - } catch (ApkProvisionException e) { - throw new ExecutionException("Unable to identify application id"); - } - } -} diff --git a/aswb/sdkcompat/as223/com/google/idea/blaze/android/run/binary/BlazeAndroidBinaryNormalBuildRunContext.java b/aswb/sdkcompat/as223/com/google/idea/blaze/android/run/binary/BlazeAndroidBinaryNormalBuildRunContext.java deleted file mode 100644 index 6b2d10e2dac..00000000000 --- a/aswb/sdkcompat/as223/com/google/idea/blaze/android/run/binary/BlazeAndroidBinaryNormalBuildRunContext.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright 2019 The Bazel Authors. All rights reserved. - * - * 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. - */ -package com.google.idea.blaze.android.run.binary; - -import static com.android.tools.idea.run.tasks.DefaultConnectDebuggerTaskKt.getBaseDebuggerTask; - -import com.android.tools.idea.execution.common.debug.AndroidDebugger; -import com.android.tools.idea.execution.common.debug.AndroidDebuggerState; -import com.android.tools.idea.run.ApkProvisionException; -import com.android.tools.idea.run.LaunchOptions; -import com.android.tools.idea.run.activity.DefaultStartActivityFlagsProvider; -import com.android.tools.idea.run.activity.StartActivityFlagsProvider; -import com.android.tools.idea.run.blaze.BlazeLaunchTask; -import com.android.tools.idea.run.tasks.ConnectDebuggerTask; -import com.google.idea.blaze.android.run.deployinfo.BlazeAndroidDeployInfo; -import com.google.idea.blaze.android.run.runner.ApkBuildStep; -import com.intellij.execution.ExecutionException; -import com.intellij.execution.Executor; -import com.intellij.execution.configurations.RunConfiguration; -import com.intellij.execution.runners.ExecutionEnvironment; -import com.intellij.openapi.project.Project; -import javax.annotation.Nullable; -import org.jetbrains.android.facet.AndroidFacet; - -/** Compat for #api212 */ -public class BlazeAndroidBinaryNormalBuildRunContext - extends BlazeAndroidBinaryNormalBuildRunContextBase { - BlazeAndroidBinaryNormalBuildRunContext( - Project project, - AndroidFacet facet, - RunConfiguration runConfiguration, - ExecutionEnvironment env, - BlazeAndroidBinaryRunConfigurationState configState, - ApkBuildStep buildStep, - String launchId) { - super(project, facet, runConfiguration, env, configState, buildStep, launchId); - } - - @Override - public BlazeLaunchTask getApplicationLaunchTask( - LaunchOptions launchOptions, @Nullable Integer userId, String contributorsAmStartOptions) - throws ExecutionException { - String extraFlags = UserIdHelper.getFlagsFromUserId(userId); - if (!contributorsAmStartOptions.isEmpty()) { - extraFlags += (extraFlags.isEmpty() ? "" : " ") + contributorsAmStartOptions; - } - - final StartActivityFlagsProvider startActivityFlagsProvider = - new DefaultStartActivityFlagsProvider(project, launchOptions.isDebug(), extraFlags); - - BlazeAndroidDeployInfo deployInfo; - try { - deployInfo = buildStep.getDeployInfo(); - } catch (ApkProvisionException e) { - throw new ExecutionException(e); - } - - return BlazeAndroidBinaryApplicationLaunchTaskProvider.getApplicationLaunchTask( - applicationIdProvider, - deployInfo.getMergedManifest(), - configState, - startActivityFlagsProvider); - } - - @Nullable - @Override - @SuppressWarnings("unchecked") - public ConnectDebuggerTask getDebuggerTask( - AndroidDebugger androidDebugger, AndroidDebuggerState androidDebuggerState) { - return getBaseDebuggerTask(androidDebugger, androidDebuggerState, env, facet); - } - - @Override - public Executor getExecutor() { - return env.getExecutor(); - } -} diff --git a/aswb/sdkcompat/as223/com/google/idea/blaze/android/run/binary/BlazeAndroidBinaryNormalBuildRunContextBase.java b/aswb/sdkcompat/as223/com/google/idea/blaze/android/run/binary/BlazeAndroidBinaryNormalBuildRunContextBase.java deleted file mode 100644 index bc3517e8fe8..00000000000 --- a/aswb/sdkcompat/as223/com/google/idea/blaze/android/run/binary/BlazeAndroidBinaryNormalBuildRunContextBase.java +++ /dev/null @@ -1,177 +0,0 @@ -/* - * Copyright 2016 The Bazel Authors. All rights reserved. - * - * 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. - */ -package com.google.idea.blaze.android.run.binary; - -import static com.google.idea.blaze.android.run.runner.BlazeAndroidLaunchTasksProvider.NATIVE_DEBUGGING_ENABLED; - -import com.android.ddmlib.IDevice; -import com.android.tools.idea.gradle.util.DynamicAppUtils; -import com.android.tools.idea.run.ApkFileUnit; -import com.android.tools.idea.run.ApkInfo; -import com.android.tools.idea.run.ApkProvider; -import com.android.tools.idea.run.ApkProvisionException; -import com.android.tools.idea.run.ApplicationIdProvider; -import com.android.tools.idea.run.ConsoleProvider; -import com.android.tools.idea.run.LaunchOptions; -import com.android.tools.idea.run.blaze.BlazeLaunchTask; -import com.android.tools.idea.run.blaze.BlazeLaunchTasksProvider; -import com.android.tools.idea.run.editor.ProfilerState; -import com.android.tools.idea.run.tasks.DeployTasksCompat; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; -import com.google.idea.blaze.android.run.deployinfo.BlazeApkProviderService; -import com.google.idea.blaze.android.run.runner.ApkBuildStep; -import com.google.idea.blaze.android.run.runner.BlazeAndroidDeviceSelector; -import com.google.idea.blaze.android.run.runner.BlazeAndroidLaunchTasksProvider; -import com.google.idea.blaze.android.run.runner.BlazeAndroidRunContext; -import com.intellij.execution.ExecutionException; -import com.intellij.execution.configurations.RunConfiguration; -import com.intellij.execution.runners.ExecutionEnvironment; -import com.intellij.openapi.project.Project; -import java.util.Collection; -import java.util.List; -import java.util.stream.Collectors; -import javax.annotation.Nullable; -import org.jetbrains.android.facet.AndroidFacet; -import org.jetbrains.annotations.NotNull; - -/** Run context for android_binary. */ -public abstract class BlazeAndroidBinaryNormalBuildRunContextBase - implements BlazeAndroidRunContext { - protected final Project project; - protected final AndroidFacet facet; - protected final RunConfiguration runConfiguration; - protected final ExecutionEnvironment env; - protected final BlazeAndroidBinaryRunConfigurationState configState; - protected final ConsoleProvider consoleProvider; - protected final ApkBuildStep buildStep; - protected final ApkProvider apkProvider; - protected final ApplicationIdProvider applicationIdProvider; - private final String launchId; - - BlazeAndroidBinaryNormalBuildRunContextBase( - Project project, - AndroidFacet facet, - RunConfiguration runConfiguration, - ExecutionEnvironment env, - BlazeAndroidBinaryRunConfigurationState configState, - ApkBuildStep buildStep, - String launchId) { - this.project = project; - this.facet = facet; - this.runConfiguration = runConfiguration; - this.env = env; - this.configState = configState; - this.consoleProvider = new BlazeAndroidBinaryConsoleProvider(project); - this.buildStep = buildStep; - this.apkProvider = BlazeApkProviderService.getInstance().getApkProvider(project, buildStep); - this.applicationIdProvider = new BlazeAndroidBinaryApplicationIdProvider(buildStep); - this.launchId = launchId; - } - - @Override - public BlazeAndroidDeviceSelector getDeviceSelector() { - return new BlazeAndroidDeviceSelector.NormalDeviceSelector(); - } - - @Override - public void augmentLaunchOptions(LaunchOptions.Builder options) { - options.setDeploy(true).setOpenLogcatAutomatically(configState.showLogcatAutomatically()); - options.addExtraOptions( - ImmutableMap.of( - "android.profilers.state", // Not used after #api211 - configState.getProfilerState(), - NATIVE_DEBUGGING_ENABLED, - configState.getCommonState().isNativeDebuggingEnabled())); - } - - @Override - public ConsoleProvider getConsoleProvider() { - return consoleProvider; - } - - @Override - public ApplicationIdProvider getApplicationIdProvider() throws ExecutionException { - return applicationIdProvider; - } - - @Override - public ApkBuildStep getBuildStep() { - return buildStep; - } - - @Nullable - @Override - public Integer getUserId(IDevice device) throws ExecutionException { - return UserIdHelper.getUserIdFromConfigurationState(project, device, configState); - } - - @Override - public BlazeLaunchTasksProvider getLaunchTasksProvider(LaunchOptions.Builder launchOptionsBuilder) - throws ExecutionException { - return new BlazeAndroidLaunchTasksProvider( - project, this, applicationIdProvider, launchOptionsBuilder); - } - - @Override - public String getAmStartOptions() { - return configState.getAmStartOptions(); - } - - @Override - public ProfilerState getProfileState() { - return configState.getProfilerState(); - } - - @Nullable - @Override - public ImmutableList getDeployTasks(IDevice device, LaunchOptions launchOptions) - throws ExecutionException { - BlazeLaunchTask deployTask = - DeployTasksCompat.createDeployTask( - project, getApkInfoToInstall(device, launchOptions, apkProvider), launchOptions); - return ImmutableList.of(new DeploymentTimingReporterTask(launchId, deployTask)); - } - - /** Returns a list of APKs excluding any APKs for features that are disabled. */ - public static List getApkInfoToInstall( - IDevice device, LaunchOptions launchOptions, ApkProvider apkProvider) - throws ExecutionException { - Collection apks; - try { - apks = apkProvider.getApks(device); - } catch (ApkProvisionException e) { - throw new ExecutionException(e); - } - List disabledFeatures = launchOptions.getDisabledDynamicFeatures(); - return apks.stream() - .map(apk -> getApkInfoToInstall(apk, disabledFeatures)) - .collect(Collectors.toList()); - } - - @NotNull - private static ApkInfo getApkInfoToInstall(ApkInfo apkInfo, List disabledFeatures) { - if (apkInfo.getFiles().size() > 1) { - List filteredApks = - apkInfo.getFiles().stream() - .filter(feature -> DynamicAppUtils.isFeatureEnabled(disabledFeatures, feature)) - .collect(Collectors.toList()); - return new ApkInfo(filteredApks, apkInfo.getApplicationId()); - } else { - return apkInfo; - } - } -} diff --git a/aswb/sdkcompat/as223/com/google/idea/blaze/android/run/binary/BlazeAndroidBinaryNormalBuildRunContextCompat.java b/aswb/sdkcompat/as223/com/google/idea/blaze/android/run/binary/BlazeAndroidBinaryNormalBuildRunContextCompat.java deleted file mode 100644 index d54c472c84b..00000000000 --- a/aswb/sdkcompat/as223/com/google/idea/blaze/android/run/binary/BlazeAndroidBinaryNormalBuildRunContextCompat.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright 2022 The Bazel Authors. All rights reserved. - * - * 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. - */ -package com.google.idea.blaze.android.run.binary; - -import static com.android.tools.idea.run.tasks.DefaultConnectDebuggerTaskKt.getBaseDebuggerTask; - -import com.android.tools.idea.execution.common.debug.AndroidDebugger; -import com.android.tools.idea.execution.common.debug.AndroidDebuggerState; -import com.android.tools.idea.run.tasks.ConnectDebuggerTask; -import com.google.idea.blaze.android.run.runner.ApkBuildStep; -import com.intellij.execution.configurations.RunConfiguration; -import com.intellij.execution.runners.ExecutionEnvironment; -import com.intellij.openapi.project.Project; -import javax.annotation.Nullable; -import org.jetbrains.android.facet.AndroidFacet; - -/** Compat class for {@link BlazeAndroidBinaryNormalBuildRunContext}. */ -public class BlazeAndroidBinaryNormalBuildRunContextCompat - extends BlazeAndroidBinaryNormalBuildRunContext { - - BlazeAndroidBinaryNormalBuildRunContextCompat( - Project project, - AndroidFacet facet, - RunConfiguration runConfiguration, - ExecutionEnvironment env, - BlazeAndroidBinaryRunConfigurationState configState, - ApkBuildStep buildStep, - String launchId) { - super(project, facet, runConfiguration, env, configState, buildStep, launchId); - } - - @Nullable - @Override - @SuppressWarnings("unchecked") - public ConnectDebuggerTask getDebuggerTask( - AndroidDebugger androidDebugger, AndroidDebuggerState androidDebuggerState) { - return getBaseDebuggerTask(androidDebugger, androidDebuggerState, env, facet); - } -} diff --git a/aswb/sdkcompat/as223/com/google/idea/blaze/android/run/binary/BlazeAndroidBinaryProgramRunner.java b/aswb/sdkcompat/as223/com/google/idea/blaze/android/run/binary/BlazeAndroidBinaryProgramRunner.java deleted file mode 100644 index 50f42d4b2dd..00000000000 --- a/aswb/sdkcompat/as223/com/google/idea/blaze/android/run/binary/BlazeAndroidBinaryProgramRunner.java +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Copyright 2016 The Bazel Authors. All rights reserved. - * - * 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. - */ -package com.google.idea.blaze.android.run.binary; - -import static com.intellij.openapi.application.ModalityState.NON_MODAL; - -import com.android.tools.idea.profilers.ProfileRunExecutor; -import com.android.tools.idea.run.configuration.execution.AndroidConfigurationExecutor; -import com.google.idea.blaze.android.run.BlazeAndroidRunConfigurationHandler; -import com.intellij.execution.ExecutionException; -import com.intellij.execution.ExecutionResult; -import com.intellij.execution.Executor; -import com.intellij.execution.configurations.RunProfile; -import com.intellij.execution.configurations.RunProfileState; -import com.intellij.execution.configurations.RunnerSettings; -import com.intellij.execution.executors.DefaultDebugExecutor; -import com.intellij.execution.executors.DefaultRunExecutor; -import com.intellij.execution.runners.AsyncProgramRunner; -import com.intellij.execution.runners.ExecutionEnvironment; -import com.intellij.execution.runners.RunContentBuilder; -import com.intellij.execution.ui.RunContentDescriptor; -import com.intellij.openapi.application.ActionsKt; -import com.intellij.openapi.fileEditor.FileDocumentManager; -import com.intellij.openapi.progress.ProgressIndicator; -import com.intellij.openapi.progress.ProgressManager; -import com.intellij.openapi.progress.Task; -import org.jetbrains.concurrency.AsyncPromise; -import org.jetbrains.concurrency.Promise; - -/** Program runner for configurations from {@link BlazeAndroidBinaryRunConfigurationHandler}. */ -public class BlazeAndroidBinaryProgramRunner extends AsyncProgramRunner { - @Override - public boolean canRun(String executorId, RunProfile profile) { - BlazeAndroidRunConfigurationHandler handler = - BlazeAndroidRunConfigurationHandler.getHandlerFrom(profile); - if (!(handler instanceof BlazeAndroidBinaryRunConfigurationHandler)) { - return false; - } - return (DefaultDebugExecutor.EXECUTOR_ID.equals(executorId) - || DefaultRunExecutor.EXECUTOR_ID.equals(executorId) - || ProfileRunExecutor.EXECUTOR_ID.equals(executorId)); - } - - @Override - protected Promise execute( - ExecutionEnvironment environment, RunProfileState state) { - FileDocumentManager.getInstance().saveAllDocuments(); - - AsyncPromise promise = new AsyncPromise<>(); - - ProgressManager.getInstance() - .run( - new Task.Backgroundable(environment.getProject(), "Launching ${runProfile.name}") { - @Override - public void run(ProgressIndicator indicator) { - try { - RunContentDescriptor descriptor; - if (state instanceof AndroidConfigurationExecutor) { - AndroidConfigurationExecutor configurationExecutor = - (AndroidConfigurationExecutor) state; - Executor executor = environment.getExecutor(); - if (executor.getId().equals(DefaultDebugExecutor.EXECUTOR_ID)) { - descriptor = configurationExecutor.debug(indicator); - } else if (executor.getId().equals(DefaultRunExecutor.EXECUTOR_ID) - || executor.getId().equals(ProfileRunExecutor.EXECUTOR_ID)) { - descriptor = configurationExecutor.run(indicator); - } else { - throw new ExecutionException("Unsupported executor"); - } - } else { - descriptor = doExecute(state, environment); - } - promise.setResult(descriptor); - } catch (ExecutionException e) { - boolean unused = promise.setError(e); - } - } - - @Override - public void onCancel() { - super.onCancel(); - promise.setResult(null); - } - }); - - return promise; - } - - private RunContentDescriptor doExecute( - final RunProfileState state, final ExecutionEnvironment env) throws ExecutionException { - ExecutionResult result = state.execute(env.getExecutor(), this); - return ActionsKt.invokeAndWaitIfNeeded( - NON_MODAL, - () -> new RunContentBuilder(result, env).showRunContent(env.getContentToReuse())); - } - - @Override - public String getRunnerId() { - return "AndroidBinaryProgramRunner"; - } -} diff --git a/aswb/sdkcompat/as223/com/google/idea/blaze/android/run/binary/DeploymentTimingReporterTask.java b/aswb/sdkcompat/as223/com/google/idea/blaze/android/run/binary/DeploymentTimingReporterTask.java deleted file mode 100644 index 81696ad5b1e..00000000000 --- a/aswb/sdkcompat/as223/com/google/idea/blaze/android/run/binary/DeploymentTimingReporterTask.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright 2021 The Bazel Authors. All rights reserved. - * - * 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. - */ -package com.google.idea.blaze.android.run.binary; - -import com.android.tools.idea.run.blaze.BlazeLaunchContext; -import com.android.tools.idea.run.blaze.BlazeLaunchTask; -import com.google.common.base.Stopwatch; -import com.google.idea.blaze.android.run.LaunchMetrics; -import com.intellij.execution.ExecutionException; - -/** A wrapper launch task that wraps the given deployment task and logs the deployment latency. */ -public class DeploymentTimingReporterTask implements BlazeLaunchTask { - private final BlazeLaunchTask deployTask; - private final String launchId; - - public DeploymentTimingReporterTask(String launchId, BlazeLaunchTask deployTask) { - this.launchId = launchId; - this.deployTask = deployTask; - } - - @Override - public void run(BlazeLaunchContext launchContext) throws ExecutionException { - Stopwatch s = Stopwatch.createStarted(); - try { - deployTask.run(launchContext); - LaunchMetrics.logDeploymentTime(launchId, s.elapsed(), true); - } catch (ExecutionException e) { - LaunchMetrics.logDeploymentTime(launchId, s.elapsed(), false); - throw e; - } - } -} diff --git a/aswb/sdkcompat/as223/com/google/idea/blaze/android/run/binary/mobileinstall/BlazeAndroidBinaryMobileInstallRunContext.java b/aswb/sdkcompat/as223/com/google/idea/blaze/android/run/binary/mobileinstall/BlazeAndroidBinaryMobileInstallRunContext.java deleted file mode 100644 index c49082cfdaa..00000000000 --- a/aswb/sdkcompat/as223/com/google/idea/blaze/android/run/binary/mobileinstall/BlazeAndroidBinaryMobileInstallRunContext.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright 2016 The Bazel Authors. All rights reserved. - * - * 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. - */ -package com.google.idea.blaze.android.run.binary.mobileinstall; - -import static com.android.tools.idea.run.tasks.DefaultConnectDebuggerTaskKt.getBaseDebuggerTask; - -import com.android.tools.idea.execution.common.debug.AndroidDebugger; -import com.android.tools.idea.execution.common.debug.AndroidDebuggerState; -import com.android.tools.idea.run.ApkProvisionException; -import com.android.tools.idea.run.LaunchOptions; -import com.android.tools.idea.run.activity.DefaultStartActivityFlagsProvider; -import com.android.tools.idea.run.activity.StartActivityFlagsProvider; -import com.android.tools.idea.run.blaze.BlazeLaunchTask; -import com.android.tools.idea.run.tasks.ConnectDebuggerTask; -import com.google.idea.blaze.android.run.binary.BlazeAndroidBinaryApplicationLaunchTaskProvider; -import com.google.idea.blaze.android.run.binary.BlazeAndroidBinaryRunConfigurationState; -import com.google.idea.blaze.android.run.binary.UserIdHelper; -import com.google.idea.blaze.android.run.deployinfo.BlazeAndroidDeployInfo; -import com.google.idea.blaze.android.run.runner.ApkBuildStep; -import com.intellij.execution.ExecutionException; -import com.intellij.execution.Executor; -import com.intellij.execution.configurations.RunConfiguration; -import com.intellij.execution.runners.ExecutionEnvironment; -import com.intellij.openapi.project.Project; -import javax.annotation.Nullable; -import org.jetbrains.android.facet.AndroidFacet; - -/** Run Context for mobile install launches, #api4.0 compat. */ -public class BlazeAndroidBinaryMobileInstallRunContext - extends BlazeAndroidBinaryMobileInstallRunContextBase { - public BlazeAndroidBinaryMobileInstallRunContext( - Project project, - AndroidFacet facet, - RunConfiguration runConfiguration, - ExecutionEnvironment env, - BlazeAndroidBinaryRunConfigurationState configState, - ApkBuildStep buildStep, - String launchId) { - super(project, facet, runConfiguration, env, configState, buildStep, launchId); - } - - @SuppressWarnings("unchecked") // upstream API - @Override - public BlazeLaunchTask getApplicationLaunchTask( - LaunchOptions launchOptions, @Nullable Integer userId, String contributorsAmStartOptions) - throws ExecutionException { - - String extraFlags = UserIdHelper.getFlagsFromUserId(userId); - if (!contributorsAmStartOptions.isEmpty()) { - extraFlags += (extraFlags.isEmpty() ? "" : " ") + contributorsAmStartOptions; - } - - final StartActivityFlagsProvider startActivityFlagsProvider = - new DefaultStartActivityFlagsProvider(project, launchOptions.isDebug(), extraFlags); - BlazeAndroidDeployInfo deployInfo; - try { - deployInfo = buildStep.getDeployInfo(); - } catch (ApkProvisionException e) { - throw new ExecutionException(e); - } - - return BlazeAndroidBinaryApplicationLaunchTaskProvider.getApplicationLaunchTask( - applicationIdProvider, - deployInfo.getMergedManifest(), - configState, - startActivityFlagsProvider); - } - - @Nullable - @Override - @SuppressWarnings("unchecked") - public ConnectDebuggerTask getDebuggerTask( - AndroidDebugger androidDebugger, AndroidDebuggerState androidDebuggerState) { - return getBaseDebuggerTask(androidDebugger, androidDebuggerState, env, facet); - } - - @Override - public Executor getExecutor() { - return env.getExecutor(); - } -} diff --git a/aswb/sdkcompat/as223/com/google/idea/blaze/android/run/binary/mobileinstall/BlazeAndroidBinaryMobileInstallRunContextBase.java b/aswb/sdkcompat/as223/com/google/idea/blaze/android/run/binary/mobileinstall/BlazeAndroidBinaryMobileInstallRunContextBase.java deleted file mode 100644 index 7562174bd25..00000000000 --- a/aswb/sdkcompat/as223/com/google/idea/blaze/android/run/binary/mobileinstall/BlazeAndroidBinaryMobileInstallRunContextBase.java +++ /dev/null @@ -1,165 +0,0 @@ -/* - * Copyright 2016 The Bazel Authors. All rights reserved. - * - * 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. - */ -package com.google.idea.blaze.android.run.binary.mobileinstall; - -import com.android.ddmlib.IDevice; -import com.android.tools.idea.run.ApkFileUnit; -import com.android.tools.idea.run.ApkInfo; -import com.android.tools.idea.run.ApkProvisionException; -import com.android.tools.idea.run.ApplicationIdProvider; -import com.android.tools.idea.run.ConsoleProvider; -import com.android.tools.idea.run.LaunchOptions; -import com.android.tools.idea.run.blaze.BlazeLaunchTask; -import com.android.tools.idea.run.blaze.BlazeLaunchTasksProvider; -import com.android.tools.idea.run.editor.ProfilerState; -import com.android.tools.idea.run.tasks.DeployTasksCompat; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; -import com.google.idea.blaze.android.run.binary.BlazeAndroidBinaryApplicationIdProvider; -import com.google.idea.blaze.android.run.binary.BlazeAndroidBinaryConsoleProvider; -import com.google.idea.blaze.android.run.binary.BlazeAndroidBinaryRunConfigurationState; -import com.google.idea.blaze.android.run.binary.DeploymentTimingReporterTask; -import com.google.idea.blaze.android.run.binary.UserIdHelper; -import com.google.idea.blaze.android.run.deployinfo.BlazeAndroidDeployInfo; -import com.google.idea.blaze.android.run.runner.ApkBuildStep; -import com.google.idea.blaze.android.run.runner.BlazeAndroidDeviceSelector; -import com.google.idea.blaze.android.run.runner.BlazeAndroidLaunchTasksProvider; -import com.google.idea.blaze.android.run.runner.BlazeAndroidRunContext; -import com.google.idea.blaze.base.sync.data.BlazeDataStorage; -import com.intellij.execution.ExecutionException; -import com.intellij.execution.configurations.RunConfiguration; -import com.intellij.execution.runners.ExecutionEnvironment; -import com.intellij.openapi.project.Project; -import java.util.Collections; -import java.util.stream.Collectors; -import javax.annotation.Nullable; -import org.jetbrains.android.facet.AndroidFacet; - -/** Run context for android_binary. */ -abstract class BlazeAndroidBinaryMobileInstallRunContextBase implements BlazeAndroidRunContext { - protected final Project project; - protected final AndroidFacet facet; - protected final RunConfiguration runConfiguration; - protected final ExecutionEnvironment env; - protected final BlazeAndroidBinaryRunConfigurationState configState; - protected final ConsoleProvider consoleProvider; - protected final ApplicationIdProvider applicationIdProvider; - protected final ApkBuildStep buildStep; - private final String launchId; - - public BlazeAndroidBinaryMobileInstallRunContextBase( - Project project, - AndroidFacet facet, - RunConfiguration runConfiguration, - ExecutionEnvironment env, - BlazeAndroidBinaryRunConfigurationState configState, - ApkBuildStep buildStep, - String launchId) { - this.project = project; - this.facet = facet; - this.runConfiguration = runConfiguration; - this.env = env; - this.configState = configState; - this.consoleProvider = new BlazeAndroidBinaryConsoleProvider(project); - this.buildStep = buildStep; - this.applicationIdProvider = new BlazeAndroidBinaryApplicationIdProvider(buildStep); - this.launchId = launchId; - } - - @Override - public BlazeAndroidDeviceSelector getDeviceSelector() { - return new BlazeAndroidDeviceSelector.NormalDeviceSelector(); - } - - @Override - public void augmentLaunchOptions(LaunchOptions.Builder options) { - options - .setDeploy(buildStep.needsIdeDeploy()) - .setOpenLogcatAutomatically(configState.showLogcatAutomatically()); - // This is needed for compatibility with #api211 - options.addExtraOptions( - ImmutableMap.of("android.profilers.state", configState.getProfilerState())); - } - - @Override - public ConsoleProvider getConsoleProvider() { - return consoleProvider; - } - - @Override - public ApplicationIdProvider getApplicationIdProvider() throws ExecutionException { - return applicationIdProvider; - } - - @Override - public ApkBuildStep getBuildStep() { - return buildStep; - } - - @Override - public ProfilerState getProfileState() { - return configState.getProfilerState(); - } - - @Override - public ImmutableList getDeployTasks(IDevice device, LaunchOptions launchOptions) - throws ExecutionException { - if (!buildStep.needsIdeDeploy()) { - return ImmutableList.of(); - } - - BlazeAndroidDeployInfo deployInfo; - try { - deployInfo = buildStep.getDeployInfo(); - } catch (ApkProvisionException e) { - throw new ExecutionException(e); - } - - String packageName = deployInfo.getMergedManifest().packageName; - if (packageName == null) { - throw new ExecutionException("Could not determine package name from deploy info"); - } - - ApkInfo info = - new ApkInfo( - deployInfo.getApksToDeploy().stream() - .map(file -> new ApkFileUnit(BlazeDataStorage.WORKSPACE_MODULE_NAME, file)) - .collect(Collectors.toList()), - packageName); - - BlazeLaunchTask deployTask = - DeployTasksCompat.createDeployTask(project, Collections.singletonList(info), launchOptions); - return ImmutableList.of(new DeploymentTimingReporterTask(launchId, deployTask)); - } - - @Nullable - @Override - public Integer getUserId(IDevice device) throws ExecutionException { - return UserIdHelper.getUserIdFromConfigurationState(project, device, configState); - } - - @Override - public BlazeLaunchTasksProvider getLaunchTasksProvider(LaunchOptions.Builder launchOptionsBuilder) - throws ExecutionException { - return new BlazeAndroidLaunchTasksProvider( - project, this, applicationIdProvider, launchOptionsBuilder); - } - - @Override - public String getAmStartOptions() { - return configState.getAmStartOptions(); - } -} diff --git a/aswb/sdkcompat/as223/com/google/idea/blaze/android/run/binary/mobileinstall/BlazeAndroidBinaryMobileInstallRunContextCompat.java b/aswb/sdkcompat/as223/com/google/idea/blaze/android/run/binary/mobileinstall/BlazeAndroidBinaryMobileInstallRunContextCompat.java deleted file mode 100644 index 29411ebad5a..00000000000 --- a/aswb/sdkcompat/as223/com/google/idea/blaze/android/run/binary/mobileinstall/BlazeAndroidBinaryMobileInstallRunContextCompat.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright 2022 The Bazel Authors. All rights reserved. - * - * 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. - */ -package com.google.idea.blaze.android.run.binary.mobileinstall; - -import static com.android.tools.idea.run.tasks.DefaultConnectDebuggerTaskKt.getBaseDebuggerTask; - -import com.android.tools.idea.execution.common.debug.AndroidDebugger; -import com.android.tools.idea.execution.common.debug.AndroidDebuggerState; -import com.android.tools.idea.run.tasks.ConnectDebuggerTask; -import com.google.idea.blaze.android.run.binary.BlazeAndroidBinaryRunConfigurationState; -import com.google.idea.blaze.android.run.runner.ApkBuildStep; -import com.google.idea.blaze.base.run.BlazeCommandRunConfiguration; -import com.intellij.execution.runners.ExecutionEnvironment; -import com.intellij.openapi.project.Project; -import javax.annotation.Nullable; -import org.jetbrains.android.facet.AndroidFacet; - -/** Compatct class for {@link BlazeAndroidBinaryMobileInstallRunContext}. */ -public class BlazeAndroidBinaryMobileInstallRunContextCompat - extends BlazeAndroidBinaryMobileInstallRunContext { - - public BlazeAndroidBinaryMobileInstallRunContextCompat( - Project project, - AndroidFacet facet, - BlazeCommandRunConfiguration configuration, - ExecutionEnvironment env, - BlazeAndroidBinaryRunConfigurationState configState, - ApkBuildStep buildStep, - String launchId) { - super(project, facet, configuration, env, configState, buildStep, launchId); - } - - @Nullable - @Override - @SuppressWarnings("unchecked") - public ConnectDebuggerTask getDebuggerTask( - AndroidDebugger androidDebugger, AndroidDebuggerState androidDebuggerState) { - return getBaseDebuggerTask(androidDebugger, androidDebuggerState, env, facet); - } -} diff --git a/aswb/sdkcompat/as223/com/google/idea/blaze/android/run/runner/BlazeAndroidDebuggerService.java b/aswb/sdkcompat/as223/com/google/idea/blaze/android/run/runner/BlazeAndroidDebuggerService.java deleted file mode 100644 index c8658223baa..00000000000 --- a/aswb/sdkcompat/as223/com/google/idea/blaze/android/run/runner/BlazeAndroidDebuggerService.java +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Copyright 2016 The Bazel Authors. All rights reserved. - * - * 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. - */ -package com.google.idea.blaze.android.run.runner; - -import com.android.tools.idea.execution.common.debug.AndroidDebugger; -import com.android.tools.idea.execution.common.debug.AndroidDebuggerState; -import com.android.tools.idea.execution.common.debug.impl.java.AndroidJavaDebugger; -import com.android.tools.ndk.run.editor.AutoAndroidDebuggerState; -import com.google.common.collect.ImmutableList; -import com.google.idea.blaze.android.cppimpl.debug.BlazeAutoAndroidDebugger; -import com.google.idea.blaze.android.run.deployinfo.BlazeAndroidDeployInfo; -import com.google.idea.blaze.base.model.primitives.WorkspaceRoot; -import com.intellij.ide.plugins.PluginManagerCore; -import com.intellij.openapi.project.Project; -import javax.annotation.Nullable; - -/** Provides android debuggers and debugger states for blaze projects. */ -public interface BlazeAndroidDebuggerService { - - static BlazeAndroidDebuggerService getInstance(Project project) { - return project.getService(BlazeAndroidDebuggerService.class); - } - - /** Returns the standard debugger for non-native (Java) debugging. */ - AndroidDebugger getDebugger(); - - /** Returns the standard debugger for native (C++) debugging. */ - AndroidDebugger getNativeDebugger(); - - /** - * Performs additional necessary setup for native debugging, incorporating info from {@link - * BlazeAndroidDeployInfo}. - */ - void configureNativeDebugger( - AndroidDebuggerState state, @Nullable BlazeAndroidDeployInfo deployInfo); - - /** Default debugger service. */ - class DefaultDebuggerService implements BlazeAndroidDebuggerService { - private final Project project; - - public DefaultDebuggerService(Project project) { - this.project = project; - } - - @Override - public AndroidDebugger getDebugger() { - return new AndroidJavaDebugger(); - } - - @Override - public AndroidDebugger getNativeDebugger() { - return new BlazeAutoAndroidDebugger(); - } - - @Override - public void configureNativeDebugger( - AndroidDebuggerState rawState, @Nullable BlazeAndroidDeployInfo deployInfo) { - if (!isNdkPluginLoaded() && !(rawState instanceof AutoAndroidDebuggerState)) { - return; - } - AutoAndroidDebuggerState state = (AutoAndroidDebuggerState) rawState; - - // Source code is always relative to the workspace root in a blaze project. - String workingDirPath = WorkspaceRoot.fromProject(project).directory().getPath(); - state.setWorkingDir(workingDirPath); - - // Remote built binaries may use /proc/self/cwd to represent the working directory, - // so we manually map /proc/self/cwd to the workspace root. We used to use - // `plugin.symbol-file.dwarf.comp-dir-symlink-paths = "/proc/self/cwd"` - // to automatically resolve this, but it's no longer supported in newer versions of - // LLDB. - String sourceMapToWorkspaceRootCommand = - "settings append target.source-map /proc/self/cwd/ " + workingDirPath; - - ImmutableList startupCommands = - ImmutableList.builder() - .addAll(state.getUserStartupCommands()) - .add(sourceMapToWorkspaceRootCommand) - .build(); - state.setUserStartupCommands(startupCommands); - - // NDK plugin will pass symbol directories to LLDB as `settings append - // target.exec-search-paths`. - if (deployInfo != null) { - state.setSymbolDirs( - deployInfo.getSymbolFiles().stream() - .map(symbol -> symbol.getParentFile().getAbsolutePath()) - .collect(ImmutableList.toImmutableList())); - } - } - } - - static boolean isNdkPluginLoaded() { - return PluginManagerCore.getLoadedPlugins().stream() - .anyMatch( - d -> d.isEnabled() && d.getPluginId().getIdString().equals("com.android.tools.ndk")); - } -} diff --git a/aswb/sdkcompat/as223/com/google/idea/blaze/android/run/runner/BlazeAndroidLaunchTasksProvider.java b/aswb/sdkcompat/as223/com/google/idea/blaze/android/run/runner/BlazeAndroidLaunchTasksProvider.java deleted file mode 100644 index 4f8d0d3976c..00000000000 --- a/aswb/sdkcompat/as223/com/google/idea/blaze/android/run/runner/BlazeAndroidLaunchTasksProvider.java +++ /dev/null @@ -1,211 +0,0 @@ -/* - * Copyright 2022 The Bazel Authors. All rights reserved. - * - * 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. - */ -package com.google.idea.blaze.android.run.runner; - -import static com.android.tools.idea.profilers.AndroidProfilerLaunchTaskContributor.isProfilerLaunch; - -import com.android.ddmlib.IDevice; -import com.android.tools.deployer.ApkVerifierTracker; -import com.android.tools.idea.editors.literals.LiveEditService; -import com.android.tools.idea.execution.common.debug.AndroidDebugger; -import com.android.tools.idea.execution.common.debug.AndroidDebuggerState; -import com.android.tools.idea.profilers.AndroidProfilerLaunchTaskContributor; -import com.android.tools.idea.run.ApkProvisionException; -import com.android.tools.idea.run.ApplicationIdProvider; -import com.android.tools.idea.run.LaunchOptions; -import com.android.tools.idea.run.blaze.BlazeLaunchTask; -import com.android.tools.idea.run.blaze.BlazeLaunchTaskWrapper; -import com.android.tools.idea.run.blaze.BlazeLaunchTasksProvider; -import com.android.tools.idea.run.deployment.liveedit.LiveEditApp; -import com.android.tools.idea.run.tasks.ClearLogcatTask; -import com.android.tools.idea.run.tasks.ConnectDebuggerTask; -import com.android.tools.idea.run.tasks.DismissKeyguardTask; -import com.android.tools.idea.run.tasks.ShowLogcatTask; -import com.android.tools.idea.run.tasks.StartLiveUpdateMonitoringTask; -import com.android.tools.ndk.run.editor.AutoAndroidDebuggerState; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableSet; -import com.google.common.collect.Lists; -import com.google.idea.blaze.android.run.binary.UserIdHelper; -import com.google.idea.blaze.android.run.deployinfo.BlazeAndroidDeployInfo; -import com.google.idea.common.experiments.BoolExperiment; -import com.intellij.execution.ExecutionException; -import com.intellij.openapi.diagnostic.Logger; -import com.intellij.openapi.project.Project; -import java.nio.file.Path; -import java.util.List; -import java.util.Set; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -/** Normal launch tasks provider. #api4.1 */ -public class BlazeAndroidLaunchTasksProvider implements BlazeLaunchTasksProvider { - public static final String NATIVE_DEBUGGING_ENABLED = "NATIVE_DEBUGGING_ENABLED"; - private static final Logger LOG = Logger.getInstance(BlazeAndroidLaunchTasksProvider.class); - private static final BoolExperiment isLiveEditEnabled = - new BoolExperiment("aswb.live.edit.enabled", false); - - private final Project project; - private final BlazeAndroidRunContext runContext; - private final ApplicationIdProvider applicationIdProvider; - private final LaunchOptions.Builder launchOptionsBuilder; - - public BlazeAndroidLaunchTasksProvider( - Project project, - BlazeAndroidRunContext runContext, - ApplicationIdProvider applicationIdProvider, - LaunchOptions.Builder launchOptionsBuilder) { - this.project = project; - this.runContext = runContext; - this.applicationIdProvider = applicationIdProvider; - this.launchOptionsBuilder = launchOptionsBuilder; - } - - @NotNull - @Override - public List getTasks(@NotNull IDevice device) throws ExecutionException { - final List launchTasks = Lists.newArrayList(); - - String packageName; - try { - packageName = applicationIdProvider.getPackageName(); - } catch (ApkProvisionException e) { - throw new ExecutionException("Unable to determine application id: " + e); - } - - Integer userId = runContext.getUserId(device); - String userIdFlags = UserIdHelper.getFlagsFromUserId(userId); - String skipVerification = - ApkVerifierTracker.getSkipVerificationInstallationFlag(device, packageName); - String pmInstallOption; - if (skipVerification != null) { - pmInstallOption = userIdFlags + " " + skipVerification; - } else { - pmInstallOption = userIdFlags; - } - launchOptionsBuilder.setPmInstallOptions(d -> pmInstallOption); - - LaunchOptions launchOptions = launchOptionsBuilder.build(); - - // NOTE: Task for opening the profiler tool-window should come before deployment - // to ensure the tool-window opens correctly. This is required because starting - // the profiler session requires the tool-window to be open. - if (isProfilerLaunch(runContext.getExecutor())) { - launchTasks.add(new BlazeAndroidOpenProfilerWindowTask(project)); - } - - // TODO(kovalp): Check if there's any drawback to add these tasks with BlazeLaunchTaskWrapper - // since it's different with ag/21610897 - if (launchOptions.isClearLogcatBeforeStart()) { - launchTasks.add(new BlazeLaunchTaskWrapper(new ClearLogcatTask(project))); - } - - launchTasks.add(new BlazeLaunchTaskWrapper(new DismissKeyguardTask())); - - if (launchOptions.isDeploy()) { - ImmutableList deployTasks = runContext.getDeployTasks(device, launchOptions); - launchTasks.addAll(deployTasks); - } - - try { - if (launchOptions.isDebug()) { - launchTasks.add( - new CheckApkDebuggableTask(project, runContext.getBuildStep().getDeployInfo())); - } - - ImmutableList.Builder amStartOptions = ImmutableList.builder(); - amStartOptions.add(runContext.getAmStartOptions()); - if (isProfilerLaunch(runContext.getExecutor())) { - amStartOptions.add( - AndroidProfilerLaunchTaskContributor.getAmStartOptions( - project, - packageName, - runContext.getProfileState(), - device, - runContext.getExecutor())); - launchTasks.add( - new BlazeLaunchTaskWrapper( - new AndroidProfilerLaunchTaskContributor.AndroidProfilerToolWindowLaunchTask( - project, packageName))); - } - BlazeLaunchTask appLaunchTask = - runContext.getApplicationLaunchTask( - launchOptions, userId, String.join(" ", amStartOptions.build())); - if (appLaunchTask != null) { - launchTasks.add(appLaunchTask); - if (isLiveEditEnabled.getValue()) { - // TODO(b/277244508): Fix Live Edit for Giraffe - Set apks = - runContext.getBuildStep().getDeployInfo().getApksToDeploy().stream() - .map(f -> f.toPath()) - .collect(ImmutableSet.toImmutableSet()); - - LiveEditApp app = new LiveEditApp(apks, device.getVersion().getApiLevel()); - launchTasks.add( - new BlazeLaunchTaskWrapper( - new StartLiveUpdateMonitoringTask( - () -> - LiveEditService.getInstance(project) - .getDeployMonitor() - .notifyAppDeploy(packageName, device, app)))); - } - } - } catch (ApkProvisionException e) { - throw new ExecutionException("Unable to determine application id: " + e); - } - - if (launchOptions.isOpenLogcatAutomatically()) { - launchTasks.add(new BlazeLaunchTaskWrapper(new ShowLogcatTask(project, packageName))); - } - - return ImmutableList.copyOf(launchTasks); - } - - @Override - @Nullable - public ConnectDebuggerTask getConnectDebuggerTask() { - LaunchOptions launchOptions = launchOptionsBuilder.build(); - if (!launchOptions.isDebug()) { - return null; - } - - BlazeAndroidDeployInfo deployInfo; - try { - deployInfo = runContext.getBuildStep().getDeployInfo(); - } catch (ApkProvisionException e) { - LOG.error(e); - deployInfo = null; - } - - BlazeAndroidDebuggerService debuggerService = BlazeAndroidDebuggerService.getInstance(project); - if (isNativeDebuggingEnabled(launchOptions)) { - AndroidDebugger debugger = debuggerService.getNativeDebugger(); - // The below state type should be AutoAndroidDebuggerState, but referencing it will crash the - // task if the NDK plugin is not loaded. - AndroidDebuggerState state = debugger.createState(); - debuggerService.configureNativeDebugger(state, deployInfo); - return runContext.getDebuggerTask(debugger, state); - } else { - AndroidDebugger debugger = debuggerService.getDebugger(); - return runContext.getDebuggerTask(debugger, debugger.createState()); - } - } - - private boolean isNativeDebuggingEnabled(LaunchOptions launchOptions) { - Object flag = launchOptions.getExtraOption(NATIVE_DEBUGGING_ENABLED); - return flag instanceof Boolean && (Boolean) flag; - } -} diff --git a/aswb/sdkcompat/as223/com/google/idea/blaze/android/run/runner/BlazeAndroidRunConfigurationRunner.java b/aswb/sdkcompat/as223/com/google/idea/blaze/android/run/runner/BlazeAndroidRunConfigurationRunner.java deleted file mode 100644 index 78728d9c46f..00000000000 --- a/aswb/sdkcompat/as223/com/google/idea/blaze/android/run/runner/BlazeAndroidRunConfigurationRunner.java +++ /dev/null @@ -1,327 +0,0 @@ -/* - * Copyright 2016 The Bazel Authors. All rights reserved. - * - * 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. - */ - -package com.google.idea.blaze.android.run.runner; - -import com.android.ddmlib.IDevice; -import com.android.tools.idea.execution.common.AppRunSettings; -import com.android.tools.idea.execution.common.ApplicationDeployer; -import com.android.tools.idea.execution.common.ComponentLaunchOptions; -import com.android.tools.idea.execution.common.DeployOptions; -import com.android.tools.idea.run.ApkProvider; -import com.android.tools.idea.run.ApplicationIdProvider; -import com.android.tools.idea.run.DeviceFutures; -import com.android.tools.idea.run.LaunchOptions; -import com.android.tools.idea.run.blaze.BlazeAndroidConfigurationExecutor; -import com.android.tools.idea.run.configuration.execution.AndroidComplicationConfigurationExecutor; -import com.android.tools.idea.run.configuration.execution.AndroidConfigurationExecutor; -import com.android.tools.idea.run.configuration.execution.AndroidConfigurationExecutorRunProfileState; -import com.android.tools.idea.run.configuration.execution.AndroidTileConfigurationExecutor; -import com.android.tools.idea.run.configuration.execution.AndroidWatchFaceConfigurationExecutor; -import com.android.tools.idea.run.configuration.execution.ComplicationLaunchOptions; -import com.android.tools.idea.run.configuration.execution.TileLaunchOptions; -import com.android.tools.idea.run.configuration.execution.WatchFaceLaunchOptions; -import com.android.tools.idea.run.editor.DeployTarget; -import com.android.tools.idea.run.editor.DeployTargetState; -import com.android.tools.idea.run.util.LaunchUtils; -import com.google.common.util.concurrent.Futures; -import com.google.common.util.concurrent.ListenableFuture; -import com.google.idea.blaze.android.run.binary.mobileinstall.MobileInstallBuildStep; -import com.google.idea.blaze.android.run.deployinfo.BlazeApkProviderService; -import com.google.idea.blaze.base.async.executor.ProgressiveTaskWithProgressIndicator; -import com.google.idea.blaze.base.command.BlazeInvocationContext.ContextType; -import com.google.idea.blaze.base.experiments.ExperimentScope; -import com.google.idea.blaze.base.issueparser.BlazeIssueParser; -import com.google.idea.blaze.base.model.primitives.WorkspaceRoot; -import com.google.idea.blaze.base.run.BlazeCommandRunConfiguration; -import com.google.idea.blaze.base.run.confighandler.BlazeCommandRunConfigurationRunner; -import com.google.idea.blaze.base.scope.BlazeContext; -import com.google.idea.blaze.base.scope.Scope; -import com.google.idea.blaze.base.scope.ScopedTask; -import com.google.idea.blaze.base.scope.output.IssueOutput; -import com.google.idea.blaze.base.scope.scopes.IdeaLogScope; -import com.google.idea.blaze.base.scope.scopes.ProblemsViewScope; -import com.google.idea.blaze.base.scope.scopes.ToolWindowScope; -import com.google.idea.blaze.base.settings.Blaze; -import com.google.idea.blaze.base.settings.BlazeUserSettings; -import com.google.idea.blaze.base.toolwindow.Task; -import com.intellij.execution.ExecutionException; -import com.intellij.execution.Executor; -import com.intellij.execution.configurations.RunProfileState; -import com.intellij.execution.executors.DefaultDebugExecutor; -import com.intellij.execution.runners.ExecutionEnvironment; -import com.intellij.execution.ui.ConsoleView; -import com.intellij.openapi.diagnostic.Logger; -import com.intellij.openapi.module.Module; -import com.intellij.openapi.project.Project; -import com.intellij.openapi.util.Key; -import java.util.Collections; -import java.util.concurrent.CancellationException; -import javax.annotation.Nullable; -import org.jetbrains.android.facet.AndroidFacet; -import org.jetbrains.android.util.AndroidBundle; -import org.jetbrains.annotations.NotNull; - -/** - * Supports the execution. Used by both android_binary and android_test. - * - *

Builds the APK and installs it, launches and debug tasks, etc. - * - *

Any indirection between android_binary/android_test, mobile-install, InstantRun etc. should - * come via the strategy class. - */ -public final class BlazeAndroidRunConfigurationRunner - implements BlazeCommandRunConfigurationRunner { - - private static final Logger LOG = Logger.getInstance(BlazeAndroidRunConfigurationRunner.class); - - private static final Key RUN_CONTEXT_KEY = - Key.create("blaze.run.context"); - public static final Key DEVICE_SESSION_KEY = - Key.create("blaze.device.session"); - - private final Module module; - private final BlazeAndroidRunContext runContext; - private final BlazeCommandRunConfiguration runConfig; - - public BlazeAndroidRunConfigurationRunner( - Module module, BlazeAndroidRunContext runContext, BlazeCommandRunConfiguration runConfig) { - this.module = module; - this.runContext = runContext; - this.runConfig = runConfig; - } - - @Override - @Nullable - public final RunProfileState getRunProfileState(final Executor executor, ExecutionEnvironment env) - throws ExecutionException { - - final AndroidFacet facet = AndroidFacet.getInstance(module); - assert facet != null : "Enforced by fatal validation check in createRunner."; - final Project project = env.getProject(); - - boolean isDebug = executor instanceof DefaultDebugExecutor; - - BlazeAndroidDeviceSelector deviceSelector = runContext.getDeviceSelector(); - BlazeAndroidDeviceSelector.DeviceSession deviceSession = - deviceSelector.getDevice(project, executor, env, isDebug, runConfig.getUniqueID()); - - if (deviceSession == null) { - return null; - } - - DeployTarget deployTarget = deviceSession.deployTarget; - if (deployTarget != null && deployTarget.hasCustomRunProfileState(executor)) { - return deployTarget.getRunProfileState(executor, env, DeployTargetState.DEFAULT_STATE); - } - - DeviceFutures deviceFutures = deviceSession.deviceFutures; - if (deviceFutures == null) { - // The user deliberately canceled, or some error was encountered and exposed by the chooser. - // Quietly exit. - return null; - } - - if (deviceFutures.get().isEmpty()) { - throw new ExecutionException(AndroidBundle.message("deployment.target.not.found")); - } - - if (isDebug) { - String error = canDebug(deviceFutures, facet, module.getName()); - if (error != null) { - throw new ExecutionException(error); - } - } - - LaunchOptions.Builder launchOptionsBuilder = getDefaultLaunchOptions().setDebug(isDebug); - runContext.augmentLaunchOptions(launchOptionsBuilder); - - // Store the run context on the execution environment so before-run tasks can access it. - env.putCopyableUserData(RUN_CONTEXT_KEY, runContext); - env.putCopyableUserData(DEVICE_SESSION_KEY, deviceSession); - - BlazeAndroidConfigurationExecutor runner = - new BlazeAndroidConfigurationExecutor( - runContext.getConsoleProvider(), - runContext.getApplicationIdProvider(), - env, - deviceFutures, - runContext.getLaunchTasksProvider(launchOptionsBuilder), - LaunchOptions.builder().build()); - return new AndroidConfigurationExecutorRunProfileState(runner); - } - - private RunProfileState getWearExecutor( - ComponentLaunchOptions launchOptions, ExecutionEnvironment env, DeployTarget deployTarget) - throws ExecutionException { - - AppRunSettings settings = - new AppRunSettings() { - @NotNull - @Override - public DeployOptions getDeployOptions() { - return new DeployOptions(Collections.emptyList(), "", true, true); - } - - @NotNull - @Override - public ComponentLaunchOptions getComponentLaunchOptions() { - return launchOptions; - } - - @Override - public Module getModule() { - return runConfig.getModules()[0]; - } - }; - - AndroidConfigurationExecutor configurationExecutor; - ApplicationIdProvider appIdProvider = runContext.getApplicationIdProvider(); - ApkProvider apkProvider = - BlazeApkProviderService.getInstance() - .getApkProvider(env.getProject(), runContext.getBuildStep()); - DeviceFutures deviceFutures = deployTarget.getDevices(env.getProject()); - - if (launchOptions instanceof TileLaunchOptions) { - configurationExecutor = - new AndroidTileConfigurationExecutor( - env, deviceFutures, settings, appIdProvider, apkProvider) { - @NotNull - @Override - public ApplicationDeployer getApplicationDeployer(@NotNull ConsoleView console) - throws ExecutionException { - if (runContext.getBuildStep() instanceof MobileInstallBuildStep) { - return new MobileInstallApplicationDeployer(console); - } - return super.getApplicationDeployer(console); - } - }; - } else if (launchOptions instanceof WatchFaceLaunchOptions) { - configurationExecutor = - new AndroidWatchFaceConfigurationExecutor( - env, deviceFutures, settings, appIdProvider, apkProvider) { - @NotNull - @Override - public ApplicationDeployer getApplicationDeployer(@NotNull ConsoleView console) - throws ExecutionException { - if (runContext.getBuildStep() instanceof MobileInstallBuildStep) { - return new MobileInstallApplicationDeployer(console); - } - return super.getApplicationDeployer(console); - } - }; - } else if (launchOptions instanceof ComplicationLaunchOptions) { - configurationExecutor = - new AndroidComplicationConfigurationExecutor( - env, deviceFutures, settings, appIdProvider, apkProvider) { - @NotNull - @Override - public ApplicationDeployer getApplicationDeployer(@NotNull ConsoleView console) - throws ExecutionException { - if (runContext.getBuildStep() instanceof MobileInstallBuildStep) { - return new MobileInstallApplicationDeployer(console); - } - return super.getApplicationDeployer(console); - } - }; - } else { - throw new RuntimeException("Unknown launch options " + launchOptions.getClass().getName()); - } - - return new AndroidConfigurationExecutorRunProfileState( - new BlazeWrapperForAndroidConfigurationExecutor(configurationExecutor)); - } - - @Nullable - private static String canDebug( - DeviceFutures deviceFutures, AndroidFacet facet, String moduleName) { - // If we are debugging on a device, then the app needs to be debuggable - for (ListenableFuture future : deviceFutures.get()) { - if (!future.isDone()) { - // this is an emulator, and we assume that all emulators are debuggable - continue; - } - IDevice device = Futures.getUnchecked(future); - if (!LaunchUtils.canDebugAppOnDevice(facet, device)) { - return AndroidBundle.message( - "android.cannot.debug.noDebugPermissions", moduleName, device.getName()); - } - } - return null; - } - - private static LaunchOptions.Builder getDefaultLaunchOptions() { - return LaunchOptionsCompat.getDefaultLaunchOptions(); - } - - @Override - public boolean executeBeforeRunTask(ExecutionEnvironment env) { - final Project project = env.getProject(); - BlazeUserSettings settings = BlazeUserSettings.getInstance(); - return Scope.root( - context -> { - context - .push(new ProblemsViewScope(project, settings.getShowProblemsViewOnRun())) - .push(new ExperimentScope()) - .push( - new ToolWindowScope.Builder( - project, new Task(project, "Build apk", Task.Type.BEFORE_LAUNCH)) - .setPopupBehavior(settings.getShowBlazeConsoleOnRun()) - .setIssueParsers( - BlazeIssueParser.defaultIssueParsers( - project, - WorkspaceRoot.fromProject(project), - ContextType.BeforeRunTask)) - .build()) - .push(new IdeaLogScope()); - - BlazeAndroidRunContext runContext = env.getCopyableUserData(RUN_CONTEXT_KEY); - if (runContext == null) { - IssueOutput.error("Could not find run context. Please try again").submit(context); - return false; - } - BlazeAndroidDeviceSelector.DeviceSession deviceSession = - env.getCopyableUserData(DEVICE_SESSION_KEY); - - ApkBuildStep buildStep = runContext.getBuildStep(); - ScopedTask buildTask = - new ScopedTask(context) { - @Override - protected Void execute(BlazeContext context) { - buildStep.build(context, deviceSession); - return null; - } - }; - - try { - ListenableFuture buildFuture = - ProgressiveTaskWithProgressIndicator.builder( - project, - String.format("Executing %s apk build", Blaze.buildSystemName(project))) - .submitTaskWithResult(buildTask); - Futures.getChecked(buildFuture, ExecutionException.class); - } catch (ExecutionException e) { - context.setHasError(); - } catch (CancellationException e) { - context.setCancelled(); - } catch (Exception e) { - LOG.error(e); - return false; - } - return context.shouldContinue(); - }); - } -} diff --git a/aswb/sdkcompat/as223/com/google/idea/blaze/android/run/runner/BlazeAndroidRunContext.java b/aswb/sdkcompat/as223/com/google/idea/blaze/android/run/runner/BlazeAndroidRunContext.java deleted file mode 100644 index c1e33020bae..00000000000 --- a/aswb/sdkcompat/as223/com/google/idea/blaze/android/run/runner/BlazeAndroidRunContext.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright 2016 The Bazel Authors. All rights reserved. - * - * 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. - */ -package com.google.idea.blaze.android.run.runner; - -import com.android.ddmlib.IDevice; -import com.android.tools.idea.execution.common.debug.AndroidDebugger; -import com.android.tools.idea.execution.common.debug.AndroidDebuggerState; -import com.android.tools.idea.run.ApplicationIdProvider; -import com.android.tools.idea.run.ConsoleProvider; -import com.android.tools.idea.run.LaunchOptions; -import com.android.tools.idea.run.blaze.BlazeLaunchTask; -import com.android.tools.idea.run.blaze.BlazeLaunchTasksProvider; -import com.android.tools.idea.run.editor.ProfilerState; -import com.android.tools.idea.run.tasks.ConnectDebuggerTask; -import com.google.common.collect.ImmutableList; -import com.intellij.execution.ExecutionException; -import com.intellij.execution.Executor; -import javax.annotation.Nullable; -import org.jetbrains.annotations.NotNull; - -/** Instantiated when the configuration wants to run. */ -public interface BlazeAndroidRunContext { - - BlazeAndroidDeviceSelector getDeviceSelector(); - - void augmentLaunchOptions(LaunchOptions.Builder options); - - ConsoleProvider getConsoleProvider(); - - ApkBuildStep getBuildStep(); - - ApplicationIdProvider getApplicationIdProvider() throws ExecutionException; - - BlazeLaunchTasksProvider getLaunchTasksProvider(LaunchOptions.Builder launchOptionsBuilder) - throws ExecutionException; - - /** Returns the tasks to deploy the application. */ - ImmutableList getDeployTasks(IDevice device, LaunchOptions launchOptions) - throws ExecutionException; - - /** Returns the task to launch the application. */ - @Nullable - BlazeLaunchTask getApplicationLaunchTask( - LaunchOptions launchOptions, - @Nullable Integer userId, - @NotNull String contributorsAmStartOptions) - throws ExecutionException; - - /** Returns the task to connect the debugger. */ - @Nullable - ConnectDebuggerTask getDebuggerTask( - AndroidDebugger androidDebugger, AndroidDebuggerState androidDebuggerState); - - @Nullable - Integer getUserId(IDevice device) throws ExecutionException; - - String getAmStartOptions(); - - Executor getExecutor(); - - ProfilerState getProfileState(); -} diff --git a/aswb/sdkcompat/as223/com/google/idea/blaze/android/run/runner/BlazeWrapperForAndroidConfigurationExecutor.java b/aswb/sdkcompat/as223/com/google/idea/blaze/android/run/runner/BlazeWrapperForAndroidConfigurationExecutor.java deleted file mode 100644 index be6f1f8552c..00000000000 --- a/aswb/sdkcompat/as223/com/google/idea/blaze/android/run/runner/BlazeWrapperForAndroidConfigurationExecutor.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright (C) 2022 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. - */ -package com.google.idea.blaze.android.run.runner; - -import com.android.tools.idea.run.DeviceFutures; -import com.android.tools.idea.run.configuration.execution.AndroidConfigurationExecutor; -import com.intellij.execution.ExecutionException; -import com.intellij.execution.configurations.RunConfiguration; -import com.intellij.execution.ui.RunContentDescriptor; -import com.intellij.openapi.progress.ProgressIndicator; -import org.jetbrains.annotations.NotNull; - -/** Implementation of {@code AndroidConfigurationExecutor} specific for Blaze project. */ -public class BlazeWrapperForAndroidConfigurationExecutor implements AndroidConfigurationExecutor { - private final AndroidConfigurationExecutor delegateExecutor; - - BlazeWrapperForAndroidConfigurationExecutor(@NotNull AndroidConfigurationExecutor executor) { - delegateExecutor = executor; - } - - @NotNull - @Override - public RunConfiguration getConfiguration() { - return delegateExecutor.getConfiguration(); - } - - @NotNull - @Override - public DeviceFutures getDeviceFutures() { - return delegateExecutor.getDeviceFutures(); - } - - @NotNull - @Override - public RunContentDescriptor run(@NotNull ProgressIndicator indicator) throws ExecutionException { - return delegateExecutor.run(indicator); - } - - @NotNull - @Override - public RunContentDescriptor debug(@NotNull ProgressIndicator indicator) - throws ExecutionException { - return delegateExecutor.debug(indicator); - } - - @NotNull - @Override - public RunContentDescriptor applyChanges(@NotNull ProgressIndicator indicator) { - throw new RuntimeException("Apply code changes is not supported for blaze"); - } - - @NotNull - @Override - public RunContentDescriptor applyCodeChanges(@NotNull ProgressIndicator indicator) { - throw new RuntimeException("Apply changes is not supported for blaze"); - } -} diff --git a/aswb/sdkcompat/as223/com/google/idea/blaze/android/run/runner/LaunchOptionsCompat.java b/aswb/sdkcompat/as223/com/google/idea/blaze/android/run/runner/LaunchOptionsCompat.java deleted file mode 100644 index 5a606a8a2ea..00000000000 --- a/aswb/sdkcompat/as223/com/google/idea/blaze/android/run/runner/LaunchOptionsCompat.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright 2022 The Bazel Authors. All rights reserved. - * - * 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. - */ -package com.google.idea.blaze.android.run.runner; - -import com.android.tools.idea.run.LaunchOptions; - -/** Compat class for LunchOptions.Builder. */ -public class LaunchOptionsCompat { - - private LaunchOptionsCompat() {} - - /** Create default launch options to maintain compatibility with #api211. */ - public static LaunchOptions.Builder getDefaultLaunchOptions() { - return LaunchOptions.builder().setClearLogcatBeforeStart(false); - } -} diff --git a/aswb/sdkcompat/as223/com/google/idea/blaze/android/run/runner/MobileInstallApplicationDeployer.java b/aswb/sdkcompat/as223/com/google/idea/blaze/android/run/runner/MobileInstallApplicationDeployer.java deleted file mode 100644 index dad762309be..00000000000 --- a/aswb/sdkcompat/as223/com/google/idea/blaze/android/run/runner/MobileInstallApplicationDeployer.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright (C) 2022 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. - */ -package com.google.idea.blaze.android.run.runner; - -import com.android.ddmlib.IDevice; -import com.android.tools.deployer.ApkParser; -import com.android.tools.deployer.Deployer; -import com.android.tools.deployer.DeployerException; -import com.android.tools.deployer.model.Apk; -import com.android.tools.deployer.model.App; -import com.android.tools.idea.execution.common.ApplicationDeployer; -import com.android.tools.idea.execution.common.DeployOptions; -import com.android.tools.idea.run.ApkFileUnit; -import com.android.tools.idea.run.ApkInfo; -import com.android.tools.idea.run.configuration.execution.AdbCommandCaptureLoggerWithConsole; -import com.intellij.execution.ui.ConsoleView; -import com.intellij.openapi.diagnostic.Logger; -import com.intellij.openapi.progress.ProgressIndicator; -import java.nio.file.Path; -import java.util.List; -import java.util.stream.Collectors; -import org.jetbrains.annotations.NotNull; - -/** Deploys mobile install application. */ -public class MobileInstallApplicationDeployer implements ApplicationDeployer { - private static final Logger LOG = Logger.getInstance(MobileInstallApplicationDeployer.class); - private final ConsoleView myConsole; - - public MobileInstallApplicationDeployer(ConsoleView console) { - myConsole = console; - } - - @NotNull - @Override - public Deployer.Result fullDeploy( - @NotNull IDevice device, - @NotNull ApkInfo apkInfo, - @NotNull DeployOptions deployOptions, - ProgressIndicator indicator) - throws DeployerException { - final List apkPaths = - apkInfo.getFiles().stream() - .map(ApkFileUnit::getApkPath) - .map(Path::toString) - .collect(Collectors.toList()); - final List apks = new ApkParser().parsePaths(apkPaths); - App app = - new App( - apkInfo.getApplicationId(), - apks, - device, - new AdbCommandCaptureLoggerWithConsole(LOG, myConsole)); - return new Deployer.Result(false, false, false, app); - } - - @NotNull - @Override - public Deployer.Result applyChangesDeploy( - @NotNull IDevice device, - @NotNull ApkInfo app, - @NotNull DeployOptions deployOptions, - ProgressIndicator indicator) - throws DeployerException { - throw new RuntimeException("Apply changes is not supported for mobile-install"); - } - - @NotNull - @Override - public Deployer.Result applyCodeChangesDeploy( - @NotNull IDevice device, - @NotNull ApkInfo app, - @NotNull DeployOptions deployOptions, - ProgressIndicator indicator) - throws DeployerException { - throw new RuntimeException("Apply code changes is not supported for mobile-install"); - } -} diff --git a/aswb/sdkcompat/as223/com/google/idea/blaze/android/run/test/BlazeAndroidTestProgramRunner.java b/aswb/sdkcompat/as223/com/google/idea/blaze/android/run/test/BlazeAndroidTestProgramRunner.java deleted file mode 100644 index eab7b24890f..00000000000 --- a/aswb/sdkcompat/as223/com/google/idea/blaze/android/run/test/BlazeAndroidTestProgramRunner.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright 2018 The Bazel Authors. All rights reserved. - * - * 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. - */ -package com.google.idea.blaze.android.run.test; - -import com.android.tools.idea.run.configuration.AndroidConfigurationProgramRunner; -import com.android.tools.idea.run.configuration.execution.AndroidConfigurationExecutor; -import com.google.idea.blaze.android.run.BlazeAndroidRunConfigurationHandler; -import com.google.idea.blaze.base.run.BlazeCommandRunConfiguration; -import com.google.idea.blaze.base.run.BlazeCommandRunConfigurationType; -import com.intellij.execution.ExecutionException; -import com.intellij.execution.configurations.RunProfile; -import com.intellij.execution.configurations.RunProfileState; -import com.intellij.execution.executors.DefaultDebugExecutor; -import com.intellij.execution.executors.DefaultRunExecutor; -import com.intellij.execution.runners.ExecutionEnvironment; -import com.intellij.execution.ui.RunContentDescriptor; -import com.intellij.openapi.progress.ProgressIndicator; -import java.util.Collections; -import java.util.List; -import org.jetbrains.annotations.NotNull; - -/** Program runner for configurations from {@link BlazeAndroidTestRunConfigurationHandler}. */ -public class BlazeAndroidTestProgramRunner extends AndroidConfigurationProgramRunner { - @Override - public boolean canRun(String executorId, RunProfile profile) { - BlazeAndroidRunConfigurationHandler handler = - BlazeAndroidRunConfigurationHandler.getHandlerFrom(profile); - if (!(handler instanceof BlazeAndroidTestRunConfigurationHandler)) { - return false; - } - if (!(profile instanceof BlazeCommandRunConfiguration)) { - return false; - } - return DefaultRunExecutor.EXECUTOR_ID.equals(executorId) - || DefaultDebugExecutor.EXECUTOR_ID.equals(executorId); - } - - @Override - public String getRunnerId() { - return "AndroidTestProgramRunner"; - } - - @Override - protected boolean canRunWithMultipleDevices(@NotNull String executorId) { - return true; - } - - @NotNull - @Override - protected List getSupportedConfigurationTypeIds() { - return Collections.singletonList(BlazeCommandRunConfigurationType.getInstance().getId()); - } - - @NotNull - @Override - protected RunContentDescriptor run( - @NotNull ExecutionEnvironment environment, - @NotNull RunProfileState state, - @NotNull ProgressIndicator indicator) - throws ExecutionException { - final AndroidConfigurationExecutor state1 = (AndroidConfigurationExecutor) state; - if (DefaultDebugExecutor.EXECUTOR_ID.equals(environment.getExecutor().getId())) { - return state1.debug(indicator); - } - if (DefaultRunExecutor.EXECUTOR_ID.equals(environment.getExecutor().getId())) { - return state1.run(indicator); - } - throw new RuntimeException("Unsupported executor"); - } -} diff --git a/aswb/sdkcompat/as223/com/google/idea/blaze/android/run/test/BlazeAndroidTestRunConfigurationHandler.java b/aswb/sdkcompat/as223/com/google/idea/blaze/android/run/test/BlazeAndroidTestRunConfigurationHandler.java deleted file mode 100644 index 050ddc03fee..00000000000 --- a/aswb/sdkcompat/as223/com/google/idea/blaze/android/run/test/BlazeAndroidTestRunConfigurationHandler.java +++ /dev/null @@ -1,224 +0,0 @@ -/* - * Copyright 2016 The Bazel Authors. All rights reserved. - * - * 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. - */ -package com.google.idea.blaze.android.run.test; - -import static com.android.tools.idea.run.deployment.DeviceAndSnapshotComboBoxAction.DEPLOYS_TO_LOCAL_DEVICE; - -import com.android.tools.idea.run.ValidationError; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.Lists; -import com.google.idea.blaze.android.run.ApkBuildStepProvider; -import com.google.idea.blaze.android.run.BlazeAndroidRunConfigurationCommonState; -import com.google.idea.blaze.android.run.BlazeAndroidRunConfigurationHandler; -import com.google.idea.blaze.android.run.BlazeAndroidRunConfigurationValidationUtil; -import com.google.idea.blaze.android.run.LaunchMetrics; -import com.google.idea.blaze.android.run.runner.ApkBuildStep; -import com.google.idea.blaze.android.run.runner.BlazeAndroidRunConfigurationRunner; -import com.google.idea.blaze.android.run.runner.BlazeAndroidRunContext; -import com.google.idea.blaze.android.run.runner.FullApkBuildStep; -import com.google.idea.blaze.android.run.test.BlazeAndroidTestLaunchMethodsProvider.AndroidTestLaunchMethod; -import com.google.idea.blaze.base.command.BlazeCommandName; -import com.google.idea.blaze.base.command.BlazeInvocationContext; -import com.google.idea.blaze.base.model.primitives.Label; -import com.google.idea.blaze.base.model.primitives.TargetExpression; -import com.google.idea.blaze.base.projectview.ProjectViewManager; -import com.google.idea.blaze.base.projectview.ProjectViewSet; -import com.google.idea.blaze.base.run.BlazeCommandRunConfiguration; -import com.google.idea.blaze.base.run.BlazeConfigurationNameBuilder; -import com.google.idea.blaze.base.run.ExecutorType; -import com.google.idea.blaze.base.run.confighandler.BlazeCommandRunConfigurationRunner; -import com.google.idea.blaze.base.settings.Blaze; -import com.google.idea.blaze.base.sync.data.BlazeDataStorage; -import com.google.idea.blaze.base.sync.projectstructure.ModuleFinder; -import com.google.idea.blaze.java.AndroidBlazeRules; -import com.intellij.execution.ExecutionException; -import com.intellij.execution.Executor; -import com.intellij.execution.JavaExecutionUtil; -import com.intellij.execution.configurations.RuntimeConfigurationException; -import com.intellij.execution.runners.ExecutionEnvironment; -import com.intellij.openapi.module.Module; -import com.intellij.openapi.project.Project; -import java.util.List; -import javax.annotation.Nullable; -import org.jetbrains.android.facet.AndroidFacet; - -/** - * {@link com.google.idea.blaze.base.run.confighandler.BlazeCommandRunConfigurationHandler} for - * android_test targets. - */ -public class BlazeAndroidTestRunConfigurationHandler - implements BlazeAndroidRunConfigurationHandler { - private final Project project; - private final BlazeAndroidTestRunConfigurationState configState; - - BlazeAndroidTestRunConfigurationHandler(BlazeCommandRunConfiguration configuration) { - this.project = configuration.getProject(); - this.configState = - new BlazeAndroidTestRunConfigurationState( - Blaze.buildSystemName(configuration.getProject())); - configuration.putUserData(DEPLOYS_TO_LOCAL_DEVICE, true); - } - - @Override - public BlazeAndroidTestRunConfigurationState getState() { - return configState; - } - - @Override - public BlazeAndroidRunConfigurationCommonState getCommonState() { - return configState.getCommonState(); - } - - @Override - public BlazeCommandRunConfigurationRunner createRunner( - Executor executor, ExecutionEnvironment env) throws ExecutionException { - Project project = env.getProject(); - BlazeCommandRunConfiguration configuration = - BlazeAndroidRunConfigurationHandler.getCommandConfig(env); - - BlazeAndroidRunConfigurationValidationUtil.validate(project); - Module module = - ModuleFinder.getInstance(env.getProject()) - .findModuleByName(BlazeDataStorage.WORKSPACE_MODULE_NAME); - AndroidFacet facet = module != null ? AndroidFacet.getInstance(module) : null; - ProjectViewSet projectViewSet = ProjectViewManager.getInstance(project).getProjectViewSet(); - - ImmutableList blazeFlags = - configState - .getCommonState() - .getExpandedBuildFlags( - project, - projectViewSet, - BlazeCommandName.TEST, - BlazeInvocationContext.runConfigContext( - ExecutorType.fromExecutor(env.getExecutor()), configuration.getType(), false)); - ImmutableList exeFlags = - ImmutableList.copyOf( - configState.getCommonState().getExeFlagsState().getFlagsForExternalProcesses()); - - // We collect metrics from a few different locations. In order to tie them all - // together, we create a unique launch id. - String launchId = LaunchMetrics.newLaunchId(); - Label label = Label.create(configuration.getSingleTarget().toString()); - - ApkBuildStep buildStep = - getTestBuildStep( - project, configState, configuration, blazeFlags, exeFlags, launchId, label); - - BlazeAndroidRunContext runContext = - new BlazeAndroidTestRunContext( - project, facet, configuration, env, configState, label, blazeFlags, buildStep); - - LaunchMetrics.logTestLaunch( - launchId, configState.getLaunchMethod().name(), env.getExecutor().getId()); - - return new BlazeAndroidRunConfigurationRunner(module, runContext, configuration); - } - - private static ApkBuildStep getTestBuildStep( - Project project, - BlazeAndroidTestRunConfigurationState configState, - BlazeCommandRunConfiguration configuration, - ImmutableList blazeFlags, - ImmutableList exeFlags, - String launchId, - Label label) - throws ExecutionException { - if (configuration.getTargetKind() - == AndroidBlazeRules.RuleTypes.ANDROID_INSTRUMENTATION_TEST.getKind()) { - boolean useMobileInstall = - AndroidTestLaunchMethod.MOBILE_INSTALL.equals(configState.getLaunchMethod()); - return ApkBuildStepProvider.getInstance(Blaze.getBuildSystemName(project)) - .getAitBuildStep( - project, - useMobileInstall, - /* nativeDebuggingEnabled= */ false, - label, - blazeFlags, - exeFlags, - launchId); - } else { - // TODO(b/248317444): This path is only invoked for the deprecated {@code android_test} - // targets, and should eventually be removed. - return new FullApkBuildStep(project, label, blazeFlags, /* nativeDebuggingEnabled= */ false); - } - } - - @Override - public final void checkConfiguration() throws RuntimeConfigurationException { - BlazeAndroidRunConfigurationValidationUtil.throwTopConfigurationError(validate()); - } - - /** - * We collect errors rather than throwing to avoid missing fatal errors by exiting early for a - * warning. We use a separate method for the collection so the compiler prevents us from - * accidentally throwing. - */ - private List validate() { - List errors = Lists.newArrayList(); - errors.addAll(BlazeAndroidRunConfigurationValidationUtil.validateWorkspaceModule(project)); - errors.addAll(configState.validate(project)); - return errors; - } - - @Override - @Nullable - public String suggestedName(BlazeCommandRunConfiguration configuration) { - TargetExpression target = configuration.getSingleTarget(); - if (target == null) { - return null; - } - BlazeConfigurationNameBuilder nameBuilder = new BlazeConfigurationNameBuilder(configuration); - - boolean isClassTest = - configState.getTestingType() == BlazeAndroidTestRunConfigurationState.TEST_CLASS; - boolean isMethodTest = - configState.getTestingType() == BlazeAndroidTestRunConfigurationState.TEST_METHOD; - if ((isClassTest || isMethodTest) && configState.getClassName() != null) { - // Get the class name without the package. - String className = JavaExecutionUtil.getPresentableClassName(configState.getClassName()); - if (className != null) { - String targetString = className; - if (isMethodTest) { - targetString += "#" + configState.getMethodName(); - } - - if (getState().getLaunchMethod().equals(AndroidTestLaunchMethod.NON_BLAZE)) { - return targetString; - } else { - return nameBuilder.setTargetString(targetString).build(); - } - } - } - return nameBuilder.build(); - } - - @Override - @Nullable - public BlazeCommandName getCommandName() { - if (getState().getLaunchMethod().equals(AndroidTestLaunchMethod.BLAZE_TEST)) { - return BlazeCommandName.TEST; - } else if (getState().getLaunchMethod().equals(AndroidTestLaunchMethod.MOBILE_INSTALL)) { - return BlazeCommandName.MOBILE_INSTALL; - } - return null; - } - - @Override - public String getHandlerName() { - return "Android Test Handler"; - } -} diff --git a/aswb/sdkcompat/as223/com/google/idea/blaze/android/run/test/BlazeAndroidTestRunContext.java b/aswb/sdkcompat/as223/com/google/idea/blaze/android/run/test/BlazeAndroidTestRunContext.java deleted file mode 100644 index feaec07157c..00000000000 --- a/aswb/sdkcompat/as223/com/google/idea/blaze/android/run/test/BlazeAndroidTestRunContext.java +++ /dev/null @@ -1,229 +0,0 @@ -/* - * Copyright 2016 The Bazel Authors. All rights reserved. - * - * 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. - */ -package com.google.idea.blaze.android.run.test; - -import static com.android.tools.idea.run.tasks.DefaultConnectDebuggerTaskKt.getBaseDebuggerTask; -import static com.google.idea.blaze.android.run.binary.BlazeAndroidBinaryNormalBuildRunContextBase.getApkInfoToInstall; - -import com.android.ddmlib.IDevice; -import com.android.tools.idea.execution.common.debug.AndroidDebugger; -import com.android.tools.idea.execution.common.debug.AndroidDebuggerState; -import com.android.tools.idea.run.ApkProvider; -import com.android.tools.idea.run.ApkProvisionException; -import com.android.tools.idea.run.ApplicationIdProvider; -import com.android.tools.idea.run.ConsoleProvider; -import com.android.tools.idea.run.LaunchOptions; -import com.android.tools.idea.run.blaze.BlazeLaunchTask; -import com.android.tools.idea.run.blaze.BlazeLaunchTasksProvider; -import com.android.tools.idea.run.editor.ProfilerState; -import com.android.tools.idea.run.tasks.ConnectDebuggerTask; -import com.android.tools.idea.run.tasks.DeployTasksCompat; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.Lists; -import com.google.idea.blaze.android.run.deployinfo.BlazeAndroidDeployInfo; -import com.google.idea.blaze.android.run.deployinfo.BlazeApkProviderService; -import com.google.idea.blaze.android.run.runner.ApkBuildStep; -import com.google.idea.blaze.android.run.runner.BlazeAndroidDeviceSelector; -import com.google.idea.blaze.android.run.runner.BlazeAndroidLaunchTasksProvider; -import com.google.idea.blaze.android.run.runner.BlazeAndroidRunContext; -import com.google.idea.blaze.android.run.test.BlazeAndroidTestLaunchMethodsProvider.AndroidTestLaunchMethod; -import com.google.idea.blaze.base.model.primitives.Label; -import com.google.idea.blaze.base.run.BlazeCommandRunConfiguration; -import com.google.idea.blaze.base.run.smrunner.BlazeTestUiSession; -import com.google.idea.blaze.base.run.testlogs.BlazeTestResultHolder; -import com.intellij.execution.ExecutionException; -import com.intellij.execution.Executor; -import com.intellij.execution.runners.ExecutionEnvironment; -import com.intellij.openapi.project.Project; -import java.util.List; -import javax.annotation.Nullable; -import org.jetbrains.android.facet.AndroidFacet; - -/** Run context for android_test. */ -public class BlazeAndroidTestRunContext implements BlazeAndroidRunContext { - protected final Project project; - protected final AndroidFacet facet; - protected final BlazeCommandRunConfiguration runConfiguration; - protected final ExecutionEnvironment env; - protected final BlazeAndroidTestRunConfigurationState configState; - protected final Label label; - protected final ImmutableList blazeFlags; - protected final List launchTaskCompleteListeners = Lists.newArrayList(); - protected final ConsoleProvider consoleProvider; - protected final ApkBuildStep buildStep; - protected final ApplicationIdProvider applicationIdProvider; - protected final ApkProvider apkProvider; - private final BlazeTestResultHolder testResultsHolder = new BlazeTestResultHolder(); - - public BlazeAndroidTestRunContext( - Project project, - AndroidFacet facet, - BlazeCommandRunConfiguration runConfiguration, - ExecutionEnvironment env, - BlazeAndroidTestRunConfigurationState configState, - Label label, - ImmutableList blazeFlags, - ApkBuildStep buildStep) { - this.project = project; - this.facet = facet; - this.runConfiguration = runConfiguration; - this.env = env; - this.label = label; - this.configState = configState; - this.buildStep = buildStep; - this.blazeFlags = blazeFlags; - switch (configState.getLaunchMethod()) { - case MOBILE_INSTALL: - case NON_BLAZE: - consoleProvider = new AitIdeTestConsoleProvider(runConfiguration, configState); - break; - case BLAZE_TEST: - BlazeTestUiSession session = - BlazeTestUiSession.create(ImmutableList.of(), testResultsHolder); - this.consoleProvider = new AitBlazeTestConsoleProvider(project, runConfiguration, session); - break; - default: - throw new IllegalStateException( - "Unsupported launch method " + configState.getLaunchMethod()); - } - applicationIdProvider = new BlazeAndroidTestApplicationIdProvider(buildStep); - apkProvider = BlazeApkProviderService.getInstance().getApkProvider(project, buildStep); - } - - @Override - public BlazeAndroidDeviceSelector getDeviceSelector() { - return new BlazeAndroidDeviceSelector.NormalDeviceSelector(); - } - - @Override - public void augmentLaunchOptions(LaunchOptions.Builder options) { - options.setDeploy(!configState.getLaunchMethod().equals(AndroidTestLaunchMethod.BLAZE_TEST)); - } - - @Override - public ConsoleProvider getConsoleProvider() { - return consoleProvider; - } - - @Override - public ApplicationIdProvider getApplicationIdProvider() throws ExecutionException { - return applicationIdProvider; - } - - @Nullable - @Override - public ApkBuildStep getBuildStep() { - return buildStep; - } - - @Override - public ProfilerState getProfileState() { - return null; - } - - @Override - public BlazeLaunchTasksProvider getLaunchTasksProvider(LaunchOptions.Builder launchOptionsBuilder) - throws ExecutionException { - return new BlazeAndroidLaunchTasksProvider( - project, this, applicationIdProvider, launchOptionsBuilder); - } - - @Override - public ImmutableList getDeployTasks(IDevice device, LaunchOptions launchOptions) - throws ExecutionException { - if (configState.getLaunchMethod() != AndroidTestLaunchMethod.NON_BLAZE) { - return ImmutableList.of(); - } - return ImmutableList.of( - DeployTasksCompat.createDeployTask( - project, getApkInfoToInstall(device, launchOptions, apkProvider), launchOptions)); - } - - @Override - @Nullable - public BlazeLaunchTask getApplicationLaunchTask( - LaunchOptions launchOptions, @Nullable Integer userId, String contributorsAmStartOptions) - throws ExecutionException { - switch (configState.getLaunchMethod()) { - case BLAZE_TEST: - BlazeAndroidTestFilter testFilter = - new BlazeAndroidTestFilter( - configState.getTestingType(), - configState.getClassName(), - configState.getMethodName(), - configState.getPackageName()); - return new BlazeAndroidTestLaunchTask( - project, - label, - blazeFlags, - testFilter, - this, - launchOptions.isDebug(), - testResultsHolder); - case NON_BLAZE: - case MOBILE_INSTALL: - BlazeAndroidDeployInfo deployInfo; - try { - deployInfo = buildStep.getDeployInfo(); - } catch (ApkProvisionException e) { - throw new ExecutionException(e); - } - return StockAndroidTestLaunchTask.getStockTestLaunchTask( - configState, applicationIdProvider, launchOptions.isDebug(), deployInfo, project); - } - throw new AssertionError(); - } - - @Override - @SuppressWarnings({"unchecked", "rawtypes"}) // Raw type from upstream. - public ConnectDebuggerTask getDebuggerTask( - AndroidDebugger androidDebugger, AndroidDebuggerState androidDebuggerState) { - switch (configState.getLaunchMethod()) { - case BLAZE_TEST: - return new ConnectBlazeTestDebuggerTask(this, androidDebugger, androidDebuggerState); - case NON_BLAZE: - case MOBILE_INSTALL: - return getBaseDebuggerTask(androidDebugger, androidDebuggerState, env, facet, 30); - } - throw new AssertionError(); - } - - void onLaunchTaskComplete() { - for (Runnable runnable : launchTaskCompleteListeners) { - runnable.run(); - } - } - - void addLaunchTaskCompleteListener(Runnable runnable) { - launchTaskCompleteListeners.add(runnable); - } - - @Override - public Executor getExecutor() { - return env.getExecutor(); - } - - @Nullable - @Override - public Integer getUserId(IDevice device) { - return null; - } - - @Override - public String getAmStartOptions() { - return ""; - } -} diff --git a/aswb/sdkcompat/as223/com/google/idea/blaze/android/run/test/ConnectBlazeTestDebuggerTask.java b/aswb/sdkcompat/as223/com/google/idea/blaze/android/run/test/ConnectBlazeTestDebuggerTask.java deleted file mode 100644 index 3ef2a6c9493..00000000000 --- a/aswb/sdkcompat/as223/com/google/idea/blaze/android/run/test/ConnectBlazeTestDebuggerTask.java +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Copyright 2016 The Bazel Authors. All rights reserved. - * - * 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. - */ -package com.google.idea.blaze.android.run.test; - -import com.android.ddmlib.IDevice; -import com.android.tools.idea.execution.common.debug.AndroidDebugger; -import com.android.tools.idea.execution.common.debug.AndroidDebuggerState; -import com.android.tools.idea.execution.common.debug.DebugSessionStarter; -import com.android.tools.idea.run.tasks.ConnectDebuggerTask; -import com.intellij.execution.process.ProcessHandler; -import com.intellij.execution.process.ProcessOutputTypes; -import com.intellij.execution.runners.ExecutionEnvironment; -import com.intellij.execution.ui.ConsoleView; -import com.intellij.openapi.progress.ProgressIndicator; -import com.intellij.xdebugger.impl.XDebugSessionImpl; -import java.io.OutputStream; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -/** Connects the blaze debugger during execution. */ -class ConnectBlazeTestDebuggerTask implements ConnectDebuggerTask { - - private final BlazeAndroidTestRunContext runContext; - private final AndroidDebugger myAndroidDebugger; - private final S myAndroidDebuggerState; - - public ConnectBlazeTestDebuggerTask( - BlazeAndroidTestRunContext runContext, - AndroidDebugger androidDebugger, - S androidDebuggerState) { - this.runContext = runContext; - myAndroidDebugger = androidDebugger; - myAndroidDebuggerState = androidDebuggerState; - } - - /** - * Wires up listeners to automatically reconnect the debugger for each test method. When you - * `blaze test` an android_test in debug mode, it kills the instrumentation process between each - * test method, disconnecting the debugger. We listen for the start of a new method waiting for a - * debugger, and reconnect. TODO: Support stopping Blaze from the UI. This is hard because we have - * no way to distinguish process handler termination/debug session ending initiated by the user. - * - * @return Promise with debug session or error - */ - @Override - public @NotNull XDebugSessionImpl perform( - @NotNull IDevice device, - @NotNull String applicationId, - @NotNull ExecutionEnvironment environment, - @NotNull ProgressIndicator progressIndicator, - ConsoleView console) { - final ProcessHandler masterProcessHandler = - new ProcessHandler() { - - @Override - protected void destroyProcessImpl() { - notifyProcessTerminated(0); - } - - @Override - protected void detachProcessImpl() { - notifyProcessDetached(); - } - - @Override - public boolean detachIsDefault() { - return false; - } - - @Override - public @Nullable OutputStream getProcessInput() { - return null; - } - }; - runContext.addLaunchTaskCompleteListener( - () -> { - masterProcessHandler.notifyTextAvailable( - "Test run completed.\n", ProcessOutputTypes.STDOUT); - masterProcessHandler.detachProcess(); - }); - return DebugSessionStarter.INSTANCE.attachReattachingDebuggerToStartedProcess( - device, - applicationId, - masterProcessHandler, - environment, - myAndroidDebugger, - myAndroidDebuggerState, - progressIndicator, - console, - Long.MAX_VALUE); - } -} diff --git a/aswb/sdkcompat/as223/com/google/idea/blaze/android/run/test/StockAndroidTestLaunchTask.java b/aswb/sdkcompat/as223/com/google/idea/blaze/android/run/test/StockAndroidTestLaunchTask.java deleted file mode 100644 index b5df308dcea..00000000000 --- a/aswb/sdkcompat/as223/com/google/idea/blaze/android/run/test/StockAndroidTestLaunchTask.java +++ /dev/null @@ -1,207 +0,0 @@ -/* - * Copyright 2016 The Bazel Authors. All rights reserved. - * - * 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. - */ -package com.google.idea.blaze.android.run.test; - -import com.android.ddmlib.IDevice; -import com.android.ddmlib.testrunner.RemoteAndroidTestRunner; -import com.android.tools.idea.execution.common.RunConfigurationNotifier; -import com.android.tools.idea.execution.common.processhandler.AndroidProcessHandler; -import com.android.tools.idea.run.ApkProvisionException; -import com.android.tools.idea.run.ApplicationIdProvider; -import com.android.tools.idea.run.blaze.BlazeLaunchContext; -import com.android.tools.idea.run.blaze.BlazeLaunchTask; -import com.android.tools.idea.run.configuration.execution.ExecutionUtils; -import com.android.tools.idea.testartifacts.instrumented.AndroidTestListener; -import com.google.common.collect.ImmutableList; -import com.google.idea.blaze.android.manifest.ManifestParser; -import com.google.idea.blaze.android.run.deployinfo.BlazeAndroidDeployInfo; -import com.intellij.execution.ExecutionException; -import com.intellij.execution.process.ProcessHandler; -import com.intellij.execution.ui.ConsoleView; -import com.intellij.openapi.application.ApplicationManager; -import com.intellij.openapi.diagnostic.Logger; -import com.intellij.openapi.project.Project; -import com.intellij.openapi.util.Computable; -import com.intellij.openapi.util.text.StringUtil; -import java.util.List; -import javax.annotation.Nullable; -import org.jetbrains.annotations.NotNull; - -class StockAndroidTestLaunchTask implements BlazeLaunchTask { - private static final String ID = "STOCK_ANDROID_TEST"; - private static final Logger LOG = Logger.getInstance(StockAndroidTestLaunchTask.class); - private final BlazeAndroidTestRunConfigurationState configState; - private final String instrumentationTestRunner; - private final String testApplicationId; - private final boolean waitForDebugger; - - StockAndroidTestLaunchTask( - BlazeAndroidTestRunConfigurationState configState, - String runner, - String testPackage, - boolean waitForDebugger) { - this.configState = configState; - this.instrumentationTestRunner = runner; - this.waitForDebugger = waitForDebugger; - this.testApplicationId = testPackage; - } - - @Nullable - public static BlazeLaunchTask getStockTestLaunchTask( - BlazeAndroidTestRunConfigurationState configState, - ApplicationIdProvider applicationIdProvider, - boolean waitForDebugger, - BlazeAndroidDeployInfo deployInfo, - Project project) - throws ExecutionException { - String testPackage; - try { - testPackage = applicationIdProvider.getTestPackageName(); - } catch (ApkProvisionException e) { - throw new ExecutionException("Unable to determine test package name. " + e.getMessage()); - } - if (testPackage == null) { - throw new ExecutionException("Unable to determine test package name."); - } - List availableRunners = getRunnersFromManifest(deployInfo); - if (availableRunners.isEmpty()) { - RunConfigurationNotifier.INSTANCE.notifyError( - project, - "", - String.format( - "No instrumentation test runner is defined in the manifest.\n" - + "At least one instrumentation tag must be defined for the\n" - + "\"%1$s\" package in the AndroidManifest.xml, e.g.:\n" - + "\n" - + "\n" - + "\n" - + " \n" - + " \n" - + "\n" - + "", - testPackage)); - // Note: Gradle users will never see the above message, so don't mention Gradle here. - // Even if no runners are defined in build.gradle, Gradle will add a default to the manifest. - throw new ExecutionException("No instrumentation test runner is defined in the manifest."); - } - String runner = configState.getInstrumentationRunnerClass(); - if (StringUtil.isEmpty(runner)) { - // Default to the first available runner. - runner = availableRunners.get(0); - } - if (!availableRunners.contains(runner)) { - RunConfigurationNotifier.INSTANCE.notifyError( - project, - "", - String.format( - "Instrumentation test runner \"%2$s\"\n" - + "is not defined for the \"%1$s\" package in the manifest.\n" - + "Clear the 'Specific instrumentation runner' field in your configuration\n" - + "to default to \"%3$s\",\n" - + "or add the runner to your AndroidManifest.xml:\n" - + "\n" - + "\n" - + "\n" - + " \n" - + " \n" - + "\n" - + "", - testPackage, runner, availableRunners.get(0))); - throw new ExecutionException( - String.format( - "Instrumentation test runner \"%2$s\" is not defined for the \"%1$s\" package in the" - + " manifest.", - testPackage, runner)); - } - - return new StockAndroidTestLaunchTask(configState, runner, testPackage, waitForDebugger); - } - - private static ImmutableList getRunnersFromManifest( - final BlazeAndroidDeployInfo deployInfo) { - if (!ApplicationManager.getApplication().isReadAccessAllowed()) { - return ApplicationManager.getApplication() - .runReadAction( - (Computable>) () -> getRunnersFromManifest(deployInfo)); - } - ManifestParser.ParsedManifest parsedManifest = deployInfo.getMergedManifest(); - if (parsedManifest != null) { - return ImmutableList.copyOf(parsedManifest.instrumentationClassNames); - } - return ImmutableList.of(); - } - - @SuppressWarnings("FutureReturnValueIgnored") - public void run(@NotNull BlazeLaunchContext launchContext) { - ConsoleView console = launchContext.getConsoleView(); - IDevice device = launchContext.getDevice(); - ExecutionUtils.println(console, "Running tests\n"); - final RemoteAndroidTestRunner runner = - new RemoteAndroidTestRunner(testApplicationId, instrumentationTestRunner, device); - switch (configState.getTestingType()) { - case BlazeAndroidTestRunConfigurationState.TEST_ALL_IN_MODULE: - break; - case BlazeAndroidTestRunConfigurationState.TEST_ALL_IN_PACKAGE: - runner.setTestPackageName(configState.getPackageName()); - break; - case BlazeAndroidTestRunConfigurationState.TEST_CLASS: - runner.setClassName(configState.getClassName()); - break; - case BlazeAndroidTestRunConfigurationState.TEST_METHOD: - runner.setMethodName(configState.getClassName(), configState.getMethodName()); - break; - default: - throw new RuntimeException( - String.format("Unrecognized testing type: %d", configState.getTestingType())); - } - runner.setDebug(waitForDebugger); - runner.setRunOptions(configState.getExtraOptions()); - ExecutionUtils.printShellCommand(console, runner.getAmInstrumentCommand()); - // run in a separate thread as this will block until the tests complete - ApplicationManager.getApplication() - .executeOnPooledThread( - () -> { - try { - // This issues "am instrument" command and blocks execution. - runner.run(new AndroidTestListener(console)); - // Detach the device from the android process handler manually as soon as "am - // instrument" command finishes. This is required because the android process - // handler may overlook target process especially when the test - // runs really fast (~10ms). Because the android process handler discovers new - // processes by polling, this race condition happens easily. By detaching the device - // manually, we can avoid the android process handler waiting for (already finished) - // process to show up until it times out (10 secs). - // Note: this is a copy of ag/9593981, but it is worth figuring out a better - // strategy here if the behavior of AndroidTestListener is not guaranteed. - ProcessHandler processHandler = launchContext.getProcessHandler(); - if (processHandler instanceof AndroidProcessHandler) { - ((AndroidProcessHandler) processHandler).detachDevice(launchContext.getDevice()); - } - } catch (Exception e) { - ExecutionUtils.printlnError( - console, "Error: Unexpected exception while running tests: " + e); - } - }); - } -} diff --git a/aswb/sdkcompat/as223/com/google/idea/blaze/android/sync/model/idea/BlazeAndroidModel.java b/aswb/sdkcompat/as223/com/google/idea/blaze/android/sync/model/idea/BlazeAndroidModel.java deleted file mode 100644 index 00a9e4a94c9..00000000000 --- a/aswb/sdkcompat/as223/com/google/idea/blaze/android/sync/model/idea/BlazeAndroidModel.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright 2020 The Bazel Authors. All rights reserved. - * - * 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. - */ -package com.google.idea.blaze.android.sync.model.idea; - -import com.android.tools.idea.model.AndroidModel; -import com.android.tools.idea.model.Namespacing; -import com.android.tools.idea.projectsystem.NamedIdeaSourceProvider; -import com.google.common.util.concurrent.ListenableFuture; -import com.intellij.openapi.project.Project; -import java.io.File; - -/** Blaze model for an android project. #api42. */ -public class BlazeAndroidModel extends BlazeAndroidModelBase { - private final NamedIdeaSourceProvider sourceProvider; - - public BlazeAndroidModel( - Project project, - File rootDirPath, - NamedIdeaSourceProvider sourceProvider, - ListenableFuture applicationId, - int minSdkVersion, - boolean desugarJava8Libs) { - super(project, rootDirPath, applicationId, minSdkVersion, desugarJava8Libs); - this.sourceProvider = sourceProvider; - } - - public NamedIdeaSourceProvider getDefaultSourceProvider() { - return sourceProvider; - } - - @Override - public Namespacing getNamespacing() { - return Namespacing.DISABLED; - } - - @Override - protected String uninitializedApplicationId() { - return AndroidModel.UNINITIALIZED_APPLICATION_ID; - } -} diff --git a/aswb/sdkcompat/as223/org/jetbrains/android/facet/AndroidFacetPropertiesCompat.java b/aswb/sdkcompat/as223/org/jetbrains/android/facet/AndroidFacetPropertiesCompat.java deleted file mode 100644 index fff25619e8a..00000000000 --- a/aswb/sdkcompat/as223/org/jetbrains/android/facet/AndroidFacetPropertiesCompat.java +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright 2022 The Bazel Authors. All rights reserved. - * - * 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. - */ -package org.jetbrains.android.facet; - -/** Compat class for AndroidFacetProperties. */ -public class AndroidFacetPropertiesCompat { - - private AndroidFacetPropertiesCompat() {} - - public static void enableSourcesAutogeneration(AndroidFacetProperties props, boolean enable) {} -} diff --git a/aswb/sdkcompat/as223/org/jetbrains/android/sdk/AndroidPlatformCompat.java b/aswb/sdkcompat/as223/org/jetbrains/android/sdk/AndroidPlatformCompat.java deleted file mode 100644 index f745ba55516..00000000000 --- a/aswb/sdkcompat/as223/org/jetbrains/android/sdk/AndroidPlatformCompat.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright 2023 The Bazel Authors. All rights reserved. - * - * 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. - */ -package org.jetbrains.android.sdk; - -import com.android.sdklib.BuildToolInfo; -import com.android.tools.sdk.AndroidPlatform; -import com.intellij.openapi.projectRoots.Sdk; - -/** Compat class for {@link com.android.tools.sdk.AndroidPlatform} */ -public class AndroidPlatformCompat { - AndroidPlatform androidPlatform; - - public AndroidPlatformCompat(AndroidPlatform androidPlatform) { - this.androidPlatform = androidPlatform; - } - - public BuildToolInfo getLatestBuildTool(boolean allowBuildTool) { - return androidPlatform.getSdkData().getLatestBuildTool(allowBuildTool); - } - - public int getApiLevel() { - return androidPlatform.getApiLevel(); - } - - public static int getApiLevel(Sdk sdk) { - int androidSdkApiLevel = 1; - AndroidSdkAdditionalData additionalData = (AndroidSdkAdditionalData) sdk.getSdkAdditionalData(); - if (additionalData != null) { - AndroidPlatform androidPlatform = additionalData.getAndroidPlatform(); - if (androidPlatform != null) { - androidSdkApiLevel = androidPlatform.getApiLevel(); - } - } - return androidSdkApiLevel; - } -} diff --git a/aswb/sdkcompat/as223/org/jetbrains/android/sdk/AndroidPlatformsCompat.java b/aswb/sdkcompat/as223/org/jetbrains/android/sdk/AndroidPlatformsCompat.java deleted file mode 100644 index d016d7ce236..00000000000 --- a/aswb/sdkcompat/as223/org/jetbrains/android/sdk/AndroidPlatformsCompat.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright 2023 The Bazel Authors. All rights reserved. - * - * 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. - */ -package org.jetbrains.android.sdk; - -import com.intellij.openapi.module.Module; -import com.intellij.openapi.projectRoots.Sdk; - -/** Compat shim class for {@link AndroidPlatforms} */ -public class AndroidPlatformsCompat { - private AndroidPlatformsCompat() {} - - public static AndroidPlatformCompat getInstance(Sdk sdk) { - return new AndroidPlatformCompat(AndroidPlatforms.getInstance(sdk)); - } - - public static AndroidPlatformCompat getInstance(Module module) { - return new AndroidPlatformCompat(AndroidPlatforms.getInstance(module)); - } -} diff --git a/aswb/sdkcompat/as223/org/jetbrains/android/sdk/AndroidSdkAdditionalDataCompat.java b/aswb/sdkcompat/as223/org/jetbrains/android/sdk/AndroidSdkAdditionalDataCompat.java deleted file mode 100644 index 6364b6fa8cf..00000000000 --- a/aswb/sdkcompat/as223/org/jetbrains/android/sdk/AndroidSdkAdditionalDataCompat.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright 2023 The Bazel Authors. All rights reserved. - * - * 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. - */ -package org.jetbrains.android.sdk; - -import com.intellij.openapi.projectRoots.Sdk; - -/** Compat shim class for {@link AndroidSdkAdditionalData} */ -public class AndroidSdkAdditionalDataCompat { - private AndroidSdkAdditionalDataCompat() {} - - public static AndroidSdkAdditionalData from(Sdk sdk) { - return AndroidSdkAdditionalData.from(sdk); - } -} diff --git a/aswb/sdkcompat/as223/org/jetbrains/android/sdk/AndroidSdkDataCompat.java b/aswb/sdkcompat/as223/org/jetbrains/android/sdk/AndroidSdkDataCompat.java deleted file mode 100644 index 4aea6d6e832..00000000000 --- a/aswb/sdkcompat/as223/org/jetbrains/android/sdk/AndroidSdkDataCompat.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright 2023 The Bazel Authors. All rights reserved. - * - * 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. - */ -package org.jetbrains.android.sdk; - -import com.android.sdklib.IAndroidTarget; -import com.android.tools.sdk.AndroidSdkData; -import com.google.errorprone.annotations.CanIgnoreReturnValue; -import java.io.File; - -/** Compat class for {@link com.android.tools.sdk.AndroidSdkData} */ -public class AndroidSdkDataCompat { - AndroidSdkData androidSdkData; - - private AndroidSdkDataCompat(File sdkLocation, boolean forceReparse) { - androidSdkData = AndroidSdkData.getSdkData(sdkLocation, forceReparse); - } - - public static AndroidSdkDataCompat getSdkData(String sdkHomepath) { - return new AndroidSdkDataCompat(new File(sdkHomepath), false); - } - - @CanIgnoreReturnValue - public static AndroidSdkDataCompat getSdkData(File sdkLocation, boolean forceReparse) { - return new AndroidSdkDataCompat(sdkLocation, forceReparse); - } - - public IAndroidTarget[] getTargets() { - return androidSdkData.getTargets(); - } -} diff --git a/aswb/sdkcompat/as231/com/android/tools/idea/model/AndroidManifestIndexCompat.java b/aswb/sdkcompat/as231/com/android/tools/idea/model/AndroidManifestIndexCompat.java deleted file mode 100644 index 27f94f054c6..00000000000 --- a/aswb/sdkcompat/as231/com/android/tools/idea/model/AndroidManifestIndexCompat.java +++ /dev/null @@ -1,27 +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. - */ -package com.android.tools.idea.model; - -/** Compat class for {@link com.android.tools.idea.model.AndroidManifestIndex}. */ -public class AndroidManifestIndexCompat { - - private AndroidManifestIndexCompat() {} - - /** {@code indexEnabled} was removed in Studio 2021.2. #api211 */ - public static boolean indexEnabled() { - return true; - } -} diff --git a/aswb/sdkcompat/as231/com/android/tools/idea/progress/StudioLoggerProgressIndicatorCompat.java b/aswb/sdkcompat/as231/com/android/tools/idea/progress/StudioLoggerProgressIndicatorCompat.java deleted file mode 100644 index e581bd190d8..00000000000 --- a/aswb/sdkcompat/as231/com/android/tools/idea/progress/StudioLoggerProgressIndicatorCompat.java +++ /dev/null @@ -1,23 +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. - */ -package com.android.tools.idea.progress; - -/** Compat layer for StudioLoggerProgressIndicator which moved packages in 2021.2. #api211 */ -public class StudioLoggerProgressIndicatorCompat extends StudioLoggerProgressIndicator { - public StudioLoggerProgressIndicatorCompat(Class c) { - super(c); - } -} diff --git a/aswb/sdkcompat/as231/com/android/tools/idea/run/ValidationErrorCompat.java b/aswb/sdkcompat/as231/com/android/tools/idea/run/ValidationErrorCompat.java deleted file mode 100644 index fb233c7eeb8..00000000000 --- a/aswb/sdkcompat/as231/com/android/tools/idea/run/ValidationErrorCompat.java +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright 2023 The Bazel Authors. All rights reserved. - * - * 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. - */ -package com.android.tools.idea.run; - -/** Compat class for {@link ValidationError} */ -public class ValidationErrorCompat { - private ValidationErrorCompat() {} - - public static ValidationError fatal(String message, Runnable quickFick) { - return ValidationError.fatal(message, (dataContext) -> quickFick.run()); - } -} diff --git a/aswb/sdkcompat/as231/com/android/tools/idea/run/tasks/DeployTasksCompat.java b/aswb/sdkcompat/as231/com/android/tools/idea/run/tasks/DeployTasksCompat.java deleted file mode 100644 index 500a6786340..00000000000 --- a/aswb/sdkcompat/as231/com/android/tools/idea/run/tasks/DeployTasksCompat.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2020 The Bazel Authors. All rights reserved. - * - * 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. - */ -package com.android.tools.idea.run.tasks; - -import com.android.tools.idea.run.ApkInfo; -import com.android.tools.idea.run.LaunchOptions; -import com.android.tools.idea.run.blaze.BlazeLaunchTask; -import com.android.tools.idea.run.blaze.BlazeLaunchTaskWrapper; -import com.google.idea.common.experiments.BoolExperiment; -import com.intellij.openapi.project.Project; -import java.util.Collection; - -/** Compat class for {@link DeployTask} */ -public class DeployTasksCompat { - private static final BoolExperiment updateCodeViaJvmti = - new BoolExperiment("android.apply.changes", false); - - private DeployTasksCompat() {} - - public static BlazeLaunchTask createDeployTask( - Project project, Collection packages, LaunchOptions launchOptions) { - // We don't have a device information, fallback to the most conservative - // install option. - return new BlazeLaunchTaskWrapper( - new DeployTask( - project, - packages, - launchOptions.getPmInstallOptions(/* device= */ null), - launchOptions.getInstallOnAllUsers(), - launchOptions.getAlwaysInstallWithPm())); - } -} - diff --git a/aswb/sdkcompat/as231/com/android/tools/rendering/HtmlLinkManagerCompat.java b/aswb/sdkcompat/as231/com/android/tools/rendering/HtmlLinkManagerCompat.java deleted file mode 100644 index 28ca9471258..00000000000 --- a/aswb/sdkcompat/as231/com/android/tools/rendering/HtmlLinkManagerCompat.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright 2023 The Bazel Authors. All rights reserved. - * - * 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. - */ -package com.android.tools.rendering; - -import java.io.File; -import org.jetbrains.annotations.NotNull; - -/** Compat class for {@link HtmlLinkManager} */ -public final class HtmlLinkManagerCompat { - public static String createFilePositionUrl(@NotNull File file, int line, int column) { - return HtmlLinkManager.createFilePositionUrl(file, line, column); - } - - private HtmlLinkManagerCompat() {} -} diff --git a/aswb/sdkcompat/as231/com/google/idea/blaze/android/cppimpl/debug/BlazeAutoAndroidDebugger.java b/aswb/sdkcompat/as231/com/google/idea/blaze/android/cppimpl/debug/BlazeAutoAndroidDebugger.java deleted file mode 100644 index 167fd4433a9..00000000000 --- a/aswb/sdkcompat/as231/com/google/idea/blaze/android/cppimpl/debug/BlazeAutoAndroidDebugger.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright 2016 The Bazel Authors. All rights reserved. - * - * 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. - */ -package com.google.idea.blaze.android.cppimpl.debug; - -import com.android.ddmlib.Client; -import com.android.tools.ndk.run.editor.AutoAndroidDebuggerState; -import com.intellij.execution.ExecutionException; -import com.intellij.openapi.project.Project; -import com.intellij.xdebugger.XDebugSession; - -/** Shim for #api212 compat. */ -public class BlazeAutoAndroidDebugger extends BlazeAutoAndroidDebuggerBase { - @Override - public XDebugSession attachToClient( - Project project, Client client, AutoAndroidDebuggerState state) throws ExecutionException { - if (isNativeProject(project)) { - log.info("Project has native development enabled. Attaching native debugger."); - return nativeDebugger.attachToClient(project, client, state); - } else { - return super.attachToClient(project, client, state); - } - } -} diff --git a/aswb/sdkcompat/as231/com/google/idea/blaze/android/cppimpl/debug/BlazeNativeAndroidDebugger.java b/aswb/sdkcompat/as231/com/google/idea/blaze/android/cppimpl/debug/BlazeNativeAndroidDebugger.java deleted file mode 100644 index bfa296e12e2..00000000000 --- a/aswb/sdkcompat/as231/com/google/idea/blaze/android/cppimpl/debug/BlazeNativeAndroidDebugger.java +++ /dev/null @@ -1,28 +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. - */ -package com.google.idea.blaze.android.cppimpl.debug; - -/** - * API compat of {@link BlazeNativeAndroidDebuggerBase} with the following additions: - * - *

    - *
  • Creates a run-config setting using {@link BlazeAndroidNativeAttachConfiguration} instead of - * {@link AndroidNativeAttachConfiguration} to override counterproductive validations. - *
- * - * #api4.0 - */ -public class BlazeNativeAndroidDebugger extends BlazeNativeAndroidDebuggerBase {} diff --git a/aswb/sdkcompat/as231/com/google/idea/blaze/android/cppimpl/debug/BlazeNativeAndroidDebuggerBase.java b/aswb/sdkcompat/as231/com/google/idea/blaze/android/cppimpl/debug/BlazeNativeAndroidDebuggerBase.java deleted file mode 100644 index 911d90b7711..00000000000 --- a/aswb/sdkcompat/as231/com/google/idea/blaze/android/cppimpl/debug/BlazeNativeAndroidDebuggerBase.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright 2020 The Bazel Authors. All rights reserved. - * - * 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. - */ -package com.google.idea.blaze.android.cppimpl.debug; - -import com.android.tools.ndk.run.editor.NativeAndroidDebugger; -import com.google.idea.blaze.base.model.BlazeProjectData; -import com.google.idea.blaze.base.model.primitives.LanguageClass; -import com.google.idea.blaze.base.settings.Blaze; -import com.google.idea.blaze.base.sync.data.BlazeProjectDataManager; -import com.intellij.openapi.project.Project; - -/** - * Extension of {@link NativeAndroidDebugger} with the following key differences compared to {@link - * NativeAndroidDebugger}. - * - *
    - *
  • Overrides {@link #supportsProject} so native debugger is only enabled for native support is - * enabled. - *
- */ -public class BlazeNativeAndroidDebuggerBase extends NativeAndroidDebugger { - /** - * This ID needs to be lexicographically larger than "Java" so it come after the "Java" debugger - * when sorted lexicographically in the "Attach Debugger to Android Process" dialog. See {@link - * org.jetbrains.android.actions.AndroidProcessChooserDialog#populateDebuggerTypeCombo}. - */ - public static final String ID = "Native" + Blaze.defaultBuildSystemName(); - - @Override - public String getId() { - return ID; - } - - @Override - public String getDisplayName() { - return "Native Only"; - } - - @Override - public boolean supportsProject(Project project) { - BlazeProjectData blazeProjectData = - BlazeProjectDataManager.getInstance(project).getBlazeProjectData(); - return blazeProjectData != null - && blazeProjectData.getWorkspaceLanguageSettings().isLanguageActive(LanguageClass.C); - } -} diff --git a/aswb/sdkcompat/as231/com/google/idea/blaze/android/npw/project/BlazeAndroidModuleTemplate.java b/aswb/sdkcompat/as231/com/google/idea/blaze/android/npw/project/BlazeAndroidModuleTemplate.java deleted file mode 100644 index 8d3b76b90e3..00000000000 --- a/aswb/sdkcompat/as231/com/google/idea/blaze/android/npw/project/BlazeAndroidModuleTemplate.java +++ /dev/null @@ -1,184 +0,0 @@ -/* - * Copyright 2017 The Bazel Authors. All rights reserved. - * - * 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. - */ -package com.google.idea.blaze.android.npw.project; - -import com.android.tools.idea.projectsystem.AndroidModulePaths; -import com.android.tools.idea.projectsystem.IdeaSourceProvider; -import com.android.tools.idea.projectsystem.NamedModuleTemplate; -import com.android.tools.idea.projectsystem.SourceProviderManager; -import com.google.common.collect.Streams; -import com.intellij.openapi.module.Module; -import com.intellij.openapi.project.Project; -import com.intellij.openapi.roots.ModuleRootManager; -import com.intellij.openapi.vfs.VfsUtilCore; -import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.psi.JavaDirectoryService; -import com.intellij.psi.PsiDirectory; -import com.intellij.psi.PsiManager; -import com.intellij.psi.PsiPackage; -import java.io.File; -import java.util.Collections; -import java.util.List; -import java.util.stream.Collectors; -import javax.annotation.Nullable; -import org.jetbrains.android.facet.AndroidFacet; - -/** - * Project paths for a Blaze Android project. - * - *

We mostly just take whatever directory the user specified and put the new component there. - * Unlike Gradle, Blaze has no strict requirements regarding the structure of an Android project, - * but there are some common conventions: - * - *

- * google3/
- * |-java/com/google/foo/bar/... (module root)
- * | |-BUILD
- * | |-AndroidManifest.xml (manifest directory)
- * | |-Baz.java (source directory of com.google.foo.bar.Baz)
- * | |-Baz.aidl (aidl directory, option 1)
- * | |-aidl/
- * | | `-com/google/foo/bar/Baz.aidl (aidl directory, option 2)
- * | `-res/... (res directory, one of the few things required by the build system)
- * `-javatest/com/google/foo/bar/...
- *   |-BUILD
- *   `-BazTest.java (test directory of com.google.foo.bar.BazTest)
- * 
- * - * However, this is also possible (package name unrelated to directory structure): - * - *
- * google3/experimental/users/foo/my/own/project/
- * |-Baz.java (com.google.foo.bar.Baz)
- * `-BazTest.java (com.google.foo.bar.BazTest)
- * 
- * - * So is this (versioned paths that aren't reflected by the package name): - * - *
- * google3/third_party/com/google/foo/bar/
- * |-v1/Baz.java (com.google.foo.bar.Baz)
- * `-v2/Baz.java (com.google.foo.bar.Baz)
- * 
- */ -public class BlazeAndroidModuleTemplate implements AndroidModulePaths { - @Nullable private File moduleRoot; - @Nullable private File srcDirectory; - private List resDirectories = Collections.emptyList(); - - @Nullable - @Override - public File getModuleRoot() { - return moduleRoot; - } - - @Nullable - @Override - public File getSrcDirectory(@Nullable String packageName) { - return srcDirectory; - } - - @Nullable - @Override - public File getTestDirectory(@Nullable String packageName) { - return srcDirectory; - } - - @Nullable - @Override - public File getUnitTestDirectory(@Nullable String packageName) { - return srcDirectory; - } - - @Override - public List getResDirectories() { - return resDirectories; - } - - @Nullable - @Override - public File getAidlDirectory(@Nullable String packageName) { - return srcDirectory; - } - - @Nullable - @Override - public File getManifestDirectory() { - return srcDirectory; - } - /** - * The new component wizard uses {@link NamedModuleTemplate#getName()} for the default package - * name of the new component. If we can figure it out from the target directory here, then we can - * pass it to the new component wizard. - */ - private static String getPackageName(Project project, VirtualFile targetDirectory) { - PsiDirectory psiDirectory = PsiManager.getInstance(project).findDirectory(targetDirectory); - if (psiDirectory == null) { - return null; - } - PsiPackage psiPackage = JavaDirectoryService.getInstance().getPackage(psiDirectory); - if (psiPackage == null) { - return null; - } - return psiPackage.getQualifiedName(); - } - - public static List getTemplates( - Module module, @Nullable VirtualFile targetDirectory) { - AndroidFacet androidFacet = AndroidFacet.getInstance(module); - if (androidFacet == null) { - return Collections.emptyList(); - } - return getTemplates(androidFacet, targetDirectory); - } - - public static List getTemplates( - AndroidFacet androidFacet, @Nullable VirtualFile targetDirectory) { - Module module = androidFacet.getModule(); - BlazeAndroidModuleTemplate paths = new BlazeAndroidModuleTemplate(); - VirtualFile[] roots = ModuleRootManager.getInstance(module).getContentRoots(); - if (roots.length > 0) { - paths.moduleRoot = VfsUtilCore.virtualToIoFile(roots[0]); - } - IdeaSourceProvider sourceProvider = - SourceProviderManager.getInstance(androidFacet).getSources(); - // If this happens to be a resource package, - // the module name (resource package) would be more descriptive than the facet name (Android). - // Otherwise, .workspace is still better than (Android). - String name = androidFacet.getModule().getName(); - if (targetDirectory != null) { - String packageName = getPackageName(module.getProject(), targetDirectory); - if (packageName != null) { - name = packageName; - } - paths.srcDirectory = VfsUtilCore.virtualToIoFile(targetDirectory); - } else { - // People usually put the manifest file with their sources. - //noinspection OptionalGetWithoutIsPresent - paths.srcDirectory = - Streams.stream(sourceProvider.getManifestDirectoryUrls()) - .map(it -> new File(VfsUtilCore.urlToPath(it))) - .findFirst() - .get(); - } - // We have a res dir if this happens to be a resource module. - paths.resDirectories = - Streams.stream(sourceProvider.getResDirectoryUrls()) - .map(it -> new File(VfsUtilCore.urlToPath(it))) - .collect(Collectors.toList()); - return Collections.singletonList(new NamedModuleTemplate(name, paths)); - } -} diff --git a/aswb/sdkcompat/as231/com/google/idea/blaze/android/projectsystem/BlazeProjectSystem.java b/aswb/sdkcompat/as231/com/google/idea/blaze/android/projectsystem/BlazeProjectSystem.java deleted file mode 100755 index b5b20a1b2a7..00000000000 --- a/aswb/sdkcompat/as231/com/google/idea/blaze/android/projectsystem/BlazeProjectSystem.java +++ /dev/null @@ -1,228 +0,0 @@ -/* - * Copyright 2017 The Bazel Authors. All rights reserved. - * - * 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. - */ -package com.google.idea.blaze.android.projectsystem; - -import static com.android.tools.idea.projectsystem.SourceProvidersKt.emptySourceProvider; -import static org.jetbrains.android.facet.SourceProviderUtil.createSourceProvidersForLegacyModule; - -import com.android.tools.apk.analyzer.AaptInvoker; -import com.android.tools.idea.log.LogWrapper; -import com.android.tools.idea.model.AndroidModel; -import com.android.tools.idea.model.ClassJarProvider; -import com.android.tools.idea.projectsystem.AndroidModuleSystem; -import com.android.tools.idea.projectsystem.AndroidProjectSystem; -import com.android.tools.idea.projectsystem.NamedIdeaSourceProvider; -import com.android.tools.idea.projectsystem.ProjectSystemBuildManager; -import com.android.tools.idea.projectsystem.ProjectSystemSyncManager; -import com.android.tools.idea.projectsystem.ScopeType; -import com.android.tools.idea.projectsystem.SourceProviderManager; -import com.android.tools.idea.projectsystem.SourceProviders; -import com.android.tools.idea.projectsystem.SourceProvidersFactory; -import com.android.tools.idea.projectsystem.SourceProvidersImpl; -import com.android.tools.idea.res.AndroidInnerClassFinder; -import com.android.tools.idea.res.AndroidResourceClassPsiElementFinder; -import com.android.tools.idea.sdk.AndroidSdks; -import com.google.common.collect.ImmutableList; -import com.google.idea.blaze.android.resources.BlazeLightResourceClassService; -import com.google.idea.blaze.android.sync.model.idea.BlazeAndroidModel; -import com.google.idea.blaze.android.sync.model.idea.BlazeClassJarProvider; -import com.google.idea.blaze.base.build.BlazeBuildService; -import com.google.idea.blaze.base.qsync.QuerySync; -import com.intellij.facet.ProjectFacetManager; -import com.intellij.openapi.module.Module; -import com.intellij.openapi.project.Project; -import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.psi.PsiElementFinder; -import com.intellij.psi.search.GlobalSearchScope; -import java.io.File; -import java.nio.file.Path; -import java.util.Arrays; -import java.util.Collection; -import java.util.List; -import java.util.stream.Collectors; -import javax.annotation.Nullable; -import org.jetbrains.android.facet.AndroidFacet; -import org.jetbrains.annotations.NotNull; - -/** - * Base class to implement common methods in {@link AndroidProjectSystem} for blaze with different - * sdk - */ -public class BlazeProjectSystem implements AndroidProjectSystem { - protected final Project project; - protected final ProjectSystemSyncManager syncManager; - protected final List myFinders; - private final BlazeProjectSystemBuildManager buildManager; - - public BlazeProjectSystem(Project project) { - this.project = project; - syncManager = new BlazeProjectSystemSyncManager(project); - buildManager = new BlazeProjectSystemBuildManager(project); - - myFinders = - Arrays.asList( - AndroidInnerClassFinder.INSTANCE, - new AndroidResourceClassPsiElementFinder(getLightResourceClassService())); - } - - @Override - public boolean allowsFileCreation() { - return true; - } - - @Nullable - @Override - public VirtualFile getDefaultApkFile() { - return null; - } - - @Override - public Path getPathToAapt() { - return AaptInvoker.getPathToAapt( - AndroidSdks.getInstance().tryToChooseSdkHandler(), - new LogWrapper(BlazeProjectSystem.class)); - } - - // @Override #api42 - public void buildProject() { - BlazeBuildService.getInstance(project).buildProject(); - } - - // @Override #api42 - public ProjectSystemBuildManager getBuildManager() { - return buildManager; - } - - @Override - public AndroidModuleSystem getModuleSystem(Module module) { - return BlazeModuleSystem.getInstance(module); - } - - @Override - public ProjectSystemSyncManager getSyncManager() { - return syncManager; - } - - @Override - public Collection getPsiElementFinders() { - return myFinders; - } - - @Override - public BlazeLightResourceClassService getLightResourceClassService() { - return BlazeLightResourceClassService.getInstance(project); - } - - @Override - public SourceProvidersFactory getSourceProvidersFactory() { - return new SourceProvidersFactory() { - @Override - public SourceProviders createSourceProvidersFor(AndroidFacet facet) { - BlazeAndroidModel model = ((BlazeAndroidModel) AndroidModel.get(facet)); - if (model != null) { - return createForModel(model); - } else { - return createSourceProvidersForLegacyModule(facet); - } - } - - private SourceProviders createForModel(BlazeAndroidModel model) { - NamedIdeaSourceProvider mainSourceProvider = model.getDefaultSourceProvider(); - if (QuerySync.isEnabled()) { - return new SourceProvidersImpl( - mainSourceProvider, - ImmutableList.of(mainSourceProvider), - ImmutableList.of(), - ImmutableList.of(), - ImmutableList.of(), - ImmutableList.of(mainSourceProvider), - ImmutableList.of(mainSourceProvider), - emptySourceProvider(ScopeType.MAIN), - emptySourceProvider(ScopeType.UNIT_TEST), - emptySourceProvider(ScopeType.ANDROID_TEST), - emptySourceProvider(ScopeType.TEST_FIXTURES)); - } else { - return new SourceProvidersImpl( - mainSourceProvider, - ImmutableList.of(mainSourceProvider), - ImmutableList.of(mainSourceProvider), - ImmutableList.of(mainSourceProvider), - ImmutableList.of(mainSourceProvider), - ImmutableList.of(mainSourceProvider), - ImmutableList.of(mainSourceProvider), - emptySourceProvider(ScopeType.MAIN), - emptySourceProvider(ScopeType.UNIT_TEST), - emptySourceProvider(ScopeType.ANDROID_TEST), - emptySourceProvider(ScopeType.TEST_FIXTURES)); - } - } - }; - } - - // @Override #api212 - public ClassJarProvider getClassJarProvider() { - return new BlazeClassJarProvider(project); - } - - @Override - public Collection getAndroidFacetsWithPackageName( - Project project, String packageName) { - return getAndroidFacetsWithPackageName( - project, packageName, GlobalSearchScope.projectScope(project)); - } - - private Collection getAndroidFacetsWithPackageName( - Project project, String packageName, GlobalSearchScope scope) { - List facets = ProjectFacetManager.getInstance(project).getFacets(AndroidFacet.ID); - return facets.stream() - .filter(facet -> hasPackageName(facet, packageName)) - .filter( - facet -> { - VirtualFile file = SourceProviderManager.getInstance(facet).getMainManifestFile(); - if (file == null) { - return false; - } else { - return scope.contains(file); - } - }) - .collect(Collectors.toList()); - } - - @Override - public Collection getSubmodules() { - return ImmutableList.of(); - } - - @Override - public Collection getBootClasspath(@NotNull Module module) { - // TODO: b/266586669 - return ImmutableList.of(); - } - - private static boolean hasPackageName(AndroidFacet facet, String packageName) { - String nameFromFacet = PackageNameUtils.getPackageName(facet.getModule()); - if (nameFromFacet == null) { - return false; - } - return nameFromFacet.equals(packageName); - } - - @NotNull - // @Override #api223 - public List desugarLibraryConfigFiles(@NotNull Project project) { - return ImmutableList.of(); - } -} diff --git a/aswb/sdkcompat/as231/com/google/idea/blaze/android/projectsystem/PackageNameUtils.java b/aswb/sdkcompat/as231/com/google/idea/blaze/android/projectsystem/PackageNameUtils.java deleted file mode 100644 index 83a7fcd9b20..00000000000 --- a/aswb/sdkcompat/as231/com/google/idea/blaze/android/projectsystem/PackageNameUtils.java +++ /dev/null @@ -1,139 +0,0 @@ -/* - * Copyright 2018 The Bazel Authors. All rights reserved. - * - * 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. - */ -package com.google.idea.blaze.android.projectsystem; - -import com.android.manifmerger.ManifestSystemProperty; -import com.android.tools.idea.model.AndroidManifestIndex; -import com.android.tools.idea.model.AndroidManifestIndexCompat; -import com.android.tools.idea.model.AndroidManifestRawText; -import com.android.tools.idea.model.MergedManifestModificationTracker; -import com.android.tools.idea.projectsystem.ManifestOverrides; -import com.android.tools.idea.projectsystem.SourceProviderManager; -import com.google.common.annotations.VisibleForTesting; -import com.google.idea.common.experiments.BoolExperiment; -import com.intellij.openapi.module.Module; -import com.intellij.openapi.project.DumbService; -import com.intellij.openapi.project.IndexNotReadyException; -import com.intellij.openapi.project.Project; -import com.intellij.openapi.util.text.StringUtil; -import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.psi.util.CachedValueProvider; -import com.intellij.psi.util.CachedValuesManager; -import org.jetbrains.android.dom.manifest.AndroidManifestUtils; -import org.jetbrains.android.dom.manifest.AndroidManifestXmlFile; -import org.jetbrains.android.facet.AndroidFacet; -import org.jetbrains.annotations.Nullable; - -/** Utilities to obtain the package name for a given module. */ -public class PackageNameUtils { - /** - * Determines whether we use the {@link AndroidManifestIndex} to obtain the raw text package name - * from a module's primary manifest. Note that we still won't use the index if {@link - * AndroidManifestIndex#indexEnabled()} returns false. - * - * @see PackageNameUtils#getPackageName(Module) - * @see PackageNameUtils#doGetPackageName(AndroidFacet, boolean) - */ - private static final BoolExperiment USE_ANDROID_MANIFEST_INDEX = - new BoolExperiment("use.android.manifest.index", true); - - @Nullable - public static String getPackageName(Module module) { - AndroidFacet facet = AndroidFacet.getInstance(module); - assert facet != null; - return CachedValuesManager.getManager(module.getProject()) - .getCachedValue( - facet, - () -> { - boolean useIndex = - AndroidManifestIndexCompat.indexEnabled() - && USE_ANDROID_MANIFEST_INDEX.getValue(); - String packageName = doGetPackageName(facet, useIndex); - return CachedValueProvider.Result.create( - StringUtil.nullize(packageName, true), - MergedManifestModificationTracker.getInstance(module)); - }); - } - - /** - * Returns the package name from an Android module's merged manifest without actually computing - * the whole merged manifest. This is either - * - *
    - *
  1. The {@link ManifestSystemProperty#PACKAGE} manifest override if one is specified by the - * corresponding BUILD target, or - *
  2. The result of applying placeholder substitution to the raw package name from the module's - * primary manifest - *
- * - * In the second case, we try to obtain the raw package name using the {@link - * AndroidManifestIndex} if {@code useIndex} is true. If {@code useIndex} is false or querying the - * index fails for some reason (e.g. this method is called in a read action but not a *smart* read - * action), then we resort to parsing the PSI of the module's primary manifest to get the raw - * package name. - * - * @see AndroidModuleSystem#getManifestOverrides() - * @see AndroidModuleSystem#getPackageName() - */ - @Nullable - @VisibleForTesting - static String doGetPackageName(AndroidFacet facet, boolean useIndex) { - ManifestOverrides manifestOverrides = - BlazeModuleSystem.getInstance(facet.getModule()).getManifestOverrides(); - String packageOverride = - ManifestValueProcessor.getPackageOverride(manifestOverrides.getDirectOverrides()); - if (packageOverride != null) { - return packageOverride; - } - String rawPackageName = null; - if (useIndex) { - rawPackageName = getRawPackageNameFromIndex(facet); - } - if (rawPackageName == null) { - rawPackageName = getRawPackageNameFromPsi(facet); - } - return rawPackageName == null ? null : manifestOverrides.resolvePlaceholders(rawPackageName); - } - - @Nullable - private static String getRawPackageNameFromIndex(AndroidFacet facet) { - VirtualFile primaryManifest = SourceProviderManager.getInstance(facet).getMainManifestFile(); - if (primaryManifest == null) { - return null; - } - Project project = facet.getModule().getProject(); - try { - AndroidManifestRawText manifestRawText = - DumbService.getInstance(project) - .runReadActionInSmartMode( - () -> AndroidManifestIndex.getDataForManifestFile(project, primaryManifest)); - return manifestRawText == null ? null : manifestRawText.getPackageName(); - } catch (IndexNotReadyException e) { - // TODO(142681129): runReadActionInSmartMode doesn't work if we already have read access. - // We need to refactor the callers of AndroidManifestUtils#getPackage to require a *smart* - // read action, at which point we can remove this try-catch. - return null; - } - } - - @Nullable - private static String getRawPackageNameFromPsi(AndroidFacet facet) { - AndroidManifestXmlFile primaryManifest = AndroidManifestUtils.getPrimaryManifestXml(facet); - return primaryManifest == null ? null : primaryManifest.getPackageName(); - } - - private PackageNameUtils() {} -} diff --git a/aswb/sdkcompat/as231/com/google/idea/blaze/android/resources/BlazeRClass.java b/aswb/sdkcompat/as231/com/google/idea/blaze/android/resources/BlazeRClass.java deleted file mode 100644 index f8cfbac94a2..00000000000 --- a/aswb/sdkcompat/as231/com/google/idea/blaze/android/resources/BlazeRClass.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright 2018 The Bazel Authors. All rights reserved. - * - * 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. - */ -package com.google.idea.blaze.android.resources; - -import static org.jetbrains.android.AndroidResolveScopeEnlarger.LIGHT_CLASS_KEY; -import static org.jetbrains.android.AndroidResolveScopeEnlarger.MODULE_POINTER_KEY; - -import com.android.ide.common.rendering.api.ResourceNamespace; -import com.android.tools.idea.res.LocalResourceRepository; -import com.android.tools.idea.res.ResourceRepositoryRClass; -import com.android.tools.idea.res.StudioResourceRepositoryManager; -import com.intellij.openapi.module.Module; -import com.intellij.openapi.module.ModulePointerManager; -import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.psi.PsiManager; -import org.jetbrains.android.augment.AndroidLightField; -import org.jetbrains.android.facet.AndroidFacet; - -/** Blaze implementation of an R class based on resource repositories. */ -public class BlazeRClass extends ResourceRepositoryRClass { - - private final AndroidFacet androidFacet; - - public BlazeRClass(PsiManager psiManager, AndroidFacet androidFacet, String packageName) { - super( - psiManager, - new ResourcesSource() { - @Override - public String getPackageName() { - return packageName; - } - - // @Override #api4.1 - public Transitivity getTransitivity() { - return Transitivity.TRANSITIVE; - } - - @Override - public StudioResourceRepositoryManager getResourceRepositoryManager() { - return StudioResourceRepositoryManager.getInstance(androidFacet); - } - - @Override - public LocalResourceRepository getResourceRepository() { - return StudioResourceRepositoryManager.getAppResources(androidFacet); - } - - @Override - public ResourceNamespace getResourceNamespace() { - return ResourceNamespace.RES_AUTO; - } - - @Override - public AndroidLightField.FieldModifier getFieldModifier() { - return AndroidLightField.FieldModifier.NON_FINAL; - } - }); - this.androidFacet = androidFacet; - setModuleInfo(getModule(), false); - VirtualFile virtualFile = myFile.getViewProvider().getVirtualFile(); - virtualFile.putUserData( - MODULE_POINTER_KEY, ModulePointerManager.getInstance(getProject()).create(getModule())); - virtualFile.putUserData(LIGHT_CLASS_KEY, ResourceRepositoryRClass.class); - } - - public Module getModule() { - return androidFacet.getModule(); - } -} diff --git a/aswb/sdkcompat/as231/com/google/idea/blaze/android/run/BlazeAndroidDeploymentService.java b/aswb/sdkcompat/as231/com/google/idea/blaze/android/run/BlazeAndroidDeploymentService.java deleted file mode 100644 index 6cc3a63459e..00000000000 --- a/aswb/sdkcompat/as231/com/google/idea/blaze/android/run/BlazeAndroidDeploymentService.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright 2020 The Bazel Authors. All rights reserved. - * - * 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. - */ -package com.google.idea.blaze.android.run; - -import com.android.tools.idea.run.ApkInfo; -import com.android.tools.idea.run.LaunchOptions; -import com.android.tools.idea.run.blaze.BlazeLaunchTask; -import com.android.tools.idea.run.tasks.DeployTask; -import com.android.tools.idea.run.tasks.DeployTasksCompat; -import com.intellij.openapi.project.Project; -import java.util.Collection; - -/** A service that provides {@link DeployTask}. */ -public interface BlazeAndroidDeploymentService { - static BlazeAndroidDeploymentService getInstance(Project project) { - return project.getService(BlazeAndroidDeploymentService.class); - } - - /** Returns a {@link DeployTask} to deploy the given files and launch options. */ - BlazeLaunchTask getDeployTask(Collection packages, LaunchOptions launchOptions); - - /** A default implementation that uses {@link DeployTasksCompat#createDeployTask}. */ - class DefaultDeploymentService implements BlazeAndroidDeploymentService { - private final Project project; - - public DefaultDeploymentService(Project project) { - this.project = project; - } - - @Override - public BlazeLaunchTask getDeployTask( - Collection packages, LaunchOptions launchOptions) { - return DeployTasksCompat.createDeployTask(project, packages, launchOptions); - } - } -} diff --git a/aswb/sdkcompat/as231/com/google/idea/blaze/android/run/BlazeCommandAndroidDebuggerInfoProvider.java b/aswb/sdkcompat/as231/com/google/idea/blaze/android/run/BlazeCommandAndroidDebuggerInfoProvider.java deleted file mode 100644 index 03dd9f80da7..00000000000 --- a/aswb/sdkcompat/as231/com/google/idea/blaze/android/run/BlazeCommandAndroidDebuggerInfoProvider.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright (C) 2020 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. - */ -package com.google.idea.blaze.android.run; - -import com.android.tools.idea.execution.common.debug.AndroidDebugger; -import com.android.tools.idea.execution.common.debug.AndroidDebuggerState; -import com.android.tools.idea.execution.common.debug.impl.java.AndroidJavaDebugger; -import com.android.tools.idea.run.editor.AndroidDebuggerInfoProvider; -import com.google.idea.blaze.android.cppimpl.debug.BlazeNativeAndroidDebugger; -import com.google.idea.blaze.android.run.binary.BlazeAndroidBinaryRunConfigurationState; -import com.google.idea.blaze.android.run.test.BlazeAndroidTestRunConfigurationState; -import com.google.idea.blaze.base.model.BlazeProjectData; -import com.google.idea.blaze.base.run.BlazeCommandRunConfiguration; -import com.google.idea.blaze.base.sync.data.BlazeProjectDataManager; -import com.intellij.execution.configurations.RunConfiguration; -import com.intellij.openapi.project.Project; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import org.jetbrains.annotations.Nullable; - -/** Provider of blaze project compatible android debuggers. */ -public class BlazeCommandAndroidDebuggerInfoProvider implements AndroidDebuggerInfoProvider { - @Override - public boolean supportsProject(Project project) { - BlazeProjectData blazeProjectData = - BlazeProjectDataManager.getInstance(project).getBlazeProjectData(); - return blazeProjectData != null; - } - - @Override - @SuppressWarnings("rawtypes") // List includes multiple AndroidDebuggerState types. - public List getAndroidDebuggers(RunConfiguration configuration) { - if (getCommonState(configuration) != null) { - return Arrays.asList(new BlazeNativeAndroidDebugger(), new AndroidJavaDebugger()); - } - return Collections.emptyList(); - } - - @Nullable - @Override - public AndroidDebugger getSelectedAndroidDebugger( - RunConfiguration configuration) { - // b/170159822 Always return java debugger because BlazeAutoAndroidDebugger doesn't work and - // users likely want the java debugger not the native debugger. - return new AndroidJavaDebugger(); - } - - @Nullable - @Override - public AndroidDebuggerState getSelectedAndroidDebuggerState(RunConfiguration configuration) { - AndroidDebugger debugger = getSelectedAndroidDebugger(configuration); - if (debugger == null) { - return null; - } - return debugger.createState(); - } - - @Nullable - private BlazeAndroidRunConfigurationCommonState getCommonState(RunConfiguration configuration) { - if (!(configuration instanceof BlazeCommandRunConfiguration)) { - return null; - } - BlazeCommandRunConfiguration blazeRunConfig = (BlazeCommandRunConfiguration) configuration; - BlazeAndroidBinaryRunConfigurationState binaryState = - blazeRunConfig.getHandlerStateIfType(BlazeAndroidBinaryRunConfigurationState.class); - if (binaryState != null) { - return binaryState.getCommonState(); - } - BlazeAndroidTestRunConfigurationState testState = - blazeRunConfig.getHandlerStateIfType(BlazeAndroidTestRunConfigurationState.class); - if (testState != null) { - return testState.getCommonState(); - } - return null; - } -} diff --git a/aswb/sdkcompat/as231/com/google/idea/blaze/android/run/binary/BlazeAndroidBinaryApplicationLaunchTaskProvider.java b/aswb/sdkcompat/as231/com/google/idea/blaze/android/run/binary/BlazeAndroidBinaryApplicationLaunchTaskProvider.java deleted file mode 100644 index 8a74f3d458f..00000000000 --- a/aswb/sdkcompat/as231/com/google/idea/blaze/android/run/binary/BlazeAndroidBinaryApplicationLaunchTaskProvider.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright 2016 The Bazel Authors. All rights reserved. - * - * 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. - */ -package com.google.idea.blaze.android.run.binary; - -import com.android.tools.idea.run.ApkProvisionException; -import com.android.tools.idea.run.ApplicationIdProvider; -import com.android.tools.idea.run.activity.StartActivityFlagsProvider; -import com.android.tools.idea.run.blaze.BlazeLaunchTask; -import com.android.tools.idea.run.blaze.BlazeLaunchTaskWrapper; -import com.android.tools.idea.run.tasks.AndroidDeepLinkLaunchTask; -import com.android.tools.idea.run.tasks.DefaultActivityLaunchTask; -import com.android.tools.idea.run.tasks.SpecificActivityLaunchTask; -import com.google.idea.blaze.android.manifest.ManifestParser; -import com.intellij.execution.ExecutionException; -import com.intellij.openapi.diagnostic.Logger; - -/** Provides the launch task for android_binary */ -public class BlazeAndroidBinaryApplicationLaunchTaskProvider { - private static final Logger LOG = - Logger.getInstance(BlazeAndroidBinaryApplicationLaunchTaskProvider.class); - - public static BlazeLaunchTask getApplicationLaunchTask( - ApplicationIdProvider applicationIdProvider, - ManifestParser.ParsedManifest mergedManifestParsedManifest, - BlazeAndroidBinaryRunConfigurationState configState, - StartActivityFlagsProvider startActivityFlagsProvider) - throws ExecutionException { - try { - String applicationId = applicationIdProvider.getPackageName(); - - switch (configState.getMode()) { - case BlazeAndroidBinaryRunConfigurationState.LAUNCH_DEFAULT_ACTIVITY: - BlazeDefaultActivityLocator activityLocator = - new BlazeDefaultActivityLocator(mergedManifestParsedManifest); - return new BlazeLaunchTaskWrapper( - new DefaultActivityLaunchTask( - applicationId, activityLocator, startActivityFlagsProvider)); - case BlazeAndroidBinaryRunConfigurationState.LAUNCH_SPECIFIC_ACTIVITY: - return new BlazeLaunchTaskWrapper( - new SpecificActivityLaunchTask( - applicationId, configState.getActivityClass(), startActivityFlagsProvider)); - case BlazeAndroidBinaryRunConfigurationState.LAUNCH_DEEP_LINK: - return new BlazeLaunchTaskWrapper( - new AndroidDeepLinkLaunchTask(configState.getDeepLink(), startActivityFlagsProvider)); - case BlazeAndroidBinaryRunConfigurationState.DO_NOTHING: - default: - return null; - } - } catch (ApkProvisionException e) { - throw new ExecutionException("Unable to identify application id"); - } - } -} diff --git a/aswb/sdkcompat/as231/com/google/idea/blaze/android/run/binary/BlazeAndroidBinaryNormalBuildRunContext.java b/aswb/sdkcompat/as231/com/google/idea/blaze/android/run/binary/BlazeAndroidBinaryNormalBuildRunContext.java deleted file mode 100644 index 6b2d10e2dac..00000000000 --- a/aswb/sdkcompat/as231/com/google/idea/blaze/android/run/binary/BlazeAndroidBinaryNormalBuildRunContext.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright 2019 The Bazel Authors. All rights reserved. - * - * 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. - */ -package com.google.idea.blaze.android.run.binary; - -import static com.android.tools.idea.run.tasks.DefaultConnectDebuggerTaskKt.getBaseDebuggerTask; - -import com.android.tools.idea.execution.common.debug.AndroidDebugger; -import com.android.tools.idea.execution.common.debug.AndroidDebuggerState; -import com.android.tools.idea.run.ApkProvisionException; -import com.android.tools.idea.run.LaunchOptions; -import com.android.tools.idea.run.activity.DefaultStartActivityFlagsProvider; -import com.android.tools.idea.run.activity.StartActivityFlagsProvider; -import com.android.tools.idea.run.blaze.BlazeLaunchTask; -import com.android.tools.idea.run.tasks.ConnectDebuggerTask; -import com.google.idea.blaze.android.run.deployinfo.BlazeAndroidDeployInfo; -import com.google.idea.blaze.android.run.runner.ApkBuildStep; -import com.intellij.execution.ExecutionException; -import com.intellij.execution.Executor; -import com.intellij.execution.configurations.RunConfiguration; -import com.intellij.execution.runners.ExecutionEnvironment; -import com.intellij.openapi.project.Project; -import javax.annotation.Nullable; -import org.jetbrains.android.facet.AndroidFacet; - -/** Compat for #api212 */ -public class BlazeAndroidBinaryNormalBuildRunContext - extends BlazeAndroidBinaryNormalBuildRunContextBase { - BlazeAndroidBinaryNormalBuildRunContext( - Project project, - AndroidFacet facet, - RunConfiguration runConfiguration, - ExecutionEnvironment env, - BlazeAndroidBinaryRunConfigurationState configState, - ApkBuildStep buildStep, - String launchId) { - super(project, facet, runConfiguration, env, configState, buildStep, launchId); - } - - @Override - public BlazeLaunchTask getApplicationLaunchTask( - LaunchOptions launchOptions, @Nullable Integer userId, String contributorsAmStartOptions) - throws ExecutionException { - String extraFlags = UserIdHelper.getFlagsFromUserId(userId); - if (!contributorsAmStartOptions.isEmpty()) { - extraFlags += (extraFlags.isEmpty() ? "" : " ") + contributorsAmStartOptions; - } - - final StartActivityFlagsProvider startActivityFlagsProvider = - new DefaultStartActivityFlagsProvider(project, launchOptions.isDebug(), extraFlags); - - BlazeAndroidDeployInfo deployInfo; - try { - deployInfo = buildStep.getDeployInfo(); - } catch (ApkProvisionException e) { - throw new ExecutionException(e); - } - - return BlazeAndroidBinaryApplicationLaunchTaskProvider.getApplicationLaunchTask( - applicationIdProvider, - deployInfo.getMergedManifest(), - configState, - startActivityFlagsProvider); - } - - @Nullable - @Override - @SuppressWarnings("unchecked") - public ConnectDebuggerTask getDebuggerTask( - AndroidDebugger androidDebugger, AndroidDebuggerState androidDebuggerState) { - return getBaseDebuggerTask(androidDebugger, androidDebuggerState, env, facet); - } - - @Override - public Executor getExecutor() { - return env.getExecutor(); - } -} diff --git a/aswb/sdkcompat/as231/com/google/idea/blaze/android/run/binary/BlazeAndroidBinaryNormalBuildRunContextBase.java b/aswb/sdkcompat/as231/com/google/idea/blaze/android/run/binary/BlazeAndroidBinaryNormalBuildRunContextBase.java deleted file mode 100644 index bc3517e8fe8..00000000000 --- a/aswb/sdkcompat/as231/com/google/idea/blaze/android/run/binary/BlazeAndroidBinaryNormalBuildRunContextBase.java +++ /dev/null @@ -1,177 +0,0 @@ -/* - * Copyright 2016 The Bazel Authors. All rights reserved. - * - * 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. - */ -package com.google.idea.blaze.android.run.binary; - -import static com.google.idea.blaze.android.run.runner.BlazeAndroidLaunchTasksProvider.NATIVE_DEBUGGING_ENABLED; - -import com.android.ddmlib.IDevice; -import com.android.tools.idea.gradle.util.DynamicAppUtils; -import com.android.tools.idea.run.ApkFileUnit; -import com.android.tools.idea.run.ApkInfo; -import com.android.tools.idea.run.ApkProvider; -import com.android.tools.idea.run.ApkProvisionException; -import com.android.tools.idea.run.ApplicationIdProvider; -import com.android.tools.idea.run.ConsoleProvider; -import com.android.tools.idea.run.LaunchOptions; -import com.android.tools.idea.run.blaze.BlazeLaunchTask; -import com.android.tools.idea.run.blaze.BlazeLaunchTasksProvider; -import com.android.tools.idea.run.editor.ProfilerState; -import com.android.tools.idea.run.tasks.DeployTasksCompat; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; -import com.google.idea.blaze.android.run.deployinfo.BlazeApkProviderService; -import com.google.idea.blaze.android.run.runner.ApkBuildStep; -import com.google.idea.blaze.android.run.runner.BlazeAndroidDeviceSelector; -import com.google.idea.blaze.android.run.runner.BlazeAndroidLaunchTasksProvider; -import com.google.idea.blaze.android.run.runner.BlazeAndroidRunContext; -import com.intellij.execution.ExecutionException; -import com.intellij.execution.configurations.RunConfiguration; -import com.intellij.execution.runners.ExecutionEnvironment; -import com.intellij.openapi.project.Project; -import java.util.Collection; -import java.util.List; -import java.util.stream.Collectors; -import javax.annotation.Nullable; -import org.jetbrains.android.facet.AndroidFacet; -import org.jetbrains.annotations.NotNull; - -/** Run context for android_binary. */ -public abstract class BlazeAndroidBinaryNormalBuildRunContextBase - implements BlazeAndroidRunContext { - protected final Project project; - protected final AndroidFacet facet; - protected final RunConfiguration runConfiguration; - protected final ExecutionEnvironment env; - protected final BlazeAndroidBinaryRunConfigurationState configState; - protected final ConsoleProvider consoleProvider; - protected final ApkBuildStep buildStep; - protected final ApkProvider apkProvider; - protected final ApplicationIdProvider applicationIdProvider; - private final String launchId; - - BlazeAndroidBinaryNormalBuildRunContextBase( - Project project, - AndroidFacet facet, - RunConfiguration runConfiguration, - ExecutionEnvironment env, - BlazeAndroidBinaryRunConfigurationState configState, - ApkBuildStep buildStep, - String launchId) { - this.project = project; - this.facet = facet; - this.runConfiguration = runConfiguration; - this.env = env; - this.configState = configState; - this.consoleProvider = new BlazeAndroidBinaryConsoleProvider(project); - this.buildStep = buildStep; - this.apkProvider = BlazeApkProviderService.getInstance().getApkProvider(project, buildStep); - this.applicationIdProvider = new BlazeAndroidBinaryApplicationIdProvider(buildStep); - this.launchId = launchId; - } - - @Override - public BlazeAndroidDeviceSelector getDeviceSelector() { - return new BlazeAndroidDeviceSelector.NormalDeviceSelector(); - } - - @Override - public void augmentLaunchOptions(LaunchOptions.Builder options) { - options.setDeploy(true).setOpenLogcatAutomatically(configState.showLogcatAutomatically()); - options.addExtraOptions( - ImmutableMap.of( - "android.profilers.state", // Not used after #api211 - configState.getProfilerState(), - NATIVE_DEBUGGING_ENABLED, - configState.getCommonState().isNativeDebuggingEnabled())); - } - - @Override - public ConsoleProvider getConsoleProvider() { - return consoleProvider; - } - - @Override - public ApplicationIdProvider getApplicationIdProvider() throws ExecutionException { - return applicationIdProvider; - } - - @Override - public ApkBuildStep getBuildStep() { - return buildStep; - } - - @Nullable - @Override - public Integer getUserId(IDevice device) throws ExecutionException { - return UserIdHelper.getUserIdFromConfigurationState(project, device, configState); - } - - @Override - public BlazeLaunchTasksProvider getLaunchTasksProvider(LaunchOptions.Builder launchOptionsBuilder) - throws ExecutionException { - return new BlazeAndroidLaunchTasksProvider( - project, this, applicationIdProvider, launchOptionsBuilder); - } - - @Override - public String getAmStartOptions() { - return configState.getAmStartOptions(); - } - - @Override - public ProfilerState getProfileState() { - return configState.getProfilerState(); - } - - @Nullable - @Override - public ImmutableList getDeployTasks(IDevice device, LaunchOptions launchOptions) - throws ExecutionException { - BlazeLaunchTask deployTask = - DeployTasksCompat.createDeployTask( - project, getApkInfoToInstall(device, launchOptions, apkProvider), launchOptions); - return ImmutableList.of(new DeploymentTimingReporterTask(launchId, deployTask)); - } - - /** Returns a list of APKs excluding any APKs for features that are disabled. */ - public static List getApkInfoToInstall( - IDevice device, LaunchOptions launchOptions, ApkProvider apkProvider) - throws ExecutionException { - Collection apks; - try { - apks = apkProvider.getApks(device); - } catch (ApkProvisionException e) { - throw new ExecutionException(e); - } - List disabledFeatures = launchOptions.getDisabledDynamicFeatures(); - return apks.stream() - .map(apk -> getApkInfoToInstall(apk, disabledFeatures)) - .collect(Collectors.toList()); - } - - @NotNull - private static ApkInfo getApkInfoToInstall(ApkInfo apkInfo, List disabledFeatures) { - if (apkInfo.getFiles().size() > 1) { - List filteredApks = - apkInfo.getFiles().stream() - .filter(feature -> DynamicAppUtils.isFeatureEnabled(disabledFeatures, feature)) - .collect(Collectors.toList()); - return new ApkInfo(filteredApks, apkInfo.getApplicationId()); - } else { - return apkInfo; - } - } -} diff --git a/aswb/sdkcompat/as231/com/google/idea/blaze/android/run/binary/BlazeAndroidBinaryNormalBuildRunContextCompat.java b/aswb/sdkcompat/as231/com/google/idea/blaze/android/run/binary/BlazeAndroidBinaryNormalBuildRunContextCompat.java deleted file mode 100644 index d54c472c84b..00000000000 --- a/aswb/sdkcompat/as231/com/google/idea/blaze/android/run/binary/BlazeAndroidBinaryNormalBuildRunContextCompat.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright 2022 The Bazel Authors. All rights reserved. - * - * 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. - */ -package com.google.idea.blaze.android.run.binary; - -import static com.android.tools.idea.run.tasks.DefaultConnectDebuggerTaskKt.getBaseDebuggerTask; - -import com.android.tools.idea.execution.common.debug.AndroidDebugger; -import com.android.tools.idea.execution.common.debug.AndroidDebuggerState; -import com.android.tools.idea.run.tasks.ConnectDebuggerTask; -import com.google.idea.blaze.android.run.runner.ApkBuildStep; -import com.intellij.execution.configurations.RunConfiguration; -import com.intellij.execution.runners.ExecutionEnvironment; -import com.intellij.openapi.project.Project; -import javax.annotation.Nullable; -import org.jetbrains.android.facet.AndroidFacet; - -/** Compat class for {@link BlazeAndroidBinaryNormalBuildRunContext}. */ -public class BlazeAndroidBinaryNormalBuildRunContextCompat - extends BlazeAndroidBinaryNormalBuildRunContext { - - BlazeAndroidBinaryNormalBuildRunContextCompat( - Project project, - AndroidFacet facet, - RunConfiguration runConfiguration, - ExecutionEnvironment env, - BlazeAndroidBinaryRunConfigurationState configState, - ApkBuildStep buildStep, - String launchId) { - super(project, facet, runConfiguration, env, configState, buildStep, launchId); - } - - @Nullable - @Override - @SuppressWarnings("unchecked") - public ConnectDebuggerTask getDebuggerTask( - AndroidDebugger androidDebugger, AndroidDebuggerState androidDebuggerState) { - return getBaseDebuggerTask(androidDebugger, androidDebuggerState, env, facet); - } -} diff --git a/aswb/sdkcompat/as231/com/google/idea/blaze/android/run/binary/BlazeAndroidBinaryProgramRunner.java b/aswb/sdkcompat/as231/com/google/idea/blaze/android/run/binary/BlazeAndroidBinaryProgramRunner.java deleted file mode 100644 index 50f42d4b2dd..00000000000 --- a/aswb/sdkcompat/as231/com/google/idea/blaze/android/run/binary/BlazeAndroidBinaryProgramRunner.java +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Copyright 2016 The Bazel Authors. All rights reserved. - * - * 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. - */ -package com.google.idea.blaze.android.run.binary; - -import static com.intellij.openapi.application.ModalityState.NON_MODAL; - -import com.android.tools.idea.profilers.ProfileRunExecutor; -import com.android.tools.idea.run.configuration.execution.AndroidConfigurationExecutor; -import com.google.idea.blaze.android.run.BlazeAndroidRunConfigurationHandler; -import com.intellij.execution.ExecutionException; -import com.intellij.execution.ExecutionResult; -import com.intellij.execution.Executor; -import com.intellij.execution.configurations.RunProfile; -import com.intellij.execution.configurations.RunProfileState; -import com.intellij.execution.configurations.RunnerSettings; -import com.intellij.execution.executors.DefaultDebugExecutor; -import com.intellij.execution.executors.DefaultRunExecutor; -import com.intellij.execution.runners.AsyncProgramRunner; -import com.intellij.execution.runners.ExecutionEnvironment; -import com.intellij.execution.runners.RunContentBuilder; -import com.intellij.execution.ui.RunContentDescriptor; -import com.intellij.openapi.application.ActionsKt; -import com.intellij.openapi.fileEditor.FileDocumentManager; -import com.intellij.openapi.progress.ProgressIndicator; -import com.intellij.openapi.progress.ProgressManager; -import com.intellij.openapi.progress.Task; -import org.jetbrains.concurrency.AsyncPromise; -import org.jetbrains.concurrency.Promise; - -/** Program runner for configurations from {@link BlazeAndroidBinaryRunConfigurationHandler}. */ -public class BlazeAndroidBinaryProgramRunner extends AsyncProgramRunner { - @Override - public boolean canRun(String executorId, RunProfile profile) { - BlazeAndroidRunConfigurationHandler handler = - BlazeAndroidRunConfigurationHandler.getHandlerFrom(profile); - if (!(handler instanceof BlazeAndroidBinaryRunConfigurationHandler)) { - return false; - } - return (DefaultDebugExecutor.EXECUTOR_ID.equals(executorId) - || DefaultRunExecutor.EXECUTOR_ID.equals(executorId) - || ProfileRunExecutor.EXECUTOR_ID.equals(executorId)); - } - - @Override - protected Promise execute( - ExecutionEnvironment environment, RunProfileState state) { - FileDocumentManager.getInstance().saveAllDocuments(); - - AsyncPromise promise = new AsyncPromise<>(); - - ProgressManager.getInstance() - .run( - new Task.Backgroundable(environment.getProject(), "Launching ${runProfile.name}") { - @Override - public void run(ProgressIndicator indicator) { - try { - RunContentDescriptor descriptor; - if (state instanceof AndroidConfigurationExecutor) { - AndroidConfigurationExecutor configurationExecutor = - (AndroidConfigurationExecutor) state; - Executor executor = environment.getExecutor(); - if (executor.getId().equals(DefaultDebugExecutor.EXECUTOR_ID)) { - descriptor = configurationExecutor.debug(indicator); - } else if (executor.getId().equals(DefaultRunExecutor.EXECUTOR_ID) - || executor.getId().equals(ProfileRunExecutor.EXECUTOR_ID)) { - descriptor = configurationExecutor.run(indicator); - } else { - throw new ExecutionException("Unsupported executor"); - } - } else { - descriptor = doExecute(state, environment); - } - promise.setResult(descriptor); - } catch (ExecutionException e) { - boolean unused = promise.setError(e); - } - } - - @Override - public void onCancel() { - super.onCancel(); - promise.setResult(null); - } - }); - - return promise; - } - - private RunContentDescriptor doExecute( - final RunProfileState state, final ExecutionEnvironment env) throws ExecutionException { - ExecutionResult result = state.execute(env.getExecutor(), this); - return ActionsKt.invokeAndWaitIfNeeded( - NON_MODAL, - () -> new RunContentBuilder(result, env).showRunContent(env.getContentToReuse())); - } - - @Override - public String getRunnerId() { - return "AndroidBinaryProgramRunner"; - } -} diff --git a/aswb/sdkcompat/as231/com/google/idea/blaze/android/run/binary/DeploymentTimingReporterTask.java b/aswb/sdkcompat/as231/com/google/idea/blaze/android/run/binary/DeploymentTimingReporterTask.java deleted file mode 100644 index 81696ad5b1e..00000000000 --- a/aswb/sdkcompat/as231/com/google/idea/blaze/android/run/binary/DeploymentTimingReporterTask.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright 2021 The Bazel Authors. All rights reserved. - * - * 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. - */ -package com.google.idea.blaze.android.run.binary; - -import com.android.tools.idea.run.blaze.BlazeLaunchContext; -import com.android.tools.idea.run.blaze.BlazeLaunchTask; -import com.google.common.base.Stopwatch; -import com.google.idea.blaze.android.run.LaunchMetrics; -import com.intellij.execution.ExecutionException; - -/** A wrapper launch task that wraps the given deployment task and logs the deployment latency. */ -public class DeploymentTimingReporterTask implements BlazeLaunchTask { - private final BlazeLaunchTask deployTask; - private final String launchId; - - public DeploymentTimingReporterTask(String launchId, BlazeLaunchTask deployTask) { - this.launchId = launchId; - this.deployTask = deployTask; - } - - @Override - public void run(BlazeLaunchContext launchContext) throws ExecutionException { - Stopwatch s = Stopwatch.createStarted(); - try { - deployTask.run(launchContext); - LaunchMetrics.logDeploymentTime(launchId, s.elapsed(), true); - } catch (ExecutionException e) { - LaunchMetrics.logDeploymentTime(launchId, s.elapsed(), false); - throw e; - } - } -} diff --git a/aswb/sdkcompat/as231/com/google/idea/blaze/android/run/binary/UserIdHelper.java b/aswb/sdkcompat/as231/com/google/idea/blaze/android/run/binary/UserIdHelper.java deleted file mode 100644 index ab71d4747c2..00000000000 --- a/aswb/sdkcompat/as231/com/google/idea/blaze/android/run/binary/UserIdHelper.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright 2016 The Bazel Authors. All rights reserved. - * - * 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. - */ -package com.google.idea.blaze.android.run.binary; - -import com.android.ddmlib.AdbCommandRejectedException; -import com.android.ddmlib.CollectingOutputReceiver; -import com.android.ddmlib.IDevice; -import com.android.ddmlib.ShellCommandUnresponsiveException; -import com.android.ddmlib.TimeoutException; -import com.android.tools.idea.execution.common.RunConfigurationNotifier; -import com.intellij.execution.ExecutionException; -import com.intellij.openapi.project.Project; -import java.io.IOException; -import java.util.regex.Matcher; -import java.util.regex.Pattern; -import javax.annotation.Nullable; - -/** Helpers for user id */ -public final class UserIdHelper { - private UserIdHelper() {} - - private static final Pattern USER_ID_REGEX = - Pattern.compile("UserInfo\\{([0-9]+):Work profile:[0-9]+\\}"); - - @Nullable - public static Integer getUserIdFromConfigurationState( - Project project, IDevice device, BlazeAndroidBinaryRunConfigurationState state) - throws ExecutionException { - if (state.useWorkProfileIfPresent()) { - try { - Integer userId = getWorkProfileId(device); - if (userId == null) { - RunConfigurationNotifier.INSTANCE.notifyWarning( - project, - "", - "Could not locate work profile on selected device. Launching default user."); - } - return userId; - } catch (TimeoutException - | AdbCommandRejectedException - | ShellCommandUnresponsiveException - | IOException e) { - throw new ExecutionException(e); - } - } - return state.getUserId(); - } - - @Nullable - public static Integer getWorkProfileId(IDevice device) - throws TimeoutException, AdbCommandRejectedException, ShellCommandUnresponsiveException, - IOException { - CollectingOutputReceiver receiver = new CollectingOutputReceiver(); - device.executeShellCommand("pm list users", receiver); - String result = receiver.getOutput(); - Matcher matcher = USER_ID_REGEX.matcher(result); - if (matcher.find()) { - return Integer.parseInt(matcher.group(1)); - } - return null; - } - - public static String getFlagsFromUserId(@Nullable Integer userId) { - return userId != null ? ("--user " + userId.intValue()) : ""; - } -} diff --git a/aswb/sdkcompat/as231/com/google/idea/blaze/android/run/binary/mobileinstall/BlazeAndroidBinaryMobileInstallRunContext.java b/aswb/sdkcompat/as231/com/google/idea/blaze/android/run/binary/mobileinstall/BlazeAndroidBinaryMobileInstallRunContext.java deleted file mode 100644 index c49082cfdaa..00000000000 --- a/aswb/sdkcompat/as231/com/google/idea/blaze/android/run/binary/mobileinstall/BlazeAndroidBinaryMobileInstallRunContext.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright 2016 The Bazel Authors. All rights reserved. - * - * 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. - */ -package com.google.idea.blaze.android.run.binary.mobileinstall; - -import static com.android.tools.idea.run.tasks.DefaultConnectDebuggerTaskKt.getBaseDebuggerTask; - -import com.android.tools.idea.execution.common.debug.AndroidDebugger; -import com.android.tools.idea.execution.common.debug.AndroidDebuggerState; -import com.android.tools.idea.run.ApkProvisionException; -import com.android.tools.idea.run.LaunchOptions; -import com.android.tools.idea.run.activity.DefaultStartActivityFlagsProvider; -import com.android.tools.idea.run.activity.StartActivityFlagsProvider; -import com.android.tools.idea.run.blaze.BlazeLaunchTask; -import com.android.tools.idea.run.tasks.ConnectDebuggerTask; -import com.google.idea.blaze.android.run.binary.BlazeAndroidBinaryApplicationLaunchTaskProvider; -import com.google.idea.blaze.android.run.binary.BlazeAndroidBinaryRunConfigurationState; -import com.google.idea.blaze.android.run.binary.UserIdHelper; -import com.google.idea.blaze.android.run.deployinfo.BlazeAndroidDeployInfo; -import com.google.idea.blaze.android.run.runner.ApkBuildStep; -import com.intellij.execution.ExecutionException; -import com.intellij.execution.Executor; -import com.intellij.execution.configurations.RunConfiguration; -import com.intellij.execution.runners.ExecutionEnvironment; -import com.intellij.openapi.project.Project; -import javax.annotation.Nullable; -import org.jetbrains.android.facet.AndroidFacet; - -/** Run Context for mobile install launches, #api4.0 compat. */ -public class BlazeAndroidBinaryMobileInstallRunContext - extends BlazeAndroidBinaryMobileInstallRunContextBase { - public BlazeAndroidBinaryMobileInstallRunContext( - Project project, - AndroidFacet facet, - RunConfiguration runConfiguration, - ExecutionEnvironment env, - BlazeAndroidBinaryRunConfigurationState configState, - ApkBuildStep buildStep, - String launchId) { - super(project, facet, runConfiguration, env, configState, buildStep, launchId); - } - - @SuppressWarnings("unchecked") // upstream API - @Override - public BlazeLaunchTask getApplicationLaunchTask( - LaunchOptions launchOptions, @Nullable Integer userId, String contributorsAmStartOptions) - throws ExecutionException { - - String extraFlags = UserIdHelper.getFlagsFromUserId(userId); - if (!contributorsAmStartOptions.isEmpty()) { - extraFlags += (extraFlags.isEmpty() ? "" : " ") + contributorsAmStartOptions; - } - - final StartActivityFlagsProvider startActivityFlagsProvider = - new DefaultStartActivityFlagsProvider(project, launchOptions.isDebug(), extraFlags); - BlazeAndroidDeployInfo deployInfo; - try { - deployInfo = buildStep.getDeployInfo(); - } catch (ApkProvisionException e) { - throw new ExecutionException(e); - } - - return BlazeAndroidBinaryApplicationLaunchTaskProvider.getApplicationLaunchTask( - applicationIdProvider, - deployInfo.getMergedManifest(), - configState, - startActivityFlagsProvider); - } - - @Nullable - @Override - @SuppressWarnings("unchecked") - public ConnectDebuggerTask getDebuggerTask( - AndroidDebugger androidDebugger, AndroidDebuggerState androidDebuggerState) { - return getBaseDebuggerTask(androidDebugger, androidDebuggerState, env, facet); - } - - @Override - public Executor getExecutor() { - return env.getExecutor(); - } -} diff --git a/aswb/sdkcompat/as231/com/google/idea/blaze/android/run/binary/mobileinstall/BlazeAndroidBinaryMobileInstallRunContextBase.java b/aswb/sdkcompat/as231/com/google/idea/blaze/android/run/binary/mobileinstall/BlazeAndroidBinaryMobileInstallRunContextBase.java deleted file mode 100644 index 7562174bd25..00000000000 --- a/aswb/sdkcompat/as231/com/google/idea/blaze/android/run/binary/mobileinstall/BlazeAndroidBinaryMobileInstallRunContextBase.java +++ /dev/null @@ -1,165 +0,0 @@ -/* - * Copyright 2016 The Bazel Authors. All rights reserved. - * - * 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. - */ -package com.google.idea.blaze.android.run.binary.mobileinstall; - -import com.android.ddmlib.IDevice; -import com.android.tools.idea.run.ApkFileUnit; -import com.android.tools.idea.run.ApkInfo; -import com.android.tools.idea.run.ApkProvisionException; -import com.android.tools.idea.run.ApplicationIdProvider; -import com.android.tools.idea.run.ConsoleProvider; -import com.android.tools.idea.run.LaunchOptions; -import com.android.tools.idea.run.blaze.BlazeLaunchTask; -import com.android.tools.idea.run.blaze.BlazeLaunchTasksProvider; -import com.android.tools.idea.run.editor.ProfilerState; -import com.android.tools.idea.run.tasks.DeployTasksCompat; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; -import com.google.idea.blaze.android.run.binary.BlazeAndroidBinaryApplicationIdProvider; -import com.google.idea.blaze.android.run.binary.BlazeAndroidBinaryConsoleProvider; -import com.google.idea.blaze.android.run.binary.BlazeAndroidBinaryRunConfigurationState; -import com.google.idea.blaze.android.run.binary.DeploymentTimingReporterTask; -import com.google.idea.blaze.android.run.binary.UserIdHelper; -import com.google.idea.blaze.android.run.deployinfo.BlazeAndroidDeployInfo; -import com.google.idea.blaze.android.run.runner.ApkBuildStep; -import com.google.idea.blaze.android.run.runner.BlazeAndroidDeviceSelector; -import com.google.idea.blaze.android.run.runner.BlazeAndroidLaunchTasksProvider; -import com.google.idea.blaze.android.run.runner.BlazeAndroidRunContext; -import com.google.idea.blaze.base.sync.data.BlazeDataStorage; -import com.intellij.execution.ExecutionException; -import com.intellij.execution.configurations.RunConfiguration; -import com.intellij.execution.runners.ExecutionEnvironment; -import com.intellij.openapi.project.Project; -import java.util.Collections; -import java.util.stream.Collectors; -import javax.annotation.Nullable; -import org.jetbrains.android.facet.AndroidFacet; - -/** Run context for android_binary. */ -abstract class BlazeAndroidBinaryMobileInstallRunContextBase implements BlazeAndroidRunContext { - protected final Project project; - protected final AndroidFacet facet; - protected final RunConfiguration runConfiguration; - protected final ExecutionEnvironment env; - protected final BlazeAndroidBinaryRunConfigurationState configState; - protected final ConsoleProvider consoleProvider; - protected final ApplicationIdProvider applicationIdProvider; - protected final ApkBuildStep buildStep; - private final String launchId; - - public BlazeAndroidBinaryMobileInstallRunContextBase( - Project project, - AndroidFacet facet, - RunConfiguration runConfiguration, - ExecutionEnvironment env, - BlazeAndroidBinaryRunConfigurationState configState, - ApkBuildStep buildStep, - String launchId) { - this.project = project; - this.facet = facet; - this.runConfiguration = runConfiguration; - this.env = env; - this.configState = configState; - this.consoleProvider = new BlazeAndroidBinaryConsoleProvider(project); - this.buildStep = buildStep; - this.applicationIdProvider = new BlazeAndroidBinaryApplicationIdProvider(buildStep); - this.launchId = launchId; - } - - @Override - public BlazeAndroidDeviceSelector getDeviceSelector() { - return new BlazeAndroidDeviceSelector.NormalDeviceSelector(); - } - - @Override - public void augmentLaunchOptions(LaunchOptions.Builder options) { - options - .setDeploy(buildStep.needsIdeDeploy()) - .setOpenLogcatAutomatically(configState.showLogcatAutomatically()); - // This is needed for compatibility with #api211 - options.addExtraOptions( - ImmutableMap.of("android.profilers.state", configState.getProfilerState())); - } - - @Override - public ConsoleProvider getConsoleProvider() { - return consoleProvider; - } - - @Override - public ApplicationIdProvider getApplicationIdProvider() throws ExecutionException { - return applicationIdProvider; - } - - @Override - public ApkBuildStep getBuildStep() { - return buildStep; - } - - @Override - public ProfilerState getProfileState() { - return configState.getProfilerState(); - } - - @Override - public ImmutableList getDeployTasks(IDevice device, LaunchOptions launchOptions) - throws ExecutionException { - if (!buildStep.needsIdeDeploy()) { - return ImmutableList.of(); - } - - BlazeAndroidDeployInfo deployInfo; - try { - deployInfo = buildStep.getDeployInfo(); - } catch (ApkProvisionException e) { - throw new ExecutionException(e); - } - - String packageName = deployInfo.getMergedManifest().packageName; - if (packageName == null) { - throw new ExecutionException("Could not determine package name from deploy info"); - } - - ApkInfo info = - new ApkInfo( - deployInfo.getApksToDeploy().stream() - .map(file -> new ApkFileUnit(BlazeDataStorage.WORKSPACE_MODULE_NAME, file)) - .collect(Collectors.toList()), - packageName); - - BlazeLaunchTask deployTask = - DeployTasksCompat.createDeployTask(project, Collections.singletonList(info), launchOptions); - return ImmutableList.of(new DeploymentTimingReporterTask(launchId, deployTask)); - } - - @Nullable - @Override - public Integer getUserId(IDevice device) throws ExecutionException { - return UserIdHelper.getUserIdFromConfigurationState(project, device, configState); - } - - @Override - public BlazeLaunchTasksProvider getLaunchTasksProvider(LaunchOptions.Builder launchOptionsBuilder) - throws ExecutionException { - return new BlazeAndroidLaunchTasksProvider( - project, this, applicationIdProvider, launchOptionsBuilder); - } - - @Override - public String getAmStartOptions() { - return configState.getAmStartOptions(); - } -} diff --git a/aswb/sdkcompat/as231/com/google/idea/blaze/android/run/binary/mobileinstall/BlazeAndroidBinaryMobileInstallRunContextCompat.java b/aswb/sdkcompat/as231/com/google/idea/blaze/android/run/binary/mobileinstall/BlazeAndroidBinaryMobileInstallRunContextCompat.java deleted file mode 100644 index 29411ebad5a..00000000000 --- a/aswb/sdkcompat/as231/com/google/idea/blaze/android/run/binary/mobileinstall/BlazeAndroidBinaryMobileInstallRunContextCompat.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright 2022 The Bazel Authors. All rights reserved. - * - * 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. - */ -package com.google.idea.blaze.android.run.binary.mobileinstall; - -import static com.android.tools.idea.run.tasks.DefaultConnectDebuggerTaskKt.getBaseDebuggerTask; - -import com.android.tools.idea.execution.common.debug.AndroidDebugger; -import com.android.tools.idea.execution.common.debug.AndroidDebuggerState; -import com.android.tools.idea.run.tasks.ConnectDebuggerTask; -import com.google.idea.blaze.android.run.binary.BlazeAndroidBinaryRunConfigurationState; -import com.google.idea.blaze.android.run.runner.ApkBuildStep; -import com.google.idea.blaze.base.run.BlazeCommandRunConfiguration; -import com.intellij.execution.runners.ExecutionEnvironment; -import com.intellij.openapi.project.Project; -import javax.annotation.Nullable; -import org.jetbrains.android.facet.AndroidFacet; - -/** Compatct class for {@link BlazeAndroidBinaryMobileInstallRunContext}. */ -public class BlazeAndroidBinaryMobileInstallRunContextCompat - extends BlazeAndroidBinaryMobileInstallRunContext { - - public BlazeAndroidBinaryMobileInstallRunContextCompat( - Project project, - AndroidFacet facet, - BlazeCommandRunConfiguration configuration, - ExecutionEnvironment env, - BlazeAndroidBinaryRunConfigurationState configState, - ApkBuildStep buildStep, - String launchId) { - super(project, facet, configuration, env, configState, buildStep, launchId); - } - - @Nullable - @Override - @SuppressWarnings("unchecked") - public ConnectDebuggerTask getDebuggerTask( - AndroidDebugger androidDebugger, AndroidDebuggerState androidDebuggerState) { - return getBaseDebuggerTask(androidDebugger, androidDebuggerState, env, facet); - } -} diff --git a/aswb/sdkcompat/as231/com/google/idea/blaze/android/run/runner/BlazeAndroidDebuggerService.java b/aswb/sdkcompat/as231/com/google/idea/blaze/android/run/runner/BlazeAndroidDebuggerService.java deleted file mode 100644 index c8658223baa..00000000000 --- a/aswb/sdkcompat/as231/com/google/idea/blaze/android/run/runner/BlazeAndroidDebuggerService.java +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Copyright 2016 The Bazel Authors. All rights reserved. - * - * 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. - */ -package com.google.idea.blaze.android.run.runner; - -import com.android.tools.idea.execution.common.debug.AndroidDebugger; -import com.android.tools.idea.execution.common.debug.AndroidDebuggerState; -import com.android.tools.idea.execution.common.debug.impl.java.AndroidJavaDebugger; -import com.android.tools.ndk.run.editor.AutoAndroidDebuggerState; -import com.google.common.collect.ImmutableList; -import com.google.idea.blaze.android.cppimpl.debug.BlazeAutoAndroidDebugger; -import com.google.idea.blaze.android.run.deployinfo.BlazeAndroidDeployInfo; -import com.google.idea.blaze.base.model.primitives.WorkspaceRoot; -import com.intellij.ide.plugins.PluginManagerCore; -import com.intellij.openapi.project.Project; -import javax.annotation.Nullable; - -/** Provides android debuggers and debugger states for blaze projects. */ -public interface BlazeAndroidDebuggerService { - - static BlazeAndroidDebuggerService getInstance(Project project) { - return project.getService(BlazeAndroidDebuggerService.class); - } - - /** Returns the standard debugger for non-native (Java) debugging. */ - AndroidDebugger getDebugger(); - - /** Returns the standard debugger for native (C++) debugging. */ - AndroidDebugger getNativeDebugger(); - - /** - * Performs additional necessary setup for native debugging, incorporating info from {@link - * BlazeAndroidDeployInfo}. - */ - void configureNativeDebugger( - AndroidDebuggerState state, @Nullable BlazeAndroidDeployInfo deployInfo); - - /** Default debugger service. */ - class DefaultDebuggerService implements BlazeAndroidDebuggerService { - private final Project project; - - public DefaultDebuggerService(Project project) { - this.project = project; - } - - @Override - public AndroidDebugger getDebugger() { - return new AndroidJavaDebugger(); - } - - @Override - public AndroidDebugger getNativeDebugger() { - return new BlazeAutoAndroidDebugger(); - } - - @Override - public void configureNativeDebugger( - AndroidDebuggerState rawState, @Nullable BlazeAndroidDeployInfo deployInfo) { - if (!isNdkPluginLoaded() && !(rawState instanceof AutoAndroidDebuggerState)) { - return; - } - AutoAndroidDebuggerState state = (AutoAndroidDebuggerState) rawState; - - // Source code is always relative to the workspace root in a blaze project. - String workingDirPath = WorkspaceRoot.fromProject(project).directory().getPath(); - state.setWorkingDir(workingDirPath); - - // Remote built binaries may use /proc/self/cwd to represent the working directory, - // so we manually map /proc/self/cwd to the workspace root. We used to use - // `plugin.symbol-file.dwarf.comp-dir-symlink-paths = "/proc/self/cwd"` - // to automatically resolve this, but it's no longer supported in newer versions of - // LLDB. - String sourceMapToWorkspaceRootCommand = - "settings append target.source-map /proc/self/cwd/ " + workingDirPath; - - ImmutableList startupCommands = - ImmutableList.builder() - .addAll(state.getUserStartupCommands()) - .add(sourceMapToWorkspaceRootCommand) - .build(); - state.setUserStartupCommands(startupCommands); - - // NDK plugin will pass symbol directories to LLDB as `settings append - // target.exec-search-paths`. - if (deployInfo != null) { - state.setSymbolDirs( - deployInfo.getSymbolFiles().stream() - .map(symbol -> symbol.getParentFile().getAbsolutePath()) - .collect(ImmutableList.toImmutableList())); - } - } - } - - static boolean isNdkPluginLoaded() { - return PluginManagerCore.getLoadedPlugins().stream() - .anyMatch( - d -> d.isEnabled() && d.getPluginId().getIdString().equals("com.android.tools.ndk")); - } -} diff --git a/aswb/sdkcompat/as231/com/google/idea/blaze/android/run/runner/BlazeAndroidDeviceSelector.java b/aswb/sdkcompat/as231/com/google/idea/blaze/android/run/runner/BlazeAndroidDeviceSelector.java deleted file mode 100644 index b4fdcf0fd33..00000000000 --- a/aswb/sdkcompat/as231/com/google/idea/blaze/android/run/runner/BlazeAndroidDeviceSelector.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright 2018 The Bazel Authors. All rights reserved. - * - * 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. - */ - -package com.google.idea.blaze.android.run.runner; - -import com.android.tools.idea.execution.common.AndroidSessionInfo; -import com.android.tools.idea.run.DeviceFutures; -import com.android.tools.idea.run.editor.DeployTarget; -import com.google.common.annotations.VisibleForTesting; -import com.intellij.execution.ExecutionException; -import com.intellij.execution.Executor; -import com.intellij.execution.runners.ExecutionEnvironment; -import com.intellij.openapi.project.Project; -import javax.annotation.Nullable; - -/** Selects a device. */ -public interface BlazeAndroidDeviceSelector { - /** A device session */ - class DeviceSession { - @Nullable public final DeployTarget deployTarget; - @Nullable public final DeviceFutures deviceFutures; - - public DeviceSession( - @Nullable DeployTarget deployTarget, @Nullable DeviceFutures deviceFutures) { - this.deployTarget = deployTarget; - this.deviceFutures = deviceFutures; - } - - // Only for back compat - @VisibleForTesting - public DeviceSession( - @Nullable DeployTarget deployTarget, - @Nullable DeviceFutures deviceFutures, - @Nullable AndroidSessionInfo sessionInfo) { - this(deployTarget, deviceFutures); - } - } - - DeviceSession getDevice( - Project project, Executor executor, ExecutionEnvironment env, boolean debug, int runConfigId) - throws ExecutionException; - /** Standard device selector */ - class NormalDeviceSelector implements BlazeAndroidDeviceSelector { - @Override - public DeviceSession getDevice( - Project project, - Executor executor, - ExecutionEnvironment env, - boolean debug, - int runConfigId) { - DeployTarget deployTarget = BlazeDeployTargetService.getInstance(project).getDeployTarget(); - if (deployTarget == null) { - return null; - } - DeviceFutures deviceFutures = null; - if (!deployTarget.hasCustomRunProfileState(executor)) { - deviceFutures = deployTarget.getDevices(project); - } - return new DeviceSession(deployTarget, deviceFutures); - } - } -} diff --git a/aswb/sdkcompat/as231/com/google/idea/blaze/android/run/runner/BlazeAndroidLaunchTasksProvider.java b/aswb/sdkcompat/as231/com/google/idea/blaze/android/run/runner/BlazeAndroidLaunchTasksProvider.java deleted file mode 100644 index 7a3cd3b2dee..00000000000 --- a/aswb/sdkcompat/as231/com/google/idea/blaze/android/run/runner/BlazeAndroidLaunchTasksProvider.java +++ /dev/null @@ -1,207 +0,0 @@ -/* - * Copyright 2022 The Bazel Authors. All rights reserved. - * - * 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. - */ -package com.google.idea.blaze.android.run.runner; - -import static com.android.tools.idea.profilers.AndroidProfilerLaunchTaskContributor.isProfilerLaunch; - -import com.android.ddmlib.IDevice; -import com.android.tools.deployer.ApkVerifierTracker; -import com.android.tools.idea.editors.literals.LiveEditService; -import com.android.tools.idea.execution.common.debug.AndroidDebugger; -import com.android.tools.idea.execution.common.debug.AndroidDebuggerState; -import com.android.tools.idea.profilers.AndroidProfilerLaunchTaskContributor; -import com.android.tools.idea.run.ApkProvisionException; -import com.android.tools.idea.run.ApplicationIdProvider; -import com.android.tools.idea.run.LaunchOptions; -import com.android.tools.idea.run.blaze.BlazeLaunchTask; -import com.android.tools.idea.run.blaze.BlazeLaunchTaskWrapper; -import com.android.tools.idea.run.blaze.BlazeLaunchTasksProvider; -import com.android.tools.idea.run.deployment.liveedit.LiveEditApp; -import com.android.tools.idea.run.tasks.ClearLogcatTask; -import com.android.tools.idea.run.tasks.ConnectDebuggerTask; -import com.android.tools.idea.run.tasks.DismissKeyguardTask; -import com.android.tools.idea.run.tasks.ShowLogcatTask; -import com.android.tools.idea.run.tasks.StartLiveUpdateMonitoringTask; -import com.android.tools.ndk.run.editor.AutoAndroidDebuggerState; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableSet; -import com.google.common.collect.Lists; -import com.google.idea.blaze.android.run.binary.UserIdHelper; -import com.google.idea.blaze.android.run.deployinfo.BlazeAndroidDeployInfo; -import com.google.idea.common.experiments.BoolExperiment; -import com.intellij.execution.ExecutionException; -import com.intellij.openapi.diagnostic.Logger; -import com.intellij.openapi.project.Project; -import java.nio.file.Path; -import java.util.List; -import java.util.Set; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -/** Normal launch tasks provider. #api4.1 */ -public class BlazeAndroidLaunchTasksProvider implements BlazeLaunchTasksProvider { - public static final String NATIVE_DEBUGGING_ENABLED = "NATIVE_DEBUGGING_ENABLED"; - private static final Logger LOG = Logger.getInstance(BlazeAndroidLaunchTasksProvider.class); - private static final BoolExperiment isLiveEditEnabled = - new BoolExperiment("aswb.live.edit.enabled", false); - - private final Project project; - private final BlazeAndroidRunContext runContext; - private final ApplicationIdProvider applicationIdProvider; - private final LaunchOptions.Builder launchOptionsBuilder; - - public BlazeAndroidLaunchTasksProvider( - Project project, - BlazeAndroidRunContext runContext, - ApplicationIdProvider applicationIdProvider, - LaunchOptions.Builder launchOptionsBuilder) { - this.project = project; - this.runContext = runContext; - this.applicationIdProvider = applicationIdProvider; - this.launchOptionsBuilder = launchOptionsBuilder; - } - - @NotNull - @Override - public List getTasks(@NotNull IDevice device) throws ExecutionException { - final List launchTasks = Lists.newArrayList(); - - String packageName; - try { - packageName = applicationIdProvider.getPackageName(); - } catch (ApkProvisionException e) { - throw new ExecutionException("Unable to determine application id: " + e); - } - - Integer userId = runContext.getUserId(device); - String userIdFlags = UserIdHelper.getFlagsFromUserId(userId); - String skipVerification = - ApkVerifierTracker.getSkipVerificationInstallationFlag(device, packageName); - String pmInstallOption; - if (skipVerification != null) { - pmInstallOption = userIdFlags + " " + skipVerification; - } else { - pmInstallOption = userIdFlags; - } - launchOptionsBuilder.setPmInstallOptions(d -> pmInstallOption); - - LaunchOptions launchOptions = launchOptionsBuilder.build(); - - // NOTE: Task for opening the profiler tool-window should come before deployment - // to ensure the tool-window opens correctly. This is required because starting - // the profiler session requires the tool-window to be open. - if (isProfilerLaunch(runContext.getExecutor())) { - launchTasks.add(new BlazeAndroidOpenProfilerWindowTask(project)); - } - - // TODO(kovalp): Check if there's any drawback to add these tasks with BlazeLaunchTaskWrapper - // since it's different with ag/21610897 - if (launchOptions.isClearLogcatBeforeStart()) { - launchTasks.add(new BlazeLaunchTaskWrapper(new ClearLogcatTask(project))); - } - - launchTasks.add(new BlazeLaunchTaskWrapper(new DismissKeyguardTask())); - - if (launchOptions.isDeploy()) { - ImmutableList deployTasks = runContext.getDeployTasks(device, launchOptions); - launchTasks.addAll(deployTasks); - } - - try { - if (launchOptions.isDebug()) { - launchTasks.add( - new CheckApkDebuggableTask(project, runContext.getBuildStep().getDeployInfo())); - } - - ImmutableList.Builder amStartOptions = ImmutableList.builder(); - amStartOptions.add(runContext.getAmStartOptions()); - if (isProfilerLaunch(runContext.getExecutor())) { - amStartOptions.add( - AndroidProfilerLaunchTaskContributor.getAmStartOptions( - project, - packageName, - runContext.getProfileState(), - device, - runContext.getExecutor())); - } - BlazeLaunchTask appLaunchTask = - runContext.getApplicationLaunchTask( - launchOptions, userId, String.join(" ", amStartOptions.build())); - if (appLaunchTask != null) { - launchTasks.add(appLaunchTask); - if (isLiveEditEnabled.getValue()) { - // TODO(b/277244508): Fix Live Edit for Giraffe - Set apks = - runContext.getBuildStep().getDeployInfo().getApksToDeploy().stream() - .map(f -> f.toPath()) - .collect(ImmutableSet.toImmutableSet()); - - LiveEditApp app = new LiveEditApp(apks, device.getVersion().getApiLevel()); - launchTasks.add( - new BlazeLaunchTaskWrapper( - new StartLiveUpdateMonitoringTask( - () -> - LiveEditService.getInstance(project) - .getDeployMonitor() - .notifyAppDeploy(packageName, device, app)))); - } - } - } catch (ApkProvisionException e) { - throw new ExecutionException("Unable to determine application id: " + e); - } - - if (launchOptions.isOpenLogcatAutomatically()) { - launchTasks.add(new BlazeLaunchTaskWrapper(new ShowLogcatTask(project, packageName))); - } - - return ImmutableList.copyOf(launchTasks); - } - - @Override - @Nullable - public ConnectDebuggerTask getConnectDebuggerTask() { - LaunchOptions launchOptions = launchOptionsBuilder.build(); - if (!launchOptions.isDebug()) { - return null; - } - - BlazeAndroidDeployInfo deployInfo; - try { - deployInfo = runContext.getBuildStep().getDeployInfo(); - } catch (ApkProvisionException e) { - LOG.error(e); - deployInfo = null; - } - - BlazeAndroidDebuggerService debuggerService = BlazeAndroidDebuggerService.getInstance(project); - if (isNativeDebuggingEnabled(launchOptions)) { - AndroidDebugger debugger = debuggerService.getNativeDebugger(); - // The below state type should be AutoAndroidDebuggerState, but referencing it will crash the - // task if the NDK plugin is not loaded. - AndroidDebuggerState state = debugger.createState(); - debuggerService.configureNativeDebugger(state, deployInfo); - return runContext.getDebuggerTask(debugger, state); - } else { - AndroidDebugger debugger = debuggerService.getDebugger(); - return runContext.getDebuggerTask(debugger, debugger.createState()); - } - } - - private boolean isNativeDebuggingEnabled(LaunchOptions launchOptions) { - Object flag = launchOptions.getExtraOption(NATIVE_DEBUGGING_ENABLED); - return flag instanceof Boolean && (Boolean) flag; - } -} diff --git a/aswb/sdkcompat/as231/com/google/idea/blaze/android/run/runner/BlazeAndroidOpenProfilerWindowTask.java b/aswb/sdkcompat/as231/com/google/idea/blaze/android/run/runner/BlazeAndroidOpenProfilerWindowTask.java deleted file mode 100644 index b3941316668..00000000000 --- a/aswb/sdkcompat/as231/com/google/idea/blaze/android/run/runner/BlazeAndroidOpenProfilerWindowTask.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (C) 2019 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. - */ -package com.google.idea.blaze.android.run.runner; - -import com.android.tools.idea.profilers.ProfilerProgramRunner; -import com.android.tools.idea.run.blaze.BlazeLaunchContext; -import com.android.tools.idea.run.blaze.BlazeLaunchTask; -import com.intellij.openapi.application.ApplicationManager; -import com.intellij.openapi.project.Project; - -/** Opens the profiler tool window. */ -public class BlazeAndroidOpenProfilerWindowTask implements BlazeLaunchTask { - private static final String ID = "OPEN_PROFILER_TOOLWINDOW"; - private final Project project; - - public BlazeAndroidOpenProfilerWindowTask(Project project) { - this.project = project; - } - - @Override - public void run(BlazeLaunchContext launchContext) { - ApplicationManager.getApplication() - .invokeLater(() -> ProfilerProgramRunner.createProfilerToolWindow(project, null)); - } -} diff --git a/aswb/sdkcompat/as231/com/google/idea/blaze/android/run/runner/BlazeAndroidRunConfigurationRunner.java b/aswb/sdkcompat/as231/com/google/idea/blaze/android/run/runner/BlazeAndroidRunConfigurationRunner.java deleted file mode 100644 index 78728d9c46f..00000000000 --- a/aswb/sdkcompat/as231/com/google/idea/blaze/android/run/runner/BlazeAndroidRunConfigurationRunner.java +++ /dev/null @@ -1,327 +0,0 @@ -/* - * Copyright 2016 The Bazel Authors. All rights reserved. - * - * 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. - */ - -package com.google.idea.blaze.android.run.runner; - -import com.android.ddmlib.IDevice; -import com.android.tools.idea.execution.common.AppRunSettings; -import com.android.tools.idea.execution.common.ApplicationDeployer; -import com.android.tools.idea.execution.common.ComponentLaunchOptions; -import com.android.tools.idea.execution.common.DeployOptions; -import com.android.tools.idea.run.ApkProvider; -import com.android.tools.idea.run.ApplicationIdProvider; -import com.android.tools.idea.run.DeviceFutures; -import com.android.tools.idea.run.LaunchOptions; -import com.android.tools.idea.run.blaze.BlazeAndroidConfigurationExecutor; -import com.android.tools.idea.run.configuration.execution.AndroidComplicationConfigurationExecutor; -import com.android.tools.idea.run.configuration.execution.AndroidConfigurationExecutor; -import com.android.tools.idea.run.configuration.execution.AndroidConfigurationExecutorRunProfileState; -import com.android.tools.idea.run.configuration.execution.AndroidTileConfigurationExecutor; -import com.android.tools.idea.run.configuration.execution.AndroidWatchFaceConfigurationExecutor; -import com.android.tools.idea.run.configuration.execution.ComplicationLaunchOptions; -import com.android.tools.idea.run.configuration.execution.TileLaunchOptions; -import com.android.tools.idea.run.configuration.execution.WatchFaceLaunchOptions; -import com.android.tools.idea.run.editor.DeployTarget; -import com.android.tools.idea.run.editor.DeployTargetState; -import com.android.tools.idea.run.util.LaunchUtils; -import com.google.common.util.concurrent.Futures; -import com.google.common.util.concurrent.ListenableFuture; -import com.google.idea.blaze.android.run.binary.mobileinstall.MobileInstallBuildStep; -import com.google.idea.blaze.android.run.deployinfo.BlazeApkProviderService; -import com.google.idea.blaze.base.async.executor.ProgressiveTaskWithProgressIndicator; -import com.google.idea.blaze.base.command.BlazeInvocationContext.ContextType; -import com.google.idea.blaze.base.experiments.ExperimentScope; -import com.google.idea.blaze.base.issueparser.BlazeIssueParser; -import com.google.idea.blaze.base.model.primitives.WorkspaceRoot; -import com.google.idea.blaze.base.run.BlazeCommandRunConfiguration; -import com.google.idea.blaze.base.run.confighandler.BlazeCommandRunConfigurationRunner; -import com.google.idea.blaze.base.scope.BlazeContext; -import com.google.idea.blaze.base.scope.Scope; -import com.google.idea.blaze.base.scope.ScopedTask; -import com.google.idea.blaze.base.scope.output.IssueOutput; -import com.google.idea.blaze.base.scope.scopes.IdeaLogScope; -import com.google.idea.blaze.base.scope.scopes.ProblemsViewScope; -import com.google.idea.blaze.base.scope.scopes.ToolWindowScope; -import com.google.idea.blaze.base.settings.Blaze; -import com.google.idea.blaze.base.settings.BlazeUserSettings; -import com.google.idea.blaze.base.toolwindow.Task; -import com.intellij.execution.ExecutionException; -import com.intellij.execution.Executor; -import com.intellij.execution.configurations.RunProfileState; -import com.intellij.execution.executors.DefaultDebugExecutor; -import com.intellij.execution.runners.ExecutionEnvironment; -import com.intellij.execution.ui.ConsoleView; -import com.intellij.openapi.diagnostic.Logger; -import com.intellij.openapi.module.Module; -import com.intellij.openapi.project.Project; -import com.intellij.openapi.util.Key; -import java.util.Collections; -import java.util.concurrent.CancellationException; -import javax.annotation.Nullable; -import org.jetbrains.android.facet.AndroidFacet; -import org.jetbrains.android.util.AndroidBundle; -import org.jetbrains.annotations.NotNull; - -/** - * Supports the execution. Used by both android_binary and android_test. - * - *

Builds the APK and installs it, launches and debug tasks, etc. - * - *

Any indirection between android_binary/android_test, mobile-install, InstantRun etc. should - * come via the strategy class. - */ -public final class BlazeAndroidRunConfigurationRunner - implements BlazeCommandRunConfigurationRunner { - - private static final Logger LOG = Logger.getInstance(BlazeAndroidRunConfigurationRunner.class); - - private static final Key RUN_CONTEXT_KEY = - Key.create("blaze.run.context"); - public static final Key DEVICE_SESSION_KEY = - Key.create("blaze.device.session"); - - private final Module module; - private final BlazeAndroidRunContext runContext; - private final BlazeCommandRunConfiguration runConfig; - - public BlazeAndroidRunConfigurationRunner( - Module module, BlazeAndroidRunContext runContext, BlazeCommandRunConfiguration runConfig) { - this.module = module; - this.runContext = runContext; - this.runConfig = runConfig; - } - - @Override - @Nullable - public final RunProfileState getRunProfileState(final Executor executor, ExecutionEnvironment env) - throws ExecutionException { - - final AndroidFacet facet = AndroidFacet.getInstance(module); - assert facet != null : "Enforced by fatal validation check in createRunner."; - final Project project = env.getProject(); - - boolean isDebug = executor instanceof DefaultDebugExecutor; - - BlazeAndroidDeviceSelector deviceSelector = runContext.getDeviceSelector(); - BlazeAndroidDeviceSelector.DeviceSession deviceSession = - deviceSelector.getDevice(project, executor, env, isDebug, runConfig.getUniqueID()); - - if (deviceSession == null) { - return null; - } - - DeployTarget deployTarget = deviceSession.deployTarget; - if (deployTarget != null && deployTarget.hasCustomRunProfileState(executor)) { - return deployTarget.getRunProfileState(executor, env, DeployTargetState.DEFAULT_STATE); - } - - DeviceFutures deviceFutures = deviceSession.deviceFutures; - if (deviceFutures == null) { - // The user deliberately canceled, or some error was encountered and exposed by the chooser. - // Quietly exit. - return null; - } - - if (deviceFutures.get().isEmpty()) { - throw new ExecutionException(AndroidBundle.message("deployment.target.not.found")); - } - - if (isDebug) { - String error = canDebug(deviceFutures, facet, module.getName()); - if (error != null) { - throw new ExecutionException(error); - } - } - - LaunchOptions.Builder launchOptionsBuilder = getDefaultLaunchOptions().setDebug(isDebug); - runContext.augmentLaunchOptions(launchOptionsBuilder); - - // Store the run context on the execution environment so before-run tasks can access it. - env.putCopyableUserData(RUN_CONTEXT_KEY, runContext); - env.putCopyableUserData(DEVICE_SESSION_KEY, deviceSession); - - BlazeAndroidConfigurationExecutor runner = - new BlazeAndroidConfigurationExecutor( - runContext.getConsoleProvider(), - runContext.getApplicationIdProvider(), - env, - deviceFutures, - runContext.getLaunchTasksProvider(launchOptionsBuilder), - LaunchOptions.builder().build()); - return new AndroidConfigurationExecutorRunProfileState(runner); - } - - private RunProfileState getWearExecutor( - ComponentLaunchOptions launchOptions, ExecutionEnvironment env, DeployTarget deployTarget) - throws ExecutionException { - - AppRunSettings settings = - new AppRunSettings() { - @NotNull - @Override - public DeployOptions getDeployOptions() { - return new DeployOptions(Collections.emptyList(), "", true, true); - } - - @NotNull - @Override - public ComponentLaunchOptions getComponentLaunchOptions() { - return launchOptions; - } - - @Override - public Module getModule() { - return runConfig.getModules()[0]; - } - }; - - AndroidConfigurationExecutor configurationExecutor; - ApplicationIdProvider appIdProvider = runContext.getApplicationIdProvider(); - ApkProvider apkProvider = - BlazeApkProviderService.getInstance() - .getApkProvider(env.getProject(), runContext.getBuildStep()); - DeviceFutures deviceFutures = deployTarget.getDevices(env.getProject()); - - if (launchOptions instanceof TileLaunchOptions) { - configurationExecutor = - new AndroidTileConfigurationExecutor( - env, deviceFutures, settings, appIdProvider, apkProvider) { - @NotNull - @Override - public ApplicationDeployer getApplicationDeployer(@NotNull ConsoleView console) - throws ExecutionException { - if (runContext.getBuildStep() instanceof MobileInstallBuildStep) { - return new MobileInstallApplicationDeployer(console); - } - return super.getApplicationDeployer(console); - } - }; - } else if (launchOptions instanceof WatchFaceLaunchOptions) { - configurationExecutor = - new AndroidWatchFaceConfigurationExecutor( - env, deviceFutures, settings, appIdProvider, apkProvider) { - @NotNull - @Override - public ApplicationDeployer getApplicationDeployer(@NotNull ConsoleView console) - throws ExecutionException { - if (runContext.getBuildStep() instanceof MobileInstallBuildStep) { - return new MobileInstallApplicationDeployer(console); - } - return super.getApplicationDeployer(console); - } - }; - } else if (launchOptions instanceof ComplicationLaunchOptions) { - configurationExecutor = - new AndroidComplicationConfigurationExecutor( - env, deviceFutures, settings, appIdProvider, apkProvider) { - @NotNull - @Override - public ApplicationDeployer getApplicationDeployer(@NotNull ConsoleView console) - throws ExecutionException { - if (runContext.getBuildStep() instanceof MobileInstallBuildStep) { - return new MobileInstallApplicationDeployer(console); - } - return super.getApplicationDeployer(console); - } - }; - } else { - throw new RuntimeException("Unknown launch options " + launchOptions.getClass().getName()); - } - - return new AndroidConfigurationExecutorRunProfileState( - new BlazeWrapperForAndroidConfigurationExecutor(configurationExecutor)); - } - - @Nullable - private static String canDebug( - DeviceFutures deviceFutures, AndroidFacet facet, String moduleName) { - // If we are debugging on a device, then the app needs to be debuggable - for (ListenableFuture future : deviceFutures.get()) { - if (!future.isDone()) { - // this is an emulator, and we assume that all emulators are debuggable - continue; - } - IDevice device = Futures.getUnchecked(future); - if (!LaunchUtils.canDebugAppOnDevice(facet, device)) { - return AndroidBundle.message( - "android.cannot.debug.noDebugPermissions", moduleName, device.getName()); - } - } - return null; - } - - private static LaunchOptions.Builder getDefaultLaunchOptions() { - return LaunchOptionsCompat.getDefaultLaunchOptions(); - } - - @Override - public boolean executeBeforeRunTask(ExecutionEnvironment env) { - final Project project = env.getProject(); - BlazeUserSettings settings = BlazeUserSettings.getInstance(); - return Scope.root( - context -> { - context - .push(new ProblemsViewScope(project, settings.getShowProblemsViewOnRun())) - .push(new ExperimentScope()) - .push( - new ToolWindowScope.Builder( - project, new Task(project, "Build apk", Task.Type.BEFORE_LAUNCH)) - .setPopupBehavior(settings.getShowBlazeConsoleOnRun()) - .setIssueParsers( - BlazeIssueParser.defaultIssueParsers( - project, - WorkspaceRoot.fromProject(project), - ContextType.BeforeRunTask)) - .build()) - .push(new IdeaLogScope()); - - BlazeAndroidRunContext runContext = env.getCopyableUserData(RUN_CONTEXT_KEY); - if (runContext == null) { - IssueOutput.error("Could not find run context. Please try again").submit(context); - return false; - } - BlazeAndroidDeviceSelector.DeviceSession deviceSession = - env.getCopyableUserData(DEVICE_SESSION_KEY); - - ApkBuildStep buildStep = runContext.getBuildStep(); - ScopedTask buildTask = - new ScopedTask(context) { - @Override - protected Void execute(BlazeContext context) { - buildStep.build(context, deviceSession); - return null; - } - }; - - try { - ListenableFuture buildFuture = - ProgressiveTaskWithProgressIndicator.builder( - project, - String.format("Executing %s apk build", Blaze.buildSystemName(project))) - .submitTaskWithResult(buildTask); - Futures.getChecked(buildFuture, ExecutionException.class); - } catch (ExecutionException e) { - context.setHasError(); - } catch (CancellationException e) { - context.setCancelled(); - } catch (Exception e) { - LOG.error(e); - return false; - } - return context.shouldContinue(); - }); - } -} diff --git a/aswb/sdkcompat/as231/com/google/idea/blaze/android/run/runner/BlazeAndroidRunContext.java b/aswb/sdkcompat/as231/com/google/idea/blaze/android/run/runner/BlazeAndroidRunContext.java deleted file mode 100644 index c1e33020bae..00000000000 --- a/aswb/sdkcompat/as231/com/google/idea/blaze/android/run/runner/BlazeAndroidRunContext.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright 2016 The Bazel Authors. All rights reserved. - * - * 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. - */ -package com.google.idea.blaze.android.run.runner; - -import com.android.ddmlib.IDevice; -import com.android.tools.idea.execution.common.debug.AndroidDebugger; -import com.android.tools.idea.execution.common.debug.AndroidDebuggerState; -import com.android.tools.idea.run.ApplicationIdProvider; -import com.android.tools.idea.run.ConsoleProvider; -import com.android.tools.idea.run.LaunchOptions; -import com.android.tools.idea.run.blaze.BlazeLaunchTask; -import com.android.tools.idea.run.blaze.BlazeLaunchTasksProvider; -import com.android.tools.idea.run.editor.ProfilerState; -import com.android.tools.idea.run.tasks.ConnectDebuggerTask; -import com.google.common.collect.ImmutableList; -import com.intellij.execution.ExecutionException; -import com.intellij.execution.Executor; -import javax.annotation.Nullable; -import org.jetbrains.annotations.NotNull; - -/** Instantiated when the configuration wants to run. */ -public interface BlazeAndroidRunContext { - - BlazeAndroidDeviceSelector getDeviceSelector(); - - void augmentLaunchOptions(LaunchOptions.Builder options); - - ConsoleProvider getConsoleProvider(); - - ApkBuildStep getBuildStep(); - - ApplicationIdProvider getApplicationIdProvider() throws ExecutionException; - - BlazeLaunchTasksProvider getLaunchTasksProvider(LaunchOptions.Builder launchOptionsBuilder) - throws ExecutionException; - - /** Returns the tasks to deploy the application. */ - ImmutableList getDeployTasks(IDevice device, LaunchOptions launchOptions) - throws ExecutionException; - - /** Returns the task to launch the application. */ - @Nullable - BlazeLaunchTask getApplicationLaunchTask( - LaunchOptions launchOptions, - @Nullable Integer userId, - @NotNull String contributorsAmStartOptions) - throws ExecutionException; - - /** Returns the task to connect the debugger. */ - @Nullable - ConnectDebuggerTask getDebuggerTask( - AndroidDebugger androidDebugger, AndroidDebuggerState androidDebuggerState); - - @Nullable - Integer getUserId(IDevice device) throws ExecutionException; - - String getAmStartOptions(); - - Executor getExecutor(); - - ProfilerState getProfileState(); -} diff --git a/aswb/sdkcompat/as231/com/google/idea/blaze/android/run/runner/BlazeWrapperForAndroidConfigurationExecutor.java b/aswb/sdkcompat/as231/com/google/idea/blaze/android/run/runner/BlazeWrapperForAndroidConfigurationExecutor.java deleted file mode 100644 index be6f1f8552c..00000000000 --- a/aswb/sdkcompat/as231/com/google/idea/blaze/android/run/runner/BlazeWrapperForAndroidConfigurationExecutor.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright (C) 2022 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. - */ -package com.google.idea.blaze.android.run.runner; - -import com.android.tools.idea.run.DeviceFutures; -import com.android.tools.idea.run.configuration.execution.AndroidConfigurationExecutor; -import com.intellij.execution.ExecutionException; -import com.intellij.execution.configurations.RunConfiguration; -import com.intellij.execution.ui.RunContentDescriptor; -import com.intellij.openapi.progress.ProgressIndicator; -import org.jetbrains.annotations.NotNull; - -/** Implementation of {@code AndroidConfigurationExecutor} specific for Blaze project. */ -public class BlazeWrapperForAndroidConfigurationExecutor implements AndroidConfigurationExecutor { - private final AndroidConfigurationExecutor delegateExecutor; - - BlazeWrapperForAndroidConfigurationExecutor(@NotNull AndroidConfigurationExecutor executor) { - delegateExecutor = executor; - } - - @NotNull - @Override - public RunConfiguration getConfiguration() { - return delegateExecutor.getConfiguration(); - } - - @NotNull - @Override - public DeviceFutures getDeviceFutures() { - return delegateExecutor.getDeviceFutures(); - } - - @NotNull - @Override - public RunContentDescriptor run(@NotNull ProgressIndicator indicator) throws ExecutionException { - return delegateExecutor.run(indicator); - } - - @NotNull - @Override - public RunContentDescriptor debug(@NotNull ProgressIndicator indicator) - throws ExecutionException { - return delegateExecutor.debug(indicator); - } - - @NotNull - @Override - public RunContentDescriptor applyChanges(@NotNull ProgressIndicator indicator) { - throw new RuntimeException("Apply code changes is not supported for blaze"); - } - - @NotNull - @Override - public RunContentDescriptor applyCodeChanges(@NotNull ProgressIndicator indicator) { - throw new RuntimeException("Apply changes is not supported for blaze"); - } -} diff --git a/aswb/sdkcompat/as231/com/google/idea/blaze/android/run/runner/CheckApkDebuggableTask.java b/aswb/sdkcompat/as231/com/google/idea/blaze/android/run/runner/CheckApkDebuggableTask.java deleted file mode 100644 index 748734ce06b..00000000000 --- a/aswb/sdkcompat/as231/com/google/idea/blaze/android/run/runner/CheckApkDebuggableTask.java +++ /dev/null @@ -1,139 +0,0 @@ -/* - * Copyright 2020 The Bazel Authors. All rights reserved. - * - * 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. - */ -package com.google.idea.blaze.android.run.runner; - -import static com.google.common.collect.ImmutableList.toImmutableList; - -import com.android.ddmlib.IDevice; -import com.android.tools.idea.execution.common.RunConfigurationNotifier; -import com.android.tools.idea.run.blaze.BlazeLaunchContext; -import com.android.tools.idea.run.blaze.BlazeLaunchTask; -import com.google.common.annotations.VisibleForTesting; -import com.google.common.collect.ImmutableList; -import com.google.devrel.gmscore.tools.apk.arsc.BinaryResourceFile; -import com.google.devrel.gmscore.tools.apk.arsc.Chunk; -import com.google.devrel.gmscore.tools.apk.arsc.XmlAttribute; -import com.google.devrel.gmscore.tools.apk.arsc.XmlChunk; -import com.google.devrel.gmscore.tools.apk.arsc.XmlStartElementChunk; -import com.google.idea.blaze.android.run.deployinfo.BlazeAndroidDeployInfo; -import com.intellij.execution.ExecutionException; -import com.intellij.openapi.project.Project; -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.util.List; -import java.util.zip.ZipFile; -import org.jetbrains.annotations.NotNull; - -/** Checks APKs to see if they are debuggable and warn the user if they aren't. */ -public class CheckApkDebuggableTask implements BlazeLaunchTask { - private static final String ID = "APK_DEBUGGABILITY_CHECKER"; - private final BlazeAndroidDeployInfo deployInfo; - - public CheckApkDebuggableTask(Project project, BlazeAndroidDeployInfo deployInfo) { - this.deployInfo = deployInfo; - } - - @Override - public void run(@NotNull BlazeLaunchContext launchContext) throws ExecutionException { - checkApkDebuggableTaskDelegate( - launchContext.getEnv().getProject(), deployInfo, launchContext.getDevice()); - } - - /** - * Checks if all APKs in the deploy info are debuggable and output an error message to console if - * any of them aren't. This check doesn't apply if the target device is a running a debug build - * android (e.g. userdebug build) and will simply return. - */ - @VisibleForTesting - public static void checkApkDebuggableTaskDelegate( - Project project, BlazeAndroidDeployInfo deployInfo, IDevice device) - throws ExecutionException { - if (isDebugDevice(device)) { - return; - } - try { - ImmutableList nonDebuggableApkNames = - getNonDebuggableDeployApks(deployInfo).stream() - .map(File::getName) - .collect(toImmutableList()); - if (nonDebuggableApkNames.isEmpty()) { - return; - } - // Use "and" as delimiter because there won't be more than 2 APKs, so "and" makes more sense. - String message = - "The \"android:debuggable\" attribute is not set to \"true\" in " - + String.join(" and ", nonDebuggableApkNames) - + ". Debugger may not attach properly or attach at all." - + " Please ensure \"android:debuggable\" attribute is set to true or" - + " overridden to true via manifest overrides."; - RunConfigurationNotifier.INSTANCE.notifyWarning(project, "", message); - } catch (IOException e) { - throw new ExecutionException("Could not read deploy apks: " + e.getMessage()); - } - } - - private static ImmutableList getNonDebuggableDeployApks(BlazeAndroidDeployInfo deployInfo) - throws IOException { - ImmutableList.Builder nonDebuggableApks = ImmutableList.builder(); - for (File apk : deployInfo.getApksToDeploy()) { - if (!isApkDebuggable(apk)) { - nonDebuggableApks.add(apk); - } - } - return nonDebuggableApks.build(); - } - - /** Returns true if the device is a debug build device. */ - private static boolean isDebugDevice(IDevice device) { - String roDebuggable = device.getProperty("ro.debuggable"); - return (roDebuggable != null && roDebuggable.equals("1")); - } - - @VisibleForTesting - public static boolean isApkDebuggable(File apk) throws IOException { - try (ZipFile zipFile = new ZipFile(apk); - InputStream stream = zipFile.getInputStream(zipFile.getEntry("AndroidManifest.xml"))) { - BinaryResourceFile file = BinaryResourceFile.fromInputStream(stream); - List chunks = file.getChunks(); - - if (chunks.isEmpty()) { - throw new IllegalArgumentException("Invalid APK, empty manifest"); - } - - if (!(chunks.get(0) instanceof XmlChunk)) { - throw new IllegalArgumentException("APK manifest chunk[0] != XmlChunk"); - } - - XmlChunk xmlChunk = (XmlChunk) chunks.get(0); - for (Chunk chunk : xmlChunk.getChunks().values()) { - if (!(chunk instanceof XmlStartElementChunk)) { - continue; - } - - XmlStartElementChunk startChunk = (XmlStartElementChunk) chunk; - if (startChunk.getName().equals("application")) { - for (XmlAttribute attribute : startChunk.getAttributes()) { - if (attribute.name().equals("debuggable")) { - return true; - } - } - } - } - } - return false; - } -} diff --git a/aswb/sdkcompat/as231/com/google/idea/blaze/android/run/runner/LaunchOptionsCompat.java b/aswb/sdkcompat/as231/com/google/idea/blaze/android/run/runner/LaunchOptionsCompat.java deleted file mode 100644 index 5a606a8a2ea..00000000000 --- a/aswb/sdkcompat/as231/com/google/idea/blaze/android/run/runner/LaunchOptionsCompat.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright 2022 The Bazel Authors. All rights reserved. - * - * 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. - */ -package com.google.idea.blaze.android.run.runner; - -import com.android.tools.idea.run.LaunchOptions; - -/** Compat class for LunchOptions.Builder. */ -public class LaunchOptionsCompat { - - private LaunchOptionsCompat() {} - - /** Create default launch options to maintain compatibility with #api211. */ - public static LaunchOptions.Builder getDefaultLaunchOptions() { - return LaunchOptions.builder().setClearLogcatBeforeStart(false); - } -} diff --git a/aswb/sdkcompat/as231/com/google/idea/blaze/android/run/runner/MobileInstallApplicationDeployer.java b/aswb/sdkcompat/as231/com/google/idea/blaze/android/run/runner/MobileInstallApplicationDeployer.java deleted file mode 100644 index dad762309be..00000000000 --- a/aswb/sdkcompat/as231/com/google/idea/blaze/android/run/runner/MobileInstallApplicationDeployer.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright (C) 2022 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. - */ -package com.google.idea.blaze.android.run.runner; - -import com.android.ddmlib.IDevice; -import com.android.tools.deployer.ApkParser; -import com.android.tools.deployer.Deployer; -import com.android.tools.deployer.DeployerException; -import com.android.tools.deployer.model.Apk; -import com.android.tools.deployer.model.App; -import com.android.tools.idea.execution.common.ApplicationDeployer; -import com.android.tools.idea.execution.common.DeployOptions; -import com.android.tools.idea.run.ApkFileUnit; -import com.android.tools.idea.run.ApkInfo; -import com.android.tools.idea.run.configuration.execution.AdbCommandCaptureLoggerWithConsole; -import com.intellij.execution.ui.ConsoleView; -import com.intellij.openapi.diagnostic.Logger; -import com.intellij.openapi.progress.ProgressIndicator; -import java.nio.file.Path; -import java.util.List; -import java.util.stream.Collectors; -import org.jetbrains.annotations.NotNull; - -/** Deploys mobile install application. */ -public class MobileInstallApplicationDeployer implements ApplicationDeployer { - private static final Logger LOG = Logger.getInstance(MobileInstallApplicationDeployer.class); - private final ConsoleView myConsole; - - public MobileInstallApplicationDeployer(ConsoleView console) { - myConsole = console; - } - - @NotNull - @Override - public Deployer.Result fullDeploy( - @NotNull IDevice device, - @NotNull ApkInfo apkInfo, - @NotNull DeployOptions deployOptions, - ProgressIndicator indicator) - throws DeployerException { - final List apkPaths = - apkInfo.getFiles().stream() - .map(ApkFileUnit::getApkPath) - .map(Path::toString) - .collect(Collectors.toList()); - final List apks = new ApkParser().parsePaths(apkPaths); - App app = - new App( - apkInfo.getApplicationId(), - apks, - device, - new AdbCommandCaptureLoggerWithConsole(LOG, myConsole)); - return new Deployer.Result(false, false, false, app); - } - - @NotNull - @Override - public Deployer.Result applyChangesDeploy( - @NotNull IDevice device, - @NotNull ApkInfo app, - @NotNull DeployOptions deployOptions, - ProgressIndicator indicator) - throws DeployerException { - throw new RuntimeException("Apply changes is not supported for mobile-install"); - } - - @NotNull - @Override - public Deployer.Result applyCodeChangesDeploy( - @NotNull IDevice device, - @NotNull ApkInfo app, - @NotNull DeployOptions deployOptions, - ProgressIndicator indicator) - throws DeployerException { - throw new RuntimeException("Apply code changes is not supported for mobile-install"); - } -} diff --git a/aswb/sdkcompat/as231/com/google/idea/blaze/android/run/test/BlazeAndroidTestLaunchTask.java b/aswb/sdkcompat/as231/com/google/idea/blaze/android/run/test/BlazeAndroidTestLaunchTask.java deleted file mode 100644 index dc7dd974c06..00000000000 --- a/aswb/sdkcompat/as231/com/google/idea/blaze/android/run/test/BlazeAndroidTestLaunchTask.java +++ /dev/null @@ -1,265 +0,0 @@ -/* - * Copyright 2016 The Bazel Authors. All rights reserved. - * - * 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. - */ -package com.google.idea.blaze.android.run.test; - -import com.android.tools.idea.run.blaze.BlazeLaunchContext; -import com.android.tools.idea.run.blaze.BlazeLaunchTask; -import com.android.tools.idea.run.configuration.execution.ExecutionUtils; -import com.google.common.util.concurrent.ListenableFuture; -import com.google.idea.blaze.base.async.executor.BlazeExecutor; -import com.google.idea.blaze.base.async.process.ExternalTask; -import com.google.idea.blaze.base.async.process.LineProcessingOutputStream; -import com.google.idea.blaze.base.command.BlazeCommand; -import com.google.idea.blaze.base.command.BlazeCommandName; -import com.google.idea.blaze.base.command.BlazeFlags; -import com.google.idea.blaze.base.command.buildresult.BuildResultHelper; -import com.google.idea.blaze.base.command.buildresult.BuildResultHelper.GetArtifactsException; -import com.google.idea.blaze.base.command.buildresult.BuildResultHelperBep; -import com.google.idea.blaze.base.filecache.FileCaches; -import com.google.idea.blaze.base.ideinfo.AndroidInstrumentationInfo; -import com.google.idea.blaze.base.ideinfo.TargetIdeInfo; -import com.google.idea.blaze.base.ideinfo.TargetKey; -import com.google.idea.blaze.base.model.BlazeProjectData; -import com.google.idea.blaze.base.model.primitives.Label; -import com.google.idea.blaze.base.model.primitives.WorkspaceRoot; -import com.google.idea.blaze.base.projectview.ProjectViewManager; -import com.google.idea.blaze.base.projectview.ProjectViewSet; -import com.google.idea.blaze.base.run.testlogs.BlazeTestResultHolder; -import com.google.idea.blaze.base.scope.Scope; -import com.google.idea.blaze.base.scope.output.IssueOutput; -import com.google.idea.blaze.base.settings.Blaze; -import com.google.idea.blaze.base.sync.aspects.BlazeBuildOutputs; -import com.google.idea.blaze.base.sync.aspects.BuildResult; -import com.google.idea.blaze.base.sync.data.BlazeProjectDataManager; -import com.google.idea.blaze.base.util.SaveUtil; -import com.google.idea.blaze.java.AndroidBlazeRules.RuleTypes; -import com.intellij.execution.process.ProcessAdapter; -import com.intellij.execution.process.ProcessEvent; -import com.intellij.execution.process.ProcessHandler; -import com.intellij.execution.ui.ConsoleView; -import com.intellij.openapi.diagnostic.Logger; -import com.intellij.openapi.project.Project; -import java.util.List; -import java.util.Optional; -import java.util.concurrent.ExecutionException; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.ide.PooledThreadExecutor; - -/** - * An Android application launcher that invokes `blaze test` on an android_test target, and sets up - * process handling and debugging for the test run. - */ -public class BlazeAndroidTestLaunchTask implements BlazeLaunchTask { - private static final String ID = "BLAZE_ANDROID_TEST"; - - // Uses a local device/emulator attached to adb to run an android_test. - public static final String TEST_LOCAL_DEVICE = - BlazeFlags.TEST_ARG + "--device_broker_type=LOCAL_ADB_SERVER"; - // Uses a local device/emulator attached to adb to run an android_test. - public static final String TEST_DEBUG = BlazeFlags.TEST_ARG + "--enable_debug"; - // Specifies the serial number for a local test device. - private static final String TEST_DEVICE_SERIAL = "--device_serial_number="; - private static final Logger LOG = Logger.getInstance(BlazeAndroidTestLaunchTask.class); - - private final Project project; - private final Label target; - private final List buildFlags; - private final BlazeAndroidTestFilter testFilter; - private final BlazeTestResultHolder testResultsHolder; - - private ListenableFuture blazeResult; - - private final BlazeAndroidTestRunContext runContext; - - private final boolean debug; - - public BlazeAndroidTestLaunchTask( - Project project, - Label target, - List buildFlags, - BlazeAndroidTestFilter testFilter, - BlazeAndroidTestRunContext runContext, - boolean debug, - BlazeTestResultHolder testResultsHolder) { - this.project = project; - this.target = target; - this.buildFlags = buildFlags; - this.testFilter = testFilter; - this.runContext = runContext; - this.debug = debug; - this.testResultsHolder = testResultsHolder; - } - - @Override - public void run(@NotNull BlazeLaunchContext launchContext) - throws com.intellij.execution.ExecutionException { - BlazeExecutor blazeExecutor = BlazeExecutor.getInstance(); - - final ProcessHandler processHandler = launchContext.getProcessHandler(); - - blazeResult = - blazeExecutor.submit( - () -> - Scope.root( - context -> { - SaveUtil.saveAllFiles(); - - ProjectViewSet projectViewSet = - ProjectViewManager.getInstance(project).getProjectViewSet(); - if (projectViewSet == null) { - IssueOutput.error("Could not load project view. Please resync project.") - .submit(context); - return false; - } - - BlazeProjectData projectData = - BlazeProjectDataManager.getInstance(project).getBlazeProjectData(); - TargetIdeInfo targetInfo = - projectData.getTargetMap().get(TargetKey.forPlainTarget(target)); - if (targetInfo == null - || targetInfo.getKind() - != RuleTypes.ANDROID_INSTRUMENTATION_TEST.getKind()) { - IssueOutput.error( - "Unable to identify target \"" - + target - + "\". If this is a newly added target, please sync the" - + " project and try again.") - .submit(context); - return null; - } - AndroidInstrumentationInfo testInstrumentationInfo = - targetInfo.getAndroidInstrumentationInfo(); - if (testInstrumentationInfo == null) { - IssueOutput.error( - "Required target data missing for \"" - + target - + "\". Has the target definition changed recently? Please" - + " sync the project and try again.") - .submit(context); - return null; - } - - BlazeCommand.Builder commandBuilder = - BlazeCommand.builder( - Blaze.getBuildSystemProvider(project) - .getBuildSystem() - .getBuildInvoker(project, context), - BlazeCommandName.TEST) - .addTargets(target); - // Build flags must match BlazeBeforeRunTask. - commandBuilder.addBlazeFlags(buildFlags); - - // Run the test on the selected local device/emulator if no target device is - // specified. - Label targetDevice = testInstrumentationInfo.getTargetDevice(); - if (targetDevice == null) { - commandBuilder - .addBlazeFlags(TEST_LOCAL_DEVICE, BlazeFlags.TEST_OUTPUT_STREAMED) - .addBlazeFlags( - testDeviceSerialFlags(launchContext.getDevice().getSerialNumber())) - .addBlazeFlags(testFilter.getBlazeFlags()); - } - - if (debug) { - commandBuilder.addBlazeFlags(TEST_DEBUG, BlazeFlags.NO_CACHE_TEST_RESULTS); - } - - ConsoleView console = launchContext.getConsoleView(); - LineProcessingOutputStream.LineProcessor stdoutLineProcessor = - line -> { - ExecutionUtils.println(console, line); - return true; - }; - LineProcessingOutputStream.LineProcessor stderrLineProcessor = - line -> { - ExecutionUtils.println(console, line); - return true; - }; - - ExecutionUtils.println( - console, - String.format("Starting %s test...\n", Blaze.buildSystemName(project))); - - int retVal; - try (BuildResultHelper buildResultHelper = new BuildResultHelperBep()) { - commandBuilder.addBlazeFlags(buildResultHelper.getBuildFlags()); - BlazeCommand command = commandBuilder.build(); - ExecutionUtils.println(console, command + "\n"); - - retVal = - ExternalTask.builder(WorkspaceRoot.fromProject(project)) - .addBlazeCommand(command) - .context(context) - .stdout(LineProcessingOutputStream.of(stdoutLineProcessor)) - .stderr(LineProcessingOutputStream.of(stderrLineProcessor)) - .build() - .run(); - - if (retVal != 0) { - context.setHasError(); - } else { - testResultsHolder.setTestResults( - buildResultHelper.getTestResults(Optional.empty())); - } - ListenableFuture unusedFuture = - FileCaches.refresh( - project, - context, - BlazeBuildOutputs.noOutputs(BuildResult.fromExitCode(retVal))); - } catch (GetArtifactsException e) { - LOG.error(e.getMessage()); - } - return !context.hasErrors(); - })); - - blazeResult.addListener(runContext::onLaunchTaskComplete, PooledThreadExecutor.INSTANCE); - - // The debug case is set up in ConnectBlazeTestDebuggerTask - if (!debug) { - waitAndSetUpForKillingBlazeOnStop(processHandler); - } - } - - /** - * Hooks up the Blaze process to be killed if the user hits the 'Stop' button, then waits for the - * Blaze process to stop. In non-debug mode, we wait for test execution to finish before returning - * from launch() (this matches the behavior of the stock ddmlib runner). - */ - @SuppressWarnings("Interruption") - private void waitAndSetUpForKillingBlazeOnStop(@NotNull final ProcessHandler processHandler) { - processHandler.addProcessListener( - new ProcessAdapter() { - @Override - public void processWillTerminate(ProcessEvent event, boolean willBeDestroyed) { - blazeResult.cancel(true /* mayInterruptIfRunning */); - } - }); - - try { - blazeResult.get(); - } catch (InterruptedException e) { - // We've been interrupted - cancel the underlying Blaze process. - blazeResult.cancel(true /* mayInterruptIfRunning */); - } catch (ExecutionException e) { - LOG.error(e); - } - } - - @NotNull - private static String testDeviceSerialFlags(@NotNull String serial) { - return BlazeFlags.TEST_ARG + TEST_DEVICE_SERIAL + serial; - } -} diff --git a/aswb/sdkcompat/as231/com/google/idea/blaze/android/run/test/BlazeAndroidTestProgramRunner.java b/aswb/sdkcompat/as231/com/google/idea/blaze/android/run/test/BlazeAndroidTestProgramRunner.java deleted file mode 100644 index eab7b24890f..00000000000 --- a/aswb/sdkcompat/as231/com/google/idea/blaze/android/run/test/BlazeAndroidTestProgramRunner.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright 2018 The Bazel Authors. All rights reserved. - * - * 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. - */ -package com.google.idea.blaze.android.run.test; - -import com.android.tools.idea.run.configuration.AndroidConfigurationProgramRunner; -import com.android.tools.idea.run.configuration.execution.AndroidConfigurationExecutor; -import com.google.idea.blaze.android.run.BlazeAndroidRunConfigurationHandler; -import com.google.idea.blaze.base.run.BlazeCommandRunConfiguration; -import com.google.idea.blaze.base.run.BlazeCommandRunConfigurationType; -import com.intellij.execution.ExecutionException; -import com.intellij.execution.configurations.RunProfile; -import com.intellij.execution.configurations.RunProfileState; -import com.intellij.execution.executors.DefaultDebugExecutor; -import com.intellij.execution.executors.DefaultRunExecutor; -import com.intellij.execution.runners.ExecutionEnvironment; -import com.intellij.execution.ui.RunContentDescriptor; -import com.intellij.openapi.progress.ProgressIndicator; -import java.util.Collections; -import java.util.List; -import org.jetbrains.annotations.NotNull; - -/** Program runner for configurations from {@link BlazeAndroidTestRunConfigurationHandler}. */ -public class BlazeAndroidTestProgramRunner extends AndroidConfigurationProgramRunner { - @Override - public boolean canRun(String executorId, RunProfile profile) { - BlazeAndroidRunConfigurationHandler handler = - BlazeAndroidRunConfigurationHandler.getHandlerFrom(profile); - if (!(handler instanceof BlazeAndroidTestRunConfigurationHandler)) { - return false; - } - if (!(profile instanceof BlazeCommandRunConfiguration)) { - return false; - } - return DefaultRunExecutor.EXECUTOR_ID.equals(executorId) - || DefaultDebugExecutor.EXECUTOR_ID.equals(executorId); - } - - @Override - public String getRunnerId() { - return "AndroidTestProgramRunner"; - } - - @Override - protected boolean canRunWithMultipleDevices(@NotNull String executorId) { - return true; - } - - @NotNull - @Override - protected List getSupportedConfigurationTypeIds() { - return Collections.singletonList(BlazeCommandRunConfigurationType.getInstance().getId()); - } - - @NotNull - @Override - protected RunContentDescriptor run( - @NotNull ExecutionEnvironment environment, - @NotNull RunProfileState state, - @NotNull ProgressIndicator indicator) - throws ExecutionException { - final AndroidConfigurationExecutor state1 = (AndroidConfigurationExecutor) state; - if (DefaultDebugExecutor.EXECUTOR_ID.equals(environment.getExecutor().getId())) { - return state1.debug(indicator); - } - if (DefaultRunExecutor.EXECUTOR_ID.equals(environment.getExecutor().getId())) { - return state1.run(indicator); - } - throw new RuntimeException("Unsupported executor"); - } -} diff --git a/aswb/sdkcompat/as231/com/google/idea/blaze/android/run/test/BlazeAndroidTestRunConfigurationHandler.java b/aswb/sdkcompat/as231/com/google/idea/blaze/android/run/test/BlazeAndroidTestRunConfigurationHandler.java deleted file mode 100644 index 050ddc03fee..00000000000 --- a/aswb/sdkcompat/as231/com/google/idea/blaze/android/run/test/BlazeAndroidTestRunConfigurationHandler.java +++ /dev/null @@ -1,224 +0,0 @@ -/* - * Copyright 2016 The Bazel Authors. All rights reserved. - * - * 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. - */ -package com.google.idea.blaze.android.run.test; - -import static com.android.tools.idea.run.deployment.DeviceAndSnapshotComboBoxAction.DEPLOYS_TO_LOCAL_DEVICE; - -import com.android.tools.idea.run.ValidationError; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.Lists; -import com.google.idea.blaze.android.run.ApkBuildStepProvider; -import com.google.idea.blaze.android.run.BlazeAndroidRunConfigurationCommonState; -import com.google.idea.blaze.android.run.BlazeAndroidRunConfigurationHandler; -import com.google.idea.blaze.android.run.BlazeAndroidRunConfigurationValidationUtil; -import com.google.idea.blaze.android.run.LaunchMetrics; -import com.google.idea.blaze.android.run.runner.ApkBuildStep; -import com.google.idea.blaze.android.run.runner.BlazeAndroidRunConfigurationRunner; -import com.google.idea.blaze.android.run.runner.BlazeAndroidRunContext; -import com.google.idea.blaze.android.run.runner.FullApkBuildStep; -import com.google.idea.blaze.android.run.test.BlazeAndroidTestLaunchMethodsProvider.AndroidTestLaunchMethod; -import com.google.idea.blaze.base.command.BlazeCommandName; -import com.google.idea.blaze.base.command.BlazeInvocationContext; -import com.google.idea.blaze.base.model.primitives.Label; -import com.google.idea.blaze.base.model.primitives.TargetExpression; -import com.google.idea.blaze.base.projectview.ProjectViewManager; -import com.google.idea.blaze.base.projectview.ProjectViewSet; -import com.google.idea.blaze.base.run.BlazeCommandRunConfiguration; -import com.google.idea.blaze.base.run.BlazeConfigurationNameBuilder; -import com.google.idea.blaze.base.run.ExecutorType; -import com.google.idea.blaze.base.run.confighandler.BlazeCommandRunConfigurationRunner; -import com.google.idea.blaze.base.settings.Blaze; -import com.google.idea.blaze.base.sync.data.BlazeDataStorage; -import com.google.idea.blaze.base.sync.projectstructure.ModuleFinder; -import com.google.idea.blaze.java.AndroidBlazeRules; -import com.intellij.execution.ExecutionException; -import com.intellij.execution.Executor; -import com.intellij.execution.JavaExecutionUtil; -import com.intellij.execution.configurations.RuntimeConfigurationException; -import com.intellij.execution.runners.ExecutionEnvironment; -import com.intellij.openapi.module.Module; -import com.intellij.openapi.project.Project; -import java.util.List; -import javax.annotation.Nullable; -import org.jetbrains.android.facet.AndroidFacet; - -/** - * {@link com.google.idea.blaze.base.run.confighandler.BlazeCommandRunConfigurationHandler} for - * android_test targets. - */ -public class BlazeAndroidTestRunConfigurationHandler - implements BlazeAndroidRunConfigurationHandler { - private final Project project; - private final BlazeAndroidTestRunConfigurationState configState; - - BlazeAndroidTestRunConfigurationHandler(BlazeCommandRunConfiguration configuration) { - this.project = configuration.getProject(); - this.configState = - new BlazeAndroidTestRunConfigurationState( - Blaze.buildSystemName(configuration.getProject())); - configuration.putUserData(DEPLOYS_TO_LOCAL_DEVICE, true); - } - - @Override - public BlazeAndroidTestRunConfigurationState getState() { - return configState; - } - - @Override - public BlazeAndroidRunConfigurationCommonState getCommonState() { - return configState.getCommonState(); - } - - @Override - public BlazeCommandRunConfigurationRunner createRunner( - Executor executor, ExecutionEnvironment env) throws ExecutionException { - Project project = env.getProject(); - BlazeCommandRunConfiguration configuration = - BlazeAndroidRunConfigurationHandler.getCommandConfig(env); - - BlazeAndroidRunConfigurationValidationUtil.validate(project); - Module module = - ModuleFinder.getInstance(env.getProject()) - .findModuleByName(BlazeDataStorage.WORKSPACE_MODULE_NAME); - AndroidFacet facet = module != null ? AndroidFacet.getInstance(module) : null; - ProjectViewSet projectViewSet = ProjectViewManager.getInstance(project).getProjectViewSet(); - - ImmutableList blazeFlags = - configState - .getCommonState() - .getExpandedBuildFlags( - project, - projectViewSet, - BlazeCommandName.TEST, - BlazeInvocationContext.runConfigContext( - ExecutorType.fromExecutor(env.getExecutor()), configuration.getType(), false)); - ImmutableList exeFlags = - ImmutableList.copyOf( - configState.getCommonState().getExeFlagsState().getFlagsForExternalProcesses()); - - // We collect metrics from a few different locations. In order to tie them all - // together, we create a unique launch id. - String launchId = LaunchMetrics.newLaunchId(); - Label label = Label.create(configuration.getSingleTarget().toString()); - - ApkBuildStep buildStep = - getTestBuildStep( - project, configState, configuration, blazeFlags, exeFlags, launchId, label); - - BlazeAndroidRunContext runContext = - new BlazeAndroidTestRunContext( - project, facet, configuration, env, configState, label, blazeFlags, buildStep); - - LaunchMetrics.logTestLaunch( - launchId, configState.getLaunchMethod().name(), env.getExecutor().getId()); - - return new BlazeAndroidRunConfigurationRunner(module, runContext, configuration); - } - - private static ApkBuildStep getTestBuildStep( - Project project, - BlazeAndroidTestRunConfigurationState configState, - BlazeCommandRunConfiguration configuration, - ImmutableList blazeFlags, - ImmutableList exeFlags, - String launchId, - Label label) - throws ExecutionException { - if (configuration.getTargetKind() - == AndroidBlazeRules.RuleTypes.ANDROID_INSTRUMENTATION_TEST.getKind()) { - boolean useMobileInstall = - AndroidTestLaunchMethod.MOBILE_INSTALL.equals(configState.getLaunchMethod()); - return ApkBuildStepProvider.getInstance(Blaze.getBuildSystemName(project)) - .getAitBuildStep( - project, - useMobileInstall, - /* nativeDebuggingEnabled= */ false, - label, - blazeFlags, - exeFlags, - launchId); - } else { - // TODO(b/248317444): This path is only invoked for the deprecated {@code android_test} - // targets, and should eventually be removed. - return new FullApkBuildStep(project, label, blazeFlags, /* nativeDebuggingEnabled= */ false); - } - } - - @Override - public final void checkConfiguration() throws RuntimeConfigurationException { - BlazeAndroidRunConfigurationValidationUtil.throwTopConfigurationError(validate()); - } - - /** - * We collect errors rather than throwing to avoid missing fatal errors by exiting early for a - * warning. We use a separate method for the collection so the compiler prevents us from - * accidentally throwing. - */ - private List validate() { - List errors = Lists.newArrayList(); - errors.addAll(BlazeAndroidRunConfigurationValidationUtil.validateWorkspaceModule(project)); - errors.addAll(configState.validate(project)); - return errors; - } - - @Override - @Nullable - public String suggestedName(BlazeCommandRunConfiguration configuration) { - TargetExpression target = configuration.getSingleTarget(); - if (target == null) { - return null; - } - BlazeConfigurationNameBuilder nameBuilder = new BlazeConfigurationNameBuilder(configuration); - - boolean isClassTest = - configState.getTestingType() == BlazeAndroidTestRunConfigurationState.TEST_CLASS; - boolean isMethodTest = - configState.getTestingType() == BlazeAndroidTestRunConfigurationState.TEST_METHOD; - if ((isClassTest || isMethodTest) && configState.getClassName() != null) { - // Get the class name without the package. - String className = JavaExecutionUtil.getPresentableClassName(configState.getClassName()); - if (className != null) { - String targetString = className; - if (isMethodTest) { - targetString += "#" + configState.getMethodName(); - } - - if (getState().getLaunchMethod().equals(AndroidTestLaunchMethod.NON_BLAZE)) { - return targetString; - } else { - return nameBuilder.setTargetString(targetString).build(); - } - } - } - return nameBuilder.build(); - } - - @Override - @Nullable - public BlazeCommandName getCommandName() { - if (getState().getLaunchMethod().equals(AndroidTestLaunchMethod.BLAZE_TEST)) { - return BlazeCommandName.TEST; - } else if (getState().getLaunchMethod().equals(AndroidTestLaunchMethod.MOBILE_INSTALL)) { - return BlazeCommandName.MOBILE_INSTALL; - } - return null; - } - - @Override - public String getHandlerName() { - return "Android Test Handler"; - } -} diff --git a/aswb/sdkcompat/as231/com/google/idea/blaze/android/run/test/BlazeAndroidTestRunContext.java b/aswb/sdkcompat/as231/com/google/idea/blaze/android/run/test/BlazeAndroidTestRunContext.java deleted file mode 100644 index feaec07157c..00000000000 --- a/aswb/sdkcompat/as231/com/google/idea/blaze/android/run/test/BlazeAndroidTestRunContext.java +++ /dev/null @@ -1,229 +0,0 @@ -/* - * Copyright 2016 The Bazel Authors. All rights reserved. - * - * 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. - */ -package com.google.idea.blaze.android.run.test; - -import static com.android.tools.idea.run.tasks.DefaultConnectDebuggerTaskKt.getBaseDebuggerTask; -import static com.google.idea.blaze.android.run.binary.BlazeAndroidBinaryNormalBuildRunContextBase.getApkInfoToInstall; - -import com.android.ddmlib.IDevice; -import com.android.tools.idea.execution.common.debug.AndroidDebugger; -import com.android.tools.idea.execution.common.debug.AndroidDebuggerState; -import com.android.tools.idea.run.ApkProvider; -import com.android.tools.idea.run.ApkProvisionException; -import com.android.tools.idea.run.ApplicationIdProvider; -import com.android.tools.idea.run.ConsoleProvider; -import com.android.tools.idea.run.LaunchOptions; -import com.android.tools.idea.run.blaze.BlazeLaunchTask; -import com.android.tools.idea.run.blaze.BlazeLaunchTasksProvider; -import com.android.tools.idea.run.editor.ProfilerState; -import com.android.tools.idea.run.tasks.ConnectDebuggerTask; -import com.android.tools.idea.run.tasks.DeployTasksCompat; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.Lists; -import com.google.idea.blaze.android.run.deployinfo.BlazeAndroidDeployInfo; -import com.google.idea.blaze.android.run.deployinfo.BlazeApkProviderService; -import com.google.idea.blaze.android.run.runner.ApkBuildStep; -import com.google.idea.blaze.android.run.runner.BlazeAndroidDeviceSelector; -import com.google.idea.blaze.android.run.runner.BlazeAndroidLaunchTasksProvider; -import com.google.idea.blaze.android.run.runner.BlazeAndroidRunContext; -import com.google.idea.blaze.android.run.test.BlazeAndroidTestLaunchMethodsProvider.AndroidTestLaunchMethod; -import com.google.idea.blaze.base.model.primitives.Label; -import com.google.idea.blaze.base.run.BlazeCommandRunConfiguration; -import com.google.idea.blaze.base.run.smrunner.BlazeTestUiSession; -import com.google.idea.blaze.base.run.testlogs.BlazeTestResultHolder; -import com.intellij.execution.ExecutionException; -import com.intellij.execution.Executor; -import com.intellij.execution.runners.ExecutionEnvironment; -import com.intellij.openapi.project.Project; -import java.util.List; -import javax.annotation.Nullable; -import org.jetbrains.android.facet.AndroidFacet; - -/** Run context for android_test. */ -public class BlazeAndroidTestRunContext implements BlazeAndroidRunContext { - protected final Project project; - protected final AndroidFacet facet; - protected final BlazeCommandRunConfiguration runConfiguration; - protected final ExecutionEnvironment env; - protected final BlazeAndroidTestRunConfigurationState configState; - protected final Label label; - protected final ImmutableList blazeFlags; - protected final List launchTaskCompleteListeners = Lists.newArrayList(); - protected final ConsoleProvider consoleProvider; - protected final ApkBuildStep buildStep; - protected final ApplicationIdProvider applicationIdProvider; - protected final ApkProvider apkProvider; - private final BlazeTestResultHolder testResultsHolder = new BlazeTestResultHolder(); - - public BlazeAndroidTestRunContext( - Project project, - AndroidFacet facet, - BlazeCommandRunConfiguration runConfiguration, - ExecutionEnvironment env, - BlazeAndroidTestRunConfigurationState configState, - Label label, - ImmutableList blazeFlags, - ApkBuildStep buildStep) { - this.project = project; - this.facet = facet; - this.runConfiguration = runConfiguration; - this.env = env; - this.label = label; - this.configState = configState; - this.buildStep = buildStep; - this.blazeFlags = blazeFlags; - switch (configState.getLaunchMethod()) { - case MOBILE_INSTALL: - case NON_BLAZE: - consoleProvider = new AitIdeTestConsoleProvider(runConfiguration, configState); - break; - case BLAZE_TEST: - BlazeTestUiSession session = - BlazeTestUiSession.create(ImmutableList.of(), testResultsHolder); - this.consoleProvider = new AitBlazeTestConsoleProvider(project, runConfiguration, session); - break; - default: - throw new IllegalStateException( - "Unsupported launch method " + configState.getLaunchMethod()); - } - applicationIdProvider = new BlazeAndroidTestApplicationIdProvider(buildStep); - apkProvider = BlazeApkProviderService.getInstance().getApkProvider(project, buildStep); - } - - @Override - public BlazeAndroidDeviceSelector getDeviceSelector() { - return new BlazeAndroidDeviceSelector.NormalDeviceSelector(); - } - - @Override - public void augmentLaunchOptions(LaunchOptions.Builder options) { - options.setDeploy(!configState.getLaunchMethod().equals(AndroidTestLaunchMethod.BLAZE_TEST)); - } - - @Override - public ConsoleProvider getConsoleProvider() { - return consoleProvider; - } - - @Override - public ApplicationIdProvider getApplicationIdProvider() throws ExecutionException { - return applicationIdProvider; - } - - @Nullable - @Override - public ApkBuildStep getBuildStep() { - return buildStep; - } - - @Override - public ProfilerState getProfileState() { - return null; - } - - @Override - public BlazeLaunchTasksProvider getLaunchTasksProvider(LaunchOptions.Builder launchOptionsBuilder) - throws ExecutionException { - return new BlazeAndroidLaunchTasksProvider( - project, this, applicationIdProvider, launchOptionsBuilder); - } - - @Override - public ImmutableList getDeployTasks(IDevice device, LaunchOptions launchOptions) - throws ExecutionException { - if (configState.getLaunchMethod() != AndroidTestLaunchMethod.NON_BLAZE) { - return ImmutableList.of(); - } - return ImmutableList.of( - DeployTasksCompat.createDeployTask( - project, getApkInfoToInstall(device, launchOptions, apkProvider), launchOptions)); - } - - @Override - @Nullable - public BlazeLaunchTask getApplicationLaunchTask( - LaunchOptions launchOptions, @Nullable Integer userId, String contributorsAmStartOptions) - throws ExecutionException { - switch (configState.getLaunchMethod()) { - case BLAZE_TEST: - BlazeAndroidTestFilter testFilter = - new BlazeAndroidTestFilter( - configState.getTestingType(), - configState.getClassName(), - configState.getMethodName(), - configState.getPackageName()); - return new BlazeAndroidTestLaunchTask( - project, - label, - blazeFlags, - testFilter, - this, - launchOptions.isDebug(), - testResultsHolder); - case NON_BLAZE: - case MOBILE_INSTALL: - BlazeAndroidDeployInfo deployInfo; - try { - deployInfo = buildStep.getDeployInfo(); - } catch (ApkProvisionException e) { - throw new ExecutionException(e); - } - return StockAndroidTestLaunchTask.getStockTestLaunchTask( - configState, applicationIdProvider, launchOptions.isDebug(), deployInfo, project); - } - throw new AssertionError(); - } - - @Override - @SuppressWarnings({"unchecked", "rawtypes"}) // Raw type from upstream. - public ConnectDebuggerTask getDebuggerTask( - AndroidDebugger androidDebugger, AndroidDebuggerState androidDebuggerState) { - switch (configState.getLaunchMethod()) { - case BLAZE_TEST: - return new ConnectBlazeTestDebuggerTask(this, androidDebugger, androidDebuggerState); - case NON_BLAZE: - case MOBILE_INSTALL: - return getBaseDebuggerTask(androidDebugger, androidDebuggerState, env, facet, 30); - } - throw new AssertionError(); - } - - void onLaunchTaskComplete() { - for (Runnable runnable : launchTaskCompleteListeners) { - runnable.run(); - } - } - - void addLaunchTaskCompleteListener(Runnable runnable) { - launchTaskCompleteListeners.add(runnable); - } - - @Override - public Executor getExecutor() { - return env.getExecutor(); - } - - @Nullable - @Override - public Integer getUserId(IDevice device) { - return null; - } - - @Override - public String getAmStartOptions() { - return ""; - } -} diff --git a/aswb/sdkcompat/as231/com/google/idea/blaze/android/run/test/ConnectBlazeTestDebuggerTask.java b/aswb/sdkcompat/as231/com/google/idea/blaze/android/run/test/ConnectBlazeTestDebuggerTask.java deleted file mode 100644 index 3ef2a6c9493..00000000000 --- a/aswb/sdkcompat/as231/com/google/idea/blaze/android/run/test/ConnectBlazeTestDebuggerTask.java +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Copyright 2016 The Bazel Authors. All rights reserved. - * - * 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. - */ -package com.google.idea.blaze.android.run.test; - -import com.android.ddmlib.IDevice; -import com.android.tools.idea.execution.common.debug.AndroidDebugger; -import com.android.tools.idea.execution.common.debug.AndroidDebuggerState; -import com.android.tools.idea.execution.common.debug.DebugSessionStarter; -import com.android.tools.idea.run.tasks.ConnectDebuggerTask; -import com.intellij.execution.process.ProcessHandler; -import com.intellij.execution.process.ProcessOutputTypes; -import com.intellij.execution.runners.ExecutionEnvironment; -import com.intellij.execution.ui.ConsoleView; -import com.intellij.openapi.progress.ProgressIndicator; -import com.intellij.xdebugger.impl.XDebugSessionImpl; -import java.io.OutputStream; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -/** Connects the blaze debugger during execution. */ -class ConnectBlazeTestDebuggerTask implements ConnectDebuggerTask { - - private final BlazeAndroidTestRunContext runContext; - private final AndroidDebugger myAndroidDebugger; - private final S myAndroidDebuggerState; - - public ConnectBlazeTestDebuggerTask( - BlazeAndroidTestRunContext runContext, - AndroidDebugger androidDebugger, - S androidDebuggerState) { - this.runContext = runContext; - myAndroidDebugger = androidDebugger; - myAndroidDebuggerState = androidDebuggerState; - } - - /** - * Wires up listeners to automatically reconnect the debugger for each test method. When you - * `blaze test` an android_test in debug mode, it kills the instrumentation process between each - * test method, disconnecting the debugger. We listen for the start of a new method waiting for a - * debugger, and reconnect. TODO: Support stopping Blaze from the UI. This is hard because we have - * no way to distinguish process handler termination/debug session ending initiated by the user. - * - * @return Promise with debug session or error - */ - @Override - public @NotNull XDebugSessionImpl perform( - @NotNull IDevice device, - @NotNull String applicationId, - @NotNull ExecutionEnvironment environment, - @NotNull ProgressIndicator progressIndicator, - ConsoleView console) { - final ProcessHandler masterProcessHandler = - new ProcessHandler() { - - @Override - protected void destroyProcessImpl() { - notifyProcessTerminated(0); - } - - @Override - protected void detachProcessImpl() { - notifyProcessDetached(); - } - - @Override - public boolean detachIsDefault() { - return false; - } - - @Override - public @Nullable OutputStream getProcessInput() { - return null; - } - }; - runContext.addLaunchTaskCompleteListener( - () -> { - masterProcessHandler.notifyTextAvailable( - "Test run completed.\n", ProcessOutputTypes.STDOUT); - masterProcessHandler.detachProcess(); - }); - return DebugSessionStarter.INSTANCE.attachReattachingDebuggerToStartedProcess( - device, - applicationId, - masterProcessHandler, - environment, - myAndroidDebugger, - myAndroidDebuggerState, - progressIndicator, - console, - Long.MAX_VALUE); - } -} diff --git a/aswb/sdkcompat/as231/com/google/idea/blaze/android/run/test/StockAndroidTestLaunchTask.java b/aswb/sdkcompat/as231/com/google/idea/blaze/android/run/test/StockAndroidTestLaunchTask.java deleted file mode 100644 index b5df308dcea..00000000000 --- a/aswb/sdkcompat/as231/com/google/idea/blaze/android/run/test/StockAndroidTestLaunchTask.java +++ /dev/null @@ -1,207 +0,0 @@ -/* - * Copyright 2016 The Bazel Authors. All rights reserved. - * - * 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. - */ -package com.google.idea.blaze.android.run.test; - -import com.android.ddmlib.IDevice; -import com.android.ddmlib.testrunner.RemoteAndroidTestRunner; -import com.android.tools.idea.execution.common.RunConfigurationNotifier; -import com.android.tools.idea.execution.common.processhandler.AndroidProcessHandler; -import com.android.tools.idea.run.ApkProvisionException; -import com.android.tools.idea.run.ApplicationIdProvider; -import com.android.tools.idea.run.blaze.BlazeLaunchContext; -import com.android.tools.idea.run.blaze.BlazeLaunchTask; -import com.android.tools.idea.run.configuration.execution.ExecutionUtils; -import com.android.tools.idea.testartifacts.instrumented.AndroidTestListener; -import com.google.common.collect.ImmutableList; -import com.google.idea.blaze.android.manifest.ManifestParser; -import com.google.idea.blaze.android.run.deployinfo.BlazeAndroidDeployInfo; -import com.intellij.execution.ExecutionException; -import com.intellij.execution.process.ProcessHandler; -import com.intellij.execution.ui.ConsoleView; -import com.intellij.openapi.application.ApplicationManager; -import com.intellij.openapi.diagnostic.Logger; -import com.intellij.openapi.project.Project; -import com.intellij.openapi.util.Computable; -import com.intellij.openapi.util.text.StringUtil; -import java.util.List; -import javax.annotation.Nullable; -import org.jetbrains.annotations.NotNull; - -class StockAndroidTestLaunchTask implements BlazeLaunchTask { - private static final String ID = "STOCK_ANDROID_TEST"; - private static final Logger LOG = Logger.getInstance(StockAndroidTestLaunchTask.class); - private final BlazeAndroidTestRunConfigurationState configState; - private final String instrumentationTestRunner; - private final String testApplicationId; - private final boolean waitForDebugger; - - StockAndroidTestLaunchTask( - BlazeAndroidTestRunConfigurationState configState, - String runner, - String testPackage, - boolean waitForDebugger) { - this.configState = configState; - this.instrumentationTestRunner = runner; - this.waitForDebugger = waitForDebugger; - this.testApplicationId = testPackage; - } - - @Nullable - public static BlazeLaunchTask getStockTestLaunchTask( - BlazeAndroidTestRunConfigurationState configState, - ApplicationIdProvider applicationIdProvider, - boolean waitForDebugger, - BlazeAndroidDeployInfo deployInfo, - Project project) - throws ExecutionException { - String testPackage; - try { - testPackage = applicationIdProvider.getTestPackageName(); - } catch (ApkProvisionException e) { - throw new ExecutionException("Unable to determine test package name. " + e.getMessage()); - } - if (testPackage == null) { - throw new ExecutionException("Unable to determine test package name."); - } - List availableRunners = getRunnersFromManifest(deployInfo); - if (availableRunners.isEmpty()) { - RunConfigurationNotifier.INSTANCE.notifyError( - project, - "", - String.format( - "No instrumentation test runner is defined in the manifest.\n" - + "At least one instrumentation tag must be defined for the\n" - + "\"%1$s\" package in the AndroidManifest.xml, e.g.:\n" - + "\n" - + "\n" - + "\n" - + " \n" - + " \n" - + "\n" - + "", - testPackage)); - // Note: Gradle users will never see the above message, so don't mention Gradle here. - // Even if no runners are defined in build.gradle, Gradle will add a default to the manifest. - throw new ExecutionException("No instrumentation test runner is defined in the manifest."); - } - String runner = configState.getInstrumentationRunnerClass(); - if (StringUtil.isEmpty(runner)) { - // Default to the first available runner. - runner = availableRunners.get(0); - } - if (!availableRunners.contains(runner)) { - RunConfigurationNotifier.INSTANCE.notifyError( - project, - "", - String.format( - "Instrumentation test runner \"%2$s\"\n" - + "is not defined for the \"%1$s\" package in the manifest.\n" - + "Clear the 'Specific instrumentation runner' field in your configuration\n" - + "to default to \"%3$s\",\n" - + "or add the runner to your AndroidManifest.xml:\n" - + "\n" - + "\n" - + "\n" - + " \n" - + " \n" - + "\n" - + "", - testPackage, runner, availableRunners.get(0))); - throw new ExecutionException( - String.format( - "Instrumentation test runner \"%2$s\" is not defined for the \"%1$s\" package in the" - + " manifest.", - testPackage, runner)); - } - - return new StockAndroidTestLaunchTask(configState, runner, testPackage, waitForDebugger); - } - - private static ImmutableList getRunnersFromManifest( - final BlazeAndroidDeployInfo deployInfo) { - if (!ApplicationManager.getApplication().isReadAccessAllowed()) { - return ApplicationManager.getApplication() - .runReadAction( - (Computable>) () -> getRunnersFromManifest(deployInfo)); - } - ManifestParser.ParsedManifest parsedManifest = deployInfo.getMergedManifest(); - if (parsedManifest != null) { - return ImmutableList.copyOf(parsedManifest.instrumentationClassNames); - } - return ImmutableList.of(); - } - - @SuppressWarnings("FutureReturnValueIgnored") - public void run(@NotNull BlazeLaunchContext launchContext) { - ConsoleView console = launchContext.getConsoleView(); - IDevice device = launchContext.getDevice(); - ExecutionUtils.println(console, "Running tests\n"); - final RemoteAndroidTestRunner runner = - new RemoteAndroidTestRunner(testApplicationId, instrumentationTestRunner, device); - switch (configState.getTestingType()) { - case BlazeAndroidTestRunConfigurationState.TEST_ALL_IN_MODULE: - break; - case BlazeAndroidTestRunConfigurationState.TEST_ALL_IN_PACKAGE: - runner.setTestPackageName(configState.getPackageName()); - break; - case BlazeAndroidTestRunConfigurationState.TEST_CLASS: - runner.setClassName(configState.getClassName()); - break; - case BlazeAndroidTestRunConfigurationState.TEST_METHOD: - runner.setMethodName(configState.getClassName(), configState.getMethodName()); - break; - default: - throw new RuntimeException( - String.format("Unrecognized testing type: %d", configState.getTestingType())); - } - runner.setDebug(waitForDebugger); - runner.setRunOptions(configState.getExtraOptions()); - ExecutionUtils.printShellCommand(console, runner.getAmInstrumentCommand()); - // run in a separate thread as this will block until the tests complete - ApplicationManager.getApplication() - .executeOnPooledThread( - () -> { - try { - // This issues "am instrument" command and blocks execution. - runner.run(new AndroidTestListener(console)); - // Detach the device from the android process handler manually as soon as "am - // instrument" command finishes. This is required because the android process - // handler may overlook target process especially when the test - // runs really fast (~10ms). Because the android process handler discovers new - // processes by polling, this race condition happens easily. By detaching the device - // manually, we can avoid the android process handler waiting for (already finished) - // process to show up until it times out (10 secs). - // Note: this is a copy of ag/9593981, but it is worth figuring out a better - // strategy here if the behavior of AndroidTestListener is not guaranteed. - ProcessHandler processHandler = launchContext.getProcessHandler(); - if (processHandler instanceof AndroidProcessHandler) { - ((AndroidProcessHandler) processHandler).detachDevice(launchContext.getDevice()); - } - } catch (Exception e) { - ExecutionUtils.printlnError( - console, "Error: Unexpected exception while running tests: " + e); - } - }); - } -} diff --git a/aswb/sdkcompat/as231/com/google/idea/blaze/android/sync/model/idea/BlazeAndroidModel.java b/aswb/sdkcompat/as231/com/google/idea/blaze/android/sync/model/idea/BlazeAndroidModel.java deleted file mode 100644 index 3049cdd0eff..00000000000 --- a/aswb/sdkcompat/as231/com/google/idea/blaze/android/sync/model/idea/BlazeAndroidModel.java +++ /dev/null @@ -1,53 +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. - */ -package com.google.idea.blaze.android.sync.model.idea; - -import com.android.tools.idea.model.AndroidModel; -import com.android.tools.idea.model.Namespacing; -import com.android.tools.idea.projectsystem.NamedIdeaSourceProvider; -import com.google.common.util.concurrent.ListenableFuture; -import com.intellij.openapi.project.Project; -import java.io.File; - -/** Blaze model for an android project. #api42. */ -public class BlazeAndroidModel extends BlazeAndroidModelBase { - private final NamedIdeaSourceProvider sourceProvider; - - public BlazeAndroidModel( - Project project, - File rootDirPath, - NamedIdeaSourceProvider sourceProvider, - ListenableFuture applicationId, - int minSdkVersion, - boolean desugarJava8Libs) { - super(project, rootDirPath, applicationId, minSdkVersion, desugarJava8Libs); - this.sourceProvider = sourceProvider; - } - - public NamedIdeaSourceProvider getDefaultSourceProvider() { - return sourceProvider; - } - - @Override - public Namespacing getNamespacing() { - return Namespacing.DISABLED; - } - - @Override - protected String uninitializedApplicationId() { - return AndroidModel.UNINITIALIZED_APPLICATION_ID; - } -} diff --git a/aswb/sdkcompat/as231/org/jetbrains/android/facet/AndroidFacetPropertiesCompat.java b/aswb/sdkcompat/as231/org/jetbrains/android/facet/AndroidFacetPropertiesCompat.java deleted file mode 100644 index fff25619e8a..00000000000 --- a/aswb/sdkcompat/as231/org/jetbrains/android/facet/AndroidFacetPropertiesCompat.java +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright 2022 The Bazel Authors. All rights reserved. - * - * 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. - */ -package org.jetbrains.android.facet; - -/** Compat class for AndroidFacetProperties. */ -public class AndroidFacetPropertiesCompat { - - private AndroidFacetPropertiesCompat() {} - - public static void enableSourcesAutogeneration(AndroidFacetProperties props, boolean enable) {} -} diff --git a/aswb/sdkcompat/as231/org/jetbrains/android/sdk/AndroidPlatformCompat.java b/aswb/sdkcompat/as231/org/jetbrains/android/sdk/AndroidPlatformCompat.java deleted file mode 100644 index f745ba55516..00000000000 --- a/aswb/sdkcompat/as231/org/jetbrains/android/sdk/AndroidPlatformCompat.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright 2023 The Bazel Authors. All rights reserved. - * - * 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. - */ -package org.jetbrains.android.sdk; - -import com.android.sdklib.BuildToolInfo; -import com.android.tools.sdk.AndroidPlatform; -import com.intellij.openapi.projectRoots.Sdk; - -/** Compat class for {@link com.android.tools.sdk.AndroidPlatform} */ -public class AndroidPlatformCompat { - AndroidPlatform androidPlatform; - - public AndroidPlatformCompat(AndroidPlatform androidPlatform) { - this.androidPlatform = androidPlatform; - } - - public BuildToolInfo getLatestBuildTool(boolean allowBuildTool) { - return androidPlatform.getSdkData().getLatestBuildTool(allowBuildTool); - } - - public int getApiLevel() { - return androidPlatform.getApiLevel(); - } - - public static int getApiLevel(Sdk sdk) { - int androidSdkApiLevel = 1; - AndroidSdkAdditionalData additionalData = (AndroidSdkAdditionalData) sdk.getSdkAdditionalData(); - if (additionalData != null) { - AndroidPlatform androidPlatform = additionalData.getAndroidPlatform(); - if (androidPlatform != null) { - androidSdkApiLevel = androidPlatform.getApiLevel(); - } - } - return androidSdkApiLevel; - } -} diff --git a/aswb/sdkcompat/as231/org/jetbrains/android/sdk/AndroidPlatformsCompat.java b/aswb/sdkcompat/as231/org/jetbrains/android/sdk/AndroidPlatformsCompat.java deleted file mode 100644 index d016d7ce236..00000000000 --- a/aswb/sdkcompat/as231/org/jetbrains/android/sdk/AndroidPlatformsCompat.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright 2023 The Bazel Authors. All rights reserved. - * - * 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. - */ -package org.jetbrains.android.sdk; - -import com.intellij.openapi.module.Module; -import com.intellij.openapi.projectRoots.Sdk; - -/** Compat shim class for {@link AndroidPlatforms} */ -public class AndroidPlatformsCompat { - private AndroidPlatformsCompat() {} - - public static AndroidPlatformCompat getInstance(Sdk sdk) { - return new AndroidPlatformCompat(AndroidPlatforms.getInstance(sdk)); - } - - public static AndroidPlatformCompat getInstance(Module module) { - return new AndroidPlatformCompat(AndroidPlatforms.getInstance(module)); - } -} diff --git a/aswb/sdkcompat/as231/org/jetbrains/android/sdk/AndroidSdkAdditionalDataCompat.java b/aswb/sdkcompat/as231/org/jetbrains/android/sdk/AndroidSdkAdditionalDataCompat.java deleted file mode 100644 index 6364b6fa8cf..00000000000 --- a/aswb/sdkcompat/as231/org/jetbrains/android/sdk/AndroidSdkAdditionalDataCompat.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright 2023 The Bazel Authors. All rights reserved. - * - * 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. - */ -package org.jetbrains.android.sdk; - -import com.intellij.openapi.projectRoots.Sdk; - -/** Compat shim class for {@link AndroidSdkAdditionalData} */ -public class AndroidSdkAdditionalDataCompat { - private AndroidSdkAdditionalDataCompat() {} - - public static AndroidSdkAdditionalData from(Sdk sdk) { - return AndroidSdkAdditionalData.from(sdk); - } -} diff --git a/aswb/sdkcompat/as231/org/jetbrains/android/sdk/AndroidSdkDataCompat.java b/aswb/sdkcompat/as231/org/jetbrains/android/sdk/AndroidSdkDataCompat.java deleted file mode 100644 index 4aea6d6e832..00000000000 --- a/aswb/sdkcompat/as231/org/jetbrains/android/sdk/AndroidSdkDataCompat.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright 2023 The Bazel Authors. All rights reserved. - * - * 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. - */ -package org.jetbrains.android.sdk; - -import com.android.sdklib.IAndroidTarget; -import com.android.tools.sdk.AndroidSdkData; -import com.google.errorprone.annotations.CanIgnoreReturnValue; -import java.io.File; - -/** Compat class for {@link com.android.tools.sdk.AndroidSdkData} */ -public class AndroidSdkDataCompat { - AndroidSdkData androidSdkData; - - private AndroidSdkDataCompat(File sdkLocation, boolean forceReparse) { - androidSdkData = AndroidSdkData.getSdkData(sdkLocation, forceReparse); - } - - public static AndroidSdkDataCompat getSdkData(String sdkHomepath) { - return new AndroidSdkDataCompat(new File(sdkHomepath), false); - } - - @CanIgnoreReturnValue - public static AndroidSdkDataCompat getSdkData(File sdkLocation, boolean forceReparse) { - return new AndroidSdkDataCompat(sdkLocation, forceReparse); - } - - public IAndroidTarget[] getTargets() { - return androidSdkData.getTargets(); - } -} diff --git a/aswb/sdkcompat/asdev/com/android/tools/idea/model/AndroidManifestIndexCompat.java b/aswb/sdkcompat/asdev/com/android/tools/idea/model/AndroidManifestIndexCompat.java deleted file mode 100644 index 82eb27bee0c..00000000000 --- a/aswb/sdkcompat/asdev/com/android/tools/idea/model/AndroidManifestIndexCompat.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright 2022 The Bazel Authors. All rights reserved. - * - * 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. - */ -package com.android.tools.idea.model; - -/** Compat class for {@link com.android.tools.idea.model.AndroidManifestIndex}. */ -public class AndroidManifestIndexCompat { - - private AndroidManifestIndexCompat() {} - - /** {@code indexEnabled} was removed in Studio 2021.2. #api211 */ - public static boolean indexEnabled() { - return true; - } -} diff --git a/aswb/sdkcompat/asdev/com/android/tools/idea/progress/StudioLoggerProgressIndicatorCompat.java b/aswb/sdkcompat/asdev/com/android/tools/idea/progress/StudioLoggerProgressIndicatorCompat.java deleted file mode 100644 index 7f9654b2ccf..00000000000 --- a/aswb/sdkcompat/asdev/com/android/tools/idea/progress/StudioLoggerProgressIndicatorCompat.java +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright 2022 The Bazel Authors. All rights reserved. - * - * 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. - */ -package com.android.tools.idea.progress; - -/** Compat layer for StudioLoggerProgressIndicator which moved packages in 2021.2. #api211 */ -public class StudioLoggerProgressIndicatorCompat extends StudioLoggerProgressIndicator { - public StudioLoggerProgressIndicatorCompat(Class c) { - super(c); - } -} diff --git a/aswb/sdkcompat/asdev/com/android/tools/idea/run/AndroidSessionInfoCompat.java b/aswb/sdkcompat/asdev/com/android/tools/idea/run/AndroidSessionInfoCompat.java deleted file mode 100644 index 783ad5d39e4..00000000000 --- a/aswb/sdkcompat/asdev/com/android/tools/idea/run/AndroidSessionInfoCompat.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright 2022 The Bazel Authors. All rights reserved. - * - * 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. - */ -package com.android.tools.idea.run; - -import com.android.ddmlib.Client; -import com.android.tools.idea.execution.common.AndroidSessionInfo; -import com.intellij.debugger.engine.RemoteDebugProcessHandler; -import com.intellij.execution.ExecutionTarget; -import com.intellij.execution.configurations.RunConfiguration; -import com.intellij.execution.process.ProcessHandler; -import com.intellij.execution.ui.RunContentDescriptor; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -/** Compat class for AndroidSessionInfo */ -public class AndroidSessionInfoCompat { - - private AndroidSessionInfoCompat() {} - - public static AndroidSessionInfo create( - @NotNull ProcessHandler processHandler, - @NotNull RunContentDescriptor descriptor, - @Nullable RunConfiguration runConfiguration, - @NotNull String executorId, - @NotNull String executorActionName, - @NotNull ExecutionTarget executionTarget) { - return AndroidSessionInfo.create(processHandler, runConfiguration, executorId, executionTarget); - } - - @Nullable - public static RunContentDescriptor getDescriptor(AndroidSessionInfo session) { - return null; - } - - public static void putAndroidDebugClient(RemoteDebugProcessHandler handler, Client client) {} -} diff --git a/aswb/sdkcompat/asdev/com/android/tools/idea/run/ValidationErrorCompat.java b/aswb/sdkcompat/asdev/com/android/tools/idea/run/ValidationErrorCompat.java deleted file mode 100644 index fb233c7eeb8..00000000000 --- a/aswb/sdkcompat/asdev/com/android/tools/idea/run/ValidationErrorCompat.java +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright 2023 The Bazel Authors. All rights reserved. - * - * 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. - */ -package com.android.tools.idea.run; - -/** Compat class for {@link ValidationError} */ -public class ValidationErrorCompat { - private ValidationErrorCompat() {} - - public static ValidationError fatal(String message, Runnable quickFick) { - return ValidationError.fatal(message, (dataContext) -> quickFick.run()); - } -} diff --git a/aswb/sdkcompat/asdev/com/android/tools/idea/run/editor/DeployTargetCompat.java b/aswb/sdkcompat/asdev/com/android/tools/idea/run/editor/DeployTargetCompat.java deleted file mode 100644 index faa6faec6fe..00000000000 --- a/aswb/sdkcompat/asdev/com/android/tools/idea/run/editor/DeployTargetCompat.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright 2022 The Bazel Authors. All rights reserved. - * - * 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. - */ -package com.android.tools.idea.run.editor; - -import com.android.tools.idea.run.DeviceFutures; -import com.intellij.openapi.project.Project; -import org.jetbrains.android.facet.AndroidFacet; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -/** SDK Compat class for {@link DeployTarget#getDevices}. */ -public class DeployTargetCompat { - - private DeployTargetCompat() {} - - @Nullable - public static DeviceFutures getDevices( - DeployTarget target, AndroidFacet facet, @NotNull Project project) { - return target.getDevices(project); - } -} diff --git a/aswb/sdkcompat/asdev/com/android/tools/idea/run/tasks/DeployTasksCompat.java b/aswb/sdkcompat/asdev/com/android/tools/idea/run/tasks/DeployTasksCompat.java deleted file mode 100644 index 500a6786340..00000000000 --- a/aswb/sdkcompat/asdev/com/android/tools/idea/run/tasks/DeployTasksCompat.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2020 The Bazel Authors. All rights reserved. - * - * 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. - */ -package com.android.tools.idea.run.tasks; - -import com.android.tools.idea.run.ApkInfo; -import com.android.tools.idea.run.LaunchOptions; -import com.android.tools.idea.run.blaze.BlazeLaunchTask; -import com.android.tools.idea.run.blaze.BlazeLaunchTaskWrapper; -import com.google.idea.common.experiments.BoolExperiment; -import com.intellij.openapi.project.Project; -import java.util.Collection; - -/** Compat class for {@link DeployTask} */ -public class DeployTasksCompat { - private static final BoolExperiment updateCodeViaJvmti = - new BoolExperiment("android.apply.changes", false); - - private DeployTasksCompat() {} - - public static BlazeLaunchTask createDeployTask( - Project project, Collection packages, LaunchOptions launchOptions) { - // We don't have a device information, fallback to the most conservative - // install option. - return new BlazeLaunchTaskWrapper( - new DeployTask( - project, - packages, - launchOptions.getPmInstallOptions(/* device= */ null), - launchOptions.getInstallOnAllUsers(), - launchOptions.getAlwaysInstallWithPm())); - } -} - diff --git a/aswb/sdkcompat/asdev/com/android/tools/rendering/HtmlLinkManagerCompat.java b/aswb/sdkcompat/asdev/com/android/tools/rendering/HtmlLinkManagerCompat.java deleted file mode 100644 index 594132f69af..00000000000 --- a/aswb/sdkcompat/asdev/com/android/tools/rendering/HtmlLinkManagerCompat.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright 2023 The Bazel Authors. All rights reserved. - * - * 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. - */ -package com.android.tools.rendering; - -import com.android.tools.idea.rendering.HtmlLinkManager; -import java.io.File; -import org.jetbrains.annotations.NotNull; - -/** Compat class for {@link HtmlLinkManager} */ -public final class HtmlLinkManagerCompat { - public static String createFilePositionUrl(@NotNull File file, int line, int column) { - return HtmlLinkManager.createFilePositionUrl(file, line, column); - } - - private HtmlLinkManagerCompat() {} -} diff --git a/aswb/sdkcompat/asdev/com/google/idea/blaze/android/cppimpl/debug/BlazeAutoAndroidDebugger.java b/aswb/sdkcompat/asdev/com/google/idea/blaze/android/cppimpl/debug/BlazeAutoAndroidDebugger.java deleted file mode 100644 index 167fd4433a9..00000000000 --- a/aswb/sdkcompat/asdev/com/google/idea/blaze/android/cppimpl/debug/BlazeAutoAndroidDebugger.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright 2016 The Bazel Authors. All rights reserved. - * - * 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. - */ -package com.google.idea.blaze.android.cppimpl.debug; - -import com.android.ddmlib.Client; -import com.android.tools.ndk.run.editor.AutoAndroidDebuggerState; -import com.intellij.execution.ExecutionException; -import com.intellij.openapi.project.Project; -import com.intellij.xdebugger.XDebugSession; - -/** Shim for #api212 compat. */ -public class BlazeAutoAndroidDebugger extends BlazeAutoAndroidDebuggerBase { - @Override - public XDebugSession attachToClient( - Project project, Client client, AutoAndroidDebuggerState state) throws ExecutionException { - if (isNativeProject(project)) { - log.info("Project has native development enabled. Attaching native debugger."); - return nativeDebugger.attachToClient(project, client, state); - } else { - return super.attachToClient(project, client, state); - } - } -} diff --git a/aswb/sdkcompat/asdev/com/google/idea/blaze/android/cppimpl/debug/BlazeNativeAndroidDebugger.java b/aswb/sdkcompat/asdev/com/google/idea/blaze/android/cppimpl/debug/BlazeNativeAndroidDebugger.java deleted file mode 100644 index e92afddc27c..00000000000 --- a/aswb/sdkcompat/asdev/com/google/idea/blaze/android/cppimpl/debug/BlazeNativeAndroidDebugger.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright 2018 The Bazel Authors. All rights reserved. - * - * 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. - */ -package com.google.idea.blaze.android.cppimpl.debug; - -/** - * API compat of {@link BlazeNativeAndroidDebuggerBase} with the following additions: - * - *

    - *
  • Creates a run-config setting using {@link BlazeAndroidNativeAttachConfiguration} instead of - * {@link AndroidNativeAttachConfiguration} to override counterproductive validations. - *
- * - * #api4.0 - */ -public class BlazeNativeAndroidDebugger extends BlazeNativeAndroidDebuggerBase {} diff --git a/aswb/sdkcompat/asdev/com/google/idea/blaze/android/cppimpl/debug/BlazeNativeAndroidDebuggerBase.java b/aswb/sdkcompat/asdev/com/google/idea/blaze/android/cppimpl/debug/BlazeNativeAndroidDebuggerBase.java deleted file mode 100644 index 911d90b7711..00000000000 --- a/aswb/sdkcompat/asdev/com/google/idea/blaze/android/cppimpl/debug/BlazeNativeAndroidDebuggerBase.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright 2020 The Bazel Authors. All rights reserved. - * - * 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. - */ -package com.google.idea.blaze.android.cppimpl.debug; - -import com.android.tools.ndk.run.editor.NativeAndroidDebugger; -import com.google.idea.blaze.base.model.BlazeProjectData; -import com.google.idea.blaze.base.model.primitives.LanguageClass; -import com.google.idea.blaze.base.settings.Blaze; -import com.google.idea.blaze.base.sync.data.BlazeProjectDataManager; -import com.intellij.openapi.project.Project; - -/** - * Extension of {@link NativeAndroidDebugger} with the following key differences compared to {@link - * NativeAndroidDebugger}. - * - *
    - *
  • Overrides {@link #supportsProject} so native debugger is only enabled for native support is - * enabled. - *
- */ -public class BlazeNativeAndroidDebuggerBase extends NativeAndroidDebugger { - /** - * This ID needs to be lexicographically larger than "Java" so it come after the "Java" debugger - * when sorted lexicographically in the "Attach Debugger to Android Process" dialog. See {@link - * org.jetbrains.android.actions.AndroidProcessChooserDialog#populateDebuggerTypeCombo}. - */ - public static final String ID = "Native" + Blaze.defaultBuildSystemName(); - - @Override - public String getId() { - return ID; - } - - @Override - public String getDisplayName() { - return "Native Only"; - } - - @Override - public boolean supportsProject(Project project) { - BlazeProjectData blazeProjectData = - BlazeProjectDataManager.getInstance(project).getBlazeProjectData(); - return blazeProjectData != null - && blazeProjectData.getWorkspaceLanguageSettings().isLanguageActive(LanguageClass.C); - } -} diff --git a/aswb/sdkcompat/asdev/com/google/idea/blaze/android/npw/project/BlazeAndroidModuleTemplate.java b/aswb/sdkcompat/asdev/com/google/idea/blaze/android/npw/project/BlazeAndroidModuleTemplate.java deleted file mode 100644 index 8d3b76b90e3..00000000000 --- a/aswb/sdkcompat/asdev/com/google/idea/blaze/android/npw/project/BlazeAndroidModuleTemplate.java +++ /dev/null @@ -1,184 +0,0 @@ -/* - * Copyright 2017 The Bazel Authors. All rights reserved. - * - * 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. - */ -package com.google.idea.blaze.android.npw.project; - -import com.android.tools.idea.projectsystem.AndroidModulePaths; -import com.android.tools.idea.projectsystem.IdeaSourceProvider; -import com.android.tools.idea.projectsystem.NamedModuleTemplate; -import com.android.tools.idea.projectsystem.SourceProviderManager; -import com.google.common.collect.Streams; -import com.intellij.openapi.module.Module; -import com.intellij.openapi.project.Project; -import com.intellij.openapi.roots.ModuleRootManager; -import com.intellij.openapi.vfs.VfsUtilCore; -import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.psi.JavaDirectoryService; -import com.intellij.psi.PsiDirectory; -import com.intellij.psi.PsiManager; -import com.intellij.psi.PsiPackage; -import java.io.File; -import java.util.Collections; -import java.util.List; -import java.util.stream.Collectors; -import javax.annotation.Nullable; -import org.jetbrains.android.facet.AndroidFacet; - -/** - * Project paths for a Blaze Android project. - * - *

We mostly just take whatever directory the user specified and put the new component there. - * Unlike Gradle, Blaze has no strict requirements regarding the structure of an Android project, - * but there are some common conventions: - * - *

- * google3/
- * |-java/com/google/foo/bar/... (module root)
- * | |-BUILD
- * | |-AndroidManifest.xml (manifest directory)
- * | |-Baz.java (source directory of com.google.foo.bar.Baz)
- * | |-Baz.aidl (aidl directory, option 1)
- * | |-aidl/
- * | | `-com/google/foo/bar/Baz.aidl (aidl directory, option 2)
- * | `-res/... (res directory, one of the few things required by the build system)
- * `-javatest/com/google/foo/bar/...
- *   |-BUILD
- *   `-BazTest.java (test directory of com.google.foo.bar.BazTest)
- * 
- * - * However, this is also possible (package name unrelated to directory structure): - * - *
- * google3/experimental/users/foo/my/own/project/
- * |-Baz.java (com.google.foo.bar.Baz)
- * `-BazTest.java (com.google.foo.bar.BazTest)
- * 
- * - * So is this (versioned paths that aren't reflected by the package name): - * - *
- * google3/third_party/com/google/foo/bar/
- * |-v1/Baz.java (com.google.foo.bar.Baz)
- * `-v2/Baz.java (com.google.foo.bar.Baz)
- * 
- */ -public class BlazeAndroidModuleTemplate implements AndroidModulePaths { - @Nullable private File moduleRoot; - @Nullable private File srcDirectory; - private List resDirectories = Collections.emptyList(); - - @Nullable - @Override - public File getModuleRoot() { - return moduleRoot; - } - - @Nullable - @Override - public File getSrcDirectory(@Nullable String packageName) { - return srcDirectory; - } - - @Nullable - @Override - public File getTestDirectory(@Nullable String packageName) { - return srcDirectory; - } - - @Nullable - @Override - public File getUnitTestDirectory(@Nullable String packageName) { - return srcDirectory; - } - - @Override - public List getResDirectories() { - return resDirectories; - } - - @Nullable - @Override - public File getAidlDirectory(@Nullable String packageName) { - return srcDirectory; - } - - @Nullable - @Override - public File getManifestDirectory() { - return srcDirectory; - } - /** - * The new component wizard uses {@link NamedModuleTemplate#getName()} for the default package - * name of the new component. If we can figure it out from the target directory here, then we can - * pass it to the new component wizard. - */ - private static String getPackageName(Project project, VirtualFile targetDirectory) { - PsiDirectory psiDirectory = PsiManager.getInstance(project).findDirectory(targetDirectory); - if (psiDirectory == null) { - return null; - } - PsiPackage psiPackage = JavaDirectoryService.getInstance().getPackage(psiDirectory); - if (psiPackage == null) { - return null; - } - return psiPackage.getQualifiedName(); - } - - public static List getTemplates( - Module module, @Nullable VirtualFile targetDirectory) { - AndroidFacet androidFacet = AndroidFacet.getInstance(module); - if (androidFacet == null) { - return Collections.emptyList(); - } - return getTemplates(androidFacet, targetDirectory); - } - - public static List getTemplates( - AndroidFacet androidFacet, @Nullable VirtualFile targetDirectory) { - Module module = androidFacet.getModule(); - BlazeAndroidModuleTemplate paths = new BlazeAndroidModuleTemplate(); - VirtualFile[] roots = ModuleRootManager.getInstance(module).getContentRoots(); - if (roots.length > 0) { - paths.moduleRoot = VfsUtilCore.virtualToIoFile(roots[0]); - } - IdeaSourceProvider sourceProvider = - SourceProviderManager.getInstance(androidFacet).getSources(); - // If this happens to be a resource package, - // the module name (resource package) would be more descriptive than the facet name (Android). - // Otherwise, .workspace is still better than (Android). - String name = androidFacet.getModule().getName(); - if (targetDirectory != null) { - String packageName = getPackageName(module.getProject(), targetDirectory); - if (packageName != null) { - name = packageName; - } - paths.srcDirectory = VfsUtilCore.virtualToIoFile(targetDirectory); - } else { - // People usually put the manifest file with their sources. - //noinspection OptionalGetWithoutIsPresent - paths.srcDirectory = - Streams.stream(sourceProvider.getManifestDirectoryUrls()) - .map(it -> new File(VfsUtilCore.urlToPath(it))) - .findFirst() - .get(); - } - // We have a res dir if this happens to be a resource module. - paths.resDirectories = - Streams.stream(sourceProvider.getResDirectoryUrls()) - .map(it -> new File(VfsUtilCore.urlToPath(it))) - .collect(Collectors.toList()); - return Collections.singletonList(new NamedModuleTemplate(name, paths)); - } -} diff --git a/aswb/sdkcompat/asdev/com/google/idea/blaze/android/projectsystem/BlazeProjectSystem.java b/aswb/sdkcompat/asdev/com/google/idea/blaze/android/projectsystem/BlazeProjectSystem.java deleted file mode 100755 index b5b20a1b2a7..00000000000 --- a/aswb/sdkcompat/asdev/com/google/idea/blaze/android/projectsystem/BlazeProjectSystem.java +++ /dev/null @@ -1,228 +0,0 @@ -/* - * Copyright 2017 The Bazel Authors. All rights reserved. - * - * 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. - */ -package com.google.idea.blaze.android.projectsystem; - -import static com.android.tools.idea.projectsystem.SourceProvidersKt.emptySourceProvider; -import static org.jetbrains.android.facet.SourceProviderUtil.createSourceProvidersForLegacyModule; - -import com.android.tools.apk.analyzer.AaptInvoker; -import com.android.tools.idea.log.LogWrapper; -import com.android.tools.idea.model.AndroidModel; -import com.android.tools.idea.model.ClassJarProvider; -import com.android.tools.idea.projectsystem.AndroidModuleSystem; -import com.android.tools.idea.projectsystem.AndroidProjectSystem; -import com.android.tools.idea.projectsystem.NamedIdeaSourceProvider; -import com.android.tools.idea.projectsystem.ProjectSystemBuildManager; -import com.android.tools.idea.projectsystem.ProjectSystemSyncManager; -import com.android.tools.idea.projectsystem.ScopeType; -import com.android.tools.idea.projectsystem.SourceProviderManager; -import com.android.tools.idea.projectsystem.SourceProviders; -import com.android.tools.idea.projectsystem.SourceProvidersFactory; -import com.android.tools.idea.projectsystem.SourceProvidersImpl; -import com.android.tools.idea.res.AndroidInnerClassFinder; -import com.android.tools.idea.res.AndroidResourceClassPsiElementFinder; -import com.android.tools.idea.sdk.AndroidSdks; -import com.google.common.collect.ImmutableList; -import com.google.idea.blaze.android.resources.BlazeLightResourceClassService; -import com.google.idea.blaze.android.sync.model.idea.BlazeAndroidModel; -import com.google.idea.blaze.android.sync.model.idea.BlazeClassJarProvider; -import com.google.idea.blaze.base.build.BlazeBuildService; -import com.google.idea.blaze.base.qsync.QuerySync; -import com.intellij.facet.ProjectFacetManager; -import com.intellij.openapi.module.Module; -import com.intellij.openapi.project.Project; -import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.psi.PsiElementFinder; -import com.intellij.psi.search.GlobalSearchScope; -import java.io.File; -import java.nio.file.Path; -import java.util.Arrays; -import java.util.Collection; -import java.util.List; -import java.util.stream.Collectors; -import javax.annotation.Nullable; -import org.jetbrains.android.facet.AndroidFacet; -import org.jetbrains.annotations.NotNull; - -/** - * Base class to implement common methods in {@link AndroidProjectSystem} for blaze with different - * sdk - */ -public class BlazeProjectSystem implements AndroidProjectSystem { - protected final Project project; - protected final ProjectSystemSyncManager syncManager; - protected final List myFinders; - private final BlazeProjectSystemBuildManager buildManager; - - public BlazeProjectSystem(Project project) { - this.project = project; - syncManager = new BlazeProjectSystemSyncManager(project); - buildManager = new BlazeProjectSystemBuildManager(project); - - myFinders = - Arrays.asList( - AndroidInnerClassFinder.INSTANCE, - new AndroidResourceClassPsiElementFinder(getLightResourceClassService())); - } - - @Override - public boolean allowsFileCreation() { - return true; - } - - @Nullable - @Override - public VirtualFile getDefaultApkFile() { - return null; - } - - @Override - public Path getPathToAapt() { - return AaptInvoker.getPathToAapt( - AndroidSdks.getInstance().tryToChooseSdkHandler(), - new LogWrapper(BlazeProjectSystem.class)); - } - - // @Override #api42 - public void buildProject() { - BlazeBuildService.getInstance(project).buildProject(); - } - - // @Override #api42 - public ProjectSystemBuildManager getBuildManager() { - return buildManager; - } - - @Override - public AndroidModuleSystem getModuleSystem(Module module) { - return BlazeModuleSystem.getInstance(module); - } - - @Override - public ProjectSystemSyncManager getSyncManager() { - return syncManager; - } - - @Override - public Collection getPsiElementFinders() { - return myFinders; - } - - @Override - public BlazeLightResourceClassService getLightResourceClassService() { - return BlazeLightResourceClassService.getInstance(project); - } - - @Override - public SourceProvidersFactory getSourceProvidersFactory() { - return new SourceProvidersFactory() { - @Override - public SourceProviders createSourceProvidersFor(AndroidFacet facet) { - BlazeAndroidModel model = ((BlazeAndroidModel) AndroidModel.get(facet)); - if (model != null) { - return createForModel(model); - } else { - return createSourceProvidersForLegacyModule(facet); - } - } - - private SourceProviders createForModel(BlazeAndroidModel model) { - NamedIdeaSourceProvider mainSourceProvider = model.getDefaultSourceProvider(); - if (QuerySync.isEnabled()) { - return new SourceProvidersImpl( - mainSourceProvider, - ImmutableList.of(mainSourceProvider), - ImmutableList.of(), - ImmutableList.of(), - ImmutableList.of(), - ImmutableList.of(mainSourceProvider), - ImmutableList.of(mainSourceProvider), - emptySourceProvider(ScopeType.MAIN), - emptySourceProvider(ScopeType.UNIT_TEST), - emptySourceProvider(ScopeType.ANDROID_TEST), - emptySourceProvider(ScopeType.TEST_FIXTURES)); - } else { - return new SourceProvidersImpl( - mainSourceProvider, - ImmutableList.of(mainSourceProvider), - ImmutableList.of(mainSourceProvider), - ImmutableList.of(mainSourceProvider), - ImmutableList.of(mainSourceProvider), - ImmutableList.of(mainSourceProvider), - ImmutableList.of(mainSourceProvider), - emptySourceProvider(ScopeType.MAIN), - emptySourceProvider(ScopeType.UNIT_TEST), - emptySourceProvider(ScopeType.ANDROID_TEST), - emptySourceProvider(ScopeType.TEST_FIXTURES)); - } - } - }; - } - - // @Override #api212 - public ClassJarProvider getClassJarProvider() { - return new BlazeClassJarProvider(project); - } - - @Override - public Collection getAndroidFacetsWithPackageName( - Project project, String packageName) { - return getAndroidFacetsWithPackageName( - project, packageName, GlobalSearchScope.projectScope(project)); - } - - private Collection getAndroidFacetsWithPackageName( - Project project, String packageName, GlobalSearchScope scope) { - List facets = ProjectFacetManager.getInstance(project).getFacets(AndroidFacet.ID); - return facets.stream() - .filter(facet -> hasPackageName(facet, packageName)) - .filter( - facet -> { - VirtualFile file = SourceProviderManager.getInstance(facet).getMainManifestFile(); - if (file == null) { - return false; - } else { - return scope.contains(file); - } - }) - .collect(Collectors.toList()); - } - - @Override - public Collection getSubmodules() { - return ImmutableList.of(); - } - - @Override - public Collection getBootClasspath(@NotNull Module module) { - // TODO: b/266586669 - return ImmutableList.of(); - } - - private static boolean hasPackageName(AndroidFacet facet, String packageName) { - String nameFromFacet = PackageNameUtils.getPackageName(facet.getModule()); - if (nameFromFacet == null) { - return false; - } - return nameFromFacet.equals(packageName); - } - - @NotNull - // @Override #api223 - public List desugarLibraryConfigFiles(@NotNull Project project) { - return ImmutableList.of(); - } -} diff --git a/aswb/sdkcompat/asdev/com/google/idea/blaze/android/projectsystem/PackageNameUtils.java b/aswb/sdkcompat/asdev/com/google/idea/blaze/android/projectsystem/PackageNameUtils.java deleted file mode 100644 index 83a7fcd9b20..00000000000 --- a/aswb/sdkcompat/asdev/com/google/idea/blaze/android/projectsystem/PackageNameUtils.java +++ /dev/null @@ -1,139 +0,0 @@ -/* - * Copyright 2018 The Bazel Authors. All rights reserved. - * - * 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. - */ -package com.google.idea.blaze.android.projectsystem; - -import com.android.manifmerger.ManifestSystemProperty; -import com.android.tools.idea.model.AndroidManifestIndex; -import com.android.tools.idea.model.AndroidManifestIndexCompat; -import com.android.tools.idea.model.AndroidManifestRawText; -import com.android.tools.idea.model.MergedManifestModificationTracker; -import com.android.tools.idea.projectsystem.ManifestOverrides; -import com.android.tools.idea.projectsystem.SourceProviderManager; -import com.google.common.annotations.VisibleForTesting; -import com.google.idea.common.experiments.BoolExperiment; -import com.intellij.openapi.module.Module; -import com.intellij.openapi.project.DumbService; -import com.intellij.openapi.project.IndexNotReadyException; -import com.intellij.openapi.project.Project; -import com.intellij.openapi.util.text.StringUtil; -import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.psi.util.CachedValueProvider; -import com.intellij.psi.util.CachedValuesManager; -import org.jetbrains.android.dom.manifest.AndroidManifestUtils; -import org.jetbrains.android.dom.manifest.AndroidManifestXmlFile; -import org.jetbrains.android.facet.AndroidFacet; -import org.jetbrains.annotations.Nullable; - -/** Utilities to obtain the package name for a given module. */ -public class PackageNameUtils { - /** - * Determines whether we use the {@link AndroidManifestIndex} to obtain the raw text package name - * from a module's primary manifest. Note that we still won't use the index if {@link - * AndroidManifestIndex#indexEnabled()} returns false. - * - * @see PackageNameUtils#getPackageName(Module) - * @see PackageNameUtils#doGetPackageName(AndroidFacet, boolean) - */ - private static final BoolExperiment USE_ANDROID_MANIFEST_INDEX = - new BoolExperiment("use.android.manifest.index", true); - - @Nullable - public static String getPackageName(Module module) { - AndroidFacet facet = AndroidFacet.getInstance(module); - assert facet != null; - return CachedValuesManager.getManager(module.getProject()) - .getCachedValue( - facet, - () -> { - boolean useIndex = - AndroidManifestIndexCompat.indexEnabled() - && USE_ANDROID_MANIFEST_INDEX.getValue(); - String packageName = doGetPackageName(facet, useIndex); - return CachedValueProvider.Result.create( - StringUtil.nullize(packageName, true), - MergedManifestModificationTracker.getInstance(module)); - }); - } - - /** - * Returns the package name from an Android module's merged manifest without actually computing - * the whole merged manifest. This is either - * - *
    - *
  1. The {@link ManifestSystemProperty#PACKAGE} manifest override if one is specified by the - * corresponding BUILD target, or - *
  2. The result of applying placeholder substitution to the raw package name from the module's - * primary manifest - *
- * - * In the second case, we try to obtain the raw package name using the {@link - * AndroidManifestIndex} if {@code useIndex} is true. If {@code useIndex} is false or querying the - * index fails for some reason (e.g. this method is called in a read action but not a *smart* read - * action), then we resort to parsing the PSI of the module's primary manifest to get the raw - * package name. - * - * @see AndroidModuleSystem#getManifestOverrides() - * @see AndroidModuleSystem#getPackageName() - */ - @Nullable - @VisibleForTesting - static String doGetPackageName(AndroidFacet facet, boolean useIndex) { - ManifestOverrides manifestOverrides = - BlazeModuleSystem.getInstance(facet.getModule()).getManifestOverrides(); - String packageOverride = - ManifestValueProcessor.getPackageOverride(manifestOverrides.getDirectOverrides()); - if (packageOverride != null) { - return packageOverride; - } - String rawPackageName = null; - if (useIndex) { - rawPackageName = getRawPackageNameFromIndex(facet); - } - if (rawPackageName == null) { - rawPackageName = getRawPackageNameFromPsi(facet); - } - return rawPackageName == null ? null : manifestOverrides.resolvePlaceholders(rawPackageName); - } - - @Nullable - private static String getRawPackageNameFromIndex(AndroidFacet facet) { - VirtualFile primaryManifest = SourceProviderManager.getInstance(facet).getMainManifestFile(); - if (primaryManifest == null) { - return null; - } - Project project = facet.getModule().getProject(); - try { - AndroidManifestRawText manifestRawText = - DumbService.getInstance(project) - .runReadActionInSmartMode( - () -> AndroidManifestIndex.getDataForManifestFile(project, primaryManifest)); - return manifestRawText == null ? null : manifestRawText.getPackageName(); - } catch (IndexNotReadyException e) { - // TODO(142681129): runReadActionInSmartMode doesn't work if we already have read access. - // We need to refactor the callers of AndroidManifestUtils#getPackage to require a *smart* - // read action, at which point we can remove this try-catch. - return null; - } - } - - @Nullable - private static String getRawPackageNameFromPsi(AndroidFacet facet) { - AndroidManifestXmlFile primaryManifest = AndroidManifestUtils.getPrimaryManifestXml(facet); - return primaryManifest == null ? null : primaryManifest.getPackageName(); - } - - private PackageNameUtils() {} -} diff --git a/aswb/sdkcompat/asdev/com/google/idea/blaze/android/resources/BlazeRClass.java b/aswb/sdkcompat/asdev/com/google/idea/blaze/android/resources/BlazeRClass.java deleted file mode 100644 index 5a8cbf8e450..00000000000 --- a/aswb/sdkcompat/asdev/com/google/idea/blaze/android/resources/BlazeRClass.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright 2018 The Bazel Authors. All rights reserved. - * - * 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. - */ -package com.google.idea.blaze.android.resources; - -import static org.jetbrains.android.AndroidResolveScopeEnlarger.LIGHT_CLASS_KEY; -import static org.jetbrains.android.AndroidResolveScopeEnlarger.MODULE_POINTER_KEY; - -import com.android.ide.common.rendering.api.ResourceNamespace; -import com.android.tools.idea.res.LocalResourceRepository; -import com.android.tools.idea.res.ResourceRepositoryRClass; -import com.android.tools.idea.res.StudioResourceRepositoryManager; -import com.intellij.openapi.module.Module; -import com.intellij.openapi.module.ModulePointerManager; -import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.psi.PsiManager; -import org.jetbrains.android.augment.AndroidLightField; -import org.jetbrains.android.facet.AndroidFacet; - -/** Blaze implementation of an R class based on resource repositories. */ -public class BlazeRClass extends ResourceRepositoryRClass { - - private final AndroidFacet androidFacet; - - public BlazeRClass(PsiManager psiManager, AndroidFacet androidFacet, String packageName) { - super( - psiManager, - new ResourcesSource() { - @Override - public String getPackageName() { - return packageName; - } - - @Override - public Transitivity getTransitivity() { - return Transitivity.TRANSITIVE; - } - - @Override - public StudioResourceRepositoryManager getResourceRepositoryManager() { - return StudioResourceRepositoryManager.getInstance(androidFacet); - } - - @Override - public LocalResourceRepository getResourceRepository() { - return StudioResourceRepositoryManager.getAppResources(androidFacet); - } - - @Override - public ResourceNamespace getResourceNamespace() { - return ResourceNamespace.RES_AUTO; - } - - @Override - public AndroidLightField.FieldModifier getFieldModifier() { - return AndroidLightField.FieldModifier.NON_FINAL; - } - }); - this.androidFacet = androidFacet; - setModuleInfo(getModule(), false); - VirtualFile virtualFile = myFile.getViewProvider().getVirtualFile(); - virtualFile.putUserData( - MODULE_POINTER_KEY, ModulePointerManager.getInstance(getProject()).create(getModule())); - virtualFile.putUserData(LIGHT_CLASS_KEY, ResourceRepositoryRClass.class); - } - - public Module getModule() { - return androidFacet.getModule(); - } -} diff --git a/aswb/sdkcompat/asdev/com/google/idea/blaze/android/run/BlazeAndroidDeploymentService.java b/aswb/sdkcompat/asdev/com/google/idea/blaze/android/run/BlazeAndroidDeploymentService.java deleted file mode 100644 index 6cc3a63459e..00000000000 --- a/aswb/sdkcompat/asdev/com/google/idea/blaze/android/run/BlazeAndroidDeploymentService.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright 2020 The Bazel Authors. All rights reserved. - * - * 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. - */ -package com.google.idea.blaze.android.run; - -import com.android.tools.idea.run.ApkInfo; -import com.android.tools.idea.run.LaunchOptions; -import com.android.tools.idea.run.blaze.BlazeLaunchTask; -import com.android.tools.idea.run.tasks.DeployTask; -import com.android.tools.idea.run.tasks.DeployTasksCompat; -import com.intellij.openapi.project.Project; -import java.util.Collection; - -/** A service that provides {@link DeployTask}. */ -public interface BlazeAndroidDeploymentService { - static BlazeAndroidDeploymentService getInstance(Project project) { - return project.getService(BlazeAndroidDeploymentService.class); - } - - /** Returns a {@link DeployTask} to deploy the given files and launch options. */ - BlazeLaunchTask getDeployTask(Collection packages, LaunchOptions launchOptions); - - /** A default implementation that uses {@link DeployTasksCompat#createDeployTask}. */ - class DefaultDeploymentService implements BlazeAndroidDeploymentService { - private final Project project; - - public DefaultDeploymentService(Project project) { - this.project = project; - } - - @Override - public BlazeLaunchTask getDeployTask( - Collection packages, LaunchOptions launchOptions) { - return DeployTasksCompat.createDeployTask(project, packages, launchOptions); - } - } -} diff --git a/aswb/sdkcompat/asdev/com/google/idea/blaze/android/run/BlazeCommandAndroidDebuggerInfoProvider.java b/aswb/sdkcompat/asdev/com/google/idea/blaze/android/run/BlazeCommandAndroidDebuggerInfoProvider.java deleted file mode 100644 index 03dd9f80da7..00000000000 --- a/aswb/sdkcompat/asdev/com/google/idea/blaze/android/run/BlazeCommandAndroidDebuggerInfoProvider.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright (C) 2020 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. - */ -package com.google.idea.blaze.android.run; - -import com.android.tools.idea.execution.common.debug.AndroidDebugger; -import com.android.tools.idea.execution.common.debug.AndroidDebuggerState; -import com.android.tools.idea.execution.common.debug.impl.java.AndroidJavaDebugger; -import com.android.tools.idea.run.editor.AndroidDebuggerInfoProvider; -import com.google.idea.blaze.android.cppimpl.debug.BlazeNativeAndroidDebugger; -import com.google.idea.blaze.android.run.binary.BlazeAndroidBinaryRunConfigurationState; -import com.google.idea.blaze.android.run.test.BlazeAndroidTestRunConfigurationState; -import com.google.idea.blaze.base.model.BlazeProjectData; -import com.google.idea.blaze.base.run.BlazeCommandRunConfiguration; -import com.google.idea.blaze.base.sync.data.BlazeProjectDataManager; -import com.intellij.execution.configurations.RunConfiguration; -import com.intellij.openapi.project.Project; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import org.jetbrains.annotations.Nullable; - -/** Provider of blaze project compatible android debuggers. */ -public class BlazeCommandAndroidDebuggerInfoProvider implements AndroidDebuggerInfoProvider { - @Override - public boolean supportsProject(Project project) { - BlazeProjectData blazeProjectData = - BlazeProjectDataManager.getInstance(project).getBlazeProjectData(); - return blazeProjectData != null; - } - - @Override - @SuppressWarnings("rawtypes") // List includes multiple AndroidDebuggerState types. - public List getAndroidDebuggers(RunConfiguration configuration) { - if (getCommonState(configuration) != null) { - return Arrays.asList(new BlazeNativeAndroidDebugger(), new AndroidJavaDebugger()); - } - return Collections.emptyList(); - } - - @Nullable - @Override - public AndroidDebugger getSelectedAndroidDebugger( - RunConfiguration configuration) { - // b/170159822 Always return java debugger because BlazeAutoAndroidDebugger doesn't work and - // users likely want the java debugger not the native debugger. - return new AndroidJavaDebugger(); - } - - @Nullable - @Override - public AndroidDebuggerState getSelectedAndroidDebuggerState(RunConfiguration configuration) { - AndroidDebugger debugger = getSelectedAndroidDebugger(configuration); - if (debugger == null) { - return null; - } - return debugger.createState(); - } - - @Nullable - private BlazeAndroidRunConfigurationCommonState getCommonState(RunConfiguration configuration) { - if (!(configuration instanceof BlazeCommandRunConfiguration)) { - return null; - } - BlazeCommandRunConfiguration blazeRunConfig = (BlazeCommandRunConfiguration) configuration; - BlazeAndroidBinaryRunConfigurationState binaryState = - blazeRunConfig.getHandlerStateIfType(BlazeAndroidBinaryRunConfigurationState.class); - if (binaryState != null) { - return binaryState.getCommonState(); - } - BlazeAndroidTestRunConfigurationState testState = - blazeRunConfig.getHandlerStateIfType(BlazeAndroidTestRunConfigurationState.class); - if (testState != null) { - return testState.getCommonState(); - } - return null; - } -} diff --git a/aswb/sdkcompat/asdev/com/google/idea/blaze/android/run/binary/BlazeAndroidBinaryApplicationLaunchTaskProvider.java b/aswb/sdkcompat/asdev/com/google/idea/blaze/android/run/binary/BlazeAndroidBinaryApplicationLaunchTaskProvider.java deleted file mode 100644 index 8a74f3d458f..00000000000 --- a/aswb/sdkcompat/asdev/com/google/idea/blaze/android/run/binary/BlazeAndroidBinaryApplicationLaunchTaskProvider.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright 2016 The Bazel Authors. All rights reserved. - * - * 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. - */ -package com.google.idea.blaze.android.run.binary; - -import com.android.tools.idea.run.ApkProvisionException; -import com.android.tools.idea.run.ApplicationIdProvider; -import com.android.tools.idea.run.activity.StartActivityFlagsProvider; -import com.android.tools.idea.run.blaze.BlazeLaunchTask; -import com.android.tools.idea.run.blaze.BlazeLaunchTaskWrapper; -import com.android.tools.idea.run.tasks.AndroidDeepLinkLaunchTask; -import com.android.tools.idea.run.tasks.DefaultActivityLaunchTask; -import com.android.tools.idea.run.tasks.SpecificActivityLaunchTask; -import com.google.idea.blaze.android.manifest.ManifestParser; -import com.intellij.execution.ExecutionException; -import com.intellij.openapi.diagnostic.Logger; - -/** Provides the launch task for android_binary */ -public class BlazeAndroidBinaryApplicationLaunchTaskProvider { - private static final Logger LOG = - Logger.getInstance(BlazeAndroidBinaryApplicationLaunchTaskProvider.class); - - public static BlazeLaunchTask getApplicationLaunchTask( - ApplicationIdProvider applicationIdProvider, - ManifestParser.ParsedManifest mergedManifestParsedManifest, - BlazeAndroidBinaryRunConfigurationState configState, - StartActivityFlagsProvider startActivityFlagsProvider) - throws ExecutionException { - try { - String applicationId = applicationIdProvider.getPackageName(); - - switch (configState.getMode()) { - case BlazeAndroidBinaryRunConfigurationState.LAUNCH_DEFAULT_ACTIVITY: - BlazeDefaultActivityLocator activityLocator = - new BlazeDefaultActivityLocator(mergedManifestParsedManifest); - return new BlazeLaunchTaskWrapper( - new DefaultActivityLaunchTask( - applicationId, activityLocator, startActivityFlagsProvider)); - case BlazeAndroidBinaryRunConfigurationState.LAUNCH_SPECIFIC_ACTIVITY: - return new BlazeLaunchTaskWrapper( - new SpecificActivityLaunchTask( - applicationId, configState.getActivityClass(), startActivityFlagsProvider)); - case BlazeAndroidBinaryRunConfigurationState.LAUNCH_DEEP_LINK: - return new BlazeLaunchTaskWrapper( - new AndroidDeepLinkLaunchTask(configState.getDeepLink(), startActivityFlagsProvider)); - case BlazeAndroidBinaryRunConfigurationState.DO_NOTHING: - default: - return null; - } - } catch (ApkProvisionException e) { - throw new ExecutionException("Unable to identify application id"); - } - } -} diff --git a/aswb/sdkcompat/asdev/com/google/idea/blaze/android/run/binary/BlazeAndroidBinaryNormalBuildRunContext.java b/aswb/sdkcompat/asdev/com/google/idea/blaze/android/run/binary/BlazeAndroidBinaryNormalBuildRunContext.java deleted file mode 100644 index 6b2d10e2dac..00000000000 --- a/aswb/sdkcompat/asdev/com/google/idea/blaze/android/run/binary/BlazeAndroidBinaryNormalBuildRunContext.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright 2019 The Bazel Authors. All rights reserved. - * - * 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. - */ -package com.google.idea.blaze.android.run.binary; - -import static com.android.tools.idea.run.tasks.DefaultConnectDebuggerTaskKt.getBaseDebuggerTask; - -import com.android.tools.idea.execution.common.debug.AndroidDebugger; -import com.android.tools.idea.execution.common.debug.AndroidDebuggerState; -import com.android.tools.idea.run.ApkProvisionException; -import com.android.tools.idea.run.LaunchOptions; -import com.android.tools.idea.run.activity.DefaultStartActivityFlagsProvider; -import com.android.tools.idea.run.activity.StartActivityFlagsProvider; -import com.android.tools.idea.run.blaze.BlazeLaunchTask; -import com.android.tools.idea.run.tasks.ConnectDebuggerTask; -import com.google.idea.blaze.android.run.deployinfo.BlazeAndroidDeployInfo; -import com.google.idea.blaze.android.run.runner.ApkBuildStep; -import com.intellij.execution.ExecutionException; -import com.intellij.execution.Executor; -import com.intellij.execution.configurations.RunConfiguration; -import com.intellij.execution.runners.ExecutionEnvironment; -import com.intellij.openapi.project.Project; -import javax.annotation.Nullable; -import org.jetbrains.android.facet.AndroidFacet; - -/** Compat for #api212 */ -public class BlazeAndroidBinaryNormalBuildRunContext - extends BlazeAndroidBinaryNormalBuildRunContextBase { - BlazeAndroidBinaryNormalBuildRunContext( - Project project, - AndroidFacet facet, - RunConfiguration runConfiguration, - ExecutionEnvironment env, - BlazeAndroidBinaryRunConfigurationState configState, - ApkBuildStep buildStep, - String launchId) { - super(project, facet, runConfiguration, env, configState, buildStep, launchId); - } - - @Override - public BlazeLaunchTask getApplicationLaunchTask( - LaunchOptions launchOptions, @Nullable Integer userId, String contributorsAmStartOptions) - throws ExecutionException { - String extraFlags = UserIdHelper.getFlagsFromUserId(userId); - if (!contributorsAmStartOptions.isEmpty()) { - extraFlags += (extraFlags.isEmpty() ? "" : " ") + contributorsAmStartOptions; - } - - final StartActivityFlagsProvider startActivityFlagsProvider = - new DefaultStartActivityFlagsProvider(project, launchOptions.isDebug(), extraFlags); - - BlazeAndroidDeployInfo deployInfo; - try { - deployInfo = buildStep.getDeployInfo(); - } catch (ApkProvisionException e) { - throw new ExecutionException(e); - } - - return BlazeAndroidBinaryApplicationLaunchTaskProvider.getApplicationLaunchTask( - applicationIdProvider, - deployInfo.getMergedManifest(), - configState, - startActivityFlagsProvider); - } - - @Nullable - @Override - @SuppressWarnings("unchecked") - public ConnectDebuggerTask getDebuggerTask( - AndroidDebugger androidDebugger, AndroidDebuggerState androidDebuggerState) { - return getBaseDebuggerTask(androidDebugger, androidDebuggerState, env, facet); - } - - @Override - public Executor getExecutor() { - return env.getExecutor(); - } -} diff --git a/aswb/sdkcompat/asdev/com/google/idea/blaze/android/run/binary/BlazeAndroidBinaryNormalBuildRunContextBase.java b/aswb/sdkcompat/asdev/com/google/idea/blaze/android/run/binary/BlazeAndroidBinaryNormalBuildRunContextBase.java deleted file mode 100644 index bc3517e8fe8..00000000000 --- a/aswb/sdkcompat/asdev/com/google/idea/blaze/android/run/binary/BlazeAndroidBinaryNormalBuildRunContextBase.java +++ /dev/null @@ -1,177 +0,0 @@ -/* - * Copyright 2016 The Bazel Authors. All rights reserved. - * - * 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. - */ -package com.google.idea.blaze.android.run.binary; - -import static com.google.idea.blaze.android.run.runner.BlazeAndroidLaunchTasksProvider.NATIVE_DEBUGGING_ENABLED; - -import com.android.ddmlib.IDevice; -import com.android.tools.idea.gradle.util.DynamicAppUtils; -import com.android.tools.idea.run.ApkFileUnit; -import com.android.tools.idea.run.ApkInfo; -import com.android.tools.idea.run.ApkProvider; -import com.android.tools.idea.run.ApkProvisionException; -import com.android.tools.idea.run.ApplicationIdProvider; -import com.android.tools.idea.run.ConsoleProvider; -import com.android.tools.idea.run.LaunchOptions; -import com.android.tools.idea.run.blaze.BlazeLaunchTask; -import com.android.tools.idea.run.blaze.BlazeLaunchTasksProvider; -import com.android.tools.idea.run.editor.ProfilerState; -import com.android.tools.idea.run.tasks.DeployTasksCompat; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; -import com.google.idea.blaze.android.run.deployinfo.BlazeApkProviderService; -import com.google.idea.blaze.android.run.runner.ApkBuildStep; -import com.google.idea.blaze.android.run.runner.BlazeAndroidDeviceSelector; -import com.google.idea.blaze.android.run.runner.BlazeAndroidLaunchTasksProvider; -import com.google.idea.blaze.android.run.runner.BlazeAndroidRunContext; -import com.intellij.execution.ExecutionException; -import com.intellij.execution.configurations.RunConfiguration; -import com.intellij.execution.runners.ExecutionEnvironment; -import com.intellij.openapi.project.Project; -import java.util.Collection; -import java.util.List; -import java.util.stream.Collectors; -import javax.annotation.Nullable; -import org.jetbrains.android.facet.AndroidFacet; -import org.jetbrains.annotations.NotNull; - -/** Run context for android_binary. */ -public abstract class BlazeAndroidBinaryNormalBuildRunContextBase - implements BlazeAndroidRunContext { - protected final Project project; - protected final AndroidFacet facet; - protected final RunConfiguration runConfiguration; - protected final ExecutionEnvironment env; - protected final BlazeAndroidBinaryRunConfigurationState configState; - protected final ConsoleProvider consoleProvider; - protected final ApkBuildStep buildStep; - protected final ApkProvider apkProvider; - protected final ApplicationIdProvider applicationIdProvider; - private final String launchId; - - BlazeAndroidBinaryNormalBuildRunContextBase( - Project project, - AndroidFacet facet, - RunConfiguration runConfiguration, - ExecutionEnvironment env, - BlazeAndroidBinaryRunConfigurationState configState, - ApkBuildStep buildStep, - String launchId) { - this.project = project; - this.facet = facet; - this.runConfiguration = runConfiguration; - this.env = env; - this.configState = configState; - this.consoleProvider = new BlazeAndroidBinaryConsoleProvider(project); - this.buildStep = buildStep; - this.apkProvider = BlazeApkProviderService.getInstance().getApkProvider(project, buildStep); - this.applicationIdProvider = new BlazeAndroidBinaryApplicationIdProvider(buildStep); - this.launchId = launchId; - } - - @Override - public BlazeAndroidDeviceSelector getDeviceSelector() { - return new BlazeAndroidDeviceSelector.NormalDeviceSelector(); - } - - @Override - public void augmentLaunchOptions(LaunchOptions.Builder options) { - options.setDeploy(true).setOpenLogcatAutomatically(configState.showLogcatAutomatically()); - options.addExtraOptions( - ImmutableMap.of( - "android.profilers.state", // Not used after #api211 - configState.getProfilerState(), - NATIVE_DEBUGGING_ENABLED, - configState.getCommonState().isNativeDebuggingEnabled())); - } - - @Override - public ConsoleProvider getConsoleProvider() { - return consoleProvider; - } - - @Override - public ApplicationIdProvider getApplicationIdProvider() throws ExecutionException { - return applicationIdProvider; - } - - @Override - public ApkBuildStep getBuildStep() { - return buildStep; - } - - @Nullable - @Override - public Integer getUserId(IDevice device) throws ExecutionException { - return UserIdHelper.getUserIdFromConfigurationState(project, device, configState); - } - - @Override - public BlazeLaunchTasksProvider getLaunchTasksProvider(LaunchOptions.Builder launchOptionsBuilder) - throws ExecutionException { - return new BlazeAndroidLaunchTasksProvider( - project, this, applicationIdProvider, launchOptionsBuilder); - } - - @Override - public String getAmStartOptions() { - return configState.getAmStartOptions(); - } - - @Override - public ProfilerState getProfileState() { - return configState.getProfilerState(); - } - - @Nullable - @Override - public ImmutableList getDeployTasks(IDevice device, LaunchOptions launchOptions) - throws ExecutionException { - BlazeLaunchTask deployTask = - DeployTasksCompat.createDeployTask( - project, getApkInfoToInstall(device, launchOptions, apkProvider), launchOptions); - return ImmutableList.of(new DeploymentTimingReporterTask(launchId, deployTask)); - } - - /** Returns a list of APKs excluding any APKs for features that are disabled. */ - public static List getApkInfoToInstall( - IDevice device, LaunchOptions launchOptions, ApkProvider apkProvider) - throws ExecutionException { - Collection apks; - try { - apks = apkProvider.getApks(device); - } catch (ApkProvisionException e) { - throw new ExecutionException(e); - } - List disabledFeatures = launchOptions.getDisabledDynamicFeatures(); - return apks.stream() - .map(apk -> getApkInfoToInstall(apk, disabledFeatures)) - .collect(Collectors.toList()); - } - - @NotNull - private static ApkInfo getApkInfoToInstall(ApkInfo apkInfo, List disabledFeatures) { - if (apkInfo.getFiles().size() > 1) { - List filteredApks = - apkInfo.getFiles().stream() - .filter(feature -> DynamicAppUtils.isFeatureEnabled(disabledFeatures, feature)) - .collect(Collectors.toList()); - return new ApkInfo(filteredApks, apkInfo.getApplicationId()); - } else { - return apkInfo; - } - } -} diff --git a/aswb/sdkcompat/asdev/com/google/idea/blaze/android/run/binary/BlazeAndroidBinaryNormalBuildRunContextCompat.java b/aswb/sdkcompat/asdev/com/google/idea/blaze/android/run/binary/BlazeAndroidBinaryNormalBuildRunContextCompat.java deleted file mode 100644 index d54c472c84b..00000000000 --- a/aswb/sdkcompat/asdev/com/google/idea/blaze/android/run/binary/BlazeAndroidBinaryNormalBuildRunContextCompat.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright 2022 The Bazel Authors. All rights reserved. - * - * 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. - */ -package com.google.idea.blaze.android.run.binary; - -import static com.android.tools.idea.run.tasks.DefaultConnectDebuggerTaskKt.getBaseDebuggerTask; - -import com.android.tools.idea.execution.common.debug.AndroidDebugger; -import com.android.tools.idea.execution.common.debug.AndroidDebuggerState; -import com.android.tools.idea.run.tasks.ConnectDebuggerTask; -import com.google.idea.blaze.android.run.runner.ApkBuildStep; -import com.intellij.execution.configurations.RunConfiguration; -import com.intellij.execution.runners.ExecutionEnvironment; -import com.intellij.openapi.project.Project; -import javax.annotation.Nullable; -import org.jetbrains.android.facet.AndroidFacet; - -/** Compat class for {@link BlazeAndroidBinaryNormalBuildRunContext}. */ -public class BlazeAndroidBinaryNormalBuildRunContextCompat - extends BlazeAndroidBinaryNormalBuildRunContext { - - BlazeAndroidBinaryNormalBuildRunContextCompat( - Project project, - AndroidFacet facet, - RunConfiguration runConfiguration, - ExecutionEnvironment env, - BlazeAndroidBinaryRunConfigurationState configState, - ApkBuildStep buildStep, - String launchId) { - super(project, facet, runConfiguration, env, configState, buildStep, launchId); - } - - @Nullable - @Override - @SuppressWarnings("unchecked") - public ConnectDebuggerTask getDebuggerTask( - AndroidDebugger androidDebugger, AndroidDebuggerState androidDebuggerState) { - return getBaseDebuggerTask(androidDebugger, androidDebuggerState, env, facet); - } -} diff --git a/aswb/sdkcompat/asdev/com/google/idea/blaze/android/run/binary/BlazeAndroidBinaryProgramRunner.java b/aswb/sdkcompat/asdev/com/google/idea/blaze/android/run/binary/BlazeAndroidBinaryProgramRunner.java deleted file mode 100644 index 97b3d36aec1..00000000000 --- a/aswb/sdkcompat/asdev/com/google/idea/blaze/android/run/binary/BlazeAndroidBinaryProgramRunner.java +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Copyright 2016 The Bazel Authors. All rights reserved. - * - * 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. - */ -package com.google.idea.blaze.android.run.binary; - -import static com.intellij.openapi.application.ModalityState.NON_MODAL; - -import com.android.tools.idea.profilers.ProfileRunExecutor; -import com.android.tools.idea.run.configuration.execution.AndroidConfigurationExecutor; -import com.google.idea.blaze.android.run.BlazeAndroidRunConfigurationHandler; -import com.intellij.execution.ExecutionException; -import com.intellij.execution.ExecutionResult; -import com.intellij.execution.Executor; -import com.intellij.execution.configurations.RunProfile; -import com.intellij.execution.configurations.RunProfileState; -import com.intellij.execution.configurations.RunnerSettings; -import com.intellij.execution.executors.DefaultDebugExecutor; -import com.intellij.execution.executors.DefaultRunExecutor; -import com.intellij.execution.runners.AsyncProgramRunner; -import com.intellij.execution.runners.ExecutionEnvironment; -import com.intellij.execution.runners.RunContentBuilder; -import com.intellij.execution.ui.RunContentDescriptor; -import com.intellij.openapi.application.ActionsKt; -import com.intellij.openapi.fileEditor.FileDocumentManager; -import com.intellij.openapi.progress.ProgressIndicator; -import com.intellij.openapi.progress.ProgressManager; -import com.intellij.openapi.progress.Task; -import org.jetbrains.concurrency.AsyncPromise; -import org.jetbrains.concurrency.Promise; - -/** Program runner for configurations from {@link BlazeAndroidBinaryRunConfigurationHandler}. */ -public class BlazeAndroidBinaryProgramRunner extends AsyncProgramRunner { - @Override - public boolean canRun(String executorId, RunProfile profile) { - BlazeAndroidRunConfigurationHandler handler = - BlazeAndroidRunConfigurationHandler.getHandlerFrom(profile); - if (!(handler instanceof BlazeAndroidBinaryRunConfigurationHandler)) { - return false; - } - return (DefaultDebugExecutor.EXECUTOR_ID.equals(executorId) - || DefaultRunExecutor.EXECUTOR_ID.equals(executorId) - || ProfileRunExecutor.EXECUTOR_ID.equals(executorId)); - } - - @Override - protected Promise execute( - ExecutionEnvironment environment, RunProfileState state) { - FileDocumentManager.getInstance().saveAllDocuments(); - - AsyncPromise promise = new AsyncPromise<>(); - - ProgressManager.getInstance() - .run( - new Task.Backgroundable(environment.getProject(), "Launching ${runProfile.name}") { - @Override - public void run(ProgressIndicator indicator) { - try { - RunContentDescriptor descriptor; - if (state instanceof AndroidConfigurationExecutor) { - AndroidConfigurationExecutor configurationExecutor = - (AndroidConfigurationExecutor) state; - Executor executor = environment.getExecutor(); - if (executor.getId().equals(DefaultDebugExecutor.EXECUTOR_ID)) { - descriptor = configurationExecutor.debug(indicator); - } else if (executor.getId().equals(DefaultRunExecutor.EXECUTOR_ID) - || executor.getId().equals(ProfileRunExecutor.EXECUTOR_ID)) { - descriptor = configurationExecutor.run(indicator); - } else { - throw new ExecutionException("Unsupported executor"); - } - } else { - descriptor = doExecute(state, environment); - } - promise.setResult(descriptor); - } catch (ExecutionException e) { - var unused = promise.setError(e); - } - } - - @Override - public void onCancel() { - super.onCancel(); - promise.setResult(null); - } - }); - - return promise; - } - - private RunContentDescriptor doExecute( - final RunProfileState state, final ExecutionEnvironment env) throws ExecutionException { - ExecutionResult result = state.execute(env.getExecutor(), this); - return ActionsKt.invokeAndWaitIfNeeded( - NON_MODAL, - () -> new RunContentBuilder(result, env).showRunContent(env.getContentToReuse())); - } - - @Override - public String getRunnerId() { - return "AndroidBinaryProgramRunner"; - } -} diff --git a/aswb/sdkcompat/asdev/com/google/idea/blaze/android/run/binary/DeploymentTimingReporterTask.java b/aswb/sdkcompat/asdev/com/google/idea/blaze/android/run/binary/DeploymentTimingReporterTask.java deleted file mode 100644 index 81696ad5b1e..00000000000 --- a/aswb/sdkcompat/asdev/com/google/idea/blaze/android/run/binary/DeploymentTimingReporterTask.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright 2021 The Bazel Authors. All rights reserved. - * - * 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. - */ -package com.google.idea.blaze.android.run.binary; - -import com.android.tools.idea.run.blaze.BlazeLaunchContext; -import com.android.tools.idea.run.blaze.BlazeLaunchTask; -import com.google.common.base.Stopwatch; -import com.google.idea.blaze.android.run.LaunchMetrics; -import com.intellij.execution.ExecutionException; - -/** A wrapper launch task that wraps the given deployment task and logs the deployment latency. */ -public class DeploymentTimingReporterTask implements BlazeLaunchTask { - private final BlazeLaunchTask deployTask; - private final String launchId; - - public DeploymentTimingReporterTask(String launchId, BlazeLaunchTask deployTask) { - this.launchId = launchId; - this.deployTask = deployTask; - } - - @Override - public void run(BlazeLaunchContext launchContext) throws ExecutionException { - Stopwatch s = Stopwatch.createStarted(); - try { - deployTask.run(launchContext); - LaunchMetrics.logDeploymentTime(launchId, s.elapsed(), true); - } catch (ExecutionException e) { - LaunchMetrics.logDeploymentTime(launchId, s.elapsed(), false); - throw e; - } - } -} diff --git a/aswb/sdkcompat/asdev/com/google/idea/blaze/android/run/binary/UserIdHelper.java b/aswb/sdkcompat/asdev/com/google/idea/blaze/android/run/binary/UserIdHelper.java deleted file mode 100644 index ab71d4747c2..00000000000 --- a/aswb/sdkcompat/asdev/com/google/idea/blaze/android/run/binary/UserIdHelper.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright 2016 The Bazel Authors. All rights reserved. - * - * 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. - */ -package com.google.idea.blaze.android.run.binary; - -import com.android.ddmlib.AdbCommandRejectedException; -import com.android.ddmlib.CollectingOutputReceiver; -import com.android.ddmlib.IDevice; -import com.android.ddmlib.ShellCommandUnresponsiveException; -import com.android.ddmlib.TimeoutException; -import com.android.tools.idea.execution.common.RunConfigurationNotifier; -import com.intellij.execution.ExecutionException; -import com.intellij.openapi.project.Project; -import java.io.IOException; -import java.util.regex.Matcher; -import java.util.regex.Pattern; -import javax.annotation.Nullable; - -/** Helpers for user id */ -public final class UserIdHelper { - private UserIdHelper() {} - - private static final Pattern USER_ID_REGEX = - Pattern.compile("UserInfo\\{([0-9]+):Work profile:[0-9]+\\}"); - - @Nullable - public static Integer getUserIdFromConfigurationState( - Project project, IDevice device, BlazeAndroidBinaryRunConfigurationState state) - throws ExecutionException { - if (state.useWorkProfileIfPresent()) { - try { - Integer userId = getWorkProfileId(device); - if (userId == null) { - RunConfigurationNotifier.INSTANCE.notifyWarning( - project, - "", - "Could not locate work profile on selected device. Launching default user."); - } - return userId; - } catch (TimeoutException - | AdbCommandRejectedException - | ShellCommandUnresponsiveException - | IOException e) { - throw new ExecutionException(e); - } - } - return state.getUserId(); - } - - @Nullable - public static Integer getWorkProfileId(IDevice device) - throws TimeoutException, AdbCommandRejectedException, ShellCommandUnresponsiveException, - IOException { - CollectingOutputReceiver receiver = new CollectingOutputReceiver(); - device.executeShellCommand("pm list users", receiver); - String result = receiver.getOutput(); - Matcher matcher = USER_ID_REGEX.matcher(result); - if (matcher.find()) { - return Integer.parseInt(matcher.group(1)); - } - return null; - } - - public static String getFlagsFromUserId(@Nullable Integer userId) { - return userId != null ? ("--user " + userId.intValue()) : ""; - } -} diff --git a/aswb/sdkcompat/asdev/com/google/idea/blaze/android/run/binary/mobileinstall/BlazeAndroidBinaryMobileInstallRunContext.java b/aswb/sdkcompat/asdev/com/google/idea/blaze/android/run/binary/mobileinstall/BlazeAndroidBinaryMobileInstallRunContext.java deleted file mode 100644 index c49082cfdaa..00000000000 --- a/aswb/sdkcompat/asdev/com/google/idea/blaze/android/run/binary/mobileinstall/BlazeAndroidBinaryMobileInstallRunContext.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright 2016 The Bazel Authors. All rights reserved. - * - * 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. - */ -package com.google.idea.blaze.android.run.binary.mobileinstall; - -import static com.android.tools.idea.run.tasks.DefaultConnectDebuggerTaskKt.getBaseDebuggerTask; - -import com.android.tools.idea.execution.common.debug.AndroidDebugger; -import com.android.tools.idea.execution.common.debug.AndroidDebuggerState; -import com.android.tools.idea.run.ApkProvisionException; -import com.android.tools.idea.run.LaunchOptions; -import com.android.tools.idea.run.activity.DefaultStartActivityFlagsProvider; -import com.android.tools.idea.run.activity.StartActivityFlagsProvider; -import com.android.tools.idea.run.blaze.BlazeLaunchTask; -import com.android.tools.idea.run.tasks.ConnectDebuggerTask; -import com.google.idea.blaze.android.run.binary.BlazeAndroidBinaryApplicationLaunchTaskProvider; -import com.google.idea.blaze.android.run.binary.BlazeAndroidBinaryRunConfigurationState; -import com.google.idea.blaze.android.run.binary.UserIdHelper; -import com.google.idea.blaze.android.run.deployinfo.BlazeAndroidDeployInfo; -import com.google.idea.blaze.android.run.runner.ApkBuildStep; -import com.intellij.execution.ExecutionException; -import com.intellij.execution.Executor; -import com.intellij.execution.configurations.RunConfiguration; -import com.intellij.execution.runners.ExecutionEnvironment; -import com.intellij.openapi.project.Project; -import javax.annotation.Nullable; -import org.jetbrains.android.facet.AndroidFacet; - -/** Run Context for mobile install launches, #api4.0 compat. */ -public class BlazeAndroidBinaryMobileInstallRunContext - extends BlazeAndroidBinaryMobileInstallRunContextBase { - public BlazeAndroidBinaryMobileInstallRunContext( - Project project, - AndroidFacet facet, - RunConfiguration runConfiguration, - ExecutionEnvironment env, - BlazeAndroidBinaryRunConfigurationState configState, - ApkBuildStep buildStep, - String launchId) { - super(project, facet, runConfiguration, env, configState, buildStep, launchId); - } - - @SuppressWarnings("unchecked") // upstream API - @Override - public BlazeLaunchTask getApplicationLaunchTask( - LaunchOptions launchOptions, @Nullable Integer userId, String contributorsAmStartOptions) - throws ExecutionException { - - String extraFlags = UserIdHelper.getFlagsFromUserId(userId); - if (!contributorsAmStartOptions.isEmpty()) { - extraFlags += (extraFlags.isEmpty() ? "" : " ") + contributorsAmStartOptions; - } - - final StartActivityFlagsProvider startActivityFlagsProvider = - new DefaultStartActivityFlagsProvider(project, launchOptions.isDebug(), extraFlags); - BlazeAndroidDeployInfo deployInfo; - try { - deployInfo = buildStep.getDeployInfo(); - } catch (ApkProvisionException e) { - throw new ExecutionException(e); - } - - return BlazeAndroidBinaryApplicationLaunchTaskProvider.getApplicationLaunchTask( - applicationIdProvider, - deployInfo.getMergedManifest(), - configState, - startActivityFlagsProvider); - } - - @Nullable - @Override - @SuppressWarnings("unchecked") - public ConnectDebuggerTask getDebuggerTask( - AndroidDebugger androidDebugger, AndroidDebuggerState androidDebuggerState) { - return getBaseDebuggerTask(androidDebugger, androidDebuggerState, env, facet); - } - - @Override - public Executor getExecutor() { - return env.getExecutor(); - } -} diff --git a/aswb/sdkcompat/asdev/com/google/idea/blaze/android/run/binary/mobileinstall/BlazeAndroidBinaryMobileInstallRunContextBase.java b/aswb/sdkcompat/asdev/com/google/idea/blaze/android/run/binary/mobileinstall/BlazeAndroidBinaryMobileInstallRunContextBase.java deleted file mode 100644 index 7562174bd25..00000000000 --- a/aswb/sdkcompat/asdev/com/google/idea/blaze/android/run/binary/mobileinstall/BlazeAndroidBinaryMobileInstallRunContextBase.java +++ /dev/null @@ -1,165 +0,0 @@ -/* - * Copyright 2016 The Bazel Authors. All rights reserved. - * - * 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. - */ -package com.google.idea.blaze.android.run.binary.mobileinstall; - -import com.android.ddmlib.IDevice; -import com.android.tools.idea.run.ApkFileUnit; -import com.android.tools.idea.run.ApkInfo; -import com.android.tools.idea.run.ApkProvisionException; -import com.android.tools.idea.run.ApplicationIdProvider; -import com.android.tools.idea.run.ConsoleProvider; -import com.android.tools.idea.run.LaunchOptions; -import com.android.tools.idea.run.blaze.BlazeLaunchTask; -import com.android.tools.idea.run.blaze.BlazeLaunchTasksProvider; -import com.android.tools.idea.run.editor.ProfilerState; -import com.android.tools.idea.run.tasks.DeployTasksCompat; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; -import com.google.idea.blaze.android.run.binary.BlazeAndroidBinaryApplicationIdProvider; -import com.google.idea.blaze.android.run.binary.BlazeAndroidBinaryConsoleProvider; -import com.google.idea.blaze.android.run.binary.BlazeAndroidBinaryRunConfigurationState; -import com.google.idea.blaze.android.run.binary.DeploymentTimingReporterTask; -import com.google.idea.blaze.android.run.binary.UserIdHelper; -import com.google.idea.blaze.android.run.deployinfo.BlazeAndroidDeployInfo; -import com.google.idea.blaze.android.run.runner.ApkBuildStep; -import com.google.idea.blaze.android.run.runner.BlazeAndroidDeviceSelector; -import com.google.idea.blaze.android.run.runner.BlazeAndroidLaunchTasksProvider; -import com.google.idea.blaze.android.run.runner.BlazeAndroidRunContext; -import com.google.idea.blaze.base.sync.data.BlazeDataStorage; -import com.intellij.execution.ExecutionException; -import com.intellij.execution.configurations.RunConfiguration; -import com.intellij.execution.runners.ExecutionEnvironment; -import com.intellij.openapi.project.Project; -import java.util.Collections; -import java.util.stream.Collectors; -import javax.annotation.Nullable; -import org.jetbrains.android.facet.AndroidFacet; - -/** Run context for android_binary. */ -abstract class BlazeAndroidBinaryMobileInstallRunContextBase implements BlazeAndroidRunContext { - protected final Project project; - protected final AndroidFacet facet; - protected final RunConfiguration runConfiguration; - protected final ExecutionEnvironment env; - protected final BlazeAndroidBinaryRunConfigurationState configState; - protected final ConsoleProvider consoleProvider; - protected final ApplicationIdProvider applicationIdProvider; - protected final ApkBuildStep buildStep; - private final String launchId; - - public BlazeAndroidBinaryMobileInstallRunContextBase( - Project project, - AndroidFacet facet, - RunConfiguration runConfiguration, - ExecutionEnvironment env, - BlazeAndroidBinaryRunConfigurationState configState, - ApkBuildStep buildStep, - String launchId) { - this.project = project; - this.facet = facet; - this.runConfiguration = runConfiguration; - this.env = env; - this.configState = configState; - this.consoleProvider = new BlazeAndroidBinaryConsoleProvider(project); - this.buildStep = buildStep; - this.applicationIdProvider = new BlazeAndroidBinaryApplicationIdProvider(buildStep); - this.launchId = launchId; - } - - @Override - public BlazeAndroidDeviceSelector getDeviceSelector() { - return new BlazeAndroidDeviceSelector.NormalDeviceSelector(); - } - - @Override - public void augmentLaunchOptions(LaunchOptions.Builder options) { - options - .setDeploy(buildStep.needsIdeDeploy()) - .setOpenLogcatAutomatically(configState.showLogcatAutomatically()); - // This is needed for compatibility with #api211 - options.addExtraOptions( - ImmutableMap.of("android.profilers.state", configState.getProfilerState())); - } - - @Override - public ConsoleProvider getConsoleProvider() { - return consoleProvider; - } - - @Override - public ApplicationIdProvider getApplicationIdProvider() throws ExecutionException { - return applicationIdProvider; - } - - @Override - public ApkBuildStep getBuildStep() { - return buildStep; - } - - @Override - public ProfilerState getProfileState() { - return configState.getProfilerState(); - } - - @Override - public ImmutableList getDeployTasks(IDevice device, LaunchOptions launchOptions) - throws ExecutionException { - if (!buildStep.needsIdeDeploy()) { - return ImmutableList.of(); - } - - BlazeAndroidDeployInfo deployInfo; - try { - deployInfo = buildStep.getDeployInfo(); - } catch (ApkProvisionException e) { - throw new ExecutionException(e); - } - - String packageName = deployInfo.getMergedManifest().packageName; - if (packageName == null) { - throw new ExecutionException("Could not determine package name from deploy info"); - } - - ApkInfo info = - new ApkInfo( - deployInfo.getApksToDeploy().stream() - .map(file -> new ApkFileUnit(BlazeDataStorage.WORKSPACE_MODULE_NAME, file)) - .collect(Collectors.toList()), - packageName); - - BlazeLaunchTask deployTask = - DeployTasksCompat.createDeployTask(project, Collections.singletonList(info), launchOptions); - return ImmutableList.of(new DeploymentTimingReporterTask(launchId, deployTask)); - } - - @Nullable - @Override - public Integer getUserId(IDevice device) throws ExecutionException { - return UserIdHelper.getUserIdFromConfigurationState(project, device, configState); - } - - @Override - public BlazeLaunchTasksProvider getLaunchTasksProvider(LaunchOptions.Builder launchOptionsBuilder) - throws ExecutionException { - return new BlazeAndroidLaunchTasksProvider( - project, this, applicationIdProvider, launchOptionsBuilder); - } - - @Override - public String getAmStartOptions() { - return configState.getAmStartOptions(); - } -} diff --git a/aswb/sdkcompat/asdev/com/google/idea/blaze/android/run/binary/mobileinstall/BlazeAndroidBinaryMobileInstallRunContextCompat.java b/aswb/sdkcompat/asdev/com/google/idea/blaze/android/run/binary/mobileinstall/BlazeAndroidBinaryMobileInstallRunContextCompat.java deleted file mode 100644 index 29411ebad5a..00000000000 --- a/aswb/sdkcompat/asdev/com/google/idea/blaze/android/run/binary/mobileinstall/BlazeAndroidBinaryMobileInstallRunContextCompat.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright 2022 The Bazel Authors. All rights reserved. - * - * 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. - */ -package com.google.idea.blaze.android.run.binary.mobileinstall; - -import static com.android.tools.idea.run.tasks.DefaultConnectDebuggerTaskKt.getBaseDebuggerTask; - -import com.android.tools.idea.execution.common.debug.AndroidDebugger; -import com.android.tools.idea.execution.common.debug.AndroidDebuggerState; -import com.android.tools.idea.run.tasks.ConnectDebuggerTask; -import com.google.idea.blaze.android.run.binary.BlazeAndroidBinaryRunConfigurationState; -import com.google.idea.blaze.android.run.runner.ApkBuildStep; -import com.google.idea.blaze.base.run.BlazeCommandRunConfiguration; -import com.intellij.execution.runners.ExecutionEnvironment; -import com.intellij.openapi.project.Project; -import javax.annotation.Nullable; -import org.jetbrains.android.facet.AndroidFacet; - -/** Compatct class for {@link BlazeAndroidBinaryMobileInstallRunContext}. */ -public class BlazeAndroidBinaryMobileInstallRunContextCompat - extends BlazeAndroidBinaryMobileInstallRunContext { - - public BlazeAndroidBinaryMobileInstallRunContextCompat( - Project project, - AndroidFacet facet, - BlazeCommandRunConfiguration configuration, - ExecutionEnvironment env, - BlazeAndroidBinaryRunConfigurationState configState, - ApkBuildStep buildStep, - String launchId) { - super(project, facet, configuration, env, configState, buildStep, launchId); - } - - @Nullable - @Override - @SuppressWarnings("unchecked") - public ConnectDebuggerTask getDebuggerTask( - AndroidDebugger androidDebugger, AndroidDebuggerState androidDebuggerState) { - return getBaseDebuggerTask(androidDebugger, androidDebuggerState, env, facet); - } -} diff --git a/aswb/sdkcompat/asdev/com/google/idea/blaze/android/run/runner/BlazeAndroidDebuggerService.java b/aswb/sdkcompat/asdev/com/google/idea/blaze/android/run/runner/BlazeAndroidDebuggerService.java deleted file mode 100644 index c8658223baa..00000000000 --- a/aswb/sdkcompat/asdev/com/google/idea/blaze/android/run/runner/BlazeAndroidDebuggerService.java +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Copyright 2016 The Bazel Authors. All rights reserved. - * - * 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. - */ -package com.google.idea.blaze.android.run.runner; - -import com.android.tools.idea.execution.common.debug.AndroidDebugger; -import com.android.tools.idea.execution.common.debug.AndroidDebuggerState; -import com.android.tools.idea.execution.common.debug.impl.java.AndroidJavaDebugger; -import com.android.tools.ndk.run.editor.AutoAndroidDebuggerState; -import com.google.common.collect.ImmutableList; -import com.google.idea.blaze.android.cppimpl.debug.BlazeAutoAndroidDebugger; -import com.google.idea.blaze.android.run.deployinfo.BlazeAndroidDeployInfo; -import com.google.idea.blaze.base.model.primitives.WorkspaceRoot; -import com.intellij.ide.plugins.PluginManagerCore; -import com.intellij.openapi.project.Project; -import javax.annotation.Nullable; - -/** Provides android debuggers and debugger states for blaze projects. */ -public interface BlazeAndroidDebuggerService { - - static BlazeAndroidDebuggerService getInstance(Project project) { - return project.getService(BlazeAndroidDebuggerService.class); - } - - /** Returns the standard debugger for non-native (Java) debugging. */ - AndroidDebugger getDebugger(); - - /** Returns the standard debugger for native (C++) debugging. */ - AndroidDebugger getNativeDebugger(); - - /** - * Performs additional necessary setup for native debugging, incorporating info from {@link - * BlazeAndroidDeployInfo}. - */ - void configureNativeDebugger( - AndroidDebuggerState state, @Nullable BlazeAndroidDeployInfo deployInfo); - - /** Default debugger service. */ - class DefaultDebuggerService implements BlazeAndroidDebuggerService { - private final Project project; - - public DefaultDebuggerService(Project project) { - this.project = project; - } - - @Override - public AndroidDebugger getDebugger() { - return new AndroidJavaDebugger(); - } - - @Override - public AndroidDebugger getNativeDebugger() { - return new BlazeAutoAndroidDebugger(); - } - - @Override - public void configureNativeDebugger( - AndroidDebuggerState rawState, @Nullable BlazeAndroidDeployInfo deployInfo) { - if (!isNdkPluginLoaded() && !(rawState instanceof AutoAndroidDebuggerState)) { - return; - } - AutoAndroidDebuggerState state = (AutoAndroidDebuggerState) rawState; - - // Source code is always relative to the workspace root in a blaze project. - String workingDirPath = WorkspaceRoot.fromProject(project).directory().getPath(); - state.setWorkingDir(workingDirPath); - - // Remote built binaries may use /proc/self/cwd to represent the working directory, - // so we manually map /proc/self/cwd to the workspace root. We used to use - // `plugin.symbol-file.dwarf.comp-dir-symlink-paths = "/proc/self/cwd"` - // to automatically resolve this, but it's no longer supported in newer versions of - // LLDB. - String sourceMapToWorkspaceRootCommand = - "settings append target.source-map /proc/self/cwd/ " + workingDirPath; - - ImmutableList startupCommands = - ImmutableList.builder() - .addAll(state.getUserStartupCommands()) - .add(sourceMapToWorkspaceRootCommand) - .build(); - state.setUserStartupCommands(startupCommands); - - // NDK plugin will pass symbol directories to LLDB as `settings append - // target.exec-search-paths`. - if (deployInfo != null) { - state.setSymbolDirs( - deployInfo.getSymbolFiles().stream() - .map(symbol -> symbol.getParentFile().getAbsolutePath()) - .collect(ImmutableList.toImmutableList())); - } - } - } - - static boolean isNdkPluginLoaded() { - return PluginManagerCore.getLoadedPlugins().stream() - .anyMatch( - d -> d.isEnabled() && d.getPluginId().getIdString().equals("com.android.tools.ndk")); - } -} diff --git a/aswb/sdkcompat/asdev/com/google/idea/blaze/android/run/runner/BlazeAndroidDeviceSelector.java b/aswb/sdkcompat/asdev/com/google/idea/blaze/android/run/runner/BlazeAndroidDeviceSelector.java deleted file mode 100644 index b4fdcf0fd33..00000000000 --- a/aswb/sdkcompat/asdev/com/google/idea/blaze/android/run/runner/BlazeAndroidDeviceSelector.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright 2018 The Bazel Authors. All rights reserved. - * - * 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. - */ - -package com.google.idea.blaze.android.run.runner; - -import com.android.tools.idea.execution.common.AndroidSessionInfo; -import com.android.tools.idea.run.DeviceFutures; -import com.android.tools.idea.run.editor.DeployTarget; -import com.google.common.annotations.VisibleForTesting; -import com.intellij.execution.ExecutionException; -import com.intellij.execution.Executor; -import com.intellij.execution.runners.ExecutionEnvironment; -import com.intellij.openapi.project.Project; -import javax.annotation.Nullable; - -/** Selects a device. */ -public interface BlazeAndroidDeviceSelector { - /** A device session */ - class DeviceSession { - @Nullable public final DeployTarget deployTarget; - @Nullable public final DeviceFutures deviceFutures; - - public DeviceSession( - @Nullable DeployTarget deployTarget, @Nullable DeviceFutures deviceFutures) { - this.deployTarget = deployTarget; - this.deviceFutures = deviceFutures; - } - - // Only for back compat - @VisibleForTesting - public DeviceSession( - @Nullable DeployTarget deployTarget, - @Nullable DeviceFutures deviceFutures, - @Nullable AndroidSessionInfo sessionInfo) { - this(deployTarget, deviceFutures); - } - } - - DeviceSession getDevice( - Project project, Executor executor, ExecutionEnvironment env, boolean debug, int runConfigId) - throws ExecutionException; - /** Standard device selector */ - class NormalDeviceSelector implements BlazeAndroidDeviceSelector { - @Override - public DeviceSession getDevice( - Project project, - Executor executor, - ExecutionEnvironment env, - boolean debug, - int runConfigId) { - DeployTarget deployTarget = BlazeDeployTargetService.getInstance(project).getDeployTarget(); - if (deployTarget == null) { - return null; - } - DeviceFutures deviceFutures = null; - if (!deployTarget.hasCustomRunProfileState(executor)) { - deviceFutures = deployTarget.getDevices(project); - } - return new DeviceSession(deployTarget, deviceFutures); - } - } -} diff --git a/aswb/sdkcompat/asdev/com/google/idea/blaze/android/run/runner/BlazeAndroidLaunchTasksProvider.java b/aswb/sdkcompat/asdev/com/google/idea/blaze/android/run/runner/BlazeAndroidLaunchTasksProvider.java deleted file mode 100644 index 7190b723a88..00000000000 --- a/aswb/sdkcompat/asdev/com/google/idea/blaze/android/run/runner/BlazeAndroidLaunchTasksProvider.java +++ /dev/null @@ -1,191 +0,0 @@ -/* - * Copyright 2022 The Bazel Authors. All rights reserved. - * - * 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. - */ -package com.google.idea.blaze.android.run.runner; - -import static com.android.tools.idea.profilers.AndroidProfilerLaunchTaskContributor.isProfilerLaunch; - -import com.android.ddmlib.IDevice; -import com.android.tools.deployer.ApkVerifierTracker; -import com.android.tools.idea.execution.common.debug.AndroidDebugger; -import com.android.tools.idea.execution.common.debug.AndroidDebuggerState; -import com.android.tools.idea.profilers.AndroidProfilerLaunchTaskContributor; -import com.android.tools.idea.run.ApkProvisionException; -import com.android.tools.idea.run.ApplicationIdProvider; -import com.android.tools.idea.run.LaunchOptions; -import com.android.tools.idea.run.blaze.BlazeLaunchTask; -import com.android.tools.idea.run.blaze.BlazeLaunchTaskWrapper; -import com.android.tools.idea.run.blaze.BlazeLaunchTasksProvider; -import com.android.tools.idea.run.tasks.ClearLogcatTask; -import com.android.tools.idea.run.tasks.ConnectDebuggerTask; -import com.android.tools.idea.run.tasks.DismissKeyguardTask; -import com.android.tools.idea.run.tasks.ShowLogcatTask; -import com.android.tools.ndk.run.editor.AutoAndroidDebuggerState; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.Lists; -import com.google.idea.blaze.android.run.binary.UserIdHelper; -import com.google.idea.blaze.android.run.deployinfo.BlazeAndroidDeployInfo; -import com.google.idea.common.experiments.BoolExperiment; -import com.intellij.execution.ExecutionException; -import com.intellij.openapi.diagnostic.Logger; -import com.intellij.openapi.project.Project; -import java.util.List; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -/** Normal launch tasks provider. #api4.1 */ -public class BlazeAndroidLaunchTasksProvider implements BlazeLaunchTasksProvider { - public static final String NATIVE_DEBUGGING_ENABLED = "NATIVE_DEBUGGING_ENABLED"; - private static final Logger LOG = Logger.getInstance(BlazeAndroidLaunchTasksProvider.class); - private static final BoolExperiment isLiveEditEnabled = - new BoolExperiment("aswb.live.edit.enabled", false); - - private final Project project; - private final BlazeAndroidRunContext runContext; - private final ApplicationIdProvider applicationIdProvider; - private final LaunchOptions.Builder launchOptionsBuilder; - - public BlazeAndroidLaunchTasksProvider( - Project project, - BlazeAndroidRunContext runContext, - ApplicationIdProvider applicationIdProvider, - LaunchOptions.Builder launchOptionsBuilder) { - this.project = project; - this.runContext = runContext; - this.applicationIdProvider = applicationIdProvider; - this.launchOptionsBuilder = launchOptionsBuilder; - } - - @NotNull - @Override - public List getTasks(@NotNull IDevice device) throws ExecutionException { - final List launchTasks = Lists.newArrayList(); - - String packageName; - try { - packageName = applicationIdProvider.getPackageName(); - } catch (ApkProvisionException e) { - throw new ExecutionException("Unable to determine application id: " + e); - } - - Integer userId = runContext.getUserId(device); - String userIdFlags = UserIdHelper.getFlagsFromUserId(userId); - String skipVerification = - ApkVerifierTracker.getSkipVerificationInstallationFlag(device, packageName); - String pmInstallOption; - if (skipVerification != null) { - pmInstallOption = userIdFlags + " " + skipVerification; - } else { - pmInstallOption = userIdFlags; - } - launchOptionsBuilder.setPmInstallOptions(d -> pmInstallOption); - - LaunchOptions launchOptions = launchOptionsBuilder.build(); - - // NOTE: Task for opening the profiler tool-window should come before deployment - // to ensure the tool-window opens correctly. This is required because starting - // the profiler session requires the tool-window to be open. - if (isProfilerLaunch(runContext.getExecutor())) { - launchTasks.add(new BlazeAndroidOpenProfilerWindowTask(project)); - } - - // TODO(kovalp): Check if there's any drawback to add these tasks with BlazeLaunchTaskWrapper - // since it's different with ag/21610897 - if (launchOptions.isClearLogcatBeforeStart()) { - launchTasks.add(new BlazeLaunchTaskWrapper(new ClearLogcatTask(project))); - } - - launchTasks.add(new BlazeLaunchTaskWrapper(new DismissKeyguardTask())); - - if (launchOptions.isDeploy()) { - ImmutableList deployTasks = runContext.getDeployTasks(device, launchOptions); - launchTasks.addAll(deployTasks); - } - - try { - if (launchOptions.isDebug()) { - launchTasks.add( - new CheckApkDebuggableTask(project, runContext.getBuildStep().getDeployInfo())); - } - - ImmutableList.Builder amStartOptions = ImmutableList.builder(); - amStartOptions.add(runContext.getAmStartOptions()); - if (isProfilerLaunch(runContext.getExecutor())) { - amStartOptions.add( - AndroidProfilerLaunchTaskContributor.getAmStartOptions( - project, - packageName, - runContext.getProfileState(), - device, - runContext.getExecutor())); - launchTasks.add( - new BlazeLaunchTaskWrapper( - new AndroidProfilerLaunchTaskContributor.AndroidProfilerToolWindowLaunchTask( - project, packageName))); - } - BlazeLaunchTask appLaunchTask = - runContext.getApplicationLaunchTask( - launchOptions, userId, String.join(" ", amStartOptions.build())); - if (appLaunchTask != null) { - launchTasks.add(appLaunchTask); - // TODO(arvindanekal): live edit api get changed and we cannot get apk here to create live - // edit, live edit team or Arvind need to fix this - } - } catch (ApkProvisionException e) { - throw new ExecutionException("Unable to determine application id: " + e); - } - - if (launchOptions.isOpenLogcatAutomatically()) { - launchTasks.add(new BlazeLaunchTaskWrapper(new ShowLogcatTask(project, packageName))); - } - - return ImmutableList.copyOf(launchTasks); - } - - @Override - @Nullable - public ConnectDebuggerTask getConnectDebuggerTask() { - LaunchOptions launchOptions = launchOptionsBuilder.build(); - if (!launchOptions.isDebug()) { - return null; - } - - BlazeAndroidDeployInfo deployInfo; - try { - deployInfo = runContext.getBuildStep().getDeployInfo(); - } catch (ApkProvisionException e) { - LOG.error(e); - deployInfo = null; - } - - BlazeAndroidDebuggerService debuggerService = BlazeAndroidDebuggerService.getInstance(project); - if (isNativeDebuggingEnabled(launchOptions)) { - AndroidDebugger debugger = debuggerService.getNativeDebugger(); - // The below state type should be AutoAndroidDebuggerState, but referencing it will crash the - // task if the NDK plugin is not loaded. - AndroidDebuggerState state = debugger.createState(); - debuggerService.configureNativeDebugger(state, deployInfo); - return runContext.getDebuggerTask(debugger, state); - } else { - AndroidDebugger debugger = debuggerService.getDebugger(); - return runContext.getDebuggerTask(debugger, debugger.createState()); - } - } - - private boolean isNativeDebuggingEnabled(LaunchOptions launchOptions) { - Object flag = launchOptions.getExtraOption(NATIVE_DEBUGGING_ENABLED); - return flag instanceof Boolean && (Boolean) flag; - } -} diff --git a/aswb/sdkcompat/asdev/com/google/idea/blaze/android/run/runner/BlazeAndroidOpenProfilerWindowTask.java b/aswb/sdkcompat/asdev/com/google/idea/blaze/android/run/runner/BlazeAndroidOpenProfilerWindowTask.java deleted file mode 100644 index b3941316668..00000000000 --- a/aswb/sdkcompat/asdev/com/google/idea/blaze/android/run/runner/BlazeAndroidOpenProfilerWindowTask.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (C) 2019 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. - */ -package com.google.idea.blaze.android.run.runner; - -import com.android.tools.idea.profilers.ProfilerProgramRunner; -import com.android.tools.idea.run.blaze.BlazeLaunchContext; -import com.android.tools.idea.run.blaze.BlazeLaunchTask; -import com.intellij.openapi.application.ApplicationManager; -import com.intellij.openapi.project.Project; - -/** Opens the profiler tool window. */ -public class BlazeAndroidOpenProfilerWindowTask implements BlazeLaunchTask { - private static final String ID = "OPEN_PROFILER_TOOLWINDOW"; - private final Project project; - - public BlazeAndroidOpenProfilerWindowTask(Project project) { - this.project = project; - } - - @Override - public void run(BlazeLaunchContext launchContext) { - ApplicationManager.getApplication() - .invokeLater(() -> ProfilerProgramRunner.createProfilerToolWindow(project, null)); - } -} diff --git a/aswb/sdkcompat/asdev/com/google/idea/blaze/android/run/runner/BlazeAndroidRunConfigurationRunner.java b/aswb/sdkcompat/asdev/com/google/idea/blaze/android/run/runner/BlazeAndroidRunConfigurationRunner.java deleted file mode 100644 index 78728d9c46f..00000000000 --- a/aswb/sdkcompat/asdev/com/google/idea/blaze/android/run/runner/BlazeAndroidRunConfigurationRunner.java +++ /dev/null @@ -1,327 +0,0 @@ -/* - * Copyright 2016 The Bazel Authors. All rights reserved. - * - * 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. - */ - -package com.google.idea.blaze.android.run.runner; - -import com.android.ddmlib.IDevice; -import com.android.tools.idea.execution.common.AppRunSettings; -import com.android.tools.idea.execution.common.ApplicationDeployer; -import com.android.tools.idea.execution.common.ComponentLaunchOptions; -import com.android.tools.idea.execution.common.DeployOptions; -import com.android.tools.idea.run.ApkProvider; -import com.android.tools.idea.run.ApplicationIdProvider; -import com.android.tools.idea.run.DeviceFutures; -import com.android.tools.idea.run.LaunchOptions; -import com.android.tools.idea.run.blaze.BlazeAndroidConfigurationExecutor; -import com.android.tools.idea.run.configuration.execution.AndroidComplicationConfigurationExecutor; -import com.android.tools.idea.run.configuration.execution.AndroidConfigurationExecutor; -import com.android.tools.idea.run.configuration.execution.AndroidConfigurationExecutorRunProfileState; -import com.android.tools.idea.run.configuration.execution.AndroidTileConfigurationExecutor; -import com.android.tools.idea.run.configuration.execution.AndroidWatchFaceConfigurationExecutor; -import com.android.tools.idea.run.configuration.execution.ComplicationLaunchOptions; -import com.android.tools.idea.run.configuration.execution.TileLaunchOptions; -import com.android.tools.idea.run.configuration.execution.WatchFaceLaunchOptions; -import com.android.tools.idea.run.editor.DeployTarget; -import com.android.tools.idea.run.editor.DeployTargetState; -import com.android.tools.idea.run.util.LaunchUtils; -import com.google.common.util.concurrent.Futures; -import com.google.common.util.concurrent.ListenableFuture; -import com.google.idea.blaze.android.run.binary.mobileinstall.MobileInstallBuildStep; -import com.google.idea.blaze.android.run.deployinfo.BlazeApkProviderService; -import com.google.idea.blaze.base.async.executor.ProgressiveTaskWithProgressIndicator; -import com.google.idea.blaze.base.command.BlazeInvocationContext.ContextType; -import com.google.idea.blaze.base.experiments.ExperimentScope; -import com.google.idea.blaze.base.issueparser.BlazeIssueParser; -import com.google.idea.blaze.base.model.primitives.WorkspaceRoot; -import com.google.idea.blaze.base.run.BlazeCommandRunConfiguration; -import com.google.idea.blaze.base.run.confighandler.BlazeCommandRunConfigurationRunner; -import com.google.idea.blaze.base.scope.BlazeContext; -import com.google.idea.blaze.base.scope.Scope; -import com.google.idea.blaze.base.scope.ScopedTask; -import com.google.idea.blaze.base.scope.output.IssueOutput; -import com.google.idea.blaze.base.scope.scopes.IdeaLogScope; -import com.google.idea.blaze.base.scope.scopes.ProblemsViewScope; -import com.google.idea.blaze.base.scope.scopes.ToolWindowScope; -import com.google.idea.blaze.base.settings.Blaze; -import com.google.idea.blaze.base.settings.BlazeUserSettings; -import com.google.idea.blaze.base.toolwindow.Task; -import com.intellij.execution.ExecutionException; -import com.intellij.execution.Executor; -import com.intellij.execution.configurations.RunProfileState; -import com.intellij.execution.executors.DefaultDebugExecutor; -import com.intellij.execution.runners.ExecutionEnvironment; -import com.intellij.execution.ui.ConsoleView; -import com.intellij.openapi.diagnostic.Logger; -import com.intellij.openapi.module.Module; -import com.intellij.openapi.project.Project; -import com.intellij.openapi.util.Key; -import java.util.Collections; -import java.util.concurrent.CancellationException; -import javax.annotation.Nullable; -import org.jetbrains.android.facet.AndroidFacet; -import org.jetbrains.android.util.AndroidBundle; -import org.jetbrains.annotations.NotNull; - -/** - * Supports the execution. Used by both android_binary and android_test. - * - *

Builds the APK and installs it, launches and debug tasks, etc. - * - *

Any indirection between android_binary/android_test, mobile-install, InstantRun etc. should - * come via the strategy class. - */ -public final class BlazeAndroidRunConfigurationRunner - implements BlazeCommandRunConfigurationRunner { - - private static final Logger LOG = Logger.getInstance(BlazeAndroidRunConfigurationRunner.class); - - private static final Key RUN_CONTEXT_KEY = - Key.create("blaze.run.context"); - public static final Key DEVICE_SESSION_KEY = - Key.create("blaze.device.session"); - - private final Module module; - private final BlazeAndroidRunContext runContext; - private final BlazeCommandRunConfiguration runConfig; - - public BlazeAndroidRunConfigurationRunner( - Module module, BlazeAndroidRunContext runContext, BlazeCommandRunConfiguration runConfig) { - this.module = module; - this.runContext = runContext; - this.runConfig = runConfig; - } - - @Override - @Nullable - public final RunProfileState getRunProfileState(final Executor executor, ExecutionEnvironment env) - throws ExecutionException { - - final AndroidFacet facet = AndroidFacet.getInstance(module); - assert facet != null : "Enforced by fatal validation check in createRunner."; - final Project project = env.getProject(); - - boolean isDebug = executor instanceof DefaultDebugExecutor; - - BlazeAndroidDeviceSelector deviceSelector = runContext.getDeviceSelector(); - BlazeAndroidDeviceSelector.DeviceSession deviceSession = - deviceSelector.getDevice(project, executor, env, isDebug, runConfig.getUniqueID()); - - if (deviceSession == null) { - return null; - } - - DeployTarget deployTarget = deviceSession.deployTarget; - if (deployTarget != null && deployTarget.hasCustomRunProfileState(executor)) { - return deployTarget.getRunProfileState(executor, env, DeployTargetState.DEFAULT_STATE); - } - - DeviceFutures deviceFutures = deviceSession.deviceFutures; - if (deviceFutures == null) { - // The user deliberately canceled, or some error was encountered and exposed by the chooser. - // Quietly exit. - return null; - } - - if (deviceFutures.get().isEmpty()) { - throw new ExecutionException(AndroidBundle.message("deployment.target.not.found")); - } - - if (isDebug) { - String error = canDebug(deviceFutures, facet, module.getName()); - if (error != null) { - throw new ExecutionException(error); - } - } - - LaunchOptions.Builder launchOptionsBuilder = getDefaultLaunchOptions().setDebug(isDebug); - runContext.augmentLaunchOptions(launchOptionsBuilder); - - // Store the run context on the execution environment so before-run tasks can access it. - env.putCopyableUserData(RUN_CONTEXT_KEY, runContext); - env.putCopyableUserData(DEVICE_SESSION_KEY, deviceSession); - - BlazeAndroidConfigurationExecutor runner = - new BlazeAndroidConfigurationExecutor( - runContext.getConsoleProvider(), - runContext.getApplicationIdProvider(), - env, - deviceFutures, - runContext.getLaunchTasksProvider(launchOptionsBuilder), - LaunchOptions.builder().build()); - return new AndroidConfigurationExecutorRunProfileState(runner); - } - - private RunProfileState getWearExecutor( - ComponentLaunchOptions launchOptions, ExecutionEnvironment env, DeployTarget deployTarget) - throws ExecutionException { - - AppRunSettings settings = - new AppRunSettings() { - @NotNull - @Override - public DeployOptions getDeployOptions() { - return new DeployOptions(Collections.emptyList(), "", true, true); - } - - @NotNull - @Override - public ComponentLaunchOptions getComponentLaunchOptions() { - return launchOptions; - } - - @Override - public Module getModule() { - return runConfig.getModules()[0]; - } - }; - - AndroidConfigurationExecutor configurationExecutor; - ApplicationIdProvider appIdProvider = runContext.getApplicationIdProvider(); - ApkProvider apkProvider = - BlazeApkProviderService.getInstance() - .getApkProvider(env.getProject(), runContext.getBuildStep()); - DeviceFutures deviceFutures = deployTarget.getDevices(env.getProject()); - - if (launchOptions instanceof TileLaunchOptions) { - configurationExecutor = - new AndroidTileConfigurationExecutor( - env, deviceFutures, settings, appIdProvider, apkProvider) { - @NotNull - @Override - public ApplicationDeployer getApplicationDeployer(@NotNull ConsoleView console) - throws ExecutionException { - if (runContext.getBuildStep() instanceof MobileInstallBuildStep) { - return new MobileInstallApplicationDeployer(console); - } - return super.getApplicationDeployer(console); - } - }; - } else if (launchOptions instanceof WatchFaceLaunchOptions) { - configurationExecutor = - new AndroidWatchFaceConfigurationExecutor( - env, deviceFutures, settings, appIdProvider, apkProvider) { - @NotNull - @Override - public ApplicationDeployer getApplicationDeployer(@NotNull ConsoleView console) - throws ExecutionException { - if (runContext.getBuildStep() instanceof MobileInstallBuildStep) { - return new MobileInstallApplicationDeployer(console); - } - return super.getApplicationDeployer(console); - } - }; - } else if (launchOptions instanceof ComplicationLaunchOptions) { - configurationExecutor = - new AndroidComplicationConfigurationExecutor( - env, deviceFutures, settings, appIdProvider, apkProvider) { - @NotNull - @Override - public ApplicationDeployer getApplicationDeployer(@NotNull ConsoleView console) - throws ExecutionException { - if (runContext.getBuildStep() instanceof MobileInstallBuildStep) { - return new MobileInstallApplicationDeployer(console); - } - return super.getApplicationDeployer(console); - } - }; - } else { - throw new RuntimeException("Unknown launch options " + launchOptions.getClass().getName()); - } - - return new AndroidConfigurationExecutorRunProfileState( - new BlazeWrapperForAndroidConfigurationExecutor(configurationExecutor)); - } - - @Nullable - private static String canDebug( - DeviceFutures deviceFutures, AndroidFacet facet, String moduleName) { - // If we are debugging on a device, then the app needs to be debuggable - for (ListenableFuture future : deviceFutures.get()) { - if (!future.isDone()) { - // this is an emulator, and we assume that all emulators are debuggable - continue; - } - IDevice device = Futures.getUnchecked(future); - if (!LaunchUtils.canDebugAppOnDevice(facet, device)) { - return AndroidBundle.message( - "android.cannot.debug.noDebugPermissions", moduleName, device.getName()); - } - } - return null; - } - - private static LaunchOptions.Builder getDefaultLaunchOptions() { - return LaunchOptionsCompat.getDefaultLaunchOptions(); - } - - @Override - public boolean executeBeforeRunTask(ExecutionEnvironment env) { - final Project project = env.getProject(); - BlazeUserSettings settings = BlazeUserSettings.getInstance(); - return Scope.root( - context -> { - context - .push(new ProblemsViewScope(project, settings.getShowProblemsViewOnRun())) - .push(new ExperimentScope()) - .push( - new ToolWindowScope.Builder( - project, new Task(project, "Build apk", Task.Type.BEFORE_LAUNCH)) - .setPopupBehavior(settings.getShowBlazeConsoleOnRun()) - .setIssueParsers( - BlazeIssueParser.defaultIssueParsers( - project, - WorkspaceRoot.fromProject(project), - ContextType.BeforeRunTask)) - .build()) - .push(new IdeaLogScope()); - - BlazeAndroidRunContext runContext = env.getCopyableUserData(RUN_CONTEXT_KEY); - if (runContext == null) { - IssueOutput.error("Could not find run context. Please try again").submit(context); - return false; - } - BlazeAndroidDeviceSelector.DeviceSession deviceSession = - env.getCopyableUserData(DEVICE_SESSION_KEY); - - ApkBuildStep buildStep = runContext.getBuildStep(); - ScopedTask buildTask = - new ScopedTask(context) { - @Override - protected Void execute(BlazeContext context) { - buildStep.build(context, deviceSession); - return null; - } - }; - - try { - ListenableFuture buildFuture = - ProgressiveTaskWithProgressIndicator.builder( - project, - String.format("Executing %s apk build", Blaze.buildSystemName(project))) - .submitTaskWithResult(buildTask); - Futures.getChecked(buildFuture, ExecutionException.class); - } catch (ExecutionException e) { - context.setHasError(); - } catch (CancellationException e) { - context.setCancelled(); - } catch (Exception e) { - LOG.error(e); - return false; - } - return context.shouldContinue(); - }); - } -} diff --git a/aswb/sdkcompat/asdev/com/google/idea/blaze/android/run/runner/BlazeAndroidRunContext.java b/aswb/sdkcompat/asdev/com/google/idea/blaze/android/run/runner/BlazeAndroidRunContext.java deleted file mode 100644 index c1e33020bae..00000000000 --- a/aswb/sdkcompat/asdev/com/google/idea/blaze/android/run/runner/BlazeAndroidRunContext.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright 2016 The Bazel Authors. All rights reserved. - * - * 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. - */ -package com.google.idea.blaze.android.run.runner; - -import com.android.ddmlib.IDevice; -import com.android.tools.idea.execution.common.debug.AndroidDebugger; -import com.android.tools.idea.execution.common.debug.AndroidDebuggerState; -import com.android.tools.idea.run.ApplicationIdProvider; -import com.android.tools.idea.run.ConsoleProvider; -import com.android.tools.idea.run.LaunchOptions; -import com.android.tools.idea.run.blaze.BlazeLaunchTask; -import com.android.tools.idea.run.blaze.BlazeLaunchTasksProvider; -import com.android.tools.idea.run.editor.ProfilerState; -import com.android.tools.idea.run.tasks.ConnectDebuggerTask; -import com.google.common.collect.ImmutableList; -import com.intellij.execution.ExecutionException; -import com.intellij.execution.Executor; -import javax.annotation.Nullable; -import org.jetbrains.annotations.NotNull; - -/** Instantiated when the configuration wants to run. */ -public interface BlazeAndroidRunContext { - - BlazeAndroidDeviceSelector getDeviceSelector(); - - void augmentLaunchOptions(LaunchOptions.Builder options); - - ConsoleProvider getConsoleProvider(); - - ApkBuildStep getBuildStep(); - - ApplicationIdProvider getApplicationIdProvider() throws ExecutionException; - - BlazeLaunchTasksProvider getLaunchTasksProvider(LaunchOptions.Builder launchOptionsBuilder) - throws ExecutionException; - - /** Returns the tasks to deploy the application. */ - ImmutableList getDeployTasks(IDevice device, LaunchOptions launchOptions) - throws ExecutionException; - - /** Returns the task to launch the application. */ - @Nullable - BlazeLaunchTask getApplicationLaunchTask( - LaunchOptions launchOptions, - @Nullable Integer userId, - @NotNull String contributorsAmStartOptions) - throws ExecutionException; - - /** Returns the task to connect the debugger. */ - @Nullable - ConnectDebuggerTask getDebuggerTask( - AndroidDebugger androidDebugger, AndroidDebuggerState androidDebuggerState); - - @Nullable - Integer getUserId(IDevice device) throws ExecutionException; - - String getAmStartOptions(); - - Executor getExecutor(); - - ProfilerState getProfileState(); -} diff --git a/aswb/sdkcompat/asdev/com/google/idea/blaze/android/run/runner/BlazeWrapperForAndroidConfigurationExecutor.java b/aswb/sdkcompat/asdev/com/google/idea/blaze/android/run/runner/BlazeWrapperForAndroidConfigurationExecutor.java deleted file mode 100644 index be6f1f8552c..00000000000 --- a/aswb/sdkcompat/asdev/com/google/idea/blaze/android/run/runner/BlazeWrapperForAndroidConfigurationExecutor.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright (C) 2022 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. - */ -package com.google.idea.blaze.android.run.runner; - -import com.android.tools.idea.run.DeviceFutures; -import com.android.tools.idea.run.configuration.execution.AndroidConfigurationExecutor; -import com.intellij.execution.ExecutionException; -import com.intellij.execution.configurations.RunConfiguration; -import com.intellij.execution.ui.RunContentDescriptor; -import com.intellij.openapi.progress.ProgressIndicator; -import org.jetbrains.annotations.NotNull; - -/** Implementation of {@code AndroidConfigurationExecutor} specific for Blaze project. */ -public class BlazeWrapperForAndroidConfigurationExecutor implements AndroidConfigurationExecutor { - private final AndroidConfigurationExecutor delegateExecutor; - - BlazeWrapperForAndroidConfigurationExecutor(@NotNull AndroidConfigurationExecutor executor) { - delegateExecutor = executor; - } - - @NotNull - @Override - public RunConfiguration getConfiguration() { - return delegateExecutor.getConfiguration(); - } - - @NotNull - @Override - public DeviceFutures getDeviceFutures() { - return delegateExecutor.getDeviceFutures(); - } - - @NotNull - @Override - public RunContentDescriptor run(@NotNull ProgressIndicator indicator) throws ExecutionException { - return delegateExecutor.run(indicator); - } - - @NotNull - @Override - public RunContentDescriptor debug(@NotNull ProgressIndicator indicator) - throws ExecutionException { - return delegateExecutor.debug(indicator); - } - - @NotNull - @Override - public RunContentDescriptor applyChanges(@NotNull ProgressIndicator indicator) { - throw new RuntimeException("Apply code changes is not supported for blaze"); - } - - @NotNull - @Override - public RunContentDescriptor applyCodeChanges(@NotNull ProgressIndicator indicator) { - throw new RuntimeException("Apply changes is not supported for blaze"); - } -} diff --git a/aswb/sdkcompat/asdev/com/google/idea/blaze/android/run/runner/CheckApkDebuggableTask.java b/aswb/sdkcompat/asdev/com/google/idea/blaze/android/run/runner/CheckApkDebuggableTask.java deleted file mode 100644 index 748734ce06b..00000000000 --- a/aswb/sdkcompat/asdev/com/google/idea/blaze/android/run/runner/CheckApkDebuggableTask.java +++ /dev/null @@ -1,139 +0,0 @@ -/* - * Copyright 2020 The Bazel Authors. All rights reserved. - * - * 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. - */ -package com.google.idea.blaze.android.run.runner; - -import static com.google.common.collect.ImmutableList.toImmutableList; - -import com.android.ddmlib.IDevice; -import com.android.tools.idea.execution.common.RunConfigurationNotifier; -import com.android.tools.idea.run.blaze.BlazeLaunchContext; -import com.android.tools.idea.run.blaze.BlazeLaunchTask; -import com.google.common.annotations.VisibleForTesting; -import com.google.common.collect.ImmutableList; -import com.google.devrel.gmscore.tools.apk.arsc.BinaryResourceFile; -import com.google.devrel.gmscore.tools.apk.arsc.Chunk; -import com.google.devrel.gmscore.tools.apk.arsc.XmlAttribute; -import com.google.devrel.gmscore.tools.apk.arsc.XmlChunk; -import com.google.devrel.gmscore.tools.apk.arsc.XmlStartElementChunk; -import com.google.idea.blaze.android.run.deployinfo.BlazeAndroidDeployInfo; -import com.intellij.execution.ExecutionException; -import com.intellij.openapi.project.Project; -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.util.List; -import java.util.zip.ZipFile; -import org.jetbrains.annotations.NotNull; - -/** Checks APKs to see if they are debuggable and warn the user if they aren't. */ -public class CheckApkDebuggableTask implements BlazeLaunchTask { - private static final String ID = "APK_DEBUGGABILITY_CHECKER"; - private final BlazeAndroidDeployInfo deployInfo; - - public CheckApkDebuggableTask(Project project, BlazeAndroidDeployInfo deployInfo) { - this.deployInfo = deployInfo; - } - - @Override - public void run(@NotNull BlazeLaunchContext launchContext) throws ExecutionException { - checkApkDebuggableTaskDelegate( - launchContext.getEnv().getProject(), deployInfo, launchContext.getDevice()); - } - - /** - * Checks if all APKs in the deploy info are debuggable and output an error message to console if - * any of them aren't. This check doesn't apply if the target device is a running a debug build - * android (e.g. userdebug build) and will simply return. - */ - @VisibleForTesting - public static void checkApkDebuggableTaskDelegate( - Project project, BlazeAndroidDeployInfo deployInfo, IDevice device) - throws ExecutionException { - if (isDebugDevice(device)) { - return; - } - try { - ImmutableList nonDebuggableApkNames = - getNonDebuggableDeployApks(deployInfo).stream() - .map(File::getName) - .collect(toImmutableList()); - if (nonDebuggableApkNames.isEmpty()) { - return; - } - // Use "and" as delimiter because there won't be more than 2 APKs, so "and" makes more sense. - String message = - "The \"android:debuggable\" attribute is not set to \"true\" in " - + String.join(" and ", nonDebuggableApkNames) - + ". Debugger may not attach properly or attach at all." - + " Please ensure \"android:debuggable\" attribute is set to true or" - + " overridden to true via manifest overrides."; - RunConfigurationNotifier.INSTANCE.notifyWarning(project, "", message); - } catch (IOException e) { - throw new ExecutionException("Could not read deploy apks: " + e.getMessage()); - } - } - - private static ImmutableList getNonDebuggableDeployApks(BlazeAndroidDeployInfo deployInfo) - throws IOException { - ImmutableList.Builder nonDebuggableApks = ImmutableList.builder(); - for (File apk : deployInfo.getApksToDeploy()) { - if (!isApkDebuggable(apk)) { - nonDebuggableApks.add(apk); - } - } - return nonDebuggableApks.build(); - } - - /** Returns true if the device is a debug build device. */ - private static boolean isDebugDevice(IDevice device) { - String roDebuggable = device.getProperty("ro.debuggable"); - return (roDebuggable != null && roDebuggable.equals("1")); - } - - @VisibleForTesting - public static boolean isApkDebuggable(File apk) throws IOException { - try (ZipFile zipFile = new ZipFile(apk); - InputStream stream = zipFile.getInputStream(zipFile.getEntry("AndroidManifest.xml"))) { - BinaryResourceFile file = BinaryResourceFile.fromInputStream(stream); - List chunks = file.getChunks(); - - if (chunks.isEmpty()) { - throw new IllegalArgumentException("Invalid APK, empty manifest"); - } - - if (!(chunks.get(0) instanceof XmlChunk)) { - throw new IllegalArgumentException("APK manifest chunk[0] != XmlChunk"); - } - - XmlChunk xmlChunk = (XmlChunk) chunks.get(0); - for (Chunk chunk : xmlChunk.getChunks().values()) { - if (!(chunk instanceof XmlStartElementChunk)) { - continue; - } - - XmlStartElementChunk startChunk = (XmlStartElementChunk) chunk; - if (startChunk.getName().equals("application")) { - for (XmlAttribute attribute : startChunk.getAttributes()) { - if (attribute.name().equals("debuggable")) { - return true; - } - } - } - } - } - return false; - } -} diff --git a/aswb/sdkcompat/asdev/com/google/idea/blaze/android/run/runner/LaunchOptionsCompat.java b/aswb/sdkcompat/asdev/com/google/idea/blaze/android/run/runner/LaunchOptionsCompat.java deleted file mode 100644 index 5a606a8a2ea..00000000000 --- a/aswb/sdkcompat/asdev/com/google/idea/blaze/android/run/runner/LaunchOptionsCompat.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright 2022 The Bazel Authors. All rights reserved. - * - * 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. - */ -package com.google.idea.blaze.android.run.runner; - -import com.android.tools.idea.run.LaunchOptions; - -/** Compat class for LunchOptions.Builder. */ -public class LaunchOptionsCompat { - - private LaunchOptionsCompat() {} - - /** Create default launch options to maintain compatibility with #api211. */ - public static LaunchOptions.Builder getDefaultLaunchOptions() { - return LaunchOptions.builder().setClearLogcatBeforeStart(false); - } -} diff --git a/aswb/sdkcompat/asdev/com/google/idea/blaze/android/run/runner/MobileInstallApplicationDeployer.java b/aswb/sdkcompat/asdev/com/google/idea/blaze/android/run/runner/MobileInstallApplicationDeployer.java deleted file mode 100644 index dad762309be..00000000000 --- a/aswb/sdkcompat/asdev/com/google/idea/blaze/android/run/runner/MobileInstallApplicationDeployer.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright (C) 2022 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. - */ -package com.google.idea.blaze.android.run.runner; - -import com.android.ddmlib.IDevice; -import com.android.tools.deployer.ApkParser; -import com.android.tools.deployer.Deployer; -import com.android.tools.deployer.DeployerException; -import com.android.tools.deployer.model.Apk; -import com.android.tools.deployer.model.App; -import com.android.tools.idea.execution.common.ApplicationDeployer; -import com.android.tools.idea.execution.common.DeployOptions; -import com.android.tools.idea.run.ApkFileUnit; -import com.android.tools.idea.run.ApkInfo; -import com.android.tools.idea.run.configuration.execution.AdbCommandCaptureLoggerWithConsole; -import com.intellij.execution.ui.ConsoleView; -import com.intellij.openapi.diagnostic.Logger; -import com.intellij.openapi.progress.ProgressIndicator; -import java.nio.file.Path; -import java.util.List; -import java.util.stream.Collectors; -import org.jetbrains.annotations.NotNull; - -/** Deploys mobile install application. */ -public class MobileInstallApplicationDeployer implements ApplicationDeployer { - private static final Logger LOG = Logger.getInstance(MobileInstallApplicationDeployer.class); - private final ConsoleView myConsole; - - public MobileInstallApplicationDeployer(ConsoleView console) { - myConsole = console; - } - - @NotNull - @Override - public Deployer.Result fullDeploy( - @NotNull IDevice device, - @NotNull ApkInfo apkInfo, - @NotNull DeployOptions deployOptions, - ProgressIndicator indicator) - throws DeployerException { - final List apkPaths = - apkInfo.getFiles().stream() - .map(ApkFileUnit::getApkPath) - .map(Path::toString) - .collect(Collectors.toList()); - final List apks = new ApkParser().parsePaths(apkPaths); - App app = - new App( - apkInfo.getApplicationId(), - apks, - device, - new AdbCommandCaptureLoggerWithConsole(LOG, myConsole)); - return new Deployer.Result(false, false, false, app); - } - - @NotNull - @Override - public Deployer.Result applyChangesDeploy( - @NotNull IDevice device, - @NotNull ApkInfo app, - @NotNull DeployOptions deployOptions, - ProgressIndicator indicator) - throws DeployerException { - throw new RuntimeException("Apply changes is not supported for mobile-install"); - } - - @NotNull - @Override - public Deployer.Result applyCodeChangesDeploy( - @NotNull IDevice device, - @NotNull ApkInfo app, - @NotNull DeployOptions deployOptions, - ProgressIndicator indicator) - throws DeployerException { - throw new RuntimeException("Apply code changes is not supported for mobile-install"); - } -} diff --git a/aswb/sdkcompat/asdev/com/google/idea/blaze/android/run/test/BlazeAndroidTestLaunchTask.java b/aswb/sdkcompat/asdev/com/google/idea/blaze/android/run/test/BlazeAndroidTestLaunchTask.java deleted file mode 100644 index dc7dd974c06..00000000000 --- a/aswb/sdkcompat/asdev/com/google/idea/blaze/android/run/test/BlazeAndroidTestLaunchTask.java +++ /dev/null @@ -1,265 +0,0 @@ -/* - * Copyright 2016 The Bazel Authors. All rights reserved. - * - * 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. - */ -package com.google.idea.blaze.android.run.test; - -import com.android.tools.idea.run.blaze.BlazeLaunchContext; -import com.android.tools.idea.run.blaze.BlazeLaunchTask; -import com.android.tools.idea.run.configuration.execution.ExecutionUtils; -import com.google.common.util.concurrent.ListenableFuture; -import com.google.idea.blaze.base.async.executor.BlazeExecutor; -import com.google.idea.blaze.base.async.process.ExternalTask; -import com.google.idea.blaze.base.async.process.LineProcessingOutputStream; -import com.google.idea.blaze.base.command.BlazeCommand; -import com.google.idea.blaze.base.command.BlazeCommandName; -import com.google.idea.blaze.base.command.BlazeFlags; -import com.google.idea.blaze.base.command.buildresult.BuildResultHelper; -import com.google.idea.blaze.base.command.buildresult.BuildResultHelper.GetArtifactsException; -import com.google.idea.blaze.base.command.buildresult.BuildResultHelperBep; -import com.google.idea.blaze.base.filecache.FileCaches; -import com.google.idea.blaze.base.ideinfo.AndroidInstrumentationInfo; -import com.google.idea.blaze.base.ideinfo.TargetIdeInfo; -import com.google.idea.blaze.base.ideinfo.TargetKey; -import com.google.idea.blaze.base.model.BlazeProjectData; -import com.google.idea.blaze.base.model.primitives.Label; -import com.google.idea.blaze.base.model.primitives.WorkspaceRoot; -import com.google.idea.blaze.base.projectview.ProjectViewManager; -import com.google.idea.blaze.base.projectview.ProjectViewSet; -import com.google.idea.blaze.base.run.testlogs.BlazeTestResultHolder; -import com.google.idea.blaze.base.scope.Scope; -import com.google.idea.blaze.base.scope.output.IssueOutput; -import com.google.idea.blaze.base.settings.Blaze; -import com.google.idea.blaze.base.sync.aspects.BlazeBuildOutputs; -import com.google.idea.blaze.base.sync.aspects.BuildResult; -import com.google.idea.blaze.base.sync.data.BlazeProjectDataManager; -import com.google.idea.blaze.base.util.SaveUtil; -import com.google.idea.blaze.java.AndroidBlazeRules.RuleTypes; -import com.intellij.execution.process.ProcessAdapter; -import com.intellij.execution.process.ProcessEvent; -import com.intellij.execution.process.ProcessHandler; -import com.intellij.execution.ui.ConsoleView; -import com.intellij.openapi.diagnostic.Logger; -import com.intellij.openapi.project.Project; -import java.util.List; -import java.util.Optional; -import java.util.concurrent.ExecutionException; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.ide.PooledThreadExecutor; - -/** - * An Android application launcher that invokes `blaze test` on an android_test target, and sets up - * process handling and debugging for the test run. - */ -public class BlazeAndroidTestLaunchTask implements BlazeLaunchTask { - private static final String ID = "BLAZE_ANDROID_TEST"; - - // Uses a local device/emulator attached to adb to run an android_test. - public static final String TEST_LOCAL_DEVICE = - BlazeFlags.TEST_ARG + "--device_broker_type=LOCAL_ADB_SERVER"; - // Uses a local device/emulator attached to adb to run an android_test. - public static final String TEST_DEBUG = BlazeFlags.TEST_ARG + "--enable_debug"; - // Specifies the serial number for a local test device. - private static final String TEST_DEVICE_SERIAL = "--device_serial_number="; - private static final Logger LOG = Logger.getInstance(BlazeAndroidTestLaunchTask.class); - - private final Project project; - private final Label target; - private final List buildFlags; - private final BlazeAndroidTestFilter testFilter; - private final BlazeTestResultHolder testResultsHolder; - - private ListenableFuture blazeResult; - - private final BlazeAndroidTestRunContext runContext; - - private final boolean debug; - - public BlazeAndroidTestLaunchTask( - Project project, - Label target, - List buildFlags, - BlazeAndroidTestFilter testFilter, - BlazeAndroidTestRunContext runContext, - boolean debug, - BlazeTestResultHolder testResultsHolder) { - this.project = project; - this.target = target; - this.buildFlags = buildFlags; - this.testFilter = testFilter; - this.runContext = runContext; - this.debug = debug; - this.testResultsHolder = testResultsHolder; - } - - @Override - public void run(@NotNull BlazeLaunchContext launchContext) - throws com.intellij.execution.ExecutionException { - BlazeExecutor blazeExecutor = BlazeExecutor.getInstance(); - - final ProcessHandler processHandler = launchContext.getProcessHandler(); - - blazeResult = - blazeExecutor.submit( - () -> - Scope.root( - context -> { - SaveUtil.saveAllFiles(); - - ProjectViewSet projectViewSet = - ProjectViewManager.getInstance(project).getProjectViewSet(); - if (projectViewSet == null) { - IssueOutput.error("Could not load project view. Please resync project.") - .submit(context); - return false; - } - - BlazeProjectData projectData = - BlazeProjectDataManager.getInstance(project).getBlazeProjectData(); - TargetIdeInfo targetInfo = - projectData.getTargetMap().get(TargetKey.forPlainTarget(target)); - if (targetInfo == null - || targetInfo.getKind() - != RuleTypes.ANDROID_INSTRUMENTATION_TEST.getKind()) { - IssueOutput.error( - "Unable to identify target \"" - + target - + "\". If this is a newly added target, please sync the" - + " project and try again.") - .submit(context); - return null; - } - AndroidInstrumentationInfo testInstrumentationInfo = - targetInfo.getAndroidInstrumentationInfo(); - if (testInstrumentationInfo == null) { - IssueOutput.error( - "Required target data missing for \"" - + target - + "\". Has the target definition changed recently? Please" - + " sync the project and try again.") - .submit(context); - return null; - } - - BlazeCommand.Builder commandBuilder = - BlazeCommand.builder( - Blaze.getBuildSystemProvider(project) - .getBuildSystem() - .getBuildInvoker(project, context), - BlazeCommandName.TEST) - .addTargets(target); - // Build flags must match BlazeBeforeRunTask. - commandBuilder.addBlazeFlags(buildFlags); - - // Run the test on the selected local device/emulator if no target device is - // specified. - Label targetDevice = testInstrumentationInfo.getTargetDevice(); - if (targetDevice == null) { - commandBuilder - .addBlazeFlags(TEST_LOCAL_DEVICE, BlazeFlags.TEST_OUTPUT_STREAMED) - .addBlazeFlags( - testDeviceSerialFlags(launchContext.getDevice().getSerialNumber())) - .addBlazeFlags(testFilter.getBlazeFlags()); - } - - if (debug) { - commandBuilder.addBlazeFlags(TEST_DEBUG, BlazeFlags.NO_CACHE_TEST_RESULTS); - } - - ConsoleView console = launchContext.getConsoleView(); - LineProcessingOutputStream.LineProcessor stdoutLineProcessor = - line -> { - ExecutionUtils.println(console, line); - return true; - }; - LineProcessingOutputStream.LineProcessor stderrLineProcessor = - line -> { - ExecutionUtils.println(console, line); - return true; - }; - - ExecutionUtils.println( - console, - String.format("Starting %s test...\n", Blaze.buildSystemName(project))); - - int retVal; - try (BuildResultHelper buildResultHelper = new BuildResultHelperBep()) { - commandBuilder.addBlazeFlags(buildResultHelper.getBuildFlags()); - BlazeCommand command = commandBuilder.build(); - ExecutionUtils.println(console, command + "\n"); - - retVal = - ExternalTask.builder(WorkspaceRoot.fromProject(project)) - .addBlazeCommand(command) - .context(context) - .stdout(LineProcessingOutputStream.of(stdoutLineProcessor)) - .stderr(LineProcessingOutputStream.of(stderrLineProcessor)) - .build() - .run(); - - if (retVal != 0) { - context.setHasError(); - } else { - testResultsHolder.setTestResults( - buildResultHelper.getTestResults(Optional.empty())); - } - ListenableFuture unusedFuture = - FileCaches.refresh( - project, - context, - BlazeBuildOutputs.noOutputs(BuildResult.fromExitCode(retVal))); - } catch (GetArtifactsException e) { - LOG.error(e.getMessage()); - } - return !context.hasErrors(); - })); - - blazeResult.addListener(runContext::onLaunchTaskComplete, PooledThreadExecutor.INSTANCE); - - // The debug case is set up in ConnectBlazeTestDebuggerTask - if (!debug) { - waitAndSetUpForKillingBlazeOnStop(processHandler); - } - } - - /** - * Hooks up the Blaze process to be killed if the user hits the 'Stop' button, then waits for the - * Blaze process to stop. In non-debug mode, we wait for test execution to finish before returning - * from launch() (this matches the behavior of the stock ddmlib runner). - */ - @SuppressWarnings("Interruption") - private void waitAndSetUpForKillingBlazeOnStop(@NotNull final ProcessHandler processHandler) { - processHandler.addProcessListener( - new ProcessAdapter() { - @Override - public void processWillTerminate(ProcessEvent event, boolean willBeDestroyed) { - blazeResult.cancel(true /* mayInterruptIfRunning */); - } - }); - - try { - blazeResult.get(); - } catch (InterruptedException e) { - // We've been interrupted - cancel the underlying Blaze process. - blazeResult.cancel(true /* mayInterruptIfRunning */); - } catch (ExecutionException e) { - LOG.error(e); - } - } - - @NotNull - private static String testDeviceSerialFlags(@NotNull String serial) { - return BlazeFlags.TEST_ARG + TEST_DEVICE_SERIAL + serial; - } -} diff --git a/aswb/sdkcompat/asdev/com/google/idea/blaze/android/run/test/BlazeAndroidTestProgramRunner.java b/aswb/sdkcompat/asdev/com/google/idea/blaze/android/run/test/BlazeAndroidTestProgramRunner.java deleted file mode 100644 index eab7b24890f..00000000000 --- a/aswb/sdkcompat/asdev/com/google/idea/blaze/android/run/test/BlazeAndroidTestProgramRunner.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright 2018 The Bazel Authors. All rights reserved. - * - * 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. - */ -package com.google.idea.blaze.android.run.test; - -import com.android.tools.idea.run.configuration.AndroidConfigurationProgramRunner; -import com.android.tools.idea.run.configuration.execution.AndroidConfigurationExecutor; -import com.google.idea.blaze.android.run.BlazeAndroidRunConfigurationHandler; -import com.google.idea.blaze.base.run.BlazeCommandRunConfiguration; -import com.google.idea.blaze.base.run.BlazeCommandRunConfigurationType; -import com.intellij.execution.ExecutionException; -import com.intellij.execution.configurations.RunProfile; -import com.intellij.execution.configurations.RunProfileState; -import com.intellij.execution.executors.DefaultDebugExecutor; -import com.intellij.execution.executors.DefaultRunExecutor; -import com.intellij.execution.runners.ExecutionEnvironment; -import com.intellij.execution.ui.RunContentDescriptor; -import com.intellij.openapi.progress.ProgressIndicator; -import java.util.Collections; -import java.util.List; -import org.jetbrains.annotations.NotNull; - -/** Program runner for configurations from {@link BlazeAndroidTestRunConfigurationHandler}. */ -public class BlazeAndroidTestProgramRunner extends AndroidConfigurationProgramRunner { - @Override - public boolean canRun(String executorId, RunProfile profile) { - BlazeAndroidRunConfigurationHandler handler = - BlazeAndroidRunConfigurationHandler.getHandlerFrom(profile); - if (!(handler instanceof BlazeAndroidTestRunConfigurationHandler)) { - return false; - } - if (!(profile instanceof BlazeCommandRunConfiguration)) { - return false; - } - return DefaultRunExecutor.EXECUTOR_ID.equals(executorId) - || DefaultDebugExecutor.EXECUTOR_ID.equals(executorId); - } - - @Override - public String getRunnerId() { - return "AndroidTestProgramRunner"; - } - - @Override - protected boolean canRunWithMultipleDevices(@NotNull String executorId) { - return true; - } - - @NotNull - @Override - protected List getSupportedConfigurationTypeIds() { - return Collections.singletonList(BlazeCommandRunConfigurationType.getInstance().getId()); - } - - @NotNull - @Override - protected RunContentDescriptor run( - @NotNull ExecutionEnvironment environment, - @NotNull RunProfileState state, - @NotNull ProgressIndicator indicator) - throws ExecutionException { - final AndroidConfigurationExecutor state1 = (AndroidConfigurationExecutor) state; - if (DefaultDebugExecutor.EXECUTOR_ID.equals(environment.getExecutor().getId())) { - return state1.debug(indicator); - } - if (DefaultRunExecutor.EXECUTOR_ID.equals(environment.getExecutor().getId())) { - return state1.run(indicator); - } - throw new RuntimeException("Unsupported executor"); - } -} diff --git a/aswb/sdkcompat/asdev/com/google/idea/blaze/android/run/test/BlazeAndroidTestRunConfigurationHandler.java b/aswb/sdkcompat/asdev/com/google/idea/blaze/android/run/test/BlazeAndroidTestRunConfigurationHandler.java deleted file mode 100644 index 050ddc03fee..00000000000 --- a/aswb/sdkcompat/asdev/com/google/idea/blaze/android/run/test/BlazeAndroidTestRunConfigurationHandler.java +++ /dev/null @@ -1,224 +0,0 @@ -/* - * Copyright 2016 The Bazel Authors. All rights reserved. - * - * 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. - */ -package com.google.idea.blaze.android.run.test; - -import static com.android.tools.idea.run.deployment.DeviceAndSnapshotComboBoxAction.DEPLOYS_TO_LOCAL_DEVICE; - -import com.android.tools.idea.run.ValidationError; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.Lists; -import com.google.idea.blaze.android.run.ApkBuildStepProvider; -import com.google.idea.blaze.android.run.BlazeAndroidRunConfigurationCommonState; -import com.google.idea.blaze.android.run.BlazeAndroidRunConfigurationHandler; -import com.google.idea.blaze.android.run.BlazeAndroidRunConfigurationValidationUtil; -import com.google.idea.blaze.android.run.LaunchMetrics; -import com.google.idea.blaze.android.run.runner.ApkBuildStep; -import com.google.idea.blaze.android.run.runner.BlazeAndroidRunConfigurationRunner; -import com.google.idea.blaze.android.run.runner.BlazeAndroidRunContext; -import com.google.idea.blaze.android.run.runner.FullApkBuildStep; -import com.google.idea.blaze.android.run.test.BlazeAndroidTestLaunchMethodsProvider.AndroidTestLaunchMethod; -import com.google.idea.blaze.base.command.BlazeCommandName; -import com.google.idea.blaze.base.command.BlazeInvocationContext; -import com.google.idea.blaze.base.model.primitives.Label; -import com.google.idea.blaze.base.model.primitives.TargetExpression; -import com.google.idea.blaze.base.projectview.ProjectViewManager; -import com.google.idea.blaze.base.projectview.ProjectViewSet; -import com.google.idea.blaze.base.run.BlazeCommandRunConfiguration; -import com.google.idea.blaze.base.run.BlazeConfigurationNameBuilder; -import com.google.idea.blaze.base.run.ExecutorType; -import com.google.idea.blaze.base.run.confighandler.BlazeCommandRunConfigurationRunner; -import com.google.idea.blaze.base.settings.Blaze; -import com.google.idea.blaze.base.sync.data.BlazeDataStorage; -import com.google.idea.blaze.base.sync.projectstructure.ModuleFinder; -import com.google.idea.blaze.java.AndroidBlazeRules; -import com.intellij.execution.ExecutionException; -import com.intellij.execution.Executor; -import com.intellij.execution.JavaExecutionUtil; -import com.intellij.execution.configurations.RuntimeConfigurationException; -import com.intellij.execution.runners.ExecutionEnvironment; -import com.intellij.openapi.module.Module; -import com.intellij.openapi.project.Project; -import java.util.List; -import javax.annotation.Nullable; -import org.jetbrains.android.facet.AndroidFacet; - -/** - * {@link com.google.idea.blaze.base.run.confighandler.BlazeCommandRunConfigurationHandler} for - * android_test targets. - */ -public class BlazeAndroidTestRunConfigurationHandler - implements BlazeAndroidRunConfigurationHandler { - private final Project project; - private final BlazeAndroidTestRunConfigurationState configState; - - BlazeAndroidTestRunConfigurationHandler(BlazeCommandRunConfiguration configuration) { - this.project = configuration.getProject(); - this.configState = - new BlazeAndroidTestRunConfigurationState( - Blaze.buildSystemName(configuration.getProject())); - configuration.putUserData(DEPLOYS_TO_LOCAL_DEVICE, true); - } - - @Override - public BlazeAndroidTestRunConfigurationState getState() { - return configState; - } - - @Override - public BlazeAndroidRunConfigurationCommonState getCommonState() { - return configState.getCommonState(); - } - - @Override - public BlazeCommandRunConfigurationRunner createRunner( - Executor executor, ExecutionEnvironment env) throws ExecutionException { - Project project = env.getProject(); - BlazeCommandRunConfiguration configuration = - BlazeAndroidRunConfigurationHandler.getCommandConfig(env); - - BlazeAndroidRunConfigurationValidationUtil.validate(project); - Module module = - ModuleFinder.getInstance(env.getProject()) - .findModuleByName(BlazeDataStorage.WORKSPACE_MODULE_NAME); - AndroidFacet facet = module != null ? AndroidFacet.getInstance(module) : null; - ProjectViewSet projectViewSet = ProjectViewManager.getInstance(project).getProjectViewSet(); - - ImmutableList blazeFlags = - configState - .getCommonState() - .getExpandedBuildFlags( - project, - projectViewSet, - BlazeCommandName.TEST, - BlazeInvocationContext.runConfigContext( - ExecutorType.fromExecutor(env.getExecutor()), configuration.getType(), false)); - ImmutableList exeFlags = - ImmutableList.copyOf( - configState.getCommonState().getExeFlagsState().getFlagsForExternalProcesses()); - - // We collect metrics from a few different locations. In order to tie them all - // together, we create a unique launch id. - String launchId = LaunchMetrics.newLaunchId(); - Label label = Label.create(configuration.getSingleTarget().toString()); - - ApkBuildStep buildStep = - getTestBuildStep( - project, configState, configuration, blazeFlags, exeFlags, launchId, label); - - BlazeAndroidRunContext runContext = - new BlazeAndroidTestRunContext( - project, facet, configuration, env, configState, label, blazeFlags, buildStep); - - LaunchMetrics.logTestLaunch( - launchId, configState.getLaunchMethod().name(), env.getExecutor().getId()); - - return new BlazeAndroidRunConfigurationRunner(module, runContext, configuration); - } - - private static ApkBuildStep getTestBuildStep( - Project project, - BlazeAndroidTestRunConfigurationState configState, - BlazeCommandRunConfiguration configuration, - ImmutableList blazeFlags, - ImmutableList exeFlags, - String launchId, - Label label) - throws ExecutionException { - if (configuration.getTargetKind() - == AndroidBlazeRules.RuleTypes.ANDROID_INSTRUMENTATION_TEST.getKind()) { - boolean useMobileInstall = - AndroidTestLaunchMethod.MOBILE_INSTALL.equals(configState.getLaunchMethod()); - return ApkBuildStepProvider.getInstance(Blaze.getBuildSystemName(project)) - .getAitBuildStep( - project, - useMobileInstall, - /* nativeDebuggingEnabled= */ false, - label, - blazeFlags, - exeFlags, - launchId); - } else { - // TODO(b/248317444): This path is only invoked for the deprecated {@code android_test} - // targets, and should eventually be removed. - return new FullApkBuildStep(project, label, blazeFlags, /* nativeDebuggingEnabled= */ false); - } - } - - @Override - public final void checkConfiguration() throws RuntimeConfigurationException { - BlazeAndroidRunConfigurationValidationUtil.throwTopConfigurationError(validate()); - } - - /** - * We collect errors rather than throwing to avoid missing fatal errors by exiting early for a - * warning. We use a separate method for the collection so the compiler prevents us from - * accidentally throwing. - */ - private List validate() { - List errors = Lists.newArrayList(); - errors.addAll(BlazeAndroidRunConfigurationValidationUtil.validateWorkspaceModule(project)); - errors.addAll(configState.validate(project)); - return errors; - } - - @Override - @Nullable - public String suggestedName(BlazeCommandRunConfiguration configuration) { - TargetExpression target = configuration.getSingleTarget(); - if (target == null) { - return null; - } - BlazeConfigurationNameBuilder nameBuilder = new BlazeConfigurationNameBuilder(configuration); - - boolean isClassTest = - configState.getTestingType() == BlazeAndroidTestRunConfigurationState.TEST_CLASS; - boolean isMethodTest = - configState.getTestingType() == BlazeAndroidTestRunConfigurationState.TEST_METHOD; - if ((isClassTest || isMethodTest) && configState.getClassName() != null) { - // Get the class name without the package. - String className = JavaExecutionUtil.getPresentableClassName(configState.getClassName()); - if (className != null) { - String targetString = className; - if (isMethodTest) { - targetString += "#" + configState.getMethodName(); - } - - if (getState().getLaunchMethod().equals(AndroidTestLaunchMethod.NON_BLAZE)) { - return targetString; - } else { - return nameBuilder.setTargetString(targetString).build(); - } - } - } - return nameBuilder.build(); - } - - @Override - @Nullable - public BlazeCommandName getCommandName() { - if (getState().getLaunchMethod().equals(AndroidTestLaunchMethod.BLAZE_TEST)) { - return BlazeCommandName.TEST; - } else if (getState().getLaunchMethod().equals(AndroidTestLaunchMethod.MOBILE_INSTALL)) { - return BlazeCommandName.MOBILE_INSTALL; - } - return null; - } - - @Override - public String getHandlerName() { - return "Android Test Handler"; - } -} diff --git a/aswb/sdkcompat/asdev/com/google/idea/blaze/android/run/test/BlazeAndroidTestRunContext.java b/aswb/sdkcompat/asdev/com/google/idea/blaze/android/run/test/BlazeAndroidTestRunContext.java deleted file mode 100644 index feaec07157c..00000000000 --- a/aswb/sdkcompat/asdev/com/google/idea/blaze/android/run/test/BlazeAndroidTestRunContext.java +++ /dev/null @@ -1,229 +0,0 @@ -/* - * Copyright 2016 The Bazel Authors. All rights reserved. - * - * 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. - */ -package com.google.idea.blaze.android.run.test; - -import static com.android.tools.idea.run.tasks.DefaultConnectDebuggerTaskKt.getBaseDebuggerTask; -import static com.google.idea.blaze.android.run.binary.BlazeAndroidBinaryNormalBuildRunContextBase.getApkInfoToInstall; - -import com.android.ddmlib.IDevice; -import com.android.tools.idea.execution.common.debug.AndroidDebugger; -import com.android.tools.idea.execution.common.debug.AndroidDebuggerState; -import com.android.tools.idea.run.ApkProvider; -import com.android.tools.idea.run.ApkProvisionException; -import com.android.tools.idea.run.ApplicationIdProvider; -import com.android.tools.idea.run.ConsoleProvider; -import com.android.tools.idea.run.LaunchOptions; -import com.android.tools.idea.run.blaze.BlazeLaunchTask; -import com.android.tools.idea.run.blaze.BlazeLaunchTasksProvider; -import com.android.tools.idea.run.editor.ProfilerState; -import com.android.tools.idea.run.tasks.ConnectDebuggerTask; -import com.android.tools.idea.run.tasks.DeployTasksCompat; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.Lists; -import com.google.idea.blaze.android.run.deployinfo.BlazeAndroidDeployInfo; -import com.google.idea.blaze.android.run.deployinfo.BlazeApkProviderService; -import com.google.idea.blaze.android.run.runner.ApkBuildStep; -import com.google.idea.blaze.android.run.runner.BlazeAndroidDeviceSelector; -import com.google.idea.blaze.android.run.runner.BlazeAndroidLaunchTasksProvider; -import com.google.idea.blaze.android.run.runner.BlazeAndroidRunContext; -import com.google.idea.blaze.android.run.test.BlazeAndroidTestLaunchMethodsProvider.AndroidTestLaunchMethod; -import com.google.idea.blaze.base.model.primitives.Label; -import com.google.idea.blaze.base.run.BlazeCommandRunConfiguration; -import com.google.idea.blaze.base.run.smrunner.BlazeTestUiSession; -import com.google.idea.blaze.base.run.testlogs.BlazeTestResultHolder; -import com.intellij.execution.ExecutionException; -import com.intellij.execution.Executor; -import com.intellij.execution.runners.ExecutionEnvironment; -import com.intellij.openapi.project.Project; -import java.util.List; -import javax.annotation.Nullable; -import org.jetbrains.android.facet.AndroidFacet; - -/** Run context for android_test. */ -public class BlazeAndroidTestRunContext implements BlazeAndroidRunContext { - protected final Project project; - protected final AndroidFacet facet; - protected final BlazeCommandRunConfiguration runConfiguration; - protected final ExecutionEnvironment env; - protected final BlazeAndroidTestRunConfigurationState configState; - protected final Label label; - protected final ImmutableList blazeFlags; - protected final List launchTaskCompleteListeners = Lists.newArrayList(); - protected final ConsoleProvider consoleProvider; - protected final ApkBuildStep buildStep; - protected final ApplicationIdProvider applicationIdProvider; - protected final ApkProvider apkProvider; - private final BlazeTestResultHolder testResultsHolder = new BlazeTestResultHolder(); - - public BlazeAndroidTestRunContext( - Project project, - AndroidFacet facet, - BlazeCommandRunConfiguration runConfiguration, - ExecutionEnvironment env, - BlazeAndroidTestRunConfigurationState configState, - Label label, - ImmutableList blazeFlags, - ApkBuildStep buildStep) { - this.project = project; - this.facet = facet; - this.runConfiguration = runConfiguration; - this.env = env; - this.label = label; - this.configState = configState; - this.buildStep = buildStep; - this.blazeFlags = blazeFlags; - switch (configState.getLaunchMethod()) { - case MOBILE_INSTALL: - case NON_BLAZE: - consoleProvider = new AitIdeTestConsoleProvider(runConfiguration, configState); - break; - case BLAZE_TEST: - BlazeTestUiSession session = - BlazeTestUiSession.create(ImmutableList.of(), testResultsHolder); - this.consoleProvider = new AitBlazeTestConsoleProvider(project, runConfiguration, session); - break; - default: - throw new IllegalStateException( - "Unsupported launch method " + configState.getLaunchMethod()); - } - applicationIdProvider = new BlazeAndroidTestApplicationIdProvider(buildStep); - apkProvider = BlazeApkProviderService.getInstance().getApkProvider(project, buildStep); - } - - @Override - public BlazeAndroidDeviceSelector getDeviceSelector() { - return new BlazeAndroidDeviceSelector.NormalDeviceSelector(); - } - - @Override - public void augmentLaunchOptions(LaunchOptions.Builder options) { - options.setDeploy(!configState.getLaunchMethod().equals(AndroidTestLaunchMethod.BLAZE_TEST)); - } - - @Override - public ConsoleProvider getConsoleProvider() { - return consoleProvider; - } - - @Override - public ApplicationIdProvider getApplicationIdProvider() throws ExecutionException { - return applicationIdProvider; - } - - @Nullable - @Override - public ApkBuildStep getBuildStep() { - return buildStep; - } - - @Override - public ProfilerState getProfileState() { - return null; - } - - @Override - public BlazeLaunchTasksProvider getLaunchTasksProvider(LaunchOptions.Builder launchOptionsBuilder) - throws ExecutionException { - return new BlazeAndroidLaunchTasksProvider( - project, this, applicationIdProvider, launchOptionsBuilder); - } - - @Override - public ImmutableList getDeployTasks(IDevice device, LaunchOptions launchOptions) - throws ExecutionException { - if (configState.getLaunchMethod() != AndroidTestLaunchMethod.NON_BLAZE) { - return ImmutableList.of(); - } - return ImmutableList.of( - DeployTasksCompat.createDeployTask( - project, getApkInfoToInstall(device, launchOptions, apkProvider), launchOptions)); - } - - @Override - @Nullable - public BlazeLaunchTask getApplicationLaunchTask( - LaunchOptions launchOptions, @Nullable Integer userId, String contributorsAmStartOptions) - throws ExecutionException { - switch (configState.getLaunchMethod()) { - case BLAZE_TEST: - BlazeAndroidTestFilter testFilter = - new BlazeAndroidTestFilter( - configState.getTestingType(), - configState.getClassName(), - configState.getMethodName(), - configState.getPackageName()); - return new BlazeAndroidTestLaunchTask( - project, - label, - blazeFlags, - testFilter, - this, - launchOptions.isDebug(), - testResultsHolder); - case NON_BLAZE: - case MOBILE_INSTALL: - BlazeAndroidDeployInfo deployInfo; - try { - deployInfo = buildStep.getDeployInfo(); - } catch (ApkProvisionException e) { - throw new ExecutionException(e); - } - return StockAndroidTestLaunchTask.getStockTestLaunchTask( - configState, applicationIdProvider, launchOptions.isDebug(), deployInfo, project); - } - throw new AssertionError(); - } - - @Override - @SuppressWarnings({"unchecked", "rawtypes"}) // Raw type from upstream. - public ConnectDebuggerTask getDebuggerTask( - AndroidDebugger androidDebugger, AndroidDebuggerState androidDebuggerState) { - switch (configState.getLaunchMethod()) { - case BLAZE_TEST: - return new ConnectBlazeTestDebuggerTask(this, androidDebugger, androidDebuggerState); - case NON_BLAZE: - case MOBILE_INSTALL: - return getBaseDebuggerTask(androidDebugger, androidDebuggerState, env, facet, 30); - } - throw new AssertionError(); - } - - void onLaunchTaskComplete() { - for (Runnable runnable : launchTaskCompleteListeners) { - runnable.run(); - } - } - - void addLaunchTaskCompleteListener(Runnable runnable) { - launchTaskCompleteListeners.add(runnable); - } - - @Override - public Executor getExecutor() { - return env.getExecutor(); - } - - @Nullable - @Override - public Integer getUserId(IDevice device) { - return null; - } - - @Override - public String getAmStartOptions() { - return ""; - } -} diff --git a/aswb/sdkcompat/asdev/com/google/idea/blaze/android/run/test/ConnectBlazeTestDebuggerTask.java b/aswb/sdkcompat/asdev/com/google/idea/blaze/android/run/test/ConnectBlazeTestDebuggerTask.java deleted file mode 100644 index 3ef2a6c9493..00000000000 --- a/aswb/sdkcompat/asdev/com/google/idea/blaze/android/run/test/ConnectBlazeTestDebuggerTask.java +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Copyright 2016 The Bazel Authors. All rights reserved. - * - * 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. - */ -package com.google.idea.blaze.android.run.test; - -import com.android.ddmlib.IDevice; -import com.android.tools.idea.execution.common.debug.AndroidDebugger; -import com.android.tools.idea.execution.common.debug.AndroidDebuggerState; -import com.android.tools.idea.execution.common.debug.DebugSessionStarter; -import com.android.tools.idea.run.tasks.ConnectDebuggerTask; -import com.intellij.execution.process.ProcessHandler; -import com.intellij.execution.process.ProcessOutputTypes; -import com.intellij.execution.runners.ExecutionEnvironment; -import com.intellij.execution.ui.ConsoleView; -import com.intellij.openapi.progress.ProgressIndicator; -import com.intellij.xdebugger.impl.XDebugSessionImpl; -import java.io.OutputStream; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -/** Connects the blaze debugger during execution. */ -class ConnectBlazeTestDebuggerTask implements ConnectDebuggerTask { - - private final BlazeAndroidTestRunContext runContext; - private final AndroidDebugger myAndroidDebugger; - private final S myAndroidDebuggerState; - - public ConnectBlazeTestDebuggerTask( - BlazeAndroidTestRunContext runContext, - AndroidDebugger androidDebugger, - S androidDebuggerState) { - this.runContext = runContext; - myAndroidDebugger = androidDebugger; - myAndroidDebuggerState = androidDebuggerState; - } - - /** - * Wires up listeners to automatically reconnect the debugger for each test method. When you - * `blaze test` an android_test in debug mode, it kills the instrumentation process between each - * test method, disconnecting the debugger. We listen for the start of a new method waiting for a - * debugger, and reconnect. TODO: Support stopping Blaze from the UI. This is hard because we have - * no way to distinguish process handler termination/debug session ending initiated by the user. - * - * @return Promise with debug session or error - */ - @Override - public @NotNull XDebugSessionImpl perform( - @NotNull IDevice device, - @NotNull String applicationId, - @NotNull ExecutionEnvironment environment, - @NotNull ProgressIndicator progressIndicator, - ConsoleView console) { - final ProcessHandler masterProcessHandler = - new ProcessHandler() { - - @Override - protected void destroyProcessImpl() { - notifyProcessTerminated(0); - } - - @Override - protected void detachProcessImpl() { - notifyProcessDetached(); - } - - @Override - public boolean detachIsDefault() { - return false; - } - - @Override - public @Nullable OutputStream getProcessInput() { - return null; - } - }; - runContext.addLaunchTaskCompleteListener( - () -> { - masterProcessHandler.notifyTextAvailable( - "Test run completed.\n", ProcessOutputTypes.STDOUT); - masterProcessHandler.detachProcess(); - }); - return DebugSessionStarter.INSTANCE.attachReattachingDebuggerToStartedProcess( - device, - applicationId, - masterProcessHandler, - environment, - myAndroidDebugger, - myAndroidDebuggerState, - progressIndicator, - console, - Long.MAX_VALUE); - } -} diff --git a/aswb/sdkcompat/asdev/com/google/idea/blaze/android/run/test/StockAndroidTestLaunchTask.java b/aswb/sdkcompat/asdev/com/google/idea/blaze/android/run/test/StockAndroidTestLaunchTask.java deleted file mode 100644 index b5df308dcea..00000000000 --- a/aswb/sdkcompat/asdev/com/google/idea/blaze/android/run/test/StockAndroidTestLaunchTask.java +++ /dev/null @@ -1,207 +0,0 @@ -/* - * Copyright 2016 The Bazel Authors. All rights reserved. - * - * 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. - */ -package com.google.idea.blaze.android.run.test; - -import com.android.ddmlib.IDevice; -import com.android.ddmlib.testrunner.RemoteAndroidTestRunner; -import com.android.tools.idea.execution.common.RunConfigurationNotifier; -import com.android.tools.idea.execution.common.processhandler.AndroidProcessHandler; -import com.android.tools.idea.run.ApkProvisionException; -import com.android.tools.idea.run.ApplicationIdProvider; -import com.android.tools.idea.run.blaze.BlazeLaunchContext; -import com.android.tools.idea.run.blaze.BlazeLaunchTask; -import com.android.tools.idea.run.configuration.execution.ExecutionUtils; -import com.android.tools.idea.testartifacts.instrumented.AndroidTestListener; -import com.google.common.collect.ImmutableList; -import com.google.idea.blaze.android.manifest.ManifestParser; -import com.google.idea.blaze.android.run.deployinfo.BlazeAndroidDeployInfo; -import com.intellij.execution.ExecutionException; -import com.intellij.execution.process.ProcessHandler; -import com.intellij.execution.ui.ConsoleView; -import com.intellij.openapi.application.ApplicationManager; -import com.intellij.openapi.diagnostic.Logger; -import com.intellij.openapi.project.Project; -import com.intellij.openapi.util.Computable; -import com.intellij.openapi.util.text.StringUtil; -import java.util.List; -import javax.annotation.Nullable; -import org.jetbrains.annotations.NotNull; - -class StockAndroidTestLaunchTask implements BlazeLaunchTask { - private static final String ID = "STOCK_ANDROID_TEST"; - private static final Logger LOG = Logger.getInstance(StockAndroidTestLaunchTask.class); - private final BlazeAndroidTestRunConfigurationState configState; - private final String instrumentationTestRunner; - private final String testApplicationId; - private final boolean waitForDebugger; - - StockAndroidTestLaunchTask( - BlazeAndroidTestRunConfigurationState configState, - String runner, - String testPackage, - boolean waitForDebugger) { - this.configState = configState; - this.instrumentationTestRunner = runner; - this.waitForDebugger = waitForDebugger; - this.testApplicationId = testPackage; - } - - @Nullable - public static BlazeLaunchTask getStockTestLaunchTask( - BlazeAndroidTestRunConfigurationState configState, - ApplicationIdProvider applicationIdProvider, - boolean waitForDebugger, - BlazeAndroidDeployInfo deployInfo, - Project project) - throws ExecutionException { - String testPackage; - try { - testPackage = applicationIdProvider.getTestPackageName(); - } catch (ApkProvisionException e) { - throw new ExecutionException("Unable to determine test package name. " + e.getMessage()); - } - if (testPackage == null) { - throw new ExecutionException("Unable to determine test package name."); - } - List availableRunners = getRunnersFromManifest(deployInfo); - if (availableRunners.isEmpty()) { - RunConfigurationNotifier.INSTANCE.notifyError( - project, - "", - String.format( - "No instrumentation test runner is defined in the manifest.\n" - + "At least one instrumentation tag must be defined for the\n" - + "\"%1$s\" package in the AndroidManifest.xml, e.g.:\n" - + "\n" - + "\n" - + "\n" - + " \n" - + " \n" - + "\n" - + "", - testPackage)); - // Note: Gradle users will never see the above message, so don't mention Gradle here. - // Even if no runners are defined in build.gradle, Gradle will add a default to the manifest. - throw new ExecutionException("No instrumentation test runner is defined in the manifest."); - } - String runner = configState.getInstrumentationRunnerClass(); - if (StringUtil.isEmpty(runner)) { - // Default to the first available runner. - runner = availableRunners.get(0); - } - if (!availableRunners.contains(runner)) { - RunConfigurationNotifier.INSTANCE.notifyError( - project, - "", - String.format( - "Instrumentation test runner \"%2$s\"\n" - + "is not defined for the \"%1$s\" package in the manifest.\n" - + "Clear the 'Specific instrumentation runner' field in your configuration\n" - + "to default to \"%3$s\",\n" - + "or add the runner to your AndroidManifest.xml:\n" - + "\n" - + "\n" - + "\n" - + " \n" - + " \n" - + "\n" - + "", - testPackage, runner, availableRunners.get(0))); - throw new ExecutionException( - String.format( - "Instrumentation test runner \"%2$s\" is not defined for the \"%1$s\" package in the" - + " manifest.", - testPackage, runner)); - } - - return new StockAndroidTestLaunchTask(configState, runner, testPackage, waitForDebugger); - } - - private static ImmutableList getRunnersFromManifest( - final BlazeAndroidDeployInfo deployInfo) { - if (!ApplicationManager.getApplication().isReadAccessAllowed()) { - return ApplicationManager.getApplication() - .runReadAction( - (Computable>) () -> getRunnersFromManifest(deployInfo)); - } - ManifestParser.ParsedManifest parsedManifest = deployInfo.getMergedManifest(); - if (parsedManifest != null) { - return ImmutableList.copyOf(parsedManifest.instrumentationClassNames); - } - return ImmutableList.of(); - } - - @SuppressWarnings("FutureReturnValueIgnored") - public void run(@NotNull BlazeLaunchContext launchContext) { - ConsoleView console = launchContext.getConsoleView(); - IDevice device = launchContext.getDevice(); - ExecutionUtils.println(console, "Running tests\n"); - final RemoteAndroidTestRunner runner = - new RemoteAndroidTestRunner(testApplicationId, instrumentationTestRunner, device); - switch (configState.getTestingType()) { - case BlazeAndroidTestRunConfigurationState.TEST_ALL_IN_MODULE: - break; - case BlazeAndroidTestRunConfigurationState.TEST_ALL_IN_PACKAGE: - runner.setTestPackageName(configState.getPackageName()); - break; - case BlazeAndroidTestRunConfigurationState.TEST_CLASS: - runner.setClassName(configState.getClassName()); - break; - case BlazeAndroidTestRunConfigurationState.TEST_METHOD: - runner.setMethodName(configState.getClassName(), configState.getMethodName()); - break; - default: - throw new RuntimeException( - String.format("Unrecognized testing type: %d", configState.getTestingType())); - } - runner.setDebug(waitForDebugger); - runner.setRunOptions(configState.getExtraOptions()); - ExecutionUtils.printShellCommand(console, runner.getAmInstrumentCommand()); - // run in a separate thread as this will block until the tests complete - ApplicationManager.getApplication() - .executeOnPooledThread( - () -> { - try { - // This issues "am instrument" command and blocks execution. - runner.run(new AndroidTestListener(console)); - // Detach the device from the android process handler manually as soon as "am - // instrument" command finishes. This is required because the android process - // handler may overlook target process especially when the test - // runs really fast (~10ms). Because the android process handler discovers new - // processes by polling, this race condition happens easily. By detaching the device - // manually, we can avoid the android process handler waiting for (already finished) - // process to show up until it times out (10 secs). - // Note: this is a copy of ag/9593981, but it is worth figuring out a better - // strategy here if the behavior of AndroidTestListener is not guaranteed. - ProcessHandler processHandler = launchContext.getProcessHandler(); - if (processHandler instanceof AndroidProcessHandler) { - ((AndroidProcessHandler) processHandler).detachDevice(launchContext.getDevice()); - } - } catch (Exception e) { - ExecutionUtils.printlnError( - console, "Error: Unexpected exception while running tests: " + e); - } - }); - } -} diff --git a/aswb/sdkcompat/asdev/com/google/idea/blaze/android/sync/model/idea/BlazeAndroidModel.java b/aswb/sdkcompat/asdev/com/google/idea/blaze/android/sync/model/idea/BlazeAndroidModel.java deleted file mode 100644 index 00a9e4a94c9..00000000000 --- a/aswb/sdkcompat/asdev/com/google/idea/blaze/android/sync/model/idea/BlazeAndroidModel.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright 2020 The Bazel Authors. All rights reserved. - * - * 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. - */ -package com.google.idea.blaze.android.sync.model.idea; - -import com.android.tools.idea.model.AndroidModel; -import com.android.tools.idea.model.Namespacing; -import com.android.tools.idea.projectsystem.NamedIdeaSourceProvider; -import com.google.common.util.concurrent.ListenableFuture; -import com.intellij.openapi.project.Project; -import java.io.File; - -/** Blaze model for an android project. #api42. */ -public class BlazeAndroidModel extends BlazeAndroidModelBase { - private final NamedIdeaSourceProvider sourceProvider; - - public BlazeAndroidModel( - Project project, - File rootDirPath, - NamedIdeaSourceProvider sourceProvider, - ListenableFuture applicationId, - int minSdkVersion, - boolean desugarJava8Libs) { - super(project, rootDirPath, applicationId, minSdkVersion, desugarJava8Libs); - this.sourceProvider = sourceProvider; - } - - public NamedIdeaSourceProvider getDefaultSourceProvider() { - return sourceProvider; - } - - @Override - public Namespacing getNamespacing() { - return Namespacing.DISABLED; - } - - @Override - protected String uninitializedApplicationId() { - return AndroidModel.UNINITIALIZED_APPLICATION_ID; - } -} diff --git a/aswb/sdkcompat/asdev/org/jetbrains/android/facet/AndroidFacetPropertiesCompat.java b/aswb/sdkcompat/asdev/org/jetbrains/android/facet/AndroidFacetPropertiesCompat.java deleted file mode 100644 index fff25619e8a..00000000000 --- a/aswb/sdkcompat/asdev/org/jetbrains/android/facet/AndroidFacetPropertiesCompat.java +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright 2022 The Bazel Authors. All rights reserved. - * - * 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. - */ -package org.jetbrains.android.facet; - -/** Compat class for AndroidFacetProperties. */ -public class AndroidFacetPropertiesCompat { - - private AndroidFacetPropertiesCompat() {} - - public static void enableSourcesAutogeneration(AndroidFacetProperties props, boolean enable) {} -} diff --git a/aswb/sdkcompat/asdev/org/jetbrains/android/sdk/AndroidPlatformCompat.java b/aswb/sdkcompat/asdev/org/jetbrains/android/sdk/AndroidPlatformCompat.java deleted file mode 100644 index f745ba55516..00000000000 --- a/aswb/sdkcompat/asdev/org/jetbrains/android/sdk/AndroidPlatformCompat.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright 2023 The Bazel Authors. All rights reserved. - * - * 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. - */ -package org.jetbrains.android.sdk; - -import com.android.sdklib.BuildToolInfo; -import com.android.tools.sdk.AndroidPlatform; -import com.intellij.openapi.projectRoots.Sdk; - -/** Compat class for {@link com.android.tools.sdk.AndroidPlatform} */ -public class AndroidPlatformCompat { - AndroidPlatform androidPlatform; - - public AndroidPlatformCompat(AndroidPlatform androidPlatform) { - this.androidPlatform = androidPlatform; - } - - public BuildToolInfo getLatestBuildTool(boolean allowBuildTool) { - return androidPlatform.getSdkData().getLatestBuildTool(allowBuildTool); - } - - public int getApiLevel() { - return androidPlatform.getApiLevel(); - } - - public static int getApiLevel(Sdk sdk) { - int androidSdkApiLevel = 1; - AndroidSdkAdditionalData additionalData = (AndroidSdkAdditionalData) sdk.getSdkAdditionalData(); - if (additionalData != null) { - AndroidPlatform androidPlatform = additionalData.getAndroidPlatform(); - if (androidPlatform != null) { - androidSdkApiLevel = androidPlatform.getApiLevel(); - } - } - return androidSdkApiLevel; - } -} diff --git a/aswb/sdkcompat/asdev/org/jetbrains/android/sdk/AndroidPlatformsCompat.java b/aswb/sdkcompat/asdev/org/jetbrains/android/sdk/AndroidPlatformsCompat.java deleted file mode 100644 index d016d7ce236..00000000000 --- a/aswb/sdkcompat/asdev/org/jetbrains/android/sdk/AndroidPlatformsCompat.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright 2023 The Bazel Authors. All rights reserved. - * - * 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. - */ -package org.jetbrains.android.sdk; - -import com.intellij.openapi.module.Module; -import com.intellij.openapi.projectRoots.Sdk; - -/** Compat shim class for {@link AndroidPlatforms} */ -public class AndroidPlatformsCompat { - private AndroidPlatformsCompat() {} - - public static AndroidPlatformCompat getInstance(Sdk sdk) { - return new AndroidPlatformCompat(AndroidPlatforms.getInstance(sdk)); - } - - public static AndroidPlatformCompat getInstance(Module module) { - return new AndroidPlatformCompat(AndroidPlatforms.getInstance(module)); - } -} diff --git a/aswb/sdkcompat/asdev/org/jetbrains/android/sdk/AndroidSdkAdditionalDataCompat.java b/aswb/sdkcompat/asdev/org/jetbrains/android/sdk/AndroidSdkAdditionalDataCompat.java deleted file mode 100644 index 6364b6fa8cf..00000000000 --- a/aswb/sdkcompat/asdev/org/jetbrains/android/sdk/AndroidSdkAdditionalDataCompat.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright 2023 The Bazel Authors. All rights reserved. - * - * 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. - */ -package org.jetbrains.android.sdk; - -import com.intellij.openapi.projectRoots.Sdk; - -/** Compat shim class for {@link AndroidSdkAdditionalData} */ -public class AndroidSdkAdditionalDataCompat { - private AndroidSdkAdditionalDataCompat() {} - - public static AndroidSdkAdditionalData from(Sdk sdk) { - return AndroidSdkAdditionalData.from(sdk); - } -} diff --git a/aswb/sdkcompat/asdev/org/jetbrains/android/sdk/AndroidSdkDataCompat.java b/aswb/sdkcompat/asdev/org/jetbrains/android/sdk/AndroidSdkDataCompat.java deleted file mode 100644 index 4aea6d6e832..00000000000 --- a/aswb/sdkcompat/asdev/org/jetbrains/android/sdk/AndroidSdkDataCompat.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright 2023 The Bazel Authors. All rights reserved. - * - * 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. - */ -package org.jetbrains.android.sdk; - -import com.android.sdklib.IAndroidTarget; -import com.android.tools.sdk.AndroidSdkData; -import com.google.errorprone.annotations.CanIgnoreReturnValue; -import java.io.File; - -/** Compat class for {@link com.android.tools.sdk.AndroidSdkData} */ -public class AndroidSdkDataCompat { - AndroidSdkData androidSdkData; - - private AndroidSdkDataCompat(File sdkLocation, boolean forceReparse) { - androidSdkData = AndroidSdkData.getSdkData(sdkLocation, forceReparse); - } - - public static AndroidSdkDataCompat getSdkData(String sdkHomepath) { - return new AndroidSdkDataCompat(new File(sdkHomepath), false); - } - - @CanIgnoreReturnValue - public static AndroidSdkDataCompat getSdkData(File sdkLocation, boolean forceReparse) { - return new AndroidSdkDataCompat(sdkLocation, forceReparse); - } - - public IAndroidTarget[] getTargets() { - return androidSdkData.getTargets(); - } -} diff --git a/aswb/src/META-INF/aswb.xml b/aswb/src/META-INF/aswb.xml index f95599dc894..d8640eeab5c 100644 --- a/aswb/src/META-INF/aswb.xml +++ b/aswb/src/META-INF/aswb.xml @@ -19,6 +19,8 @@ com.intellij.modules.androidstudio org.jetbrains.android com.google.gct.test.recorder + com.intellij.modules.java + com.android.tools.design @@ -31,8 +33,6 @@ - - + @@ -59,6 +59,7 @@ + @@ -72,6 +73,7 @@ + @@ -97,6 +99,10 @@ + + + + @@ -106,7 +112,7 @@ - + @@ -114,8 +120,21 @@ + + + + + + + + + + + + diff --git a/aswb/src/META-INF/ndk_contents.xml b/aswb/src/META-INF/ndk_contents.xml index 578be7294fe..673b73a74a3 100644 --- a/aswb/src/META-INF/ndk_contents.xml +++ b/aswb/src/META-INF/ndk_contents.xml @@ -20,6 +20,10 @@ + + + + diff --git a/aswb/src/com/android/tools/idea/rendering/tokens/BUILD b/aswb/src/com/android/tools/idea/rendering/tokens/BUILD new file mode 100644 index 00000000000..d8c8722b5d6 --- /dev/null +++ b/aswb/src/com/android/tools/idea/rendering/tokens/BUILD @@ -0,0 +1,30 @@ +load( + "//:build-visibility.bzl", + "ASWB_SUBPACKAGES_VISIBILITY", + "TEST_ASWB_SUBPACKAGES_VISIBILITY", +) +load( + "//build_defs:build_defs.bzl", + "combine_visibilities", +) + +java_library( + name = "tokens", + srcs = glob(["*.java"]), + visibility = combine_visibilities( + ASWB_SUBPACKAGES_VISIBILITY, + TEST_ASWB_SUBPACKAGES_VISIBILITY, + ), + deps = [ + "//aswb:aswb_lib", + "//base", + "//common/experiments", + "//cpp", + "//java", + "//proto:proto_deps", + "//querysync", + "//shared", + "//shared:artifact", + "//intellij_platform_sdk:plugin_api", + ], +) diff --git a/aswb/src/com/android/tools/idea/rendering/tokens/BazelBuildSystemFilePreviewServices.java b/aswb/src/com/android/tools/idea/rendering/tokens/BazelBuildSystemFilePreviewServices.java new file mode 100644 index 00000000000..d6dfdbc2975 --- /dev/null +++ b/aswb/src/com/android/tools/idea/rendering/tokens/BazelBuildSystemFilePreviewServices.java @@ -0,0 +1,76 @@ +/* + * Copyright 2024 The Bazel Authors. All rights reserved. + * + * 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. + */ +package com.android.tools.idea.rendering.tokens; + +import com.android.tools.idea.projectsystem.ProjectSystemBuildManager; +import com.android.tools.idea.rendering.BuildTargetReference; +import com.google.idea.blaze.android.projectsystem.BazelProjectSystem; +import com.google.idea.blaze.android.projectsystem.BazelToken; +import com.intellij.openapi.Disposable; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vfs.VirtualFile; +import java.util.Collection; +import org.jetbrains.annotations.NotNull; + + +public class BazelBuildSystemFilePreviewServices + implements BuildSystemFilePreviewServices, BazelToken { + + @Override + public boolean isApplicable(BuildTargetReference buildTargetReference) { + return buildTargetReference instanceof BazelBuildTargetReference; + } + + @Override + public BuildServices getBuildServices() { + return new BuildServices<>() { + @Override + public @NotNull ProjectSystemBuildManager.BuildStatus getLastCompileStatus( + @NotNull BazelBuildTargetReference buildTarget) { + return ProjectSystemBuildManager.BuildStatus.UNKNOWN; + } + + @Override + public void buildArtifacts( + @NotNull Collection buildTargets) { + throw new UnsupportedOperationException(); + } + }; + } + + @Override + public void subscribeBuildListener(Project project, + Disposable parentDisposable, BuildListener listener) { + throw new UnsupportedOperationException(); + } + + @Override + public BuildTargets getBuildTargets() { + return new BuildTargets() { + @Override + public @NotNull BuildTargetReference from(@NotNull Module module, + @NotNull VirtualFile targetFile) { + return fromModuleOnly(module); + } + + @Override + public @NotNull BuildTargetReference fromModuleOnly(@NotNull Module module) { + return new BazelBuildTargetReference(module); + } + }; + } +} \ No newline at end of file diff --git a/aswb/src/com/android/tools/idea/rendering/tokens/BazelBuildTargetReference.java b/aswb/src/com/android/tools/idea/rendering/tokens/BazelBuildTargetReference.java new file mode 100644 index 00000000000..7c957a94da9 --- /dev/null +++ b/aswb/src/com/android/tools/idea/rendering/tokens/BazelBuildTargetReference.java @@ -0,0 +1,55 @@ +/* + * Copyright 2024 The Bazel Authors. All rights reserved. + * + * 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. + */ +package com.android.tools.idea.rendering.tokens; + +import com.android.tools.idea.rendering.BuildTargetReference; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.project.Project; +import com.intellij.serviceContainer.AlreadyDisposedException; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +class BazelBuildTargetReference implements BuildTargetReference { + private final Module module; + + BazelBuildTargetReference(Module module) { + this.module = module; + } + + @NotNull + @Override + public Module getModule() { + if (module.isDisposed()) { + throw new AlreadyDisposedException("Already disposed: " + module); + } + return module; + } + + @NotNull + @Override + public Project getProject() { + return module.getProject(); + } + + @Nullable + @Override + public Module getModuleIfNotDisposed() { + if (module.isDisposed()) { + return null; + } + return module; + } +} diff --git a/aswb/sdkcompat/as223/com/android/tools/idea/run/ValidationErrorCompat.java b/aswb/src/com/android/tools/idea/run/ValidationErrorCompat.java similarity index 100% rename from aswb/sdkcompat/as223/com/android/tools/idea/run/ValidationErrorCompat.java rename to aswb/src/com/android/tools/idea/run/ValidationErrorCompat.java diff --git a/aswb/src/com/android/tools/idea/run/tasks/DeployTasksHelper.java b/aswb/src/com/android/tools/idea/run/tasks/DeployTasksHelper.java new file mode 100644 index 00000000000..1c103aabaeb --- /dev/null +++ b/aswb/src/com/android/tools/idea/run/tasks/DeployTasksHelper.java @@ -0,0 +1,50 @@ +/* + * Copyright 2020 The Bazel Authors. All rights reserved. + * + * 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. + */ +package com.android.tools.idea.run.tasks; + +import com.android.tools.deployer.DeployerException; +import com.android.tools.idea.execution.common.AndroidExecutionException; +import com.android.tools.idea.execution.common.DeployOptions; +import com.android.tools.idea.run.ApkInfo; +import com.android.tools.idea.run.blaze.BlazeLaunchTask; +import com.intellij.openapi.project.Project; +import java.util.Collection; +import java.util.List; + +/** Helper class for {@link DeployTask} */ +public class DeployTasksHelper { + + private DeployTasksHelper() {} + + public static BlazeLaunchTask createDeployTask( + Project project, Collection packages, DeployOptions deployOptions) { + return launchContext -> { + try { + List unused = + new DeployTask( + project, + packages, + deployOptions.getPmInstallFlags(), + deployOptions.getInstallOnAllUsers(), + deployOptions.getAlwaysInstallWithPm(), + deployOptions.getAllowAssumeVerified()) + .run(launchContext.getDevice(), launchContext.getProgressIndicator()); + } catch (DeployerException e) { + throw new AndroidExecutionException(e.getId(), e.getMessage()); + } + }; + } +} diff --git a/aswb/src/com/google/idea/blaze/android/cppimpl/BlazeNdkSupportEnabler.java b/aswb/src/com/google/idea/blaze/android/cppimpl/BlazeNdkSupportEnabler.java index dbd8f2384c2..8e987ebf3f0 100644 --- a/aswb/src/com/google/idea/blaze/android/cppimpl/BlazeNdkSupportEnabler.java +++ b/aswb/src/com/google/idea/blaze/android/cppimpl/BlazeNdkSupportEnabler.java @@ -19,22 +19,30 @@ import com.android.tools.ndk.NdkHelper; import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Sets; import com.google.idea.blaze.base.model.BlazeProjectData; import com.google.idea.blaze.base.model.primitives.LanguageClass; import com.google.idea.blaze.base.projectview.ProjectViewSet; +import com.google.idea.blaze.base.qsync.QuerySyncProject; +import com.google.idea.blaze.base.qsync.QuerySyncProjectListenerProvider; import com.google.idea.blaze.base.scope.BlazeContext; import com.google.idea.blaze.base.settings.BlazeImportSettings; import com.google.idea.blaze.base.sync.SyncListener; import com.google.idea.blaze.base.sync.SyncMode; import com.google.idea.blaze.base.sync.SyncResult; +import com.google.idea.blaze.common.Context; +import com.google.idea.blaze.qsync.QuerySyncProjectListener; +import com.google.idea.blaze.qsync.QuerySyncProjectSnapshot; +import com.google.idea.blaze.qsync.project.QuerySyncLanguage; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.application.TransactionGuard; import com.intellij.openapi.project.Project; import com.jetbrains.cidr.lang.workspace.OCWorkspace; import com.jetbrains.cidr.lang.workspace.OCWorkspaceEventImpl; import com.jetbrains.cidr.lang.workspace.OCWorkspaceModificationTrackersImpl; +import java.util.Set; -final class BlazeNdkSupportEnabler implements SyncListener { +final class BlazeNdkSupportEnabler implements SyncListener, QuerySyncProjectListenerProvider { @Override public void onSyncComplete( @@ -51,6 +59,22 @@ public void onSyncComplete( enableCSupportInIde(project, enabled); } + @Override + public QuerySyncProjectListener createListener(QuerySyncProject project) { + return new QuerySyncProjectListener() { + @Override + public void onNewProjectSnapshot(Context context, QuerySyncProjectSnapshot instance) { + + Set allLanguages = + Sets.union( + instance.queryData().projectDefinition().languageClasses(), + QuerySyncLanguage.fromProtoList(instance.project().getActiveLanguagesList())); + + enableCSupportInIde(project.getIdeProject(), allLanguages.contains(QuerySyncLanguage.CC)); + } + }; + } + /** * If {@code enabled} is true, this method will enable C support in the IDE if it is not already * enabled. if {@code enabled} is false this method will clear out any currently stored diff --git a/aswb/src/com/google/idea/blaze/android/cppimpl/NdkCppSupportChecker.java b/aswb/src/com/google/idea/blaze/android/cppimpl/NdkCppSupportChecker.java new file mode 100644 index 00000000000..bfddb725345 --- /dev/null +++ b/aswb/src/com/google/idea/blaze/android/cppimpl/NdkCppSupportChecker.java @@ -0,0 +1,41 @@ +/* + * Copyright 2024 The Bazel Authors. All rights reserved. + * + * 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. + */ +package com.google.idea.blaze.android.cppimpl; + +import com.android.tools.ndk.AndroidSysroot; +import com.android.tools.ndk.configuration.NdkConfigurationValidatorKt; +import com.google.idea.blaze.cpp.CppSupportChecker; +import com.jetbrains.cidr.lang.toolchains.CidrCompilerSwitches; +import com.jetbrains.cidr.lang.toolchains.CidrCompilerSwitches.Format; +import java.nio.file.Path; + +/** + * Uses the Android Studio API to check if a CPP configuration is supported, i.e. is for NDK + * development rather than non-Android CPP. + */ +public class NdkCppSupportChecker implements CppSupportChecker { + + @Override + public boolean supportsCppConfiguration( + CidrCompilerSwitches compilerSwitches, Path workspaceRoot) { + return NdkConfigurationValidatorKt.isValidNdkConfiguration( + compilerSwitches.getList(Format.RAW), + workspaceRoot, + AndroidSysroot::isValidAndroidSysroot, + AndroidSysroot::isValidAndroidSysrootUsrInclude, + AndroidSysroot::isPotentialNonAndroidSysrootUsrInclude); + } +} diff --git a/aswb/src/com/google/idea/blaze/android/cppimpl/debug/BlazeAutoAndroidDebugger.java b/aswb/src/com/google/idea/blaze/android/cppimpl/debug/BlazeAutoAndroidDebugger.java new file mode 100644 index 00000000000..06fbf1b43b4 --- /dev/null +++ b/aswb/src/com/google/idea/blaze/android/cppimpl/debug/BlazeAutoAndroidDebugger.java @@ -0,0 +1,39 @@ +/* + * Copyright 2016 The Bazel Authors. All rights reserved. + * + * 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. + */ +package com.google.idea.blaze.android.cppimpl.debug; + +import com.android.ddmlib.Client; +import com.intellij.openapi.project.Project; +import com.intellij.xdebugger.XDebugSession; +import org.jetbrains.annotations.NotNull; + +public class BlazeAutoAndroidDebugger extends BlazeAutoAndroidDebuggerBase { + + @Override + public XDebugSession getExistingDebugSession(@NotNull Project project, @NotNull Client client) { + if (isNativeProject(project)) { + log.info("Project has native development enabled"); + return nativeDebugger.getExistingDebugSession(project, client); + } else { + return super.getExistingDebugSession(project, client); + } + } + + @Override + protected boolean isNativeDeployment(Project project, Client clientData) { + return isNativeProject(project); + } +} diff --git a/aswb/src/com/google/idea/blaze/android/cppimpl/debug/BlazeAutoAndroidDebuggerBase.java b/aswb/src/com/google/idea/blaze/android/cppimpl/debug/BlazeAutoAndroidDebuggerBase.java index f920f1414d6..855aee1589c 100644 --- a/aswb/src/com/google/idea/blaze/android/cppimpl/debug/BlazeAutoAndroidDebuggerBase.java +++ b/aswb/src/com/google/idea/blaze/android/cppimpl/debug/BlazeAutoAndroidDebuggerBase.java @@ -21,7 +21,6 @@ import com.google.idea.blaze.base.settings.Blaze; import com.google.idea.blaze.base.sync.data.BlazeProjectDataManager; import com.intellij.openapi.diagnostic.Logger; -import com.intellij.openapi.module.Module; import com.intellij.openapi.project.Project; /** Attached either java or native debugger depending on if native debugging is enabled. */ @@ -32,17 +31,16 @@ public abstract class BlazeAutoAndroidDebuggerBase extends AutoAndroidDebugger { @Override protected boolean isNativeProject(Project project) { + return isNativeCodeInProject(project); + } + + public static boolean isNativeCodeInProject(Project project) { BlazeProjectData blazeProjectData = BlazeProjectDataManager.getInstance(project).getBlazeProjectData(); return blazeProjectData != null && blazeProjectData.getWorkspaceLanguageSettings().isLanguageActive(LanguageClass.C); } - @Override - protected boolean isNativeDeployment(Project project, Module debuggeeModule) { - return isNativeProject(project); - } - @Override public String getId() { return ID; diff --git a/aswb/src/com/google/idea/blaze/android/cppimpl/debug/BlazeNativeAndroidDebugger.java b/aswb/src/com/google/idea/blaze/android/cppimpl/debug/BlazeNativeAndroidDebugger.java new file mode 100644 index 00000000000..f125ae025b2 --- /dev/null +++ b/aswb/src/com/google/idea/blaze/android/cppimpl/debug/BlazeNativeAndroidDebugger.java @@ -0,0 +1,18 @@ +/* + * Copyright 2018 The Bazel Authors. All rights reserved. + * + * 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. + */ +package com.google.idea.blaze.android.cppimpl.debug; + +public class BlazeNativeAndroidDebugger extends BlazeNativeAndroidDebuggerBase {} diff --git a/aswb/src/com/google/idea/blaze/android/cppimpl/debug/BlazeNativeAndroidDebuggerBase.java b/aswb/src/com/google/idea/blaze/android/cppimpl/debug/BlazeNativeAndroidDebuggerBase.java new file mode 100644 index 00000000000..e9ba5c444c5 --- /dev/null +++ b/aswb/src/com/google/idea/blaze/android/cppimpl/debug/BlazeNativeAndroidDebuggerBase.java @@ -0,0 +1,78 @@ +/* + * Copyright 2020 The Bazel Authors. All rights reserved. + * + * 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. + */ +package com.google.idea.blaze.android.cppimpl.debug; + +import com.android.ddmlib.Client; +import com.android.tools.idea.projectsystem.ApplicationProjectContext; +import com.android.tools.ndk.run.editor.NativeAndroidDebugger; +import com.android.tools.ndk.run.editor.NativeAndroidDebuggerState; +import com.google.idea.blaze.base.model.BlazeProjectData; +import com.google.idea.blaze.base.model.primitives.LanguageClass; +import com.google.idea.blaze.base.settings.Blaze; +import com.google.idea.blaze.base.sync.data.BlazeProjectDataManager; +import com.intellij.openapi.project.Project; +import com.intellij.xdebugger.XDebugProcessStarter; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +/** + * Extension of {@link NativeAndroidDebugger} with the following key differences compared to {@link + * NativeAndroidDebugger}. + * + *

    + *
  • Overrides {@link #supportsProject} so native debugger is only enabled for native support is + * enabled. + *
+ */ +public class BlazeNativeAndroidDebuggerBase extends NativeAndroidDebugger { + /** + * This ID needs to be lexicographically larger than "Java" so it come after the "Java" debugger + * when sorted lexicographically in the "Attach Debugger to Android Process" dialog. See {@link + * org.jetbrains.android.actions.AndroidProcessChooserDialog#populateDebuggerTypeCombo}. + */ + public static final String ID = "Native" + Blaze.defaultBuildSystemName(); + + @Override + public String getId() { + return ID; + } + + @Override + public String getDisplayName() { + return "Native Only"; + } + + @Override + public boolean supportsProject(Project project) { + BlazeProjectData blazeProjectData = + BlazeProjectDataManager.getInstance(project).getBlazeProjectData(); + return blazeProjectData != null + && blazeProjectData.getWorkspaceLanguageSettings().isLanguageActive(LanguageClass.C); + } + + @Override + public XDebugProcessStarter getDebugProcessStarterForExistingProcess( + @NotNull Project project, + @NotNull Client client, + ApplicationProjectContext applicationContext, + @Nullable NativeAndroidDebuggerState state) { + if (state != null) { + BlazeNativeDebuggerStateSourceMapping.addSourceMapping(project, state); + } + return super.getDebugProcessStarterForExistingProcess( + project, client, applicationContext, state); + } +} diff --git a/aswb/src/com/google/idea/blaze/android/cppimpl/debug/BlazeNativeDebuggerStateSourceMapping.java b/aswb/src/com/google/idea/blaze/android/cppimpl/debug/BlazeNativeDebuggerStateSourceMapping.java new file mode 100644 index 00000000000..640e5f82075 --- /dev/null +++ b/aswb/src/com/google/idea/blaze/android/cppimpl/debug/BlazeNativeDebuggerStateSourceMapping.java @@ -0,0 +1,46 @@ +/* + * 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. + */ +package com.google.idea.blaze.android.cppimpl.debug; + +import com.android.tools.ndk.run.editor.NativeAndroidDebuggerState; +import com.google.common.collect.ImmutableList; +import com.google.idea.blaze.base.model.primitives.WorkspaceRoot; +import com.intellij.openapi.project.Project; +import org.jetbrains.annotations.NotNull; + +/** Maps source directory when attaching to a process */ +public class BlazeNativeDebuggerStateSourceMapping { + public static void addSourceMapping( + @NotNull Project project, @NotNull NativeAndroidDebuggerState state) { + // Source code is always relative to the workspace root in a blaze project. + String workingDirPath = WorkspaceRoot.fromProject(project).directory().getPath(); + state.setWorkingDir(workingDirPath); + + // Remote built binaries may use /proc/self/cwd to represent the working directory + // so we manually map /proc/self/cwd to the workspace root. We used to use + // `plugin.symbol-file.dwarf.comp-dir-symlink-paths = "/proc/self/cwd"` + // to automatically resolve this but it's no longer supported in newer versions of + // LLDB. + String sourceMapToWorkspaceRootCommand = + "settings append target.source-map /proc/self/cwd " + workingDirPath; + ImmutableList startupCommands = + ImmutableList.builder() + .addAll(state.getUserStartupCommands()) + .add(sourceMapToWorkspaceRootCommand) + .build(); + state.setUserStartupCommands(startupCommands); + } +} diff --git a/aswb/src/com/google/idea/blaze/android/filecache/ArtifactCache.java b/aswb/src/com/google/idea/blaze/android/filecache/ArtifactCache.java index ee1f4da02fe..aa4c0be7ba0 100644 --- a/aswb/src/com/google/idea/blaze/android/filecache/ArtifactCache.java +++ b/aswb/src/com/google/idea/blaze/android/filecache/ArtifactCache.java @@ -15,8 +15,8 @@ */ package com.google.idea.blaze.android.filecache; -import com.google.idea.blaze.base.command.buildresult.OutputArtifact; import com.google.idea.blaze.base.scope.BlazeContext; +import com.google.idea.blaze.common.artifact.OutputArtifactWithoutDigest; import java.nio.file.Path; import java.util.Collection; import javax.annotation.Nullable; @@ -35,19 +35,21 @@ public interface ArtifactCache { void clearCache(); /** - * Fetches and caches the given collection of {@link OutputArtifact} to disk. + * Fetches and caches the given collection of {@link OutputArtifactWithoutDigest} to disk. * * @param artifacts Collection of artifacts to add to cache * @param removeMissingArtifacts if true, will remove any cached artifact that is not present in * {@code artifacts}. */ void putAll( - Collection artifacts, BlazeContext context, boolean removeMissingArtifacts); + Collection artifacts, + BlazeContext context, + boolean removeMissingArtifacts); /** - * Returns the {@link Path} corresponding to the given {@link OutputArtifact}, or {@code null} if - * the artifact is not tracked in cache. + * Returns the {@link Path} corresponding to the given {@link OutputArtifactWithoutDigest}, or + * {@code null} if the artifact is not tracked in cache. */ @Nullable - Path get(OutputArtifact artifact); + Path get(OutputArtifactWithoutDigest artifact); } diff --git a/aswb/src/com/google/idea/blaze/android/filecache/ArtifactMetadata.java b/aswb/src/com/google/idea/blaze/android/filecache/ArtifactMetadata.java index 72bd362792e..c23af23af27 100644 --- a/aswb/src/com/google/idea/blaze/android/filecache/ArtifactMetadata.java +++ b/aswb/src/com/google/idea/blaze/android/filecache/ArtifactMetadata.java @@ -18,8 +18,9 @@ import com.google.devtools.intellij.model.ProjectData; import com.google.devtools.intellij.model.ProjectData.LocalFile; import com.google.devtools.intellij.model.ProjectData.LocalFileOrOutputArtifact; -import com.google.idea.blaze.base.command.buildresult.OutputArtifact; -import com.google.idea.blaze.base.filecache.ArtifactState; +import com.google.idea.blaze.base.filecache.ArtifactStateProtoConverter; +import com.google.idea.blaze.common.artifact.ArtifactState; +import com.google.idea.blaze.common.artifact.OutputArtifactWithoutDigest; import java.util.Objects; /** Data class to (de)serialize metadata of an artifact in cache */ @@ -66,14 +67,15 @@ public int hashCode() { * * @throws ArtifactNotFoundException if the artifact is not present. */ - public static ArtifactMetadata forArtifact(OutputArtifact artifact) + public static ArtifactMetadata forArtifact(OutputArtifactWithoutDigest artifact) throws ArtifactNotFoundException { ArtifactState artifactState = artifact.toArtifactState(); if (artifactState == null) { throw new ArtifactNotFoundException(artifact); } // Serialize to proto to make grabbing the fields easier - LocalFileOrOutputArtifact serializedArtifact = artifactState.serializeToProto(); + LocalFileOrOutputArtifact serializedArtifact = + ArtifactStateProtoConverter.toProto(artifactState); if (serializedArtifact.hasArtifact()) { ProjectData.OutputArtifact o = serializedArtifact.getArtifact(); return new ArtifactMetadata(o.getRelativePath(), o.getId()); diff --git a/aswb/src/com/google/idea/blaze/android/filecache/ArtifactNotFoundException.java b/aswb/src/com/google/idea/blaze/android/filecache/ArtifactNotFoundException.java index f6893f8100b..139ed5371c1 100644 --- a/aswb/src/com/google/idea/blaze/android/filecache/ArtifactNotFoundException.java +++ b/aswb/src/com/google/idea/blaze/android/filecache/ArtifactNotFoundException.java @@ -15,12 +15,12 @@ */ package com.google.idea.blaze.android.filecache; -import com.google.idea.blaze.base.command.buildresult.OutputArtifact; +import com.google.idea.blaze.common.artifact.OutputArtifactWithoutDigest; import java.io.IOException; /** Signals that a particular artifact cannot be located. */ public class ArtifactNotFoundException extends IOException { - public ArtifactNotFoundException(OutputArtifact artifact) { - super(artifact.getRelativePath() + " not found."); + public ArtifactNotFoundException(OutputArtifactWithoutDigest artifact) { + super(artifact.getBazelOutRelativePath() + " not found."); } } diff --git a/aswb/src/com/google/idea/blaze/android/filecache/CacheEntry.java b/aswb/src/com/google/idea/blaze/android/filecache/CacheEntry.java index 545ab86ad64..23f99cc4605 100644 --- a/aswb/src/com/google/idea/blaze/android/filecache/CacheEntry.java +++ b/aswb/src/com/google/idea/blaze/android/filecache/CacheEntry.java @@ -17,8 +17,8 @@ import com.google.common.annotations.VisibleForTesting; import com.google.common.collect.ImmutableSet; -import com.google.idea.blaze.base.command.buildresult.BlazeArtifact; -import com.google.idea.blaze.base.command.buildresult.OutputArtifact; +import com.google.idea.blaze.common.artifact.BlazeArtifact; +import com.google.idea.blaze.common.artifact.OutputArtifactWithoutDigest; import com.intellij.openapi.util.io.FileUtil; import com.intellij.util.PathUtil; import java.util.Objects; @@ -76,7 +76,7 @@ public int hashCode() { /** Returns a {@link CacheEntry} corresponding to the given {@code OutputArtifact}. */ @VisibleForTesting - public static CacheEntry forArtifact(OutputArtifact blazeArtifact) + public static CacheEntry forArtifact(OutputArtifactWithoutDigest blazeArtifact) throws ArtifactNotFoundException { ArtifactMetadata artifactMetadata = ArtifactMetadata.forArtifact(blazeArtifact); diff --git a/aswb/src/com/google/idea/blaze/android/filecache/LocalArtifactCache.java b/aswb/src/com/google/idea/blaze/android/filecache/LocalArtifactCache.java index ee3af212cde..e2ac2d64d18 100644 --- a/aswb/src/com/google/idea/blaze/android/filecache/LocalArtifactCache.java +++ b/aswb/src/com/google/idea/blaze/android/filecache/LocalArtifactCache.java @@ -24,8 +24,7 @@ import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; import com.google.idea.blaze.base.async.FutureUtil; -import com.google.idea.blaze.base.command.buildresult.BlazeArtifact; -import com.google.idea.blaze.base.command.buildresult.OutputArtifact; +import com.google.idea.blaze.base.command.buildresult.RemoteOutputArtifact; import com.google.idea.blaze.base.io.FileOperationProvider; import com.google.idea.blaze.base.logging.EventLoggingService; import com.google.idea.blaze.base.prefetch.FetchExecutor; @@ -34,6 +33,7 @@ import com.google.idea.blaze.base.scope.output.IssueOutput; import com.google.idea.blaze.base.scope.scopes.TimingScope.EventType; import com.google.idea.blaze.common.PrintOutput; +import com.google.idea.blaze.common.artifact.OutputArtifactWithoutDigest; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Pair; @@ -58,7 +58,7 @@ import javax.annotation.Nullable; /** - * LocalArtifactCache is an on disk cache for {@link OutputArtifact}s. + * LocalArtifactCache is an on disk cache for {@link OutputArtifactWithoutDigest}s. * *

The {@link #get} returns the path to a local copy of the cached artifact (if present). * @@ -75,9 +75,9 @@ * is set to true. * * - * Internally, every {@link OutputArtifact} is mapped to a {@link CacheEntry} object, which captures - * metadata about the artifact including data like timestamp or objfs blobId that allows it to - * determine when an artifact has been updated. + * Internally, every {@link OutputArtifactWithoutDigest} is mapped to a {@link CacheEntry} object, + * which captures metadata about the artifact including data like timestamp or objfs blobId that + * allows it to determine when an artifact has been updated. * *

An in memory map of these CacheEntries allows for quick retrieval of the cached objects. But * this map is also persisted to the disk after calls to {@link #clearCache} and {@link #putAll} and @@ -156,9 +156,11 @@ public synchronized void clearCache() { */ @Override public synchronized void putAll( - Collection artifacts, BlazeContext context, boolean removeMissingArtifacts) { + Collection artifacts, + BlazeContext context, + boolean removeMissingArtifacts) { // Utility maps for the passed artifacts - Map keyToArtifact = new HashMap<>(); + Map keyToArtifact = new HashMap<>(); Map keyToCacheEntry = new HashMap<>(); artifacts.forEach( a -> { @@ -184,7 +186,7 @@ public synchronized void putAll( || !cacheState.get(kv.getKey()).equals(kv.getValue())) .map(Entry::getKey) .collect(ImmutableList.toImmutableList()); - ImmutableMap updatedKeyToArtifact = + ImmutableMap updatedKeyToArtifact = updatedKeys.stream().collect(ImmutableMap.toImmutableMap(k -> k, keyToArtifact::get)); ImmutableMap updatedKeyToCacheEntry = updatedKeys.stream().collect(ImmutableMap.toImmutableMap(k -> k, keyToCacheEntry::get)); @@ -204,7 +206,7 @@ public synchronized void putAll( RemoteArtifactPrefetcher.getInstance() .downloadArtifacts( project.getName(), - BlazeArtifact.getRemoteArtifacts(updatedKeyToArtifact.values())); + RemoteOutputArtifact.getRemoteArtifacts(updatedKeyToArtifact.values())); FutureUtil.waitForFuture(context, downloadArtifactsFuture) .timed("FetchCacheArtifacts", EventType.Prefetching) .withProgressMessage(String.format("Fetching Artifacts for %s...", cacheName)) @@ -251,7 +253,7 @@ public synchronized void putAll( @Override @Nullable - public synchronized Path get(OutputArtifact artifact) { + public synchronized Path get(OutputArtifactWithoutDigest artifact) { CacheEntry queriedEntry; try { queriedEntry = CacheEntry.forArtifact(artifact); @@ -318,11 +320,11 @@ private void loadCacheData() { } /** - * Returns a list of futures copying the given {@link OutputArtifact}s to disk. The returned - * futures return the cache key on successful copy, or an empty string on copy failure. + * Returns a list of futures copying the given {@link OutputArtifactWithoutDigest}s to disk. The + * returned futures return the cache key on successful copy, or an empty string on copy failure. */ private ImmutableList> copyLocally( - Map updatedKeyToArtifact, + Map updatedKeyToArtifact, Map updatedKeyToCacheEntry) { return updatedKeyToArtifact.entrySet().stream() .map( @@ -348,7 +350,7 @@ private ImmutableList> copyLocally( .collect(ImmutableList.toImmutableList()); } - private static void copyLocally(OutputArtifact blazeArtifact, Path destinationPath) + private static void copyLocally(OutputArtifactWithoutDigest blazeArtifact, Path destinationPath) throws IOException { try (InputStream stream = blazeArtifact.getInputStream()) { Files.copy(stream, destinationPath, StandardCopyOption.REPLACE_EXISTING); diff --git a/aswb/src/com/google/idea/blaze/android/libraries/AarLibraryContents.java b/aswb/src/com/google/idea/blaze/android/libraries/AarLibraryContents.java index 3638634f030..0fe195896bc 100644 --- a/aswb/src/com/google/idea/blaze/android/libraries/AarLibraryContents.java +++ b/aswb/src/com/google/idea/blaze/android/libraries/AarLibraryContents.java @@ -18,7 +18,7 @@ import com.google.auto.value.AutoValue; import com.google.common.collect.ImmutableList; -import com.google.idea.blaze.base.command.buildresult.BlazeArtifact; +import com.google.idea.blaze.common.artifact.BlazeArtifact; import javax.annotation.Nullable; /* Provides BlazeArtifacts to unpack an Aar. */ diff --git a/aswb/src/com/google/idea/blaze/android/libraries/RenderJarCache.java b/aswb/src/com/google/idea/blaze/android/libraries/RenderJarCache.java index 14e16b5b816..1958e0fa040 100644 --- a/aswb/src/com/google/idea/blaze/android/libraries/RenderJarCache.java +++ b/aswb/src/com/google/idea/blaze/android/libraries/RenderJarCache.java @@ -22,8 +22,6 @@ import com.google.idea.blaze.android.projectsystem.RenderJarClassFileFinder; import com.google.idea.blaze.android.sync.aspects.strategy.RenderResolveOutputGroupProvider; import com.google.idea.blaze.android.sync.importer.BlazeImportUtil; -import com.google.idea.blaze.base.command.buildresult.BlazeArtifact; -import com.google.idea.blaze.base.command.buildresult.OutputArtifact; import com.google.idea.blaze.base.filecache.FileCache; import com.google.idea.blaze.base.ideinfo.AndroidIdeInfo; import com.google.idea.blaze.base.ideinfo.ArtifactLocation; @@ -39,6 +37,8 @@ import com.google.idea.blaze.base.sync.data.BlazeDataStorage; import com.google.idea.blaze.base.sync.data.BlazeProjectDataManager; import com.google.idea.blaze.base.sync.workspace.ArtifactLocationDecoder; +import com.google.idea.blaze.common.artifact.BlazeArtifact; +import com.google.idea.blaze.common.artifact.OutputArtifactWithoutDigest; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.Project; import java.io.File; @@ -124,7 +124,7 @@ private void onSync( boolean removeMissingFiles = syncMode == SyncMode.INCREMENTAL; - ImmutableList artifactsToCache = + ImmutableList artifactsToCache = getArtifactsToCache(projectViewSet, projectData); artifactCache.putAll(artifactsToCache, context, removeMissingFiles); @@ -139,7 +139,7 @@ private void refresh(BlazeContext context, BlazeBuildOutputs buildOutput) { return; } - ImmutableList renderJars = + ImmutableList renderJars = buildOutput .getOutputGroupArtifacts( RenderResolveOutputGroupProvider.RESOLVE_OUTPUT_GROUP::contains) @@ -152,7 +152,7 @@ private void refresh(BlazeContext context, BlazeBuildOutputs buildOutput) { artifactCache.putAll(renderJars, context, false); } - private ImmutableList getArtifactsToCache( + private ImmutableList getArtifactsToCache( ProjectViewSet projectViewSet, BlazeProjectData projectData) { List renderJars = BlazeImportUtil.getSourceTargetsStream(project, projectData, projectViewSet) @@ -163,10 +163,10 @@ private ImmutableList getArtifactsToCache( .collect(Collectors.toList()); ArtifactLocationDecoder decoder = projectData.getArtifactLocationDecoder(); - List blazeArtifacts = + List blazeArtifacts = decoder.resolveOutputs(renderJars).stream() - .filter(artifact -> artifact instanceof OutputArtifact) - .map(artifact -> (OutputArtifact) artifact) + .filter(artifact -> artifact instanceof OutputArtifactWithoutDigest) + .map(artifact -> (OutputArtifactWithoutDigest) artifact) .collect(Collectors.toList()); return ImmutableList.copyOf(blazeArtifacts); } @@ -191,12 +191,12 @@ public File getCachedJarForBinaryTarget( } BlazeArtifact jarArtifact = artifactLocationDecoder.resolveOutput(jarArtifactLocation); - if (!(jarArtifact instanceof OutputArtifact)) { + if (!(jarArtifact instanceof OutputArtifactWithoutDigest)) { Logger.getInstance(RenderJarCache.class) .warn("Unexpected render jar that is not an OutputArtifact: " + jarArtifactLocation); return null; } - Path jarPath = artifactCache.get((OutputArtifact) jarArtifact); + Path jarPath = artifactCache.get((OutputArtifactWithoutDigest) jarArtifact); return jarPath == null ? null : jarPath.toFile(); } diff --git a/aswb/src/com/google/idea/blaze/android/libraries/UnpackedAarUtils.java b/aswb/src/com/google/idea/blaze/android/libraries/UnpackedAarUtils.java index 6921da1681e..08192537959 100644 --- a/aswb/src/com/google/idea/blaze/android/libraries/UnpackedAarUtils.java +++ b/aswb/src/com/google/idea/blaze/android/libraries/UnpackedAarUtils.java @@ -19,9 +19,9 @@ import static com.android.SdkConstants.FN_LINT_JAR; import com.android.SdkConstants; -import com.google.idea.blaze.base.command.buildresult.BlazeArtifact; -import com.google.idea.blaze.base.command.buildresult.OutputArtifact; import com.google.idea.blaze.base.command.buildresult.SourceArtifact; +import com.google.idea.blaze.common.artifact.BlazeArtifact; +import com.google.idea.blaze.common.artifact.OutputArtifactWithoutDigest; import com.intellij.openapi.util.io.FileUtil; import com.intellij.util.PathUtil; import java.io.File; @@ -36,8 +36,8 @@ public final class UnpackedAarUtils { /* Converts {@link BlazeArtifact} to the key which is used to create aar directory name */ public static String getArtifactKey(BlazeArtifact artifact) { - if (artifact instanceof OutputArtifact) { - return ((OutputArtifact) artifact).getKey(); + if (artifact instanceof OutputArtifactWithoutDigest) { + return ((OutputArtifactWithoutDigest) artifact).getBazelOutRelativePath(); } if (artifact instanceof SourceArtifact) { return ((SourceArtifact) artifact).getFile().getPath(); @@ -67,8 +67,7 @@ public static String getSrcJarName(BlazeArtifact srcJar) { * Returns aar directory name in the format of _. This provides flexibility to * caller to generate aar directory name to deal with different cases. But this method cannot * guarantee the uniqueness. - -* + * * @param name the file name of aar file without extension. * @param hashCode the file name of aar is not guaranteed to be unique, so a hash code is used to * make sure the directory name is unique. Caller needs to make sure the hashcode provided is diff --git a/aswb/src/com/google/idea/blaze/android/libraries/UnpackedAars.java b/aswb/src/com/google/idea/blaze/android/libraries/UnpackedAars.java index f7eddd1d6c0..0a5a0c491a8 100644 --- a/aswb/src/com/google/idea/blaze/android/libraries/UnpackedAars.java +++ b/aswb/src/com/google/idea/blaze/android/libraries/UnpackedAars.java @@ -25,8 +25,7 @@ import com.google.common.util.concurrent.ListenableFuture; import com.google.idea.blaze.android.sync.model.AarLibrary; import com.google.idea.blaze.base.async.FutureUtil; -import com.google.idea.blaze.base.command.buildresult.BlazeArtifact; -import com.google.idea.blaze.base.command.buildresult.BlazeArtifact.LocalFileArtifact; +import com.google.idea.blaze.base.command.buildresult.LocalFileArtifact; import com.google.idea.blaze.base.command.buildresult.RemoteOutputArtifact; import com.google.idea.blaze.base.filecache.FileCache; import com.google.idea.blaze.base.filecache.FileCacheDiffer; @@ -49,6 +48,7 @@ import com.google.idea.blaze.base.sync.libraries.BlazeLibraryCollector; import com.google.idea.blaze.base.sync.workspace.ArtifactLocationDecoder; import com.google.idea.blaze.common.PrintOutput; +import com.google.idea.blaze.common.artifact.BlazeArtifact; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.Project; import java.io.File; @@ -176,7 +176,8 @@ private void refresh( RemoteArtifactPrefetcher.getInstance() .downloadArtifacts( /* projectName= */ project.getName(), - /* outputArtifacts= */ BlazeArtifact.getRemoteArtifacts(artifactsToDownload)); + /* outputArtifacts= */ RemoteOutputArtifact.getRemoteArtifacts( + artifactsToDownload)); FutureUtil.waitForFuture(context, downloadArtifactsFuture) .timed("FetchAars", EventType.Prefetching) diff --git a/aswb/src/com/google/idea/blaze/android/libraries/Unpacker.java b/aswb/src/com/google/idea/blaze/android/libraries/Unpacker.java index 1e8abb69fcb..e29f972299e 100644 --- a/aswb/src/com/google/idea/blaze/android/libraries/Unpacker.java +++ b/aswb/src/com/google/idea/blaze/android/libraries/Unpacker.java @@ -22,10 +22,10 @@ import com.google.common.collect.ImmutableSet; import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; -import com.google.idea.blaze.base.command.buildresult.BlazeArtifact; -import com.google.idea.blaze.base.command.buildresult.BlazeArtifact.LocalFileArtifact; +import com.google.idea.blaze.base.command.buildresult.LocalFileArtifact; import com.google.idea.blaze.base.io.FileOperationProvider; import com.google.idea.blaze.base.prefetch.FetchExecutor; +import com.google.idea.blaze.common.artifact.BlazeArtifact; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.util.io.FileUtil; import com.intellij.util.io.ZipUtil; diff --git a/aswb/src/com/google/idea/blaze/android/manifest/ManifestParser.java b/aswb/src/com/google/idea/blaze/android/manifest/ManifestParser.java index 349b16fd2cd..3fb656a7708 100644 --- a/aswb/src/com/google/idea/blaze/android/manifest/ManifestParser.java +++ b/aswb/src/com/google/idea/blaze/android/manifest/ManifestParser.java @@ -86,6 +86,7 @@ public ParsedManifest( *

An invalid manifest is anything that could not be parsed by the parser, such as a malformed * manifest. */ + @Nullable public static ParsedManifest parseManifestFromInputStream(InputStream inputStream) throws IOException { Element manifestRootElement = getManifestRootElementFromInputStream(inputStream); diff --git a/aswb/sdkcompat/as223/com/google/idea/blaze/android/npw/project/BlazeAndroidModuleTemplate.java b/aswb/src/com/google/idea/blaze/android/npw/project/BlazeAndroidModuleTemplate.java similarity index 100% rename from aswb/sdkcompat/as223/com/google/idea/blaze/android/npw/project/BlazeAndroidModuleTemplate.java rename to aswb/src/com/google/idea/blaze/android/npw/project/BlazeAndroidModuleTemplate.java diff --git a/aswb/src/com/google/idea/blaze/android/projectsystem/BazelAddDestinationMenuToken.java b/aswb/src/com/google/idea/blaze/android/projectsystem/BazelAddDestinationMenuToken.java new file mode 100644 index 00000000000..6d57188b38c --- /dev/null +++ b/aswb/src/com/google/idea/blaze/android/projectsystem/BazelAddDestinationMenuToken.java @@ -0,0 +1,51 @@ +/* + * 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. + */ +package com.google.idea.blaze.android.projectsystem; + +import static com.android.tools.idea.util.DependencyManagementUtil.addDependenciesWithUiConfirmation; +import static com.android.tools.idea.util.DependencyManagementUtil.dependsOn; + +import com.android.ide.common.repository.GoogleMavenArtifactId; +import com.android.tools.idea.common.model.NlModel; +import com.android.tools.idea.naveditor.editor.AddDestinationMenuToken; +import com.intellij.openapi.module.Module; +import java.util.List; +import org.jetbrains.annotations.NotNull; + +/** Blaze implementation of project system tokens for the navigation editor: Add Destination Menu */ +public class BazelAddDestinationMenuToken + implements AddDestinationMenuToken, BazelToken { + @Override + public void modifyProject( + @NotNull BazelProjectSystem projectSystem, @NotNull AddDestinationMenuToken.Data data) { + NlModel model = data.getSurface().getModel(); + if (model == null) { + return; + } + Module module = model.getModule(); + if (dependsOn(module, GoogleMavenArtifactId.ANDROIDX_NAVIGATION_DYNAMIC_FEATURES_FRAGMENT)) { + return; + } + final var unused = + addDependenciesWithUiConfirmation( + module, + List.of( + GoogleMavenArtifactId.ANDROIDX_NAVIGATION_DYNAMIC_FEATURES_FRAGMENT.getCoordinate( + "+")), + true, + false); + } +} diff --git a/aswb/src/com/google/idea/blaze/android/projectsystem/BazelModuleDependencies.java b/aswb/src/com/google/idea/blaze/android/projectsystem/BazelModuleDependencies.java new file mode 100644 index 00000000000..d8fea990a70 --- /dev/null +++ b/aswb/src/com/google/idea/blaze/android/projectsystem/BazelModuleDependencies.java @@ -0,0 +1,83 @@ +/* + * Copyright 2024 The Bazel Authors. All rights reserved. + * + * 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. + */ +package com.google.idea.blaze.android.projectsystem; + +import static com.google.common.collect.ImmutableList.toImmutableList; + +import com.android.ide.common.repository.GoogleMavenArtifactId; +import com.android.projectmodel.ExternalAndroidLibrary; +import com.android.tools.idea.projectsystem.DependencyScopeType; +import com.android.tools.idea.rendering.PsiClassViewClass; +import com.android.tools.module.ModuleDependencies; +import com.android.tools.module.ViewClass; +import com.google.common.collect.ImmutableList; +import com.google.idea.blaze.android.resources.BlazeLightResourceClassService; +import com.intellij.openapi.module.Module; +import com.intellij.psi.JavaPsiFacade; +import java.util.List; +import java.util.Objects; +import java.util.function.Predicate; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +/** ASwB specific implementation of [ModuleDependencies]. */ +public class BazelModuleDependencies implements ModuleDependencies { + + Module module; + + BazelModuleDependencies(Module module) { + this.module = module; + } + + @Override + public boolean dependsOn(@NotNull GoogleMavenArtifactId googleMavenArtifactId) { + return false; + } + + /** + * Fetches the resource packages within the project and from external dependencies. Input + * parameter includeExternalLibraries is ignored as ASwB/Blaze uses a single workspace module to + * map both types of resources. + */ + @NotNull + @Override + public List getResourcePackageNames(boolean includeExternalLibraries) { + // TODO(b/304821496): Add an integration test to test it similar to BuildDependenciesTest + // TODO(b/307604153): Update AndroidExternalLibraryManager to read package name from multiple + // locations + return ImmutableList.builder() + .addAll( + BazelModuleSystem.getInstance(module) + .getAndroidLibraryDependencies(DependencyScopeType.MAIN) + .stream() + .map(ExternalAndroidLibrary::getPackageName) + .filter(Objects::nonNull) + .filter(Predicate.not(String::isEmpty)) + .collect(toImmutableList())) + .addAll( + BlazeLightResourceClassService.getInstance(module.getProject()) + .getWorkspaceResourcePackages()) + .build(); + } + + @Nullable + @Override + public ViewClass findViewClass(@NotNull String fqcn) { + JavaPsiFacade facade = JavaPsiFacade.getInstance(module.getProject()); + return new PsiClassViewClass( + facade.findClass(fqcn, module.getModuleWithDependenciesAndLibrariesScope(false))); + } +} diff --git a/aswb/src/com/google/idea/blaze/android/projectsystem/BazelModuleSystem.java b/aswb/src/com/google/idea/blaze/android/projectsystem/BazelModuleSystem.java new file mode 100644 index 00000000000..60ea3f85b51 --- /dev/null +++ b/aswb/src/com/google/idea/blaze/android/projectsystem/BazelModuleSystem.java @@ -0,0 +1,67 @@ +/* + * Copyright 2020 The Bazel Authors. All rights reserved. + * + * 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. + */ +package com.google.idea.blaze.android.projectsystem; + +import static com.google.common.collect.ImmutableList.toImmutableList; + +import com.android.tools.idea.projectsystem.AndroidModuleSystem; +import com.android.tools.module.ModuleDependencies; +import com.google.common.collect.ImmutableList; +import com.google.idea.blaze.base.settings.Blaze; +import com.google.idea.blaze.base.targetmaps.SourceToTargetMap; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.vfs.VirtualFile; +import java.io.File; +import java.nio.file.Path; + +/** Blaze implementation of {@link AndroidModuleSystem}. */ +public class BazelModuleSystem extends BlazeModuleSystemBase { + + BazelModuleSystem(Module module) { + super(module); + } + + @Override + public ModuleDependencies getModuleDependencies() { + return new BazelModuleDependencies(getModule()); + } + + public String blazeTargetNameToKotlinModuleName(String blazeTargetName) { + // Before: //third_party/java_src/android_app/compose_samples/Rally:lib + // After: third_party_java_src_android_app_compose_samples_Rally_lib + assert blazeTargetName.substring(0, 2).equals("//"); + return blazeTargetName.substring(2).replaceAll("['/',':']", "_"); + } + + /** Check every supporting extension point if they contain desugaring library config files */ + @Override + public boolean getDesugarLibraryConfigFilesKnown() { + return DesugaringLibraryConfigFilesLocator.forBuildSystem( + Blaze.getBuildSystemName(module.getProject())) + .stream() + .anyMatch(provider -> provider.getDesugarLibraryConfigFilesKnown()); + } + + /** Collect desugarig library config files from every supporting extension and return the list */ + @Override + public ImmutableList getDesugarLibraryConfigFiles() { + return DesugaringLibraryConfigFilesLocator.forBuildSystem( + Blaze.getBuildSystemName(module.getProject())) + .stream() + .flatMap(provider -> provider.getDesugarLibraryConfigFiles(project).stream()) + .collect(toImmutableList()); + } +} diff --git a/aswb/src/com/google/idea/blaze/android/projectsystem/BazelNavDesignSurfaceToken.java b/aswb/src/com/google/idea/blaze/android/projectsystem/BazelNavDesignSurfaceToken.java new file mode 100644 index 00000000000..a976873d5ab --- /dev/null +++ b/aswb/src/com/google/idea/blaze/android/projectsystem/BazelNavDesignSurfaceToken.java @@ -0,0 +1,55 @@ +/* + * 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. + */ +package com.google.idea.blaze.android.projectsystem; + +import static com.android.tools.idea.util.DependencyManagementUtil.addDependenciesWithUiConfirmation; +import static com.google.common.collect.ImmutableList.toImmutableList; + +import com.android.ide.common.repository.GradleCoordinate; +import com.android.tools.idea.common.model.NlModel; +import com.android.tools.idea.naveditor.surface.NavDesignSurface; +import com.android.tools.idea.naveditor.surface.NavDesignSurfaceToken; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.module.Module; +import java.util.List; +import java.util.concurrent.atomic.AtomicBoolean; +import org.jetbrains.annotations.NotNull; + +/** Blaze implementation of project system tokens for the navigation editor: Nav Design Surface */ +public class BazelNavDesignSurfaceToken implements NavDesignSurfaceToken, BazelToken { + @Override + public boolean modifyProject(@NotNull BazelProjectSystem projectSystem, @NotNull NlModel model) { + AtomicBoolean didAdd = new AtomicBoolean(false); + Module module = model.getModule(); + List coordinates = + NavDesignSurface.getDependencies(module).stream() + .map((a) -> a.getCoordinate("+")) + .collect(toImmutableList()); + Runnable runnable = + () -> { + try { + didAdd.set( + addDependenciesWithUiConfirmation(module, coordinates, true, false).isEmpty()); + } catch (Throwable t) { + Logger.getInstance(NavDesignSurface.class).warn("Failed to add dependencies", t); + didAdd.set(false); + } + }; + ApplicationManager.getApplication().invokeAndWait(runnable); + return didAdd.get(); + } +} diff --git a/aswb/src/com/google/idea/blaze/android/projectsystem/BazelProjectSystem.java b/aswb/src/com/google/idea/blaze/android/projectsystem/BazelProjectSystem.java new file mode 100644 index 00000000000..f289c05fcb5 --- /dev/null +++ b/aswb/src/com/google/idea/blaze/android/projectsystem/BazelProjectSystem.java @@ -0,0 +1,301 @@ +/* + * Copyright 2017 The Bazel Authors. All rights reserved. + * + * 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. + */ +package com.google.idea.blaze.android.projectsystem; + +import static com.android.tools.idea.projectsystem.SourceProvidersKt.emptySourceProvider; +import static com.google.idea.blaze.base.sync.data.BlazeDataStorage.WORKSPACE_MODULE_NAME; +import static org.jetbrains.android.facet.SourceProviderUtil.createSourceProvidersForLegacyModule; + +import com.android.tools.apk.analyzer.AaptInvoker; +import com.android.tools.idea.log.LogWrapper; +import com.android.tools.idea.model.AndroidModel; +import com.android.tools.idea.model.ClassJarProvider; +import com.android.tools.idea.projectsystem.AndroidProjectSystem; +import com.android.tools.idea.projectsystem.CommonTestType; +import com.android.tools.idea.projectsystem.NamedIdeaSourceProvider; +import com.android.tools.idea.projectsystem.ProjectSystemBuildManager; +import com.android.tools.idea.projectsystem.ProjectSystemSyncManager; +import com.android.tools.idea.projectsystem.ScopeType; +import com.android.tools.idea.projectsystem.SourceProviderManager; +import com.android.tools.idea.projectsystem.SourceProviders; +import com.android.tools.idea.projectsystem.SourceProvidersFactory; +import com.android.tools.idea.projectsystem.SourceProvidersImpl; +import com.android.tools.idea.res.AndroidInnerClassFinder; +import com.android.tools.idea.res.AndroidResourceClassPsiElementFinder; +import com.android.tools.idea.sdk.AndroidSdks; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableSet; +import com.google.idea.blaze.android.resources.BlazeLightResourceClassService; +import com.google.idea.blaze.android.sync.model.idea.BlazeAndroidModel; +import com.google.idea.blaze.android.sync.model.idea.BlazeClassJarProvider; +import com.google.idea.blaze.base.settings.Blaze; +import com.google.idea.blaze.base.settings.BlazeImportSettings.ProjectType; +import com.intellij.facet.ProjectFacetManager; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.ModuleManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiElementFinder; +import com.intellij.psi.search.GlobalSearchScope; +import java.nio.file.Path; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; +import javax.annotation.Nullable; +import org.jetbrains.android.facet.AndroidFacet; +import org.jetbrains.android.sdk.AndroidPlatforms; +import org.jetbrains.annotations.NotNull; + +/** + * Base class to implement common methods in {@link AndroidProjectSystem} for blaze with different + * sdk + */ +public class BazelProjectSystem implements AndroidProjectSystem { + protected final Project project; + protected final ProjectSystemSyncManager syncManager; + protected final List myFinders; + private final BlazeProjectSystemBuildManager buildManager; + + public BazelProjectSystem(Project project) { + this.project = project; + syncManager = new BlazeProjectSystemSyncManager(project); + buildManager = new BlazeProjectSystemBuildManager(project); + + myFinders = + Arrays.asList( + AndroidInnerClassFinder.INSTANCE, + new AndroidResourceClassPsiElementFinder(getLightResourceClassService())); + } + + @Override + public Project getProject() { + return project; + } + + @Override + public boolean allowsFileCreation() { + return true; + } + + @Nullable + @Override + public VirtualFile getDefaultApkFile() { + return null; + } + + @Override + public Path getPathToAapt() { + return AaptInvoker.getPathToAapt( + AndroidSdks.getInstance().tryToChooseSdkHandler(), + new LogWrapper(BazelProjectSystem.class)); + } + + @Override + public ProjectSystemBuildManager getBuildManager() { + return buildManager; + } + + @Override + public BazelModuleSystem getModuleSystem(Module module) { + return BazelModuleSystem.getInstance(module); + } + + @Override + public ProjectSystemSyncManager getSyncManager() { + return syncManager; + } + + @Override + public Collection getPsiElementFinders() { + return myFinders; + } + + @Override + public BlazeLightResourceClassService getLightResourceClassService() { + return BlazeLightResourceClassService.getInstance(project); + } + + @Override + public SourceProvidersFactory getSourceProvidersFactory() { + return new SourceProvidersFactory() { + @Override + public SourceProviders createSourceProvidersFor(AndroidFacet facet) { + BlazeAndroidModel model = ((BlazeAndroidModel) AndroidModel.get(facet)); + if (model != null) { + return createForModel(model); + } else { + return createSourceProvidersForLegacyModule(facet); + } + } + + private SourceProviders createForModel(BlazeAndroidModel model) { + NamedIdeaSourceProvider mainSourceProvider = model.getDefaultSourceProvider(); + if (Blaze.getProjectType(project).equals(ProjectType.QUERY_SYNC)) { + return new SourceProvidersImpl( + mainSourceProvider, + ImmutableList.of(mainSourceProvider), + ImmutableMap.of(CommonTestType.UNIT_TEST, ImmutableList.of()), + ImmutableMap.of(CommonTestType.ANDROID_TEST, ImmutableList.of()), + ImmutableList.of(), + ImmutableList.of(mainSourceProvider), + ImmutableList.of(mainSourceProvider), + ImmutableList.of(mainSourceProvider), + emptySourceProvider(ScopeType.MAIN), + ImmutableMap.of(CommonTestType.UNIT_TEST, emptySourceProvider(ScopeType.UNIT_TEST)), + ImmutableMap.of( + CommonTestType.ANDROID_TEST, emptySourceProvider(ScopeType.ANDROID_TEST)), + emptySourceProvider(ScopeType.TEST_FIXTURES)); + } else { + return new SourceProvidersImpl( + mainSourceProvider, + ImmutableList.of(mainSourceProvider), + ImmutableMap.of(CommonTestType.UNIT_TEST, ImmutableList.of(mainSourceProvider)), + ImmutableMap.of(CommonTestType.ANDROID_TEST, ImmutableList.of(mainSourceProvider)), + ImmutableList.of(mainSourceProvider), + ImmutableList.of(mainSourceProvider), + ImmutableList.of(mainSourceProvider), + ImmutableList.of(mainSourceProvider), + emptySourceProvider(ScopeType.MAIN), + ImmutableMap.of(CommonTestType.UNIT_TEST, emptySourceProvider(ScopeType.UNIT_TEST)), + ImmutableMap.of( + CommonTestType.ANDROID_TEST, emptySourceProvider(ScopeType.ANDROID_TEST)), + emptySourceProvider(ScopeType.TEST_FIXTURES)); + } + } + }; + } + + @Override + public ClassJarProvider getClassJarProvider() { + return new BlazeClassJarProvider(project); + } + + @Override + public Collection getAndroidFacetsWithPackageName(String packageName) { + return getAndroidFacetsWithPackageName( + project, packageName, GlobalSearchScope.projectScope(project)); + } + + private Collection getAndroidFacetsWithPackageName( + Project project, String packageName, GlobalSearchScope scope) { + List facets = ProjectFacetManager.getInstance(project).getFacets(AndroidFacet.ID); + return facets.stream() + .filter(facet -> hasPackageName(facet, packageName)) + .filter( + facet -> { + VirtualFile file = SourceProviderManager.getInstance(facet).getMainManifestFile(); + if (file == null) { + return false; + } else { + return scope.contains(file); + } + }) + .collect(Collectors.toList()); + } + + @Override + public boolean isNamespaceOrParentPackage(@NotNull String packageName) { + List facets = ProjectFacetManager.getInstance(project).getFacets(AndroidFacet.ID); + GlobalSearchScope scope = GlobalSearchScope.projectScope(project); + for (AndroidFacet facet : facets) { + String moduleNamespace = PackageNameUtils.getPackageName(facet.getModule()); + if (moduleNamespace == null) { + continue; + } + // Check if the moduleNamespace is exactly the package name, or is a subpackage + if (!moduleNamespace.startsWith(packageName)) { + continue; + } + // packageName=com.example should not match moduleNamespace=com.example2 + if (moduleNamespace.length() > packageName.length() + && moduleNamespace.charAt(packageName.length()) != '.') { + continue; + } + VirtualFile file = SourceProviderManager.getInstance(facet).getMainManifestFile(); + if (file == null || !scope.contains(file)) { + continue; + } + return true; + } + return false; + } + + @NotNull + @Override + public Set getKnownApplicationIds() { + List facets = ProjectFacetManager.getInstance(project).getFacets(AndroidFacet.ID); + Set applicationIds = new HashSet<>(facets.size()); + for (AndroidFacet facet : facets) { + AndroidModel model = AndroidModel.get(facet); + if (model == null) { + continue; + } + applicationIds.addAll(model.getAllApplicationIds()); + } + return Collections.unmodifiableSet(applicationIds); + } + + @NotNull + @Override + public Collection findModulesWithApplicationId(@NotNull String applicationId) { + if (Blaze.getProjectType(project).equals(ProjectType.QUERY_SYNC)) { + Module workspaceModule = + ModuleManager.getInstance(project).findModuleByName(WORKSPACE_MODULE_NAME); + if (workspaceModule != null) { + return ImmutableList.of(workspaceModule); + } else { + return ImmutableList.of(); + } + } + List facets = ProjectFacetManager.getInstance(project).getFacets(AndroidFacet.ID); + ImmutableSet.Builder resultBuilder = ImmutableSet.builder(); + for (AndroidFacet facet : facets) { + AndroidModel model = AndroidModel.get(facet); + if (model != null && model.getApplicationId().equals(applicationId)) { + resultBuilder.add(facet.getModule()); + } + } + return resultBuilder.build(); + } + + @Override + public Collection getSubmodules() { + return ImmutableList.of(); + } + + @Override + public Collection getBootClasspath(@NotNull Module module) { + return AndroidPlatforms.getInstance(module).getTarget().getBootClasspath(); + } + + @Override + public boolean isAndroidProject() { + return ProjectFacetManager.getInstance(project).hasFacets(AndroidFacet.ID); + } + + private static boolean hasPackageName(AndroidFacet facet, String packageName) { + String nameFromFacet = PackageNameUtils.getPackageName(facet.getModule()); + if (nameFromFacet == null) { + return false; + } + return nameFromFacet.equals(packageName); + } +} diff --git a/aswb/src/com/google/idea/blaze/android/projectsystem/BazelToken.java b/aswb/src/com/google/idea/blaze/android/projectsystem/BazelToken.java new file mode 100644 index 00000000000..1cb89b26419 --- /dev/null +++ b/aswb/src/com/google/idea/blaze/android/projectsystem/BazelToken.java @@ -0,0 +1,27 @@ +/* + * Copyright 2023 The Bazel Authors. All rights reserved. + * + * 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. + */ +package com.google.idea.blaze.android.projectsystem; + +import com.android.tools.idea.projectsystem.AndroidProjectSystem; +import com.android.tools.idea.projectsystem.Token; + +/** A mix-in implementation of the {@link Token} interface for the Blaze project system. */ +public interface BazelToken extends Token { + @Override + default boolean isApplicable(AndroidProjectSystem projectSystem) { + return projectSystem instanceof BazelProjectSystem; + } +} diff --git a/aswb/src/com/google/idea/blaze/android/projectsystem/BlazeModuleSystem.java b/aswb/src/com/google/idea/blaze/android/projectsystem/BlazeModuleSystem.java deleted file mode 100644 index 223613c89f2..00000000000 --- a/aswb/src/com/google/idea/blaze/android/projectsystem/BlazeModuleSystem.java +++ /dev/null @@ -1,197 +0,0 @@ -/* - * Copyright 2020 The Bazel Authors. All rights reserved. - * - * 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. - */ -package com.google.idea.blaze.android.projectsystem; - -import static com.google.common.collect.ImmutableList.toImmutableList; - -import com.android.ide.common.util.PathString; -import com.android.projectmodel.ExternalAndroidLibrary; -import com.android.projectmodel.ExternalLibraryImpl; -import com.android.projectmodel.SelectiveResourceFolder; -import com.android.tools.idea.projectsystem.AndroidModuleSystem; -import com.android.tools.idea.projectsystem.DependencyScopeType; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; -import com.google.idea.blaze.android.libraries.UnpackedAars; -import com.google.idea.blaze.android.sync.model.AarLibrary; -import com.google.idea.blaze.android.sync.model.AndroidResourceModuleRegistry; -import com.google.idea.blaze.android.sync.model.BlazeAndroidSyncData; -import com.google.idea.blaze.android.sync.qsync.AndroidExternalLibraryManager; -import com.google.idea.blaze.base.ideinfo.TargetIdeInfo; -import com.google.idea.blaze.base.model.BlazeLibrary; -import com.google.idea.blaze.base.model.BlazeProjectData; -import com.google.idea.blaze.base.projectview.ProjectViewManager; -import com.google.idea.blaze.base.qsync.QuerySync; -import com.google.idea.blaze.base.qsync.cache.ArtifactTracker; -import com.google.idea.blaze.base.settings.BlazeImportSettingsManager; -import com.google.idea.blaze.base.sync.SyncCache; -import com.google.idea.blaze.base.sync.data.BlazeProjectDataManager; -import com.google.idea.blaze.base.sync.libraries.BlazeLibraryCollector; -import com.google.idea.blaze.base.sync.workspace.ArtifactLocationDecoder; -import com.intellij.openapi.diagnostic.Logger; -import com.intellij.openapi.module.Module; -import com.intellij.openapi.project.Project; -import java.io.File; -import java.io.IOException; -import java.io.UncheckedIOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.Collection; -import java.util.Collections; -import java.util.stream.Stream; -import org.jetbrains.annotations.Nullable; - -/** Blaze implementation of {@link AndroidModuleSystem}. */ -public class BlazeModuleSystem extends BlazeModuleSystemBase { - - private static final Logger logger = Logger.getInstance(BlazeModuleSystem.class); - private AndroidExternalLibraryManager androidExternalLibraryManager = null; - - BlazeModuleSystem(Module module) { - super(module); - if (QuerySync.isEnabled()) { - androidExternalLibraryManager = - new AndroidExternalLibraryManager( - () -> { - Path aarDirectory = - ArtifactTracker.getExternalAarDirectory( - BlazeImportSettingsManager.getInstance(module.getProject()) - .getImportSettings()); - // This can be called by the IDE as the user navigates the project and so might be - // called before a sync has been completed and the project structure has been set - // up. - if (!aarDirectory.toFile().exists()) { - logger.warn("Aar library directory not created yet"); - return ImmutableList.of(); - } - try (Stream stream = Files.list(aarDirectory)) { - return stream.collect(toImmutableList()); - } catch (IOException ioe) { - throw new UncheckedIOException("Could not list aars", ioe); - } - }); - } - } - - public Collection getDependentLibraries() { - if (QuerySync.isEnabled()) { - return androidExternalLibraryManager.getExternalLibraries(); - } - BlazeProjectData blazeProjectData = - BlazeProjectDataManager.getInstance(project).getBlazeProjectData(); - - if (blazeProjectData == null) { - return ImmutableList.of(); - } - - if (isWorkspaceModule) { - return SyncCache.getInstance(project) - .get(BlazeModuleSystem.class, BlazeModuleSystem::getLibrariesForWorkspaceModule); - } - - AndroidResourceModuleRegistry registry = AndroidResourceModuleRegistry.getInstance(project); - TargetIdeInfo target = blazeProjectData.getTargetMap().get(registry.getTargetKey(module)); - if (target == null) { - // this can happen if the module points to the , - // does not contain any resource - // contains all external resources as module's local resources, so there's - // no dependent libraries - return ImmutableList.of(); - } - - BlazeAndroidSyncData androidSyncData = - blazeProjectData.getSyncState().get(BlazeAndroidSyncData.class); - if (androidSyncData == null) { - return ImmutableList.of(); - } - - ImmutableList.Builder libraries = ImmutableList.builder(); - ArtifactLocationDecoder decoder = blazeProjectData.getArtifactLocationDecoder(); - ExternalLibraryInterner externalLibraryInterner = ExternalLibraryInterner.getInstance(project); - for (String libraryKey : registry.get(module).resourceLibraryKeys) { - ImmutableMap aarLibraries = androidSyncData.importResult.aarLibraries; - ExternalAndroidLibrary externalLibrary = - toExternalLibrary(project, aarLibraries.get(libraryKey), decoder); - if (externalLibrary != null) { - libraries.add(externalLibraryInterner.intern(externalLibrary)); - } - } - return libraries.build(); - } - - private static ImmutableList getLibrariesForWorkspaceModule( - Project project, BlazeProjectData blazeProjectData) { - ArtifactLocationDecoder decoder = blazeProjectData.getArtifactLocationDecoder(); - ExternalLibraryInterner externalLibraryInterner = ExternalLibraryInterner.getInstance(project); - ImmutableList.Builder libraries = ImmutableList.builder(); - for (BlazeLibrary library : - BlazeLibraryCollector.getLibraries( - ProjectViewManager.getInstance(project).getProjectViewSet(), blazeProjectData)) { - if (library instanceof AarLibrary) { - ExternalAndroidLibrary externalLibrary = - toExternalLibrary(project, (AarLibrary) library, decoder); - if (externalLibrary != null) { - libraries.add(externalLibraryInterner.intern(externalLibrary)); - } - } - } - return libraries.build(); - } - - @Nullable - static ExternalAndroidLibrary toExternalLibrary( - Project project, @Nullable AarLibrary library, ArtifactLocationDecoder decoder) { - if (library == null) { - return null; - } - UnpackedAars unpackedAars = UnpackedAars.getInstance(project); - File aarFile = unpackedAars.getAarDir(decoder, library); - if (aarFile == null) { - logger.warn( - String.format( - "Fail to locate AAR file %s. Re-sync the project may solve the problem", - library.aarArtifact)); - return null; - } - File resFolder = unpackedAars.getResourceDirectory(decoder, library); - PathString resFolderPathString = resFolder == null ? null : new PathString(resFolder); - return new ExternalLibraryImpl(library.key.toString()) - .withLocation(new PathString(aarFile)) - .withManifestFile( - resFolderPathString == null - ? null - : resFolderPathString.getParentOrRoot().resolve("AndroidManifest.xml")) - .withResFolder( - resFolderPathString == null - ? null - : new SelectiveResourceFolder(resFolderPathString, null)) - .withSymbolFile( - resFolderPathString == null - ? null - : resFolderPathString.getParentOrRoot().resolve("R.txt")) - .withPackageName(library.resourcePackage); - } - - @Override - public Collection getAndroidLibraryDependencies( - DependencyScopeType dependencyScopeType) { - if (dependencyScopeType == DependencyScopeType.MAIN) { - return getDependentLibraries(); - } else { - return Collections.emptyList(); - } - } -} diff --git a/aswb/src/com/google/idea/blaze/android/projectsystem/BlazeModuleSystemBase.java b/aswb/src/com/google/idea/blaze/android/projectsystem/BlazeModuleSystemBase.java index c90ede3f88a..d25d379f47d 100644 --- a/aswb/src/com/google/idea/blaze/android/projectsystem/BlazeModuleSystemBase.java +++ b/aswb/src/com/google/idea/blaze/android/projectsystem/BlazeModuleSystemBase.java @@ -15,9 +15,16 @@ */ package com.google.idea.blaze.android.projectsystem; +import static com.google.common.collect.ImmutableList.toImmutableList; +import static com.google.common.collect.ImmutableSet.toImmutableSet; +import static java.util.Arrays.stream; + import com.android.ide.common.repository.GradleCoordinate; import com.android.ide.common.util.PathString; import com.android.manifmerger.ManifestSystemProperty; +import com.android.projectmodel.ExternalAndroidLibrary; +import com.android.projectmodel.ExternalLibraryImpl; +import com.android.projectmodel.SelectiveResourceFolder; import com.android.tools.idea.projectsystem.AndroidModuleSystem; import com.android.tools.idea.projectsystem.CapabilityNotSupported; import com.android.tools.idea.projectsystem.CapabilityStatus; @@ -34,27 +41,43 @@ import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Iterables; import com.google.idea.blaze.android.compose.ComposeStatusProvider; import com.google.idea.blaze.android.libraries.UnpackedAars; import com.google.idea.blaze.android.npw.project.BlazeAndroidModuleTemplate; +import com.google.idea.blaze.android.sync.model.AarLibrary; import com.google.idea.blaze.android.sync.model.AndroidResourceModule; import com.google.idea.blaze.android.sync.model.AndroidResourceModuleRegistry; +import com.google.idea.blaze.android.sync.model.BlazeAndroidSyncData; import com.google.idea.blaze.base.command.buildresult.OutputArtifactResolver; -import com.google.idea.blaze.base.ideinfo.AndroidAarIdeInfo; import com.google.idea.blaze.base.ideinfo.ArtifactLocation; import com.google.idea.blaze.base.ideinfo.Dependency; import com.google.idea.blaze.base.ideinfo.TargetIdeInfo; import com.google.idea.blaze.base.ideinfo.TargetKey; import com.google.idea.blaze.base.io.VfsUtils; import com.google.idea.blaze.base.lang.buildfile.references.BuildReferenceManager; +import com.google.idea.blaze.base.model.BlazeLibrary; import com.google.idea.blaze.base.model.BlazeProjectData; import com.google.idea.blaze.base.model.primitives.WorkspaceRoot; -import com.google.idea.blaze.base.qsync.QuerySync; +import com.google.idea.blaze.base.projectview.ProjectViewManager; +import com.google.idea.blaze.base.qsync.QuerySyncManager; +import com.google.idea.blaze.base.qsync.QuerySyncProject; import com.google.idea.blaze.base.settings.Blaze; +import com.google.idea.blaze.base.settings.BlazeImportSettings.ProjectType; +import com.google.idea.blaze.base.settings.BlazeImportSettingsManager; +import com.google.idea.blaze.base.sync.SyncCache; import com.google.idea.blaze.base.sync.data.BlazeDataStorage; import com.google.idea.blaze.base.sync.data.BlazeProjectDataManager; +import com.google.idea.blaze.base.sync.libraries.BlazeLibraryCollector; +import com.google.idea.blaze.base.sync.workspace.ArtifactLocationDecoder; import com.google.idea.blaze.base.targetmaps.ReverseDependencyMap; import com.google.idea.blaze.base.targetmaps.TransitiveDependencyMap; +import com.google.idea.blaze.common.Label; +import com.google.idea.blaze.qsync.QuerySyncProjectSnapshot; +import com.google.idea.blaze.qsync.SnapshotHolder; +import com.google.idea.blaze.qsync.project.ProjectPath; +import com.google.idea.blaze.qsync.project.ProjectProto; import com.google.idea.common.experiments.BoolExperiment; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.diagnostic.Logger; @@ -62,7 +85,6 @@ import com.intellij.openapi.fileEditor.OpenFileDescriptor; import com.intellij.openapi.module.Module; import com.intellij.openapi.module.ModuleManager; -import com.intellij.openapi.module.ModuleServiceManager; import com.intellij.openapi.project.Project; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiElement; @@ -71,12 +93,11 @@ import java.io.File; import java.io.IOException; import java.nio.file.Path; -import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; import java.util.List; import java.util.Map; import java.util.Objects; -import java.util.Set; -import java.util.stream.Collectors; import java.util.stream.Stream; import kotlin.Triple; import org.jetbrains.annotations.Nullable; @@ -94,9 +115,10 @@ abstract class BlazeModuleSystemBase implements AndroidModuleSystem { public static final BoolExperiment returnSimpleDirectResourceDependents = new BoolExperiment("aswb.return.simple.direct.resource.dependents", true); - protected static final Logger logger = Logger.getInstance(BlazeModuleSystem.class); + protected static final Logger logger = Logger.getInstance(BazelModuleSystem.class); protected Module module; protected final Project project; + private final ProjectPath.Resolver pathResolver; SampleDataDirectoryProvider sampleDataDirectoryProvider; RenderJarClassFileFinder classFileFinder; final boolean isWorkspaceModule; @@ -104,9 +126,16 @@ abstract class BlazeModuleSystemBase implements AndroidModuleSystem { BlazeModuleSystemBase(Module module) { this.module = module; this.project = module.getProject(); + this.pathResolver = + ProjectPath.Resolver.create( + WorkspaceRoot.fromProject(project).path(), + Path.of( + BlazeImportSettingsManager.getInstance(project) + .getImportSettings() + .getProjectDataDirectory())); classFileFinder = new RenderJarClassFileFinder(module); sampleDataDirectoryProvider = new BlazeSampleDataDirectoryProvider(module); - isWorkspaceModule = BlazeDataStorage.WORKSPACE_MODULE_NAME.equals(module.getName()); + isWorkspaceModule = module.getName().equals(BlazeDataStorage.WORKSPACE_MODULE_NAME); } @Override @@ -226,17 +255,27 @@ public GradleCoordinate getRegisteredDependency(GradleCoordinate coordinate) { return null; } - Set firstLevelDeps = + ImmutableSet firstLevelDeps = resourceModuleTarget.getDependencies().stream() .map(Dependency::getTargetKey) - .collect(Collectors.toSet()); + .collect(toImmutableSet()); return locateArtifactsFor(coordinate).anyMatch(firstLevelDeps::contains) ? coordinate : null; } + @Nullable + private Label getResolvedLabel(GradleCoordinate coordinate) { + return MavenArtifactLocator.forBuildSystem(Blaze.getBuildSystemName(module.getProject())) + .stream() + .map(locator -> locator.labelFor(coordinate)) + .map(l -> Label.of(l.toString())) + .findFirst() + .orElse(null); + } + @Nullable private TargetKey getResolvedTarget(GradleCoordinate coordinate) { - if (QuerySync.isEnabled()) { + if (Blaze.getProjectType(project) == ProjectType.QUERY_SYNC) { // TODO (b/262289199): While there is a way of mapping a gradle coordinate to a target, // that is a very tricky practice that while it could be supported with Query Sync, we // should try to avoid it. @@ -288,38 +327,6 @@ public GradleCoordinate getResolvedDependency( return target != null ? gradleCoordinate : null; } - /** - * Returns the absolute path of the dependency, if it exists. - * - * @param coordinate external coordinates for the dependency. - * @return the absolute path of the dependency including workspace root and path. - */ - @Override - @Nullable - public Path getDependencyPath(GradleCoordinate coordinate) { - TargetKey target = getResolvedTarget(coordinate); - if (target == null) { - return null; - } - BlazeProjectData projectData = - BlazeProjectDataManager.getInstance(project).getBlazeProjectData(); - Path defaultPath = - WorkspaceRoot.fromProject(project).fileForPath(target.getLabel().blazePackage()).toPath(); - if (projectData == null) { - return defaultPath; - } - - AndroidAarIdeInfo aarIdeInfo = projectData.getTargetMap().get(target).getAndroidAarIdeInfo(); - // Returns its local aar directory path (if exists) instead of google3 one for imported aars. - if (aarIdeInfo == null) { - return defaultPath; - } - File aarDir = - UnpackedAars.getInstance(module.getProject()) - .getAarDir(projectData.getArtifactLocationDecoder(), aarIdeInfo.getAar()); - return aarDir == null || !aarDir.exists() ? defaultPath : aarDir.toPath(); - } - private Stream locateArtifactsFor(GradleCoordinate coordinate) { // External dependencies can be imported into the project via many routes (e.g. maven_jar, // local_repository, custom repo paths, etc). Within the project these dependencies are all @@ -340,7 +347,7 @@ private Stream locateArtifactsFor(GradleCoordinate coordinate) { */ @Override public List getResourceModuleDependencies() { - if (QuerySync.isEnabled()) { + if (Blaze.getProjectType(project) == ProjectType.QUERY_SYNC) { return ImmutableList.of(); } AndroidResourceModuleRegistry resourceModuleRegistry = @@ -348,9 +355,9 @@ public List getResourceModuleDependencies() { if (isWorkspaceModule) { // The workspace module depends on every resource module. - return Arrays.stream(ModuleManager.getInstance(project).getModules()) + return stream(ModuleManager.getInstance(project).getModules()) .filter(module -> resourceModuleRegistry.get(module) != null) - .collect(Collectors.toList()); + .collect(toImmutableList()); } AndroidResourceModule resourceModule = resourceModuleRegistry.get(module); if (resourceModule == null) { @@ -360,7 +367,7 @@ public List getResourceModuleDependencies() { return resourceModule.transitiveResourceDependencies.stream() .map(resourceModuleRegistry::getModuleContainingResourcesOf) .filter(Objects::nonNull) - .collect(Collectors.toList()); + .collect(toImmutableList()); } @Override @@ -400,7 +407,7 @@ public List getDirectResourceModuleDependents() { .map(TargetIdeInfo::getKey) .map(resourceModuleRegistry::getModuleContainingResourcesOf) .filter(Objects::nonNull) - .collect(Collectors.toList()); + .collect(toImmutableList()); } @Override @@ -437,7 +444,7 @@ public ManifestOverrides getManifestOverrides() { manifestValues.forEach( (key, value) -> ManifestValueProcessor.processManifestValue(key, value, directOverrides, placeholders)); - return new ManifestOverrides(directOverrides.build(), placeholders.build()); + return new ManifestOverrides(directOverrides.buildOrThrow(), placeholders.buildOrThrow()); } @Override @@ -457,13 +464,158 @@ public boolean getUsesCompose() { return ComposeStatusProvider.isComposeEnabled(project); } + public Collection getDependentLibraries() { + if (Blaze.getProjectType(project) == ProjectType.QUERY_SYNC) { + ProjectProto.Project projectProto = + QuerySyncManager.getInstance(project) + .getLoadedProject() + .map(QuerySyncProject::getSnapshotHolder) + .flatMap(SnapshotHolder::getCurrent) + .map(QuerySyncProjectSnapshot::project) + .orElse(null); + if (projectProto == null) { + return ImmutableList.of(); + } + ImmutableList matchingModules = + projectProto.getModulesList().stream() + .filter(m -> m.getName().equals(module.getName())) + .collect(ImmutableList.toImmutableList()); + if (matchingModules.isEmpty()) { + return ImmutableList.of(); + } + return Iterables.getOnlyElement(matchingModules).getAndroidExternalLibrariesList().stream() + .map(this::fromProto) + .collect(toImmutableList()); + } + BlazeProjectData blazeProjectData = + BlazeProjectDataManager.getInstance(project).getBlazeProjectData(); + + if (blazeProjectData == null) { + return ImmutableList.of(); + } + + if (isWorkspaceModule) { + return SyncCache.getInstance(project) + .get(BazelModuleSystem.class, BlazeModuleSystemBase::getLibrariesForWorkspaceModule); + } + + AndroidResourceModuleRegistry registry = AndroidResourceModuleRegistry.getInstance(project); + TargetIdeInfo target = blazeProjectData.getTargetMap().get(registry.getTargetKey(module)); + if (target == null) { + // this can happen if the module points to the , + // does not contain any resource + // contains all external resources as module's local resources, so there's + // no dependent libraries + return ImmutableList.of(); + } + + BlazeAndroidSyncData androidSyncData = + blazeProjectData.getSyncState().get(BlazeAndroidSyncData.class); + if (androidSyncData == null) { + return ImmutableList.of(); + } + + ImmutableList.Builder libraries = ImmutableList.builder(); + ArtifactLocationDecoder decoder = blazeProjectData.getArtifactLocationDecoder(); + ExternalLibraryInterner externalLibraryInterner = ExternalLibraryInterner.getInstance(project); + for (String libraryKey : registry.get(module).resourceLibraryKeys) { + ImmutableMap aarLibraries = androidSyncData.importResult.aarLibraries; + ExternalAndroidLibrary externalLibrary = + toExternalLibrary(project, aarLibraries.get(libraryKey), decoder); + if (externalLibrary != null) { + libraries.add(externalLibraryInterner.intern(externalLibrary)); + } + } + return libraries.build(); + } + + private ExternalAndroidLibrary fromProto(ProjectProto.ExternalAndroidLibrary proto) { + ExternalLibraryImpl lib = + new ExternalLibraryImpl(proto.getName()) + .withLocation(toPathString(proto.getLocation())) + .withManifestFile(toPathString(proto.getManifestFile())) + .withResFolder(new SelectiveResourceFolder(toPathString(proto.getResFolder()), null)) + .withSymbolFile(toPathString(proto.getSymbolFile())); + if (!proto.getPackageName().isEmpty()) { + lib = lib.withPackageName(proto.getPackageName()); + } + return lib; + } + + private PathString toPathString(ProjectProto.ProjectPath projectPath) { + return new PathString(pathResolver.resolve(ProjectPath.create(projectPath))); + } + + private static ImmutableList getLibrariesForWorkspaceModule( + Project project, BlazeProjectData blazeProjectData) { + ArtifactLocationDecoder decoder = blazeProjectData.getArtifactLocationDecoder(); + ExternalLibraryInterner externalLibraryInterner = ExternalLibraryInterner.getInstance(project); + ImmutableList.Builder libraries = ImmutableList.builder(); + for (BlazeLibrary library : + BlazeLibraryCollector.getLibraries( + ProjectViewManager.getInstance(project).getProjectViewSet(), blazeProjectData)) { + if (library instanceof AarLibrary) { + ExternalAndroidLibrary externalLibrary = + toExternalLibrary(project, (AarLibrary) library, decoder); + if (externalLibrary != null) { + libraries.add(externalLibraryInterner.intern(externalLibrary)); + } + } + } + return libraries.build(); + } + + @Nullable + static ExternalAndroidLibrary toExternalLibrary( + Project project, @Nullable AarLibrary library, ArtifactLocationDecoder decoder) { + if (library == null) { + return null; + } + UnpackedAars unpackedAars = UnpackedAars.getInstance(project); + File aarFile = unpackedAars.getAarDir(decoder, library); + if (aarFile == null) { + logger.warn( + String.format( + "Fail to locate AAR file %s. Re-sync the project may solve the problem", + library.aarArtifact)); + return null; + } + File resFolder = unpackedAars.getResourceDirectory(decoder, library); + PathString resFolderPathString = resFolder == null ? null : new PathString(resFolder); + return new ExternalLibraryImpl(library.key.toString()) + .withLocation(new PathString(aarFile)) + .withManifestFile( + resFolderPathString == null + ? null + : resFolderPathString.getParentOrRoot().resolve("AndroidManifest.xml")) + .withResFolder( + resFolderPathString == null + ? null + : new SelectiveResourceFolder(resFolderPathString, null)) + .withSymbolFile( + resFolderPathString == null + ? null + : resFolderPathString.getParentOrRoot().resolve("R.txt")) + .withPackageName(library.resourcePackage); + } + + @Override + public Collection getAndroidLibraryDependencies( + DependencyScopeType dependencyScopeType) { + if (dependencyScopeType == DependencyScopeType.MAIN) { + return getDependentLibraries(); + } else { + return Collections.emptyList(); + } + } + @TestOnly - public static BlazeModuleSystem create(Module module) { + public static BazelModuleSystem create(Module module) { Preconditions.checkState(ApplicationManager.getApplication().isUnitTestMode()); - return new BlazeModuleSystem(module); + return new BazelModuleSystem(module); } - public static BlazeModuleSystem getInstance(Module module) { - return ModuleServiceManager.getService(module, BlazeModuleSystem.class); + public static BazelModuleSystem getInstance(Module module) { + return module.getService(BazelModuleSystem.class); } } diff --git a/aswb/src/com/google/idea/blaze/android/projectsystem/BlazeProjectSystemBuildManager.java b/aswb/src/com/google/idea/blaze/android/projectsystem/BlazeProjectSystemBuildManager.java index 0de46179722..e16aa4081c0 100644 --- a/aswb/src/com/google/idea/blaze/android/projectsystem/BlazeProjectSystemBuildManager.java +++ b/aswb/src/com/google/idea/blaze/android/projectsystem/BlazeProjectSystemBuildManager.java @@ -21,6 +21,8 @@ import com.android.tools.idea.projectsystem.ProjectSystemBuildManager; import com.google.idea.blaze.base.build.BlazeBuildListener; import com.google.idea.blaze.base.build.BlazeBuildService; +import com.google.idea.blaze.base.settings.Blaze; +import com.google.idea.blaze.base.settings.BlazeImportSettings.ProjectType; import com.google.idea.blaze.base.sync.aspects.BlazeBuildOutputs; import com.intellij.openapi.Disposable; import com.intellij.openapi.components.Service; @@ -47,13 +49,6 @@ public void compileProject() { BlazeBuildService.getInstance(project).buildProject(); } - @Override - public void compileFilesAndDependencies(Collection files) { - // TODO(b/191937319): Implement incremental builds for individual files - // Just compile the entire project for now. - compileProject(); - } - @Override public void addBuildListener( Disposable parentDisposable, ProjectSystemBuildManager.BuildListener buildListener) { @@ -102,14 +97,15 @@ public static BlazeBuildCounter getInstance(Project project) { * Class to publish BlazeBuildListener callbacks to {@link * BlazeProjectSystemBuildManager#PROJECT_SYSTEM_BUILD_TOPIC} */ - final class BuildCallbackPublisher implements BlazeBuildListener { + static final class BuildCallbackPublisher implements BlazeBuildListener { @Override public void buildStarting(Project project) { BlazeBuildCounter.getInstance(project).onBuildStarted(); project .getMessageBus() .syncPublisher(PROJECT_SYSTEM_BUILD_TOPIC) - .buildStarted(BuildMode.COMPILE); // Blaze build currently only supports compilation + .buildStarted( + BuildMode.COMPILE_OR_ASSEMBLE); // Blaze build currently only supports compilation } @Override @@ -142,9 +138,7 @@ private static LastBuildResultCache getInstance(Project project) { private BuildResult updateBuildResult( com.google.idea.blaze.base.sync.aspects.BuildResult buildResult) { - lastBuildResult = - new BuildResult( - BuildMode.COMPILE, mapBuildStatus(buildResult), System.currentTimeMillis()); + lastBuildResult = new BuildResult(BuildMode.COMPILE_OR_ASSEMBLE, mapBuildStatus(buildResult)); return lastBuildResult; } @@ -165,3 +159,4 @@ private static BuildStatus mapBuildStatus( } } } + diff --git a/aswb/src/com/google/idea/blaze/android/projectsystem/BlazeProjectSystemProvider.java b/aswb/src/com/google/idea/blaze/android/projectsystem/BlazeProjectSystemProvider.java index 69881940e53..4c0a493da9f 100644 --- a/aswb/src/com/google/idea/blaze/android/projectsystem/BlazeProjectSystemProvider.java +++ b/aswb/src/com/google/idea/blaze/android/projectsystem/BlazeProjectSystemProvider.java @@ -21,27 +21,22 @@ import com.intellij.openapi.project.Project; /** - * A BlazeProjectSystemProvider determines whether or not a BlazeProjectSystem would be applicable + * A BlazeProjectSystemProvider determines whether or not a BazelProjectSystem would be applicable * for a given project. If so, the provider is responsible for creating the instance of - * BlazeProjectSystem that should be associated with the project. + * BazelProjectSystem that should be associated with the project. * *

We provide this functionality in BlazeProjectSystemProvider instead of having - * BlazeProjectSystem implement AndroidProjectSystemProvider itself because there are times when we + * BazelProjectSystem implement AndroidProjectSystemProvider itself because there are times when we * want to instantiate the provider extension without creating a new instance of the project system. * In particular, the provider extension may be instantiated after the disposal of the project, in * which case we can't create the project system because it interacts with the project during * instantiation. */ public class BlazeProjectSystemProvider implements AndroidProjectSystemProvider { - public static final String ID = "com.google.idea.blaze.BlazeProjectSystem"; - private Project project; - - public BlazeProjectSystemProvider(Project project) { - this.project = project; - } + public static final String ID = "com.google.idea.blaze.BazelProjectSystem"; @Override - public boolean isApplicable() { + public boolean isApplicable(Project project) { return Blaze.isBlazeProject(project); } @@ -51,7 +46,7 @@ public String getId() { } @Override - public AndroidProjectSystem getProjectSystem() { - return new BlazeProjectSystem(project); + public AndroidProjectSystem projectSystemFactory(Project project) { + return new BazelProjectSystem(project); } } diff --git a/aswb/src/com/google/idea/blaze/android/projectsystem/BlazeProjectSystemSyncManager.java b/aswb/src/com/google/idea/blaze/android/projectsystem/BlazeProjectSystemSyncManager.java index cde78e8b0db..6d48a423a36 100644 --- a/aswb/src/com/google/idea/blaze/android/projectsystem/BlazeProjectSystemSyncManager.java +++ b/aswb/src/com/google/idea/blaze/android/projectsystem/BlazeProjectSystemSyncManager.java @@ -149,7 +149,7 @@ public void afterSync( /** Called after sync. Only used in new query-sync * */ @Override - public void afterSync(Project project, BlazeContext context) { + public void afterQuerySync(Project project, BlazeContext context) { LastSyncResultCache lastSyncResultCache = LastSyncResultCache.getInstance(project); if (context.isCancelled()) { diff --git a/aswb/src/com/google/idea/blaze/android/projectsystem/DesugaringLibraryConfigFilesLocator.java b/aswb/src/com/google/idea/blaze/android/projectsystem/DesugaringLibraryConfigFilesLocator.java new file mode 100644 index 00000000000..457ad795ea3 --- /dev/null +++ b/aswb/src/com/google/idea/blaze/android/projectsystem/DesugaringLibraryConfigFilesLocator.java @@ -0,0 +1,58 @@ +/* + * Copyright 2023 The Bazel Authors. All rights reserved. + * + * 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. + */ +package com.google.idea.blaze.android.projectsystem; + +import static com.google.common.collect.ImmutableList.toImmutableList; + +import com.google.common.collect.ImmutableList; +import com.google.idea.blaze.base.settings.BuildSystemName; +import com.intellij.openapi.extensions.ExtensionPointName; +import com.intellij.openapi.project.Project; +import java.nio.file.Path; +import java.util.Arrays; + +/** + * Build systems can implement their own {@link DesugaringLibraryConfigFilesLocator} to help the IDE + * to locate desugaring config files. Note that there can be multiple locators enabled at the same + * time; see {@link DesugaringLibraryConfigFilesLocator#forBuildSystem(BuildSystemName)} on how to + * obtain them for a given build system. + */ +public interface DesugaringLibraryConfigFilesLocator { + ExtensionPointName EP_NAME = + ExtensionPointName.create("com.google.idea.blaze.DesugaringLibraryConfigFilesLocator"); + + /** Returns true if desugaring library config files exist. */ + public boolean getDesugarLibraryConfigFilesKnown(); + + /** Returns the list of paths to the desugaring library config files */ + ImmutableList getDesugarLibraryConfigFiles(Project project); + + /** + * Returns the {@link BuildSystemName} this {@link DesugaringLibraryConfigFilesLocator} supports. + */ + BuildSystemName buildSystem(); + + /** + * Returns an {@link ImmutableList} of {@link DesugaringLibraryConfigFilesLocator} that supports + * the given build system. + */ + static ImmutableList forBuildSystem( + BuildSystemName buildSystemName) { + return Arrays.stream(EP_NAME.getExtensions()) + .filter(provider -> provider.buildSystem().equals(buildSystemName)) + .collect(toImmutableList()); + } +} diff --git a/aswb/src/com/google/idea/blaze/android/projectsystem/PackageNameUtils.java b/aswb/src/com/google/idea/blaze/android/projectsystem/PackageNameUtils.java new file mode 100644 index 00000000000..f9b1a68db52 --- /dev/null +++ b/aswb/src/com/google/idea/blaze/android/projectsystem/PackageNameUtils.java @@ -0,0 +1,135 @@ +/* + * Copyright 2018 The Bazel Authors. All rights reserved. + * + * 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. + */ +package com.google.idea.blaze.android.projectsystem; + +import com.android.manifmerger.ManifestSystemProperty; +import com.android.tools.idea.model.AndroidManifestIndex; +import com.android.tools.idea.model.AndroidManifestRawText; +import com.android.tools.idea.model.MergedManifestModificationTracker; +import com.android.tools.idea.projectsystem.ManifestOverrides; +import com.android.tools.idea.projectsystem.SourceProviderManager; +import com.google.common.annotations.VisibleForTesting; +import com.google.idea.common.experiments.BoolExperiment; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.project.DumbService; +import com.intellij.openapi.project.IndexNotReadyException; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.util.CachedValueProvider; +import com.intellij.psi.util.CachedValuesManager; +import org.jetbrains.android.dom.manifest.AndroidManifestUtils; +import org.jetbrains.android.dom.manifest.AndroidManifestXmlFile; +import org.jetbrains.android.facet.AndroidFacet; +import org.jetbrains.annotations.Nullable; + +/** Utilities to obtain the package name for a given module. */ +public class PackageNameUtils { + /** + * Determines whether we use the {@link AndroidManifestIndex} to obtain the raw text package name + * from a module's primary manifest. + * + * @see PackageNameUtils#getPackageName(Module) + * @see PackageNameUtils#doGetPackageName(AndroidFacet, boolean) + */ + private static final BoolExperiment USE_ANDROID_MANIFEST_INDEX = + new BoolExperiment("use.android.manifest.index", true); + + @Nullable + public static String getPackageName(Module module) { + AndroidFacet facet = AndroidFacet.getInstance(module); + assert facet != null; + return CachedValuesManager.getManager(module.getProject()) + .getCachedValue( + facet, + () -> { + boolean useIndex = USE_ANDROID_MANIFEST_INDEX.getValue(); + String packageName = doGetPackageName(facet, useIndex); + return CachedValueProvider.Result.create( + StringUtil.nullize(packageName, true), + MergedManifestModificationTracker.getInstance(module)); + }); + } + + /** + * Returns the package name from an Android module's merged manifest without actually computing + * the whole merged manifest. This is either + * + *

    + *
  1. The {@link ManifestSystemProperty#PACKAGE} manifest override if one is specified by the + * corresponding BUILD target, or + *
  2. The result of applying placeholder substitution to the raw package name from the module's + * primary manifest + *
+ * + * In the second case, we try to obtain the raw package name using the {@link + * AndroidManifestIndex} if {@code useIndex} is true. If {@code useIndex} is false or querying the + * index fails for some reason (e.g. this method is called in a read action but not a *smart* read + * action), then we resort to parsing the PSI of the module's primary manifest to get the raw + * package name. + * + * @see AndroidModuleSystem#getManifestOverrides() + * @see AndroidModuleSystem#getPackageName() + */ + @Nullable + @VisibleForTesting + static String doGetPackageName(AndroidFacet facet, boolean useIndex) { + ManifestOverrides manifestOverrides = + BazelModuleSystem.getInstance(facet.getModule()).getManifestOverrides(); + String packageOverride = + ManifestValueProcessor.getPackageOverride(manifestOverrides.getDirectOverrides()); + if (packageOverride != null) { + return packageOverride; + } + String rawPackageName = null; + if (useIndex) { + rawPackageName = getRawPackageNameFromIndex(facet); + } + if (rawPackageName == null) { + rawPackageName = getRawPackageNameFromPsi(facet); + } + return rawPackageName == null ? null : manifestOverrides.resolvePlaceholders(rawPackageName); + } + + @Nullable + private static String getRawPackageNameFromIndex(AndroidFacet facet) { + VirtualFile primaryManifest = SourceProviderManager.getInstance(facet).getMainManifestFile(); + if (primaryManifest == null) { + return null; + } + Project project = facet.getModule().getProject(); + try { + AndroidManifestRawText manifestRawText = + DumbService.getInstance(project) + .runReadActionInSmartMode( + () -> AndroidManifestIndex.getDataForManifestFile(project, primaryManifest)); + return manifestRawText == null ? null : manifestRawText.getPackageName(); + } catch (IndexNotReadyException e) { + // TODO(142681129): runReadActionInSmartMode doesn't work if we already have read access. + // We need to refactor the callers of AndroidManifestUtils#getPackage to require a *smart* + // read action, at which point we can remove this try-catch. + return null; + } + } + + @Nullable + private static String getRawPackageNameFromPsi(AndroidFacet facet) { + AndroidManifestXmlFile primaryManifest = AndroidManifestUtils.getPrimaryManifestXml(facet); + return primaryManifest == null ? null : primaryManifest.getPackageName(); + } + + private PackageNameUtils() {} +} diff --git a/aswb/src/com/google/idea/blaze/android/projectsystem/RenderJarClassFileFinder.java b/aswb/src/com/google/idea/blaze/android/projectsystem/RenderJarClassFileFinder.java index 617265883a6..912eba4df65 100644 --- a/aswb/src/com/google/idea/blaze/android/projectsystem/RenderJarClassFileFinder.java +++ b/aswb/src/com/google/idea/blaze/android/projectsystem/RenderJarClassFileFinder.java @@ -17,8 +17,10 @@ import static java.util.stream.Collectors.joining; +import com.android.tools.idea.projectsystem.ClassContent; import com.android.tools.idea.projectsystem.ClassFileFinder; import com.android.tools.idea.projectsystem.ClassFileFinderUtil; +import com.android.tools.idea.rendering.classloading.loaders.JarManager; import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Throwables; import com.google.common.collect.ImmutableSet; @@ -28,9 +30,11 @@ import com.google.idea.blaze.android.targetmaps.TargetToBinaryMap; import com.google.idea.blaze.base.ideinfo.TargetIdeInfo; import com.google.idea.blaze.base.ideinfo.TargetKey; -import com.google.idea.blaze.base.io.VirtualFileSystemProvider; import com.google.idea.blaze.base.model.BlazeProjectData; -import com.google.idea.blaze.base.qsync.QuerySync; +import com.google.idea.blaze.base.qsync.QuerySyncManager; +import com.google.idea.blaze.base.qsync.RenderJarArtifactTracker; +import com.google.idea.blaze.base.settings.Blaze; +import com.google.idea.blaze.base.settings.BlazeImportSettings.ProjectType; import com.google.idea.blaze.base.sync.BlazeSyncModificationTracker; import com.google.idea.blaze.base.sync.data.BlazeDataStorage; import com.google.idea.blaze.base.sync.data.BlazeProjectDataManager; @@ -40,10 +44,13 @@ import com.intellij.openapi.module.Module; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.text.StringUtil; -import com.intellij.openapi.vfs.JarFileSystem; -import com.intellij.openapi.vfs.VirtualFile; import java.io.File; +import java.io.IOException; +import java.io.UncheckedIOException; +import java.nio.file.Files; +import java.nio.file.Path; import java.util.regex.Pattern; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; /** @@ -98,31 +105,33 @@ public class RenderJarClassFileFinder implements ClassFileFinder { // true if the current module is the .workspace Module private final boolean isWorkspaceModule; + private final JarManager jarManager; + public RenderJarClassFileFinder(Module module) { this.module = module; this.project = module.getProject(); this.isWorkspaceModule = BlazeDataStorage.WORKSPACE_MODULE_NAME.equals(module.getName()); + if (ApplicationManager.getApplication().isUnitTestMode()) { + this.jarManager = null; // TODO(b/311649275): Mock in tests when made an interface. + } else { + this.jarManager = JarManager.getInstance(project); + } } @Nullable @Override - public VirtualFile findClassFile(String fqcn) { + public ClassContent findClassFile(@NotNull String fqcn) { if (!isEnabled()) { return null; } - // TODO(b/266726517): Query sync does not support render jars. - if (QuerySync.isEnabled()) { - return null; - } - // Ever since Compose support was introduced in AS, finding class files is invoked during the // normal course of opening an editor. The contract for this method requires that it shouldn't // throw any exceptions, but we've had a few bugs where this method threw an exception, which // resulted in users not being able to open Kotlin files at all. In order to avoid this // scenario, we wrap the underlying call and ensure that no exceptions are thrown. try { - return findClass(fqcn); + return findClassContent(fqcn); } catch (Error e) { log.warn( String.format( @@ -133,7 +142,7 @@ public VirtualFile findClassFile(String fqcn) { } @Nullable - public VirtualFile findClass(String fqcn) { + public ClassContent findClassContent(String fqcn) { // Render JAR should not resolve any resources. All resources should be available to the IDE // through ResourceRepository. Attempting to resolve resources from Render JAR indicates that // ASwB hasn't properly set up resources for the project. @@ -142,6 +151,31 @@ public VirtualFile findClass(String fqcn) { return null; } + if (Blaze.getProjectType(project).equals(ProjectType.QUERY_SYNC)) { + return findClassQuerySync(fqcn); + } + return findClassLegacySync(fqcn); + } + + private ClassContent findClassQuerySync(String fqcn) { + if (Blaze.getProjectType(project) == ProjectType.QUERY_SYNC) { + RenderJarArtifactTracker renderJarArtifactTracker = + QuerySyncManager.getInstance(project).getRenderJarArtifactTracker(); + // TODO(b/283280194): Setup fqcn -> target and target -> Render jar mappings to avoid + // iterating over all render jars when trying to locate class for fqcn. + // TODO(b/284002836): Collect metrics on time taken to iterate over the jars + for (File renderJar : renderJarArtifactTracker.getRenderJars()) { + ClassContent classContent = findClassInJar(renderJar, fqcn); + if (classContent != null) { + return classContent; + } + } + return null; + } + return null; + } + + private ClassContent findClassLegacySync(String fqcn) { BlazeProjectData projectData = BlazeProjectDataManager.getInstance(project).getBlazeProjectData(); if (projectData == null) { @@ -167,12 +201,11 @@ public VirtualFile findClass(String fqcn) { // The binaries can depend on any subset of these resource targets. Generally, we only // expect one, or a small number of binaries here. for (TargetKey binaryTarget : binaryTargets) { - VirtualFile classFile = getClassFromRenderResolveJar(projectData, fqcn, binaryTarget); - if (classFile != null) { - return classFile; + ClassContent classContent = getClassFromRenderResolveJar(projectData, fqcn, binaryTarget); + if (classContent != null) { + return classContent; } } - log.warn(String.format("Could not find class `%1$s` (module: `%2$s`)", fqcn, module.getName())); return null; } @@ -223,7 +256,7 @@ private ImmutableSet getBinaryTargets() { * Returns null if something goes wrong or if render JAR does not contain fqcn */ @Nullable - private VirtualFile getClassFromRenderResolveJar( + private ClassContent getClassFromRenderResolveJar( BlazeProjectData projectData, String fqcn, TargetKey binaryTarget) { TargetIdeInfo ideInfo = projectData.getTargetMap().get(binaryTarget); if (ideInfo == null) { @@ -238,31 +271,29 @@ private VirtualFile getClassFromRenderResolveJar( return null; } - VirtualFile renderResolveJarVF = - VirtualFileSystemProvider.getInstance().getSystem().findFileByIoFile(renderResolveJarFile); - if (renderResolveJarVF == null) { - return null; - } - - return findClassInJar(renderResolveJarVF, fqcn); + return findClassInJar(renderResolveJarFile, fqcn); } - @Nullable - private static VirtualFile findClassInJar(final VirtualFile classJar, String fqcn) { - VirtualFile jarRoot = getJarRootForLocalFile(classJar); - if (jarRoot == null) { + private ClassContent findClassInJar(File renderResolveJarFile, String fqcn) { + String relativePath = ClassFileFinderUtil.getPathFromFqcn(fqcn); + final byte[] bytes; + if (ApplicationManager.getApplication().isUnitTestMode()) { + try { + Path targetPath = renderResolveJarFile.toPath().resolve("!" + relativePath); + bytes = Files.isRegularFile(targetPath) ? Files.readAllBytes(targetPath) : new byte[0]; + } catch (IOException e) { + throw new UncheckedIOException(e); + } + } else { + bytes = + jarManager.loadFileFromJar( + renderResolveJarFile.toPath(), ClassFileFinderUtil.getPathFromFqcn(fqcn)); + } + if (bytes == null) { return null; } - return ClassFileFinderUtil.findClassFileInOutputRoot(jarRoot, fqcn); - } - /** Test aware method to redirect JARs to {@link VirtualFileSystemProvider} for tests */ - private static VirtualFile getJarRootForLocalFile(VirtualFile file) { - return ApplicationManager.getApplication().isUnitTestMode() - ? VirtualFileSystemProvider.getInstance() - .getSystem() - .findFileByPath(file.getPath() + JarFileSystem.JAR_SEPARATOR) - : JarFileSystem.getInstance().getJarRootForLocalFile(file); + return ClassContent.fromJarEntryContent(renderResolveJarFile, bytes); } public static boolean isEnabled() { diff --git a/aswb/src/com/google/idea/blaze/android/qsync/AndroidProjectProtoTransform.java b/aswb/src/com/google/idea/blaze/android/qsync/AndroidProjectProtoTransform.java new file mode 100644 index 00000000000..e58b89595d2 --- /dev/null +++ b/aswb/src/com/google/idea/blaze/android/qsync/AndroidProjectProtoTransform.java @@ -0,0 +1,72 @@ +/* + * Copyright 2024 The Bazel Authors. All rights reserved. + * + * 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. + */ +package com.google.idea.blaze.android.qsync; + +import com.google.common.collect.ImmutableList; +import com.google.idea.blaze.android.manifest.ManifestParser; +import com.google.idea.blaze.base.qsync.ProjectProtoTransformProvider; +import com.google.idea.blaze.common.Context; +import com.google.idea.blaze.exception.BuildException; +import com.google.idea.blaze.qsync.ProjectProtoTransform; +import com.google.idea.blaze.qsync.deps.ArtifactTracker; +import com.google.idea.blaze.qsync.deps.ProjectProtoUpdate; +import com.google.idea.blaze.qsync.deps.ProjectProtoUpdateOperation; +import com.google.idea.blaze.qsync.java.AarPackageNameExtractor; +import com.google.idea.blaze.qsync.java.AddAndroidResPackages; +import com.google.idea.blaze.qsync.java.AddDependencyAars; +import com.google.idea.blaze.qsync.project.BuildGraphData; +import com.google.idea.blaze.qsync.project.ProjectDefinition; +import com.google.idea.blaze.qsync.project.ProjectProto.Project; +import java.util.List; + +/** A {@link ProjectProtoTransform} that adds android specific information to the project proto. */ +public class AndroidProjectProtoTransform implements ProjectProtoTransform { + + /** + * Provides a {@link ProjectProtoTransform} that adds android specific information to the project + * proto. + */ + public static class Provider implements ProjectProtoTransformProvider { + + @Override + public List createTransforms(ProjectDefinition projectDef) { + return ImmutableList.of(new AndroidProjectProtoTransform(projectDef)); + } + } + + private final ImmutableList updateOperations; + + private AndroidProjectProtoTransform(ProjectDefinition projectDefinition) { + updateOperations = + ImmutableList.of( + new AddDependencyAars( + projectDefinition, + new AarPackageNameExtractor( + in -> ManifestParser.parseManifestFromInputStream(in).packageName)), + new AddAndroidResPackages()); + } + + @Override + public Project apply( + Project proto, BuildGraphData graph, ArtifactTracker.State artifactState, Context context) + throws BuildException { + ProjectProtoUpdate update = new ProjectProtoUpdate(proto, graph, context); + for (var op : updateOperations) { + op.update(update, artifactState); + } + return update.build(); + } +} diff --git a/aswb/src/com/google/idea/blaze/android/qsync/BlazeAndroidQuerySyncPlugin.java b/aswb/src/com/google/idea/blaze/android/qsync/BlazeAndroidQuerySyncPlugin.java new file mode 100644 index 00000000000..f5ad13ddc29 --- /dev/null +++ b/aswb/src/com/google/idea/blaze/android/qsync/BlazeAndroidQuerySyncPlugin.java @@ -0,0 +1,148 @@ +/* + * Copyright 2016 The Bazel Authors. All rights reserved. + * + * 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. + */ +package com.google.idea.blaze.android.qsync; + +import static com.google.common.collect.ImmutableSet.toImmutableSet; +import static java.util.stream.Collectors.joining; + +import com.android.tools.idea.model.AndroidModel; +import com.android.tools.idea.projectsystem.NamedIdeaSourceProvider; +import com.android.tools.idea.projectsystem.NamedIdeaSourceProviderBuilder; +import com.android.tools.idea.projectsystem.ScopeType; +import com.google.common.collect.ImmutableSet; +import com.google.common.util.concurrent.Futures; +import com.google.idea.blaze.android.qsync.projectstructure.AndroidFacetModuleCustomizer; +import com.google.idea.blaze.android.resources.BlazeLightResourceClassService; +import com.google.idea.blaze.android.sdk.BlazeSdkProvider; +import com.google.idea.blaze.android.sync.model.AndroidSdkPlatform; +import com.google.idea.blaze.android.sync.model.idea.BlazeAndroidModel; +import com.google.idea.blaze.android.sync.sdk.AndroidSdkFromProjectView; +import com.google.idea.blaze.base.model.primitives.WorkspaceRoot; +import com.google.idea.blaze.base.model.primitives.WorkspaceType; +import com.google.idea.blaze.base.projectview.ProjectViewManager; +import com.google.idea.blaze.base.projectview.ProjectViewSet; +import com.google.idea.blaze.base.projectview.section.sections.BuildFlagsSection; +import com.google.idea.blaze.base.qsync.BlazeQuerySyncPlugin; +import com.google.idea.blaze.base.sync.projectview.LanguageSupport; +import com.google.idea.blaze.base.sync.projectview.WorkspaceLanguageSettings; +import com.google.idea.blaze.common.Context; +import com.google.idea.blaze.common.PrintOutput; +import com.google.idea.blaze.java.projectview.JavaLanguageLevelSection; +import com.intellij.openapi.externalSystem.service.project.IdeModifiableModelsProvider; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.projectRoots.Sdk; +import com.intellij.openapi.roots.LanguageLevelProjectExtension; +import com.intellij.openapi.roots.ex.ProjectRootManagerEx; +import com.intellij.openapi.vfs.VfsUtilCore; +import com.intellij.pom.java.LanguageLevel; +import com.intellij.util.containers.ContainerUtil; +import java.io.File; +import java.util.Set; +import org.jetbrains.android.facet.AndroidFacet; + +/** ASwB sync plugin. */ +public class BlazeAndroidQuerySyncPlugin implements BlazeQuerySyncPlugin { + + @Override + public void updateProjectSettingsForQuerySync( + Project project, Context context, ProjectViewSet projectViewSet) { + if (!isAndroidWorkspace(LanguageSupport.createWorkspaceLanguageSettings(projectViewSet))) { + return; + } + AndroidSdkPlatform androidSdkPlatform = + AndroidSdkFromProjectView.getAndroidSdkPlatform(context, projectViewSet); + Sdk sdk = BlazeSdkProvider.getInstance().findSdk(androidSdkPlatform.androidSdk); + LanguageLevel javaLanguageLevel = + JavaLanguageLevelSection.getLanguageLevel(projectViewSet, LanguageLevel.JDK_21); + ProjectRootManagerEx rootManager = ProjectRootManagerEx.getInstanceEx(project); + rootManager.setProjectSdk(sdk); + LanguageLevelProjectExtension ext = LanguageLevelProjectExtension.getInstance(project); + ext.setLanguageLevel(javaLanguageLevel); + } + + @Override + public void updateProjectStructureForQuerySync( + Project project, + Context context, + IdeModifiableModelsProvider models, + WorkspaceRoot workspaceRoot, + Module workspaceModule, + Set androidResourceDirectories, + Set androidSourcePackages, + WorkspaceLanguageSettings workspaceLanguageSettings) { + + if (!isAndroidWorkspace(workspaceLanguageSettings)) { + return; + } + + AndroidFacetModuleCustomizer androidFacetModuleCustomizer = + new AndroidFacetModuleCustomizer(models); + + // Attach AndroidFacet to workspace modules + androidFacetModuleCustomizer.createAndroidFacet(workspaceModule, false); + + // Add all source resource directories to this AndroidFacet + AndroidFacet workspaceFacet = AndroidFacet.getInstance(workspaceModule); + if (workspaceFacet == null) { + context.output( + PrintOutput.error( + "workspace_type is android, but no android facet present; not configuring android" + + " resources")); + context.output( + PrintOutput.output( + "Consider adding \"workspace_type: java\" or similar to your .blazeproject file, or" + + " add the android facet in project settings if this is an android project.")); + return; + } + ImmutableSet androidResourceDirectoryFiles = + androidResourceDirectories.stream() + .map(dir -> new File(workspaceRoot.directory(), dir).getAbsoluteFile()) + .collect(toImmutableSet()); + NamedIdeaSourceProvider sourceProvider = + NamedIdeaSourceProviderBuilder.create( + workspaceModule.getName(), VfsUtilCore.fileToUrl(new File("MissingManifest.xml"))) + .withScopeType(ScopeType.MAIN) + .withResDirectoryUrls( + ContainerUtil.map(androidResourceDirectoryFiles, VfsUtilCore::fileToUrl)) + .build(); + + // Set AndroidModel for this AndroidFacet + ProjectViewSet projectViewSet = ProjectViewManager.getInstance(project).getProjectViewSet(); + AndroidSdkPlatform androidSdkPlatform = + AndroidSdkFromProjectView.getAndroidSdkPlatform(context, projectViewSet); + + BlazeAndroidModel androidModel = + new BlazeAndroidModel( + project, + workspaceRoot.directory(), + sourceProvider, + Futures.immediateFuture(":workspace"), + androidSdkPlatform != null ? androidSdkPlatform.androidMinSdkLevel : 1); + AndroidModel.set(workspaceFacet, androidModel); + + // Register all source java packages as workspace packages + BlazeLightResourceClassService.Builder rClassBuilder = + new BlazeLightResourceClassService.Builder(project); + rClassBuilder.addWorkspacePackages(androidSourcePackages); + // TODO(b/283282438): Make Preview work with resources in project's res folder in Query Sync + BlazeLightResourceClassService.getInstance(project).installRClasses(rClassBuilder); + } + + private static boolean isAndroidWorkspace(WorkspaceLanguageSettings workspaceLanguageSettings) { + return workspaceLanguageSettings.isWorkspaceType(WorkspaceType.ANDROID); + } +} diff --git a/aswb/src/com/google/idea/blaze/android/qsync/projectstructure/AndroidFacetModuleCustomizer.java b/aswb/src/com/google/idea/blaze/android/qsync/projectstructure/AndroidFacetModuleCustomizer.java new file mode 100755 index 00000000000..50266af470b --- /dev/null +++ b/aswb/src/com/google/idea/blaze/android/qsync/projectstructure/AndroidFacetModuleCustomizer.java @@ -0,0 +1,59 @@ +/* + * Copyright 2016 The Bazel Authors. All rights reserved. + * + * 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. + */ +package com.google.idea.blaze.android.qsync.projectstructure; + +import com.android.AndroidProjectTypes; +import com.android.builder.model.AndroidProject; +import com.intellij.facet.FacetManager; +import com.intellij.facet.ModifiableFacetModel; +import com.intellij.openapi.externalSystem.service.project.IdeModifiableModelsProvider; +import com.intellij.openapi.module.Module; +import org.jetbrains.android.facet.AndroidFacet; +import org.jetbrains.android.facet.AndroidFacetProperties; + +/** Adds the Android facet to modules imported from {@link AndroidProject}s. */ +public class AndroidFacetModuleCustomizer { + + private final IdeModifiableModelsProvider models; + + public AndroidFacetModuleCustomizer(IdeModifiableModelsProvider models) { + this.models = models; + } + + public void createAndroidFacet(Module module, boolean isApp) { + ModifiableFacetModel modifiableFacetModel = models.getModifiableFacetModel(module); + AndroidFacet facet = modifiableFacetModel.getFacetByType(AndroidFacet.ID); + FacetManager facetManager = FacetManager.getInstance(module); + if (facet != null) { + configureFacet(facet, isApp); + } else { + // Module does not have Android facet. Create one and add it. + facet = facetManager.createFacet(AndroidFacet.getFacetType(), AndroidFacet.NAME, null); + modifiableFacetModel.addFacet(facet); + configureFacet(facet, isApp); + } + } + + private static void configureFacet(AndroidFacet facet, boolean isApp) { + AndroidFacetProperties facetState = facet.getProperties(); + facetState.ALLOW_USER_CONFIGURATION = false; + facetState.PROJECT_TYPE = + isApp ? AndroidProjectTypes.PROJECT_TYPE_APP : AndroidProjectTypes.PROJECT_TYPE_LIBRARY; + facetState.MANIFEST_FILE_RELATIVE_PATH = ""; + facetState.RES_FOLDER_RELATIVE_PATH = ""; + facetState.ASSETS_FOLDER_RELATIVE_PATH = ""; + } +} diff --git a/aswb/src/com/google/idea/blaze/android/rendering/BlazeRenderErrorContributor.java b/aswb/src/com/google/idea/blaze/android/rendering/BlazeRenderErrorContributor.java index 49a7f97951c..4fd90645f03 100644 --- a/aswb/src/com/google/idea/blaze/android/rendering/BlazeRenderErrorContributor.java +++ b/aswb/src/com/google/idea/blaze/android/rendering/BlazeRenderErrorContributor.java @@ -16,13 +16,15 @@ package com.google.idea.blaze.android.rendering; import static com.android.SdkConstants.ANDROID_MANIFEST_XML; +import static com.google.common.collect.ImmutableMap.toImmutableMap; import com.android.tools.idea.rendering.RenderErrorContributor; -import com.android.tools.idea.rendering.RenderLogger; -import com.android.tools.idea.rendering.RenderResult; +import com.android.tools.idea.rendering.RenderUtils; import com.android.tools.idea.rendering.errors.ui.RenderErrorModel; import com.android.tools.idea.ui.designer.EditorDesignSurface; -import com.android.tools.rendering.HtmlLinkManagerCompat; +import com.android.tools.rendering.HtmlLinkManager; +import com.android.tools.rendering.RenderLogger; +import com.android.tools.rendering.RenderResult; import com.android.utils.HtmlBuilder; import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableCollection; @@ -41,12 +43,13 @@ import com.google.idea.blaze.base.lang.buildfile.references.BuildReferenceManager; import com.google.idea.blaze.base.model.BlazeProjectData; import com.google.idea.blaze.base.settings.Blaze; +import com.google.idea.blaze.base.settings.BlazeImportSettings.ProjectType; +import com.google.idea.blaze.base.settings.BuildSystemName; import com.google.idea.blaze.base.sync.data.BlazeProjectDataManager; import com.google.idea.blaze.base.sync.workspace.ArtifactLocationDecoder; import com.google.idea.blaze.base.targetmaps.SourceToTargetMap; import com.google.idea.blaze.base.targetmaps.TransitiveDependencyMap; import com.intellij.lang.annotation.HighlightSeverity; -import com.intellij.openapi.actionSystem.DataContext; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.module.Module; import com.intellij.openapi.project.IndexNotReadyException; @@ -60,26 +63,118 @@ import com.intellij.psi.PsiFile; import com.intellij.psi.search.GlobalSearchScope; import java.io.File; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; import java.util.Collection; import java.util.Collections; +import java.util.LinkedHashSet; import java.util.Map; +import java.util.Set; import java.util.SortedMap; import java.util.function.Function; -import java.util.stream.Collectors; +import javax.swing.JEditorPane; +import javax.swing.event.HyperlinkEvent; +import javax.swing.event.HyperlinkListener; +import javax.swing.text.html.HTMLDocument; +import javax.swing.text.html.HTMLFrameHyperlinkEvent; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; /** Contribute blaze specific render errors. */ -public class BlazeRenderErrorContributor extends RenderErrorContributor { - private RenderLogger logger; - private Module module; - private Project project; - - public BlazeRenderErrorContributor( - EditorDesignSurface surface, RenderResult result, @Nullable DataContext dataContext) { - super(surface, result, dataContext); +public class BlazeRenderErrorContributor implements RenderErrorContributor { + private final EditorDesignSurface designSurface; + private final RenderLogger logger; + private final Module module; + private final PsiFile sourceFile; + private final Project project; + private final HtmlLinkManager linkManager; + private final HyperlinkListener linkHandler; + private final Set issues = new LinkedHashSet<>(); + + public BlazeRenderErrorContributor(EditorDesignSurface surface, RenderResult result) { + designSurface = surface; logger = result.getLogger(); module = result.getModule(); + sourceFile = result.getSourceFile(); project = module.getProject(); + linkManager = logger.getLinkManager(); + linkHandler = + e -> { + if (e.getEventType() == HyperlinkEvent.EventType.ACTIVATED) { + JEditorPane pane = (JEditorPane) e.getSource(); + if (e instanceof HTMLFrameHyperlinkEvent) { + HTMLFrameHyperlinkEvent evt = (HTMLFrameHyperlinkEvent) e; + HTMLDocument doc = (HTMLDocument) pane.getDocument(); + doc.processHTMLFrameHyperlinkEvent(evt); + return; + } + + performClick(e.getDescription()); + } + }; + } + + private HtmlLinkManager getLinkManager() { + return linkManager; + } + + private Collection getIssues() { + return Collections.unmodifiableCollection(issues); + } + + private RenderErrorModel.Issue.Builder addIssue() { + return new RenderErrorModel.Issue.Builder() { + @Override + public RenderErrorModel.Issue build() { + RenderErrorModel.Issue built = super.build(); + issues.add(built); + return built; + } + }.setLinkHandler(linkHandler); + } + + private void performClick(String url) { + linkManager.handleUrl( + url, + module, + sourceFile, + true, + new HtmlLinkManager.RefreshableSurface() { + @Override + public void handleRefreshRenderUrl() { + if (designSurface != null) { + // TODO(b/321801969): Remove and replace with direct call when in repo. + // Use reflection to getConfigurations() from designSurface. Can't call directly + // because it returns an incompatible version of ImmutableCollection. + // RenderUtils.clearCache(designSurface.getConfigurations()); would fail at runtime. + try { + Method getConfigurationsMethod = + EditorDesignSurface.class.getMethod("getConfigurations", null); + Object configurations = getConfigurationsMethod.invoke(designSurface); + Method clearCacheMethod = + RenderUtils.class.getMethod( + "clearCache", getConfigurationsMethod.getReturnType()); + clearCacheMethod.invoke(null, configurations); + } catch (NoSuchMethodException ex) { + throw new RuntimeException( + "Error using reflection to get getConfigurations() instance method: " + ex); + } catch (IllegalAccessException ex) { + throw new RuntimeException( + "Error accessing getConfigurations() instance method" + ex); + } catch (InvocationTargetException ex) { + throw new RuntimeException("Error invoking target getConfigurations(): " + ex); + } + designSurface.forceUserRequestedRefresh(); + } + } + + @Override + public void requestRender() { + if (designSurface != null) { + designSurface.forceUserRequestedRefresh(); + } + } + }); } @Override @@ -91,6 +186,11 @@ public Collection reportIssues() { return getIssues(); } + if (Blaze.getProjectType(project).equals(ProjectType.QUERY_SYNC)) { + // TODO(b/284002829): Setup resource-module specific issue reporting + return getIssues(); + } + TargetMap targetMap = blazeProjectData.getTargetMap(); ArtifactLocationDecoder decoder = blazeProjectData.getArtifactLocationDecoder(); AndroidResourceModule resourceModule = @@ -163,7 +263,7 @@ private static SortedMap getGeneratedResources( target.getAndroidIdeInfo().getResources().stream() .map(AndroidResFolder::getRoot) .filter(ArtifactLocation::isGenerated) - .collect(Collectors.toMap(Function.identity(), resource -> target))); + .collect(toImmutableMap(Function.identity(), resource -> target))); return generatedResources; } @@ -196,7 +296,7 @@ private void reportNonStandardAndroidManifestName( HtmlBuilder builder = new HtmlBuilder(); addTargetLink(builder, target, decoder) .add(" uses a non-standard name for the Android manifest: "); - String linkToManifest = HtmlLinkManagerCompat.createFilePositionUrl(manifest, -1, 0); + String linkToManifest = HtmlLinkManager.createFilePositionUrl(manifest, -1, 0); if (linkToManifest != null) { builder.addLink(manifest.getName(), linkToManifest); } else { @@ -221,9 +321,10 @@ private void reportNonStandardAndroidManifestName( * android_binary, so we could end up with resources that ultimately build correctly, but fail to * find their class dependencies during rendering in the layout editor. */ + @SuppressWarnings("rawtypes") private void reportResourceTargetShouldDependOnClassTarget( TargetIdeInfo target, TargetMap targetMap, ArtifactLocationDecoder decoder) { - Collection missingClasses = logger.getMissingClasses(); + Set missingClasses = logger.getMissingClasses(); if (missingClasses == null || missingClasses.isEmpty()) { return; } @@ -334,26 +435,22 @@ private HtmlBuilder addTargetLink( return StringUtil.offsetToLineNumber( psiFile.getText(), buildTargetPsi.getTextOffset()); }); - String url = HtmlLinkManagerCompat.createFilePositionUrl(buildFile, line, 0); + String url = HtmlLinkManager.createFilePositionUrl(buildFile, line, 0); if (url != null) { return builder.addLink(target.toString(), url); } return builder.add(target.toString()); } - /** Extension to provide {@link BlazeRenderErrorContributor}. */ - public static class BlazeProvider extends Provider { - @Override + public static class Provider implements RenderErrorContributor.Provider { + public boolean isApplicable(Project project) { - return Blaze.isBlazeProject(project); + return Blaze.getProjectType(project) != ProjectType.UNKNOWN + && Blaze.getBuildSystemName(project) == BuildSystemName.Blaze; } - @Override - public RenderErrorContributor getContributor( - @Nullable EditorDesignSurface surface, - RenderResult result, - @Nullable DataContext dataContext) { - return new BlazeRenderErrorContributor(surface, result, dataContext); + public RenderErrorContributor getContributor(@Nullable EditorDesignSurface surface, @NotNull RenderResult result) { + return new BlazeRenderErrorContributor(surface, result); } } } diff --git a/aswb/src/com/google/idea/blaze/android/rendering/BlazeRenderSecurityManagerOverrides.java b/aswb/src/com/google/idea/blaze/android/rendering/BlazeRenderSecurityManagerOverrides.java index a1fd771fddc..39d3edd195f 100644 --- a/aswb/src/com/google/idea/blaze/android/rendering/BlazeRenderSecurityManagerOverrides.java +++ b/aswb/src/com/google/idea/blaze/android/rendering/BlazeRenderSecurityManagerOverrides.java @@ -15,7 +15,7 @@ */ package com.google.idea.blaze.android.rendering; -import com.android.tools.idea.rendering.RenderSecurityManagerOverrides; +import com.android.tools.rendering.security.RenderSecurityManagerOverrides; /** Overrides some security restrictions used by the render sandbox. */ public class BlazeRenderSecurityManagerOverrides implements RenderSecurityManagerOverrides { diff --git a/aswb/src/com/google/idea/blaze/android/resources/BlazeLightResourceClassService.java b/aswb/src/com/google/idea/blaze/android/resources/BlazeLightResourceClassService.java index 87e140d66fb..27db3fe5daa 100644 --- a/aswb/src/com/google/idea/blaze/android/resources/BlazeLightResourceClassService.java +++ b/aswb/src/com/google/idea/blaze/android/resources/BlazeLightResourceClassService.java @@ -23,7 +23,6 @@ import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableSet; import com.google.common.collect.Maps; -import com.google.common.collect.Sets; import com.google.idea.blaze.base.sync.data.BlazeDataStorage; import com.google.idea.common.experiments.BoolExperiment; import com.google.idea.common.experiments.FeatureRolloutExperiment; @@ -42,7 +41,8 @@ import org.jetbrains.annotations.Nullable; /** Implementation of {@link LightResourceClassService} set up at Blaze sync time. */ -public class BlazeLightResourceClassService implements LightResourceClassService { +public class BlazeLightResourceClassService extends BlazeLightResourceClassServiceBase + implements LightResourceClassService { @VisibleForTesting public static final FeatureRolloutExperiment workspaceResourcesFeature = @@ -57,13 +57,11 @@ public class BlazeLightResourceClassService implements LightResourceClassService private final Project project; - private Map rClasses = Maps.newHashMap(); - private Map rClassesByModule = Maps.newHashMap(); private Map rClassPackages = Maps.newHashMap(); private Map workspaceRClasses = Maps.newHashMap(); private Set workspaceRClassNames = ImmutableSet.of(); + private Set workspaceResourcePackages = ImmutableSet.of(); - private final Set allRClasses = Sets.newHashSet(); private PsiManager psiManager; public static BlazeLightResourceClassService getInstance(Project project) { @@ -80,6 +78,7 @@ public static class Builder { Map rClassByModuleMap = Maps.newHashMap(); Map rClassPackages = Maps.newHashMap(); Set workspaceRClassNames = ImmutableSet.of(); + Set workspaceResourcePackages = ImmutableSet.of(); PsiManager psiManager; @@ -104,6 +103,7 @@ public void addWorkspacePackages(Set resourceJavaPackages) { if (!workspaceResourcesFeature.isEnabled()) { return; } + this.workspaceResourcePackages = resourceJavaPackages; this.workspaceRClassNames = resourceJavaPackages.stream() .map(Builder::getQualifiedRClassName) @@ -132,11 +132,16 @@ private void addStubPackages(String resourceJavaPackage) { } } + public Set getWorkspaceResourcePackages() { + return workspaceResourcePackages; + } + public void installRClasses(Builder builder) { this.rClasses = builder.rClassMap; this.rClassesByModule = builder.rClassByModuleMap; this.rClassPackages = builder.rClassPackages; + this.workspaceResourcePackages = builder.workspaceResourcePackages; this.workspaceRClasses = new HashMap<>(); this.workspaceRClassNames = ImmutableSet.copyOf(builder.workspaceRClassNames); this.psiManager = builder.psiManager; @@ -196,30 +201,6 @@ private BlazeRClass getRClassForWorkspace(String qualifiedName, GlobalSearchScop } @Override - public Collection getLightRClassesAccessibleFromModule( - Module module, boolean includeTest) { - if (workspaceResourcesFeature.isEnabled() - && module.getName().equals(BlazeDataStorage.WORKSPACE_MODULE_NAME)) { - // Returns all the packages in resource modules, and all the workspace packages that - // have previously been asked for. All `res/` directories in our project should belong to a - // resource module. For java sources, IntelliJ will ask for explicit resource package by - // calling `getLightRClasses` at which point we can create the package. This is not completely - // correct and the autocomplete will be slightly off when initial `R` is typed in the editor, - // but this workaround is being used to mitigate issues (b/136685602) while resources - // are re-worked. - return allRClasses; - } else { - return rClasses.values(); - } - } - - // @Override #api4.0: override added in as4.1 - public Collection getLightRClassesDefinedByModule( - Module module, boolean includeTestClasses) { - BlazeRClass rClass = rClassesByModule.get(module); - return rClass == null ? ImmutableSet.of() : ImmutableSet.of(rClass); - } - public Collection getLightRClassesContainingModuleResources(Module module) { return rClasses.values(); } diff --git a/aswb/src/com/google/idea/blaze/android/resources/BlazeLightResourceClassServiceBase.java b/aswb/src/com/google/idea/blaze/android/resources/BlazeLightResourceClassServiceBase.java new file mode 100644 index 00000000000..be9c3b2d882 --- /dev/null +++ b/aswb/src/com/google/idea/blaze/android/resources/BlazeLightResourceClassServiceBase.java @@ -0,0 +1,64 @@ +/* + * Copyright 2016 The Bazel Authors. All rights reserved. + * + * 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. + */ +package com.google.idea.blaze.android.resources; + +import com.android.tools.idea.projectsystem.LightResourceClassService; +import com.google.common.annotations.VisibleForTesting; +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Maps; +import com.google.common.collect.Sets; +import com.google.idea.blaze.base.sync.data.BlazeDataStorage; +import com.google.idea.common.experiments.FeatureRolloutExperiment; +import com.intellij.openapi.module.Module; +import com.intellij.psi.PsiClass; +import java.util.Collection; +import java.util.Map; +import java.util.Set; + +/** Implementation of {@link LightResourceClassService} set up at Blaze sync time. */ +public abstract class BlazeLightResourceClassServiceBase implements LightResourceClassService { + + @VisibleForTesting + public static final FeatureRolloutExperiment workspaceResourcesFeature = + new FeatureRolloutExperiment("aswb.workspace.light.class.enabled"); + + Map rClasses = Maps.newHashMap(); + Map rClassesByModule = Maps.newHashMap(); + final Set allRClasses = Sets.newHashSet(); + + @Override + public Collection getLightRClassesAccessibleFromModule(Module module) { + if (workspaceResourcesFeature.isEnabled() + && module.getName().equals(BlazeDataStorage.WORKSPACE_MODULE_NAME)) { + // Returns all the packages in resource modules, and all the workspace packages that + // have previously been asked for. All `res/` directories in our project should belong to a + // resource module. For java sources, IntelliJ will ask for explicit resource package by + // calling `getLightRClasses` at which point we can create the package. This is not completely + // correct and the autocomplete will be slightly off when initial `R` is typed in the editor, + // but this workaround is being used to mitigate issues (b/136685602) while resources + // are re-worked. + return allRClasses; + } else { + return rClasses.values(); + } + } + + @Override + public Collection getLightRClassesDefinedByModule(Module module) { + BlazeRClass rClass = rClassesByModule.get(module); + return rClass == null ? ImmutableSet.of() : ImmutableSet.of(rClass); + } +} diff --git a/aswb/src/com/google/idea/blaze/android/resources/BlazeRClass.java b/aswb/src/com/google/idea/blaze/android/resources/BlazeRClass.java new file mode 100644 index 00000000000..3c64683d517 --- /dev/null +++ b/aswb/src/com/google/idea/blaze/android/resources/BlazeRClass.java @@ -0,0 +1,82 @@ +/* + * Copyright 2018 The Bazel Authors. All rights reserved. + * + * 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. + */ +package com.google.idea.blaze.android.resources; + +import static org.jetbrains.android.AndroidResolveScopeEnlarger.LIGHT_CLASS_KEY; +import static org.jetbrains.android.AndroidResolveScopeEnlarger.MODULE_POINTER_KEY; + +import com.android.ide.common.rendering.api.ResourceNamespace; +import com.android.tools.idea.res.ResourceRepositoryRClass; +import com.android.tools.idea.res.StudioResourceRepositoryManager; +import com.android.tools.res.LocalResourceRepository; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.ModulePointerManager; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiManager; +import org.jetbrains.android.augment.AndroidLightField; +import org.jetbrains.android.facet.AndroidFacet; + +/** Blaze implementation of an R class based on resource repositories. */ +public class BlazeRClass extends ResourceRepositoryRClass { + + private final AndroidFacet androidFacet; + + public BlazeRClass(PsiManager psiManager, AndroidFacet androidFacet, String packageName) { + super( + psiManager, + new ResourcesSource() { + @Override + public String getPackageName() { + return packageName; + } + + // @Override #api4.1 + public Transitivity getTransitivity() { + return Transitivity.TRANSITIVE; + } + + @Override + public StudioResourceRepositoryManager getResourceRepositoryManager() { + return StudioResourceRepositoryManager.getInstance(androidFacet); + } + + @Override + public LocalResourceRepository getResourceRepository() { + return StudioResourceRepositoryManager.getAppResources(androidFacet); + } + + @Override + public ResourceNamespace getResourceNamespace() { + return ResourceNamespace.RES_AUTO; + } + + @Override + public AndroidLightField.FieldModifier getFieldModifier() { + return AndroidLightField.FieldModifier.NON_FINAL; + } + }); + this.androidFacet = androidFacet; + setModuleInfo(getModule(), false); + VirtualFile virtualFile = myFile.getViewProvider().getVirtualFile(); + virtualFile.putUserData( + MODULE_POINTER_KEY, ModulePointerManager.getInstance(getProject()).create(getModule())); + virtualFile.putUserData(LIGHT_CLASS_KEY, ResourceRepositoryRClass.class); + } + + public Module getModule() { + return androidFacet.getModule(); + } +} diff --git a/aswb/src/com/google/idea/blaze/android/resources/actions/BlazeCreateResourceUtils.java b/aswb/src/com/google/idea/blaze/android/resources/actions/BlazeCreateResourceUtils.java index 6def189f7d0..1ca0f34b281 100644 --- a/aswb/src/com/google/idea/blaze/android/resources/actions/BlazeCreateResourceUtils.java +++ b/aswb/src/com/google/idea/blaze/android/resources/actions/BlazeCreateResourceUtils.java @@ -24,6 +24,8 @@ import com.google.idea.blaze.base.command.buildresult.OutputArtifactResolver; import com.google.idea.blaze.base.ideinfo.TargetKey; import com.google.idea.blaze.base.model.BlazeProjectData; +import com.google.idea.blaze.base.settings.Blaze; +import com.google.idea.blaze.base.settings.BlazeImportSettings.ProjectType; import com.google.idea.blaze.base.sync.data.BlazeProjectDataManager; import com.google.idea.blaze.base.sync.workspace.ArtifactLocationDecoder; import com.google.idea.blaze.base.targetmaps.SourceToTargetMap; @@ -50,6 +52,8 @@ class BlazeCreateResourceUtils { private static final String PLACEHOLDER_TEXT = "choose a res/ directory with dropdown or browse button"; + // TODO(b/295880481): Revisit how resources are created. This file conflates logic and UI, but it + // also reveals that the integration with Studio is done at the wrong level. static void setupResDirectoryChoices( Project project, @Nullable VirtualFile contextFile, @@ -57,6 +61,31 @@ static void setupResDirectoryChoices( ComboboxWithBrowseButton resDirComboAndBrowser) { // Reset the item list before filling it back up. resDirComboAndBrowser.getComboBox().removeAllItems(); + + if (Blaze.getProjectType(project).equals(ProjectType.QUERY_SYNC)) { + if (contextFile == null) { + return; + } + // For query sync, populates the combo box with either the directory itself, if a directory + // was right-clicked, or the containing directory, if a file was right-clicked. This + // could be augmented with additional options (i.e. res folders in higher directories and + // perhaps other res folders) + File fileFromContext = VfsUtilCore.virtualToIoFile(contextFile); + if (!fileFromContext.isDirectory()) { + fileFromContext = fileFromContext.getParentFile(); + } + File closestDirToContext = new File(fileFromContext.getPath(), "res"); + + @SuppressWarnings({"unchecked", "rawtypes"}) // Class comes with raw type from JetBrains + JComboBox resDirCombo = resDirComboAndBrowser.getComboBox(); + resDirCombo.setEditable(true); + resDirCombo.addItem(closestDirToContext); + resDirCombo.setSelectedItem(closestDirToContext); + resDirComboAndBrowser.setVisible(true); + resDirLabel.setVisible(true); + return; + } + BlazeProjectData blazeProjectData = BlazeProjectDataManager.getInstance(project).getBlazeProjectData(); if (blazeProjectData != null) { diff --git a/aswb/src/com/google/idea/blaze/android/run/BazelApplicationProjectContext.java b/aswb/src/com/google/idea/blaze/android/run/BazelApplicationProjectContext.java new file mode 100644 index 00000000000..cbca2310836 --- /dev/null +++ b/aswb/src/com/google/idea/blaze/android/run/BazelApplicationProjectContext.java @@ -0,0 +1,61 @@ +/* + * Copyright 2023 The Bazel Authors. All rights reserved. + * + * 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. + */ +package com.google.idea.blaze.android.run; + +import com.android.tools.idea.projectsystem.ApplicationProjectContext; +import com.android.tools.idea.run.ApkProvisionException; +import com.android.tools.idea.run.ApplicationIdProvider; +import com.intellij.openapi.project.Project; +import java.util.function.Supplier; + +/** + * An implementation of {@link ApplicationProjectContext} used in the Blaze project system. + * + *

Note: The Blaze project system assumes all instances of the {@link + * ApplicationProjectContext} associated with its projects to be backed by this specific class. + */ +public class BazelApplicationProjectContext implements ApplicationProjectContext { + + private final Project project; + private final Supplier applicationId; + + public BazelApplicationProjectContext(Project project, String applicationId) { + this.project = project; + this.applicationId = () -> applicationId; + } + + public BazelApplicationProjectContext( + Project project, ApplicationIdProvider applicationIdProvider) { + this.project = project; + this.applicationId = + () -> { + try { + return applicationIdProvider.getPackageName(); + } catch (ApkProvisionException e) { + throw new RuntimeException(e); + } + }; + } + + public Project getProject() { + return project; + } + + @Override + public String getApplicationId() { + return applicationId.get(); + } +} diff --git a/aswb/src/com/google/idea/blaze/android/run/BazelApplicationProjectContextProvider.java b/aswb/src/com/google/idea/blaze/android/run/BazelApplicationProjectContextProvider.java new file mode 100644 index 00000000000..da3d9de897f --- /dev/null +++ b/aswb/src/com/google/idea/blaze/android/run/BazelApplicationProjectContextProvider.java @@ -0,0 +1,40 @@ +/* + * Copyright 2024 The Bazel Authors. All rights reserved. + * + * 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. + */ +package com.google.idea.blaze.android.run; + +import com.android.tools.idea.projectsystem.ApplicationProjectContext; +import com.android.tools.idea.projectsystem.ApplicationProjectContextProvider; +import com.google.idea.blaze.android.projectsystem.BazelProjectSystem; +import com.google.idea.blaze.android.projectsystem.BazelToken; +import javax.annotation.Nullable; + +/** An implementation of {@link ApplicationProjectContextProvider} for the Blaze project system. */ +public class BazelApplicationProjectContextProvider + implements ApplicationProjectContextProvider, BazelToken { + + @Nullable + @Override + public ApplicationProjectContext computeApplicationProjectContext( + BazelProjectSystem projectSystem, + ApplicationProjectContextProvider.RunningApplicationIdentity identity + ) { + String applicationId = identity.getHeuristicApplicationId(); + if (applicationId == null) { + return null; + } + return new BazelApplicationProjectContext(projectSystem.getProject(), applicationId); + } +} diff --git a/aswb/src/com/google/idea/blaze/android/run/BazelNativeDebuggerAppContextProvider.java b/aswb/src/com/google/idea/blaze/android/run/BazelNativeDebuggerAppContextProvider.java new file mode 100644 index 00000000000..ee2817f48d0 --- /dev/null +++ b/aswb/src/com/google/idea/blaze/android/run/BazelNativeDebuggerAppContextProvider.java @@ -0,0 +1,75 @@ +/* + * 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. + */ +package com.google.idea.blaze.android.run; + +import com.android.sdklib.devices.Abi; +import com.android.tools.idea.projectsystem.ApplicationProjectContext; +import com.android.tools.ndk.run.NativeDebuggerAppContext; +import com.android.tools.ndk.run.NativeDebuggerAppContextProvider; +import com.android.tools.ndk.run.SymbolDir; +import com.google.idea.blaze.android.projectsystem.BazelToken; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.project.Project; +import java.io.File; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.Map; + +/** An implementation of {@link NativeDebuggerAppContextProvider} for the Blaze project system. */ +public class BazelNativeDebuggerAppContextProvider + implements NativeDebuggerAppContextProvider, BazelToken { + + @Override + public NativeDebuggerAppContext getNativeDebuggerAppContext( + ApplicationProjectContext applicationProjectContext) { + final var context = (BazelApplicationProjectContext) applicationProjectContext; + // TODO(solodkyy): Find out whether any configuration that is supposed to be part of this + // context is passed to the debugger in oher ways and make sure this is the + // only way to set up the debugger. + return new NativeDebuggerAppContext() { + @Override + public Project getProject() { + return context.getProject(); + } + + @Override + public String getApplicationId() { + return context.getApplicationId(); + } + + @Override + public Collection getSymDirs(List abis) { + return Collections.emptyList(); + } + + @Override + public Map getSourceMap() { + return Collections.emptyMap(); + } + + @Override + public Map getExplicitModuleSymbolMap(Abi abi) { + return Collections.emptyMap(); + } + + @Override + public Collection getModulesToVerify() { + return Collections.emptyList(); + } + }; + } +} diff --git a/aswb/src/com/google/idea/blaze/android/run/BlazeAndroidRunConfigurationCommonState.java b/aswb/src/com/google/idea/blaze/android/run/BlazeAndroidRunConfigurationCommonState.java index 756ea45a61c..020c43f6ee4 100644 --- a/aswb/src/com/google/idea/blaze/android/run/BlazeAndroidRunConfigurationCommonState.java +++ b/aswb/src/com/google/idea/blaze/android/run/BlazeAndroidRunConfigurationCommonState.java @@ -27,10 +27,13 @@ import com.google.idea.blaze.base.model.BlazeProjectData; import com.google.idea.blaze.base.model.primitives.LanguageClass; import com.google.idea.blaze.base.projectview.ProjectViewSet; +import com.google.idea.blaze.base.qsync.QuerySync; import com.google.idea.blaze.base.run.state.RunConfigurationFlagsState; import com.google.idea.blaze.base.run.state.RunConfigurationState; import com.google.idea.blaze.base.run.state.RunConfigurationStateEditor; import com.google.idea.blaze.base.scope.BlazeContext; +import com.google.idea.blaze.base.settings.Blaze; +import com.google.idea.blaze.base.settings.BlazeImportSettings.ProjectType; import com.google.idea.blaze.base.sync.data.BlazeProjectDataManager; import com.google.idea.blaze.base.ui.UiUtil; import com.intellij.openapi.project.Project; @@ -105,6 +108,9 @@ private ImmutableList getNativeDebuggerFlags() { * warning. */ public List validate(Project project) { + if (Blaze.getProjectType(project) == ProjectType.QUERY_SYNC) { + return ImmutableList.of(); + } List errors = Lists.newArrayList(); BlazeProjectData blazeProjectData = BlazeProjectDataManager.getInstance(project).getBlazeProjectData(); diff --git a/aswb/src/com/google/idea/blaze/android/run/BlazeAndroidRunConfigurationValidationUtil.java b/aswb/src/com/google/idea/blaze/android/run/BlazeAndroidRunConfigurationValidationUtil.java index c717407a075..f06e9fff494 100644 --- a/aswb/src/com/google/idea/blaze/android/run/BlazeAndroidRunConfigurationValidationUtil.java +++ b/aswb/src/com/google/idea/blaze/android/run/BlazeAndroidRunConfigurationValidationUtil.java @@ -33,7 +33,7 @@ import com.intellij.openapi.project.Project; import java.util.List; import org.jetbrains.android.facet.AndroidFacet; -import org.jetbrains.android.sdk.AndroidPlatformsCompat; +import org.jetbrains.android.sdk.AndroidPlatforms; import org.jetbrains.android.util.AndroidBundle; /** @@ -80,7 +80,7 @@ public static List validateWorkspaceModule(Project project) { "Android model missing from workspace module. Please resync project.", () -> resync(project))); } - if (AndroidPlatformsCompat.getInstance(workspaceModule) == null) { + if (AndroidPlatforms.getInstance(workspaceModule) == null) { errors.add(ValidationError.fatal(AndroidBundle.message("select.platform.error"))); } return errors; diff --git a/aswb/sdkcompat/as222/com/google/idea/blaze/android/run/BlazeCommandAndroidDebuggerInfoProvider.java b/aswb/src/com/google/idea/blaze/android/run/BlazeCommandAndroidDebuggerInfoProvider.java similarity index 100% rename from aswb/sdkcompat/as222/com/google/idea/blaze/android/run/BlazeCommandAndroidDebuggerInfoProvider.java rename to aswb/src/com/google/idea/blaze/android/run/BlazeCommandAndroidDebuggerInfoProvider.java diff --git a/aswb/src/com/google/idea/blaze/android/run/binary/BlazeAndroidBinaryApplicationLaunchTaskProvider.java b/aswb/src/com/google/idea/blaze/android/run/binary/BlazeAndroidBinaryApplicationLaunchTaskProvider.java new file mode 100644 index 00000000000..948dae75f36 --- /dev/null +++ b/aswb/src/com/google/idea/blaze/android/run/binary/BlazeAndroidBinaryApplicationLaunchTaskProvider.java @@ -0,0 +1,72 @@ +/* + * Copyright 2016 The Bazel Authors. All rights reserved. + * + * 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. + */ +package com.google.idea.blaze.android.run.binary; + +import com.android.tools.idea.run.ApkProvisionException; +import com.android.tools.idea.run.ApplicationIdProvider; +import com.android.tools.idea.run.activity.StartActivityFlagsProvider; +import com.android.tools.idea.run.blaze.BlazeLaunchTask; +import com.google.idea.blaze.android.manifest.ManifestParser; +import com.google.idea.blaze.android.run.binary.tasks.AndroidDeepLinkLaunchTask; +import com.google.idea.blaze.android.run.binary.tasks.BlazeDefaultActivityLaunchTask; +import com.google.idea.blaze.android.run.binary.tasks.SpecificActivityLaunchTask; +import com.intellij.execution.ExecutionException; +import com.intellij.openapi.diagnostic.Logger; + +/** Provides the launch task for android_binary */ +public class BlazeAndroidBinaryApplicationLaunchTaskProvider { + private static final Logger LOG = + Logger.getInstance(BlazeAndroidBinaryApplicationLaunchTaskProvider.class); + + public static BlazeLaunchTask getApplicationLaunchTask( + ApplicationIdProvider applicationIdProvider, + ManifestParser.ParsedManifest mergedManifestParsedManifest, + BlazeAndroidBinaryRunConfigurationState configState, + StartActivityFlagsProvider startActivityFlagsProvider) + throws ExecutionException { + String applicationId; + try { + applicationId = applicationIdProvider.getPackageName(); + } catch (ApkProvisionException e) { + throw new ExecutionException("Unable to identify application id"); + } + + switch (configState.getMode()) { + case BlazeAndroidBinaryRunConfigurationState.LAUNCH_DEFAULT_ACTIVITY: + BlazeDefaultActivityLocator activityLocator = + new BlazeDefaultActivityLocator(mergedManifestParsedManifest); + return new BlazeDefaultActivityLaunchTask( + applicationId, activityLocator, startActivityFlagsProvider); + case BlazeAndroidBinaryRunConfigurationState.LAUNCH_SPECIFIC_ACTIVITY: + return launchContext -> + new SpecificActivityLaunchTask( + applicationId, configState.getActivityClass(), startActivityFlagsProvider) + .run( + launchContext.getDevice(), + launchContext.getProgressIndicator(), + launchContext.getConsoleView()); + case BlazeAndroidBinaryRunConfigurationState.LAUNCH_DEEP_LINK: + return launchContext -> + new AndroidDeepLinkLaunchTask(configState.getDeepLink(), startActivityFlagsProvider) + .run( + launchContext.getDevice(), + launchContext.getProgressIndicator(), + launchContext.getConsoleView()); + default: + return null; + } + } +} diff --git a/aswb/src/com/google/idea/blaze/android/run/binary/BlazeAndroidBinaryNormalBuildRunContext.java b/aswb/src/com/google/idea/blaze/android/run/binary/BlazeAndroidBinaryNormalBuildRunContext.java new file mode 100644 index 00000000000..1d134314d6e --- /dev/null +++ b/aswb/src/com/google/idea/blaze/android/run/binary/BlazeAndroidBinaryNormalBuildRunContext.java @@ -0,0 +1,131 @@ +/* + * Copyright 2019 The Bazel Authors. All rights reserved. + * + * 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. + */ +package com.google.idea.blaze.android.run.binary; + +import com.android.ddmlib.ClientData; +import com.android.ddmlib.IDevice; +import com.android.tools.idea.execution.common.debug.AndroidDebugger; +import com.android.tools.idea.execution.common.debug.AndroidDebuggerState; +import com.android.tools.idea.execution.common.debug.DebugSessionStarter; +import com.android.tools.idea.projectsystem.ApplicationProjectContext; +import com.android.tools.idea.run.ApkProvisionException; +import com.android.tools.idea.run.activity.DefaultStartActivityFlagsProvider; +import com.android.tools.idea.run.activity.StartActivityFlagsProvider; +import com.android.tools.idea.run.blaze.BlazeLaunchTask; +import com.google.idea.blaze.android.run.BazelApplicationProjectContext; +import com.google.idea.blaze.android.run.deployinfo.BlazeAndroidDeployInfo; +import com.google.idea.blaze.android.run.runner.ApkBuildStep; +import com.intellij.execution.ExecutionException; +import com.intellij.execution.Executor; +import com.intellij.execution.configurations.RunConfiguration; +import com.intellij.execution.runners.ExecutionEnvironment; +import com.intellij.execution.ui.ConsoleView; +import com.intellij.openapi.progress.ProcessCanceledException; +import com.intellij.openapi.progress.ProgressIndicator; +import com.intellij.openapi.project.Project; +import com.intellij.xdebugger.XDebugSession; +import javax.annotation.Nullable; +import kotlin.Unit; +import kotlin.coroutines.EmptyCoroutineContext; +import kotlinx.coroutines.BuildersKt; +import org.jetbrains.android.facet.AndroidFacet; + +public class BlazeAndroidBinaryNormalBuildRunContext + extends BlazeAndroidBinaryNormalBuildRunContextBase { + BlazeAndroidBinaryNormalBuildRunContext( + Project project, + AndroidFacet facet, + RunConfiguration runConfiguration, + ExecutionEnvironment env, + BlazeAndroidBinaryRunConfigurationState configState, + ApkBuildStep buildStep, + String launchId) { + super(project, facet, runConfiguration, env, configState, buildStep, launchId); + } + + @Override + public ApplicationProjectContext getApplicationProjectContext() { + return new BazelApplicationProjectContext(project, getApplicationIdProvider()); + } + + @Override + public BlazeLaunchTask getApplicationLaunchTask( + boolean isDebug, @Nullable Integer userId, String contributorsAmStartOptions) + throws ExecutionException { + String extraFlags = UserIdHelper.getFlagsFromUserId(userId); + if (!contributorsAmStartOptions.isEmpty()) { + extraFlags += (extraFlags.isEmpty() ? "" : " ") + contributorsAmStartOptions; + } + if (isDebug) { + extraFlags += (extraFlags.isEmpty() ? "" : " ") + "-D"; + } + + final StartActivityFlagsProvider startActivityFlagsProvider = + new DefaultStartActivityFlagsProvider(project, isDebug, extraFlags); + + BlazeAndroidDeployInfo deployInfo; + try { + deployInfo = buildStep.getDeployInfo(); + } catch (ApkProvisionException e) { + throw new ExecutionException(e); + } + + return BlazeAndroidBinaryApplicationLaunchTaskProvider.getApplicationLaunchTask( + applicationIdProvider, + deployInfo.getMergedManifest(), + configState, + startActivityFlagsProvider); + } + + @Nullable + @Override + public XDebugSession startDebuggerSession( + AndroidDebugger androidDebugger, + AndroidDebuggerState androidDebuggerState, + ExecutionEnvironment env, + IDevice device, + ConsoleView consoleView, + ProgressIndicator indicator, + String packageName) { + try { + return BuildersKt.runBlocking( + EmptyCoroutineContext.INSTANCE, + (scope, continuation) -> + DebugSessionStarter.INSTANCE.attachDebuggerToStartedProcess( + device, + new BazelApplicationProjectContext(project, packageName), + env, + androidDebugger, + androidDebuggerState, + /*destroyRunningProcess*/ d -> { + d.forceStop(packageName); + return Unit.INSTANCE; + }, + indicator, + consoleView, + 15L, + ClientData.DebuggerStatus.WAITING, + continuation)); + } catch (InterruptedException e) { + throw new ProcessCanceledException(); + } + } + + @Override + public Executor getExecutor() { + return env.getExecutor(); + } +} diff --git a/aswb/src/com/google/idea/blaze/android/run/binary/BlazeAndroidBinaryNormalBuildRunContextBase.java b/aswb/src/com/google/idea/blaze/android/run/binary/BlazeAndroidBinaryNormalBuildRunContextBase.java new file mode 100644 index 00000000000..79e00886994 --- /dev/null +++ b/aswb/src/com/google/idea/blaze/android/run/binary/BlazeAndroidBinaryNormalBuildRunContextBase.java @@ -0,0 +1,186 @@ +/* + * Copyright 2016 The Bazel Authors. All rights reserved. + * + * 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. + */ +package com.google.idea.blaze.android.run.binary; + +import static com.google.idea.blaze.android.run.runner.BlazeAndroidLaunchTasksProvider.NATIVE_DEBUGGING_ENABLED; + +import com.android.ddmlib.IDevice; +import com.android.tools.idea.execution.common.DeployOptions; +import com.android.tools.idea.run.ApkFileUnit; +import com.android.tools.idea.run.ApkInfo; +import com.android.tools.idea.run.ApkProvider; +import com.android.tools.idea.run.ApkProvisionException; +import com.android.tools.idea.run.ApplicationIdProvider; +import com.android.tools.idea.run.ConsoleProvider; +import com.android.tools.idea.run.LaunchOptions; +import com.android.tools.idea.run.blaze.BlazeLaunchTask; +import com.android.tools.idea.run.blaze.BlazeLaunchTasksProvider; +import com.android.tools.idea.run.editor.ProfilerState; +import com.android.tools.idea.util.DynamicAppUtils; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import com.google.idea.blaze.android.run.deployinfo.BlazeApkProviderService; +import com.google.idea.blaze.android.run.runner.ApkBuildStep; +import com.google.idea.blaze.android.run.runner.BlazeAndroidDeviceSelector; +import com.google.idea.blaze.android.run.runner.BlazeAndroidLaunchTasksProvider; +import com.google.idea.blaze.android.run.runner.BlazeAndroidRunContext; +import com.intellij.execution.ExecutionException; +import com.intellij.execution.Executor; +import com.intellij.execution.configurations.RunConfiguration; +import com.intellij.execution.runners.ExecutionEnvironment; +import com.intellij.openapi.project.Project; +import java.util.Collection; +import java.util.List; +import java.util.stream.Collectors; +import javax.annotation.Nullable; +import org.jetbrains.android.facet.AndroidFacet; +import org.jetbrains.annotations.NotNull; + +/** Run context for android_binary. */ +public abstract class BlazeAndroidBinaryNormalBuildRunContextBase + implements BlazeAndroidRunContext { + protected final Project project; + protected final AndroidFacet facet; + protected final RunConfiguration runConfiguration; + protected final ExecutionEnvironment env; + protected final BlazeAndroidBinaryRunConfigurationState configState; + protected final ConsoleProvider consoleProvider; + protected final ApkBuildStep buildStep; + protected final ApkProvider apkProvider; + protected final ApplicationIdProvider applicationIdProvider; + private final String launchId; + + BlazeAndroidBinaryNormalBuildRunContextBase( + Project project, + AndroidFacet facet, + RunConfiguration runConfiguration, + ExecutionEnvironment env, + BlazeAndroidBinaryRunConfigurationState configState, + ApkBuildStep buildStep, + String launchId) { + this.project = project; + this.facet = facet; + this.runConfiguration = runConfiguration; + this.env = env; + this.configState = configState; + this.consoleProvider = new BlazeAndroidBinaryConsoleProvider(project); + this.buildStep = buildStep; + this.apkProvider = BlazeApkProviderService.getInstance().getApkProvider(project, buildStep); + this.applicationIdProvider = new BlazeAndroidBinaryApplicationIdProvider(buildStep); + this.launchId = launchId; + } + + @Override + public BlazeAndroidDeviceSelector getDeviceSelector() { + return new BlazeAndroidDeviceSelector.NormalDeviceSelector(); + } + + @Override + public void augmentLaunchOptions(LaunchOptions.Builder options) { + LaunchOptions.Builder unused = + options + .setDeploy(true) + .setOpenLogcatAutomatically(configState.showLogcatAutomatically()) + .addExtraOptions( + ImmutableMap.of( + NATIVE_DEBUGGING_ENABLED, + configState.getCommonState().isNativeDebuggingEnabled())) + .setClearAppStorage(configState.getClearAppStorage()); + } + + @Override + public ConsoleProvider getConsoleProvider() { + return consoleProvider; + } + + @Override + public ApplicationIdProvider getApplicationIdProvider() { + return applicationIdProvider; + } + + @Override + public ApkBuildStep getBuildStep() { + return buildStep; + } + + @Nullable + @Override + public Integer getUserId(IDevice device) throws ExecutionException { + return UserIdHelper.getUserIdFromConfigurationState(project, device, configState); + } + + @Override + public BlazeLaunchTasksProvider getLaunchTasksProvider(LaunchOptions launchOptions) + throws ExecutionException { + return new BlazeAndroidLaunchTasksProvider(project, this, applicationIdProvider, launchOptions); + } + + @Override + public String getAmStartOptions() { + return configState.getAmStartOptions(); + } + + @Nullable + @Override + public ImmutableList getDeployTasks(IDevice device, DeployOptions deployOptions) + throws ExecutionException { + return ImmutableList.of( + new DeploymentTimingReporterTask( + launchId, + project, + getApkInfoToInstall(device, deployOptions, apkProvider), + deployOptions)); + } + + /** Returns a list of APKs excluding any APKs for features that are disabled. */ + public static List getApkInfoToInstall( + IDevice device, DeployOptions deployOptions, ApkProvider apkProvider) + throws ExecutionException { + Collection apks; + try { + apks = apkProvider.getApks(device); + } catch (ApkProvisionException e) { + throw new ExecutionException(e); + } + List disabledFeatures = deployOptions.getDisabledDynamicFeatures(); + return apks.stream() + .map(apk -> getApkInfoToInstall(apk, disabledFeatures)) + .collect(Collectors.toList()); + } + + @NotNull + private static ApkInfo getApkInfoToInstall(ApkInfo apkInfo, List disabledFeatures) { + if (apkInfo.getFiles().size() > 1) { + List filteredApks = + apkInfo.getFiles().stream() + .filter(feature -> DynamicAppUtils.isFeatureEnabled(disabledFeatures, feature)) + .collect(Collectors.toList()); + return new ApkInfo(filteredApks, apkInfo.getApplicationId()); + } else { + return apkInfo; + } + } + + @Override + public Executor getExecutor() { + return env.getExecutor(); + } + + @Override + public ProfilerState getProfileState() { + return configState.getProfilerState(); + } +} diff --git a/aswb/src/com/google/idea/blaze/android/run/binary/BlazeAndroidBinaryProgramRunner.java b/aswb/src/com/google/idea/blaze/android/run/binary/BlazeAndroidBinaryProgramRunner.java new file mode 100644 index 00000000000..60bd11debaf --- /dev/null +++ b/aswb/src/com/google/idea/blaze/android/run/binary/BlazeAndroidBinaryProgramRunner.java @@ -0,0 +1,114 @@ +/* + * Copyright 2016 The Bazel Authors. All rights reserved. + * + * 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. + */ +package com.google.idea.blaze.android.run.binary; + +import static com.intellij.openapi.application.ModalityState.NON_MODAL; + +import com.android.tools.idea.execution.common.AndroidConfigurationExecutor; +import com.android.tools.idea.profilers.ProfileRunExecutor; +import com.google.idea.blaze.android.run.BlazeAndroidRunConfigurationHandler; +import com.intellij.execution.ExecutionException; +import com.intellij.execution.ExecutionResult; +import com.intellij.execution.Executor; +import com.intellij.execution.configurations.RunProfile; +import com.intellij.execution.configurations.RunProfileState; +import com.intellij.execution.configurations.RunnerSettings; +import com.intellij.execution.executors.DefaultDebugExecutor; +import com.intellij.execution.executors.DefaultRunExecutor; +import com.intellij.execution.runners.AsyncProgramRunner; +import com.intellij.execution.runners.ExecutionEnvironment; +import com.intellij.execution.runners.RunContentBuilder; +import com.intellij.execution.ui.RunContentDescriptor; +import com.intellij.openapi.application.ActionsKt; +import com.intellij.openapi.fileEditor.FileDocumentManager; +import com.intellij.openapi.progress.ProgressIndicator; +import com.intellij.openapi.progress.ProgressManager; +import com.intellij.openapi.progress.Task; +import org.jetbrains.concurrency.AsyncPromise; +import org.jetbrains.concurrency.Promise; + +/** Program runner for configurations from {@link BlazeAndroidBinaryRunConfigurationHandler}. */ +public class BlazeAndroidBinaryProgramRunner extends AsyncProgramRunner { + @Override + public boolean canRun(String executorId, RunProfile profile) { + BlazeAndroidRunConfigurationHandler handler = + BlazeAndroidRunConfigurationHandler.getHandlerFrom(profile); + if (!(handler instanceof BlazeAndroidBinaryRunConfigurationHandler)) { + return false; + } + return (DefaultDebugExecutor.EXECUTOR_ID.equals(executorId) + || DefaultRunExecutor.EXECUTOR_ID.equals(executorId) + || ProfileRunExecutor.EXECUTOR_ID.equals(executorId)); + } + + @Override + protected Promise execute( + ExecutionEnvironment environment, RunProfileState state) { + FileDocumentManager.getInstance().saveAllDocuments(); + + AsyncPromise promise = new AsyncPromise<>(); + + ProgressManager.getInstance() + .run( + new Task.Backgroundable(environment.getProject(), "Launching ${runProfile.name}") { + @Override + public void run(ProgressIndicator indicator) { + try { + RunContentDescriptor descriptor; + if (state instanceof AndroidConfigurationExecutor) { + AndroidConfigurationExecutor configurationExecutor = + (AndroidConfigurationExecutor) state; + Executor executor = environment.getExecutor(); + if (executor.getId().equals(DefaultDebugExecutor.EXECUTOR_ID)) { + descriptor = configurationExecutor.debug(indicator); + } else if (executor.getId().equals(DefaultRunExecutor.EXECUTOR_ID) + || executor.getId().equals(ProfileRunExecutor.EXECUTOR_ID)) { + descriptor = configurationExecutor.run(indicator); + } else { + throw new ExecutionException("Unsupported executor"); + } + } else { + descriptor = doExecute(state, environment); + } + promise.setResult(descriptor); + } catch (ExecutionException e) { + boolean unused = promise.setError(e); + } + } + + @Override + public void onCancel() { + super.onCancel(); + promise.setResult(null); + } + }); + + return promise; + } + + private RunContentDescriptor doExecute( + final RunProfileState state, final ExecutionEnvironment env) throws ExecutionException { + ExecutionResult result = state.execute(env.getExecutor(), this); + return ActionsKt.invokeAndWaitIfNeeded( + NON_MODAL, + () -> new RunContentBuilder(result, env).showRunContent(env.getContentToReuse())); + } + + @Override + public String getRunnerId() { + return "AndroidBinaryProgramRunner"; + } +} diff --git a/aswb/src/com/google/idea/blaze/android/run/binary/BlazeAndroidBinaryRunConfigurationHandler.java b/aswb/src/com/google/idea/blaze/android/run/binary/BlazeAndroidBinaryRunConfigurationHandler.java index bd3ed5607c2..c31ad4cbad5 100644 --- a/aswb/src/com/google/idea/blaze/android/run/binary/BlazeAndroidBinaryRunConfigurationHandler.java +++ b/aswb/src/com/google/idea/blaze/android/run/binary/BlazeAndroidBinaryRunConfigurationHandler.java @@ -15,7 +15,6 @@ */ package com.google.idea.blaze.android.run.binary; -import static com.android.tools.idea.run.deployment.DeviceAndSnapshotComboBoxAction.DEPLOYS_TO_LOCAL_DEVICE; import static com.google.idea.blaze.android.run.LaunchMetrics.logBinaryLaunch; import com.android.tools.idea.run.ValidationError; @@ -29,7 +28,7 @@ import com.google.idea.blaze.android.run.BlazeAndroidRunConfigurationValidationUtil; import com.google.idea.blaze.android.run.LaunchMetrics; import com.google.idea.blaze.android.run.binary.AndroidBinaryLaunchMethodsUtils.AndroidBinaryLaunchMethod; -import com.google.idea.blaze.android.run.binary.mobileinstall.BlazeAndroidBinaryMobileInstallRunContextCompat; +import com.google.idea.blaze.android.run.binary.mobileinstall.BlazeAndroidBinaryMobileInstallRunContext; import com.google.idea.blaze.android.run.runner.ApkBuildStep; import com.google.idea.blaze.android.run.runner.BlazeAndroidRunConfigurationRunner; import com.google.idea.blaze.android.run.runner.BlazeAndroidRunContext; @@ -69,27 +68,22 @@ * android_binary targets. */ public class BlazeAndroidBinaryRunConfigurationHandler + extends BlazeAndroidBinaryRunConfigurationHandlerTestHelper implements BlazeAndroidRunConfigurationHandler { + + @VisibleForTesting + protected BlazeAndroidBinaryRunConfigurationHandler(BlazeCommandRunConfiguration configuration) { + super(configuration); + } + private static final Logger LOG = Logger.getInstance(BlazeAndroidBinaryRunConfigurationHandler.class); - private final Project project; - private final BlazeAndroidBinaryRunConfigurationState configState; - // Keys to store state for the MI migration prompt private static final String MI_LAST_PROMPT = "MI_MIGRATE_LAST_PROMPT"; static final String MI_NEVER_ASK_AGAIN = "MI_MIGRATE_NEVER_AGAIN"; private static final Long MI_TIMEOUT_MS = TimeUnit.HOURS.toMillis(20); // 20 hours - @VisibleForTesting - protected BlazeAndroidBinaryRunConfigurationHandler(BlazeCommandRunConfiguration configuration) { - project = configuration.getProject(); - configState = - new BlazeAndroidBinaryRunConfigurationState( - Blaze.buildSystemName(configuration.getProject())); - configuration.putUserData(DEPLOYS_TO_LOCAL_DEVICE, true); - } - @Override public BlazeAndroidBinaryRunConfigurationState getState() { return configState; @@ -153,7 +147,7 @@ public BlazeCommandRunConfigurationRunner createRunner( switch (configState.getLaunchMethod()) { case NON_BLAZE: runContext = - new BlazeAndroidBinaryNormalBuildRunContextCompat( + new BlazeAndroidBinaryNormalBuildRunContext( project, facet, configuration, env, configState, buildStep, launchId); break; case MOBILE_INSTALL_V2: @@ -162,7 +156,7 @@ public BlazeCommandRunConfigurationRunner createRunner( // fall through case MOBILE_INSTALL: runContext = - new BlazeAndroidBinaryMobileInstallRunContextCompat( + new BlazeAndroidBinaryMobileInstallRunContext( project, facet, configuration, env, configState, buildStep, launchId); break; default: diff --git a/aswb/src/com/google/idea/blaze/android/run/binary/BlazeAndroidBinaryRunConfigurationHandlerTestHelper.java b/aswb/src/com/google/idea/blaze/android/run/binary/BlazeAndroidBinaryRunConfigurationHandlerTestHelper.java new file mode 100644 index 00000000000..eab92c983a6 --- /dev/null +++ b/aswb/src/com/google/idea/blaze/android/run/binary/BlazeAndroidBinaryRunConfigurationHandlerTestHelper.java @@ -0,0 +1,38 @@ +/* + * Copyright 2022 The Bazel Authors. All rights reserved. + * + * 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. + */ +package com.google.idea.blaze.android.run.binary; + +import com.android.tools.idea.execution.common.DeployableToDevice; +import com.google.common.annotations.VisibleForTesting; +import com.google.idea.blaze.base.run.BlazeCommandRunConfiguration; +import com.google.idea.blaze.base.settings.Blaze; +import com.intellij.openapi.project.Project; + +/** Test Helper class for {@link BlazeAndroidBinaryRunConfigurationHandlerTestHelper}. */ +public class BlazeAndroidBinaryRunConfigurationHandlerTestHelper { + protected final Project project; + protected final BlazeAndroidBinaryRunConfigurationState configState; + + @VisibleForTesting + protected BlazeAndroidBinaryRunConfigurationHandlerTestHelper( + BlazeCommandRunConfiguration configuration) { + project = configuration.getProject(); + configState = + new BlazeAndroidBinaryRunConfigurationState( + Blaze.buildSystemName(configuration.getProject())); + configuration.putUserData(DeployableToDevice.getKEY(), true); + } +} diff --git a/aswb/src/com/google/idea/blaze/android/run/binary/BlazeAndroidBinaryRunConfigurationState.java b/aswb/src/com/google/idea/blaze/android/run/binary/BlazeAndroidBinaryRunConfigurationState.java index 1ee42aa44c5..94ca73bdca2 100644 --- a/aswb/src/com/google/idea/blaze/android/run/binary/BlazeAndroidBinaryRunConfigurationState.java +++ b/aswb/src/com/google/idea/blaze/android/run/binary/BlazeAndroidBinaryRunConfigurationState.java @@ -15,14 +15,22 @@ */ package com.google.idea.blaze.android.run.binary; +import static com.google.common.base.Verify.verify; + +import com.android.annotations.Nullable; +import com.android.tools.idea.execution.common.ComponentLaunchOptions; import com.android.tools.idea.run.ValidationError; +import com.android.tools.idea.run.configuration.ComplicationWatchFaceInfo; +import com.android.tools.idea.run.configuration.DefaultComplicationWatchFaceInfo; +import com.android.tools.idea.run.configuration.execution.ComplicationLaunchOptions; +import com.android.tools.idea.run.configuration.execution.TileLaunchOptions; +import com.android.tools.idea.run.configuration.execution.WatchFaceLaunchOptions; import com.android.tools.idea.run.editor.AndroidProfilersPanel; import com.android.tools.idea.run.editor.ProfilerState; -import com.android.tools.idea.run.util.LaunchUtils; import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Strings; +import com.google.common.base.VerifyException; import com.google.common.collect.ImmutableList; -import com.google.common.collect.Maps; import com.google.idea.blaze.android.run.BlazeAndroidRunConfigurationCommonState; import com.google.idea.blaze.android.run.binary.AndroidBinaryLaunchMethodsUtils.AndroidBinaryLaunchMethod; import com.google.idea.blaze.base.run.state.RunConfigurationState; @@ -30,6 +38,8 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.util.InvalidDataException; import com.intellij.openapi.util.WriteExternalException; +import com.intellij.util.xmlb.XmlSerializer; +import java.util.HashMap; import java.util.Map; import org.jdom.Element; @@ -38,10 +48,15 @@ public final class BlazeAndroidBinaryRunConfigurationState implements RunConfigu /** Element name used to group the {@link ProfilerState} settings */ private static final String PROFILERS_ELEMENT_NAME = "Profilers"; + public static final String LAUNCH_TILE = "launch_tile"; + public static final String LAUNCH_DEFAULT_ACTIVITY = "default_activity"; public static final String LAUNCH_SPECIFIC_ACTIVITY = "specific_activity"; public static final String DO_NOTHING = "do_nothing"; public static final String LAUNCH_DEEP_LINK = "launch_deep_link"; + public static final String LAUNCH_COMPLICATION = "launch_complication"; + public static final String LAUNCH_WATCHFACE = "launch_watchface"; + private static final String LAUNCH_OPTIONS_NAME = "LaunchOptions"; private static final String LAUNCH_METHOD_ATTR = "launch-method"; // Remove once v2 becomes default. @@ -62,19 +77,32 @@ public final class BlazeAndroidBinaryRunConfigurationState implements RunConfigu private static final String DEEP_LINK = "DEEP_LINK"; private static final String ACTIVITY_CLASS = "ACTIVITY_CLASS"; private static final String MODE = "MODE"; - private static final String ACTIVITY_EXTRA_FLAGS = "ACTIVITY_EXTRA_FLAGS"; private String deepLink = ""; private String activityClass = ""; private String mode = LAUNCH_DEFAULT_ACTIVITY; private static final String AM_START_OPTIONS = "AM_START_OPTIONS"; + private static final String CLEAR_APP_STORAGE = "CLEAR_APP_STORAGE"; private String amStartOptions = ""; + private boolean clearAppStorage = false; + + private String buildSystem; + + public final ComplicationWatchFaceInfo watchfaceInfo = DefaultComplicationWatchFaceInfo.INSTANCE; + private final BlazeAndroidRunConfigurationCommonState commonState; + // TODO: move activity launch here from top level properties. + private final Map wearLaunchOptions = new HashMap<>(); BlazeAndroidBinaryRunConfigurationState(String buildSystemName) { commonState = new BlazeAndroidRunConfigurationCommonState(buildSystemName); profilerState = new ProfilerState(); + buildSystem = buildSystemName; + + wearLaunchOptions.put(LAUNCH_TILE, new TileLaunchOptions()); + wearLaunchOptions.put(LAUNCH_COMPLICATION, new ComplicationLaunchOptions()); + wearLaunchOptions.put(LAUNCH_WATCHFACE, new WatchFaceLaunchOptions()); } public BlazeAndroidRunConfigurationCommonState getCommonState() { @@ -85,6 +113,21 @@ public AndroidBinaryLaunchMethod getLaunchMethod() { return launchMethod; } + /** Returns ComponentLaunchOptions if wear surface as chosen for launch otherwise returns null. */ + @Nullable + public ComponentLaunchOptions getCurrentWearLaunchOptions() { + return wearLaunchOptions.get(mode); + } + + /** Set Wear launch options corresponding to the current mode. */ + public void setWearLaunchOptions(ComponentLaunchOptions options) { + verify( + mode.equals(LAUNCH_COMPLICATION) + || mode.equals(LAUNCH_TILE) + || mode.equals(LAUNCH_WATCHFACE)); + wearLaunchOptions.put(mode, options); + } + @VisibleForTesting public void setLaunchMethod(AndroidBinaryLaunchMethod launchMethod) { this.launchMethod = launchMethod; @@ -162,6 +205,14 @@ public String getAmStartOptions() { return amStartOptions; } + public boolean getClearAppStorage() { + return clearAppStorage; + } + + public void setClearAppStorage(boolean clearAppStorage) { + this.clearAppStorage = clearAppStorage; + } + /** * We collect errors rather than throwing to avoid missing fatal errors by exiting early for a * warning. @@ -215,25 +266,18 @@ public void readExternal(Element element) throws InvalidDataException { setAmStartOptions(amStartOptionsString); } - for (Map.Entry entry : getLegacyValues(element).entrySet()) { - String value = entry.getValue(); - switch (entry.getKey()) { - case DEEP_LINK: - deepLink = Strings.nullToEmpty(value); - break; - case ACTIVITY_CLASS: - activityClass = Strings.nullToEmpty(value); - break; - case MODE: - mode = Strings.isNullOrEmpty(value) ? LAUNCH_DEFAULT_ACTIVITY : value; - break; - case ACTIVITY_EXTRA_FLAGS: - if (userId == null) { - userId = LaunchUtils.getUserIdFromFlags(value); - } - break; - default: - break; + setClearAppStorage(Boolean.parseBoolean(element.getAttributeValue(CLEAR_APP_STORAGE))); + + // Read wear launch options + Element launchOptionsElement = element.getChild(LAUNCH_OPTIONS_NAME); + if (launchOptionsElement != null) { + for (Map.Entry option : wearLaunchOptions.entrySet()) { + Element optionElement = launchOptionsElement.getChild(option.getKey()); + if (optionElement != null) { + XmlSerializer.deserializeInto(option.getValue(), optionElement); + } else { + throw new VerifyException("Missing launch option declaration " + option.getKey()); + } } } } @@ -244,7 +288,7 @@ public void writeExternal(Element element) throws WriteExternalException { // Group profiler settings under its own section. Previously written profiler info // are replaced manually because ProfilerState#writeExternal does not handle the removal - // process; unlike i.e, implementers of RunConfigurationState. + // process; unlike i.e., implementers of RunConfigurationState. Element profilersElement = new Element(PROFILERS_ELEMENT_NAME); element.removeChildren(PROFILERS_ELEMENT_NAME); element.addContent(profilersElement); @@ -258,23 +302,24 @@ public void writeExternal(Element element) throws WriteExternalException { element.setAttribute(WORK_PROFILE_ATTR, Boolean.toString(useWorkProfileIfPresent)); element.setAttribute(SHOW_LOGCAT_AUTOMATICALLY, Boolean.toString(showLogcatAutomatically)); element.setAttribute(AM_START_OPTIONS, amStartOptions); + element.setAttribute(CLEAR_APP_STORAGE, Boolean.toString(clearAppStorage)); if (userId != null) { element.setAttribute(USER_ID_ATTR, Integer.toString(userId)); } else { element.removeAttribute(USER_ID_ATTR); } - } - /** Imports legacy values in the old reflective JDOM externalizer manner. Can be removed ~2.0+. */ - private static Map getLegacyValues(Element element) { - Map result = Maps.newHashMap(); - for (Element option : element.getChildren("option")) { - String name = option.getAttributeValue("name"); - String value = option.getAttributeValue("value"); - result.put(name, value); + // Add wear launch options + Element launchOptionsElement = new Element(LAUNCH_OPTIONS_NAME); + element.removeChildren(LAUNCH_OPTIONS_NAME); + element.addContent(launchOptionsElement); + + for (Map.Entry option : wearLaunchOptions.entrySet()) { + Element optionElement = new Element(option.getKey()); + launchOptionsElement.addContent(optionElement); + XmlSerializer.serializeInto(option.getValue(), optionElement); } - return result; } @Override @@ -282,4 +327,32 @@ public RunConfigurationStateEditor getEditor(Project project) { return new BlazeAndroidBinaryRunConfigurationStateEditor( commonState.getEditor(project), new AndroidProfilersPanel(project, profilerState), project); } + + // Create a deep copy of BlazeAndroidBinaryRunConfigurationState. + @Override + public BlazeAndroidBinaryRunConfigurationState clone() { + BlazeAndroidBinaryRunConfigurationState clone = + new BlazeAndroidBinaryRunConfigurationState(buildSystem); + + clone.launchMethod = launchMethod; + clone.profilerState = profilerState; + clone.deepLink = deepLink; + clone.activityClass = activityClass; + clone.mode = mode; + clone.useSplitApksIfPossible = useSplitApksIfPossible; + clone.useWorkProfileIfPresent = useWorkProfileIfPresent; + clone.userId = userId; + clone.showLogcatAutomatically = showLogcatAutomatically; + clone.amStartOptions = amStartOptions; + clone.clearAppStorage = clearAppStorage; + clone.wearLaunchOptions.put( + LAUNCH_TILE, ((TileLaunchOptions) wearLaunchOptions.get(LAUNCH_TILE)).clone()); + clone.wearLaunchOptions.put( + LAUNCH_COMPLICATION, + ((ComplicationLaunchOptions) wearLaunchOptions.get(LAUNCH_COMPLICATION)).clone()); + clone.wearLaunchOptions.put( + LAUNCH_WATCHFACE, + ((WatchFaceLaunchOptions) wearLaunchOptions.get(LAUNCH_WATCHFACE)).clone()); + return clone; + } } diff --git a/aswb/src/com/google/idea/blaze/android/run/binary/DeploymentTimingReporterTask.java b/aswb/src/com/google/idea/blaze/android/run/binary/DeploymentTimingReporterTask.java new file mode 100644 index 00000000000..a9986ad85f0 --- /dev/null +++ b/aswb/src/com/google/idea/blaze/android/run/binary/DeploymentTimingReporterTask.java @@ -0,0 +1,60 @@ +/* + * Copyright 2021 The Bazel Authors. All rights reserved. + * + * 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. + */ +package com.google.idea.blaze.android.run.binary; + +import com.android.tools.idea.execution.common.DeployOptions; +import com.android.tools.idea.run.ApkInfo; +import com.android.tools.idea.run.blaze.BlazeLaunchContext; +import com.android.tools.idea.run.blaze.BlazeLaunchTask; +import com.android.tools.idea.run.tasks.DeployTasksHelper; +import com.google.common.annotations.VisibleForTesting; +import com.google.common.base.Stopwatch; +import com.google.common.collect.ImmutableList; +import com.google.idea.blaze.android.run.LaunchMetrics; +import com.intellij.execution.ExecutionException; +import com.intellij.openapi.project.Project; +import java.util.Collection; + +/** A wrapper launch task that wraps the given deployment task and logs the deployment latency. */ +public class DeploymentTimingReporterTask implements BlazeLaunchTask { + private final BlazeLaunchTask deployTask; + private final String launchId; + private final ImmutableList packages; + + public DeploymentTimingReporterTask( + String launchId, Project project, Collection packages, DeployOptions deployOptions) { + this.launchId = launchId; + this.deployTask = DeployTasksHelper.createDeployTask(project, packages, deployOptions); + this.packages = ImmutableList.copyOf(packages); + } + + @VisibleForTesting + public ImmutableList getPackages() { + return packages; + } + + @Override + public void run(BlazeLaunchContext launchContext) throws ExecutionException { + Stopwatch s = Stopwatch.createStarted(); + try { + deployTask.run(launchContext); + LaunchMetrics.logDeploymentTime(launchId, s.elapsed(), true); + } catch (ExecutionException e) { + LaunchMetrics.logDeploymentTime(launchId, s.elapsed(), false); + throw e; + } + } +} diff --git a/aswb/sdkcompat/as223/com/google/idea/blaze/android/run/binary/UserIdHelper.java b/aswb/src/com/google/idea/blaze/android/run/binary/UserIdHelper.java similarity index 100% rename from aswb/sdkcompat/as223/com/google/idea/blaze/android/run/binary/UserIdHelper.java rename to aswb/src/com/google/idea/blaze/android/run/binary/UserIdHelper.java diff --git a/aswb/src/com/google/idea/blaze/android/run/binary/mobileinstall/BlazeAndroidBinaryMobileInstallRunContext.java b/aswb/src/com/google/idea/blaze/android/run/binary/mobileinstall/BlazeAndroidBinaryMobileInstallRunContext.java new file mode 100644 index 00000000000..771363e7250 --- /dev/null +++ b/aswb/src/com/google/idea/blaze/android/run/binary/mobileinstall/BlazeAndroidBinaryMobileInstallRunContext.java @@ -0,0 +1,136 @@ +/* + * Copyright 2016 The Bazel Authors. All rights reserved. + * + * 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. + */ +package com.google.idea.blaze.android.run.binary.mobileinstall; + +import com.android.ddmlib.ClientData; +import com.android.ddmlib.IDevice; +import com.android.tools.idea.execution.common.debug.AndroidDebugger; +import com.android.tools.idea.execution.common.debug.AndroidDebuggerState; +import com.android.tools.idea.execution.common.debug.DebugSessionStarter; +import com.android.tools.idea.projectsystem.ApplicationProjectContext; +import com.android.tools.idea.run.ApkProvisionException; +import com.android.tools.idea.run.activity.DefaultStartActivityFlagsProvider; +import com.android.tools.idea.run.activity.StartActivityFlagsProvider; +import com.android.tools.idea.run.blaze.BlazeLaunchTask; +import com.google.idea.blaze.android.run.BazelApplicationProjectContext; +import com.google.idea.blaze.android.run.binary.BlazeAndroidBinaryApplicationLaunchTaskProvider; +import com.google.idea.blaze.android.run.binary.BlazeAndroidBinaryRunConfigurationState; +import com.google.idea.blaze.android.run.binary.UserIdHelper; +import com.google.idea.blaze.android.run.deployinfo.BlazeAndroidDeployInfo; +import com.google.idea.blaze.android.run.runner.ApkBuildStep; +import com.intellij.execution.ExecutionException; +import com.intellij.execution.Executor; +import com.intellij.execution.configurations.RunConfiguration; +import com.intellij.execution.runners.ExecutionEnvironment; +import com.intellij.execution.ui.ConsoleView; +import com.intellij.openapi.progress.ProcessCanceledException; +import com.intellij.openapi.progress.ProgressIndicator; +import com.intellij.openapi.project.Project; +import com.intellij.xdebugger.XDebugSession; +import javax.annotation.Nullable; +import kotlin.Unit; +import kotlin.coroutines.EmptyCoroutineContext; +import kotlinx.coroutines.BuildersKt; +import org.jetbrains.android.facet.AndroidFacet; + +/** Run Context for mobile install launches, #api4.0 compat. */ +public class BlazeAndroidBinaryMobileInstallRunContext + extends BlazeAndroidBinaryMobileInstallRunContextBase { + public BlazeAndroidBinaryMobileInstallRunContext( + Project project, + AndroidFacet facet, + RunConfiguration runConfiguration, + ExecutionEnvironment env, + BlazeAndroidBinaryRunConfigurationState configState, + ApkBuildStep buildStep, + String launchId) { + super(project, facet, runConfiguration, env, configState, buildStep, launchId); + } + + @Override + public ApplicationProjectContext getApplicationProjectContext() { + return new BazelApplicationProjectContext(project, getApplicationIdProvider()); + } + + @SuppressWarnings("unchecked") // upstream API + @Override + public BlazeLaunchTask getApplicationLaunchTask( + boolean isDebug, @Nullable Integer userId, String contributorsAmStartOptions) + throws ExecutionException { + + String extraFlags = UserIdHelper.getFlagsFromUserId(userId); + if (!contributorsAmStartOptions.isEmpty()) { + extraFlags += (extraFlags.isEmpty() ? "" : " ") + contributorsAmStartOptions; + } + if (isDebug) { + extraFlags += (extraFlags.isEmpty() ? "" : " ") + "-D"; + } + + final StartActivityFlagsProvider startActivityFlagsProvider = + new DefaultStartActivityFlagsProvider(project, isDebug, extraFlags); + BlazeAndroidDeployInfo deployInfo; + try { + deployInfo = buildStep.getDeployInfo(); + } catch (ApkProvisionException e) { + throw new ExecutionException(e); + } + + return BlazeAndroidBinaryApplicationLaunchTaskProvider.getApplicationLaunchTask( + applicationIdProvider, + deployInfo.getMergedManifest(), + configState, + startActivityFlagsProvider); + } + + @Nullable + @Override + public XDebugSession startDebuggerSession( + AndroidDebugger androidDebugger, + AndroidDebuggerState androidDebuggerState, + ExecutionEnvironment env, + IDevice device, + ConsoleView consoleView, + ProgressIndicator indicator, + String packageName) { + try { + return BuildersKt.runBlocking( + EmptyCoroutineContext.INSTANCE, + (scope, continuation) -> + DebugSessionStarter.INSTANCE.attachDebuggerToStartedProcess( + device, + new BazelApplicationProjectContext(project, packageName), + env, + androidDebugger, + androidDebuggerState, + /*destroyRunningProcess*/ d -> { + d.forceStop(packageName); + return Unit.INSTANCE; + }, + indicator, + consoleView, + 15L, + ClientData.DebuggerStatus.WAITING, + continuation)); + } catch (InterruptedException e) { + throw new ProcessCanceledException(e); + } + } + + @Override + public Executor getExecutor() { + return env.getExecutor(); + } +} diff --git a/aswb/src/com/google/idea/blaze/android/run/binary/mobileinstall/BlazeAndroidBinaryMobileInstallRunContextBase.java b/aswb/src/com/google/idea/blaze/android/run/binary/mobileinstall/BlazeAndroidBinaryMobileInstallRunContextBase.java new file mode 100644 index 00000000000..967e5926fb0 --- /dev/null +++ b/aswb/src/com/google/idea/blaze/android/run/binary/mobileinstall/BlazeAndroidBinaryMobileInstallRunContextBase.java @@ -0,0 +1,164 @@ +/* + * Copyright 2016 The Bazel Authors. All rights reserved. + * + * 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. + */ +package com.google.idea.blaze.android.run.binary.mobileinstall; + +import com.android.ddmlib.IDevice; +import com.android.tools.idea.execution.common.DeployOptions; +import com.android.tools.idea.run.ApkFileUnit; +import com.android.tools.idea.run.ApkInfo; +import com.android.tools.idea.run.ApkProvisionException; +import com.android.tools.idea.run.ApplicationIdProvider; +import com.android.tools.idea.run.ConsoleProvider; +import com.android.tools.idea.run.LaunchOptions; +import com.android.tools.idea.run.blaze.BlazeLaunchTask; +import com.android.tools.idea.run.blaze.BlazeLaunchTasksProvider; +import com.android.tools.idea.run.editor.ProfilerState; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import com.google.idea.blaze.android.run.binary.BlazeAndroidBinaryApplicationIdProvider; +import com.google.idea.blaze.android.run.binary.BlazeAndroidBinaryConsoleProvider; +import com.google.idea.blaze.android.run.binary.BlazeAndroidBinaryRunConfigurationState; +import com.google.idea.blaze.android.run.binary.DeploymentTimingReporterTask; +import com.google.idea.blaze.android.run.binary.UserIdHelper; +import com.google.idea.blaze.android.run.deployinfo.BlazeAndroidDeployInfo; +import com.google.idea.blaze.android.run.runner.ApkBuildStep; +import com.google.idea.blaze.android.run.runner.BlazeAndroidDeviceSelector; +import com.google.idea.blaze.android.run.runner.BlazeAndroidLaunchTasksProvider; +import com.google.idea.blaze.android.run.runner.BlazeAndroidRunContext; +import com.google.idea.blaze.base.sync.data.BlazeDataStorage; +import com.intellij.execution.ExecutionException; +import com.intellij.execution.configurations.RunConfiguration; +import com.intellij.execution.runners.ExecutionEnvironment; +import com.intellij.openapi.project.Project; +import java.util.Collections; +import java.util.stream.Collectors; +import javax.annotation.Nullable; +import org.jetbrains.android.facet.AndroidFacet; + +/** Run context for android_binary. */ +abstract class BlazeAndroidBinaryMobileInstallRunContextBase implements BlazeAndroidRunContext { + protected final Project project; + protected final AndroidFacet facet; + protected final RunConfiguration runConfiguration; + protected final ExecutionEnvironment env; + protected final BlazeAndroidBinaryRunConfigurationState configState; + protected final ConsoleProvider consoleProvider; + protected final ApplicationIdProvider applicationIdProvider; + protected final ApkBuildStep buildStep; + private final String launchId; + + public BlazeAndroidBinaryMobileInstallRunContextBase( + Project project, + AndroidFacet facet, + RunConfiguration runConfiguration, + ExecutionEnvironment env, + BlazeAndroidBinaryRunConfigurationState configState, + ApkBuildStep buildStep, + String launchId) { + this.project = project; + this.facet = facet; + this.runConfiguration = runConfiguration; + this.env = env; + this.configState = configState; + this.consoleProvider = new BlazeAndroidBinaryConsoleProvider(project); + this.buildStep = buildStep; + this.applicationIdProvider = new BlazeAndroidBinaryApplicationIdProvider(buildStep); + this.launchId = launchId; + } + + @Override + public BlazeAndroidDeviceSelector getDeviceSelector() { + return new BlazeAndroidDeviceSelector.NormalDeviceSelector(); + } + + @Override + public void augmentLaunchOptions(LaunchOptions.Builder options) { + options + .setDeploy(buildStep.needsIdeDeploy()) + .setOpenLogcatAutomatically(configState.showLogcatAutomatically()); + // This is needed for compatibility with #api211 + options.addExtraOptions( + ImmutableMap.of("android.profilers.state", configState.getProfilerState())); + } + + @Override + public ConsoleProvider getConsoleProvider() { + return consoleProvider; + } + + @Override + public ApplicationIdProvider getApplicationIdProvider() { + return applicationIdProvider; + } + + @Override + public ApkBuildStep getBuildStep() { + return buildStep; + } + + @Override + public ProfilerState getProfileState() { + return configState.getProfilerState(); + } + + @Override + public ImmutableList getDeployTasks(IDevice device, DeployOptions deployOptions) + throws ExecutionException { + if (!buildStep.needsIdeDeploy()) { + return ImmutableList.of(); + } + + BlazeAndroidDeployInfo deployInfo; + try { + deployInfo = buildStep.getDeployInfo(); + } catch (ApkProvisionException e) { + throw new ExecutionException(e); + } + + String packageName = deployInfo.getMergedManifest().packageName; + if (packageName == null) { + throw new ExecutionException("Could not determine package name from deploy info"); + } + + ApkInfo info = + new ApkInfo( + deployInfo.getApksToDeploy().stream() + .map(file -> new ApkFileUnit(BlazeDataStorage.WORKSPACE_MODULE_NAME, file)) + .collect(Collectors.toList()), + packageName); + + return ImmutableList.of( + new DeploymentTimingReporterTask( + launchId, project, Collections.singletonList(info), deployOptions)); + } + + @Nullable + @Override + public Integer getUserId(IDevice device) throws ExecutionException { + return UserIdHelper.getUserIdFromConfigurationState(project, device, configState); + } + + @Override + public BlazeLaunchTasksProvider getLaunchTasksProvider(LaunchOptions launchOptions) + throws ExecutionException { + return new BlazeAndroidLaunchTasksProvider(project, this, applicationIdProvider, launchOptions); + } + + @Override + public String getAmStartOptions() { + return configState.getAmStartOptions(); + } +} diff --git a/aswb/src/com/google/idea/blaze/android/run/binary/mobileinstall/MobileInstallBuildStep.java b/aswb/src/com/google/idea/blaze/android/run/binary/mobileinstall/MobileInstallBuildStep.java index c83d10b2b9f..33c61d697f2 100644 --- a/aswb/src/com/google/idea/blaze/android/run/binary/mobileinstall/MobileInstallBuildStep.java +++ b/aswb/src/com/google/idea/blaze/android/run/binary/mobileinstall/MobileInstallBuildStep.java @@ -65,6 +65,7 @@ import com.intellij.openapi.project.Project; import java.io.File; import java.net.InetSocketAddress; +import java.util.List; import java.util.NoSuchElementException; import java.util.concurrent.CancellationException; import javax.annotation.Nullable; @@ -152,7 +153,9 @@ public void build(BlazeContext context, BlazeAndroidDeviceSelector.DeviceSession } BuildInvoker invoker = - Blaze.getBuildSystemProvider(project).getBuildSystem().getBuildInvoker(project, context); + Blaze.getBuildSystemProvider(project) + .getBuildSystem() + .getBuildInvoker(project, context, BlazeCommandName.MOBILE_INSTALL); BlazeCommand.Builder command = BlazeCommand.builder(invoker, BlazeCommandName.MOBILE_INSTALL); if (passAdbArgWithSerialToMi.getValue()) { @@ -277,17 +280,18 @@ public BlazeAndroidDeployInfo getDeployInfo() throws ApkProvisionException { } private static AdbTunnelConfigurator getTunnelConfigurator(BlazeContext context) { - try { - AdbTunnelConfigurator configurator = - Iterables.getOnlyElement(AdbTunnelConfiguratorProvider.EP_NAME.getExtensionList()) - .createConfigurator(context); + List extensions = + AdbTunnelConfiguratorProvider.EP_NAME.getExtensionList(); + if (extensions.size() > 1) { + // This is fine in tests. + log.warn("More than one provider registered; Using the first one!\n" + extensions); + } + // Fail quietly when there's no configurable registered. + if (!extensions.isEmpty()) { + AdbTunnelConfigurator configurator = extensions.get(0).createConfigurator(context); if (configurator != null) { return configurator; } - } catch (NoSuchElementException ex) { - // Fail quietly when there's no configurable registered. - } catch (IllegalArgumentException ex) { - log.warn("More than one provider registered; there should only be one!"); } return new AdbTunnelConfigurator() { @Override diff --git a/aswb/src/com/google/idea/blaze/android/run/binary/tasks/ActivityLaunchTask.java b/aswb/src/com/google/idea/blaze/android/run/binary/tasks/ActivityLaunchTask.java new file mode 100644 index 00000000000..1e7cdad4947 --- /dev/null +++ b/aswb/src/com/google/idea/blaze/android/run/binary/tasks/ActivityLaunchTask.java @@ -0,0 +1,102 @@ +/* + * 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. + */ +package com.google.idea.blaze.android.run.binary.tasks; + +import com.android.ddmlib.CollectingOutputReceiver; +import com.android.ddmlib.IDevice; +import com.android.tools.idea.execution.common.AndroidExecutionException; +import com.android.tools.idea.run.activity.AndroidActivityLauncher; +import com.android.tools.idea.run.activity.StartActivityFlagsProvider; +import com.android.tools.idea.run.configuration.execution.ExecutionUtils; +import com.google.common.annotations.VisibleForTesting; +import com.intellij.execution.ExecutionException; +import com.intellij.execution.ui.ConsoleView; +import com.intellij.openapi.progress.ProgressIndicator; +import java.util.concurrent.TimeUnit; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +/** Provides the launch task for activity */ +public abstract class ActivityLaunchTask { + @VisibleForTesting static final String ACTIVITY_DOES_NOT_EXIST = "ACTIVITY_DOES_NOT_EXIST"; + + @VisibleForTesting + static final String UNABLE_TO_DETERMINE_LAUNCH_ACTIVITY = "UNABLE_TO_DETERMINE_LAUNCH_ACTIVITY"; + + private static final String ACTIVITY_DOES_NOT_EXIST_REGEX = + "Activity class \\{[^}]*} does not exist"; + private static final Pattern activityDoesNotExistPattern = + Pattern.compile(ACTIVITY_DOES_NOT_EXIST_REGEX); + @NotNull private final String myApplicationId; + @NotNull private final StartActivityFlagsProvider myStartActivityFlagsProvider; + + public ActivityLaunchTask( + @NotNull String applicationId, + @NotNull StartActivityFlagsProvider startActivityFlagsProvider) { + myApplicationId = applicationId; + myStartActivityFlagsProvider = startActivityFlagsProvider; + } + + @VisibleForTesting + public String getStartActivityCommand(@NotNull IDevice device) throws ExecutionException { + String activityName = getQualifiedActivityName(device); + if (activityName == null) { + throw new AndroidExecutionException( + UNABLE_TO_DETERMINE_LAUNCH_ACTIVITY, "Unable to determine activity name"); + } + String activityPath = + AndroidActivityLauncher.getLauncherActivityPath(myApplicationId, activityName); + return AndroidActivityLauncher.getStartActivityCommand( + activityPath, myStartActivityFlagsProvider.getFlags(device)); + } + + @Nullable + protected abstract String getQualifiedActivityName(@NotNull IDevice device); + + public void run(IDevice device, ProgressIndicator progressIndicator, ConsoleView consoleView) + throws ExecutionException { + String command = getStartActivityCommand(device); + CollectingOutputReceiver collectingOutputReceiver = new CollectingOutputReceiver(); + + executeShellCommand(consoleView, device, command, collectingOutputReceiver, progressIndicator); + final Matcher matcher = + activityDoesNotExistPattern.matcher(collectingOutputReceiver.getOutput()); + if (matcher.find()) { + throw new AndroidExecutionException(ACTIVITY_DOES_NOT_EXIST, matcher.group()); + } + } + + @VisibleForTesting + protected void executeShellCommand( + ConsoleView console, + IDevice device, + String command, + CollectingOutputReceiver collectingOutputReceiver, + ProgressIndicator progressIndicator) + throws ExecutionException { + // The timeout is quite large to accommodate ARM emulators. + ExecutionUtils.executeShellCommand( + device, + command, + console, + collectingOutputReceiver, + 15, + TimeUnit.SECONDS, + progressIndicator); + } +} diff --git a/aswb/src/com/google/idea/blaze/android/run/binary/tasks/AndroidDeepLinkLaunchTask.java b/aswb/src/com/google/idea/blaze/android/run/binary/tasks/AndroidDeepLinkLaunchTask.java new file mode 100644 index 00000000000..da6f81e83de --- /dev/null +++ b/aswb/src/com/google/idea/blaze/android/run/binary/tasks/AndroidDeepLinkLaunchTask.java @@ -0,0 +1,81 @@ +/* + * 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. + */ +package com.google.idea.blaze.android.run.binary.tasks; + +import com.android.ddmlib.IDevice; +import com.android.tools.analytics.UsageTracker; +import com.android.tools.idea.run.activity.StartActivityFlagsProvider; +import com.android.tools.idea.run.configuration.execution.ExecutionUtils; +import com.google.wireless.android.sdk.stats.AndroidStudioEvent; +import com.google.wireless.android.sdk.stats.AndroidStudioEvent.EventCategory; +import com.google.wireless.android.sdk.stats.AndroidStudioEvent.EventKind; +import com.intellij.execution.ExecutionException; +import com.intellij.execution.ui.ConsoleView; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.progress.ProgressIndicator; +import org.jetbrains.annotations.NotNull; + +/** Provides the launch task for android_binary */ +public class AndroidDeepLinkLaunchTask { + + private static final String ID = "LAUNCH_DEEP_LINK"; + + @NotNull private final String myDeepLink; + @NotNull StartActivityFlagsProvider myStartActivityFlagsProvider; + + public AndroidDeepLinkLaunchTask( + @NotNull String deepLink, @NotNull StartActivityFlagsProvider startActivityFlagsProvider) { + myDeepLink = deepLink; + myStartActivityFlagsProvider = startActivityFlagsProvider; + } + + public void run(IDevice device, ProgressIndicator progressIndicator, ConsoleView consoleView) + throws ExecutionException { + + final String text = "Launching deeplink: " + myDeepLink + ".\n"; + ExecutionUtils.println(consoleView, "Launching deeplink: " + myDeepLink + ".\n"); + Logger.getInstance(this.getClass()).info(text); + + UsageTracker.log( + AndroidStudioEvent.newBuilder() + .setCategory(EventCategory.APP_INDEXING) + .setKind(EventKind.APP_INDEXING_DEEP_LINK_LAUNCHED)); + // Enable AppIndexing API log + ExecutionUtils.executeShellCommand( + device, "setprop log.tag.AppIndexApi VERBOSE", consoleView, progressIndicator); + + // Launch deeplink + String command = + getLaunchDeepLinkCommand(myDeepLink, myStartActivityFlagsProvider.getFlags(device)); + ExecutionUtils.executeShellCommand(device, command, consoleView, progressIndicator); + } + + @NotNull + public static String getLaunchDeepLinkCommand( + @NotNull String deepLink, @NotNull String extraFlags) { + return "am start" + + " -a android.intent.action.VIEW" + + " -c android.intent.category.BROWSABLE" + + " -d " + + singleQuoteShell(deepLink) + + (extraFlags.isEmpty() ? "" : " " + extraFlags); + } + + @NotNull + private static String singleQuoteShell(@NotNull String literal) { + return "'" + literal.replace("'", "'\\''") + "'"; + } +} diff --git a/aswb/src/com/google/idea/blaze/android/run/binary/tasks/BlazeDefaultActivityLaunchTask.java b/aswb/src/com/google/idea/blaze/android/run/binary/tasks/BlazeDefaultActivityLaunchTask.java new file mode 100644 index 00000000000..3b6bc7d811f --- /dev/null +++ b/aswb/src/com/google/idea/blaze/android/run/binary/tasks/BlazeDefaultActivityLaunchTask.java @@ -0,0 +1,47 @@ +/* + * Copyright 2023 The Bazel Authors. All rights reserved. + * + * 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. + */ +package com.google.idea.blaze.android.run.binary.tasks; + +import com.android.tools.idea.run.activity.ActivityLocator; +import com.android.tools.idea.run.activity.StartActivityFlagsProvider; +import com.android.tools.idea.run.blaze.BlazeLaunchContext; +import com.android.tools.idea.run.blaze.BlazeLaunchTask; +import com.intellij.execution.ExecutionException; + +/** The {@code BlazeLaunchTask} that run a {@code DefaultActivityLaunchTask}. */ +public class BlazeDefaultActivityLaunchTask implements BlazeLaunchTask { + private final DefaultActivityLaunchTask defaultActivityLaunchTask; + + public BlazeDefaultActivityLaunchTask( + String applicationId, + ActivityLocator activityLocator, + StartActivityFlagsProvider startActivityFlagsProvider) { + defaultActivityLaunchTask = + new DefaultActivityLaunchTask(applicationId, activityLocator, startActivityFlagsProvider); + } + + public DefaultActivityLaunchTask getDefaultActivityLaunchTask() { + return defaultActivityLaunchTask; + } + + @Override + public void run(BlazeLaunchContext blazeLaunchContext) throws ExecutionException { + defaultActivityLaunchTask.run( + blazeLaunchContext.getDevice(), + blazeLaunchContext.getProgressIndicator(), + blazeLaunchContext.getConsoleView()); + } +} diff --git a/aswb/src/com/google/idea/blaze/android/run/binary/tasks/DefaultActivityLaunchTask.java b/aswb/src/com/google/idea/blaze/android/run/binary/tasks/DefaultActivityLaunchTask.java new file mode 100644 index 00000000000..306327473d1 --- /dev/null +++ b/aswb/src/com/google/idea/blaze/android/run/binary/tasks/DefaultActivityLaunchTask.java @@ -0,0 +1,47 @@ +/* + * 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. + */ +package com.google.idea.blaze.android.run.binary.tasks; + +import com.android.ddmlib.IDevice; +import com.android.tools.idea.run.activity.ActivityLocator; +import com.android.tools.idea.run.activity.StartActivityFlagsProvider; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +/** Provides the launch task for activity */ +public class DefaultActivityLaunchTask extends ActivityLaunchTask { + private static final String ID = "DEFAULT_ACTIVITY"; + + @NotNull private final ActivityLocator myActivityLocator; + + public DefaultActivityLaunchTask( + @NotNull String applicationId, + @NotNull ActivityLocator activityLocator, + @NotNull StartActivityFlagsProvider startActivityFlagsProvider) { + super(applicationId, startActivityFlagsProvider); + myActivityLocator = activityLocator; + } + + @Nullable + @Override + protected String getQualifiedActivityName(@NotNull IDevice device) { + try { + return myActivityLocator.getQualifiedActivityName(device); + } catch (ActivityLocator.ActivityLocatorException e) { + return null; + } + } +} diff --git a/aswb/src/com/google/idea/blaze/android/run/binary/tasks/SpecificActivityLaunchTask.java b/aswb/src/com/google/idea/blaze/android/run/binary/tasks/SpecificActivityLaunchTask.java new file mode 100644 index 00000000000..264ec5ea44d --- /dev/null +++ b/aswb/src/com/google/idea/blaze/android/run/binary/tasks/SpecificActivityLaunchTask.java @@ -0,0 +1,40 @@ +/* + * 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. + */ +package com.google.idea.blaze.android.run.binary.tasks; + +import com.android.ddmlib.IDevice; +import com.android.tools.idea.run.activity.StartActivityFlagsProvider; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +/** Provides the launch task for activity */ +public class SpecificActivityLaunchTask extends ActivityLaunchTask { + @NotNull private final String myActivity; + + public SpecificActivityLaunchTask( + @NotNull String applicationId, + @NotNull String activity, + @NotNull StartActivityFlagsProvider startActivityFlagsProvider) { + super(applicationId, startActivityFlagsProvider); + myActivity = activity; + } + + @Nullable + @Override + protected String getQualifiedActivityName(@NotNull IDevice device) { + return myActivity; + } +} diff --git a/aswb/src/com/google/idea/blaze/android/run/deployinfo/BlazeApkDeployInfoProtoHelper.java b/aswb/src/com/google/idea/blaze/android/run/deployinfo/BlazeApkDeployInfoProtoHelper.java index 220dac43c39..aa369a0861b 100644 --- a/aswb/src/com/google/idea/blaze/android/run/deployinfo/BlazeApkDeployInfoProtoHelper.java +++ b/aswb/src/com/google/idea/blaze/android/run/deployinfo/BlazeApkDeployInfoProtoHelper.java @@ -21,12 +21,12 @@ import com.google.devtools.build.lib.rules.android.deployinfo.AndroidDeployInfoOuterClass.Artifact; import com.google.idea.blaze.android.manifest.ManifestParser.ParsedManifest; import com.google.idea.blaze.android.manifest.ParsedManifestService; -import com.google.idea.blaze.base.command.buildresult.BlazeArtifact; import com.google.idea.blaze.base.command.buildresult.BuildResultHelper; import com.google.idea.blaze.base.command.buildresult.BuildResultHelper.GetArtifactsException; -import com.google.idea.blaze.base.command.buildresult.OutputArtifact; +import com.google.idea.blaze.base.command.buildresult.LocalFileArtifact; import com.google.idea.blaze.base.command.buildresult.ParsedBepOutput; import com.google.idea.blaze.base.model.primitives.Label; +import com.google.idea.blaze.common.artifact.OutputArtifact; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.Project; import java.io.File; @@ -59,12 +59,12 @@ public AndroidDeployInfo readDeployInfoProtoForTarget( log.warn("Local execroot: " + bepOutput.getLocalExecRoot()); log.warn("All output artifacts:"); for (OutputArtifact outputArtifact : bepOutput.getAllOutputArtifacts(path -> true)) { - log.warn(outputArtifact.getKey() + " -> " + outputArtifact.getRelativePath()); + log.warn(outputArtifact.getBazelOutRelativePath() + " -> " + outputArtifact.getBazelOutRelativePath()); } log.warn("All local artifacts for " + target + ":"); List allBuildArtifacts = buildResultHelper.getBuildArtifactsForTarget(target, path -> true); - List allLocalFiles = BlazeArtifact.getLocalFiles(allBuildArtifacts); + List allLocalFiles = LocalFileArtifact.getLocalFiles(allBuildArtifacts); for (File file : allLocalFiles) { String path = file.getPath(); log.warn(path); @@ -83,7 +83,7 @@ public AndroidDeployInfo readDeployInfoProtoForTarget( throw new GetDeployInfoException( "More than one deploy info proto artifact found: " + outputArtifacts.stream() - .map(OutputArtifact::getRelativePath) + .map(OutputArtifact::getBazelOutRelativePath) .collect(Collectors.joining(", ", "[", "]"))); } diff --git a/aswb/src/com/google/idea/blaze/android/run/deployinfo/BlazeApkProviderService.java b/aswb/src/com/google/idea/blaze/android/run/deployinfo/BlazeApkProviderService.java index 1683c989eef..e89caf6c251 100644 --- a/aswb/src/com/google/idea/blaze/android/run/deployinfo/BlazeApkProviderService.java +++ b/aswb/src/com/google/idea/blaze/android/run/deployinfo/BlazeApkProviderService.java @@ -17,13 +17,13 @@ import com.android.tools.idea.run.ApkProvider; import com.google.idea.blaze.android.run.runner.ApkBuildStep; -import com.intellij.openapi.components.ServiceManager; +import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.project.Project; /** Service to provide ApkProviders that source APKs from {@link ApkBuildStep}. */ public interface BlazeApkProviderService { static BlazeApkProviderService getInstance() { - return ServiceManager.getService(BlazeApkProviderService.class); + return ApplicationManager.getApplication().getService(BlazeApkProviderService.class); } /** Returns an APK provider that sources APKs from the given {@link ApkBuildStep}. */ diff --git a/aswb/src/com/google/idea/blaze/android/run/runner/AaptUtil.java b/aswb/src/com/google/idea/blaze/android/run/runner/AaptUtil.java index 6a9f2f3f96f..9f3db2b35c4 100644 --- a/aswb/src/com/google/idea/blaze/android/run/runner/AaptUtil.java +++ b/aswb/src/com/google/idea/blaze/android/run/runner/AaptUtil.java @@ -17,6 +17,7 @@ import com.android.sdklib.BuildToolInfo; import com.android.sdklib.BuildToolInfo.PathId; +import com.android.tools.sdk.AndroidPlatform; import com.google.idea.blaze.android.sync.sdk.SdkUtil; import com.intellij.execution.ExecutionException; import com.intellij.execution.configurations.GeneralCommandLine; @@ -30,7 +31,6 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; import javax.annotation.Nullable; -import org.jetbrains.android.sdk.AndroidPlatformCompat; /** A collection of utilities for extracting information from APKs using aapt. */ public final class AaptUtil { @@ -69,12 +69,12 @@ private static MatchResult getAaptBadging(Project project, File apk, Pattern pat if (!apk.exists()) { throw new AaptUtilException("apk file does not exist: " + apk); } - AndroidPlatformCompat androidPlatform = SdkUtil.getAndroidPlatform(project); + AndroidPlatform androidPlatform = SdkUtil.getAndroidPlatform(project); if (androidPlatform == null) { throw new AaptUtilException( "Could not find Android platform sdk for project " + project.getName()); } - BuildToolInfo toolInfo = androidPlatform.getLatestBuildTool(true); + BuildToolInfo toolInfo = androidPlatform.getSdkData().getLatestBuildTool(true); if (toolInfo == null) { throw new AaptUtilException( "Could not find Android sdk build-tools for project " + project.getName()); diff --git a/aswb/src/com/google/idea/blaze/android/run/runner/BlazeAndroidDebuggerService.java b/aswb/src/com/google/idea/blaze/android/run/runner/BlazeAndroidDebuggerService.java new file mode 100644 index 00000000000..5715392a171 --- /dev/null +++ b/aswb/src/com/google/idea/blaze/android/run/runner/BlazeAndroidDebuggerService.java @@ -0,0 +1,137 @@ +/* + * Copyright 2016 The Bazel Authors. All rights reserved. + * + * 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. + */ +package com.google.idea.blaze.android.run.runner; + +import com.android.tools.idea.execution.common.debug.AndroidDebugger; +import com.android.tools.idea.execution.common.debug.AndroidDebuggerState; +import com.android.tools.idea.execution.common.debug.impl.java.AndroidJavaDebugger; +import com.android.tools.ndk.run.editor.AutoAndroidDebuggerState; +import com.android.tools.ndk.run.editor.NativeAndroidDebuggerState; +import com.google.common.collect.ImmutableList; +import com.google.idea.blaze.android.cppimpl.debug.BlazeAutoAndroidDebugger; +import com.google.idea.blaze.android.run.deployinfo.BlazeAndroidDeployInfo; +import com.google.idea.blaze.base.model.primitives.WorkspaceRoot; +import com.intellij.ide.plugins.PluginManagerCore; +import com.intellij.openapi.components.ServiceManager; +import com.intellij.openapi.project.Project; +import javax.annotation.Nullable; + +/** Provides android debuggers and debugger states for blaze projects. */ +public interface BlazeAndroidDebuggerService { + + static BlazeAndroidDebuggerService getInstance(Project project) { + return ServiceManager.getService(project, BlazeAndroidDebuggerService.class); + } + + /** Returns a different debugger depending on whether or not native debugging is required. */ + AndroidDebugger getDebugger(boolean isNativeDebuggingEnabled); + + /** + * Returns fully initialized debugger states. + * + *

Note: Blaze projects should always use this method instead of the debuggers' {@link + * AndroidDebugger#createState()} method. Blaze projects require additional setup such as + * workspace directory flags that cannot be handled by the debuggers themselves. + */ + AndroidDebuggerState getDebuggerState(AndroidDebugger debugger); + + void configureNativeDebugger( + AndroidDebuggerState state, @Nullable BlazeAndroidDeployInfo deployInfo); + + /** Default debugger service. */ + class DefaultDebuggerService implements BlazeAndroidDebuggerService { + private final Project project; + + public DefaultDebuggerService(Project project) { + this.project = project; + } + + @Override + public AndroidDebugger getDebugger(boolean isNativeDebuggingEnabled) { + return isNativeDebuggingEnabled ? new BlazeAutoAndroidDebugger() : new AndroidJavaDebugger(); + } + + @Override + public AndroidDebuggerState getDebuggerState(AndroidDebugger debugger) { + AndroidDebuggerState debuggerState = debugger.createState(); + if (isNdkPluginLoaded() && debuggerState instanceof NativeAndroidDebuggerState) { + NativeAndroidDebuggerState nativeState = (NativeAndroidDebuggerState) debuggerState; + + // Source code is always relative to the workspace root in a blaze project. + String workingDirPath = WorkspaceRoot.fromProject(project).directory().getPath(); + nativeState.setWorkingDir(workingDirPath); + + // Remote built binaries may use /proc/self/cwd to represent the working directory + // so we manually map /proc/self/cwd to the workspace root. We used to use + // `plugin.symbol-file.dwarf.comp-dir-symlink-paths = "/proc/self/cwd"` + // to automatically resolve this but it's no longer supported in newer versions of + // LLDB. + String sourceMapToWorkspaceRootCommand = + "settings append target.source-map /proc/self/cwd/ " + workingDirPath; + ImmutableList startupCommands = + ImmutableList.builder() + .addAll(nativeState.getUserStartupCommands()) + .add(sourceMapToWorkspaceRootCommand) + .build(); + nativeState.setUserStartupCommands(startupCommands); + } + return debuggerState; + } + + @Override + public void configureNativeDebugger( + AndroidDebuggerState rawState, @Nullable BlazeAndroidDeployInfo deployInfo) { + if (!isNdkPluginLoaded() && !(rawState instanceof AutoAndroidDebuggerState)) { + return; + } + AutoAndroidDebuggerState state = (AutoAndroidDebuggerState) rawState; + + // Source code is always relative to the workspace root in a blaze project. + String workingDirPath = WorkspaceRoot.fromProject(project).directory().getPath(); + state.setWorkingDir(workingDirPath); + + // Remote built binaries may use /proc/self/cwd to represent the working directory, + // so we manually map /proc/self/cwd to the workspace root. We used to use + // `plugin.symbol-file.dwarf.comp-dir-symlink-paths = "/proc/self/cwd"` + // to automatically resolve this, but it's no longer supported in newer versions of + // LLDB. + String sourceMapToWorkspaceRootCommand = + "settings append target.source-map /proc/self/cwd/ " + workingDirPath; + + ImmutableList startupCommands = + ImmutableList.builder() + .addAll(state.getUserStartupCommands()) + .add(sourceMapToWorkspaceRootCommand) + .build(); + state.setUserStartupCommands(startupCommands); + + // NDK plugin will pass symbol directories to LLDB as `settings append + // target.exec-search-paths`. + if (deployInfo != null) { + state.setSymbolDirs( + deployInfo.getSymbolFiles().stream() + .map(symbol -> symbol.getParentFile().getAbsolutePath()) + .collect(ImmutableList.toImmutableList())); + } + } + } + + static boolean isNdkPluginLoaded() { + return PluginManagerCore.getLoadedPlugins().stream() + .anyMatch( + d -> d.isEnabled() && d.getPluginId().getIdString().equals("com.android.tools.ndk")); + } +} diff --git a/aswb/sdkcompat/as223/com/google/idea/blaze/android/run/runner/BlazeAndroidDeviceSelector.java b/aswb/src/com/google/idea/blaze/android/run/runner/BlazeAndroidDeviceSelector.java similarity index 100% rename from aswb/sdkcompat/as223/com/google/idea/blaze/android/run/runner/BlazeAndroidDeviceSelector.java rename to aswb/src/com/google/idea/blaze/android/run/runner/BlazeAndroidDeviceSelector.java diff --git a/aswb/src/com/google/idea/blaze/android/run/runner/BlazeAndroidLaunchTasksProvider.java b/aswb/src/com/google/idea/blaze/android/run/runner/BlazeAndroidLaunchTasksProvider.java new file mode 100644 index 00000000000..bd9c151ac78 --- /dev/null +++ b/aswb/src/com/google/idea/blaze/android/run/runner/BlazeAndroidLaunchTasksProvider.java @@ -0,0 +1,177 @@ +/* + * Copyright 2022 The Bazel Authors. All rights reserved. + * + * 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. + */ +package com.google.idea.blaze.android.run.runner; + +import static com.android.tools.idea.profilers.AndroidProfilerLaunchTaskContributor.isProfilerLaunch; + +import com.android.ddmlib.IDevice; +import com.android.tools.deployer.ApkVerifierTracker; +import com.android.tools.idea.execution.common.DeployOptions; +import com.android.tools.idea.execution.common.debug.AndroidDebugger; +import com.android.tools.idea.execution.common.debug.AndroidDebuggerState; +import com.android.tools.idea.profilers.AndroidProfilerLaunchTaskContributor; +import com.android.tools.idea.run.ApkProvisionException; +import com.android.tools.idea.run.ApplicationIdProvider; +import com.android.tools.idea.run.LaunchOptions; +import com.android.tools.idea.run.blaze.BlazeLaunchTask; +import com.android.tools.idea.run.blaze.BlazeLaunchTasksProvider; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.Lists; +import com.google.idea.blaze.android.run.binary.UserIdHelper; +import com.google.idea.blaze.android.run.deployinfo.BlazeAndroidDeployInfo; +import com.intellij.execution.ExecutionException; +import com.intellij.execution.runners.ExecutionEnvironment; +import com.intellij.execution.ui.ConsoleView; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.progress.ProgressIndicator; +import com.intellij.openapi.project.Project; +import com.intellij.xdebugger.XDebugSession; +import java.util.Collections; +import java.util.List; +import org.jetbrains.annotations.NotNull; + +/** Normal launch tasks provider. #api4.1 */ +public class BlazeAndroidLaunchTasksProvider implements BlazeLaunchTasksProvider { + public static final String NATIVE_DEBUGGING_ENABLED = "NATIVE_DEBUGGING_ENABLED"; + private static final Logger LOG = Logger.getInstance(BlazeAndroidLaunchTasksProvider.class); + + private final Project project; + private final BlazeAndroidRunContext runContext; + private final ApplicationIdProvider applicationIdProvider; + private final LaunchOptions launchOptions; + + public BlazeAndroidLaunchTasksProvider( + Project project, + BlazeAndroidRunContext runContext, + ApplicationIdProvider applicationIdProvider, + LaunchOptions launchOptions) { + this.project = project; + this.runContext = runContext; + this.applicationIdProvider = applicationIdProvider; + this.launchOptions = launchOptions; + } + + @NotNull + @Override + public List getTasks(@NotNull IDevice device, boolean isDebug) + throws ExecutionException { + final List launchTasks = Lists.newArrayList(); + + String packageName; + try { + packageName = applicationIdProvider.getPackageName(); + } catch (ApkProvisionException e) { + throw new ExecutionException("Unable to determine application id: " + e); + } + + Integer userId = runContext.getUserId(device); + + // NOTE: Task for opening the profiler tool-window should come before deployment + // to ensure the tool-window opens correctly. This is required because starting + // the profiler session requires the tool-window to be open. + if (isProfilerLaunch(runContext.getExecutor())) { + launchTasks.add(new BlazeAndroidOpenProfilerWindowTask(project)); + } + + if (launchOptions.isDeploy()) { + String userIdFlags = UserIdHelper.getFlagsFromUserId(userId); + String skipVerification = + ApkVerifierTracker.getSkipVerificationInstallationFlag(device, packageName); + String pmInstallOption; + if (skipVerification != null) { + pmInstallOption = userIdFlags + " " + skipVerification; + } else { + pmInstallOption = userIdFlags; + } + DeployOptions deployOptions = + new DeployOptions(Collections.emptyList(), pmInstallOption, false, false, false); + ImmutableList deployTasks = runContext.getDeployTasks(device, deployOptions); + launchTasks.addAll(deployTasks); + } + + try { + if (isDebug) { + launchTasks.add( + new CheckApkDebuggableTask(project, runContext.getBuildStep().getDeployInfo())); + } + + ImmutableList.Builder amStartOptions = ImmutableList.builder(); + amStartOptions.add(runContext.getAmStartOptions()); + if (isProfilerLaunch(runContext.getExecutor())) { + amStartOptions.add( + AndroidProfilerLaunchTaskContributor.getAmStartOptions( + project, + packageName, + runContext.getProfileState(), + device, + runContext.getExecutor())); + } + BlazeLaunchTask appLaunchTask = + runContext.getApplicationLaunchTask( + isDebug, userId, String.join(" ", amStartOptions.build())); + if (appLaunchTask != null) { + launchTasks.add(appLaunchTask); + // TODO(arvindanekal): the live edit api changed and we cannot get the apk here to create + // live + // edit; the live edit team or Arvind need to fix this + } + } catch (ApkProvisionException e) { + throw new ExecutionException("Unable to determine application id: " + e); + } + + return ImmutableList.copyOf(launchTasks); + } + + @NotNull + @Override + public XDebugSession startDebugSession( + @NotNull ExecutionEnvironment environment, + @NotNull IDevice device, + @NotNull ConsoleView console, + @NotNull ProgressIndicator indicator, + @NotNull String packageName) + throws ExecutionException { + // Do not get debugger state directly from the debugger itself. + // See BlazeAndroidDebuggerService#getDebuggerState for an explanation. + boolean isNativeDebuggingEnabled = isNativeDebuggingEnabled(launchOptions); + BlazeAndroidDebuggerService debuggerService = BlazeAndroidDebuggerService.getInstance(project); + AndroidDebugger debugger = debuggerService.getDebugger(isNativeDebuggingEnabled); + if (debugger == null) { + throw new ExecutionException("Can't find AndroidDebugger for launch"); + } + AndroidDebuggerState debuggerState = debuggerService.getDebuggerState(debugger); + if (debuggerState == null) { + throw new ExecutionException("Can't find AndroidDebuggerState for launch"); + } + if (isNativeDebuggingEnabled) { + BlazeAndroidDeployInfo deployInfo = null; + try { + deployInfo = runContext.getBuildStep().getDeployInfo(); + } catch (ApkProvisionException e) { + LOG.error(e); + } + debuggerService.configureNativeDebugger(debuggerState, deployInfo); + } + + return runContext.startDebuggerSession( + debugger, debuggerState, environment, device, console, indicator, packageName); + } + + private boolean isNativeDebuggingEnabled(LaunchOptions launchOptions) { + Object flag = launchOptions.getExtraOption(NATIVE_DEBUGGING_ENABLED); + return flag instanceof Boolean && (Boolean) flag; + } +} diff --git a/aswb/sdkcompat/as223/com/google/idea/blaze/android/run/runner/BlazeAndroidOpenProfilerWindowTask.java b/aswb/src/com/google/idea/blaze/android/run/runner/BlazeAndroidOpenProfilerWindowTask.java similarity index 100% rename from aswb/sdkcompat/as223/com/google/idea/blaze/android/run/runner/BlazeAndroidOpenProfilerWindowTask.java rename to aswb/src/com/google/idea/blaze/android/run/runner/BlazeAndroidOpenProfilerWindowTask.java diff --git a/aswb/src/com/google/idea/blaze/android/run/runner/BlazeAndroidRunConfigurationRunner.java b/aswb/src/com/google/idea/blaze/android/run/runner/BlazeAndroidRunConfigurationRunner.java new file mode 100644 index 00000000000..0a1215b5b82 --- /dev/null +++ b/aswb/src/com/google/idea/blaze/android/run/runner/BlazeAndroidRunConfigurationRunner.java @@ -0,0 +1,335 @@ +/* + * Copyright 2016 The Bazel Authors. All rights reserved. + * + * 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. + */ + +package com.google.idea.blaze.android.run.runner; + +import com.android.ddmlib.IDevice; +import com.android.tools.idea.editors.liveedit.LiveEditService; +import com.android.tools.idea.execution.common.AndroidConfigurationExecutor; +import com.android.tools.idea.execution.common.AndroidConfigurationExecutorRunProfileState; +import com.android.tools.idea.execution.common.AppRunSettings; +import com.android.tools.idea.execution.common.ApplicationDeployer; +import com.android.tools.idea.execution.common.ComponentLaunchOptions; +import com.android.tools.idea.execution.common.DeployOptions; +import com.android.tools.idea.execution.common.stats.RunStats; +import com.android.tools.idea.projectsystem.ApplicationProjectContext; +import com.android.tools.idea.run.ApkProvider; +import com.android.tools.idea.run.DeviceFutures; +import com.android.tools.idea.run.LaunchOptions; +import com.android.tools.idea.run.blaze.BlazeAndroidConfigurationExecutor; +import com.android.tools.idea.run.configuration.execution.AndroidComplicationConfigurationExecutor; +import com.android.tools.idea.run.configuration.execution.AndroidTileConfigurationExecutor; +import com.android.tools.idea.run.configuration.execution.AndroidWatchFaceConfigurationExecutor; +import com.android.tools.idea.run.configuration.execution.ApplicationDeployerImpl; +import com.android.tools.idea.run.configuration.execution.ComplicationLaunchOptions; +import com.android.tools.idea.run.configuration.execution.TileLaunchOptions; +import com.android.tools.idea.run.configuration.execution.WatchFaceLaunchOptions; +import com.android.tools.idea.run.editor.DeployTarget; +import com.android.tools.idea.run.editor.DeployTargetState; +import com.android.tools.idea.run.util.LaunchUtils; +import com.google.common.util.concurrent.Futures; +import com.google.common.util.concurrent.ListenableFuture; +import com.google.idea.blaze.android.run.binary.BlazeAndroidBinaryRunConfigurationState; +import com.google.idea.blaze.android.run.binary.mobileinstall.MobileInstallBuildStep; +import com.google.idea.blaze.android.run.deployinfo.BlazeApkProviderService; +import com.google.idea.blaze.base.async.executor.ProgressiveTaskWithProgressIndicator; +import com.google.idea.blaze.base.command.BlazeInvocationContext.ContextType; +import com.google.idea.blaze.base.experiments.ExperimentScope; +import com.google.idea.blaze.base.issueparser.BlazeIssueParser; +import com.google.idea.blaze.base.model.primitives.WorkspaceRoot; +import com.google.idea.blaze.base.run.BlazeCommandRunConfiguration; +import com.google.idea.blaze.base.run.confighandler.BlazeCommandRunConfigurationRunner; +import com.google.idea.blaze.base.run.state.RunConfigurationState; +import com.google.idea.blaze.base.scope.BlazeContext; +import com.google.idea.blaze.base.scope.Scope; +import com.google.idea.blaze.base.scope.ScopedTask; +import com.google.idea.blaze.base.scope.output.IssueOutput; +import com.google.idea.blaze.base.scope.scopes.IdeaLogScope; +import com.google.idea.blaze.base.scope.scopes.ProblemsViewScope; +import com.google.idea.blaze.base.scope.scopes.ToolWindowScope; +import com.google.idea.blaze.base.settings.Blaze; +import com.google.idea.blaze.base.settings.BlazeUserSettings; +import com.google.idea.blaze.base.toolwindow.Task; +import com.intellij.execution.ExecutionException; +import com.intellij.execution.Executor; +import com.intellij.execution.configurations.RunProfileState; +import com.intellij.execution.executors.DefaultDebugExecutor; +import com.intellij.execution.runners.ExecutionEnvironment; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Key; +import java.util.Collections; +import java.util.concurrent.CancellationException; +import javax.annotation.Nullable; +import org.jetbrains.android.facet.AndroidFacet; +import org.jetbrains.android.util.AndroidBundle; +import org.jetbrains.annotations.NotNull; + +/** + * Supports the execution. Used by both android_binary and android_test. + * + *

Builds the APK and installs it, launches and debug tasks, etc. + * + *

Any indirection between android_binary/android_test, mobile-install, InstantRun etc. should + * come via the strategy class. + */ +public final class BlazeAndroidRunConfigurationRunner + implements BlazeCommandRunConfigurationRunner { + + private static final Logger LOG = Logger.getInstance(BlazeAndroidRunConfigurationRunner.class); + + private static final Key RUN_CONTEXT_KEY = + Key.create("blaze.run.context"); + public static final Key DEVICE_SESSION_KEY = + Key.create("blaze.device.session"); + + private final Module module; + private final BlazeAndroidRunContext runContext; + private final BlazeCommandRunConfiguration runConfig; + + public BlazeAndroidRunConfigurationRunner( + Module module, BlazeAndroidRunContext runContext, BlazeCommandRunConfiguration runConfig) { + this.module = module; + this.runContext = runContext; + this.runConfig = runConfig; + } + + @Override + @Nullable + public final RunProfileState getRunProfileState(final Executor executor, ExecutionEnvironment env) + throws ExecutionException { + + final AndroidFacet facet = AndroidFacet.getInstance(module); + assert facet != null : "Enforced by fatal validation check in createRunner."; + final Project project = env.getProject(); + + boolean isDebug = executor instanceof DefaultDebugExecutor; + + BlazeAndroidDeviceSelector deviceSelector = runContext.getDeviceSelector(); + BlazeAndroidDeviceSelector.DeviceSession deviceSession = + deviceSelector.getDevice(project, executor, env, isDebug, runConfig.getUniqueID()); + if (deviceSession == null) { + return null; + } + + DeployTarget deployTarget = deviceSession.deployTarget; + if (deployTarget != null && deployTarget.hasCustomRunProfileState(executor)) { + return deployTarget.getRunProfileState(executor, env, DeployTargetState.DEFAULT_STATE); + } + + DeviceFutures deviceFutures = deviceSession.deviceFutures; + if (deviceFutures == null) { + // The user deliberately canceled, or some error was encountered and exposed by the chooser. + // Quietly exit. + return null; + } + + if (deviceFutures.get().isEmpty()) { + throw new ExecutionException(AndroidBundle.message("deployment.target.not.found")); + } + + if (isDebug) { + String error = canDebug(deviceFutures, facet, module.getName()); + if (error != null) { + throw new ExecutionException(error); + } + } + + LaunchOptions.Builder launchOptionsBuilder = getDefaultLaunchOptions(); + runContext.augmentLaunchOptions(launchOptionsBuilder); + + // Store the run context on the execution environment so before-run tasks can access it. + env.putCopyableUserData(RUN_CONTEXT_KEY, runContext); + env.putCopyableUserData(DEVICE_SESSION_KEY, deviceSession); + + RunConfigurationState state = runConfig.getHandler().getState(); + + if (state instanceof BlazeAndroidBinaryRunConfigurationState + && ((BlazeAndroidBinaryRunConfigurationState) state).getCurrentWearLaunchOptions() + != null) { + ComponentLaunchOptions launchOptions = + ((BlazeAndroidBinaryRunConfigurationState) state).getCurrentWearLaunchOptions(); + + return getWearExecutor(launchOptions, env, deployTarget); + } + + ApkProvider apkProvider = + BlazeApkProviderService.getInstance() + .getApkProvider(env.getProject(), runContext.getBuildStep()); + final LaunchOptions launchOptions = launchOptionsBuilder.build(); + BlazeAndroidConfigurationExecutor runner = + new BlazeAndroidConfigurationExecutor( + runContext.getConsoleProvider(), + runContext.getApplicationProjectContext(), + env, + deviceFutures, + runContext.getLaunchTasksProvider(launchOptions), + launchOptions, + apkProvider, + LiveEditService.getInstance(env.getProject())); + return new AndroidConfigurationExecutorRunProfileState(runner); + } + + private RunProfileState getWearExecutor( + ComponentLaunchOptions launchOptions, ExecutionEnvironment env, DeployTarget deployTarget) + throws ExecutionException { + + AppRunSettings settings = + new AppRunSettings() { + @NotNull + @Override + public DeployOptions getDeployOptions() { + return new DeployOptions(Collections.emptyList(), "", true, true, false); + } + + @NotNull + @Override + public ComponentLaunchOptions getComponentLaunchOptions() { + return launchOptions; + } + + @Override + public Module getModule() { + return runConfig.getModules()[0]; + } + }; + + AndroidConfigurationExecutor configurationExecutor; + ApplicationProjectContext applicationProjectContext = runContext.getApplicationProjectContext(); + ApkProvider apkProvider = + BlazeApkProviderService.getInstance() + .getApkProvider(env.getProject(), runContext.getBuildStep()); + DeviceFutures deviceFutures = deployTarget.getDevices(env.getProject()); + + ApplicationDeployer deployer = + runContext.getBuildStep() instanceof MobileInstallBuildStep + ? new MobileInstallApplicationDeployer() + : new ApplicationDeployerImpl(env.getProject(), RunStats.from(env)); + + if (launchOptions instanceof TileLaunchOptions) { + configurationExecutor = + new AndroidTileConfigurationExecutor( + env, + deviceFutures, + settings, + apkProvider, + applicationProjectContext, + deployer); + } else if (launchOptions instanceof WatchFaceLaunchOptions) { + configurationExecutor = + new AndroidWatchFaceConfigurationExecutor( + env, + deviceFutures, + settings, + apkProvider, + applicationProjectContext, + deployer); + } else if (launchOptions instanceof ComplicationLaunchOptions) { + configurationExecutor = + new AndroidComplicationConfigurationExecutor( + env, + deviceFutures, + settings, + apkProvider, + applicationProjectContext, + deployer); + } else { + throw new RuntimeException("Unknown launch options " + launchOptions.getClass().getName()); + } + + return new AndroidConfigurationExecutorRunProfileState(configurationExecutor); + } + + private static String canDebug( + DeviceFutures deviceFutures, AndroidFacet facet, String moduleName) { + // If we are debugging on a device, then the app needs to be debuggable + for (ListenableFuture future : deviceFutures.get()) { + if (!future.isDone()) { + // this is an emulator, and we assume that all emulators are debuggable + continue; + } + IDevice device = Futures.getUnchecked(future); + if (!LaunchUtils.canDebugAppOnDevice(facet, device)) { + return AndroidBundle.message( + "android.cannot.debug.noDebugPermissions", moduleName, device.getName()); + } + } + return null; + } + + private static LaunchOptions.Builder getDefaultLaunchOptions() { + return LaunchOptions.builder(); + } + + @Override + public boolean executeBeforeRunTask(ExecutionEnvironment env) { + final Project project = env.getProject(); + BlazeUserSettings settings = BlazeUserSettings.getInstance(); + return Scope.root( + context -> { + context + .push(new ProblemsViewScope(project, settings.getShowProblemsViewOnRun())) + .push(new ExperimentScope()) + .push( + new ToolWindowScope.Builder( + project, new Task(project, "Build apk", Task.Type.BEFORE_LAUNCH)) + .setPopupBehavior(settings.getShowBlazeConsoleOnRun()) + .setIssueParsers( + BlazeIssueParser.defaultIssueParsers( + project, + WorkspaceRoot.fromProject(project), + ContextType.BeforeRunTask)) + .build()) + .push(new IdeaLogScope()); + + BlazeAndroidRunContext runContext = env.getCopyableUserData(RUN_CONTEXT_KEY); + if (runContext == null) { + IssueOutput.error("Could not find run context. Please try again").submit(context); + return false; + } + BlazeAndroidDeviceSelector.DeviceSession deviceSession = + env.getCopyableUserData(DEVICE_SESSION_KEY); + + ApkBuildStep buildStep = runContext.getBuildStep(); + ScopedTask buildTask = + new ScopedTask(context) { + @Override + protected Void execute(BlazeContext context) { + buildStep.build(context, deviceSession); + return null; + } + }; + + try { + ListenableFuture buildFuture = + ProgressiveTaskWithProgressIndicator.builder( + project, + String.format("Executing %s apk build", Blaze.buildSystemName(project))) + .submitTaskWithResult(buildTask); + Futures.getChecked(buildFuture, ExecutionException.class); + } catch (ExecutionException e) { + context.setHasError(); + } catch (CancellationException e) { + context.setCancelled(); + } catch (Exception e) { + LOG.error(e); + return false; + } + return context.shouldContinue(); + }); + } +} diff --git a/aswb/src/com/google/idea/blaze/android/run/runner/BlazeAndroidRunContext.java b/aswb/src/com/google/idea/blaze/android/run/runner/BlazeAndroidRunContext.java new file mode 100644 index 00000000000..468f24a441d --- /dev/null +++ b/aswb/src/com/google/idea/blaze/android/run/runner/BlazeAndroidRunContext.java @@ -0,0 +1,86 @@ +/* + * 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. + */ +package com.google.idea.blaze.android.run.runner; + +import com.android.ddmlib.IDevice; +import com.android.tools.idea.execution.common.DeployOptions; +import com.android.tools.idea.execution.common.debug.AndroidDebugger; +import com.android.tools.idea.execution.common.debug.AndroidDebuggerState; +import com.android.tools.idea.projectsystem.ApplicationProjectContext; +import com.android.tools.idea.run.ApplicationIdProvider; +import com.android.tools.idea.run.ConsoleProvider; +import com.android.tools.idea.run.LaunchOptions; +import com.android.tools.idea.run.blaze.BlazeLaunchTask; +import com.android.tools.idea.run.blaze.BlazeLaunchTasksProvider; +import com.android.tools.idea.run.editor.ProfilerState; +import com.google.common.collect.ImmutableList; +import com.intellij.execution.ExecutionException; +import com.intellij.execution.Executor; +import com.intellij.execution.runners.ExecutionEnvironment; +import com.intellij.execution.ui.ConsoleView; +import com.intellij.openapi.progress.ProgressIndicator; +import com.intellij.xdebugger.XDebugSession; +import javax.annotation.Nullable; +import org.jetbrains.annotations.NotNull; + +/** Instantiated when the configuration wants to run. */ +public interface BlazeAndroidRunContext { + + BlazeAndroidDeviceSelector getDeviceSelector(); + + void augmentLaunchOptions(LaunchOptions.Builder options); + + ConsoleProvider getConsoleProvider(); + + ApkBuildStep getBuildStep(); + + ApplicationIdProvider getApplicationIdProvider(); + + ApplicationProjectContext getApplicationProjectContext(); + + BlazeLaunchTasksProvider getLaunchTasksProvider(LaunchOptions launchOptions) + throws ExecutionException; + + /** Returns the tasks to deploy the application. */ + ImmutableList getDeployTasks(IDevice device, DeployOptions deployOptions) + throws ExecutionException; + + /** Returns the task to launch the application. */ + @Nullable + BlazeLaunchTask getApplicationLaunchTask( + boolean isDebug, @Nullable Integer userId, @NotNull String contributorsAmStartOptions) + throws ExecutionException; + + /** Returns the task to connect the debugger. */ + @Nullable + XDebugSession startDebuggerSession( + AndroidDebugger androidDebugger, + AndroidDebuggerState androidDebuggerState, + ExecutionEnvironment env, + IDevice device, + ConsoleView consoleView, + ProgressIndicator indicator, + String packageName); + + @Nullable + Integer getUserId(IDevice device) throws ExecutionException; + + String getAmStartOptions(); + + Executor getExecutor(); + + ProfilerState getProfileState(); +} diff --git a/aswb/sdkcompat/as223/com/google/idea/blaze/android/run/runner/CheckApkDebuggableTask.java b/aswb/src/com/google/idea/blaze/android/run/runner/CheckApkDebuggableTask.java similarity index 100% rename from aswb/sdkcompat/as223/com/google/idea/blaze/android/run/runner/CheckApkDebuggableTask.java rename to aswb/src/com/google/idea/blaze/android/run/runner/CheckApkDebuggableTask.java diff --git a/aswb/src/com/google/idea/blaze/android/run/runner/FullApkBuildStep.java b/aswb/src/com/google/idea/blaze/android/run/runner/FullApkBuildStep.java index ddf257d9f95..72e4cbad18a 100644 --- a/aswb/src/com/google/idea/blaze/android/run/runner/FullApkBuildStep.java +++ b/aswb/src/com/google/idea/blaze/android/run/runner/FullApkBuildStep.java @@ -17,6 +17,7 @@ import static java.util.stream.Collectors.joining; +import com.android.annotations.Nullable; import com.android.tools.idea.run.ApkProvisionException; import com.google.common.annotations.VisibleForTesting; import com.google.common.collect.ImmutableList; @@ -72,6 +73,7 @@ public class FullApkBuildStep implements ApkBuildStep { private final BlazeApkDeployInfoProtoHelper deployInfoHelper; private final boolean nativeDebuggingEnabled; private BlazeAndroidDeployInfo deployInfo = null; + @Nullable private final List defaultNativeSymbolFinderList; @VisibleForTesting public FullApkBuildStep( @@ -79,12 +81,14 @@ public FullApkBuildStep( Label label, ImmutableList buildFlags, boolean nativeDebuggingEnabled, - BlazeApkDeployInfoProtoHelper deployInfoHelper) { + BlazeApkDeployInfoProtoHelper deployInfoHelper, + List defaultNativeSymbolFinderList) { this.project = project; this.label = label; this.buildFlags = buildFlags; this.deployInfoHelper = deployInfoHelper; this.nativeDebuggingEnabled = nativeDebuggingEnabled; + this.defaultNativeSymbolFinderList = defaultNativeSymbolFinderList; } public FullApkBuildStep( @@ -92,7 +96,13 @@ public FullApkBuildStep( Label label, ImmutableList buildFlags, boolean nativeDebuggingEnabled) { - this(project, label, buildFlags, nativeDebuggingEnabled, new BlazeApkDeployInfoProtoHelper()); + this( + project, + label, + buildFlags, + nativeDebuggingEnabled, + new BlazeApkDeployInfoProtoHelper(), + null); } private static boolean apksRequireDownload(BlazeAndroidDeployInfo deployInfo) { @@ -146,6 +156,13 @@ private static File downloadLibIfRemote(File lib, BlazeContext context) { return lib; } + private List getNativeSymbolFinderList() { + if (defaultNativeSymbolFinderList != null) { + return defaultNativeSymbolFinderList; + } + return NativeSymbolFinder.EP_NAME.getExtensionList(); + } + @Override public void build(BlazeContext context, BlazeAndroidDeviceSelector.DeviceSession deviceSession) { BlazeProjectData projectData = @@ -162,8 +179,7 @@ public void build(BlazeContext context, BlazeAndroidDeviceSelector.DeviceSession WorkspaceRoot workspaceRoot = WorkspaceRoot.fromProject(project); try (BuildResultHelper buildResultHelper = invoker.createBuildResultHelper()) { - List nativeSymbolFinderList = - NativeSymbolFinder.EP_NAME.getExtensionList(); + List nativeSymbolFinderList = getNativeSymbolFinderList(); command.addTargets(label).addBlazeFlags("--output_groups=+android_deploy_info"); if (!nativeSymbolFinderList.isEmpty()) { diff --git a/aswb/src/com/google/idea/blaze/android/run/runner/InstrumentationInfo.java b/aswb/src/com/google/idea/blaze/android/run/runner/InstrumentationInfo.java index 53c0d644b43..53f0e8337c2 100644 --- a/aswb/src/com/google/idea/blaze/android/run/runner/InstrumentationInfo.java +++ b/aswb/src/com/google/idea/blaze/android/run/runner/InstrumentationInfo.java @@ -23,9 +23,8 @@ import com.google.idea.blaze.base.ideinfo.TargetMap; import com.google.idea.blaze.base.model.BlazeProjectData; import com.google.idea.blaze.base.model.primitives.Label; -import com.google.idea.blaze.base.qsync.QuerySync; -import com.google.idea.blaze.common.BuildTarget; import com.google.idea.blaze.java.AndroidBlazeRules.RuleTypes; +import com.google.idea.blaze.qsync.project.ProjectTarget; import javax.annotation.Nullable; /** @@ -75,10 +74,10 @@ public InstrumentationParserException(String msg) { */ @VisibleForTesting public static InstrumentationInfo getInstrumentationInfo( - Label instrumentationTestLabel, BlazeProjectData projectData) - throws InstrumentationParserException { - if (QuerySync.isEnabled()) { - BuildTarget testTarget = projectData.getBuildTarget(instrumentationTestLabel); + Label instrumentationTestLabel, BlazeProjectData projectData) { + if (projectData.isQuerySync()) { + ProjectTarget testTarget = + (ProjectTarget) projectData.getBuildTarget(instrumentationTestLabel); if (testTarget == null) { String msg = "Unable to identify target \"" + instrumentationTestLabel + "\"."; throw new InstrumentationParserException(msg); @@ -88,7 +87,7 @@ public static InstrumentationInfo getInstrumentationInfo( throw new InstrumentationParserException(msg); } Label testApp = Label.create(testTarget.testApp().get().toString()); - BuildTarget targetApp = projectData.getBuildTarget(testApp); + ProjectTarget targetApp = (ProjectTarget) projectData.getBuildTarget(testApp); Label instruments = null; if (targetApp != null && targetApp.instruments().isPresent()) { instruments = Label.create(targetApp.instruments().get().toString()); diff --git a/aswb/src/com/google/idea/blaze/android/run/runner/MobileInstallApplicationDeployer.java b/aswb/src/com/google/idea/blaze/android/run/runner/MobileInstallApplicationDeployer.java new file mode 100644 index 00000000000..541cf750686 --- /dev/null +++ b/aswb/src/com/google/idea/blaze/android/run/runner/MobileInstallApplicationDeployer.java @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2022 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. + */ +package com.google.idea.blaze.android.run.runner; + +import static com.android.tools.idea.run.tasks.AbstractDeployTask.getAppToInstall; + +import com.android.ddmlib.IDevice; +import com.android.tools.deployer.Deployer; +import com.android.tools.deployer.DeployerException; +import com.android.tools.deployer.model.App; +import com.android.tools.idea.execution.common.ApplicationDeployer; +import com.android.tools.idea.execution.common.DeployOptions; +import com.android.tools.idea.run.ApkInfo; +import com.intellij.openapi.progress.ProgressIndicator; +import org.jetbrains.annotations.NotNull; + +/** Deploys mobile install application. */ +public class MobileInstallApplicationDeployer implements ApplicationDeployer { + + public MobileInstallApplicationDeployer() {} + + @NotNull + @Override + public Deployer.Result fullDeploy( + @NotNull IDevice device, + @NotNull ApkInfo apkInfo, + @NotNull DeployOptions deployOptions, + ProgressIndicator indicator) { + App app = getAppToInstall(apkInfo); + return new Deployer.Result(false, false, false, app); + } + + @NotNull + @Override + public Deployer.Result applyChangesDeploy( + @NotNull IDevice device, + @NotNull ApkInfo app, + @NotNull DeployOptions deployOptions, + ProgressIndicator indicator) { + throw new RuntimeException("Apply changes is not supported for mobile-install"); + } + + @NotNull + @Override + public Deployer.Result applyCodeChangesDeploy( + @NotNull IDevice device, + @NotNull ApkInfo app, + @NotNull DeployOptions deployOptions, + ProgressIndicator indicator) + throws DeployerException { + throw new RuntimeException("Apply code changes is not supported for mobile-install"); + } +} diff --git a/aswb/src/com/google/idea/blaze/android/run/test/AitIdeTestConsoleProvider.java b/aswb/src/com/google/idea/blaze/android/run/test/AitIdeTestConsoleProvider.java index f4698d18d98..02072bf6c4e 100644 --- a/aswb/src/com/google/idea/blaze/android/run/test/AitIdeTestConsoleProvider.java +++ b/aswb/src/com/google/idea/blaze/android/run/test/AitIdeTestConsoleProvider.java @@ -48,8 +48,7 @@ public ConsoleView createAndAttach(Disposable parent, ProcessHandler handler, Ex throws ExecutionException { AndroidTestConsoleProperties properties = new AndroidTestConsoleProperties(runConfiguration, executor); - ConsoleView consoleView = - SMTestRunnerConnectionUtil.createAndAttachConsole("Android", handler, properties); + ConsoleView consoleView = SMTestRunnerConnectionUtil.createConsole("Android", properties); Disposer.register(parent, consoleView); return consoleView; } diff --git a/aswb/sdkcompat/as223/com/google/idea/blaze/android/run/test/BlazeAndroidTestLaunchTask.java b/aswb/src/com/google/idea/blaze/android/run/test/BlazeAndroidTestLaunchTask.java similarity index 100% rename from aswb/sdkcompat/as223/com/google/idea/blaze/android/run/test/BlazeAndroidTestLaunchTask.java rename to aswb/src/com/google/idea/blaze/android/run/test/BlazeAndroidTestLaunchTask.java diff --git a/aswb/src/com/google/idea/blaze/android/run/test/BlazeAndroidTestListener.java b/aswb/src/com/google/idea/blaze/android/run/test/BlazeAndroidTestListener.java new file mode 100644 index 00000000000..e3f51e7558d --- /dev/null +++ b/aswb/src/com/google/idea/blaze/android/run/test/BlazeAndroidTestListener.java @@ -0,0 +1,170 @@ +/* + * Copyright 2023 The Bazel Authors. All rights reserved. + * + * 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. + */ +package com.google.idea.blaze.android.run.test; + +import com.android.ddmlib.testrunner.ITestRunListener; +import com.android.ddmlib.testrunner.TestIdentifier; +import com.android.tools.idea.flags.StudioFlags; +import com.android.tools.idea.run.configuration.execution.ExecutionUtils; +import com.android.tools.idea.testartifacts.instrumented.AndroidTestLocationProvider; +import com.intellij.execution.process.ProcessHandler; +import com.intellij.execution.process.ProcessOutputType; +import com.intellij.execution.testframework.sm.ServiceMessageBuilder; +import com.intellij.execution.ui.ConsoleView; +import java.util.Map; +import java.util.Objects; + +/** + * Copy of {@link com.android.tools.idea.testartifacts.instrumented.AndroidTestListener} + * encapsulating a {@link ProcessHandler}, which is notified on any {@link ServiceMessageBuilder} + * the listener creates. + */ +public class BlazeAndroidTestListener implements ITestRunListener { + + private static final String DISPLAY_PREFIX = "android.studio.display."; + + private final ConsoleView consoleView; + private final ProcessHandler processHandler; + + private long testStartingTime; + private long testSuiteStartingTime; + private String testClassName = null; + + public BlazeAndroidTestListener(ConsoleView consoleView, ProcessHandler processHandler) { + this.consoleView = consoleView; + this.processHandler = processHandler; + } + + @Override + public void testRunStopped(long elapsedTime) { + ExecutionUtils.printlnError(consoleView, "Test run stopped.\n"); + } + + @Override + public void testRunEnded(long elapsedTime, Map runMetrics) { + if (testClassName != null) { + testSuiteFinished(); + } + ExecutionUtils.println(consoleView, "Tests ran to completion."); + } + + @Override + public void testRunFailed(String errorMessage) { + ExecutionUtils.printlnError(consoleView, "Test running failed: " + errorMessage); + } + + @Override + public void testRunStarted(String runName, int testCount) { + ExecutionUtils.println(consoleView, "Started running tests"); + + final ServiceMessageBuilder builder = new ServiceMessageBuilder("enteredTheMatrix"); + notifyProcessHandler(builder); + } + + @Override + public void testStarted(TestIdentifier test) { + if (!Objects.equals(test.getClassName(), testClassName)) { + if (testClassName != null) { + testSuiteFinished(); + } + testClassName = test.getClassName(); + testSuiteStarted(); + } + ServiceMessageBuilder builder = + new ServiceMessageBuilder("testStarted") + .addAttribute("name", test.getTestName()) + .addAttribute( + "locationHint", + AndroidTestLocationProvider.PROTOCOL_ID + + "://" + + test.getClassName() + + '.' + + test.getTestName() + + "()"); + notifyProcessHandler(builder); + testStartingTime = System.currentTimeMillis(); + } + + private void testSuiteStarted() { + testSuiteStartingTime = System.currentTimeMillis(); + ServiceMessageBuilder builder = + new ServiceMessageBuilder("testSuiteStarted") + .addAttribute("name", testClassName) + .addAttribute( + "locationHint", AndroidTestLocationProvider.PROTOCOL_ID + "://" + testClassName); + notifyProcessHandler(builder); + } + + private void testSuiteFinished() { + ServiceMessageBuilder builder = + new ServiceMessageBuilder("testSuiteFinished") + .addAttribute("name", testClassName) + .addAttribute( + "duration", Long.toString(System.currentTimeMillis() - testSuiteStartingTime)); + notifyProcessHandler(builder); + testClassName = null; + } + + @Override + public void testFailed(TestIdentifier test, String stackTrace) { + ServiceMessageBuilder builder = + new ServiceMessageBuilder("testFailed") + .addAttribute("name", test.getTestName()) + .addAttribute("message", "") + .addAttribute("details", stackTrace) + .addAttribute("error", "true"); + notifyProcessHandler(builder); + } + + @Override + public void testAssumptionFailure(TestIdentifier test, String trace) { + ServiceMessageBuilder builder = + ServiceMessageBuilder.testIgnored(test.getTestName()) + .addAttribute("message", "Test ignored. Assumption Failed:") + .addAttribute("details", trace); + notifyProcessHandler(builder); + } + + @Override + public void testIgnored(TestIdentifier test) { + ServiceMessageBuilder builder = ServiceMessageBuilder.testIgnored(test.getTestName()); + notifyProcessHandler(builder); + } + + @Override + public void testEnded(TestIdentifier test, Map testMetrics) { + if (StudioFlags.PRINT_INSTRUMENTATION_STATUS.get()) { + + for (Map.Entry entry : testMetrics.entrySet()) { + String key = entry.getKey(); + if (key.startsWith(DISPLAY_PREFIX)) { + ExecutionUtils.println( + consoleView, key.substring(DISPLAY_PREFIX.length()) + ": " + entry.getValue()); + } + } + } + + ServiceMessageBuilder builder = + new ServiceMessageBuilder("testFinished") + .addAttribute("name", test.getTestName()) + .addAttribute("duration", Long.toString(System.currentTimeMillis() - testStartingTime)); + notifyProcessHandler(builder); + } + + private void notifyProcessHandler(ServiceMessageBuilder serviceMessageBuilder) { + processHandler.notifyTextAvailable(serviceMessageBuilder.toString(), ProcessOutputType.STDOUT); + } +} diff --git a/aswb/src/com/google/idea/blaze/android/run/test/BlazeAndroidTestProgramRunner.java b/aswb/src/com/google/idea/blaze/android/run/test/BlazeAndroidTestProgramRunner.java new file mode 100644 index 00000000000..b294b565455 --- /dev/null +++ b/aswb/src/com/google/idea/blaze/android/run/test/BlazeAndroidTestProgramRunner.java @@ -0,0 +1,77 @@ +/* + * Copyright 2018 The Bazel Authors. All rights reserved. + * + * 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. + */ +package com.google.idea.blaze.android.run.test; + +import com.android.tools.idea.execution.common.AndroidConfigurationExecutor; +import com.android.tools.idea.execution.common.AndroidConfigurationProgramRunner; +import com.google.idea.blaze.android.run.BlazeAndroidRunConfigurationHandler; +import com.google.idea.blaze.base.run.BlazeCommandRunConfigurationType; +import com.intellij.execution.ExecutionException; +import com.intellij.execution.configurations.RunProfile; +import com.intellij.execution.executors.DefaultDebugExecutor; +import com.intellij.execution.executors.DefaultRunExecutor; +import com.intellij.execution.runners.ExecutionEnvironment; +import com.intellij.execution.ui.RunContentDescriptor; +import com.intellij.openapi.progress.ProgressIndicator; +import java.util.Collections; +import java.util.List; +import org.jetbrains.annotations.NotNull; + +/** Program runner for configurations from {@link BlazeAndroidTestRunConfigurationHandler}. */ +public class BlazeAndroidTestProgramRunner extends AndroidConfigurationProgramRunner { + @Override + public boolean canRun(String executorId, RunProfile profile) { + BlazeAndroidRunConfigurationHandler handler = + BlazeAndroidRunConfigurationHandler.getHandlerFrom(profile); + if (!(handler instanceof BlazeAndroidTestRunConfigurationHandler)) { + return false; + } + return super.canRun(executorId, profile) && DefaultRunExecutor.EXECUTOR_ID.equals(executorId) + || DefaultDebugExecutor.EXECUTOR_ID.equals(executorId); + } + + @Override + public String getRunnerId() { + return "AndroidTestProgramRunner"; + } + + @Override + protected boolean canRunWithMultipleDevices(@NotNull String executorId) { + return true; + } + + @NotNull + @Override + protected List getSupportedConfigurationTypeIds() { + return Collections.singletonList(BlazeCommandRunConfigurationType.getInstance().getId()); + } + + @NotNull + @Override + protected RunContentDescriptor run( + @NotNull ExecutionEnvironment environment, + @NotNull AndroidConfigurationExecutor executor, + @NotNull ProgressIndicator indicator) + throws ExecutionException { + if (DefaultDebugExecutor.EXECUTOR_ID.equals(environment.getExecutor().getId())) { + return executor.debug(indicator); + } + if (DefaultRunExecutor.EXECUTOR_ID.equals(environment.getExecutor().getId())) { + return executor.run(indicator); + } + throw new RuntimeException("Unsupported executor"); + } +} diff --git a/aswb/src/com/google/idea/blaze/android/run/test/BlazeAndroidTestRunConfigurationHandler.java b/aswb/src/com/google/idea/blaze/android/run/test/BlazeAndroidTestRunConfigurationHandler.java new file mode 100644 index 00000000000..67e2ad4dfb7 --- /dev/null +++ b/aswb/src/com/google/idea/blaze/android/run/test/BlazeAndroidTestRunConfigurationHandler.java @@ -0,0 +1,223 @@ +/* + * Copyright 2016 The Bazel Authors. All rights reserved. + * + * 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. + */ +package com.google.idea.blaze.android.run.test; + +import com.android.tools.idea.execution.common.DeployableToDevice; +import com.android.tools.idea.run.ValidationError; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.Lists; +import com.google.idea.blaze.android.run.ApkBuildStepProvider; +import com.google.idea.blaze.android.run.BlazeAndroidRunConfigurationCommonState; +import com.google.idea.blaze.android.run.BlazeAndroidRunConfigurationHandler; +import com.google.idea.blaze.android.run.BlazeAndroidRunConfigurationValidationUtil; +import com.google.idea.blaze.android.run.LaunchMetrics; +import com.google.idea.blaze.android.run.runner.ApkBuildStep; +import com.google.idea.blaze.android.run.runner.BlazeAndroidRunConfigurationRunner; +import com.google.idea.blaze.android.run.runner.BlazeAndroidRunContext; +import com.google.idea.blaze.android.run.runner.FullApkBuildStep; +import com.google.idea.blaze.android.run.test.BlazeAndroidTestLaunchMethodsProvider.AndroidTestLaunchMethod; +import com.google.idea.blaze.base.command.BlazeCommandName; +import com.google.idea.blaze.base.command.BlazeInvocationContext; +import com.google.idea.blaze.base.model.primitives.Label; +import com.google.idea.blaze.base.model.primitives.TargetExpression; +import com.google.idea.blaze.base.projectview.ProjectViewManager; +import com.google.idea.blaze.base.projectview.ProjectViewSet; +import com.google.idea.blaze.base.run.BlazeCommandRunConfiguration; +import com.google.idea.blaze.base.run.BlazeConfigurationNameBuilder; +import com.google.idea.blaze.base.run.ExecutorType; +import com.google.idea.blaze.base.run.confighandler.BlazeCommandRunConfigurationRunner; +import com.google.idea.blaze.base.settings.Blaze; +import com.google.idea.blaze.base.sync.data.BlazeDataStorage; +import com.google.idea.blaze.base.sync.projectstructure.ModuleFinder; +import com.google.idea.blaze.java.AndroidBlazeRules; +import com.intellij.execution.ExecutionException; +import com.intellij.execution.Executor; +import com.intellij.execution.JavaExecutionUtil; +import com.intellij.execution.configurations.RuntimeConfigurationException; +import com.intellij.execution.runners.ExecutionEnvironment; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.project.Project; +import java.util.List; +import javax.annotation.Nullable; +import org.jetbrains.android.facet.AndroidFacet; + +/** + * {@link com.google.idea.blaze.base.run.confighandler.BlazeCommandRunConfigurationHandler} for + * android_test targets. + */ +public class BlazeAndroidTestRunConfigurationHandler + implements BlazeAndroidRunConfigurationHandler { + private final Project project; + private final BlazeAndroidTestRunConfigurationState configState; + + BlazeAndroidTestRunConfigurationHandler(BlazeCommandRunConfiguration configuration) { + this.project = configuration.getProject(); + this.configState = + new BlazeAndroidTestRunConfigurationState( + Blaze.buildSystemName(configuration.getProject())); + configuration.putUserData(DeployableToDevice.getKEY(), true); + } + + @Override + public BlazeAndroidTestRunConfigurationState getState() { + return configState; + } + + @Override + public BlazeAndroidRunConfigurationCommonState getCommonState() { + return configState.getCommonState(); + } + + @Override + public BlazeCommandRunConfigurationRunner createRunner( + Executor executor, ExecutionEnvironment env) throws ExecutionException { + Project project = env.getProject(); + BlazeCommandRunConfiguration configuration = + BlazeAndroidRunConfigurationHandler.getCommandConfig(env); + + BlazeAndroidRunConfigurationValidationUtil.validate(project); + Module module = + ModuleFinder.getInstance(env.getProject()) + .findModuleByName(BlazeDataStorage.WORKSPACE_MODULE_NAME); + AndroidFacet facet = module != null ? AndroidFacet.getInstance(module) : null; + ProjectViewSet projectViewSet = ProjectViewManager.getInstance(project).getProjectViewSet(); + + ImmutableList blazeFlags = + configState + .getCommonState() + .getExpandedBuildFlags( + project, + projectViewSet, + BlazeCommandName.TEST, + BlazeInvocationContext.runConfigContext( + ExecutorType.fromExecutor(env.getExecutor()), configuration.getType(), false)); + ImmutableList exeFlags = + ImmutableList.copyOf( + configState.getCommonState().getExeFlagsState().getFlagsForExternalProcesses()); + + // We collect metrics from a few different locations. In order to tie them all + // together, we create a unique launch id. + String launchId = LaunchMetrics.newLaunchId(); + Label label = Label.create(configuration.getSingleTarget().toString()); + + ApkBuildStep buildStep = + getTestBuildStep( + project, configState, configuration, blazeFlags, exeFlags, launchId, label); + + BlazeAndroidRunContext runContext = + new BlazeAndroidTestRunContext( + project, facet, configuration, env, configState, label, blazeFlags, buildStep); + + LaunchMetrics.logTestLaunch( + launchId, configState.getLaunchMethod().name(), env.getExecutor().getId()); + + return new BlazeAndroidRunConfigurationRunner(module, runContext, configuration); + } + + private static ApkBuildStep getTestBuildStep( + Project project, + BlazeAndroidTestRunConfigurationState configState, + BlazeCommandRunConfiguration configuration, + ImmutableList blazeFlags, + ImmutableList exeFlags, + String launchId, + Label label) + throws ExecutionException { + if (configuration.getTargetKind() + == AndroidBlazeRules.RuleTypes.ANDROID_INSTRUMENTATION_TEST.getKind()) { + boolean useMobileInstall = + AndroidTestLaunchMethod.MOBILE_INSTALL.equals(configState.getLaunchMethod()); + return ApkBuildStepProvider.getInstance(Blaze.getBuildSystemName(project)) + .getAitBuildStep( + project, + useMobileInstall, + /* nativeDebuggingEnabled= */ false, + label, + blazeFlags, + exeFlags, + launchId); + } else { + // TODO(b/248317444): This path is only invoked for the deprecated {@code android_test} + // targets, and should eventually be removed. + return new FullApkBuildStep(project, label, blazeFlags, /* nativeDebuggingEnabled= */ false); + } + } + + @Override + public final void checkConfiguration() throws RuntimeConfigurationException { + BlazeAndroidRunConfigurationValidationUtil.throwTopConfigurationError(validate()); + } + + /** + * We collect errors rather than throwing to avoid missing fatal errors by exiting early for a + * warning. We use a separate method for the collection so the compiler prevents us from + * accidentally throwing. + */ + private List validate() { + List errors = Lists.newArrayList(); + errors.addAll(BlazeAndroidRunConfigurationValidationUtil.validateWorkspaceModule(project)); + errors.addAll(configState.validate(project)); + return errors; + } + + @Override + @Nullable + public String suggestedName(BlazeCommandRunConfiguration configuration) { + TargetExpression target = configuration.getSingleTarget(); + if (target == null) { + return null; + } + BlazeConfigurationNameBuilder nameBuilder = new BlazeConfigurationNameBuilder(configuration); + + boolean isClassTest = + configState.getTestingType() == BlazeAndroidTestRunConfigurationState.TEST_CLASS; + boolean isMethodTest = + configState.getTestingType() == BlazeAndroidTestRunConfigurationState.TEST_METHOD; + if ((isClassTest || isMethodTest) && configState.getClassName() != null) { + // Get the class name without the package. + String className = JavaExecutionUtil.getPresentableClassName(configState.getClassName()); + if (className != null) { + String targetString = className; + if (isMethodTest) { + targetString += "#" + configState.getMethodName(); + } + + if (getState().getLaunchMethod().equals(AndroidTestLaunchMethod.NON_BLAZE)) { + return targetString; + } else { + return nameBuilder.setTargetString(targetString).build(); + } + } + } + return nameBuilder.build(); + } + + @Override + @Nullable + public BlazeCommandName getCommandName() { + if (getState().getLaunchMethod().equals(AndroidTestLaunchMethod.BLAZE_TEST)) { + return BlazeCommandName.TEST; + } else if (getState().getLaunchMethod().equals(AndroidTestLaunchMethod.MOBILE_INSTALL)) { + return BlazeCommandName.MOBILE_INSTALL; + } + return null; + } + + @Override + public String getHandlerName() { + return "Android Test Handler"; + } +} diff --git a/aswb/src/com/google/idea/blaze/android/run/test/BlazeAndroidTestRunContext.java b/aswb/src/com/google/idea/blaze/android/run/test/BlazeAndroidTestRunContext.java new file mode 100644 index 00000000000..f54c5ff92f4 --- /dev/null +++ b/aswb/src/com/google/idea/blaze/android/run/test/BlazeAndroidTestRunContext.java @@ -0,0 +1,294 @@ +/* + * Copyright 2016 The Bazel Authors. All rights reserved. + * + * 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. + */ +package com.google.idea.blaze.android.run.test; + +import static com.google.idea.blaze.android.run.binary.BlazeAndroidBinaryNormalBuildRunContextBase.getApkInfoToInstall; + +import com.android.ddmlib.ClientData; +import com.android.ddmlib.IDevice; +import com.android.tools.idea.execution.common.DeployOptions; +import com.android.tools.idea.execution.common.debug.AndroidDebugger; +import com.android.tools.idea.execution.common.debug.AndroidDebuggerState; +import com.android.tools.idea.execution.common.debug.DebugSessionStarter; +import com.android.tools.idea.projectsystem.ApplicationProjectContext; +import com.android.tools.idea.run.ApkProvider; +import com.android.tools.idea.run.ApkProvisionException; +import com.android.tools.idea.run.ApplicationIdProvider; +import com.android.tools.idea.run.ConsoleProvider; +import com.android.tools.idea.run.LaunchOptions; +import com.android.tools.idea.run.blaze.BlazeLaunchTask; +import com.android.tools.idea.run.blaze.BlazeLaunchTasksProvider; +import com.android.tools.idea.run.editor.ProfilerState; +import com.android.tools.idea.run.tasks.DeployTasksHelper; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.Lists; +import com.google.idea.blaze.android.run.BazelApplicationProjectContext; +import com.google.idea.blaze.android.run.deployinfo.BlazeAndroidDeployInfo; +import com.google.idea.blaze.android.run.deployinfo.BlazeApkProviderService; +import com.google.idea.blaze.android.run.runner.ApkBuildStep; +import com.google.idea.blaze.android.run.runner.BlazeAndroidDeviceSelector; +import com.google.idea.blaze.android.run.runner.BlazeAndroidLaunchTasksProvider; +import com.google.idea.blaze.android.run.runner.BlazeAndroidRunContext; +import com.google.idea.blaze.android.run.test.BlazeAndroidTestLaunchMethodsProvider.AndroidTestLaunchMethod; +import com.google.idea.blaze.base.model.primitives.Label; +import com.google.idea.blaze.base.run.BlazeCommandRunConfiguration; +import com.google.idea.blaze.base.run.smrunner.BlazeTestUiSession; +import com.google.idea.blaze.base.run.testlogs.BlazeTestResultHolder; +import com.intellij.execution.ExecutionException; +import com.intellij.execution.Executor; +import com.intellij.execution.process.NopProcessHandler; +import com.intellij.execution.process.ProcessHandler; +import com.intellij.execution.process.ProcessOutputTypes; +import com.intellij.execution.runners.ExecutionEnvironment; +import com.intellij.execution.ui.ConsoleView; +import com.intellij.openapi.progress.ProcessCanceledException; +import com.intellij.openapi.progress.ProgressIndicator; +import com.intellij.openapi.project.Project; +import com.intellij.xdebugger.XDebugSession; +import java.util.List; +import javax.annotation.Nullable; +import kotlin.Unit; +import kotlin.coroutines.EmptyCoroutineContext; +import kotlinx.coroutines.BuildersKt; +import org.jetbrains.android.facet.AndroidFacet; + +/** Run context for android_test. */ +public class BlazeAndroidTestRunContext implements BlazeAndroidRunContext { + protected final Project project; + protected final AndroidFacet facet; + protected final BlazeCommandRunConfiguration runConfiguration; + protected final ExecutionEnvironment env; + protected final BlazeAndroidTestRunConfigurationState configState; + protected final Label label; + protected final ImmutableList blazeFlags; + protected final List launchTaskCompleteListeners = Lists.newArrayList(); + protected final ConsoleProvider consoleProvider; + protected final ApkBuildStep buildStep; + protected final ApplicationIdProvider applicationIdProvider; + protected final ApkProvider apkProvider; + private final BlazeTestResultHolder testResultsHolder = new BlazeTestResultHolder(); + + public BlazeAndroidTestRunContext( + Project project, + AndroidFacet facet, + BlazeCommandRunConfiguration runConfiguration, + ExecutionEnvironment env, + BlazeAndroidTestRunConfigurationState configState, + Label label, + ImmutableList blazeFlags, + ApkBuildStep buildStep) { + this.project = project; + this.facet = facet; + this.runConfiguration = runConfiguration; + this.env = env; + this.label = label; + this.configState = configState; + this.buildStep = buildStep; + this.blazeFlags = blazeFlags; + switch (configState.getLaunchMethod()) { + case MOBILE_INSTALL: + case NON_BLAZE: + consoleProvider = new AitIdeTestConsoleProvider(runConfiguration, configState); + break; + case BLAZE_TEST: + BlazeTestUiSession session = + BlazeTestUiSession.create(ImmutableList.of(), testResultsHolder); + this.consoleProvider = new AitBlazeTestConsoleProvider(project, runConfiguration, session); + break; + default: + throw new IllegalStateException( + "Unsupported launch method " + configState.getLaunchMethod()); + } + applicationIdProvider = new BlazeAndroidTestApplicationIdProvider(buildStep); + apkProvider = BlazeApkProviderService.getInstance().getApkProvider(project, buildStep); + } + + @Override + public BlazeAndroidDeviceSelector getDeviceSelector() { + return new BlazeAndroidDeviceSelector.NormalDeviceSelector(); + } + + @Override + public void augmentLaunchOptions(LaunchOptions.Builder options) { + options.setDeploy(!configState.getLaunchMethod().equals(AndroidTestLaunchMethod.BLAZE_TEST)); + } + + @Override + public ConsoleProvider getConsoleProvider() { + return consoleProvider; + } + + @Override + public ApplicationIdProvider getApplicationIdProvider() { + return applicationIdProvider; + } + + @Override + public ApplicationProjectContext getApplicationProjectContext() { + return new BazelApplicationProjectContext(project, getApplicationIdProvider()); + } + + @Nullable + @Override + public ApkBuildStep getBuildStep() { + return buildStep; + } + + @Override + public ProfilerState getProfileState() { + return null; + } + + @Override + public BlazeLaunchTasksProvider getLaunchTasksProvider(LaunchOptions launchOptions) + throws ExecutionException { + return new BlazeAndroidLaunchTasksProvider(project, this, applicationIdProvider, launchOptions); + } + + @Override + public ImmutableList getDeployTasks(IDevice device, DeployOptions deployOptions) + throws ExecutionException { + if (configState.getLaunchMethod() != AndroidTestLaunchMethod.NON_BLAZE) { + return ImmutableList.of(); + } + return ImmutableList.of( + DeployTasksHelper.createDeployTask( + project, getApkInfoToInstall(device, deployOptions, apkProvider), deployOptions)); + } + + @Override + @Nullable + public BlazeLaunchTask getApplicationLaunchTask( + boolean isDebug, @Nullable Integer userId, String contributorsAmStartOptions) + throws ExecutionException { + switch (configState.getLaunchMethod()) { + case BLAZE_TEST: + BlazeAndroidTestFilter testFilter = + new BlazeAndroidTestFilter( + configState.getTestingType(), + configState.getClassName(), + configState.getMethodName(), + configState.getPackageName()); + return new BlazeAndroidTestLaunchTask( + project, label, blazeFlags, testFilter, this, isDebug, testResultsHolder); + case NON_BLAZE: + case MOBILE_INSTALL: + BlazeAndroidDeployInfo deployInfo; + try { + deployInfo = buildStep.getDeployInfo(); + } catch (ApkProvisionException e) { + throw new ExecutionException(e); + } + return StockAndroidTestLaunchTask.getStockTestLaunchTask( + configState, applicationIdProvider, isDebug, deployInfo, project); + } + throw new AssertionError(); + } + + @Override + @SuppressWarnings({"unchecked", "rawtypes"}) // Raw type from upstream. + public XDebugSession startDebuggerSession( + AndroidDebugger androidDebugger, + AndroidDebuggerState androidDebuggerState, + ExecutionEnvironment env, + IDevice device, + ConsoleView consoleView, + ProgressIndicator indicator, + String packageName) { + try { + return BuildersKt.runBlocking( + EmptyCoroutineContext.INSTANCE, + (scope, continuation) -> { + switch (configState.getLaunchMethod()) { + case BLAZE_TEST: + + /** + * Wires up listeners to automatically reconnect the debugger for each test method. + * When you `blaze test` an android_test in debug mode, it kills the instrumentation + * process between each test method, disconnecting the debugger. We listen for the + * start of a new method waiting for a debugger, and reconnect. TODO: Support + * stopping Blaze from the UI. This is hard because we have no way to distinguish + * process handler termination/debug session ending initiated by the user. + */ + final ProcessHandler masterProcessHandler = new NopProcessHandler(); + addLaunchTaskCompleteListener( + () -> { + masterProcessHandler.notifyTextAvailable( + "Test run completed.\n", ProcessOutputTypes.STDOUT); + masterProcessHandler.detachProcess(); + }); + return DebugSessionStarter.INSTANCE.attachReattachingDebuggerToStartedProcess( + device, + new BazelApplicationProjectContext(project, packageName), + masterProcessHandler, + env, + androidDebugger, + androidDebuggerState, + indicator, + consoleView, + Long.MAX_VALUE, + continuation); + case NON_BLAZE: + case MOBILE_INSTALL: + return DebugSessionStarter.INSTANCE.attachDebuggerToStartedProcess( + device, + new BazelApplicationProjectContext(project, packageName), + env, + androidDebugger, + androidDebuggerState, + /*destroyRunningProcess*/ d -> { + d.forceStop(packageName); + return Unit.INSTANCE; + }, + indicator, + consoleView, + Long.MAX_VALUE, + ClientData.DebuggerStatus.WAITING, + continuation); + } + throw new RuntimeException("Unknown lunch mode"); + }); + } catch (InterruptedException e) { + throw new ProcessCanceledException(); + } + } + + void onLaunchTaskComplete() { + for (Runnable runnable : launchTaskCompleteListeners) { + runnable.run(); + } + } + + void addLaunchTaskCompleteListener(Runnable runnable) { + launchTaskCompleteListeners.add(runnable); + } + + @Override + public Executor getExecutor() { + return env.getExecutor(); + } + + @Nullable + @Override + public Integer getUserId(IDevice device) { + return null; + } + + @Override + public String getAmStartOptions() { + return ""; + } +} diff --git a/aswb/src/com/google/idea/blaze/android/run/test/StockAndroidTestLaunchTask.java b/aswb/src/com/google/idea/blaze/android/run/test/StockAndroidTestLaunchTask.java new file mode 100644 index 00000000000..6ec9004fb57 --- /dev/null +++ b/aswb/src/com/google/idea/blaze/android/run/test/StockAndroidTestLaunchTask.java @@ -0,0 +1,207 @@ +/* + * Copyright 2016 The Bazel Authors. All rights reserved. + * + * 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. + */ +package com.google.idea.blaze.android.run.test; + +import com.android.ddmlib.IDevice; +import com.android.ddmlib.testrunner.RemoteAndroidTestRunner; +import com.android.tools.idea.execution.common.RunConfigurationNotifier; +import com.android.tools.idea.execution.common.processhandler.AndroidProcessHandler; +import com.android.tools.idea.run.ApkProvisionException; +import com.android.tools.idea.run.ApplicationIdProvider; +import com.android.tools.idea.run.blaze.BlazeLaunchContext; +import com.android.tools.idea.run.blaze.BlazeLaunchTask; +import com.android.tools.idea.run.configuration.execution.ExecutionUtils; +import com.google.common.collect.ImmutableList; +import com.google.idea.blaze.android.manifest.ManifestParser; +import com.google.idea.blaze.android.run.deployinfo.BlazeAndroidDeployInfo; +import com.intellij.execution.ExecutionException; +import com.intellij.execution.process.ProcessHandler; +import com.intellij.execution.ui.ConsoleView; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Computable; +import com.intellij.openapi.util.text.StringUtil; +import java.util.List; +import javax.annotation.Nullable; +import org.jetbrains.annotations.NotNull; + +class StockAndroidTestLaunchTask implements BlazeLaunchTask { + private static final String ID = "STOCK_ANDROID_TEST"; + private static final Logger LOG = Logger.getInstance(StockAndroidTestLaunchTask.class); + private final BlazeAndroidTestRunConfigurationState configState; + private final String instrumentationTestRunner; + private final String testApplicationId; + private final boolean waitForDebugger; + + StockAndroidTestLaunchTask( + BlazeAndroidTestRunConfigurationState configState, + String runner, + String testPackage, + boolean waitForDebugger) { + this.configState = configState; + this.instrumentationTestRunner = runner; + this.waitForDebugger = waitForDebugger; + this.testApplicationId = testPackage; + } + + @Nullable + public static BlazeLaunchTask getStockTestLaunchTask( + BlazeAndroidTestRunConfigurationState configState, + ApplicationIdProvider applicationIdProvider, + boolean waitForDebugger, + BlazeAndroidDeployInfo deployInfo, + Project project) + throws ExecutionException { + String testPackage; + try { + testPackage = applicationIdProvider.getTestPackageName(); + } catch (ApkProvisionException e) { + throw new ExecutionException("Unable to determine test package name. " + e.getMessage()); + } + if (testPackage == null) { + throw new ExecutionException("Unable to determine test package name."); + } + List availableRunners = getRunnersFromManifest(deployInfo); + if (availableRunners.isEmpty()) { + RunConfigurationNotifier.INSTANCE.notifyError( + project, + "", + String.format( + "No instrumentation test runner is defined in the manifest.\n" + + "At least one instrumentation tag must be defined for the\n" + + "\"%1$s\" package in the AndroidManifest.xml, e.g.:\n" + + "\n" + + "\n" + + "\n" + + " \n" + + " \n" + + "\n" + + "", + testPackage)); + // Note: Gradle users will never see the above message, so don't mention Gradle here. + // Even if no runners are defined in build.gradle, Gradle will add a default to the manifest. + throw new ExecutionException("No instrumentation test runner is defined in the manifest."); + } + String runner = configState.getInstrumentationRunnerClass(); + if (StringUtil.isEmpty(runner)) { + // Default to the first available runner. + runner = availableRunners.get(0); + } + if (!availableRunners.contains(runner)) { + RunConfigurationNotifier.INSTANCE.notifyError( + project, + "", + String.format( + "Instrumentation test runner \"%2$s\"\n" + + "is not defined for the \"%1$s\" package in the manifest.\n" + + "Clear the 'Specific instrumentation runner' field in your configuration\n" + + "to default to \"%3$s\",\n" + + "or add the runner to your AndroidManifest.xml:\n" + + "\n" + + "\n" + + "\n" + + " \n" + + " \n" + + "\n" + + "", + testPackage, runner, availableRunners.get(0))); + throw new ExecutionException( + String.format( + "Instrumentation test runner \"%2$s\" is not defined for the \"%1$s\" package in the" + + " manifest.", + testPackage, runner)); + } + + return new StockAndroidTestLaunchTask(configState, runner, testPackage, waitForDebugger); + } + + private static ImmutableList getRunnersFromManifest( + final BlazeAndroidDeployInfo deployInfo) { + if (!ApplicationManager.getApplication().isReadAccessAllowed()) { + return ApplicationManager.getApplication() + .runReadAction( + (Computable>) () -> getRunnersFromManifest(deployInfo)); + } + ManifestParser.ParsedManifest parsedManifest = deployInfo.getMergedManifest(); + if (parsedManifest != null) { + return ImmutableList.copyOf(parsedManifest.instrumentationClassNames); + } + return ImmutableList.of(); + } + + @SuppressWarnings("FutureReturnValueIgnored") + public void run(@NotNull BlazeLaunchContext launchContext) { + ConsoleView console = launchContext.getConsoleView(); + IDevice device = launchContext.getDevice(); + ExecutionUtils.println(console, "Running tests\n"); + final RemoteAndroidTestRunner runner = + new RemoteAndroidTestRunner(testApplicationId, instrumentationTestRunner, device); + switch (configState.getTestingType()) { + case BlazeAndroidTestRunConfigurationState.TEST_ALL_IN_MODULE: + break; + case BlazeAndroidTestRunConfigurationState.TEST_ALL_IN_PACKAGE: + runner.setTestPackageName(configState.getPackageName()); + break; + case BlazeAndroidTestRunConfigurationState.TEST_CLASS: + runner.setClassName(configState.getClassName()); + break; + case BlazeAndroidTestRunConfigurationState.TEST_METHOD: + runner.setMethodName(configState.getClassName(), configState.getMethodName()); + break; + default: + throw new RuntimeException( + String.format("Unrecognized testing type: %d", configState.getTestingType())); + } + runner.setDebug(waitForDebugger); + runner.setRunOptions(configState.getExtraOptions()); + ExecutionUtils.printShellCommand(console, runner.getAmInstrumentCommand()); + // run in a separate thread as this will block until the tests complete + ApplicationManager.getApplication() + .executeOnPooledThread( + () -> { + try { + // This issues "am instrument" command and blocks execution. + runner.run( + new BlazeAndroidTestListener(console, launchContext.getProcessHandler())); + // Detach the device from the android process handler manually as soon as "am + // instrument" command finishes. This is required because the android process + // handler may overlook target process especially when the test + // runs really fast (~10ms). Because the android process handler discovers new + // processes by polling, this race condition happens easily. By detaching the device + // manually, we can avoid the android process handler waiting for (already finished) + // process to show up until it times out (10 secs). + // Note: this is a copy of ag/9593981, but it is worth figuring out a better + // strategy here if the behavior of AndroidTestListener is not guaranteed. + ProcessHandler processHandler = launchContext.getProcessHandler(); + if (processHandler instanceof AndroidProcessHandler) { + ((AndroidProcessHandler) processHandler).detachDevice(launchContext.getDevice()); + } + } catch (Exception e) { + ExecutionUtils.printlnError( + console, "Error: Unexpected exception while running tests: " + e); + } + }); + } +} diff --git a/aswb/src/com/google/idea/blaze/android/run/test/smrunner/BlazeAndroidTestEventsHandler.java b/aswb/src/com/google/idea/blaze/android/run/test/smrunner/BlazeAndroidTestEventsHandler.java index 092c40c614e..e3b2e808654 100644 --- a/aswb/src/com/google/idea/blaze/android/run/test/smrunner/BlazeAndroidTestEventsHandler.java +++ b/aswb/src/com/google/idea/blaze/android/run/test/smrunner/BlazeAndroidTestEventsHandler.java @@ -102,7 +102,7 @@ public String getTestFilter(Project project, List> testLocations) { String filter = BlazeJUnitTestFilterFlags.testFilterForClassesAndMethods( failedClassesAndMethods, JUnitVersion.JUNIT_4); - return filter != null ? BlazeFlags.TEST_FILTER + "=" + filter : null; + return filter != null ? String.format("%s='%s'", BlazeFlags.TEST_FILTER, filter) : null; } private static void appendTest(Map>> map, Location location) { diff --git a/aswb/src/com/google/idea/blaze/android/run/testrecorder/TestRecorderBlazeCommandRunConfigurationProxy.java b/aswb/src/com/google/idea/blaze/android/run/testrecorder/TestRecorderBlazeCommandRunConfigurationProxy.java index aa6e7713145..599f2c90061 100644 --- a/aswb/src/com/google/idea/blaze/android/run/testrecorder/TestRecorderBlazeCommandRunConfigurationProxy.java +++ b/aswb/src/com/google/idea/blaze/android/run/testrecorder/TestRecorderBlazeCommandRunConfigurationProxy.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 The Bazel Authors. All rights reserved. + * Copyright 2023 The Bazel Authors. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,72 +15,20 @@ */ package com.google.idea.blaze.android.run.testrecorder; -import com.android.annotations.Nullable; -import com.android.ddmlib.IDevice; -import com.google.common.util.concurrent.ListenableFuture; -import com.google.gct.testrecorder.run.TestRecorderRunConfigurationProxy; -import com.google.idea.blaze.android.run.binary.BlazeAndroidBinaryRunConfigurationHandler; -import com.google.idea.blaze.android.run.binary.BlazeAndroidBinaryRunConfigurationState; -import com.google.idea.blaze.android.run.runner.BlazeAndroidRunConfigurationRunner; +import com.google.idea.blaze.android.cppimpl.debug.BlazeAutoAndroidDebuggerBase; import com.google.idea.blaze.base.run.BlazeCommandRunConfiguration; -import com.google.idea.blaze.base.sync.data.BlazeDataStorage; -import com.google.idea.blaze.base.sync.projectstructure.ModuleFinder; -import com.intellij.execution.configurations.LocatableConfigurationBase; -import com.intellij.execution.runners.ExecutionEnvironment; -import com.intellij.openapi.module.Module; -import java.util.List; -/** {@link TestRecorderRunConfigurationProxy} for blaze. */ +/** Implementation of TestRecorderBlazeCommandRunConfigurationProxy. */ public class TestRecorderBlazeCommandRunConfigurationProxy - implements TestRecorderRunConfigurationProxy { - - private final BlazeCommandRunConfiguration myBaseConfiguration; - private final BlazeAndroidBinaryRunConfigurationHandler myBaseConfigurationHandler; + extends TestRecorderBlazeCommandRunConfigurationProxyBase { public TestRecorderBlazeCommandRunConfigurationProxy( BlazeCommandRunConfiguration baseConfiguration) { - myBaseConfiguration = baseConfiguration; - myBaseConfigurationHandler = - (BlazeAndroidBinaryRunConfigurationHandler) baseConfiguration.getHandler(); - } - - @Override - public LocatableConfigurationBase getTestRecorderRunConfiguration() { - return new TestRecorderBlazeCommandRunConfiguration(myBaseConfiguration); - } - - @Override - public Module getModule() { - return ModuleFinder.getInstance(myBaseConfiguration.getProject()) - .findModuleByName(BlazeDataStorage.WORKSPACE_MODULE_NAME); - } - - @Override - public boolean isLaunchActivitySupported() { - String mode = myBaseConfigurationHandler.getState().getMode(); - - // Supported launch activities are Default and Specified. - return BlazeAndroidBinaryRunConfigurationState.LAUNCH_DEFAULT_ACTIVITY.equals(mode) - || BlazeAndroidBinaryRunConfigurationState.LAUNCH_SPECIFIC_ACTIVITY.equals(mode); - } - - @Override - public String getLaunchActivityClass() { - BlazeAndroidBinaryRunConfigurationState state = myBaseConfigurationHandler.getState(); - - if (BlazeAndroidBinaryRunConfigurationState.LAUNCH_SPECIFIC_ACTIVITY.equals(state.getMode())) { - return state.getActivityClass(); - } - - return ""; + super(baseConfiguration); } - @Nullable @Override - public List> getDeviceFutures(ExecutionEnvironment environment) { - return environment - .getCopyableUserData(BlazeAndroidRunConfigurationRunner.DEVICE_SESSION_KEY) - .deviceFutures - .get(); + public boolean isNativeProject() { + return BlazeAutoAndroidDebuggerBase.isNativeCodeInProject(getModule().getProject()); } } diff --git a/aswb/src/com/google/idea/blaze/android/run/testrecorder/TestRecorderBlazeCommandRunConfigurationProxyBase.java b/aswb/src/com/google/idea/blaze/android/run/testrecorder/TestRecorderBlazeCommandRunConfigurationProxyBase.java new file mode 100644 index 00000000000..5387ae97d31 --- /dev/null +++ b/aswb/src/com/google/idea/blaze/android/run/testrecorder/TestRecorderBlazeCommandRunConfigurationProxyBase.java @@ -0,0 +1,71 @@ +/* + * Copyright 2016 The Bazel Authors. All rights reserved. + * + * 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. + */ +package com.google.idea.blaze.android.run.testrecorder; + +import com.google.gct.testrecorder.run.TestRecorderRunConfigurationProxy; +import com.google.idea.blaze.android.run.binary.BlazeAndroidBinaryRunConfigurationHandler; +import com.google.idea.blaze.android.run.binary.BlazeAndroidBinaryRunConfigurationState; +import com.google.idea.blaze.base.run.BlazeCommandRunConfiguration; +import com.google.idea.blaze.base.sync.data.BlazeDataStorage; +import com.google.idea.blaze.base.sync.projectstructure.ModuleFinder; +import com.intellij.execution.configurations.LocatableConfigurationBase; +import com.intellij.openapi.module.Module; + +/** {@link TestRecorderRunConfigurationProxy} for blaze. */ +public abstract class TestRecorderBlazeCommandRunConfigurationProxyBase + implements TestRecorderRunConfigurationProxy { + + private final BlazeCommandRunConfiguration myBaseConfiguration; + private final BlazeAndroidBinaryRunConfigurationHandler myBaseConfigurationHandler; + + public TestRecorderBlazeCommandRunConfigurationProxyBase( + BlazeCommandRunConfiguration baseConfiguration) { + myBaseConfiguration = baseConfiguration; + myBaseConfigurationHandler = + (BlazeAndroidBinaryRunConfigurationHandler) baseConfiguration.getHandler(); + } + + // @Override Removed #api232 + public LocatableConfigurationBase getTestRecorderRunConfiguration() { + return new TestRecorderBlazeCommandRunConfiguration(myBaseConfiguration); + } + + @Override + public Module getModule() { + return ModuleFinder.getInstance(myBaseConfiguration.getProject()) + .findModuleByName(BlazeDataStorage.WORKSPACE_MODULE_NAME); + } + + @Override + public boolean isLaunchActivitySupported() { + String mode = myBaseConfigurationHandler.getState().getMode(); + + // Supported launch activities are Default and Specified. + return BlazeAndroidBinaryRunConfigurationState.LAUNCH_DEFAULT_ACTIVITY.equals(mode) + || BlazeAndroidBinaryRunConfigurationState.LAUNCH_SPECIFIC_ACTIVITY.equals(mode); + } + + // @Override Removed #api232 + public String getLaunchActivityClass() { + BlazeAndroidBinaryRunConfigurationState state = myBaseConfigurationHandler.getState(); + + if (BlazeAndroidBinaryRunConfigurationState.LAUNCH_SPECIFIC_ACTIVITY.equals(state.getMode())) { + return state.getActivityClass(); + } + + return ""; + } +} diff --git a/aswb/src/com/google/idea/blaze/android/sdk/BlazeSdkProvider.java b/aswb/src/com/google/idea/blaze/android/sdk/BlazeSdkProvider.java index 866351d88ee..2a5e43fe22e 100644 --- a/aswb/src/com/google/idea/blaze/android/sdk/BlazeSdkProvider.java +++ b/aswb/src/com/google/idea/blaze/android/sdk/BlazeSdkProvider.java @@ -15,7 +15,7 @@ */ package com.google.idea.blaze.android.sdk; -import com.intellij.openapi.components.ServiceManager; +import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.projectRoots.Sdk; import java.util.List; import javax.annotation.Nullable; @@ -23,7 +23,7 @@ /** Indirection to Sdks for testing purposes. */ public interface BlazeSdkProvider { static BlazeSdkProvider getInstance() { - return ServiceManager.getService(BlazeSdkProvider.class); + return ApplicationManager.getApplication().getService(BlazeSdkProvider.class); } List getAllAndroidSdks(); diff --git a/aswb/src/com/google/idea/blaze/android/sdk/BlazeSdkProviderImpl.java b/aswb/src/com/google/idea/blaze/android/sdk/BlazeSdkProviderImpl.java index b4481f9ab32..c45d330e9b9 100644 --- a/aswb/src/com/google/idea/blaze/android/sdk/BlazeSdkProviderImpl.java +++ b/aswb/src/com/google/idea/blaze/android/sdk/BlazeSdkProviderImpl.java @@ -16,7 +16,7 @@ package com.google.idea.blaze.android.sdk; import com.android.repository.api.ProgressIndicator; -import com.android.tools.idea.progress.StudioLoggerProgressIndicatorCompat; +import com.android.tools.idea.progress.StudioLoggerProgressIndicator; import com.android.tools.idea.sdk.AndroidSdks; import com.android.tools.idea.sdk.IdeSdks; import com.google.idea.blaze.android.sync.sdk.SdkUtil; @@ -25,7 +25,6 @@ import java.util.List; import javax.annotation.Nullable; import org.jetbrains.android.sdk.AndroidSdkAdditionalData; -import org.jetbrains.android.sdk.AndroidSdkAdditionalDataCompat; /** Indirection to Sdks for testing purposes. */ public class BlazeSdkProviderImpl implements BlazeSdkProvider { @@ -45,7 +44,7 @@ public Sdk findSdk(String targetHash) { // We may have an android platform downloaded, but not created an IntelliJ SDK out of it. // If so, trigger the construction of an SDK ProgressIndicator progress = - new StudioLoggerProgressIndicatorCompat(BlazeSdkProviderImpl.class); + new StudioLoggerProgressIndicator(BlazeSdkProviderImpl.class); androidSdks.tryToChooseSdkHandler().getSdkManager(progress).reloadLocalIfNeeded(progress); return UIUtil.invokeAndWaitIfNeeded( @@ -55,7 +54,7 @@ public Sdk findSdk(String targetHash) { @Override @Nullable public String getSdkTargetHash(Sdk sdk) { - AndroidSdkAdditionalData additionalData = AndroidSdkAdditionalDataCompat.from(sdk); + AndroidSdkAdditionalData additionalData = AndroidSdkAdditionalData.from(sdk); if (additionalData == null) { return null; } diff --git a/aswb/src/com/google/idea/blaze/android/settings/BlazeAndroidUserSettings.java b/aswb/src/com/google/idea/blaze/android/settings/BlazeAndroidUserSettings.java index 81176577075..919c169c9c9 100644 --- a/aswb/src/com/google/idea/blaze/android/settings/BlazeAndroidUserSettings.java +++ b/aswb/src/com/google/idea/blaze/android/settings/BlazeAndroidUserSettings.java @@ -15,8 +15,8 @@ */ package com.google.idea.blaze.android.settings; +import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.components.PersistentStateComponent; -import com.intellij.openapi.components.ServiceManager; import com.intellij.openapi.components.State; import com.intellij.openapi.components.Storage; import com.intellij.util.xmlb.XmlSerializerUtil; @@ -30,7 +30,7 @@ public class BlazeAndroidUserSettings private boolean useLayoutEditor = false; public static BlazeAndroidUserSettings getInstance() { - return ServiceManager.getService(BlazeAndroidUserSettings.class); + return ApplicationManager.getApplication().getService(BlazeAndroidUserSettings.class); } @Override diff --git a/aswb/src/com/google/idea/blaze/android/sync/BlazeAndroidSyncPlugin.java b/aswb/src/com/google/idea/blaze/android/sync/BlazeAndroidSyncPlugin.java index b6fe50b5912..000b39557a8 100644 --- a/aswb/src/com/google/idea/blaze/android/sync/BlazeAndroidSyncPlugin.java +++ b/aswb/src/com/google/idea/blaze/android/sync/BlazeAndroidSyncPlugin.java @@ -15,28 +15,19 @@ */ package com.google.idea.blaze.android.sync; -import static com.google.common.collect.ImmutableSet.toImmutableSet; -import static java.util.stream.Collectors.joining; import com.android.tools.idea.model.AndroidModel; -import com.android.tools.idea.projectsystem.NamedIdeaSourceProvider; -import com.android.tools.idea.projectsystem.NamedIdeaSourceProviderBuilder; -import com.android.tools.idea.projectsystem.ScopeType; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableSet; -import com.google.common.util.concurrent.Futures; import com.google.idea.blaze.android.projectview.AndroidMinSdkSection; import com.google.idea.blaze.android.projectview.AndroidSdkPlatformSection; import com.google.idea.blaze.android.projectview.GeneratedAndroidResourcesSection; -import com.google.idea.blaze.android.resources.BlazeLightResourceClassService; import com.google.idea.blaze.android.sdk.BlazeSdkProvider; import com.google.idea.blaze.android.sync.importer.BlazeAndroidWorkspaceImporter; import com.google.idea.blaze.android.sync.importer.BlazeImportInput; import com.google.idea.blaze.android.sync.model.AndroidSdkPlatform; import com.google.idea.blaze.android.sync.model.BlazeAndroidImportResult; import com.google.idea.blaze.android.sync.model.BlazeAndroidSyncData; -import com.google.idea.blaze.android.sync.model.idea.BlazeAndroidModel; -import com.google.idea.blaze.android.sync.projectstructure.AndroidFacetModuleCustomizer; import com.google.idea.blaze.android.sync.projectstructure.BlazeAndroidProjectStructureSyncer; import com.google.idea.blaze.android.sync.sdk.AndroidSdkFromProjectView; import com.google.idea.blaze.base.ideinfo.TargetMap; @@ -46,11 +37,8 @@ import com.google.idea.blaze.base.model.primitives.LanguageClass; import com.google.idea.blaze.base.model.primitives.WorkspaceRoot; import com.google.idea.blaze.base.model.primitives.WorkspaceType; -import com.google.idea.blaze.base.projectview.ProjectViewManager; import com.google.idea.blaze.base.projectview.ProjectViewSet; import com.google.idea.blaze.base.projectview.section.SectionParser; -import com.google.idea.blaze.base.projectview.section.sections.BuildFlagsSection; -import com.google.idea.blaze.base.qsync.QuerySync; import com.google.idea.blaze.base.scope.BlazeContext; import com.google.idea.blaze.base.scope.Scope; import com.google.idea.blaze.base.scope.output.IssueOutput; @@ -60,12 +48,9 @@ import com.google.idea.blaze.base.sync.SourceFolderProvider; import com.google.idea.blaze.base.sync.SyncMode; import com.google.idea.blaze.base.sync.libraries.LibrarySource; -import com.google.idea.blaze.base.sync.projectview.LanguageSupport; import com.google.idea.blaze.base.sync.projectview.WorkspaceLanguageSettings; import com.google.idea.blaze.base.sync.workspace.ArtifactLocationDecoder; import com.google.idea.blaze.base.sync.workspace.WorkingSet; -import com.google.idea.blaze.common.Context; -import com.google.idea.blaze.java.projectview.JavaLanguageLevelSection; import com.google.idea.blaze.java.sync.JavaLanguageLevelHelper; import com.google.idea.blaze.java.sync.model.BlazeJavaSyncData; import com.google.idea.blaze.java.sync.projectstructure.JavaSourceFolderProvider; @@ -79,16 +64,12 @@ import com.intellij.openapi.roots.LanguageLevelProjectExtension; import com.intellij.openapi.roots.ModifiableRootModel; import com.intellij.openapi.roots.ex.ProjectRootManagerEx; -import com.intellij.openapi.vfs.VfsUtilCore; import com.intellij.pom.java.LanguageLevel; -import com.intellij.util.containers.ContainerUtil; import com.intellij.util.ui.UIUtil; -import java.io.File; import java.util.Collection; import java.util.Set; import javax.annotation.Nullable; import org.jetbrains.android.facet.AndroidFacet; -import org.jetbrains.android.facet.AndroidFacetProperties; /** ASwB sync plugin. */ public class BlazeAndroidSyncPlugin implements BlazeSyncPlugin { @@ -170,24 +151,6 @@ public void updateSyncState( syncStateBuilder.put(new BlazeAndroidSyncData(importResult, androidSdkPlatform)); } - @Override - public void updateProjectSdk(Project project, Context context, ProjectViewSet projectViewSet) { - if (QuerySync.isEnabled()) { - if (!isAndroidWorkspace(LanguageSupport.createWorkspaceLanguageSettings(projectViewSet))) { - return; - } - AndroidSdkPlatform androidSdkPlatform = - AndroidSdkFromProjectView.getAndroidSdkPlatform(context, projectViewSet); - Sdk sdk = BlazeSdkProvider.getInstance().findSdk(androidSdkPlatform.androidSdk); - LanguageLevel javaLanguageLevel = - JavaLanguageLevelSection.getLanguageLevel(projectViewSet, LanguageLevel.JDK_11); - ProjectRootManagerEx rootManager = ProjectRootManagerEx.getInstanceEx(project); - rootManager.setProjectSdk(sdk); - LanguageLevelProjectExtension ext = LanguageLevelProjectExtension.getInstance(project); - ext.setLanguageLevel(javaLanguageLevel); - } - } - @Override public void updateProjectSdk( Project project, @@ -231,66 +194,6 @@ public void updateProjectSdk( setProjectSdkAndLanguageLevel(project, sdk, javaLanguageLevel); } - @Override - public void updateProjectStructure( - Project project, - Context context, - WorkspaceRoot workspaceRoot, - Module workspaceModule, - Set androidResourceDirectories, - Set androidSourcePackages, - WorkspaceLanguageSettings workspaceLanguageSettings) { - - if (!isAndroidWorkspace(workspaceLanguageSettings)) { - return; - } - - // Attach AndroidFacet to workspace modules - AndroidFacetModuleCustomizer.createAndroidFacet(workspaceModule, false); - - // Add all source resource directories to this AndroidFacet - AndroidFacet workspaceFacet = AndroidFacet.getInstance(workspaceModule); - ImmutableSet androidResourceDirectoryFiles = - androidResourceDirectories.stream() - .map(dir -> new File(workspaceRoot.directory(), dir).getAbsoluteFile()) - .collect(toImmutableSet()); - NamedIdeaSourceProvider sourceProvider = - NamedIdeaSourceProviderBuilder.create( - workspaceModule.getName(), VfsUtilCore.fileToUrl(new File("MissingManifest.xml"))) - .withScopeType(ScopeType.MAIN) - .withResDirectoryUrls( - ContainerUtil.map(androidResourceDirectoryFiles, VfsUtilCore::fileToUrl)) - .build(); - - // Set AndroidModel for this AndroidFacet - ProjectViewSet projectViewSet = ProjectViewManager.getInstance(project).getProjectViewSet(); - boolean desugarJava8Libs = - projectViewSet.listItems(BuildFlagsSection.KEY).contains("--config=android_java8_libs"); - AndroidSdkPlatform androidSdkPlatform = - AndroidSdkFromProjectView.getAndroidSdkPlatform(context, projectViewSet); - - BlazeAndroidModel androidModel = - new BlazeAndroidModel( - project, - workspaceRoot.directory(), - sourceProvider, - Futures.immediateFuture(":workspace"), - androidSdkPlatform != null ? androidSdkPlatform.androidMinSdkLevel : 1, - desugarJava8Libs); - AndroidModel.set(workspaceFacet, androidModel); - workspaceFacet.getProperties().RES_FOLDERS_RELATIVE_PATH = - androidResourceDirectoryFiles.stream() - .map(VfsUtilCore::fileToUrl) - .collect(joining(AndroidFacetProperties.PATH_LIST_SEPARATOR_IN_FACET_CONFIGURATION)); - - // Register all source java packages as workspace packages - BlazeLightResourceClassService.Builder rClassBuilder = - new BlazeLightResourceClassService.Builder(project); - rClassBuilder.addWorkspacePackages(androidSourcePackages); - - BlazeLightResourceClassService.getInstance(project).installRClasses(rClassBuilder); - } - @Override public void updateProjectStructure( Project project, diff --git a/aswb/src/com/google/idea/blaze/android/sync/model/AarLibrary.java b/aswb/src/com/google/idea/blaze/android/sync/model/AarLibrary.java index 4e8509bdb53..cdc3b5d008b 100644 --- a/aswb/src/com/google/idea/blaze/android/sync/model/AarLibrary.java +++ b/aswb/src/com/google/idea/blaze/android/sync/model/AarLibrary.java @@ -59,7 +59,7 @@ public final class AarLibrary extends BlazeLibrary { public final ArtifactLocation aarArtifact; // resourcePackage is used to set the resource package of the corresponding ExternalLibrary - // generated by BlazeModuleSystem. Setting resourcePackage to null will create an ExternalLibrary + // generated by BazelModuleSystem. Setting resourcePackage to null will create an ExternalLibrary // that doesn't have its resource package set. // // resourcePackage is null when we don't want to export a resource package for the Aar. This would diff --git a/aswb/src/com/google/idea/blaze/android/sync/model/idea/BlazeAndroidModel.java b/aswb/src/com/google/idea/blaze/android/sync/model/idea/BlazeAndroidModel.java new file mode 100644 index 00000000000..e1344d6a976 --- /dev/null +++ b/aswb/src/com/google/idea/blaze/android/sync/model/idea/BlazeAndroidModel.java @@ -0,0 +1,52 @@ +/* + * Copyright 2020 The Bazel Authors. All rights reserved. + * + * 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. + */ +package com.google.idea.blaze.android.sync.model.idea; + +import com.android.tools.idea.model.AndroidModel; +import com.android.tools.idea.model.Namespacing; +import com.android.tools.idea.projectsystem.NamedIdeaSourceProvider; +import com.google.common.util.concurrent.ListenableFuture; +import com.intellij.openapi.project.Project; +import java.io.File; + +/** Blaze model for an android project */ +public class BlazeAndroidModel extends BlazeAndroidModelBase { + private final NamedIdeaSourceProvider sourceProvider; + + public BlazeAndroidModel( + Project project, + File rootDirPath, + NamedIdeaSourceProvider sourceProvider, + ListenableFuture applicationId, + int minSdkVersion) { + super(project, rootDirPath, applicationId, minSdkVersion); + this.sourceProvider = sourceProvider; + } + + public NamedIdeaSourceProvider getDefaultSourceProvider() { + return sourceProvider; + } + + @Override + public Namespacing getNamespacing() { + return Namespacing.DISABLED; + } + + @Override + protected String uninitializedApplicationId() { + return AndroidModel.UNINITIALIZED_APPLICATION_ID; + } +} diff --git a/aswb/src/com/google/idea/blaze/android/sync/model/idea/BlazeAndroidModelBase.java b/aswb/src/com/google/idea/blaze/android/sync/model/idea/BlazeAndroidModelBase.java index ea9cdfb07a8..8650347a439 100644 --- a/aswb/src/com/google/idea/blaze/android/sync/model/idea/BlazeAndroidModelBase.java +++ b/aswb/src/com/google/idea/blaze/android/sync/model/idea/BlazeAndroidModelBase.java @@ -25,7 +25,8 @@ import com.google.common.collect.ImmutableSet; import com.google.common.util.concurrent.ListenableFuture; import com.google.idea.blaze.base.model.BlazeProjectData; -import com.google.idea.blaze.base.qsync.QuerySync; +import com.google.idea.blaze.base.settings.Blaze; +import com.google.idea.blaze.base.settings.BlazeImportSettings.ProjectType; import com.google.idea.blaze.base.sync.data.BlazeProjectDataManager; import com.google.idea.blaze.base.sync.libraries.LintCollector; import com.intellij.openapi.diagnostic.Logger; @@ -44,18 +45,15 @@ abstract class BlazeAndroidModelBase implements AndroidModel { protected final Project project; private final ListenableFuture applicationId; private final int minSdkVersion; - private final boolean desugarJava8Libs; protected BlazeAndroidModelBase( Project project, File rootDirPath, ListenableFuture applicationId, - int minSdkVersion, - boolean desugarJava8Libs) { + int minSdkVersion) { this.project = project; this.applicationId = applicationId; this.minSdkVersion = minSdkVersion; - this.desugarJava8Libs = desugarJava8Libs; } @Override @@ -112,13 +110,13 @@ public ClassJarProvider getClassJarProvider() { @Override public Set getDesugaring() { - return desugarJava8Libs ? Desugaring.FULL : Desugaring.DEFAULT; + return Desugaring.FULL; } @Override @Nullable public Iterable getLintRuleJarsOverride() { - if (QuerySync.isEnabled()) { + if (Blaze.getProjectType(project) != ProjectType.ASPECT_SYNC) { return ImmutableList.of(); } BlazeProjectData blazeProjectData = diff --git a/aswb/src/com/google/idea/blaze/android/sync/model/idea/BlazeClassJarProvider.java b/aswb/src/com/google/idea/blaze/android/sync/model/idea/BlazeClassJarProvider.java index 82fe2957c73..8fe8e613809 100644 --- a/aswb/src/com/google/idea/blaze/android/sync/model/idea/BlazeClassJarProvider.java +++ b/aswb/src/com/google/idea/blaze/android/sync/model/idea/BlazeClassJarProvider.java @@ -32,7 +32,10 @@ import com.google.idea.blaze.base.ideinfo.TargetKey; import com.google.idea.blaze.base.ideinfo.TargetMap; import com.google.idea.blaze.base.model.BlazeProjectData; -import com.google.idea.blaze.base.qsync.QuerySync; +import com.google.idea.blaze.base.qsync.QuerySyncManager; +import com.google.idea.blaze.base.qsync.RenderJarArtifactTracker; +import com.google.idea.blaze.base.settings.Blaze; +import com.google.idea.blaze.base.settings.BlazeImportSettings.ProjectType; import com.google.idea.blaze.base.sync.data.BlazeProjectDataManager; import com.google.idea.blaze.base.sync.workspace.ArtifactLocationDecoder; import com.google.idea.blaze.base.targetmaps.TransitiveDependencyMap; @@ -67,9 +70,13 @@ public BlazeClassJarProvider(final Project project) { @Override public List getModuleExternalLibraries(Module module) { - // TODO(b/266726517): Query sync does not support render jars. - if (QuerySync.isEnabled()) { - return ImmutableList.of(); + if (Blaze.getProjectType(project) == ProjectType.QUERY_SYNC) { + // As Query Sync has a single workspace module but multiple resource modules + // (TODO(b/283282438): for setting up the resources). All render jars are mapped to the same + // workspace module + RenderJarArtifactTracker renderJarArtifactTracker = + QuerySyncManager.getInstance(project).getRenderJarArtifactTracker(); + return renderJarArtifactTracker.getRenderJars(); } BlazeProjectData blazeProjectData = diff --git a/aswb/src/com/google/idea/blaze/android/sync/projectstructure/AndroidFacetModuleCustomizer.java b/aswb/src/com/google/idea/blaze/android/sync/projectstructure/AndroidFacetModuleCustomizer.java index 7da6e1939a8..4023dca033b 100755 --- a/aswb/src/com/google/idea/blaze/android/sync/projectstructure/AndroidFacetModuleCustomizer.java +++ b/aswb/src/com/google/idea/blaze/android/sync/projectstructure/AndroidFacetModuleCustomizer.java @@ -22,7 +22,6 @@ import com.intellij.openapi.module.Module; import org.jetbrains.android.facet.AndroidFacet; import org.jetbrains.android.facet.AndroidFacetProperties; -import org.jetbrains.android.facet.AndroidFacetPropertiesCompat; /** Adds the Android facet to modules imported from {@link AndroidProject}s. */ public class AndroidFacetModuleCustomizer { @@ -62,6 +61,5 @@ private static void configureFacet(AndroidFacet facet, boolean isApp) { facetState.MANIFEST_FILE_RELATIVE_PATH = ""; facetState.RES_FOLDER_RELATIVE_PATH = ""; facetState.ASSETS_FOLDER_RELATIVE_PATH = ""; - AndroidFacetPropertiesCompat.enableSourcesAutogeneration(facetState, false); } } diff --git a/aswb/src/com/google/idea/blaze/android/sync/projectstructure/BlazeAndroidProjectStructureSyncer.java b/aswb/src/com/google/idea/blaze/android/sync/projectstructure/BlazeAndroidProjectStructureSyncer.java index 2382d6b168e..3fc28c91042 100644 --- a/aswb/src/com/google/idea/blaze/android/sync/projectstructure/BlazeAndroidProjectStructureSyncer.java +++ b/aswb/src/com/google/idea/blaze/android/sync/projectstructure/BlazeAndroidProjectStructureSyncer.java @@ -81,7 +81,6 @@ import java.util.stream.Collectors; import javax.annotation.Nullable; import org.jetbrains.android.facet.AndroidFacet; -import org.jetbrains.android.facet.AndroidFacetProperties; /** Updates the IDE's project structure. */ public class BlazeAndroidProjectStructureSyncer { @@ -112,7 +111,7 @@ public static void updateProjectStructure( if (!isAndroidWorkspace) { AndroidFacetModuleCustomizer.removeAndroidFacet(workspaceModule); // Workspace type should always be ANDROID as long as the blaze android plugin is present. - log.error( + log.warn( "No android workspace found for project \"" + project.getName() + "\". Removing AndroidFacet from workspace module."); @@ -274,15 +273,13 @@ private static void updateInMemoryState( if (androidSdkPlatform == null) { return; } - boolean configAndroidJava8Libs = hasConfigAndroidJava8Libs(projectViewSet); - updateWorkspaceModuleFacetInMemoryState( project, context, workspaceRoot, workspaceModule, - androidSdkPlatform, - configAndroidJava8Libs); + androidSdkPlatform + ); ArtifactLocationDecoder artifactLocationDecoder = blazeProjectData.getArtifactLocationDecoder(); ModuleFinder moduleFinder = ModuleFinder.getInstance(project); @@ -354,8 +351,8 @@ private static void updateInMemoryState( moduleDirectory, manifestFile, modulePackage, - resources, - configAndroidJava8Libs); + resources + ); rClassBuilder.addRClass(modulePackage, module); sourcePackages.remove(modulePackage); } @@ -363,12 +360,6 @@ private static void updateInMemoryState( rClassBuilder.addWorkspacePackages(sourcePackages); } - @VisibleForTesting - static boolean hasConfigAndroidJava8Libs(ProjectViewSet projectViewSet) { - return projectViewSet.listItems(BuildFlagsSection.KEY).stream() - .anyMatch(f -> "--config=android_java8_libs".equals(f)); - } - private static File moduleDirectoryForAndroidTarget( WorkspaceRoot workspaceRoot, TargetIdeInfo target) { return workspaceRoot.fileForPath(target.getKey().getLabel().blazePackage()); @@ -436,8 +427,7 @@ private static void updateWorkspaceModuleFacetInMemoryState( BlazeContext context, WorkspaceRoot workspaceRoot, Module workspaceModule, - AndroidSdkPlatform androidSdkPlatform, - boolean configAndroidJava8Libs) { + AndroidSdkPlatform androidSdkPlatform) { File moduleDirectory = workspaceRoot.directory(); String resourceJavaPackage = ":workspace"; updateModuleFacetInMemoryState( @@ -448,8 +438,8 @@ private static void updateWorkspaceModuleFacetInMemoryState( moduleDirectory, null, resourceJavaPackage, - ImmutableList.of(), - configAndroidJava8Libs); + ImmutableList.of() + ); } private static void updateModuleFacetInMemoryState( @@ -460,8 +450,7 @@ private static void updateModuleFacetInMemoryState( File moduleDirectory, @Nullable File manifestFile, String resourceJavaPackage, - Collection resources, - boolean configAndroidJava8Libs) { + Collection resources) { String name = module.getName(); File manifest = manifestFile != null ? manifestFile : new File("MissingManifest.xml"); NamedIdeaSourceProvider sourceProvider = @@ -487,8 +476,7 @@ private static void updateModuleFacetInMemoryState( moduleDirectory, sourceProvider, applicationId, - androidSdkPlatform.androidMinSdkLevel, - configAndroidJava8Libs); + androidSdkPlatform.androidMinSdkLevel); AndroidFacet facet = AndroidFacet.getInstance(module); if (facet != null) { updateAndroidFacetWithSourceAndModel(facet, sourceProvider, androidModel); @@ -497,11 +485,6 @@ private static void updateModuleFacetInMemoryState( private static void updateAndroidFacetWithSourceAndModel( AndroidFacet facet, NamedIdeaSourceProvider sourceProvider, BlazeAndroidModel androidModel) { - facet.getProperties().RES_FOLDERS_RELATIVE_PATH = - String.join( - AndroidFacetProperties.PATH_LIST_SEPARATOR_IN_FACET_CONFIGURATION, - sourceProvider.getResDirectoryUrls()); - facet.getProperties().TEST_RES_FOLDERS_RELATIVE_PATH = ""; AndroidModel.set(facet, androidModel); } } diff --git a/aswb/src/com/google/idea/blaze/android/sync/qsync/AndroidExternalLibraryManager.java b/aswb/src/com/google/idea/blaze/android/sync/qsync/AndroidExternalLibraryManager.java deleted file mode 100644 index 2a5c0e551e9..00000000000 --- a/aswb/src/com/google/idea/blaze/android/sync/qsync/AndroidExternalLibraryManager.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright 2023 The Bazel Authors. All rights reserved. - * - * 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. - */ -package com.google.idea.blaze.android.sync.qsync; - -import com.android.ide.common.util.PathString; -import com.android.projectmodel.ExternalAndroidLibrary; -import com.android.projectmodel.ExternalLibraryImpl; -import com.android.projectmodel.SelectiveResourceFolder; -import com.google.idea.blaze.android.manifest.ManifestParser; -import com.google.idea.blaze.android.manifest.ManifestParser.ParsedManifest; -import com.intellij.openapi.diagnostic.Logger; -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.nio.file.Path; -import java.util.Collection; -import java.util.HashMap; -import java.util.Map; -import java.util.function.Supplier; -import javax.annotation.Nullable; - -/** Retrieves {@link ExternalAndroidLibrary} for external aars */ -public final class AndroidExternalLibraryManager { - private static final Logger logger = Logger.getInstance(AndroidExternalLibraryManager.class); - - private final Supplier> pathSupplier; - private final Map librariesByPath; - - public AndroidExternalLibraryManager(Supplier> pathSupplier) { - this.pathSupplier = pathSupplier; - this.librariesByPath = new HashMap<>(); - } - - public synchronized Collection getExternalLibraries() { - Collection currentPaths = pathSupplier.get(); - librariesByPath.keySet().retainAll(currentPaths); - - for (Path path : currentPaths) { - // TODO: This assumes that a given dependency will never change over the lifetime of a - // project, which may not always be true. - if (librariesByPath.containsKey(path)) { - continue; - } else { - ExternalAndroidLibrary externalAndroidLibrary = toExternalLibrary(path); - if (externalAndroidLibrary != null) { - librariesByPath.put(path, externalAndroidLibrary); - } - } - } - return librariesByPath.values(); - } - - @Nullable - private static ExternalAndroidLibrary toExternalLibrary(Path libraryPath) { - File aarFile = libraryPath.toFile(); - File manifest = new File(aarFile, "AndroidManifest.xml"); - if (!manifest.exists()) { - logger.warn(String.format("No manifest for library %s", aarFile.getName())); - return null; - } - - String javaPackage; - try (InputStream is = new FileInputStream(manifest)) { - ParsedManifest parsedManifest = ManifestParser.parseManifestFromInputStream(is); - javaPackage = parsedManifest.packageName; - } catch (IOException ioe) { - logger.warn( - String.format("Could not parse package from manifest in library %s", aarFile.getName())); - return null; - } - - PathString resFolderPathString = new PathString(new File(aarFile, "res")); - return new ExternalLibraryImpl(aarFile.getName()) - .withLocation(new PathString(aarFile)) - .withManifestFile(new PathString(manifest)) - .withResFolder(new SelectiveResourceFolder(resFolderPathString, null)) - .withSymbolFile(resFolderPathString.getParentOrRoot().resolve("R.txt")) - .withPackageName(javaPackage); - } -} diff --git a/aswb/src/com/google/idea/blaze/android/sync/sdk/AndroidSdkFromProjectView.java b/aswb/src/com/google/idea/blaze/android/sync/sdk/AndroidSdkFromProjectView.java index 3cd96696b3c..fecc301f3b3 100644 --- a/aswb/src/com/google/idea/blaze/android/sync/sdk/AndroidSdkFromProjectView.java +++ b/aswb/src/com/google/idea/blaze/android/sync/sdk/AndroidSdkFromProjectView.java @@ -15,6 +15,7 @@ */ package com.google.idea.blaze.android.sync.sdk; +import com.android.tools.sdk.AndroidPlatform; import com.google.common.base.Joiner; import com.google.common.collect.Lists; import com.google.common.collect.Sets; @@ -33,10 +34,11 @@ import java.util.List; import java.util.Set; import javax.annotation.Nullable; -import org.jetbrains.android.sdk.AndroidPlatformCompat; +import org.jetbrains.android.sdk.AndroidSdkAdditionalData; /** Calculates AndroidSdkPlatform. */ public final class AndroidSdkFromProjectView { + private static final int DEFAULT_ANDROID_SDK_API_LEVEL = 1; private static final Joiner COMMA_JOINER = Joiner.on(", "); public static final String NO_SDK_ERROR_TEMPLATE = "No such android_sdk_platform: '%s'. " @@ -46,12 +48,12 @@ public final class AndroidSdkFromProjectView { @Nullable public static AndroidSdkPlatform getAndroidSdkPlatform( - Context context, ProjectViewSet projectViewSet) { + Context context, ProjectViewSet projectViewSet) { List sdks = BlazeSdkProvider.getInstance().getAllAndroidSdks(); if (sdks.isEmpty()) { String msg = "No Android SDK configured. Please use the SDK manager to configure."; IssueOutput.error(msg) - .navigatable( + .withNavigatable( new Navigatable() { @Override public void navigate(boolean b) { @@ -133,7 +135,14 @@ private static String getAllAvailableTargetHashes() { } private static int getAndroidSdkApiLevel(Sdk sdk) { - return AndroidPlatformCompat.getApiLevel(sdk); + AndroidSdkAdditionalData additionalData = (AndroidSdkAdditionalData) sdk.getSdkAdditionalData(); + if (additionalData != null) { + AndroidPlatform androidPlatform = additionalData.getAndroidPlatform(); + if (androidPlatform != null) { + return androidPlatform.getApiLevel(); + } + } + return DEFAULT_ANDROID_SDK_API_LEVEL; } private AndroidSdkFromProjectView() {} diff --git a/aswb/src/com/google/idea/blaze/android/sync/sdk/SdkUtil.java b/aswb/src/com/google/idea/blaze/android/sync/sdk/SdkUtil.java index 96525105f35..a4f24dc8fa4 100644 --- a/aswb/src/com/google/idea/blaze/android/sync/sdk/SdkUtil.java +++ b/aswb/src/com/google/idea/blaze/android/sync/sdk/SdkUtil.java @@ -19,6 +19,7 @@ import static com.android.SdkConstants.RES_FOLDER; import com.android.tools.idea.updater.configure.SdkUpdaterConfigurableProvider; +import com.android.tools.sdk.AndroidPlatform; import com.google.idea.blaze.android.projectview.AndroidSdkPlatformSection; import com.google.idea.blaze.android.sdk.BlazeSdkProvider; import com.google.idea.blaze.android.sync.model.BlazeAndroidSyncData; @@ -26,7 +27,8 @@ import com.google.idea.blaze.base.model.BlazeProjectData; import com.google.idea.blaze.base.projectview.ProjectViewManager; import com.google.idea.blaze.base.projectview.ProjectViewSet; -import com.google.idea.blaze.base.qsync.QuerySync; +import com.google.idea.blaze.base.settings.Blaze; +import com.google.idea.blaze.base.settings.BlazeImportSettings.ProjectType; import com.google.idea.blaze.base.sync.data.BlazeProjectDataManager; import com.intellij.openapi.application.Application; import com.intellij.openapi.application.ApplicationManager; @@ -42,8 +44,7 @@ import com.intellij.openapi.vfs.VirtualFile; import com.intellij.util.ui.UIUtil; import java.util.Optional; -import org.jetbrains.android.sdk.AndroidPlatformCompat; -import org.jetbrains.android.sdk.AndroidPlatformsCompat; +import org.jetbrains.android.sdk.AndroidPlatforms; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -54,7 +55,7 @@ public class SdkUtil { @Nullable private static String getAndroidSdkPlatform(Project project, BlazeProjectData blazeProjectData) { // TODO(b/271874279): Retrieve sdk from project data - if (QuerySync.isEnabled()) { + if (Blaze.getProjectType(project) == ProjectType.QUERY_SYNC) { ProjectViewSet projectViewSet = ProjectViewManager.getInstance(project).getProjectViewSet(); if (projectViewSet == null) { return null; @@ -70,7 +71,7 @@ private static String getAndroidSdkPlatform(Project project, BlazeProjectData bl } @Nullable - public static AndroidPlatformCompat getAndroidPlatform(@NotNull Project project) { + public static AndroidPlatform getAndroidPlatform(@NotNull Project project) { BlazeProjectData blazeProjectData = BlazeProjectDataManager.getInstance(project).getBlazeProjectData(); if (blazeProjectData == null) { @@ -84,7 +85,7 @@ public static AndroidPlatformCompat getAndroidPlatform(@NotNull Project project) if (sdk == null) { return null; } - return AndroidPlatformsCompat.getInstance(sdk); + return AndroidPlatforms.getInstance(sdk); } /** Opens the SDK manager settings page */ diff --git a/aswb/src/icons/BlazeAndroidIcons.java b/aswb/src/icons/BlazeAndroidIcons.java index cd986d31632..4b1abc4f374 100644 --- a/aswb/src/icons/BlazeAndroidIcons.java +++ b/aswb/src/icons/BlazeAndroidIcons.java @@ -32,6 +32,6 @@ public class BlazeAndroidIcons { load("aswb/resources/icons/crowToolWindow.png"); // 13x13 private static Icon load(String path) { - return IconLoader.getIcon(BASE + path, BlazeAndroidIcons.class); + return IconLoader.findIcon(BASE + path, BlazeAndroidIcons.class); } } diff --git a/aswb/testdata/projects/BUILD b/aswb/testdata/projects/BUILD new file mode 100644 index 00000000000..2e2588069a0 --- /dev/null +++ b/aswb/testdata/projects/BUILD @@ -0,0 +1,26 @@ +load("@bazel_skylib//rules:build_test.bzl", "build_test") +load("//:build-visibility.bzl", "DEFAULT_TEST_VISIBILITY") + +package( + default_visibility = DEFAULT_TEST_VISIBILITY, +) + +build_test( + name = "test_projects_test", + targets = [ + # TODO: b/335388630 + # "//aswb/testdata/projects/android1/project:test_data_build", + "//aswb/testdata/projects/autovalue:test_data_build", + "//aswb/testdata/projects/cc1:test_data_build", + "//aswb/testdata/projects/cc_genhdr:test_data_build", + "//aswb/testdata/projects/generated1:test_data_build", + "//aswb/testdata/projects/generated2:test_data_build", + "//aswb/testdata/projects/generated3:test_data_build", + "//aswb/testdata/projects/generated_tests:test_data_build", + "//aswb/testdata/projects/javabinaries:test_data_build", + "//aswb/testdata/projects/kotlin1:test_data_build", + "//aswb/testdata/projects/sample1:test_data_build", + "//aswb/testdata/projects/proto1/project:test_data_build", + "//aswb/testdata/projects/src_transform:test_data_build", + ], +) diff --git a/aswb/testdata/projects/android1/external/BUILD b/aswb/testdata/projects/android1/external/BUILD new file mode 100644 index 00000000000..a67d8cdb8e8 --- /dev/null +++ b/aswb/testdata/projects/android1/external/BUILD @@ -0,0 +1,12 @@ +package( + default_visibility = [ + "//aswb/testdata/projects/android1:__subpackages__", + ], +) + +android_library( + name = "lib", + srcs = glob(["lib/java/**/*.java"]), + manifest = "lib/AndroidManifest.xml", + resource_files = glob(["lib/res/**"]), +) diff --git a/aswb/testdata/projects/android1/external/lib/AndroidManifest.xml b/aswb/testdata/projects/android1/external/lib/AndroidManifest.xml new file mode 100644 index 00000000000..d3967f0a1a8 --- /dev/null +++ b/aswb/testdata/projects/android1/external/lib/AndroidManifest.xml @@ -0,0 +1,9 @@ + + + + diff --git a/aswb/testdata/projects/android1/external/lib/java/com/example/external/lib/ExternalGreeter.java b/aswb/testdata/projects/android1/external/lib/java/com/example/external/lib/ExternalGreeter.java new file mode 100644 index 00000000000..79f34616a27 --- /dev/null +++ b/aswb/testdata/projects/android1/external/lib/java/com/example/external/lib/ExternalGreeter.java @@ -0,0 +1,23 @@ +/* + * Copyright 2023 The Bazel Authors. All rights reserved. + * + * 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. + */ +package com.example.external.lib; + +/** A tiny Greeter library for the Bazel Android "Hello, World" app. */ +public class ExternalGreeter { + public String sayHello() { + return "Hello Bazel! \uD83D\uDC4B\uD83C\uDF31"; // Unicode for 👋🌱 + } +} diff --git a/aswb/testdata/projects/android1/external/lib/res/font/just_font.ttf b/aswb/testdata/projects/android1/external/lib/res/font/just_font.ttf new file mode 100644 index 00000000000..59f351b5d2c --- /dev/null +++ b/aswb/testdata/projects/android1/external/lib/res/font/just_font.ttf @@ -0,0 +1 @@ +# just a file \ No newline at end of file diff --git a/aswb/testdata/projects/android1/external/lib/res/values/colors.xml b/aswb/testdata/projects/android1/external/lib/res/values/colors.xml new file mode 100644 index 00000000000..f098c3e1685 --- /dev/null +++ b/aswb/testdata/projects/android1/external/lib/res/values/colors.xml @@ -0,0 +1,5 @@ + + + #FFFFFF + #43A047 + diff --git a/aswb/testdata/projects/android1/external/lib/res/values/strings.xml b/aswb/testdata/projects/android1/external/lib/res/values/strings.xml new file mode 100644 index 00000000000..5621ad60f1c --- /dev/null +++ b/aswb/testdata/projects/android1/external/lib/res/values/strings.xml @@ -0,0 +1,5 @@ + + + Say hello, External! + 🤔 + diff --git a/aswb/testdata/projects/android1/external/lib/res/values/typography.xml b/aswb/testdata/projects/android1/external/lib/res/values/typography.xml new file mode 100644 index 00000000000..85ffa5c73f1 --- /dev/null +++ b/aswb/testdata/projects/android1/external/lib/res/values/typography.xml @@ -0,0 +1,4 @@ + + + @font/just_font + \ No newline at end of file diff --git a/aswb/testdata/projects/android1/project/.bazelproject b/aswb/testdata/projects/android1/project/.bazelproject new file mode 100644 index 00000000000..85d9ae89f04 --- /dev/null +++ b/aswb/testdata/projects/android1/project/.bazelproject @@ -0,0 +1,7 @@ + +directories: + aswb/testdata/projects/android1/project +derive_targets_from_directories: true +android_sdk_platform: android-34 + + diff --git a/aswb/testdata/projects/android1/project/BUILD b/aswb/testdata/projects/android1/project/BUILD new file mode 100644 index 00000000000..151e9439d84 --- /dev/null +++ b/aswb/testdata/projects/android1/project/BUILD @@ -0,0 +1,86 @@ +load( + "//aswb/testdata/projects:test_projects.bzl", + "test_project_package", +) + +package( + default_visibility = ["//src:__subpackages__"], +) + +test_project_package( + name = "test_data", + all_targets = [ + ":app", + ":app_srcs", + #":app_test", + #":app_test_bin", + ":lib", + ":resources", + ], + visibility = [ + "//aswb/testdata/projects:__pkg__", + "//javatests/com/google/devtools/intellij/blaze/plugin/aswb:__pkg__", + ], +) + +android_library( + name = "app_srcs", + srcs = glob(["app/java/**/*.java"]), + exports_manifest = 1, + javacopts = [ + "-source", + "8", + "-target", + "8", + ], + manifest = "app/AndroidManifest.xml", + resource_files = glob(["app/res/**"]), + deps = [ + ":lib", + ":resources", + "//aswb/testdata/projects/android1/external:lib", + ], +) + +android_binary( + name = "app", + manifest = "app/AndroidManifest.xml", + deps = [ + ":app_srcs", + ], +) + +android_library( + name = "lib", + srcs = glob(["lib/java/**/*.java"]), + custom_package = "com.example.bazel", + manifest = "lib/AndroidManifest.xml", + resource_files = glob(["lib/res/**"]), +) + +android_library( + name = "resources", + srcs = [], + manifest = "resources/AndroidManifest.xml", + resource_files = glob(["resources/res/**"]), +) + +# TODO(b/331378322) Re-enable this. +#android_application_test( +# name = "app_test", +# srcs = ["test/javatests/com/example/bazel/AppTest.java"], +# instruments = ":app", +# manifest = "test/AndroidManifest.xml", +# target_devices = [ +# "//tools/android/emulated_devices/generic_phone:android_21_x86", +# ], +# test_class = "com.example.bazel.AppTest", +# deps = [ +# ":app_srcs", +# "//third_party/android/androidx_test/espresso/core", +# "//third_party/android/androidx_test/ext/junit", +# "//third_party/java/android/android_sdk_linux/extras/android/compatibility/v4", +# "//third_party/java/androidx/appcompat", +# "//third_party/java/junit:junit-android", +# ], +#) diff --git a/aswb/testdata/projects/android1/project/app/AndroidManifest.xml b/aswb/testdata/projects/android1/project/app/AndroidManifest.xml new file mode 100644 index 00000000000..36274edab33 --- /dev/null +++ b/aswb/testdata/projects/android1/project/app/AndroidManifest.xml @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + diff --git a/aswb/testdata/projects/android1/project/app/java/com/example/bazel/MainActivity.java b/aswb/testdata/projects/android1/project/app/java/com/example/bazel/MainActivity.java new file mode 100644 index 00000000000..ae1c0ac0caa --- /dev/null +++ b/aswb/testdata/projects/android1/project/app/java/com/example/bazel/MainActivity.java @@ -0,0 +1,45 @@ +/* + * Copyright 2023 The Bazel Authors. All rights reserved. + * + * 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. + */ +package com.example.bazel; + +import android.app.Activity; +import android.os.Bundle; +import android.util.Log; +import android.widget.Button; +import android.widget.TextView; +import com.example.external.lib.ExternalGreeter; +import com.example.lib.Greeter; + +/** Main class for the Bazel Android "Hello, World" app. */ +public class MainActivity extends Activity { + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + Log.v("Bazel", "Hello, Android"); + + setContentView(R.layout.activity_main); + + Button clickMeButton = findViewById(R.id.clickMeButton); + Button clickMeButtonExternal = findViewById(R.id.clickMeButtonExternal); + TextView helloBazelTextView = findViewById(R.id.helloBazelTextView); + + Greeter greeter = new Greeter(); + ExternalGreeter externalGreeter = new ExternalGreeter(); + + // Bazel supports Java 8 language features like lambdas! + clickMeButton.setOnClickListener(v -> helloBazelTextView.setText(greeter.sayHello())); + } +} diff --git a/aswb/testdata/projects/android1/project/app/java/com/example/bazel/pkg1/ScopedResourceActivity.java b/aswb/testdata/projects/android1/project/app/java/com/example/bazel/pkg1/ScopedResourceActivity.java new file mode 100644 index 00000000000..4d34faf9ab1 --- /dev/null +++ b/aswb/testdata/projects/android1/project/app/java/com/example/bazel/pkg1/ScopedResourceActivity.java @@ -0,0 +1,30 @@ +/* + * Copyright 2023 The Bazel Authors. All rights reserved. + * + * 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. + */ +package com.example.bazel.pkg1; + +import android.app.Activity; +import android.os.Bundle; +import android.util.Log; +import com.example.bazel.resources.R; + +/** Class consuming resources from a specific library. */ +public class ScopedResourceActivity extends Activity { + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + Log.v("Bazel", getResources().getString(R.string.resource_lib_string)); + } +} diff --git a/aswb/testdata/projects/android1/project/app/res/layout/activity_main.xml b/aswb/testdata/projects/android1/project/app/res/layout/activity_main.xml new file mode 100644 index 00000000000..f208f3be11f --- /dev/null +++ b/aswb/testdata/projects/android1/project/app/res/layout/activity_main.xml @@ -0,0 +1,37 @@ + + + + + +