Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 68 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
name: CI

on:
pull_request:
branches: [ main ]

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
lint:
name: Lint
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Make gradlew executable
run: chmod +x ./gradlew
- uses: actions/setup-java@v4
with:
distribution: temurin
java-version: 17
cache: gradle
- name: Run Android lint
run: ./gradlew lint

detekt:
name: Detekt
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Make gradlew executable
run: chmod +x ./gradlew
- uses: actions/setup-java@v4
with:
distribution: temurin
java-version: 17
cache: gradle
- name: Run Detekt
run: ./gradlew detekt

unit-tests:
name: Unit Tests & Coverage (≥80%)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Make gradlew executable
run: chmod +x ./gradlew
- uses: actions/setup-java@v4
with:
distribution: temurin
java-version: 17
cache: gradle
- name: Run unit tests with coverage
run: ./gradlew testDebugUnitTest
- name: Upload coverage reports
if: always()
uses: actions/upload-artifact@v4
with:
name: coverage-reports
path: |
app/build/reports/coverage/
scanner-core/build/reports/coverage/
scanner-ui/build/reports/coverage/
scanner-rules/build/reports/coverage/
retention-days: 14
- name: Check coverage ≥ 80%
run: python3 scripts/check_coverage.py . 80
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,6 @@
.externalNativeBuild
.cxx
local.properties
/.idea/markdown.xml
/.idea/gradle.xml
/.idea/misc.xml
8 changes: 8 additions & 0 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
plugins {
alias(libs.plugins.android.application)
alias(libs.plugins.kotlin.compose)
alias(libs.plugins.hilt)
alias(libs.plugins.ksp)
}

