Tomacco

Docs Operation reference project operations

project operations#

11 operations. Generated from assets/operations.json; all areas.

On this page (11)

project.inspect#

Open project

Detect frameworks and available platforms without executing project code. For a Gradle build, android lists each app module's application ID, namespace, min, target and compile SDK, build types, flavors and variants as read from the build files and versions catalog; values only Gradle can compute are listed under unresolved. test_setup lists per Gradle module the coverage the build files enable (unit_test_coverage, android_test_coverage, kover, jacoco_plugin) and its Gradle Managed Devices and groups.

Annotations: read-only, idempotent, open world.

ArgumentTypeRequiredDefaultDetails
pathstringyesnon-empty; Absolute local filesystem path
tomaccoctl call project.inspect '{"path":"<path>"}'

project.configure#

Configure project

Save the deployment application ID and explicit command-array tasks; update xtool's bundleID when applicable.

Annotations: destructive, idempotent, open world.

ArgumentTypeRequiredDefaultDetails
pathstringyesnon-empty; Absolute local filesystem path
application_idstring""
tasksobjectTask names mapped to argv arrays; replaces configured tasks
tomaccoctl call project.configure '{"path":"<path>"}'

project.create#

Create project

Create a native Android app, a Jetpack Compose app in Kotlin with one UI test (kind compose), an Android app with Swift core, SwiftUI iOS app (xtool), or Flutter app in a new directory. With build:true, an xtool project is also built in the same job; project.app then names the .app. With performance:true a Compose app also gets the :baselineprofile module (Macrobenchmark startup benchmarks and a Baseline Profile generator) that profile.macrobenchmark and profile.baseline_profile run.

Annotations: writes, not idempotent, open world.

ArgumentTypeRequiredDefaultDetails
pathstringyesnon-empty; Absolute local filesystem path
kindstringyesone of swift-android, android, compose, xtool, flutter
namestring"TomaccoApp"
organizationstring"com.example"
buildbooleanfalse
performancebooleanfalsekind compose: also add a :baselineprofile module with a Macrobenchmark startup test and a Baseline Profile generator, and apply the androidx.baselineprofile plugin to the app
tomaccoctl call project.create '{"path":"<path>","kind":"swift-android"}'

project.plan#

View build plan

Resolve exact commands, working directory and expected artifacts without executing them.

Annotations: read-only, idempotent, open world.

