diff --git a/.detekt/detekt-config.yml b/.detekt/detekt-config.yml
new file mode 100644
index 0000000..ffe88b8
--- /dev/null
+++ b/.detekt/detekt-config.yml
@@ -0,0 +1,613 @@
+build:
+ maxIssues: 0
+ excludeCorrectable: false
+ weights:
+ # complexity: 2
+ # LongParameterList: 1
+ # style: 1
+ # comments: 1
+
+config:
+ validation: true
+ # when writing own rules with new properties, exclude the property path e.g.: 'my_rule_set,.*>.*>[my_property]'
+ excludes: ''
+
+processors:
+ active: true
+ exclude:
+ - 'DetektProgressListener'
+ # - 'FunctionCountProcessor'
+ # - 'PropertyCountProcessor'
+ # - 'ClassCountProcessor'
+ # - 'PackageCountProcessor'
+ # - 'KtFileCountProcessor'
+
+console-reports:
+ active: true
+ exclude:
+ - 'ProjectStatisticsReport'
+ - 'ComplexityReport'
+ # - 'NotificationReport'
+ - 'FindingsReport'
+ # - 'FileBasedFindingsReport'
+
+comments:
+ active: true
+ excludes: '**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt'
+ AbsentOrWrongFileLicense:
+ active: false
+ licenseTemplateFile: 'license.template'
+ CommentOverPrivateFunction:
+ active: false
+ CommentOverPrivateProperty:
+ active: false
+ EndOfSentenceFormat:
+ active: false
+ endOfSentenceFormat: '([.?!][ \t\n\r\f<])|([.?!:]$)'
+ UndocumentedPublicClass:
+ active: false
+ searchInNestedClass: true
+ searchInInnerClass: true
+ searchInInnerObject: true
+ searchInInnerInterface: true
+ UndocumentedPublicFunction:
+ active: false
+ UndocumentedPublicProperty:
+ active: false
+
+complexity:
+ active: true
+ ComplexCondition:
+ active: true
+ threshold: 4
+ ComplexInterface:
+ active: false
+ threshold: 10
+ includeStaticDeclarations: false
+ includePrivateDeclarations: false
+ ComplexMethod:
+ active: true
+ threshold: 15
+ ignoreSingleWhenExpression: false
+ ignoreSimpleWhenEntries: false
+ ignoreNestingFunctions: false
+ nestingFunctions: run,let,apply,with,also,use,forEach,isNotNull,ifNull
+ LabeledExpression:
+ active: false
+ ignoredLabels: ''
+ LargeClass:
+ active: true
+ threshold: 600
+ LongMethod:
+ active: true
+ threshold: 60
+ LongParameterList:
+ active: true
+ functionThreshold: 6
+ constructorThreshold: 20
+ ignoreDefaultParameters: true
+ ignoreDataClasses: true
+ MethodOverloading:
+ active: false
+ threshold: 6
+ NestedBlockDepth:
+ active: true
+ threshold: 4
+ StringLiteralDuplication:
+ active: false
+ excludes: '**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt'
+ threshold: 3
+ ignoreAnnotation: true
+ excludeStringsWithLessThan5Characters: true
+ ignoreStringsRegex: '$^'
+ TooManyFunctions:
+ active: true
+ excludes: '**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt'
+ thresholdInFiles: 15
+ thresholdInClasses: 15
+ thresholdInInterfaces: 50 # Contracts have a lot of functions
+ thresholdInObjects: 15
+ thresholdInEnums: 15
+ ignoreDeprecated: true
+ ignorePrivate: true
+ ignoreOverridden: true
+
+coroutines:
+ active: true
+ GlobalCoroutineUsage:
+ active: true
+ RedundantSuspendModifier:
+ active: true
+
+empty-blocks:
+ active: true
+ EmptyCatchBlock:
+ active: true
+ allowedExceptionNameRegex: '^(_|(ignore|expected).*)'
+ EmptyClassBlock:
+ active: true
+ EmptyDefaultConstructor:
+ active: true
+ EmptyDoWhileBlock:
+ active: true
+ EmptyElseBlock:
+ active: true
+ EmptyFinallyBlock:
+ active: true
+ EmptyForBlock:
+ active: true
+ EmptyFunctionBlock:
+ active: true
+ ignoreOverridden: true
+ EmptyIfBlock:
+ active: true
+ EmptyInitBlock:
+ active: true
+ EmptyKtFile:
+ active: true
+ EmptySecondaryConstructor:
+ active: true
+ EmptyTryBlock:
+ active: true
+ EmptyWhenBlock:
+ active: true
+ EmptyWhileBlock:
+ active: true
+
+exceptions:
+ active: true
+ ExceptionRaisedInUnexpectedLocation:
+ active: false
+ methodNames: 'toString,hashCode,equals,finalize'
+ InstanceOfCheckForException:
+ active: false
+ excludes: '**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt'
+ NotImplementedDeclaration:
+ active: false
+ PrintStackTrace:
+ active: false
+ RethrowCaughtException:
+ active: false
+ ReturnFromFinally:
+ active: false
+ ignoreLabeled: false
+ SwallowedException:
+ active: false
+ ignoredExceptionTypes: 'InterruptedException,NumberFormatException,ParseException,MalformedURLException'
+ allowedExceptionNameRegex: '^(_|(ignore|expected).*)'
+ ThrowingExceptionFromFinally:
+ active: false
+ ThrowingExceptionInMain:
+ active: false
+ ThrowingExceptionsWithoutMessageOrCause:
+ active: false
+ exceptions: 'IllegalArgumentException,IllegalStateException,IOException'
+ ThrowingNewInstanceOfSameException:
+ active: false
+ TooGenericExceptionCaught:
+ active: false
+ excludes: '**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt'
+ exceptionNames:
+ - ArrayIndexOutOfBoundsException
+ - Error
+ - Exception
+ - IllegalMonitorStateException
+ - NullPointerException
+ - IndexOutOfBoundsException
+ - RuntimeException
+ - Throwable
+ allowedExceptionNameRegex: '^(_|(ignore|expected).*)'
+ TooGenericExceptionThrown:
+ active: true
+ exceptionNames:
+ - Error
+ - Exception
+ - Throwable
+ - RuntimeException
+
+formatting:
+ active: true
+ android: true
+ autoCorrect: true
+ AnnotationOnSeparateLine:
+ active: false
+ autoCorrect: true
+ ChainWrapping:
+ active: true
+ autoCorrect: true
+ CommentSpacing:
+ active: true
+ autoCorrect: true
+ EnumEntryNameCase:
+ active: true
+ autoCorrect: true
+ Filename:
+ active: true
+ FinalNewline:
+ active: true
+ autoCorrect: true
+ insertFinalNewLine: true
+ ImportOrdering:
+ active: false
+ autoCorrect: true
+ Indentation:
+ active: false
+ autoCorrect: true
+ indentSize: 4
+ continuationIndentSize: 4
+ MaximumLineLength:
+ active: true
+ maxLineLength: 120
+ ModifierOrdering:
+ active: true
+ autoCorrect: true
+ MultiLineIfElse:
+ active: true
+ autoCorrect: true
+ NoBlankLineBeforeRbrace:
+ active: true
+ autoCorrect: true
+ NoConsecutiveBlankLines:
+ active: true
+ autoCorrect: true
+ NoEmptyClassBody:
+ active: true
+ autoCorrect: true
+ NoEmptyFirstLineInMethodBlock:
+ active: true
+ autoCorrect: true
+ NoLineBreakAfterElse:
+ active: true
+ autoCorrect: true
+ NoLineBreakBeforeAssignment:
+ active: true
+ autoCorrect: true
+ NoMultipleSpaces:
+ active: true
+ autoCorrect: true
+ NoSemicolons:
+ active: true
+ autoCorrect: true
+ NoTrailingSpaces:
+ active: true
+ autoCorrect: true
+ NoUnitReturn:
+ active: true
+ autoCorrect: true
+ NoUnusedImports:
+ active: true
+ autoCorrect: true
+ PackageName:
+ active: true
+ autoCorrect: true
+ ParameterListWrapping:
+ active: true
+ autoCorrect: true
+ indentSize: 4
+ SpacingAroundColon:
+ active: true
+ autoCorrect: true
+ SpacingAroundComma:
+ active: true
+ autoCorrect: true
+ SpacingAroundCurly:
+ active: true
+ autoCorrect: true
+ SpacingAroundDot:
+ active: true
+ autoCorrect: true
+ SpacingAroundKeyword:
+ active: true
+ autoCorrect: true
+ SpacingAroundOperators:
+ active: true
+ autoCorrect: true
+ SpacingAroundParens:
+ active: true
+ autoCorrect: true
+ SpacingAroundRangeOperator:
+ active: true
+ autoCorrect: true
+ StringTemplate:
+ active: true
+ autoCorrect: true
+
+naming:
+ active: true
+ ClassNaming:
+ active: true
+ excludes: '**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt'
+ classPattern: '[A-Z$][a-zA-Z0-9$]*'
+ ConstructorParameterNaming:
+ active: true
+ excludes: '**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt'
+ parameterPattern: '[a-z][A-Za-z0-9]*'
+ privateParameterPattern: '[a-z][A-Za-z0-9]*'
+ excludeClassPattern: '$^'
+ ignoreOverridden: true
+ EnumNaming:
+ active: true
+ excludes: '**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt'
+ enumEntryPattern: '^[A-Z][_a-zA-Z0-9]*'
+ ForbiddenClassName:
+ active: false
+ excludes: '**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt'
+ forbiddenName: ''
+ FunctionMaxLength:
+ active: false
+ excludes: '**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt'
+ maximumFunctionNameLength: 30
+ FunctionMinLength:
+ active: false
+ excludes: '**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt'
+ minimumFunctionNameLength: 3
+ FunctionNaming:
+ active: true
+ excludes: '**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt'
+ functionPattern: '^([a-z$][a-zA-Z$0-9]*)|(`.*`)$'
+ excludeClassPattern: '$^'
+ ignoreOverridden: true
+ FunctionParameterNaming:
+ active: true
+ excludes: '**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt'
+ parameterPattern: '[a-z][A-Za-z0-9]*'
+ excludeClassPattern: '$^'
+ ignoreOverridden: true
+ InvalidPackageDeclaration:
+ active: true
+ rootPackage: ''
+ MatchingDeclarationName:
+ active: true
+ mustBeFirst: true
+ MemberNameEqualsClassName:
+ active: true
+ ignoreOverridden: true
+ ObjectPropertyNaming:
+ active: true
+ excludes: '**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt'
+ constantPattern: '[A-Za-z][_A-Za-z0-9]*'
+ propertyPattern: '[A-Za-z][_A-Za-z0-9]*'
+ privatePropertyPattern: '(_)?[A-Za-z][_A-Za-z0-9]*'
+ PackageNaming:
+ active: true
+ excludes: '**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt'
+ packagePattern: '^[a-z]+(\.[a-z][A-Za-z0-9]*)*$'
+ TopLevelPropertyNaming:
+ active: true
+ excludes: '**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt'
+ constantPattern: '[A-Z][_A-Z0-9]*'
+ propertyPattern: '[A-Za-z][_A-Za-z0-9]*'
+ privatePropertyPattern: '_?[A-Za-z][_A-Za-z0-9]*'
+ VariableMaxLength:
+ active: false
+ excludes: '**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt'
+ maximumVariableNameLength: 64
+ VariableMinLength:
+ active: false
+ excludes: '**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt'
+ minimumVariableNameLength: 1
+ VariableNaming:
+ active: true
+ excludes: '**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt'
+ variablePattern: '[a-z][A-Za-z0-9]*'
+ privateVariablePattern: '(_)?[a-z][A-Za-z0-9]*'
+ excludeClassPattern: '$^'
+ ignoreOverridden: true
+
+performance:
+ active: true
+ ArrayPrimitive:
+ active: true
+ ForEachOnRange:
+ active: true
+ excludes: '**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt'
+ SpreadOperator:
+ active: true
+ excludes: '**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt'
+ UnnecessaryTemporaryInstantiation:
+ active: true
+
+potential-bugs:
+ active: true
+ Deprecation:
+ active: true
+ DuplicateCaseInWhenExpression:
+ active: true
+ EqualsAlwaysReturnsTrueOrFalse:
+ active: true
+ EqualsWithHashCodeExist:
+ active: true
+ ExplicitGarbageCollectionCall:
+ active: true
+ HasPlatformType:
+ active: false
+ ImplicitDefaultLocale:
+ active: false
+ InvalidRange:
+ active: true
+ IteratorHasNextCallsNextMethod:
+ active: true
+ IteratorNotThrowingNoSuchElementException:
+ active: true
+ LateinitUsage:
+ active: false
+ excludes: '**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt'
+ excludeAnnotatedProperties: ''
+ ignoreOnClassesPattern: ''
+ MapGetWithNotNullAssertionOperator:
+ active: false
+ MissingWhenCase:
+ active: true
+ RedundantElseInWhen:
+ active: true
+ UnconditionalJumpStatementInLoop:
+ active: false
+ UnreachableCode:
+ active: true
+ UnsafeCallOnNullableType:
+ active: true
+ UnsafeCast:
+ active: false
+ UselessPostfixExpression:
+ active: false
+ WrongEqualsTypeParameter:
+ active: true
+
+style:
+ active: true
+ CollapsibleIfStatements:
+ active: false
+ DataClassContainsFunctions:
+ active: false
+ conversionFunctionPrefix: 'to'
+ DataClassShouldBeImmutable:
+ active: false
+ EqualsNullCall:
+ active: true
+ EqualsOnSignatureLine:
+ active: false
+ ExplicitCollectionElementAccessMethod:
+ active: false
+ ExplicitItLambdaParameter:
+ active: false
+ ExpressionBodySyntax:
+ active: false
+ includeLineWrapping: false
+ ForbiddenComment:
+ active: true
+ values: 'TODO_NOW:,STOPSHIP:'
+ allowedPatterns: ''
+ ForbiddenImport:
+ active: false
+ imports: []
+ forbiddenPatterns: ''
+ ForbiddenMethodCall:
+ active: false
+ methods: ''
+ ForbiddenPublicDataClass:
+ active: false
+ ignorePackages: '*.internal,*.internal.*'
+ ForbiddenVoid:
+ active: false
+ ignoreOverridden: false
+ ignoreUsageInGenerics: false
+ FunctionOnlyReturningConstant:
+ active: true
+ ignoreOverridableFunction: true
+ excludedFunctions: 'describeContents'
+ excludeAnnotatedFunction: 'dagger.Provides'
+ LibraryCodeMustSpecifyReturnType:
+ active: true
+ LoopWithTooManyJumpStatements:
+ active: true
+ maxJumpCount: 1
+ MagicNumber:
+ active: true
+ excludes: '**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt'
+ ignoreNumbers: '-1,0,1,2,100'
+ ignoreHashCodeFunction: true
+ ignorePropertyDeclaration: false
+ ignoreLocalVariableDeclaration: false
+ ignoreConstantDeclaration: true
+ ignoreCompanionObjectPropertyDeclaration: true
+ ignoreAnnotation: false
+ ignoreNamedArgument: true
+ ignoreEnums: false
+ ignoreRanges: false
+ MandatoryBracesIfStatements:
+ active: false
+ MaxLineLength:
+ active: true
+ maxLineLength: 120
+ excludePackageStatements: true
+ excludeImportStatements: true
+ excludeCommentStatements: true
+ MayBeConst:
+ active: true
+ ModifierOrder:
+ active: true
+ NestedClassesVisibility:
+ active: false
+ NewLineAtEndOfFile:
+ active: true
+ NoTabs:
+ active: false
+ OptionalAbstractKeyword:
+ active: true
+ OptionalUnit:
+ active: false
+ OptionalWhenBraces:
+ active: false
+ PreferToOverPairSyntax:
+ active: false
+ ProtectedMemberInFinalClass:
+ active: true
+ RedundantExplicitType:
+ active: false
+ RedundantVisibilityModifierRule:
+ active: false
+ ReturnCount:
+ active: true
+ max: 2
+ excludedFunctions: 'equals'
+ excludeLabeled: false
+ excludeReturnFromLambda: true
+ excludeGuardClauses: false
+ SafeCast:
+ active: true
+ SerialVersionUIDInSerializableClass:
+ active: false
+ SpacingBetweenPackageAndImports:
+ active: false
+ ThrowsCount:
+ active: true
+ max: 2
+ TrailingWhitespace:
+ active: false
+ UnderscoresInNumericLiterals:
+ active: false
+ acceptableDecimalLength: 5
+ UnnecessaryAbstractClass:
+ active: true
+ excludeAnnotatedClasses: 'dagger.Module'
+ UnnecessaryAnnotationUseSiteTarget:
+ active: false
+ UnnecessaryApply:
+ active: false
+ UnnecessaryInheritance:
+ active: true
+ UnnecessaryLet:
+ active: false
+ UnnecessaryParentheses:
+ active: false
+ UntilInsteadOfRangeTo:
+ active: false
+ UnusedImports:
+ active: false
+ UnusedPrivateClass:
+ active: true
+ UnusedPrivateMember:
+ active: false
+ allowedNames: '(_|ignored|expected|serialVersionUID)'
+ UseArrayLiteralsInAnnotations:
+ active: false
+ UseCheckOrError:
+ active: false
+ UseDataClass:
+ active: false
+ excludeAnnotatedClasses: ''
+ allowVars: false
+ UseIfInsteadOfWhen:
+ active: false
+ UseRequire:
+ active: false
+ UselessCallOnNotNull:
+ active: true
+ UtilityClassWithPublicConstructor:
+ active: true
+ VarCouldBeVal:
+ active: false
+ WildcardImport:
+ active: true
+ excludes: '**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt'
+ excludeImports: 'java.util.*,kotlinx.android.synthetic.*'
diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS
new file mode 100644
index 0000000..46648db
--- /dev/null
+++ b/.github/CODEOWNERS
@@ -0,0 +1 @@
+* @xmartlabs/android-open-source
diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md
new file mode 100644
index 0000000..e9e4cd1
--- /dev/null
+++ b/.github/PULL_REQUEST_TEMPLATE.md
@@ -0,0 +1,33 @@
+## :link: Github Issue reference:
+
+
+
+## Description:
+
+
+
+
+## :camera_flash: UI preview
+
+
+
+
+## :pushpin: Notes:
+
+
+
+
+## :warning: Warnings:
+
+
diff --git a/.github/workflows/check_and_compile.yml b/.github/workflows/check_and_compile.yml
new file mode 100644
index 0000000..5945a69
--- /dev/null
+++ b/.github/workflows/check_and_compile.yml
@@ -0,0 +1,48 @@
+name: Check and compile
+on: [push]
+jobs:
+ build:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v2
+ - name: Cache gradle cache
+ uses: actions/cache@v1.1.2
+ with:
+ path: ~/.gradle/caches
+ key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle') }}
+ restore-keys: |
+ ${{ runner.os }}-gradle-
+ - name: Cache gradle wrapper
+ uses: actions/cache@v1.1.2
+ with:
+ path: ~/.gradle/wrapper
+ key: ${{ runner.os }}-gradlewrapper-${{ hashFiles('**/gradle-wrapper.properties') }}
+ restore-keys: |
+ ${{ runner.os }}-gradlegradlewrapper-
+ - name: Cache android cache
+ uses: actions/cache@v1.1.2
+ with:
+ path: ~/.android/build-cache
+ key: ${{ runner.os }}-android-cache
+ restore-keys: |
+ ${{ runner.os }}-gradlegradlewrapper-
+ - name: Gradle Initialization
+ run: ./gradlew
+ - name: Detekt
+ run: ./gradlew detekt
+ - name: Upload Detekt report
+ uses: actions/upload-artifact@v1
+ if: failure()
+ with:
+ name: Detekt report
+ path: build/reports/detekt/detekt.html
+ - name: Android Lints
+ run: ./gradlew lint
+ - name: Upload Lint report
+ uses: actions/upload-artifact@v1
+ if: failure()
+ with:
+ name: Lints report
+ path: app/build/reports/lint-results-devDebug.html
+ - name: Build
+ run: ./gradlew build
diff --git a/.github/workflows/test_master_dependencies.yml b/.github/workflows/test_master_dependencies.yml
new file mode 100644
index 0000000..90acc3b
--- /dev/null
+++ b/.github/workflows/test_master_dependencies.yml
@@ -0,0 +1,39 @@
+name: Check master Jitpack's dependency
+on:
+ push:
+ branches:
+ - master
+jobs:
+ check_jitpack_master_build:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v2
+ - name: Cache gradle cache
+ uses: actions/cache@v1.1.2
+ with:
+ path: ~/.gradle/caches
+ key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle') }}
+ restore-keys: |
+ ${{ runner.os }}-gradle-
+ - name: Cache gradle wrapper
+ uses: actions/cache@v1.1.2
+ with:
+ path: ~/.gradle/wrapper
+ key: ${{ runner.os }}-gradlewrapper-${{ hashFiles('**/gradle-wrapper.properties') }}
+ restore-keys: |
+ ${{ runner.os }}-gradlegradlewrapper-
+ - name: Cache android cache
+ uses: actions/cache@v1.1.2
+ with:
+ path: ~/.android/build-cache
+ key: ${{ runner.os }}-android-cache
+ restore-keys: |
+ ${{ runner.os }}-gradlegradlewrapper-
+ - name: Use master dependencies in app
+ run: |
+ perl -i -pe "s/project\(\"\:core\"\)/\"com.github.xmartlabs.AndroidSwissKnife:core:master-SNAPSHOT\"/gi" app/build.gradle
+ perl -i -pe "s/project\(\"\:navigation\"\)/\"com.github.xmartlabs.AndroidSwissKnife:navigation:master-SNAPSHOT\"/gi" app/build.gradle
+ perl -i -pe "s/project\(\"\:navigation-debug\"\)/\"com.github.xmartlabs.AndroidSwissKnife:navigation-debug:master-SNAPSHOT\"/gi" app/build.gradle
+ perl -i -pe "s/project\(\"\:reflection\"\)/\"com.github.xmartlabs.AndroidSwissKnife:reflection:master-SNAPSHOT\"/gi" app/build.gradle
+ - name: Build Sample app with master dependencies
+ run: ./gradlew build -Dhttp.socketTimeout=80000 -Dhttp.connectionTimeout=80000 --refresh-dependencies
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..9038c8a
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,14 @@
+*.iml
+*/obj
+.gradle
+/local.properties
+/.idea/workspace.xml
+/.idea/libraries
+.DS_Store
+/build
+/captures
+.externalNativeBuild
+.idea
+build
+/reports
+/secrets
diff --git a/README.md b/README.md
index aded7e5..2cab1f7 100644
--- a/README.md
+++ b/README.md
@@ -1 +1,33 @@
-# AndroidSwissKnife
\ No newline at end of file
+# AndroidSwissKnife
+![Check and compile](https://github.com/xmartlabs/AndroidSwissKnife/workflows/Check%20and%20compile/badge.svg)
+![Check and compile](https://github.com/xmartlabs/AndroidSwissKnife/workflows/Check%20and%20compile/badge.svg?branch=master)
+[![Release](https://jitpack.io/v/xmartlabs/AndroidSwissKnife.svg)](https://jitpack.io/#xmartlabs/AndroidSwissKnife)
+
+A library that contains a series of extensions, helpers, and useful classes used in most of [Xmartlabs' Android Projects](https://www.xmartlabs.com/).
+
+It's divided into a series of modules with different proposes:
+- [Core](/core): Core extensions of the application, for example view's and resource's extensions.
+- [Navigation](/navigation): Navigation extensions and useful helper classes related to [Navigation Architecture Component].
+- [Navigation-debug](/navigation-debug): A series of extensions and useful tools to debug and log important information of the [Navigation Architecture Component].
+- [Reflection](/reflection): A series of extensions useful when you are dealing with Reflection.
+
+## Setup
+Add library to project dependencies with JitPack.
+
+```groovy
+repositories {
+ maven { url "https://jitpack.io" }
+}
+
+dependencies {
+ implementation "com.github.xmartlabs.AndroidSwissKnife:core:${master-latest-hash-commit}"
+ implementation "com.github.xmartlabs.AndroidSwissKnife:navigation:${master-latest-hash-commit}"
+ implementation "com.github.xmartlabs.AndroidSwissKnife:navigation-debug:${master-latest-hash-commit}"
+ implementation "com.github.xmartlabs.AndroidSwissKnife:reflection:${master-latest-hash-commit}"
+}
+```
+
+## About
+Made with ❤️ by [XMARTLABS](http://xmartlabs.com)
+
+[Navigation Architecture Component]: https://developer.android.com/guide/navigation/navigation-getting-started
diff --git a/app/.gitignore b/app/.gitignore
new file mode 100644
index 0000000..796b96d
--- /dev/null
+++ b/app/.gitignore
@@ -0,0 +1 @@
+/build
diff --git a/app/build.gradle b/app/build.gradle
new file mode 100644
index 0000000..d16e711
--- /dev/null
+++ b/app/build.gradle
@@ -0,0 +1,52 @@
+apply plugin: 'com.android.application'
+apply plugin: 'kotlin-android'
+apply plugin: 'kotlin-android-extensions'
+
+android {
+ compileSdkVersion androidVersions.compileSdk
+ buildToolsVersion androidVersions.buildTools
+
+ defaultConfig {
+ applicationId "com.xmartlabs.swissknife.sample"
+ minSdkVersion androidVersions.minSdk
+ targetSdkVersion androidVersions.targetSdk
+ versionCode 1
+ versionName "1.0"
+
+ testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
+ }
+
+ buildTypes {
+ release {
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
+ }
+ }
+ compileOptions {
+ sourceCompatibility JavaVersion.VERSION_1_8
+ targetCompatibility JavaVersion.VERSION_1_8
+ }
+ kotlinOptions {
+ jvmTarget = "1.8"
+ }
+}
+
+dependencies {
+ implementation project(":core")
+ implementation project(":navigation")
+ implementation project(":navigation-debug")
+ implementation project(":reflection")
+
+ implementation deps.androidX.appcompat
+ implementation deps.androidX.constraintLayout
+ implementation deps.androidX.core
+ implementation deps.androidX.navigation.fragment
+ implementation deps.androidX.navigation.ui
+ implementation deps.kotlin.core
+ implementation deps.material
+ implementation deps.timber
+
+ testImplementation deps.junit
+ androidTestImplementation deps.androidX.test.junit
+ androidTestImplementation deps.androidX.test.espresso
+}
diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro
new file mode 100644
index 0000000..f1b4245
--- /dev/null
+++ b/app/proguard-rules.pro
@@ -0,0 +1,21 @@
+# Add project specific ProGuard rules here.
+# You can control the set of applied configuration files using the
+# proguardFiles setting in build.gradle.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+# public *;
+#}
+
+# Uncomment this to preserve the line number information for
+# debugging stack traces.
+#-keepattributes SourceFile,LineNumberTable
+
+# If you keep the line number information, uncomment this to
+# hide the original source file name.
+#-renamesourcefileattribute SourceFile
diff --git a/app/src/androidTest/java/com/xmartlabs/swissknife/sample/ExampleInstrumentedTest.kt b/app/src/androidTest/java/com/xmartlabs/swissknife/sample/ExampleInstrumentedTest.kt
new file mode 100644
index 0000000..e1219a8
--- /dev/null
+++ b/app/src/androidTest/java/com/xmartlabs/swissknife/sample/ExampleInstrumentedTest.kt
@@ -0,0 +1,22 @@
+package com.xmartlabs.swissknife.sample
+
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.platform.app.InstrumentationRegistry
+import org.junit.Assert.assertEquals
+import org.junit.Test
+import org.junit.runner.RunWith
+
+/**
+ * Instrumented test, which will execute on an Android device.
+ *
+ * See [testing documentation](http://d.android.com/tools/testing).
+ */
+@RunWith(AndroidJUnit4::class)
+class ExampleInstrumentedTest {
+ @Test
+ fun useAppContext() {
+ // Context of the app under test.
+ val appContext = InstrumentationRegistry.getInstrumentation().targetContext
+ assertEquals("com.xmartlabs.swissknife.sample", appContext.packageName)
+ }
+}
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..ce931a6
--- /dev/null
+++ b/app/src/main/AndroidManifest.xml
@@ -0,0 +1,28 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/java/com/xmartlabs/swissknife/sample/FirstFragment.kt b/app/src/main/java/com/xmartlabs/swissknife/sample/FirstFragment.kt
new file mode 100644
index 0000000..6386ad6
--- /dev/null
+++ b/app/src/main/java/com/xmartlabs/swissknife/sample/FirstFragment.kt
@@ -0,0 +1,21 @@
+package com.xmartlabs.swissknife.sample
+
+import android.os.Bundle
+import android.view.View
+import android.widget.Button
+import androidx.fragment.app.Fragment
+import androidx.navigation.fragment.findNavController
+import com.xmartlabs.swissknife.navigation.navigateSafe
+
+/**
+ * A simple [Fragment] subclass as the default destination in the navigation.
+ */
+class FirstFragment : Fragment(R.layout.fragment_first) {
+ override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+ super.onViewCreated(view, savedInstanceState)
+
+ view.findViewById