Giter Site home page Giter Site logo

print-me-android's Introduction

๐Ÿ‘‹ Hi there I'm Abhishek Saxena

I am a Mobile Full Stack Developer with 2 years of experience with expertise in Native Android and Spring Boot.

๐Ÿ›  Frameworks

๐Ÿ›  Programming Languages & Tools

Jetpack Compose Badge HTML5 Badge CSS3 Badge MySQL Badge Git Badge Gradle Badge Firebase Badge Postman Badge

๐Ÿค๐Ÿป Connect With Me

๐Ÿ“– Recent Articles (View All)

Title Published In Featured In
Builder Design Pattern In Kotlin
Jetpack Compose Migration: Best Practices and Strategies
SOLID Design Principles in Kotlin
Strategy Design Pattern In Kotlin
Conditionals, An Easier Design Decision But A Poor Choice
Easily manage image type with sealed classes -

โš™๏ธ GitHub Analytics



Thanks for stopping by and don't forget to check out my pinned repositories and open sourced projects.

print-me-android's People

Contributors

5abhisheksaxena avatar

Stargazers

 avatar

Watchers

 avatar  avatar

print-me-android's Issues

Add Detekt for code smell checks.

Reference: https://www.youtube.com/watch?v=ePpbpLyYI1w&list=PLeJI6UYqZX0IL4nSYTVY1-qE-VFn3SLk-&index=4&ab_channel=AdamMcNeilly

Steps to integrate Detekt

  1. Add detekt pluigin in project level build.gradle.
plugins {
   ...
    id 'io.gitlab.arturbosch.detekt' version "$detektVersion" // 1.19.0-RC2
}
  1. Create a buildscript for detekt as buildscripts/detekt.gradle and enter the configuraton for deket plugin.
apply plugin: "io.gitlab.arturbosch.detekt"

detekt {
    config = files("${rootProject.projectDir}/config/detekt/detekt.yml")

    reports {
        html.enabled = true
        xml.enabled = true
        txt.enabled = true
    }
}
  1. Add the detekt script to project level build.gradle file.
subprojects {
   ...
    apply from: "../buildscripts/detekt.gradle"
}
  1. Execute gradle task <ProjectName>Tasks>verification>detektGenerateConfig
    or ./gradlew detektGenerateConfig to generate the default detekt configuration.
  2. Update configuration for Jetpack Compose. (config/detekt/detekkt.yml)
    Reference: https://detekt.dev/docs/introduction/compose/.

Add additional configurations

style:
   UnusedPrivateMember:
        ... // other properties
        ignoreAnnotated: ['Preview']
   MagicNumber:
       ... // other properties
        ignoreAnnotated: ['Preview']

naming:
    FunctionNaming:
        ... // other properties
        ignoreAnnotated: ['Composable']  // new

In Color.kt add @file:Suppress("MagicNumber") on the top the file.

For Hilt,

style:
  UnnecessaryAbstractClass:
    ... // other properties
    ignoreAnnotated: ['Module'] // new

Optional

  • Add @Suppress("UnusedPrivateMember", "MagicNumber") to Composae Previews.

Add Github Actions workflow for Android Build and Android UI Tests.

Reference: https://www.youtube.com/watch?v=ePpbpLyYI1w&list=PLeJI6UYqZX0IL4nSYTVY1-qE-VFn3SLk-&index=4&ab_channel=AdamMcNeilly

Pro Tip

Use the Github website to create/edit Github Actions, it comes with a great UI and even better autocomplete.

Steps to add github actions.

  1. Create a directory for github actions as .github/workflows/.
  2. Add .github/workflows/android_build.yml
name: Android Build

on: push

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v1

      - name: Set Up JDK
        uses: actions/setup-java@v1
        with:
          java-version: 1.11

      - name: Change wrapper permissions
        run: chmod +x ./gradlew

      - name: Build Project
        run: ./gradlew assemble

      - name: Run Tests
        run: ./gradlew test
  1. Add .github/workflows/android_ui_test.yml
name: Android UI Tests

on: pull_request

jobs:
  android-test:
    runs-on: macos-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v2

      - name: Set Up JDK
        uses: actions/setup-java@v1
        with:
          java-version: 1.11

      - name: Change wrapper persmissions
        run: chmod +x ./gradlew

      - name: Run Tests
        uses: reactivecircus/android-emulator-runner@v2
        with:
          api-level: 29
          script: ./gradlew app:connectedCheck

