@frankzhang2026/opencode-android-orchestrator 1.2.0 → 1.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +11 -0
- package/README.md +8 -7
- package/dist/installer/capabilities-script.d.ts.map +1 -1
- package/dist/installer/capabilities-script.js +4 -1
- package/dist/installer/capabilities-script.js.map +1 -1
- package/dist/installer/opencode-config.d.ts +3 -3
- package/dist/installer/opencode-config.js +1 -1
- package/docs/GRADLE-6.7.1.md +2 -1
- package/docs/MIGRATION.md +19 -10
- package/docs/QUEUE.md +2 -2
- package/docs/SECURITY.md +1 -1
- package/docs/TROUBLESHOOTING.md +7 -7
- package/package.json +1 -1
- package/templates/automation/verification/collect.init.gradle +49 -35
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,16 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 1.2.1 - 2026-10-09
|
|
4
|
+
|
|
5
|
+
Fixes Android lazy test-output compatibility.
|
|
6
|
+
|
|
7
|
+
- Avoid resolving Android test output providers during project discovery, fixing
|
|
8
|
+
upgrades on builds with mapped ASM test-class outputs.
|
|
9
|
+
- Collect test directory evidence immediately before each Test task executes,
|
|
10
|
+
after producer tasks complete, while retaining skipped/NO-SOURCE validation.
|
|
11
|
+
- Add real Gradle regression coverage for mapped test outputs through discovery
|
|
12
|
+
and baseline/RED/GREEN inventory collection.
|
|
13
|
+
|
|
3
14
|
## 1.2.0 - 2026-10-09
|
|
4
15
|
|
|
5
16
|
- Fix Gradle 6.7.1 init-script request handling and dynamic legacy Kotlin source
|
package/README.md
CHANGED
|
@@ -2,8 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
Reusable OpenCode orchestration for macOS Android projects.
|
|
4
4
|
|
|
5
|
-
Version 1.2.
|
|
6
|
-
|
|
5
|
+
Version 1.2.1 fixes discovery and test collection with lazy Android test outputs.
|
|
6
|
+
The commands below pin the 1.2.1 npm package.
|
|
7
|
+
See [development validation](release/1.2.1-development-validation.md) for evidence.
|
|
7
8
|
|
|
8
9
|
Version `0.2.0` is the first published lifecycle release. Version `0.3.0` adds
|
|
9
10
|
default all-module orchestration and stronger verification contracts. Version
|
|
@@ -79,9 +80,9 @@ project builds retain their configured cache behavior.
|
|
|
79
80
|
## Quick start
|
|
80
81
|
|
|
81
82
|
```sh
|
|
82
|
-
npx @frankzhang2026/opencode-android-orchestrator@1.2.
|
|
83
|
+
npx @frankzhang2026/opencode-android-orchestrator@1.2.1 init .
|
|
83
84
|
$EDITOR automation/automation-commit-prefix
|
|
84
|
-
npx @frankzhang2026/opencode-android-orchestrator@1.2.
|
|
85
|
+
npx @frankzhang2026/opencode-android-orchestrator@1.2.1 doctor .
|
|
85
86
|
opencode --agent scheduled-planner .
|
|
86
87
|
```
|
|
87
88
|
|
|
@@ -91,7 +92,7 @@ a task contract without selecting a primary module. To intentionally restrict
|
|
|
91
92
|
generated contracts to one module, opt into primary-module scope:
|
|
92
93
|
|
|
93
94
|
```sh
|
|
94
|
-
npx @frankzhang2026/opencode-android-orchestrator@1.2.
|
|
95
|
+
npx @frankzhang2026/opencode-android-orchestrator@1.2.1 init . \
|
|
95
96
|
--module-scope primary \
|
|
96
97
|
--primary-module :mobile
|
|
97
98
|
```
|
|
@@ -119,7 +120,7 @@ For an existing manifest-managed installation whose generated module/task
|
|
|
119
120
|
lists are incomplete, refresh all derived Gradle data in one upgrade:
|
|
120
121
|
|
|
121
122
|
```sh
|
|
122
|
-
npx @frankzhang2026/opencode-android-orchestrator@1.2.
|
|
123
|
+
npx @frankzhang2026/opencode-android-orchestrator@1.2.1 upgrade . \
|
|
123
124
|
--refresh-gradle-discovery
|
|
124
125
|
```
|
|
125
126
|
|
|
@@ -476,7 +477,7 @@ preparation alone as resource installation;
|
|
|
476
477
|
## Init
|
|
477
478
|
|
|
478
479
|
```sh
|
|
479
|
-
npx @frankzhang2026/opencode-android-orchestrator@1.2.
|
|
480
|
+
npx @frankzhang2026/opencode-android-orchestrator@1.2.1 init .
|
|
480
481
|
$EDITOR automation/automation-commit-prefix
|
|
481
482
|
opencode --agent scheduled-planner .
|
|
482
483
|
```
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"capabilities-script.d.ts","sourceRoot":"","sources":["../../src/installer/capabilities-script.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,wBAAwB,
|
|
1
|
+
{"version":3,"file":"capabilities-script.d.ts","sourceRoot":"","sources":["../../src/installer/capabilities-script.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,wBAAwB,QAmFpC,CAAC"}
|
|
@@ -41,7 +41,10 @@ gradle.projectsEvaluated {
|
|
|
41
41
|
def sourceSets = androidId != null ? get(extension, "sourceSets") : p.extensions.findByName("sourceSets")
|
|
42
42
|
if (sourceSets == null) throw new GradleException("Cannot inspect source sets for " + key)
|
|
43
43
|
def tests = p.tasks.withType(org.gradle.api.tasks.testing.Test).toList()
|
|
44
|
-
|
|
44
|
+
// Android source sets are classified by name below. Their test output
|
|
45
|
+
// providers may depend on ASM transforms that have not executed yet.
|
|
46
|
+
def testOutputs = androidId != null ? ([] as Set) :
|
|
47
|
+
(tests.collectMany { it.testClassesDirs.files.toList() }.collect { it.canonicalPath } as Set)
|
|
45
48
|
def buildDir = p.layout.buildDirectory.get().asFile.canonicalFile.toPath()
|
|
46
49
|
def pathOf = { File file ->
|
|
47
50
|
def absolute = file.absoluteFile.toPath().normalize()
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"capabilities-script.js","sourceRoot":"","sources":["../../src/installer/capabilities-script.ts"],"names":[],"mappings":"AAAA,6EAA6E;AAC7E,4EAA4E;AAC5E,MAAM,CAAC,MAAM,wBAAwB,GAAG,MAAM,CAAC,GAAG,CAAA
|
|
1
|
+
{"version":3,"file":"capabilities-script.js","sourceRoot":"","sources":["../../src/installer/capabilities-script.ts"],"names":[],"mappings":"AAAA,6EAA6E;AAC7E,4EAA4E;AAC5E,MAAM,CAAC,MAAM,wBAAwB,GAAG,MAAM,CAAC,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAmFjD,CAAC"}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
export declare const ORCHESTRATOR_PACKAGE_NAME = "@frankzhang2026/opencode-android-orchestrator";
|
|
2
|
-
export declare const ORCHESTRATOR_PACKAGE_VERSION = "1.2.
|
|
3
|
-
export declare const ORCHESTRATOR_PLUGIN_REFERENCE = "@frankzhang2026/opencode-android-orchestrator@1.2.
|
|
2
|
+
export declare const ORCHESTRATOR_PACKAGE_VERSION = "1.2.1";
|
|
3
|
+
export declare const ORCHESTRATOR_PLUGIN_REFERENCE = "@frankzhang2026/opencode-android-orchestrator@1.2.1";
|
|
4
4
|
export declare const OPENCODE_CONFIG_SCHEMA_URL = "https://opencode.ai/config.json";
|
|
5
|
-
export declare const REQUIRED_PLUGIN_REFERENCES: readonly ["@frankzhang2026/opencode-android-orchestrator@1.2.
|
|
5
|
+
export declare const REQUIRED_PLUGIN_REFERENCES: readonly ["@frankzhang2026/opencode-android-orchestrator@1.2.1"];
|
|
6
6
|
export type OpenCodeConfigMergeErrorCode = "AMBIGUOUS_CONFIG" | "CONFIG_NOT_FILE" | "CONFIG_READ_FAILED" | "CONFIG_SYMLINK" | "DUPLICATE_PLUGIN" | "DUPLICATE_PROPERTY" | "INVALID_JSONC" | "INVALID_PLUGIN_ENTRY" | "PLUGIN_NOT_ARRAY" | "PLUGIN_VERSION_CONFLICT" | "ROOT_NOT_OBJECT" | "TARGET_NOT_DIRECTORY";
|
|
7
7
|
export declare class OpenCodeConfigMergeError extends Error {
|
|
8
8
|
readonly code: OpenCodeConfigMergeErrorCode;
|
|
@@ -2,7 +2,7 @@ import { lstatSync, readFileSync, statSync } from "node:fs";
|
|
|
2
2
|
import { join, resolve } from "node:path";
|
|
3
3
|
import { applyEdits, findNodeAtLocation, getNodeValue, modify, parseTree, printParseErrorCode, } from "jsonc-parser";
|
|
4
4
|
export const ORCHESTRATOR_PACKAGE_NAME = "@frankzhang2026/opencode-android-orchestrator";
|
|
5
|
-
export const ORCHESTRATOR_PACKAGE_VERSION = "1.2.
|
|
5
|
+
export const ORCHESTRATOR_PACKAGE_VERSION = "1.2.1";
|
|
6
6
|
export const ORCHESTRATOR_PLUGIN_REFERENCE = `${ORCHESTRATOR_PACKAGE_NAME}@${ORCHESTRATOR_PACKAGE_VERSION}`;
|
|
7
7
|
export const OPENCODE_CONFIG_SCHEMA_URL = "https://opencode.ai/config.json";
|
|
8
8
|
export const REQUIRED_PLUGIN_REFERENCES = [
|
package/docs/GRADLE-6.7.1.md
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
# Gradle 6.7.1 review fixes (1.2.0)
|
|
2
2
|
|
|
3
3
|
These changes are included in 1.2.0 and are absent from
|
|
4
|
-
1.1.0.
|
|
4
|
+
1.1.0. Use the pinned 1.2.1 package, including the lazy Android
|
|
5
|
+
test-output compatibility fix. Do not copy individual
|
|
5
6
|
managed files into an existing installation or reuse evidence made with the
|
|
6
7
|
previous collector. Keep existing evidence and approve a new task after upgrade.
|
|
7
8
|
|
package/docs/MIGRATION.md
CHANGED
|
@@ -1,9 +1,18 @@
|
|
|
1
1
|
# Migration guide
|
|
2
2
|
|
|
3
3
|
This guide covers migration to
|
|
4
|
-
`@frankzhang2026/opencode-android-orchestrator@1.2.
|
|
4
|
+
`@frankzhang2026/opencode-android-orchestrator@1.2.1`. Pin the exact version and
|
|
5
5
|
prove the migration in a disposable clone before changing a long-lived
|
|
6
|
-
repository.
|
|
6
|
+
repository.
|
|
7
|
+
|
|
8
|
+
## 1.2.1 lazy test-output compatibility
|
|
9
|
+
|
|
10
|
+
Version 1.2.1 avoids reading Android test output providers during discovery and
|
|
11
|
+
collects test output metadata only when each test task is about to execute, after
|
|
12
|
+
its producer tasks have completed. This supports mapped outputs such as ASM test
|
|
13
|
+
class transforms. Finish or abort active work before upgrading, preserve old
|
|
14
|
+
evidence and approve new tasks with the updated collector. Use
|
|
15
|
+
`upgrade --refresh-gradle-discovery` to refresh the module and source model.
|
|
7
16
|
|
|
8
17
|
## 1.2.0 compatibility and evidence upgrade
|
|
9
18
|
|
|
@@ -23,10 +32,10 @@ protocol boundaries.
|
|
|
23
32
|
|
|
24
33
|
| Current state | Correct command | Important distinction |
|
|
25
34
|
| --- | --- | --- |
|
|
26
|
-
| No orchestrator files or manifest | `npx @frankzhang2026/opencode-android-orchestrator@1.2.
|
|
35
|
+
| No orchestrator files or manifest | `npx @frankzhang2026/opencode-android-orchestrator@1.2.1 init .` | Normal new installation; all runtime-detected Android modules and registered debug verification tasks are discovered automatically. |
|
|
27
36
|
| Published `0.1.0` scaffold only | Remove any project-local `@0.1.0` plugin reference after review, then run `init`. | `0.1.0` did not create a usable managed installation and cannot be upgraded. |
|
|
28
|
-
| `0.2.0` through `0.10.0` manifest-managed installation with intact managed/backup content | Run the `1.2.
|
|
29
|
-
| Healthy `1.0.0` through `1.
|
|
37
|
+
| `0.2.0` through `0.10.0` manifest-managed installation with intact managed/backup content | Run the `1.2.1` `upgrade`; add `--refresh-gradle-discovery` when generated module/task lists are incomplete. | Refresh replaces all derived module metadata, source paths, protected build files, and task allowlists from one Gradle runtime snapshot. Module scope, operator policies, user-owned AGENTS content, and an existing commit-prefix sidecar remain preserved. |
|
|
38
|
+
| Healthy `1.0.0` through `1.2.0` installation | Stop the queue service, finish or abort retained workspaces, then run the fixed `1.2.1` `upgrade`. | Pending inbox contracts remain durable. Version 1.1.0 adds V4 test inventories, opt-in V5-V8 recovery/continuity and Android build capabilities; older approved contracts retain their authority. |
|
|
30
39
|
| Manually copied V3 files, no `.automation-plugin/manifest.json` | Finish active tasks, preserve historical evidence separately, then run `init`. | Exact files can be reused; differing managed files fail as conflicts. |
|
|
31
40
|
| Healthy older manifest-managed installation | Run `doctor`, then the fixed target version's `upgrade`. | `upgrade` requires a valid installed manifest and intact original backups. |
|
|
32
41
|
| Healthy current-version manifest | Run `doctor`; repeated `init` or same-version `upgrade` is verification-only and byte-idempotent. | Do not reinstall or delete the manifest. |
|
|
@@ -72,7 +81,7 @@ installation of `0.1.0` alone does not require project-file cleanup.
|
|
|
72
81
|
Initialize with the fixed version:
|
|
73
82
|
|
|
74
83
|
```sh
|
|
75
|
-
npx @frankzhang2026/opencode-android-orchestrator@1.2.
|
|
84
|
+
npx @frankzhang2026/opencode-android-orchestrator@1.2.1 init .
|
|
76
85
|
```
|
|
77
86
|
|
|
78
87
|
New installations default to all-module scope, so multiple application modules
|
|
@@ -120,7 +129,7 @@ Use the lifecycle command selected by the active manifest:
|
|
|
120
129
|
|
|
121
130
|
```sh
|
|
122
131
|
npx --yes --registry=https://registry.npmjs.org/ \
|
|
123
|
-
@frankzhang2026/opencode-android-orchestrator@1.2.
|
|
132
|
+
@frankzhang2026/opencode-android-orchestrator@1.2.1 upgrade . --json
|
|
124
133
|
```
|
|
125
134
|
|
|
126
135
|
The command-level Registry option is useful when a company-wide npm Registry
|
|
@@ -150,7 +159,7 @@ computed includes dynamically or a company convention plugin applied
|
|
|
150
159
|
|
|
151
160
|
```sh
|
|
152
161
|
npx --yes --registry=https://registry.npmjs.org/ \
|
|
153
|
-
@frankzhang2026/opencode-android-orchestrator@1.2.
|
|
162
|
+
@frankzhang2026/opencode-android-orchestrator@1.2.1 upgrade . \
|
|
154
163
|
--refresh-gradle-discovery --json
|
|
155
164
|
```
|
|
156
165
|
|
|
@@ -234,7 +243,7 @@ use the queue rather than the old direct Shell commands. See [Queue operation](Q
|
|
|
234
243
|
Run all checks from the detected Git root:
|
|
235
244
|
|
|
236
245
|
```sh
|
|
237
|
-
npx @frankzhang2026/opencode-android-orchestrator@1.2.
|
|
246
|
+
npx @frankzhang2026/opencode-android-orchestrator@1.2.1 doctor .
|
|
238
247
|
opencode debug config
|
|
239
248
|
opencode debug skill
|
|
240
249
|
opencode debug agent scheduled-planner
|
|
@@ -339,7 +348,7 @@ Reviewer verification commands can retry identified environment failures within
|
|
|
339
348
|
separate persisted budgets; model/provider calls and integration are unchanged.
|
|
340
349
|
Recovery logic extends the existing managed recovery.cjs. Version 1.1.0 has
|
|
341
350
|
52 managed resources, including the Android project capability validator.
|
|
342
|
-
Upgrade with 1.2.
|
|
351
|
+
Upgrade with 1.2.1; same-version upgrade does not refresh
|
|
343
352
|
managed templates. See the V7 policy and retained-evidence workflow in QUEUE.md.
|
|
344
353
|
|
|
345
354
|
|
package/docs/QUEUE.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Queue and background execution
|
|
2
2
|
|
|
3
|
-
Version `1.2.
|
|
3
|
+
Version `1.2.1` stores proposals and approved contracts under
|
|
4
4
|
`<git-common-dir>/automation-runtime/inbox/queue.json`. A contract is runnable
|
|
5
5
|
only after its full plan, version, digest, target branch and commit policy are
|
|
6
6
|
approved and durably recorded. Planning reads a fixed `planningHead`, so another
|
|
@@ -134,7 +134,7 @@ It does not run `clean` or rerun all dependency tasks. Coder, Reviewer and local
|
|
|
134
134
|
integration perform the configured full suite and build gates. Evidence records
|
|
135
135
|
fresh-test logs, configured tasks and elapsed seconds.
|
|
136
136
|
|
|
137
|
-
The 1.2.
|
|
137
|
+
The 1.2.1 templates generate task-contract schema V4 with verification
|
|
138
138
|
version 2. The 1.0.5 package
|
|
139
139
|
does not include this protocol. Every verification case
|
|
140
140
|
has a stable ID, a one-based acceptance-criterion reference, an evidence source,
|
package/docs/SECURITY.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# Security model
|
|
2
2
|
|
|
3
3
|
This document describes the security properties of
|
|
4
|
-
`@frankzhang2026/opencode-android-orchestrator@1.2.
|
|
4
|
+
`@frankzhang2026/opencode-android-orchestrator@1.2.1`. The lifecycle foundation
|
|
5
5
|
completed the real OpenCode `1.14.22` and `1.15.13` release matrix in `0.2.0`;
|
|
6
6
|
`1.0.0` retains that compatibility boundary.
|
|
7
7
|
|
package/docs/TROUBLESHOOTING.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# Troubleshooting
|
|
2
2
|
|
|
3
3
|
Use this guide for
|
|
4
|
-
`@frankzhang2026/opencode-android-orchestrator@1.2.
|
|
4
|
+
`@frankzhang2026/opencode-android-orchestrator@1.2.1`.
|
|
5
5
|
|
|
6
6
|
## Start with read-only evidence
|
|
7
7
|
|
|
@@ -11,7 +11,7 @@ From the repository root, capture:
|
|
|
11
11
|
git status --short --branch
|
|
12
12
|
git rev-parse HEAD
|
|
13
13
|
opencode --version
|
|
14
|
-
npx @frankzhang2026/opencode-android-orchestrator@1.2.
|
|
14
|
+
npx @frankzhang2026/opencode-android-orchestrator@1.2.1 doctor . --json
|
|
15
15
|
```
|
|
16
16
|
|
|
17
17
|
If installation never completed, doctor will correctly report a missing or
|
|
@@ -51,9 +51,9 @@ command-scoped override:
|
|
|
51
51
|
|
|
52
52
|
```sh
|
|
53
53
|
npm --registry=https://registry.npmjs.org/ view \
|
|
54
|
-
@frankzhang2026/opencode-android-orchestrator@1.2.
|
|
54
|
+
@frankzhang2026/opencode-android-orchestrator@1.2.1 version
|
|
55
55
|
npx --yes --registry=https://registry.npmjs.org/ \
|
|
56
|
-
@frankzhang2026/opencode-android-orchestrator@1.2.
|
|
56
|
+
@frankzhang2026/opencode-android-orchestrator@1.2.1 upgrade . --json
|
|
57
57
|
```
|
|
58
58
|
|
|
59
59
|
This leaves the company's saved npm configuration unchanged. Use the option
|
|
@@ -83,7 +83,7 @@ Git-backed Superpowers plugin at runtime.
|
|
|
83
83
|
| Invalid `--long-command-timeout-ms` | The value is not an integer from `120000` through `7200000`. | Use the `1800000` ms default or pass an intentional bounded value to `init`/`upgrade`; do not edit the generated config directly. |
|
|
84
84
|
| Android SDK failure | No valid explicit SDK, `ANDROID_HOME`, `ANDROID_SDK_ROOT`, or `local.properties` `sdk.dir` was found. | Configure one real SDK root containing `platforms/` and `build-tools/`. Do not publish `local.properties`. |
|
|
85
85
|
| Missing `git`, `jq`, `rg`, `shasum`, or Java | Required deterministic command is unavailable on `PATH`. | Install or restore the missing command, record its version, and rerun the read-only checks. |
|
|
86
|
-
| `Bundled Orchestrator skill is unavailable` | The installed `1.2.
|
|
86
|
+
| `Bundled Orchestrator skill is unavailable` | The installed `1.2.1` package is incomplete, damaged, or loaded from an unsupported partial copy. | Reinstall the exact package, inspect its `resources/third-party/superpowers-v6.2.0/skills/` entries, restart OpenCode, and rerun `opencode debug skill`. Do not add an external Superpowers plugin as a fallback. |
|
|
87
87
|
| `current process does not own this task queue execution` immediately after Coder start on 1.0.1 | OpenCode created the tool shell in a separate process group, so 1.0.1 rejected a legitimate Worker descendant. | Upgrade to 1.0.2 or later, restart OpenCode, then use the approved resume or abort workflow for the retained task. Do not edit the queue or lease files. |
|
|
88
88
|
| The exact Superpowers v6.2.0 plugin remains after upgrade | That entry existed in the verified pre-install OpenCode file and is therefore user-owned. | Leave it in place or remove it as a separate reviewed configuration change. Upgrade only removes the old Orchestrator-managed entry. |
|
|
89
89
|
|
|
@@ -100,7 +100,7 @@ silence of `./gradlew tasks --all --console=plain | rg ...` in a large build.
|
|
|
100
100
|
For an existing installation, run:
|
|
101
101
|
|
|
102
102
|
```sh
|
|
103
|
-
npx @frankzhang2026/opencode-android-orchestrator@1.2.
|
|
103
|
+
npx @frankzhang2026/opencode-android-orchestrator@1.2.1 upgrade . \
|
|
104
104
|
--refresh-gradle-discovery
|
|
105
105
|
```
|
|
106
106
|
|
|
@@ -109,7 +109,7 @@ least `1800000` milliseconds. A higher timeout already supplied by the caller
|
|
|
109
109
|
is preserved; unrelated Bash commands are unchanged. To configure one hour,
|
|
110
110
|
run `upgrade . --long-command-timeout-ms 3600000` on a healthy installation.
|
|
111
111
|
If a command still reports `120000 ms`, confirm that the project manifest and
|
|
112
|
-
OpenCode plugin reference are both `1.2.
|
|
112
|
+
OpenCode plugin reference are both `1.2.1`, restart the OpenCode session so the
|
|
113
113
|
plugin reloads, and rerun doctor before attempting recovery.
|
|
114
114
|
|
|
115
115
|
After installation, inspect OpenCode discovery separately:
|
package/package.json
CHANGED
|
@@ -27,46 +27,56 @@ append([kind: 'start', phase: request.phase, gradleVersion: gradle.gradleVersion
|
|
|
27
27
|
def filtersByTask = request.targets.groupBy { it.gradleTask }.collectEntries { path, targets ->
|
|
28
28
|
[(path): targets.collect { it.filter }.unique().sort()]
|
|
29
29
|
}
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
30
|
+
// Keep dry-run source discovery independent of Android output providers.
|
|
31
|
+
// Real output metadata is collected after producer tasks have executed.
|
|
32
|
+
def recordTask = { task, boolean discovery ->
|
|
33
|
+
def path = task.path
|
|
34
|
+
def filters = filtersByTask[path]
|
|
35
|
+
def roots = [] as Set
|
|
36
|
+
def android = task.project.extensions.findByName('android')
|
|
37
|
+
// Dry-run discovery cannot execute producer tasks. Android source roots
|
|
38
|
+
// come from its DSL; class-output paths are recorded on the real run.
|
|
39
|
+
def classes = discovery && android != null ? ([] as Set) :
|
|
40
|
+
(task.testClassesDirs.files.collect { it.canonicalFile } as Set)
|
|
41
|
+
def sourceSets = android == null ? task.project.extensions.findByName('sourceSets') : null
|
|
42
|
+
sourceSets?.each { sourceSet ->
|
|
43
|
+
if (sourceSet.output.classesDirs.files.any { classes.contains(it.canonicalFile) }) {
|
|
44
|
+
roots.addAll(sourceSet.allSource.srcDirs)
|
|
45
|
+
roots.addAll(sourceSet.resources.srcDirs)
|
|
42
46
|
}
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
}
|
|
47
|
+
}
|
|
48
|
+
// AGP variants expose the source providers actually used by each unit test.
|
|
49
|
+
if (android != null && android.hasProperty('unitTestVariants')) {
|
|
50
|
+
android.unitTestVariants.each { variant ->
|
|
51
|
+
if (task.name == "test${variant.name.capitalize()}") {
|
|
52
|
+
variant.sourceSets.each { provider ->
|
|
53
|
+
roots.addAll(provider.javaDirectories)
|
|
54
|
+
roots.addAll(provider.resourcesDirectories)
|
|
55
|
+
if (provider.hasProperty('kotlinDirectories')) roots.addAll(provider.kotlinDirectories)
|
|
53
56
|
}
|
|
54
57
|
}
|
|
55
58
|
}
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
59
|
+
}
|
|
60
|
+
// Modern AGP also exposes variant-specific test source sets through its DSL.
|
|
61
|
+
// Only unit-test providers are classified here, never production providers.
|
|
62
|
+
if (android != null && android.hasProperty('sourceSets')) {
|
|
63
|
+
android.sourceSets.findAll { it.name == 'test' || it.name.startsWith('test') && it.name.length() > 4 && Character.isUpperCase(it.name.charAt(4)) }.each { sourceSet ->
|
|
64
|
+
roots.addAll(sourceSet.java.srcDirs)
|
|
65
|
+
roots.addAll(sourceSet.resources.srcDirs)
|
|
66
|
+
if (sourceSet.hasProperty('kotlin')) roots.addAll(sourceSet.kotlin.srcDirs)
|
|
67
|
+
roots.addAll(sourceSet.assets.srcDirs)
|
|
68
|
+
roots.addAll(sourceSet.res.srcDirs)
|
|
66
69
|
}
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
+
}
|
|
71
|
+
append([kind: 'task', taskPath: path, filters: filters,
|
|
72
|
+
sourceRoots: roots.collect { it.absoluteFile.toPath().normalize().toString() }.sort(),
|
|
73
|
+
testClassesDirs: classes.collect { it.toString() }.sort()])
|
|
74
|
+
}
|
|
75
|
+
gradle.taskGraph.whenReady { graph ->
|
|
76
|
+
filtersByTask.each { path, filters ->
|
|
77
|
+
def task = graph.allTasks.find { it.path == path }
|
|
78
|
+
if (!(task instanceof Test)) throw new GradleException("Inventory target must resolve to an exact Test task: ${path}")
|
|
79
|
+
if (gradle.startParameter.dryRun) recordTask(task, true)
|
|
70
80
|
task.outputs.upToDateWhen { false }
|
|
71
81
|
task.outputs.doNotCacheIf('Orchestrator inventory requires actual test execution') { true }
|
|
72
82
|
task.ignoreFailures = true
|
|
@@ -97,6 +107,10 @@ gradle.taskGraph.whenReady { graph ->
|
|
|
97
107
|
})
|
|
98
108
|
}
|
|
99
109
|
}
|
|
110
|
+
// beforeTask also records skipped/NO-SOURCE tasks for inventory validation.
|
|
111
|
+
gradle.taskGraph.beforeTask { task ->
|
|
112
|
+
if (filtersByTask.containsKey(task.path)) recordTask(task, false)
|
|
113
|
+
}
|
|
100
114
|
gradle.taskGraph.afterTask { task, state ->
|
|
101
115
|
if (filtersByTask.containsKey(task.path)) append([kind: 'taskEnd', taskPath: task.path,
|
|
102
116
|
executed: state.executed, skipped: state.skipped, noSource: state.noSource,
|