ArgumentTypeRequiredDefaultDetails
pathstringyesnon-empty; Absolute local filesystem path
platformstring"android"one of android, ios, web, linux
actionstring"build"one of build, test, lint, instrumented-test, task
configurationstring"debug"one of debug, release
formatstring"apk"one of apk, aab, ipa
signbooleanfalse
taskstring""Name of an explicitly configured project task
devicestring""Device serial from device.list for instrumented-test: required for a Flutter project's integration_test run, and for Gradle the device ANDROID_SERIAL selects
coveragebooleanfalseGradle test or instrumented-test: also run the coverage report tasks the build files enable (AGP's enableUnitTestCoverage or enableAndroidTestCoverage, the jacoco plugin, Kover); testing.coverage reads the reports
managed_devicestring""up to 100 characters; Gradle instrumented-test: run on this Gradle Managed Device or device group from the build files (project.inspect test_setup), or all, instead of a connected device
shardsinteger1 to 32; With managed_device: split the instrumented tests across this many managed devices (AGP's numManagedDeviceShards)
tomaccoctl call project.plan '{"path":"<path>"}'

project.execute#

Start build / test

Execute a build, tests, lint or named project task as a durable cancellable job. For a Flutter project, test and instrumented-test (flutter test integration_test -d device) also write the JSON reporter's output to build/tomacco, which testing.results reads. A test or instrumented-test job ends by writing build/tomacco/test-report.html (testing.report) and adding its results to the test history (testing.history), also when tests fail. For Gradle, coverage adds the coverage report tasks and managed_device runs the instrumented tests on a Gradle Managed Device, with shards to split them. An identical active request reuses its job; different work for the occupied project returns workspace_busy with the active job. Use job.send for Flutter Hot Reload.

Annotations: writes, not idempotent, open world.

ArgumentTypeRequiredDefaultDetails
pathstringyesnon-empty; Absolute local filesystem path
platformstring"android"one of android, ios, web, linux
actionstring"build"one of build, test, lint, instrumented-test, task
configurationstring"debug"one of debug, release
formatstring"apk"one of apk, aab, ipa
signbooleanfalse
taskstring""Name of an explicitly configured project task
devicestring""Device serial from device.list for instrumented-test: required for a Flutter project's integration_test run, and for Gradle the device ANDROID_SERIAL selects
coveragebooleanfalseGradle test or instrumented-test: also run the coverage report tasks the build files enable (AGP's enableUnitTestCoverage or enableAndroidTestCoverage, the jacoco plugin, Kover); testing.coverage reads the reports
managed_devicestring""up to 100 characters; Gradle instrumented-test: run on this Gradle Managed Device or device group from the build files (project.inspect test_setup), or all, instead of a connected device
shardsinteger1 to 32; With managed_device: split the instrumented tests across this many managed devices (AGP's numManagedDeviceShards)
timeoutinteger18001 to 86400
tomaccoctl call project.execute '{"path":"<path>"}'

project.run#

Build & run on device

Build and deploy to a selected Android/iOS device. With device virtual-iphone, an xtool project is built with xtool dev build and installed and opened on the running virtual iPhone with ios.virtual.deploy, which skips the install when the signed app is unchanged; then, after crash_check_seconds, its crash reports are read, and a report that was not there before the deploy fails the job as crashed. The job writes build/tomacco/virtual_iphone_run.json in the project: state (launched, crashed, failed, or building when the build failed), build_seconds, deploy (job_id, seconds, unchanged, steps), pid and crash_check. Refused with ios_virtual_not_running when the phone is off. Flutter supports interactive hot reload via job.send. While a Flutter session runs, job.get's result.flutter has the app's VM service URI (vm_service_uri, and vm_service_http_uri for a browser) and, once Flutter reports them, devtools_uri, devtools_app_uri (DevTools opened on this app) and dtd_uri. An identical active request reuses its job; different work for the occupied project returns workspace_busy with the active job. Use job.send for Flutter Hot Reload.

Annotations: writes, not idempotent, open world.

ArgumentTypeRequiredDefaultDetails
pathstringyesnon-empty; Absolute local filesystem path
platformstringyesone of android, ios
devicestringyesnon-empty; Device serial / UDID from device.list, or virtual-iphone for the running virtual iPhone (xtool projects)
bundle_idstring""Android application ID for Gradle projects (default: the variant's ID read from the build files, or tomacco.json's applicationId), or exact installed iPhone bundle ID to resolve ambiguous xtool signing mappings. Omit for automatic iPhone detection.
configurationstring"debug"one of debug, release
variantstring""Gradle build variant to install, such as freeDebug. Required when the app has product flavors; otherwise the configuration's build type.
crash_check_secondsinteger100 to 120; Virtual iPhone only: how long after the app opened to look for a new crash report of it; 0 skips the check.
tomaccoctl call project.run '{"path":"<path>","platform":"android","device":"<device>"}'

project.watch#

Watch and rerun app

Watch a project's source files and, whenever they change and have stayed unchanged for debounce_ms, build, install and launch the app again with project.run, as a durable job; it also runs the app once at the start. Build output, dependency and tool directories (build, .gradle, .dart_tool, node_modules, Pods, .git and others) are ignored. For a Flutter project it starts one Flutter session and sends it Hot Reload on each change, starting a new session when that one has ended. Each cycle writes one line to the job's log: the files that changed and how the run ended; with device virtual-iphone (xtool projects) it gives the build and deploy seconds, whether the app was unchanged, its pid and the crash check, and the xtool output directory is ignored too. Cancel the job to stop watching; runs it started are cancelled with it.

Annotations: writes, not idempotent, open world.

ArgumentTypeRequiredDefaultDetails
pathstringyesnon-empty; Absolute local filesystem path
platformstringyesone of android, ios
devicestringyesnon-empty; Device serial / UDID from device.list, or virtual-iphone for the running virtual iPhone (xtool projects)
bundle_idstring""Android application ID for Gradle projects (default: the variant's ID read from the build files, or tomacco.json's applicationId), or exact installed iPhone bundle ID to resolve ambiguous xtool signing mappings. Omit for automatic iPhone detection.
configurationstring"debug"one of debug, release
variantstring""Gradle build variant to install, such as freeDebug. Required when the app has product flavors; otherwise the configuration's build type.
crash_check_secondsinteger100 to 120; Virtual iPhone only: how long after the app opened to look for a new crash report of it; 0 skips the check.
debounce_msinteger800100 to 10000; How long the files must stay unchanged before a cycle starts, in milliseconds
ignorearray of stringup to 50 items; More directory names to leave out, besides build, .gradle, .dart_tool, node_modules, Pods, .git and other build and tool directories
timeoutinteger8640060 to 86400; Seconds after which the watch ends
tomaccoctl call project.watch '{"path":"<path>","platform":"android","device":"<device>"}'

project.dependency_updates#

Check dependency updates

Compare the versions a project declares with the newest published ones. Gradle: gradle/libs.versions.toml and the build files against Maven metadata from Google Maven, Maven Central and the Gradle Plugin Portal. pub: flutter pub outdated --json (dart pub for a Dart package), direct and dev dependencies. npm: the dependencies in package.json with npm outdated --json, or pnpm or Yarn 1 when their lockfile is there. SwiftPM: each pin of Package.resolved (also inside an .xcodeproj or .xcworkspace) against its repository's tags from git ls-remote. Read-only, as a job whose report.json lists each dependency with its ecosystem, version, latest stable and latest version and a status, and each ecosystem checked with its error if it could not be. Answers offline at once when Gradle is all there is and no repository host resolves.

Annotations: read-only, idempotent, open world.

ArgumentTypeRequiredDefaultDetails
pathstringyesnon-empty; Absolute local filesystem path
repositoriesarray of stringup to 10 items; Maven repository base URLs (https:// or file:///) to ask in order instead of the defaults, for Gradle dependencies
tomaccoctl call project.dependency_updates '{"path":"<path>"}'

project.analyze#

Analyze project code

Run the static analysers a project already has and list their findings as issues with tool, file, line, column, severity (error, warning or info), code and message, as a job whose report.json also has totals per severity and passed (no errors and every analyser ran). A Dart or Flutter project runs dart analyze --format=json (Flutter's own bin/dart when no dart is configured); a JavaScript or TypeScript project runs eslint --format json and, with a tsconfig.json, tsc --noEmit from its node_modules/.bin. Installs and downloads nothing; changes no project file. The job fails only when no analyser produced a result.

Annotations: read-only, idempotent, closed world.

ArgumentTypeRequiredDefaultDetails
pathstringyesnon-empty; Absolute local filesystem path
toolsarray of stringitems one of dart, eslint, tsc; up to 3 items; Only these analysers; each must apply. Default: every analyser the project has
timeoutinteger90010 to 3600; Seconds after which the job ends
tomaccoctl call project.analyze '{"path":"<path>"}'

project.import_xcode#

Import Xcode project

Write an xtool adapter package for an .xcodeproj with the pinned omarchy-apple-dev xcodeproj2xtool.py, by default in omarchy-xtool beside the project. Returns what the generator could not map as warnings. Build the adapter with project.execute. Needs only ios.toolkit_install's checkout.

Annotations: writes, not idempotent, open world.

ArgumentTypeRequiredDefaultDetails
projectstringyesnon-empty; Absolute local filesystem path
targetstring""Application target, when the project has several
outstring""Absolute path of the adapter directory
bundle_idstring""
tomaccoctl call project.import_xcode '{"project":"<project>"}'

project.app#

Find built iOS app

Report the built xtool/*.app of an xtool project, its bundle identifier, and whether the virtual device's bundle rules accept it, with the calls that come next. Reads files only.

Annotations: read-only, idempotent, open world.

ArgumentTypeRequiredDefaultDetails
pathstringyesnon-empty; Absolute local filesystem path
tomaccoctl call project.app '{"path":"<path>"}'

View this page as Markdown on GitHub