Danger check GitHub action failing

The danger check Github Action is failing because of the deprecated Ruby Action which is used in the process.

Possible Fix
Update the Ruby sub-action version.

Handle connection exception in repository.

HTTP FAILED: java.net.SocketTimeoutException - thrown when the app is unable to connect to the server. One of the reasons could be that the server is down.

HTTP FAILED: java.net.ConnectException - thrown when the app is unable to connect to the server. One of the reasons could be that there is no internet available on the device.

Add Danger for PR automation

Reference: https://www.youtube.com/watch?v=ePpbpLyYI1w&list=PLeJI6UYqZX0IL4nSYTVY1-qE-VFn3SLk-&index=4&ab_channel=AdamMcNeilly

Steps to add Danger.

  1. Add github action to perform danger check on the PR. (.github/workflows/danger_checks.yml)
name: Danger Checks

on: pull_request

jobs:
  danger:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v1

      - name: Set Up JDK
        uses: actions/setup-java@v1
        with:
          java-version: 1.11

      - name: Set Up Ruby
        uses: actions/setup-ruby@v1
        with:
          ruby-version: 2.6

      - name: Danger Checks
        run: |
          gem install bundler
          bundle install
          bundle exec danger
        env:
          DANGER_GITHUB_API_TOKEN: ${{ secrets.GITHUB_TOKEN }}
  1. Create a Dangerfile in the root directory.
message "Thanks @#{github.pr_author}!"

if github.pr_body.length == 0
    fail "Please provide a summary in the Pull Request description."
end

if git.lines_of_code > 500
    warn "Please consider breaking up this pull request."
end

if github.pr_labels.empty?
    warn "Please add labels to this PR."
end

if git.deletions > git.insertions
    message  "๐ŸŽ‰ Code Cleanup!"
end
  1. Create a Gemfile in the root directory.
source "https://rubygems.org"

git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }

gem "danger"

Optional
You can also print out the list of outdated dependencies on the PR with the help of danger.

Steps to add dependency version check plugin by Ben Manes: https://github.com/ben-manes/gradle-versions-plugin

  1. Add the plugin to the project build.gradle
plugins {
    id "com.github.ben-manes.versions" version "$versionsPluginVersion" // 0.29.0
}
  1. Create a buildscript for versions plugin buildscripts/versionsplugin.gradle and enter the configuration for versions plugin.
apply plugin: "com.github.ben-manes.versions"

def isNonStable = { String version ->
    def stableKeyword = ['RELEASE', 'FINAL', 'GA'].any { it -> version.toUpperCase().contains(it) }
    def regex = /^[0-9,.v-]+(-r)?$/
    return !stableKeyword && !(version ==~ regex)
}

tasks.named("dependencyUpdates").configure {
    rejectVersionIf {
        isNonStable(it.candidate.version)
    }

    gradleReleaseChannel = "current"
}
  1. Add the versions plugin script to project level build.gradle file.
subprojects {
    .... // other gradle scripts
    apply from: "../buildscripts/versionsplugin.gradle"
}
  1. Test the plugin using ./gradlew dependencyUpdates.
  2. (Optional) Add the task to the github action - danger check.
    i. Add the following lines to the Dangerfile to print the output of ./gradlew dependencyUpdates
# Notify of outdated dependencies
dependencyReportsFile = "app/build/dependencyUpdates/report.txt"
dependencyUpdatesHeader = "The following dependencies have later milestone versions:"

