diff --git a/.github/workflows/pr_workflow.yml b/.github/workflows/pr_workflow.yml index a98b616..5d369be 100644 --- a/.github/workflows/pr_workflow.yml +++ b/.github/workflows/pr_workflow.yml @@ -14,7 +14,8 @@ jobs: runs-on: ubuntu-18.04 steps: - - uses: actions/checkout@v2 + - name: Checkout repository + uses: actions/checkout@v2 - name: set up JDK 11 uses: actions/setup-java@v1 @@ -24,8 +25,11 @@ jobs: - name: Decrypting api-properties run: gpg --quiet --batch --yes --decrypt --passphrase "${{ secrets.API_PROPERTIES_PASSPHRASE }}" project-config/api-properties/api.properties.asc > project-config/api-properties/api.properties - - name: ktlint - run: ./gradlew ktlint + - name: Generate env vars + uses: FranzDiebold/github-env-vars-action@v2 + + - name: Run detekt + run: ./quality/detekt/detekt-ci.sh -t $GITHUB_BASE_REF -s $CI_ACTION_REF_NAME - name: Unit tests run: ./gradlew test --stacktrace \ No newline at end of file diff --git a/.github/workflows/release_workflow.yml b/.github/workflows/release_workflow.yml index a70608c..b90ee36 100644 --- a/.github/workflows/release_workflow.yml +++ b/.github/workflows/release_workflow.yml @@ -11,7 +11,8 @@ jobs: runs-on: ubuntu-18.04 steps: - - uses: actions/checkout@v2 + - name: Checkout repository + uses: actions/checkout@v2 - name: set up JDK 11 uses: actions/setup-java@v1 diff --git a/.gitignore b/.gitignore index c37af1c..8278200 100644 --- a/.gitignore +++ b/.gitignore @@ -87,3 +87,6 @@ lint/tmp/ #secrets *.keystore api.properties + +#tools +.tools/ \ No newline at end of file diff --git a/build.gradle b/build.gradle index eed167f..994eba5 100644 --- a/build.gradle +++ b/build.gradle @@ -19,7 +19,7 @@ buildscript { } ext { kotlinVersion = "1.5.20" - gradleVersion = '7.0.2' + gradleVersion = '7.0.3' } dependencies { @@ -45,12 +45,15 @@ subprojects { apply from: "$rootDir/quality/ktlint.gradle" } -task installGitHook(type: Copy) { - from new File(rootProject.rootDir, 'git-hooks/pre-commit') - into { new File(rootProject.rootDir, '.git/hooks') } - fileMode 0777 +task installGitHooks(type: Exec) { + group 'Quality' + description 'Installs the git hooks' + println("Installing git hooks") + + workingDir rootDir + commandLine "quality/git-hooks/install-hooks.sh" } -tasks.getByPath(':app:preBuild').dependsOn installGitHook +tasks.getByPath(':app:preBuild').dependsOn installGitHooks task clean(type: Delete) { delete rootProject.buildDir diff --git a/features/recipe-collection/src/main/java/br/com/recipebook/recipecollection/data/RecipeCollectionRepositoryImpl.kt b/features/recipe-collection/src/main/java/br/com/recipebook/recipecollection/data/RecipeCollectionRepositoryImpl.kt index 27f1ea5..c93a3c1 100644 --- a/features/recipe-collection/src/main/java/br/com/recipebook/recipecollection/data/RecipeCollectionRepositoryImpl.kt +++ b/features/recipe-collection/src/main/java/br/com/recipebook/recipecollection/data/RecipeCollectionRepositoryImpl.kt @@ -6,7 +6,6 @@ import br.com.recipebook.utilitykotlin.CommonError import com.github.michaelbull.result.Result internal class RecipeCollectionRepositoryImpl constructor( - private val dataSourceLocal: RecipeCollectionDataSourceLocal, private val dataSourceRemote: RecipeCollectionDataSourceRemote ) : RecipeCollectionRepository { override suspend fun getRecipeCollection(): Result, CommonError> { diff --git a/features/recipe-collection/src/main/java/br/com/recipebook/recipecollection/di/RecipeCollectionModule.kt b/features/recipe-collection/src/main/java/br/com/recipebook/recipecollection/di/RecipeCollectionModule.kt index 15ffd90..f621a7e 100644 --- a/features/recipe-collection/src/main/java/br/com/recipebook/recipecollection/di/RecipeCollectionModule.kt +++ b/features/recipe-collection/src/main/java/br/com/recipebook/recipecollection/di/RecipeCollectionModule.kt @@ -37,7 +37,6 @@ val recipeCollectionDomainModule = module { val recipeCollectionDataModule = module { factory { RecipeCollectionRepositoryImpl( - dataSourceLocal = get(), dataSourceRemote = get() ) } diff --git a/features/recipe-collection/src/main/java/br/com/recipebook/recipecollection/presentation/RecipeCollectionViewModel.kt b/features/recipe-collection/src/main/java/br/com/recipebook/recipecollection/presentation/RecipeCollectionViewModel.kt index 9c8e64d..dacd9e9 100644 --- a/features/recipe-collection/src/main/java/br/com/recipebook/recipecollection/presentation/RecipeCollectionViewModel.kt +++ b/features/recipe-collection/src/main/java/br/com/recipebook/recipecollection/presentation/RecipeCollectionViewModel.kt @@ -8,7 +8,6 @@ import br.com.recipebook.recipecollection.domain.model.RecipeModel import br.com.recipebook.recipecollection.domain.usecase.GetRecipeCollectionUseCase import br.com.recipebook.recipecollection.view.RecipeItem import br.com.recipebook.utilityandroid.presentation.BaseViewModel -import br.com.recipebook.utilitykotlin.CommonError import com.github.michaelbull.result.onFailure import com.github.michaelbull.result.onSuccess import kotlinx.coroutines.ExperimentalCoroutinesApi @@ -55,7 +54,7 @@ class RecipeCollectionViewModel( getRecipeCollection() .onSuccess { onLoadRecipeListSuccess(it) } - .onFailure { onLoadRecipeListError(it) } + .onFailure { onLoadRecipeListError() } viewState.isLoading.value = false } @@ -72,7 +71,7 @@ class RecipeCollectionViewModel( } } - private fun onLoadRecipeListError(error: CommonError) { + private fun onLoadRecipeListError() { sendViewEvent(false) viewState.hasError.value = true viewState.recipes.value = emptyList() diff --git a/features/recipe-detail/src/main/java/br/com/recipebook/recipedetail/presentation/RecipeDetailViewModel.kt b/features/recipe-detail/src/main/java/br/com/recipebook/recipedetail/presentation/RecipeDetailViewModel.kt index dda7270..926c0a5 100644 --- a/features/recipe-detail/src/main/java/br/com/recipebook/recipedetail/presentation/RecipeDetailViewModel.kt +++ b/features/recipe-detail/src/main/java/br/com/recipebook/recipedetail/presentation/RecipeDetailViewModel.kt @@ -11,7 +11,6 @@ import br.com.recipebook.recipedetail.presentation.model.InstructionHeaderItem import br.com.recipebook.recipedetail.presentation.model.RecipeDetailItem import br.com.recipebook.recipedetail.view.RecipeDetailSafeArgs import br.com.recipebook.utilityandroid.presentation.BaseViewModel -import br.com.recipebook.utilitykotlin.CommonError import com.github.michaelbull.result.onFailure import com.github.michaelbull.result.onSuccess import kotlinx.coroutines.ExperimentalCoroutinesApi @@ -29,12 +28,11 @@ class RecipeDetailViewModel( viewModelScope.launch { viewState.title.value = safeArgs.title setLoadingState() - getRecipeDetail(safeArgs.recipeId).onSuccess(::onLoadSuccess).onFailure(::onLoadError) + getRecipeDetail(safeArgs.recipeId).onSuccess(::onLoadSuccess).onFailure { onLoadError() } } } - override fun dispatchAction(action: RecipeDetailAction) { - } + override fun dispatchAction(action: RecipeDetailAction) = Unit private fun setLoadingState() { viewState.isLoading.value = true @@ -72,7 +70,7 @@ class RecipeDetailViewModel( setSuccessState() } - private fun onLoadError(error: CommonError) { + private fun onLoadError() { sendViewEvent(false) setErrorState() } diff --git a/features/settings-theme/src/main/java/br/com/recipebook/settings/theme/presentation/SettingsThemeViewModel.kt b/features/settings-theme/src/main/java/br/com/recipebook/settings/theme/presentation/SettingsThemeViewModel.kt index 45bd6cd..b12d70b 100644 --- a/features/settings-theme/src/main/java/br/com/recipebook/settings/theme/presentation/SettingsThemeViewModel.kt +++ b/features/settings-theme/src/main/java/br/com/recipebook/settings/theme/presentation/SettingsThemeViewModel.kt @@ -7,7 +7,6 @@ import br.com.recipebook.settings.theme.domain.model.UserThemePreferenceModel import br.com.recipebook.settings.theme.domain.usecase.GetUserThemePreferenceUseCase import br.com.recipebook.settings.theme.domain.usecase.SetUserThemePreferenceUseCase import br.com.recipebook.utilityandroid.presentation.BaseViewModel -import br.com.recipebook.utilitykotlin.CommonError import com.github.michaelbull.result.onFailure import com.github.michaelbull.result.onSuccess import kotlinx.coroutines.ExperimentalCoroutinesApi @@ -24,7 +23,7 @@ class SettingsThemeViewModel( init { viewModelScope.launch { setLoadingState() - getUserThemePreference().onSuccess(::onLoadSuccess).onFailure(::onLoadError) + getUserThemePreference().onSuccess(::onLoadSuccess).onFailure{ onLoadError() } } } @@ -78,7 +77,7 @@ class SettingsThemeViewModel( setSuccessState() } - private fun onLoadError(error: CommonError) { + private fun onLoadError() { sendViewEvent(false) setErrorState() } diff --git a/features/settings/src/main/java/br/com/recipebook/settings/presentation/SettingsViewModel.kt b/features/settings/src/main/java/br/com/recipebook/settings/presentation/SettingsViewModel.kt index 5ffb2d4..fd39945 100644 --- a/features/settings/src/main/java/br/com/recipebook/settings/presentation/SettingsViewModel.kt +++ b/features/settings/src/main/java/br/com/recipebook/settings/presentation/SettingsViewModel.kt @@ -26,7 +26,7 @@ class SettingsViewModel( viewState.appVersion.value = buildConfiguration.appInfo.version viewModelScope.launch { setLoadingState() - getSettingsList().onSuccess(::onLoadSuccess).onFailure(::onLoadError) + getSettingsList().onSuccess(::onLoadSuccess).onFailure { onLoadError() } } } @@ -62,7 +62,7 @@ class SettingsViewModel( setSuccessState() } - private fun onLoadError(error: CommonError) { + private fun onLoadError() { sendViewEvent(false) setErrorState() } diff --git a/git-hooks/pre-commit b/git-hooks/pre-commit deleted file mode 100644 index a5c757e..0000000 --- a/git-hooks/pre-commit +++ /dev/null @@ -1,12 +0,0 @@ -#!/bin/bash - -echo "Running git pre-commit hook" - -./gradlew ktlint - -RESULT=$? - -# return 1 exit code if running checks fails -[ $RESULT -ne 0 ] && exit 1 -exit 0 - diff --git a/infrastructure/device/src/main/java/br/com/recipebook/device/ActivityProvider.kt b/infrastructure/device/src/main/java/br/com/recipebook/device/ActivityProvider.kt index 1162352..d65c20a 100644 --- a/infrastructure/device/src/main/java/br/com/recipebook/device/ActivityProvider.kt +++ b/infrastructure/device/src/main/java/br/com/recipebook/device/ActivityProvider.kt @@ -12,11 +12,9 @@ class ActivityProvider(application: Application) { override fun onActivityCreated( activity: Activity, savedInstanceState: Bundle? - ) { - } + ) = Unit - override fun onActivityStarted(activity: Activity) { - } + override fun onActivityStarted(activity: Activity) = Unit override fun onActivityResumed(activity: Activity) { activeActivity = activity @@ -26,17 +24,14 @@ class ActivityProvider(application: Application) { activeActivity = null } - override fun onActivityStopped(activity: Activity) { - } + override fun onActivityStopped(activity: Activity) = Unit override fun onActivitySaveInstanceState( activity: Activity, outState: Bundle - ) { - } + ) = Unit - override fun onActivityDestroyed(activity: Activity) { - } + override fun onActivityDestroyed(activity: Activity) = Unit }) } } diff --git a/infrastructure/startup/src/test/java/br/com/recipebook/startup/StartupJobsExecutorImplTest.kt b/infrastructure/startup/src/test/java/br/com/recipebook/startup/StartupJobsExecutorImplTest.kt index 463c9a7..787b3d4 100644 --- a/infrastructure/startup/src/test/java/br/com/recipebook/startup/StartupJobsExecutorImplTest.kt +++ b/infrastructure/startup/src/test/java/br/com/recipebook/startup/StartupJobsExecutorImplTest.kt @@ -57,7 +57,7 @@ class CoroutineTestRule : TestRule { } @ExperimentalCoroutinesApi -class TestDispatcherProvider() : DispatcherProvider { +class TestDispatcherProvider : DispatcherProvider { private val testCoroutineDispatcher = TestCoroutineDispatcher() override fun main() = testCoroutineDispatcher override fun default() = testCoroutineDispatcher diff --git a/quality/detekt/detekt-ci.sh b/quality/detekt/detekt-ci.sh new file mode 100755 index 0000000..2b085f8 --- /dev/null +++ b/quality/detekt/detekt-ci.sh @@ -0,0 +1,25 @@ +#!/bin/bash + +while getopts t:s: flag +do + case "${flag}" in + t) TARGET_BRANCH=${OPTARG};; + s) SOURCE_BRANCH=${OPTARG};; + esac +done + +git fetch origin $TARGET_BRANCH:$TARGET_BRANCH $SOURCE_BRANCH:$SOURCE_BRANCH --no-tags + +MODIFIED_DETEKT_FILES=$(git diff --diff-filter=ACMRd --name-only $TARGET_BRANCH...$SOURCE_BRANCH | grep 'detekt') + +if [[ $MODIFIED_DETEKT_FILES ]]; then + echo "Configuration files have changed. All files need to be analyzed." + quality/detekt/detekt-run.sh +else + FILES_TO_ANALYZE=$(git diff --diff-filter=ACMRd --name-only $TARGET_BRANCH...$SOURCE_BRANCH | grep '\.kt$') + if [[ -z "$FILES_TO_ANALYZE" ]]; then + echo "No files to analyze!" + else + quality/detekt/detekt-run.sh -i $FILES_TO_ANALYZE + fi +fi diff --git a/quality/detekt/detekt-install.sh b/quality/detekt/detekt-install.sh new file mode 100755 index 0000000..a956564 --- /dev/null +++ b/quality/detekt/detekt-install.sh @@ -0,0 +1,16 @@ +#!/bin/bash + +# Update detekt-run.sh on version update + +mkdir -p .tools + +echo "Downloading detekt cli" +curl -sSL https://github.com/detekt/detekt/releases/download/v1.19.0-RC1/detekt-cli-1.19.0-RC1.zip -o .tools/detekt-cli.zip + +echo "Extracting..." +unzip -q .tools/detekt-cli.zip -d .tools/ + +mv .tools/detekt-cli-1.19.0-RC1 .tools/detekt-cli +rm .tools/detekt-cli.zip + +echo "Installation finished" \ No newline at end of file diff --git a/quality/detekt/detekt-run.sh b/quality/detekt/detekt-run.sh new file mode 100755 index 0000000..dfef5be --- /dev/null +++ b/quality/detekt/detekt-run.sh @@ -0,0 +1,24 @@ +#!/bin/bash + +while getopts i:e: flag +do + case "${flag}" in + i) INCLUDE_PATHS=${OPTARG};; + e) EXCLUDE_PATHS=${OPTARG};; + esac +done + +# Install detekt cli if necessary +DETEKT_VERSION=$(.tools/detekt-cli/bin/detekt-cli --version) +if [[ $DETEKT_VERSION != "1.19.0-RC1" ]]; then + ./quality/detekt/detekt-install.sh +fi + +CMD=".tools/detekt-cli/bin/detekt-cli --all-rules \ +--excludes \"**/build/**,$EXCLUDE_PATHS\" " + +if [[ ! -z "$INCLUDE_PATHS" ]]; then + CMD+=" --input $INCLUDE_PATHS" +fi + +eval $CMD \ No newline at end of file diff --git a/quality/git-hooks/install-hooks.sh b/quality/git-hooks/install-hooks.sh new file mode 100755 index 0000000..fcc1f9d --- /dev/null +++ b/quality/git-hooks/install-hooks.sh @@ -0,0 +1,3 @@ +#!/bin/bash + +ln -f quality/git-hooks/pre-commit .git/hooks/pre-commit diff --git a/quality/git-hooks/pre-commit b/quality/git-hooks/pre-commit new file mode 100755 index 0000000..cfcfda2 --- /dev/null +++ b/quality/git-hooks/pre-commit @@ -0,0 +1,22 @@ +#!/bin/bash + +hook_dir="quality/git-hooks/pre-commit.d" + +echo $hook_dir + +if [[ -d $hook_dir ]]; then + stdin=$(cat /dev/stdin) + + for hook in $hook_dir/*; do + echo "$stdin" | $hook "$@" + + exit_code=$? + + if [ $exit_code != 0 ]; then + exit $exit_code + fi + done +fi + +exit 0 + diff --git a/quality/git-hooks/pre-commit.d/pre-commit-detekt.sh b/quality/git-hooks/pre-commit.d/pre-commit-detekt.sh new file mode 100755 index 0000000..975472a --- /dev/null +++ b/quality/git-hooks/pre-commit.d/pre-commit-detekt.sh @@ -0,0 +1,17 @@ +#!/bin/bash + +echo "[Pre-commit] Detekt" + +MODIFIED_DETEKT_FILES=$(git diff --diff-filter=ACMRd --name-only --cached --relative | grep 'detekt') + +if [[ $MODIFIED_DETEKT_FILES ]]; then + echo "Configuration files have changed. All files need to be analyzed." + quality/detekt/detekt-run.sh +else + FILES_TO_ANALYZE=$(git diff --diff-filter=ACMRd --name-only --cached --relative | grep '\.kt$') + if [[ -z "$FILES_TO_ANALYZE" ]]; then + echo "No files to analyze!" + else + quality/detekt/detekt-run.sh -i $FILES_TO_ANALYZE + fi +fi diff --git a/utility/utility-android/src/main/java/br/com/recipebook/utilityandroid/network/SafeApiCall.kt b/utility/utility-android/src/main/java/br/com/recipebook/utilityandroid/network/SafeApiCall.kt index 770dffb..cd118f6 100644 --- a/utility/utility-android/src/main/java/br/com/recipebook/utilityandroid/network/SafeApiCall.kt +++ b/utility/utility-android/src/main/java/br/com/recipebook/utilityandroid/network/SafeApiCall.kt @@ -9,9 +9,8 @@ import kotlinx.coroutines.withContext import retrofit2.HttpException import java.io.IOException -/** - * FIXME: This class need some improvements - */ +@Suppress("TooGenericExceptionCaught", "ForbiddenComment") +// FIXME: This class need some improvements suspend fun safeApiCall( dispatcher: CoroutineDispatcher, apiCall: suspend () -> T