diff --git a/cli-config-template.yml b/cli-config-template.yml index d8e11cd..18c1583 100644 --- a/cli-config-template.yml +++ b/cli-config-template.yml @@ -4,6 +4,7 @@ project-input: modules-dir-is-project-root: true r8-mapping-file: "./path/to/R8/mapping/file.txt" owner-mapping-file: "./path/to/owner/mapping/file.yml" + library-owner-mapping-file: "./path/to/library/owner/mapping/file.yml" version: "your/app/version" large-file-threshold: 10 project-name: "your/project/name" diff --git a/docker/grafana/grafana.db b/docker/grafana/grafana.db index 5123787..f254f3a 100644 Binary files a/docker/grafana/grafana.db and b/docker/grafana/grafana.db differ diff --git a/docker/grafana/grafana.db.bak b/docker/grafana/grafana.db.bak new file mode 100644 index 0000000..5123787 Binary files /dev/null and b/docker/grafana/grafana.db.bak differ diff --git a/docs/cli.md b/docs/cli.md index 6fa154a..cab2833 100644 --- a/docs/cli.md +++ b/docs/cli.md @@ -41,6 +41,7 @@ report: | modules-dir-is-project-root | Boolean value. Enable this flag if you set the root project as the modules-directory to optimize performance | | r8-mapping-file | Path to the R8 mapping file if you enable R8 for your build | | owner-mapping-file | Path to YAML file mapping project modules to team owners | +| library-owner-mapping-file | Path to YAML file mapping external libraries (Maven coordinates) to team owners. Optional. | | version | Your app version | | large-file-threshold | File size threshold (in bytes) for considering a file as large | | project-name | Project name | @@ -57,6 +58,28 @@ Team2: - sample-group:android-module-level2 ``` +And example of `library-owner-mapping-file`: + +```yaml +Platform: + - androidx.core:* # all artifacts under the androidx.core group + - androidx.lifecycle:* +Team1: + - com.google.android.material:* + - androidx.navigation:* +Team2: + - org.jetbrains.kotlin:* + - org.jetbrains.kotlinx:* +``` + +Pattern matching is evaluated in this order; the first match wins: + +1. **Exact coordinate** — e.g. `androidx.core:core-ktx:1.13.1` +2. **Group wildcard** using `:*` — e.g. `androidx.core:*` (matches any artifact under `androidx.core`) +3. **Group wildcard** using `.*` — e.g. `androidx.*` (matches any group beginning with `androidx.`) + +Libraries that do not match any pattern are attributed to the `app` module (see [Limitations](./limitation.md)). + ### APK Generation | Property | Description | @@ -94,6 +117,7 @@ project-input: modules-dir-is-project-root: true r8-mapping-file: "./app/build/outputs/mapping/proDebug/mapping.txt" owner-mapping-file: "./module-owner.yml" + library-owner-mapping-file: "./library-owner.yml" version: "1.0.1" large-file-threshold: 10 project-name: "sample" diff --git a/docs/limitation.md b/docs/limitation.md index a13d0d9..f532ddb 100644 --- a/docs/limitation.md +++ b/docs/limitation.md @@ -27,7 +27,7 @@ The `resources.arsc` file is a special file in Android APKs containing precompil ### Uncategorized Files * Any files that cannot be categorized as Java/Kotlin code, resources, native libraries, or assets are automatically distributed to the app module and grouped under the **"Others"** category. -* Any files/classes that cannot find an owner (does not belong to a module or library) are automatically distributed to the app module +* Any files/classes that cannot find an owner — i.e. files that don't belong to a module owned in `module-owner.yml` and libraries that don't match any pattern in `library-owner.yml` — are automatically distributed to the `app` module. ## Inline Functions and Classes diff --git a/docs/plugin.md b/docs/plugin.md index 4b25c97..8a4a8a5 100644 --- a/docs/plugin.md +++ b/docs/plugin.md @@ -83,6 +83,7 @@ appSizer { projectInput { largeFileThreshold = [your_threshold_in_bytes] teamMappingFile = file("path/to/your/module-owner.yml") + libraryOwnershipFile = file("path/to/your/library-owner.yml") enableMatchDebugVariant = [true|false] variantFilter { variant -> variant.setIgnore(variant.flavors.contains("your-ignore-flavor")) @@ -99,6 +100,7 @@ appSizer { |----------|----------------------------------------------------------------| | `largeFileThreshold` | File size threshold (in bytes) for considering a file as large. | | `teamMappingFile` | YAML file mapping project modules to team owners. | +| `libraryOwnershipFile` | YAML file mapping external libraries (Maven coordinates) to team owners. Optional. | | `enableMatchDebugVariant` | If true, uses debug AAR files to improve build performance. | | `variantFilter` | Specifies which variants to exclude from analysis. | @@ -114,6 +116,28 @@ Team2: - sample-group:android-module-level2 ``` +And example of `libraryOwnershipFile`: + +```yaml +Platform: + - androidx.core:* # all artifacts under the androidx.core group + - androidx.lifecycle:* +Team1: + - com.google.android.material:* + - androidx.navigation:* +Team2: + - org.jetbrains.kotlin:* + - org.jetbrains.kotlinx:* +``` + +Pattern matching is evaluated in this order; the first match wins: + +1. **Exact coordinate** — e.g. `androidx.core:core-ktx:1.13.1` +2. **Group wildcard** using `:*` — e.g. `androidx.core:*` (matches any artifact under `androidx.core`) +3. **Group wildcard** using `.*` — e.g. `androidx.*` (matches any group beginning with `androidx.`) + +Libraries that do not match any pattern are attributed to the `app` module (see [Limitations](./limitation.md)). + ### APK Generation Configure APK generation settings: @@ -199,6 +223,7 @@ appSizer { enableMatchDebugVariant = true largeFileThreshold = 10 teamMappingFile = file("${rootProject.rootDir}/module-owner.yml") + libraryOwnershipFile = file("${rootProject.rootDir}/library-owner.yml") } metrics { influxDB { diff --git a/docs/report.md b/docs/report.md index e805dd9..a9bf85f 100644 --- a/docs/report.md +++ b/docs/report.md @@ -43,6 +43,14 @@ Markdown tables provide a convenient format for local analysis. The report is sa | android-module-level1 | Team1 | 124.042 KB | | kotlin-module | Team2 | 248.326 KB | +### Example: Library-wise Size Contribution + +| Contributor | Owner | Size | +|-------------|-------|------| +| androidx.appcompat:appcompat:1.7.0 | Platform | 166.844 KB | +| com.google.android.material:material:1.4.0-beta01 | Team1 | 164.000 KB | +| org.jetbrains.kotlin:kotlin-stdlib:1.8.22 | Team2 | 58.547 KB | + ## JSON Report JSON reports offer compatibility with other platforms and tools. The report is saved as `[option]-metrics.json` in the configured output folder. diff --git a/grafana/dashboard-to-import.json b/grafana/dashboard-to-import.json index 4fcbde0..7bc17e6 100644 --- a/grafana/dashboard-to-import.json +++ b/grafana/dashboard-to-import.json @@ -25,7 +25,7 @@ "fiscalYearStartMonth": 0, "graphTooltip": 0, "id": 3, - "iteration": 1718528153248, + "iteration": 1776832837098, "links": [], "liveNow": false, "panels": [ @@ -229,8 +229,8 @@ "overrides": [] }, "gridPos": { - "h": 15, - "w": 12, + "h": 13, + "w": 24, "x": 0, "y": 17 }, @@ -260,12 +260,12 @@ }, "targets": [ { - "alias": "$tag_contributor", + "alias": "$tag_owner", "datasource": { "type": "influxdb", "uid": "m2unCvxIk" }, - "query": "SELECT last(\"size\") FROM \"app_size\" WHERE (\"type\"='team' and \"app_version\" =~ /^$app_version$/ and \"device_name\" =~ /^$reference_device$/ AND $timeFilter ) GROUP BY \"contributor\"", + "query": "SELECT last(\"size\")\nFROM \"app_size\"\nWHERE (\n \"type\" = 'team'\n AND \"contributor\" = 'total'\n AND \"app_version\" =~ /^$app_version$/\n AND \"device_name\" =~ /^$reference_device$/\n AND $timeFilter\n)\nGROUP BY \"owner\"", "rawQuery": true, "refId": "A", "resultFormat": "time_series" @@ -279,7 +279,76 @@ "type": "influxdb", "uid": "m2unCvxIk" }, - "description": "A list of module names associated with the selected 'Team Name' filter, accompanied by a graph illustrating the contribution of each module to the app download size.\nYou have the option to filter by App Version, Reference Device and Team Name", + "description": "A compilation of libraries, each denoted with the size it contributes to the overall App Download Size. You have the option to filter by App Version and Reference Device.", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + } + }, + "mappings": [], + "unit": "bytes" + }, + "overrides": [] + }, + "gridPos": { + "h": 15, + "w": 24, + "x": 0, + "y": 30 + }, + "id": 7, + "options": { + "displayLabels": [], + "legend": { + "displayMode": "table", + "placement": "right", + "values": [ + "percent", + "value" + ] + }, + "pieType": "pie", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "alias": "$tag_contributor", + "datasource": { + "type": "influxdb", + "uid": "m2unCvxIk" + }, + "query": "SELECT last(\"size\") FROM \"app_size\" WHERE (\"type\" = 'library' AND \"app_version\" =~ /^$app_version$/ AND \"device_name\" =~ /^$reference_device$/ AND $timeFilter ) GROUP BY \"contributor\"\n", + "rawQuery": true, + "refId": "A", + "resultFormat": "time_series" + } + ], + "title": "App Download Size Breakdown by Libraries", + "type": "piechart" + }, + { + "datasource": { + "type": "influxdb", + "uid": "m2unCvxIk" + }, + "description": "A list of module names/libraries associated with the selected 'Team Name' filter, accompanied by a graph illustrating the contribution of each module to the app download size.\nYou have the option to filter by App Version, Reference Device, and Team Name", "fieldConfig": { "defaults": { "color": { @@ -300,8 +369,8 @@ "gridPos": { "h": 15, "w": 12, - "x": 12, - "y": 17 + "x": 0, + "y": 45 }, "id": 6, "options": { @@ -333,13 +402,26 @@ "type": "influxdb", "uid": "m2unCvxIk" }, - "query": "SELECT last(\"size\") FROM \"app_size\" WHERE (\"type\" = 'module' AND \"app_version\" =~ /^$app_version$/ and \"device_name\" =~ /^$reference_device$/ and \"owner\" =~ /^$tf_name$/ ) GROUP BY \"contributor\"", + "query": "SELECT last(\"size\") FROM \"app_size\"\nWHERE (\"type\" = 'module'\n AND \"app_version\" =~ /^$app_version$/\n AND \"device_name\" =~ /^$reference_device$/\n AND \"owner\" =~ /^$tf_name$/)\nGROUP BY \"contributor\"", "rawQuery": true, "refId": "A", "resultFormat": "time_series" + }, + { + "alias": "$tag_contributor", + "datasource": { + "type": "influxdb", + "uid": "m2unCvxIk" + }, + "hide": false, + "query": "SELECT last(\"size\") FROM \"app_size\"\nWHERE (\"type\" = 'library'\n AND \"app_version\" =~ /^$app_version$/\n AND \"device_name\" =~ /^$reference_device$/\n AND \"owner\" =~ /^$tf_name$/)\nGROUP BY \"contributor\"", + "rawQuery": true, + "refId": "B", + "resultFormat": "time_series" } ], - "title": "Team Codebase Breakdown (Select the team name to see the detail)", + "title": "Team Breakdown (Select the team name to see the detail)", + "transformations": [], "type": "piechart" }, { @@ -347,7 +429,7 @@ "type": "influxdb", "uid": "m2unCvxIk" }, - "description": "A compilation of libraries, each denoted with the size it contributes to the overall App Download Size. You have the option to filter by App Version and Reference Device.", + "description": "A graph representation of the breakdown of the Team Download Size by individual components. You have the option to filter by App Version, Reference Device, and Team name", "fieldConfig": { "defaults": { "color": { @@ -367,13 +449,12 @@ }, "gridPos": { "h": 15, - "w": 24, - "x": 0, - "y": 32 + "w": 12, + "x": 12, + "y": 45 }, - "id": 7, + "id": 11, "options": { - "displayLabels": [], "legend": { "displayMode": "table", "placement": "right", @@ -402,13 +483,14 @@ "type": "influxdb", "uid": "m2unCvxIk" }, - "query": "SELECT last(\"size\") FROM \"app_size\" WHERE (\"type\" = 'library' AND \"app_version\" =~ /^$app_version$/ AND \"device_name\" =~ /^$reference_device$/ AND $timeFilter ) GROUP BY \"contributor\"\n", + "query": "SELECT last(\"size\")\nFROM \"app_size\"\nWHERE (\n \"type\" = 'team'\n AND \"contributor\" != 'total'\n AND \"app_version\" =~ /^$app_version$/\n AND \"owner\" =~ /^$tf_name$/\n AND \"device_name\" =~ /^$reference_device$/\n AND $timeFilter\n)\nGROUP BY \"contributor\"", "rawQuery": true, "refId": "A", "resultFormat": "time_series" } ], - "title": "App Download Size Breakdown by Libraries", + "title": "Team Breakdown by main Components (Select the team name to see the detail)", + "transformations": [], "type": "piechart" }, { @@ -433,7 +515,8 @@ "mode": "absolute", "steps": [ { - "color": "green" + "color": "green", + "value": null }, { "color": "red", @@ -449,7 +532,7 @@ "h": 9, "w": 24, "x": 0, - "y": 47 + "y": 60 }, "id": 8, "options": { @@ -505,9 +588,9 @@ "list": [ { "current": { - "selected": false, - "text": "1.0.2", - "value": "1.0.2" + "selected": true, + "text": "0.0.1", + "value": "0.0.1" }, "datasource": { "type": "influxdb", @@ -529,7 +612,7 @@ }, { "current": { - "selected": false, + "selected": true, "text": "device-1", "value": "device-1" }, @@ -585,6 +668,6 @@ "timezone": "", "title": "App Download Size Breakdown", "uid": "FBZO0xxSk", - "version": 51, + "version": 57, "weekStart": "" -} \ No newline at end of file +}