hasDependencyUpdatesHeader = File.readlines(dependencyReportsFile).grep(/#{dependencyUpdatesHeader}/).any?

if hasDependencyUpdatesHeader
    file = File.open(dependencyReportsFile, "rb").read
    index = file.index(dependencyUpdatesHeader)
    message file.slice(index..-1)
end

ii. Execute the task in the github actions - Danger Checks

name: Danger Checks

on: pull_request

jobs:
  danger:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v1

      - name: Set Up JDK
        uses: actions/setup-java@v1
        with:
          java-version: 1.11

      - name: Set Up Ruby
        uses: actions/setup-ruby@v1
        with:
          ruby-version: 2.6

      - name: Change wrapper permissions // new
        run: chmod +x ./gradlew

      - name: Danger Checks
        run: |
          ./gradlew dependencyUpdates // new
          gem install bundler
          bundle install
          bundle exec danger
        env:
          DANGER_GITHUB_API_TOKEN: ${{ secrets.GITHUB_TOKEN }}

Tip/Recommendation

Move all the dependency versions to a centralized location.

Steps to centralize dependency versions.

  1. Create a buildsripts/versions.gradle file for module dependencies(example: app/build.gradle)
ext { // don't forget this ext otherwise it won't work
    versions = [
            // implementation

            // https://developer.android.com/jetpack/androidx/releases/core
            ktxCore                : "1.7.0",
            // https://developer.android.com/jetpack/androidx/releases/lifecycle
            lifeycle               : "2.4.1",


            // testing

            // https://developer.android.com/jetpack/androidx/releases/test
            androidxTestJunit      : "1.1.3",
            // https://developer.android.com/jetpack/androidx/releases/test
            espresso               : "3.4.0",
            // https://github.com/junit-team/junit4/releases
            junit                  : "4.13.2",

    ]
}
  1. Refer to the versions in the module as follows. (app/build.gradle)
dependencies {

    implementation "androidx.core:core-ktx:$rootProject.ext.versions.ktxCore"
    implementation "androidx.lifecycle:lifecycle-runtime-ktx:$rootProject.ext.versions.lifeycle"

    testImplementation "junit:junit:$rootProject.ext.versions.junit"
    androidTestImplementation "androidx.test.ext:junit:$rootProject.ext.versions.androidxTestJunit"
    androidTestImplementation "androidx.test.espresso:espresso-core:$rootProject.ext.versions.espresso"
}
  1. Put together the dependency versions in the project level build.gradle file together.
buildscript {
    ext {
       // URL for the github releases 
        kotlinVersion = '1.6.10'
       
       .... // other versions
    }
}// Top-level build file where you can add configuration options common to all sub-projects/modules.
  1. Refer to the versions in the project level gradle file as follows.
plugins {
    id 'com.android.application' version '7.2.1' apply false
    id 'com.android.library' version '7.2.1' apply false
    id 'org.jetbrains.kotlin.android' version "$kotlinVersion" apply false

   .... // other plugins
}
  1. Apply the versions.gradle to the project level build.gradle file.
buildscript {
    ext {
        .... // project level gradle file dependency versions.
    }
}// Top-level build file where you can add configuration options common to all sub-projects/modules.
plugins {
    .... // plugins
}

apply from: "buildscripts/versions.gradle" // added here

subprojects {
    .... // subproject gradle scripts
}


task clean(type: Delete) {
    delete rootProject.buildDir
}

Add ktlint for formatting and lint checks.

Reference: https://www.youtube.com/watch?v=ePpbpLyYI1w&list=PLeJI6UYqZX0IL4nSYTVY1-qE-VFn3SLk-&index=4&ab_channel=AdamMcNeilly

Steps to integrate ktlint

  1. Add ktlint pluigin in project level build.gradle.
plugins {
   ...
   // https://github.com/JLLeitschuh/ktlint-gradle/releases
   id "org.jlleitschuh.gradle.ktlint" version "$ktlintPluginVersion" // 10.2.0
}
  1. Create a buildscript for ktlint as buildscripts/ktlint.gradle and enter the configuraton for deket plugin.
apply plugin: "org.jlleitschuh.gradle.ktlint"

ktlint {
    // https://github.com/pinterest/ktlint/releases
    version = "0.45.2"

    reporters {
        reporter "plain"
        reporter "checkstyle"
        reporter "html"
    }

    outputColorName = "RED"
}
  1. Add the ktlint script to project level build.gradle file.
subprojects {
   ...
    apply from: "../buildscripts/ktlint.gradle"
}
  1. Execute gradle task <ProjectName>Tasks>formatting>ktlintFormat or ./gradlew ktlintFormat to format the whole project.
  2. Execute gradle task <ProjectName>Tasks>verification>ktlintCheck or ./gradlew ktlintCheck to check for lint issues in the whole project.

Tip: Run them together as ./gradlew clean build ktlintFormat ktlintCheck.

Improve DX

Integrate the following tools

To run all the checks
./gradlew clean build ktlintFormat ktlintCheck detekt

Note: Each issue has steps to setup the tool.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.