android {
Expand All @@ -22,6 +24,9 @@ android {
}

buildTypes {
debug {
enableUnitTestCoverage = true
}
release {
isMinifyEnabled = false
proguardFiles(
Expand All @@ -40,6 +45,9 @@ android {
}

dependencies {
implementation(project(":scanner-ui"))
implementation(libs.hilt.android)
ksp(libs.hilt.android.compiler)
implementation(libs.androidx.core.ktx)
implementation(libs.androidx.lifecycle.runtime.ktx)
implementation(libs.androidx.activity.compose)
Expand Down
1 change: 1 addition & 0 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
xmlns:tools="http://schemas.android.com/tools">

<application
android:name=".ComposeA11yScannerApplication"
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.composea11yscanner

import android.app.Application
import dagger.hilt.android.HiltAndroidApp

@HiltAndroidApp
class ComposeA11yScannerApplication : Application()
17 changes: 17 additions & 0 deletions build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,5 +1,22 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
plugins {
alias(libs.plugins.android.application) apply false
alias(libs.plugins.android.library) apply false
alias(libs.plugins.kotlin.android) apply false
alias(libs.plugins.kotlin.compose) apply false
alias(libs.plugins.hilt) apply false
alias(libs.plugins.ksp) apply false
alias(libs.plugins.detekt)
}

detekt {
source.setFrom(
fileTree(rootDir) {
include("**/src/**/*.kt")
exclude("**/build/**", "**/.gradle/**")
}
)
config.setFrom(file("config/detekt/detekt.yml"))
buildUponDefaultConfig = true
parallel = true
}
32 changes: 32 additions & 0 deletions config/detekt/detekt.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
build:
maxIssues: 0
excludeCorrectable: false

config:
validation: true
warningsAsErrors: false

style:
MaxLineLength:
maxLineLength: 140
WildcardImport:
active: false
MagicNumber:
active: false

complexity:
LongMethod:
threshold: 60
LongParameterList:
functionThreshold: 6
constructorThreshold: 7
TooManyFunctions:
thresholdInFiles: 20
thresholdInClasses: 15
thresholdInObjects: 15
thresholdInInterfaces: 15

naming:
FunctionNaming:
functionPattern: '[a-z][a-zA-Z0-9]*'
excludes: ['**/test/**', '**/androidTest/**']
14 changes: 13 additions & 1 deletion gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ lifecycleRuntimeKtx = "2.10.0"
activityCompose = "1.13.0"
kotlin = "2.2.10"
composeBom = "2024.09.00"
hilt = "2.59.2"
ksp = "2.3.7"
coroutines = "1.10.1"
detekt = "1.23.7"

[libraries]
androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" }
Expand All @@ -24,8 +28,16 @@ androidx-compose-ui-tooling-preview = { group = "androidx.compose.ui", name = "u
androidx-compose-ui-test-manifest = { group = "androidx.compose.ui", name = "ui-test-manifest" }
androidx-compose-ui-test-junit4 = { group = "androidx.compose.ui", name = "ui-test-junit4" }
androidx-compose-material3 = { group = "androidx.compose.material3", name = "material3" }
hilt-android = { group = "com.google.dagger", name = "hilt-android", version.ref = "hilt" }
hilt-android-compiler = { group = "com.google.dagger", name = "hilt-android-compiler", version.ref = "hilt" }
kotlinx-coroutines-core = { group = "org.jetbrains.kotlinx", name = "kotlinx-coroutines-core", version.ref = "coroutines" }
kotlinx-coroutines-android = { group = "org.jetbrains.kotlinx", name = "kotlinx-coroutines-android", version.ref = "coroutines" }

[plugins]
android-application = { id = "com.android.application", version.ref = "agp" }
android-library = { id = "com.android.library", version.ref = "agp" }
kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }
kotlin-compose = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" }

hilt = { id = "com.google.dagger.hilt.android", version.ref = "hilt" }
ksp = { id = "com.google.devtools.ksp", version.ref = "ksp" }
detekt = { id = "io.gitlab.arturbosch.detekt", version.ref = "detekt" }
56 changes: 56 additions & 0 deletions sample/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
plugins {
alias(libs.plugins.android.application)
alias(libs.plugins.kotlin.compose)
alias(libs.plugins.hilt)
alias(libs.plugins.ksp)
}

android {
namespace = "com.composea11yscanner.sample"
compileSdk = 36

defaultConfig {
applicationId = "com.composea11yscanner.sample"
minSdk = 24
targetSdk = 36
versionCode = 1
versionName = "1.0"
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
}

buildTypes {
release {
isMinifyEnabled = false
proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro")
}
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_11
targetCompatibility = JavaVersion.VERSION_11
}

buildFeatures { compose = true }
}

dependencies {
implementation(project(":scanner-ui"))
implementation(project(":scanner-core"))
implementation(project(":scanner-rules"))
implementation(libs.androidx.core.ktx)
implementation(libs.androidx.lifecycle.runtime.ktx)
implementation(libs.androidx.activity.compose)
implementation(platform(libs.androidx.compose.bom))
implementation(libs.androidx.compose.ui)
implementation(libs.androidx.compose.ui.graphics)
implementation(libs.androidx.compose.ui.tooling.preview)
implementation(libs.androidx.compose.material3)
implementation(libs.hilt.android)
ksp(libs.hilt.android.compiler)
testImplementation(libs.junit)
androidTestImplementation(libs.androidx.junit)
androidTestImplementation(libs.androidx.espresso.core)
androidTestImplementation(platform(libs.androidx.compose.bom))
androidTestImplementation(libs.androidx.compose.ui.test.junit4)
debugImplementation(libs.androidx.compose.ui.tooling)
debugImplementation(libs.androidx.compose.ui.test.manifest)
}
Empty file added sample/proguard-rules.pro
Empty file.
24 changes: 24 additions & 0 deletions sample/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">

<application
android:name=".SampleApplication"
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.ComposeA11yScanner">
<activity
android:name=".SampleActivity"
android:exported="true"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>

</manifest>
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package com.composea11yscanner.sample

import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import dagger.hilt.android.AndroidEntryPoint

@AndroidEntryPoint
class SampleActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enableEdgeToEdge()
setContent { SampleApp() }
}
}

@Composable
fun SampleApp(modifier: Modifier = Modifier) {
Scaffold(modifier = modifier.fillMaxSize()) { innerPadding ->
Text(text = "ComposeA11yScanner Sample", modifier = Modifier.padding(innerPadding))
}
}

@Preview(showBackground = true)
@Composable
fun SampleAppPreview() {
SampleApp()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.composea11yscanner.sample

import android.app.Application
import dagger.hilt.android.HiltAndroidApp

@HiltAndroidApp
class SampleApplication : Application()
4 changes: 4 additions & 0 deletions sample/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">A11y Scanner Sample</string>
</resources>
4 changes: 4 additions & 0 deletions sample/src/main/res/values/themes.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="Theme.ComposeA11yScanner" parent="android:Theme.Material.Light.NoActionBar" />
</resources>
41 changes: 41 additions & 0 deletions scanner-core/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
plugins {
alias(libs.plugins.android.library)
alias(libs.plugins.hilt)
alias(libs.plugins.ksp)
}

android {
namespace = "com.composea11yscanner.core"
compileSdk = 36

defaultConfig {
minSdk = 24
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
consumerProguardFiles("consumer-rules.pro")
}

buildTypes {
debug {
enableUnitTestCoverage = true
}
release {
isMinifyEnabled = false
proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro")
}
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_11
targetCompatibility = JavaVersion.VERSION_11
}
}

dependencies {
implementation(libs.androidx.core.ktx)
implementation(libs.hilt.android)
ksp(libs.hilt.android.compiler)
implementation(libs.kotlinx.coroutines.core)
implementation(libs.kotlinx.coroutines.android)
testImplementation(libs.junit)
androidTestImplementation(libs.androidx.junit)
androidTestImplementation(libs.androidx.espresso.core)
}
Empty file added scanner-core/consumer-rules.pro
Empty file.
Empty file added scanner-core/proguard-rules.pro
Empty file.
2 changes: 2 additions & 0 deletions scanner-core/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" />
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package com.composea11yscanner.core

object ScannerCore {
const val VERSION = "0.1.0"
}
Loading
Loading