Skip to content

Commit

Permalink
Настройка detekt (#37)
Browse files Browse the repository at this point in the history
* Обновляет версии Gradle, AGP, Kotlin

* Настраивает detekt в проекте

* Переносит объявление библиотек в version catalog

* Удаляет лишние файлы из build-logic

* Настраивает проверки на PR

* Исправляет версию Java для сборки

* Добавляет флажков к запуску Gradle

* Исправляет число ошибок detekt, требуемых для остановки сборки

* Настраивает ReviewDog для лучшей видимости ошибок статического анализа

* Добавляет удаление комментариев от бота перед запуском проверок

* Добавляет документацию про detektAll и detektFormat
  • Loading branch information
PStrelchenko authored Nov 29, 2023
1 parent 44f0d99 commit 4425519
Show file tree
Hide file tree
Showing 19 changed files with 1,127 additions and 31 deletions.
13 changes: 13 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
root = true

# See conf/detekt.yml, values should be the same

[*]
charset = utf-8
end_of_line = lf
indent_size = 4
indent_style = space
insert_final_newline = true
max_line_length = 120

ij_kotlin_imports_layout = *, java.**, javax.**, kotlin.**, kotlinx.android.synthetic.**, ^
58 changes: 58 additions & 0 deletions .github/workflows/pr_checks.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
name: PR checks

on:
push:
branches: [ "main" ]
pull_request:

jobs:
pr-checks:
runs-on: ubuntu-latest
env:
commonGradleFlags: --parallel --stacktrace --no-configuration-cache --no-daemon
detektReportPath: ./build/reports/detekt/detekt.xml
reviewdogSetup: -f=checkstyle -name="detekt" -level=error -filter-mode=added

steps:
- name: Checkout
uses: actions/checkout@v3

- name: Cleanup Github-Actions bot comments
run: |
sh ./ci/github_comments_cleanup.sh "${{ github.repository_owner }}" "${{ github.event.repository.name }}" "${{ github.event.number }}" "github-actions[bot]" "${{ secrets.GITHUB_TOKEN }}"
- name: Setup Reviewdog
uses: reviewdog/action-setup@v1
with:
reviewdog_version: latest

- name: Setup JDK 17 for build
uses: actions/setup-java@v3
with:
java-version: '17'
distribution: 'temurin'
cache: gradle

- name: Grant execute permission for gradlew
run: chmod +x gradlew

- name: Warming up Gradle
run: ./gradlew help $commonGradleFlags

- name: Run detekt
run: ./gradlew detektAll $commonGradleFlags

- name: Run Reviewdog for Detekt as Github Review
env:
REVIEWDOG_GITHUB_API_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
reviewdog $reviewdogSetup -reporter=github-pr-review <$detektReportPath
- name: Run Reviewdog for Detekt as Github CHECK
env:
REVIEWDOG_GITHUB_API_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
reviewdog $reviewdogSetup -reporter=github-pr-check <$detektReportPath
- name: Assemble app
run: ./gradlew :app:assembleDebug $commonGradleFlags
15 changes: 15 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,21 @@ hhAccessToken=my_access_token
попадут в специальный объект, который называется `BuildConfig`. Подробнее про этот объект можно почитать
в [документации](https://developer.android.com/build/gradle-tips#share-custom-fields-and-resource-values-with-your-app-code).

## Статический анализ

В проекте настроен базовый статический анализатор - [detekt](https://detekt.dev/).
Он проверит наличие большого количества стандартных ошибок при написании Kotlin-кода.

Конфигурационный файл detekt находится [здесь](./conf/detekt.yml). Описание смысла правил можно найти
в официальной документации detekt - [например, вот правила группы `comments`](https://detekt.dev/docs/rules/comments).

Чтобы проверить наличие ошибок detekt в проекте, откройте терминал и выполните команду `./gradlew detektAll`. После
выполнения в выводе терминала вы увидите список ошибок, если они у вас есть, рядом с каждой ошибкой будет находиться
ссылка на кусочек кода, где detekt обнаружил ошибку.

Также в проекте настроена команда, которая исправляет большое количество ошибок форматирования detekt. Чтобы запустить
её, откройте терминал и выполните команду `./gradlew detektFormat`.

# Техническое задание

Дипломный проект представляет собой небольшое приложение для поиска работы,
Expand Down
27 changes: 17 additions & 10 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@ plugins {

android {
namespace = "ru.practicum.android.diploma"
compileSdk = 33
compileSdk = libs.versions.compileSdk.get().toInt()

defaultConfig {
applicationId = "ru.practicum.android.diploma"
minSdk = 26
targetSdk = 33
minSdk = libs.versions.minSdk.get().toInt()
targetSdk = libs.versions.targetSdk.get().toInt()
versionCode = 1
versionName = "1.0"

Expand Down Expand Up @@ -40,12 +40,19 @@ android {
}

dependencies {
implementation(libs.androidX.core)
implementation(libs.androidX.appCompat)

implementation("androidx.core:core-ktx:1.10.1")
implementation("androidx.appcompat:appcompat:1.6.1")
implementation("com.google.android.material:material:1.9.0")
implementation("androidx.constraintlayout:constraintlayout:2.1.4")
testImplementation("junit:junit:4.13.2")
androidTestImplementation("androidx.test.ext:junit:1.1.5")
androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1")
// UI layer libraries
implementation(libs.ui.material)
implementation(libs.ui.constraintLayout)

// region Unit tests
testImplementation(libs.unitTests.junit)
// endregion

// region UI tests
androidTestImplementation(libs.uiTests.junitExt)
androidTestImplementation(libs.uiTests.espressoCore)
// endregion
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
package ru.practicum.android.diploma

import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.ext.junit.runners.AndroidJUnit4

import androidx.test.platform.app.InstrumentationRegistry
import org.junit.Assert.*
import org.junit.Test
import org.junit.runner.RunWith

import org.junit.Assert.*

/**
* Instrumented test, which will execute on an Android device.
*
Expand All @@ -21,4 +19,4 @@ class ExampleInstrumentedTest {
val appContext = InstrumentationRegistry.getInstrumentation().targetContext
assertEquals("ru.practicum.android.diploma", appContext.packageName)
}
}
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
package ru.practicum.android.diploma

import org.junit.Assert.assertEquals
import org.junit.Test

import org.junit.Assert.*

/**
* Example local unit test, which will execute on the development machine (host).
*
Expand All @@ -14,4 +13,4 @@ class ExampleUnitTest {
fun addition_isCorrect() {
assertEquals(4, 2 + 2)
}
}
}
13 changes: 13 additions & 0 deletions build-logic/checks/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
plugins {
`kotlin-dsl`
}

group = "ru.practicum.android.buildlogic"

dependencies {
implementation(projects.gradleExt)

implementation(libs.staticAnalysis.detektPlugin)
// workaround for https://github.com/gradle/gradle/issues/15383
implementation(files(libs.javaClass.superclass.protectionDomain.codeSource.location))
}
87 changes: 87 additions & 0 deletions build-logic/checks/src/main/kotlin/convention.detekt.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
import io.gitlab.arturbosch.detekt.Detekt
import io.gitlab.arturbosch.detekt.DetektCreateBaselineTask
import ru.practicum.android.withVersionCatalog

plugins {
id("io.gitlab.arturbosch.detekt")
}

fun Detekt.setupCommonDetektSettings() {
// Common properties
parallel = true
autoCorrect = false
disableDefaultRuleSets = false
buildUponDefaultConfig = false

// workaround for https://github.com/gradle/gradle/issues/15383
project.withVersionCatalog { libs ->
jvmTarget = JavaVersion.valueOf(libs.versions.java.get()).toString()
}

// Setup sources for run
setSource(files(projectDir))
include("**/*.kt")
include("**/*.kts")
exclude("**/resources/**")
exclude("**/build/**")

// reports configuration
reports {
xml.required.set(true)
html.required.set(true)
txt.required.set(true)
sarif.required.set(false)
}
}

val detektAll by tasks.register<Detekt>("detektAll") {
description = "Runs over whole code base without the starting overhead for each module."

setupCommonDetektSettings()

// Configuration
config.setFrom(files(project.rootDir.resolve("conf/detekt.yml")))
}

val detektFormat by tasks.register<Detekt>("detektFormat") {
description = "Reformats whole code base."

setupCommonDetektSettings()
autoCorrect = true

// Configuration
config.setFrom(files(project.rootDir.resolve("conf/detekt.yml")))
}

val detektProjectBaseline by tasks.register<DetektCreateBaselineTask>("detektProjectBaseline") {
description = "Overrides current baseline."

// Setup sources for run
setSource(files(projectDir))
include("**/*.kt")
include("**/*.kts")
exclude("**/resources/**")
exclude("**/build/**")

// Common properties
buildUponDefaultConfig.set(true)
ignoreFailures.set(true)
parallel.set(true)

// workaround for https://github.com/gradle/gradle/issues/15383
project.withVersionCatalog { libs ->
jvmTarget = JavaVersion.valueOf(libs.versions.java.get()).toString()
}

// Configuration
config.setFrom(files(project.rootDir.resolve("conf/detekt.yml")))
}

// workaround for https://github.com/gradle/gradle/issues/15383
project.withVersionCatalog { libs ->
dependencies {
add("detekt", libs.staticAnalysis.detektCli)
add("detektPlugins", libs.staticAnalysis.detektFormatting)
add("detektPlugins", libs.staticAnalysis.detektLibraries)
}
}
10 changes: 10 additions & 0 deletions build-logic/gradle-ext/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
plugins {
`kotlin-dsl`
}

group = "ru.practicum.android.buildlogic"

dependencies {
// workaround for https://github.com/gradle/gradle/issues/15383
implementation(files(libs.javaClass.superclass.protectionDomain.codeSource.location))
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package ru.practicum.android

import org.gradle.accessors.dm.LibrariesForLibs
import org.gradle.api.Project
import org.gradle.kotlin.dsl.the


/**
* Workaround to make version catalog accessible in convention plugins
* https://github.com/gradle/gradle/issues/15383
*/
fun Project.withVersionCatalog(block: (libs: LibrariesForLibs) -> Unit) {
if (project.name != "gradle-kotlin-dsl-accessors") {
val libs = the<LibrariesForLibs>()
block.invoke(libs)
}
}
Binary file removed build-logic/gradle/wrapper/gradle-wrapper.jar
Binary file not shown.
6 changes: 0 additions & 6 deletions build-logic/gradle/wrapper/gradle-wrapper.properties

This file was deleted.

16 changes: 16 additions & 0 deletions build-logic/settings.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS")

rootProject.name = "build-logic"

pluginManagement {
Expand All @@ -8,12 +10,26 @@ pluginManagement {
}
}

@Suppress("UnstableApiUsage")
dependencyResolutionManagement {
versionCatalogs {
create("libs") {
from(files("../gradle/libs.versions.toml"))
}
}

repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories {
google()
mavenCentral()
}
}

/**
* renamed from 'gradle' to prevent IDE resolution conflict:
* usages of "typesafe project accessors", e.g. `projects.gradle.someProject` was red in IDE
* build was fine however
*/
include("gradle-ext")
include(":develop-properties")
include(":checks")
7 changes: 4 additions & 3 deletions build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
plugins {
id("com.android.application") version "8.1.0" apply false
id("org.jetbrains.kotlin.android") version "1.8.0" apply false
}
id("com.android.application") version "8.1.4" apply false
id("org.jetbrains.kotlin.android") version "1.9.21" apply false
id("convention.detekt")
}
33 changes: 33 additions & 0 deletions ci/github_comments_cleanup.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#!/bin/bash

# Variables
repo_owner="$1"
repo_name="$2"
pull_number="$3"
username="$4"
github_token="$5"

# List all comments in the pull request
comments_url="https://api.github.com/repos/$repo_owner/$repo_name/pulls/$pull_number/comments"
echo "Comments URL: $comments_url"

comments=$(curl \
-L \
-H "Accept: application/vnd.github+json" \
-H "Authorization: Bearer $github_token" \
"$comments_url" | jq -c '.[] | select(.user.login == "'$username'") | .url')

echo "$comments" | while read -r comment_url; do
# Remove quotes from comment_url
fixed_comment_url="${comment_url%\"}"
fixed_comment_url="${comment_url#\"}"

curl -s -X DELETE \
-H "Accept: application/vnd.github+json" \
-H "Authorization: Bearer $github_token" \
-H "X-GitHub-Api-Version: 2022-11-28" \
$fixed_comment_url
sleep 1

echo "Deleted comment: $fixed_comment_url"
done
Loading

0 comments on commit 4425519

Please sign in to comment.