diff --git a/.taskcluster.yml b/.taskcluster.yml index d3747da6c90..138b5296a5b 100644 --- a/.taskcluster.yml +++ b/.taskcluster.yml @@ -34,7 +34,7 @@ tasks: && git checkout ${event.pull_request.head.sha} && echo "--" > .adjust_token && python tools/l10n/check_locales.py - && ./gradlew --no-daemon clean assembleFocusDebug assembleKlarNightly assembleRelease detektCheck ktlint lintFocusDebug lintKlarNightly assembleFocusDebugAndroidTest testFocusDebugUnitTest testKlarNightlyUnitTest + && ./gradlew --no-daemon clean assembleFocusDebug assembleKlarNightly assembleRelease detekt ktlint lintFocusDebug lintKlarNightly assembleFocusDebugAndroidTest testFocusDebugUnitTest testKlarNightlyUnitTest && pip install "compare-locales>=5.0.2,<6.0" && compare-locales --validate l10n.toml . artifacts: diff --git a/build.gradle b/build.gradle index 335b6af584d..c8dea1ad01f 100644 --- a/build.gradle +++ b/build.gradle @@ -31,17 +31,22 @@ plugins { // limitations of the gradle plugin. We've decided to stick with duplication for now since the // other methods involve using undocumented APIs // https://docs.gradle.org/current/userguide/plugins.html#plugins_dsl_limitations - id "io.gitlab.arturbosch.detekt" version "1.0.0.RC6-3" + id("io.gitlab.arturbosch.detekt").version("1.16.0") } detekt { // The version number is duplicated, please refer to plugins block for more details - version = "1.0.0.RC6-3" - profile("main") { - input = "$projectDir" - config = "$projectDir/quality/detekt.yml" - filters = ".*test.*,.*/resources/.*,.*/tmp/.*" - output = "$projectDir/app/build/reports/detekt" + version = "1.16.0" + buildUponDefaultConfig = true + input = files("$projectDir/app") + config = files("$projectDir/quality/detekt.yml") + baseline = file("$projectDir/quality/detekt-baseline.xml") + + reports { + html { + enabled = true + destination = file("$projectDir/build/reports/detekt.html") + } } } diff --git a/quality/detekt-baseline.xml b/quality/detekt-baseline.xml new file mode 100644 index 00000000000..466cce16394 --- /dev/null +++ b/quality/detekt-baseline.xml @@ -0,0 +1,208 @@ + + + + + EmptyFunctionBlock:AnimatedProgressBar.kt$AnimatedProgressBar.<no name provided>${} + EmptyFunctionBlock:AutocompleteListFragment.kt$AutocompleteListFragment.<no name provided>${} + EmptyFunctionBlock:CustomTabTest.kt$CustomTabTest${} + EmptyFunctionBlock:ExceptionsListFragment.kt$ExceptionsListFragment.<no name provided>${} + EmptyFunctionBlock:FirstrunFragment.kt$FirstrunFragment.<no name provided>${} + EmptyFunctionBlock:ManualAddSearchEnginePreference.kt$ManualAddSearchEnginePreference.<no name provided>${} + EmptyFunctionBlock:TabSheetFragment.kt$TabSheetFragment${} + FunctionOnlyReturningConstant:Settings.kt$Settings$fun shouldBlockImages(): Boolean + ImplicitDefaultLocale:LocalizedContent.kt$LocalizedContent$String.format( "%s (Build #%s)", packageInfo.versionName, packageInfo.versionCode.toString() + engineIndicator ) + ImplicitDefaultLocale:URLMismatchTest.kt$URLMismatchTest$String.format("mozilla focus - %s Search", "google") + LongMethod:BrowserFragment.kt$BrowserFragment$@Suppress("ComplexMethod") override fun onClick(view: View) + LongMethod:BrowserMenuAdapter.kt$BrowserMenuAdapter$private fun initializeMenu(url: String, customTabConfig: CustomTabConfig?) + LongMethod:MultitaskingTest.kt$MultitaskingTest$@Test fun testVisitingMultipleSites() + LongMethod:UrlInputFragment.kt$UrlInputFragment$ // This method correctly triggers a complexity warning. This method is indeed very and too complex. // However refactoring it is not trivial at this point so we ignore the warning for now. @Suppress("ComplexMethod") private fun playVisibilityAnimation(reverse: Boolean) + MatchingDeclarationName:SettingsSearchMenuRobot.kt$SearchSettingsRobot + MaxLineLength:MobileMetricsPingStorageTest.kt$MobileMetricsPingStorageTest$private val file = File("${(ApplicationProvider.getApplicationContext() as FocusApplication).cacheDir}/${MobileMetricsPingStorage.STORAGE_FOLDER}/${MobileMetricsPingStorage.FILE_NAME}") + MaxLineLength:StringTest.kt$StringTest$"http://amazon.com/Mockingjay-Hunger-Games-Suzanne-Collins/dp/0545663261/ref=pd_sim_14_2?_encoding=UTF8&psc=1&refRID=90ZHE3V976TKBGDR9VAM" + MaxLineLength:StringTest.kt$StringTest$"https://www.nytimes.com/2017/08/30/world/europe/princess-diana-death-anniversary.html?hp&action=click&pgtype=Homepage&clickSource=story-heading&module=second-column-region&region=top-news&WT.nav=top-news" + MaxLineLength:StringTest.kt$StringTest$"https://www.wsj.com/articles/mexican-presidential-candidate-calls-for-nafta-talks-to-be-suspended-1504137175" + MaxLineLength:SwitchLocaleTest.kt$SwitchLocaleTest$/* re-enter settings and general settings, change it back to system locale, verify the locale is changed */ + MaxLineLength:UriTest.kt$UriTest$assertTruncatedHost("yahoo.com", "https://de.search.yahoo.com/search?p=mozilla&fr=yfp-t&fp=1&toggle=1&cop=mss&ei=UTF-8") + MayBeConst:AddToHomescreenDialogFragment.kt$AddToHomescreenDialogFragment.Companion$private val BLOCKING_ENABLED = "blocking_enabled" + MayBeConst:AddToHomescreenDialogFragment.kt$AddToHomescreenDialogFragment.Companion$private val REQUEST_DESKTOP = "request_desktop" + MayBeConst:AddToHomescreenDialogFragment.kt$AddToHomescreenDialogFragment.Companion$private val TITLE = "title" + MayBeConst:AddToHomescreenDialogFragment.kt$AddToHomescreenDialogFragment.Companion$private val URL = "url" + MayBeConst:AddToHomescreenDialogFragment.kt$AddToHomescreenDialogFragment.Companion$val FRAGMENT_TAG = "add-to-homescreen-prompt-dialog" + MayBeConst:AnimatedProgressBar.kt$AnimatedProgressBar.Companion$private val CLOSING_DELAY = 300 + MayBeConst:AnimatedProgressBar.kt$AnimatedProgressBar.Companion$private val CLOSING_DURATION = 300 + MayBeConst:AnimatedProgressBar.kt$AnimatedProgressBar.Companion$private val DEFAULT_DURATION = 1000 + MayBeConst:AnimatedProgressBar.kt$AnimatedProgressBar.Companion$private val DEFAULT_RESOURCE_ID = 0 + MayBeConst:AnimatedProgressBar.kt$AnimatedProgressBar.Companion$private val PROGRESS_DURATION = 200 + MayBeConst:BiometricAuthenticationDialogFragment.kt$BiometricAuthenticationDialogFragment.Companion$val FRAGMENT_TAG = "biometric-dialog-fragment" + MayBeConst:CrashReporterFragment.kt$CrashReporterFragment.Companion$val FRAGMENT_TAG = "crash-reporter" + MayBeConst:Features.kt$Features.Companion$val SEARCH_TERMS_OR_URL: Boolean = true + MayBeConst:IconGenerator.kt$IconGenerator.Companion$private val DEFAULT_ICON_CHAR = '?' + MayBeConst:IconGenerator.kt$IconGenerator.Companion$private val TEXT_SIZE_DP = 36f + MayBeConst:ManualAddSearchEnginePreference.kt$ManualAddSearchEnginePreference.Companion$private val SEARCH_ENGINE_NAME_KEY = "search-engine-name" + MayBeConst:ManualAddSearchEnginePreference.kt$ManualAddSearchEnginePreference.Companion$private val SEARCH_QUERY_KEY = "search-query" + MayBeConst:ManualAddSearchEnginePreference.kt$ManualAddSearchEnginePreference.Companion$private val SUPER_STATE_KEY = "super-state" + MayBeConst:SettingsActivity.kt$SettingsActivity.Companion$@JvmField val ACTIVITY_RESULT_LOCALE_CHANGED = 1 + MayBeConst:TelemetryWrapper.kt$TelemetryWrapper.Category$val ACTION = "action" + MayBeConst:TelemetryWrapper.kt$TelemetryWrapper.Category$val ERROR = "error" + MayBeConst:TelemetryWrapper.kt$TelemetryWrapper.Category$val HISTOGRAM = "histogram" + MayBeConst:TelemetryWrapper.kt$TelemetryWrapper.Extra$val AUTOCOMPLETE = "autocomplete" + MayBeConst:TelemetryWrapper.kt$TelemetryWrapper.Extra$val ERROR_CODE = "error_code" + MayBeConst:TelemetryWrapper.kt$TelemetryWrapper.Extra$val FROM = "from" + MayBeConst:TelemetryWrapper.kt$TelemetryWrapper.Extra$val HIGHLIGHTED = "highlighted" + MayBeConst:TelemetryWrapper.kt$TelemetryWrapper.Extra$val SEARCH_SUGGESTION = "search_suggestion" + MayBeConst:TelemetryWrapper.kt$TelemetryWrapper.Extra$val SELECTED = "selected" + MayBeConst:TelemetryWrapper.kt$TelemetryWrapper.Extra$val SOURCE = "source" + MayBeConst:TelemetryWrapper.kt$TelemetryWrapper.Extra$val SUBMIT_CRASH = "submit_crash" + MayBeConst:TelemetryWrapper.kt$TelemetryWrapper.Extra$val SUCCESS = "success" + MayBeConst:TelemetryWrapper.kt$TelemetryWrapper.Extra$val TO = "to" + MayBeConst:TelemetryWrapper.kt$TelemetryWrapper.Extra$val TOTAL = "total" + MayBeConst:TelemetryWrapper.kt$TelemetryWrapper.Extra$val TOTAL_URI_COUNT = "total_uri_count" + MayBeConst:TelemetryWrapper.kt$TelemetryWrapper.Extra$val UNIQUE_DOMAINS_COUNT = "unique_domains_count" + MayBeConst:TelemetryWrapper.kt$TelemetryWrapper.Method$val BACKGROUND = "background" + MayBeConst:TelemetryWrapper.kt$TelemetryWrapper.Method$val CANCEL = "cancel" + MayBeConst:TelemetryWrapper.kt$TelemetryWrapper.Method$val CHANGE = "change" + MayBeConst:TelemetryWrapper.kt$TelemetryWrapper.Method$val CLICK = "click" + MayBeConst:TelemetryWrapper.kt$TelemetryWrapper.Method$val COPY = "copy" + MayBeConst:TelemetryWrapper.kt$TelemetryWrapper.Method$val FOREGROUND = "foreground" + MayBeConst:TelemetryWrapper.kt$TelemetryWrapper.Method$val HIDE = "hide" + MayBeConst:TelemetryWrapper.kt$TelemetryWrapper.Method$val INSTALL = "install" + MayBeConst:TelemetryWrapper.kt$TelemetryWrapper.Method$val INTENT_CUSTOM_TAB = "intent_custom_tab" + MayBeConst:TelemetryWrapper.kt$TelemetryWrapper.Method$val INTENT_URL = "intent_url" + MayBeConst:TelemetryWrapper.kt$TelemetryWrapper.Method$val LONG_PRESS = "long_press" + MayBeConst:TelemetryWrapper.kt$TelemetryWrapper.Method$val OPEN = "open" + MayBeConst:TelemetryWrapper.kt$TelemetryWrapper.Method$val PAGE = "page" + MayBeConst:TelemetryWrapper.kt$TelemetryWrapper.Method$val REMOVE = "remove" + MayBeConst:TelemetryWrapper.kt$TelemetryWrapper.Method$val REMOVE_ALL = "remove_all" + MayBeConst:TelemetryWrapper.kt$TelemetryWrapper.Method$val REORDER = "reorder" + MayBeConst:TelemetryWrapper.kt$TelemetryWrapper.Method$val RESOURCE = "resource" + MayBeConst:TelemetryWrapper.kt$TelemetryWrapper.Method$val RESTORE = "restore" + MayBeConst:TelemetryWrapper.kt$TelemetryWrapper.Method$val SAVE = "save" + MayBeConst:TelemetryWrapper.kt$TelemetryWrapper.Method$val SHARE = "share" + MayBeConst:TelemetryWrapper.kt$TelemetryWrapper.Method$val SHARE_INTENT = "share_intent" + MayBeConst:TelemetryWrapper.kt$TelemetryWrapper.Method$val SHOW = "show" + MayBeConst:TelemetryWrapper.kt$TelemetryWrapper.Method$val SWIPE = "swipe" + MayBeConst:TelemetryWrapper.kt$TelemetryWrapper.Method$val TEXT_SELECTION_INTENT = "text_selection_intent" + MayBeConst:TelemetryWrapper.kt$TelemetryWrapper.Method$val TYPE_QUERY = "type_query" + MayBeConst:TelemetryWrapper.kt$TelemetryWrapper.Method$val TYPE_SELECT_QUERY = "select_query" + MayBeConst:TelemetryWrapper.kt$TelemetryWrapper.Method$val TYPE_URL = "type_url" + MayBeConst:TelemetryWrapper.kt$TelemetryWrapper.Object$val ADD_SEARCH_ENGINE_LEARN_MORE = "search_engine_learn_more" + MayBeConst:TelemetryWrapper.kt$TelemetryWrapper.Object$val ADD_TO_HOMESCREEN_DIALOG = "add_to_homescreen_dialog" + MayBeConst:TelemetryWrapper.kt$TelemetryWrapper.Object$val ALLOWLIST = "allowlist" + MayBeConst:TelemetryWrapper.kt$TelemetryWrapper.Object$val APP = "app" + MayBeConst:TelemetryWrapper.kt$TelemetryWrapper.Object$val APP_ICON = "app_icon" + MayBeConst:TelemetryWrapper.kt$TelemetryWrapper.Object$val AUTOCOMPLETE_DOMAIN = "autocomplete_domain" + MayBeConst:TelemetryWrapper.kt$TelemetryWrapper.Object$val AUTOFILL = "autofill" + MayBeConst:TelemetryWrapper.kt$TelemetryWrapper.Object$val BACK_BUTTON = "back_button" + MayBeConst:TelemetryWrapper.kt$TelemetryWrapper.Object$val BLOCKING_SWITCH = "blocking_switch" + MayBeConst:TelemetryWrapper.kt$TelemetryWrapper.Object$val BROWSER = "browser" + MayBeConst:TelemetryWrapper.kt$TelemetryWrapper.Object$val BROWSER_CONTEXTMENU = "browser_contextmenu" + MayBeConst:TelemetryWrapper.kt$TelemetryWrapper.Object$val CRASH_REPORTER = "crash_reporter" + MayBeConst:TelemetryWrapper.kt$TelemetryWrapper.Object$val CUSTOM_SEARCH_ENGINE = "custom_search_engine" + MayBeConst:TelemetryWrapper.kt$TelemetryWrapper.Object$val CUSTOM_TAB_ACTION_BUTTON = "custom_tab_action_bu" + MayBeConst:TelemetryWrapper.kt$TelemetryWrapper.Object$val CUSTOM_TAB_CLOSE_BUTTON = "custom_tab_close_but" + MayBeConst:TelemetryWrapper.kt$TelemetryWrapper.Object$val DESKTOP_REQUEST_CHECK = "desktop_request_check" + MayBeConst:TelemetryWrapper.kt$TelemetryWrapper.Object$val DOWNLOAD_DIALOG = "download_dialog" + MayBeConst:TelemetryWrapper.kt$TelemetryWrapper.Object$val ERASE_BUTTON = "erase_button" + MayBeConst:TelemetryWrapper.kt$TelemetryWrapper.Object$val FIRSTRUN = "firstrun" + MayBeConst:TelemetryWrapper.kt$TelemetryWrapper.Object$val GECKO_ENGINE = "gecko_engine" + MayBeConst:TelemetryWrapper.kt$TelemetryWrapper.Object$val HOMESCREEN_SHORTCUT = "homescreen_shortcut" + MayBeConst:TelemetryWrapper.kt$TelemetryWrapper.Object$val MAKE_DEFAULT_BROWSER_OPEN_WITH = "make_default_browser_open_with" + MayBeConst:TelemetryWrapper.kt$TelemetryWrapper.Object$val MAKE_DEFAULT_BROWSER_SETTINGS = "make_default_browser_settings" + MayBeConst:TelemetryWrapper.kt$TelemetryWrapper.Object$val MENU = "menu" + MayBeConst:TelemetryWrapper.kt$TelemetryWrapper.Object$val NOTIFICATION = "notification" + MayBeConst:TelemetryWrapper.kt$TelemetryWrapper.Object$val NOTIFICATION_ACTION = "notification_action" + MayBeConst:TelemetryWrapper.kt$TelemetryWrapper.Object$val RECENT_APPS = "recent_apps" + MayBeConst:TelemetryWrapper.kt$TelemetryWrapper.Object$val REMOVE_SEARCH_ENGINES = "remove_search_engines" + MayBeConst:TelemetryWrapper.kt$TelemetryWrapper.Object$val SEARCH_BAR = "search_bar" + MayBeConst:TelemetryWrapper.kt$TelemetryWrapper.Object$val SEARCH_ENGINE_SETTING = "search_engine_setting" + MayBeConst:TelemetryWrapper.kt$TelemetryWrapper.Object$val SEARCH_SUGGESTION_PROMPT = "search_suggestion_prompt" + MayBeConst:TelemetryWrapper.kt$TelemetryWrapper.Object$val SETTING = "setting" + MayBeConst:TelemetryWrapper.kt$TelemetryWrapper.Object$val SHORTCUT = "shortcut" + MayBeConst:TelemetryWrapper.kt$TelemetryWrapper.Object$val TABS_TRAY = "tabs_tray" + MayBeConst:TelemetryWrapper.kt$TelemetryWrapper.Object$val TIP = "tip" + MayBeConst:TelemetryWrapper.kt$TelemetryWrapper.Value$val ADD_TO_HOMESCREEN = "add_to_homescreen" + MayBeConst:TelemetryWrapper.kt$TelemetryWrapper.Value$val ADD_TO_HOMESCREEN_TIP = "add_to_homescreen_tip" + MayBeConst:TelemetryWrapper.kt$TelemetryWrapper.Value$val AUTOCOMPLETE_URL_TIP = "autocomplete_url_tip" + MayBeConst:TelemetryWrapper.kt$TelemetryWrapper.Value$val CANCEL = "cancel" + MayBeConst:TelemetryWrapper.kt$TelemetryWrapper.Value$val CLOSE_TAB = "close_tab" + MayBeConst:TelemetryWrapper.kt$TelemetryWrapper.Value$val CUSTOM_TAB = "custom_tab" + MayBeConst:TelemetryWrapper.kt$TelemetryWrapper.Value$val DEFAULT = "default" + MayBeConst:TelemetryWrapper.kt$TelemetryWrapper.Value$val DEFAULT_BROWSER_TIP = "default_browser_tip" + MayBeConst:TelemetryWrapper.kt$TelemetryWrapper.Value$val DISABLE_TIPS_TIP = "disable_tips_tip" + MayBeConst:TelemetryWrapper.kt$TelemetryWrapper.Value$val DISABLE_TRACKING_PROTECTION_TIP = "disable_tracking_protection_tip" + MayBeConst:TelemetryWrapper.kt$TelemetryWrapper.Value$val DOWNLOAD = "download" + MayBeConst:TelemetryWrapper.kt$TelemetryWrapper.Value$val ERASE = "erase" + MayBeConst:TelemetryWrapper.kt$TelemetryWrapper.Value$val ERASE_AND_OPEN = "erase_open" + MayBeConst:TelemetryWrapper.kt$TelemetryWrapper.Value$val ERASE_TO_APP = "erase_app" + MayBeConst:TelemetryWrapper.kt$TelemetryWrapper.Value$val ERASE_TO_HOME = "erase_home" + MayBeConst:TelemetryWrapper.kt$TelemetryWrapper.Value$val FIND_IN_PAGE = "find_in_page" + MayBeConst:TelemetryWrapper.kt$TelemetryWrapper.Value$val FINISH = "finish" + MayBeConst:TelemetryWrapper.kt$TelemetryWrapper.Value$val FIREFOX = "firefox" + MayBeConst:TelemetryWrapper.kt$TelemetryWrapper.Value$val FULL_BROWSER = "full_browser" + MayBeConst:TelemetryWrapper.kt$TelemetryWrapper.Value$val IMAGE = "image" + MayBeConst:TelemetryWrapper.kt$TelemetryWrapper.Value$val IMAGE_WITH_LINK = "image+link" + MayBeConst:TelemetryWrapper.kt$TelemetryWrapper.Value$val LINK = "link" + MayBeConst:TelemetryWrapper.kt$TelemetryWrapper.Value$val OPEN = "open" + MayBeConst:TelemetryWrapper.kt$TelemetryWrapper.Value$val OPEN_IN_NEW_TAB_TIP = "open_in_new_tab_tip" + MayBeConst:TelemetryWrapper.kt$TelemetryWrapper.Value$val QUICK_ADD = "quick_add" + MayBeConst:TelemetryWrapper.kt$TelemetryWrapper.Value$val RELOAD = "refresh" + MayBeConst:TelemetryWrapper.kt$TelemetryWrapper.Value$val REPORT_ISSUE = "report_issue" + MayBeConst:TelemetryWrapper.kt$TelemetryWrapper.Value$val RESUME = "resume" + MayBeConst:TelemetryWrapper.kt$TelemetryWrapper.Value$val SEARCH = "search" + MayBeConst:TelemetryWrapper.kt$TelemetryWrapper.Value$val SELECTION = "selection" + MayBeConst:TelemetryWrapper.kt$TelemetryWrapper.Value$val SETTINGS = "settings" + MayBeConst:TelemetryWrapper.kt$TelemetryWrapper.Value$val SKIP = "skip" + MayBeConst:TelemetryWrapper.kt$TelemetryWrapper.Value$val SURVEY_TIP = "survey_tip" + MayBeConst:TelemetryWrapper.kt$TelemetryWrapper.Value$val SURVEY_TIP_ES = "survey_tip_es" + MayBeConst:TelemetryWrapper.kt$TelemetryWrapper.Value$val SURVEY_TIP_FR = "survey_tip_fr" + MayBeConst:TelemetryWrapper.kt$TelemetryWrapper.Value$val TAB = "tab" + MayBeConst:TelemetryWrapper.kt$TelemetryWrapper.Value$val URL = "url" + MayBeConst:TelemetryWrapper.kt$TelemetryWrapper.Value$val WHATS_NEW = "whats_new" + MayBeConst:UrlInputFragment.kt$UrlInputFragment.Companion$@JvmField val FRAGMENT_TAG = "url_input" + MayBeConst:UrlInputFragment.kt$UrlInputFragment.Companion$private val ANIMATION_BROWSER_SCREEN = "browser_screen" + MayBeConst:UrlInputFragment.kt$UrlInputFragment.Companion$private val ANIMATION_DURATION = 200 + MayBeConst:UrlInputFragment.kt$UrlInputFragment.Companion$private val ARGUMENT_ANIMATION = "animation" + MayBeConst:UrlInputFragment.kt$UrlInputFragment.Companion$private val ARGUMENT_HEIGHT = "height" + MayBeConst:UrlInputFragment.kt$UrlInputFragment.Companion$private val ARGUMENT_SESSION_UUID = "sesssion_uuid" + MayBeConst:UrlInputFragment.kt$UrlInputFragment.Companion$private val ARGUMENT_WIDTH = "width" + MayBeConst:UrlInputFragment.kt$UrlInputFragment.Companion$private val ARGUMENT_X = "x" + MayBeConst:UrlInputFragment.kt$UrlInputFragment.Companion$private val ARGUMENT_Y = "y" + MayBeConst:UrlInputFragment.kt$UrlInputFragment.Companion$private val TIPS_ALPHA = 0.65f + MemberNameEqualsClassName:AddToHomescreenTest.kt$AddToHomescreenTest$@Ignore("Flaky test, will be refactored") @Test @Throws(UiObjectNotFoundException::class) @Suppress("LongMethod") fun AddToHomeScreenTest() + MemberNameEqualsClassName:FirstRunDialogueTest.kt$FirstRunDialogueTest$@Test fun FirstRunDialogueTest() + NewLineAtEndOfFile:Components.kt$org.mozilla.focus.Components.kt + NewLineAtEndOfFile:SupportUtilsTest.kt$org.mozilla.focus.utils.SupportUtilsTest.kt + NewLineAtEndOfFile:TestFocusApplication.kt$org.mozilla.focus.TestFocusApplication.kt + ReturnCount:IconGenerator.kt$IconGenerator.Companion$ private fun getRepresentativeSnippet(url: String?): String? + ReturnCount:IntentProcessor.kt$IntentProcessor$ fun handleIntent(context: Context, intent: SafeIntent, savedInstanceState: Bundle?): Result + ReturnCount:IntentUtils.kt$IntentUtils$private fun handleUnsupportedLink(context: Context, intent: Intent): Boolean + ReturnCount:MainActivity.kt$MainActivity$override fun onBackPressed() + ReturnCount:SearchEngineWriter.kt$SearchEngineWriter.Companion$private fun xmlToString(doc: Document): String? + ReturnCount:String.kt$ fun String.beautifyUrl(): String + SwallowedException:BiometricAuthenticationHandler.kt$BiometricAuthenticationHandler$catch (err: KeyPermanentlyInvalidatedException) { false } + SwallowedException:BrowserFragment.kt$BrowserFragment$catch (e: IllegalStateException) { // It can happen that at this point in time the activity is already in the background // and onSaveInstanceState() has already been called. Fragment transactions are not // allowed after that anymore. It's probably safe to guess that the user might not // be interested in adding to homescreen now. } + SwallowedException:BrowserFragment.kt$BrowserFragment$catch (e: IllegalStateException) { // It can happen that at this point in time the activity is already in the background // and onSaveInstanceState() has already been called. Fragment transactions are not // allowed after that anymore. } + SwallowedException:BrowserFragment.kt$BrowserFragment$catch (e: PendingIntent.CanceledException) { // There's really nothing we can do here... } + SwallowedException:IntentUtils.kt$IntentUtils$catch (e: URISyntaxException) { return false } + SwallowedException:LocalizedContent.kt$LocalizedContent$catch (e: PackageManager.NameNotFoundException) { // Nothing to do if we can't find the package name. } + SwallowedException:ManualAddSearchEngineSettingsFragment.kt$ManualAddSearchEngineSettingsFragment.Companion$catch (e: IOException) { Log.d(LOGTAG, "Failure to get response code from server: returning invalid search query") false } + SwallowedException:MobileMetricsPingStorage.kt$MobileMetricsPingStorage$catch (e: FileNotFoundException) { null } + SwallowedException:MobileMetricsPingStorage.kt$MobileMetricsPingStorage$catch (e: IOException) { atomicFile.failWrite(stream) } + SwallowedException:MobileMetricsPingStorage.kt$MobileMetricsPingStorage$catch (e: JSONException) { null } + SwallowedException:SearchEngineWriter.kt$SearchEngineWriter.Companion$catch (e: TransformerConfigurationException) { return null } + SwallowedException:SearchEngineWriter.kt$SearchEngineWriter.Companion$catch (e: TransformerException) { return null } + SwallowedException:SearchSuggestionsFetcher.kt$SearchSuggestionsFetcher$catch (ex: SearchSuggestionClient.FetchException) { listOf<String>() } + SwallowedException:SearchSuggestionsFetcher.kt$SearchSuggestionsFetcher$catch (ex: SearchSuggestionClient.ResponseParserException) { listOf<String>() } + SwallowedException:SupportUtils.kt$SupportUtils$catch (e: ActivityNotFoundException) { // In some cases, a matching Activity may not exist (according to the Android docs). openDefaultBrowserSumoPage(context) } + UnusedPrivateMember:CustomTabTest.kt$CustomTabTest$private val TEST_PAGE_HEADER_ID = "header" + UnusedPrivateMember:CustomTabTest.kt$CustomTabTest$private val TEST_PAGE_HEADER_TEXT = "focus test page" + UnusedPrivateMember:URLAutocompleteTest.kt$URLAutocompleteTest$// From API 23 and below private val CustomURLRow_old = Espresso.onData(Matchers.anything()) .inAdapterView( AllOf.allOf( ViewMatchers.withId(android.R.id.list), childAtPosition( ViewMatchers.withClassName(Matchers.`is`("android.widget.LinearLayout")), 0 ) ) ) .atPosition(4) + UnusedPrivateMember:URLAutocompleteTest.kt$URLAutocompleteTest$// From API 24 and above private val CustomURLRow = Espresso.onData(Matchers.anything()) .inAdapterView( AllOf.allOf( ViewMatchers.withId(android.R.id.list), childAtPosition( ViewMatchers.withId(android.R.id.list_container), 0 ) ) ) .atPosition(4) + UnusedPrivateMember:URLAutocompleteTest.kt$URLAutocompleteTest$private fun toggleTopsiteAC() + UnusedPrivateMember:WhatsNewTest.kt$WhatsNewTest$i + UtilityClassWithPublicConstructor:Features.kt$Features + UtilityClassWithPublicConstructor:FileUtils.kt$FileUtils + UtilityClassWithPublicConstructor:IconGenerator.kt$IconGenerator + UtilityClassWithPublicConstructor:SearchEngineWriter.kt$SearchEngineWriter + + diff --git a/quality/detekt.yml b/quality/detekt.yml index 128f409070e..3a11d724267 100644 --- a/quality/detekt.yml +++ b/quality/detekt.yml @@ -1,148 +1,155 @@ -autoCorrect: true -failFast: false - -test-pattern: # Configure exclusions for test sources - active: true - patterns: # Test file regexes - - '.*/test/.*' - - '.*Test.kt' - - '.*Spec.kt' - exclude-rule-sets: - - 'comments' - exclude-rules: - - 'NamingRules' - - 'WildcardImport' - - 'MagicNumber' - - 'MaxLineLength' - - 'LateinitUsage' - - 'StringLiteralDuplication' - build: - warningThreshold: 0 - failThreshold: 0 + maxIssues: 0 + excludeCorrectable: false weights: - complexity: 2 - formatting: 1 - LongParameterList: 1 - comments: 1 + # complexity: 2 + # LongParameterList: 1 + # style: 1 + # comments: 1 + +config: + validation: true + warningsAsErrors: false + # when writing own rules with new properties, exclude the property path e.g.: 'my_rule_set,.*>.*>[my_property]' + excludes: '' processors: active: true exclude: + - 'DetektProgressListener' + # - 'KtFileCountProcessor' + # - 'PackageCountProcessor' + # - 'ClassCountProcessor' # - 'FunctionCountProcessor' # - 'PropertyCountProcessor' - # - 'ClassCountProcessor' - # - 'PackageCountProcessor' - # - 'KtFileCountProcessor' + # - 'ProjectComplexityProcessor' + # - 'ProjectCognitiveComplexityProcessor' + # - 'ProjectLLOCProcessor' + # - 'ProjectCLOCProcessor' + # - 'ProjectLOCProcessor' + # - 'ProjectSLOCProcessor' + # - 'LicenseHeaderLoaderExtension' console-reports: active: true exclude: - # - 'ProjectStatisticsReport' - # - 'ComplexityReport' - # - 'NotificationReport' + - 'ProjectStatisticsReport' + - 'ComplexityReport' + - 'NotificationReport' # - 'FindingsReport' - # - 'BuildFailureReport' + - 'FileBasedFindingsReport' output-reports: active: true exclude: - # - 'PlainOutputReport' - # - 'XmlOutputReport' + # - 'TxtOutputReport' + # - 'XmlOutputReport' + # - 'HtmlOutputReport' -potential-bugs: +comments: active: true - DuplicateCaseInWhenExpression: - active: true - EqualsAlwaysReturnsTrueOrFalse: - active: false - EqualsWithHashCodeExist: - active: true - InvalidLoopCondition: + excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**'] + AbsentOrWrongFileLicense: active: false - WrongEqualsTypeParameter: - active: false - IteratorHasNextCallsNextMethod: - active: false - ExplicitGarbageCollectionCall: - active: true - UnconditionalJumpStatementInLoop: + licenseTemplateFile: 'license.template' + licenseTemplateIsRegex: false + CommentOverPrivateFunction: active: false - IteratorNotThrowingNoSuchElementException: + CommentOverPrivateProperty: active: false - UnreachableCode: - active: true - LateinitUsage: + EndOfSentenceFormat: active: false - excludeAnnotatedProperties: '' - ignoreOnClassesPattern: '' - UnsafeCallOnNullableType: + endOfSentenceFormat: '([.?!][ \t\n\r\f<])|([.?!:]$)' + UndocumentedPublicClass: active: false - UnsafeCast: + searchInNestedClass: true + searchInInnerClass: true + searchInInnerObject: true + searchInInnerInterface: true + UndocumentedPublicFunction: active: false - UselessPostfixExpression: + UndocumentedPublicProperty: active: false -performance: +complexity: active: true - ForEachOnRange: - active: true - SpreadOperator: - active: true - UnnecessaryTemporaryInstantiation: + ComplexCondition: active: true - -exceptions: - active: true - ExceptionRaisedInUnexpectedLocation: + threshold: 4 + ComplexInterface: active: false - methodNames: 'toString,hashCode,equals,finalize' - SwallowedException: + 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 - TooGenericExceptionCaught: + ignoredLabels: [] + LargeClass: active: true - exceptions: - - ArrayIndexOutOfBoundsException - - Error - - Exception - - IllegalMonitorStateException - - IndexOutOfBoundsException - - InterruptedException - - NullPointerException - - RuntimeException - - Throwable - TooGenericExceptionThrown: + threshold: 600 + LongMethod: active: true - exceptions: - - Error - - Exception - - NullPointerException - - RuntimeException - - Throwable - InstanceOfCheckForException: + threshold: 60 + LongParameterList: + active: true + functionThreshold: 6 + constructorThreshold: 7 + ignoreDefaultParameters: false + ignoreDataClasses: true + ignoreAnnotated: [] + MethodOverloading: active: false - NotImplementedDeclaration: + threshold: 6 + NamedArguments: active: false - ThrowingExceptionsWithoutMessageOrCause: - active: false - exceptions: 'IllegalArgumentException,IllegalStateException,IOException' - PrintStackTrace: + threshold: 3 + NestedBlockDepth: + active: true + threshold: 4 + ReplaceSafeCallChainWithRun: active: false - RethrowCaughtException: + StringLiteralDuplication: active: false - ReturnFromFinally: + excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**'] + threshold: 3 + ignoreAnnotation: true + excludeStringsWithLessThan5Characters: true + ignoreStringsRegex: '$^' + TooManyFunctions: + active: true + excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**'] + thresholdInFiles: 11 + thresholdInClasses: 11 + thresholdInInterfaces: 11 + thresholdInObjects: 11 + thresholdInEnums: 11 + ignoreDeprecated: false + ignorePrivate: false + ignoreOverridden: false + +coroutines: + active: true + GlobalCoroutineUsage: active: false - ThrowingExceptionFromFinally: + RedundantSuspendModifier: active: false - ThrowingExceptionInMain: + SleepInsteadOfDelay: active: false - ThrowingNewInstanceOfSameException: + SuspendFunWithFlowReturnType: active: false empty-blocks: active: true EmptyCatchBlock: active: true + allowedExceptionNameRegex: '_|(ignore|expected).*' EmptyClassBlock: active: true EmptyDefaultConstructor: @@ -157,6 +164,7 @@ empty-blocks: active: true EmptyFunctionBlock: active: true + ignoreOverridden: false EmptyIfBlock: active: true EmptyInitBlock: @@ -165,202 +173,564 @@ empty-blocks: active: true EmptySecondaryConstructor: active: true + EmptyTryBlock: + active: true EmptyWhenBlock: active: true EmptyWhileBlock: active: true -complexity: +exceptions: active: true - LongMethod: + ExceptionRaisedInUnexpectedLocation: active: true - threshold: 20 - NestedBlockDepth: + methodNames: [toString, hashCode, equals, finalize] + InstanceOfCheckForException: + active: false + excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**'] + NotImplementedDeclaration: + active: false + ObjectExtendsThrowable: + active: false + PrintStackTrace: active: true - threshold: 3 - LongParameterList: + RethrowCaughtException: active: true - threshold: 5 - LargeClass: + ReturnFromFinally: active: true - threshold: 150 - ComplexInterface: + ignoreLabeled: false + SwallowedException: + active: true + ignoredExceptionTypes: + - InterruptedException + - NumberFormatException + - ParseException + - MalformedURLException + allowedExceptionNameRegex: '_|(ignore|expected).*' + ThrowingExceptionFromFinally: + active: true + ThrowingExceptionInMain: active: false - threshold: 10 - includeStaticDeclarations: false - ComplexMethod: + ThrowingExceptionsWithoutMessageOrCause: active: true - threshold: 10 - MethodOverloading: + excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**'] + exceptions: + - IllegalArgumentException + - IllegalStateException + - IOException + ThrowingNewInstanceOfSameException: + active: true + TooGenericExceptionCaught: + active: true + excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**'] + exceptionNames: + - ArrayIndexOutOfBoundsException + - Error + - Exception + - IllegalMonitorStateException + - NullPointerException + - IndexOutOfBoundsException + - RuntimeException + - Throwable + allowedExceptionNameRegex: '_|(ignore|expected).*' + TooGenericExceptionThrown: + active: true + exceptionNames: + - Error + - Exception + - Throwable + - RuntimeException + +formatting: + active: true + android: false + autoCorrect: true + AnnotationOnSeparateLine: active: false - threshold: 5 - TooManyFunctions: + autoCorrect: true + AnnotationSpacing: + active: false + autoCorrect: true + ArgumentListWrapping: + active: false + autoCorrect: true + ChainWrapping: active: true - thresholdInFiles: 10 - thresholdInClasses: 10 - thresholdInInterfaces: 10 - thresholdInObjects: 10 - thresholdInEnums: 10 - ComplexCondition: + autoCorrect: true + CommentSpacing: active: true - threshold: 3 - LabeledExpression: + autoCorrect: true + EnumEntryNameCase: active: false - StringLiteralDuplication: + autoCorrect: true + Filename: + active: true + FinalNewline: + active: true + autoCorrect: true + insertFinalNewLine: true + ImportOrdering: active: false - threshold: 2 - ignoreAnnotation: true - excludeStringsWithLessThan5Characters: true - ignoreStringsRegex: '$^' + autoCorrect: true + layout: 'idea' + 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: false + 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 + NoWildcardImports: + active: true + PackageName: + active: true + autoCorrect: true + ParameterListWrapping: + active: true + autoCorrect: true + indentSize: 4 + SpacingAroundAngleBrackets: + active: false + autoCorrect: true + SpacingAroundColon: + active: true + autoCorrect: true + SpacingAroundComma: + active: true + autoCorrect: true + SpacingAroundCurly: + active: true + autoCorrect: true + SpacingAroundDot: + active: true + autoCorrect: true + SpacingAroundDoubleColon: + active: false + autoCorrect: true + SpacingAroundKeyword: + active: true + autoCorrect: true + SpacingAroundOperators: + active: true + autoCorrect: true + SpacingAroundParens: + active: true + autoCorrect: true + SpacingAroundRangeOperator: + active: true + autoCorrect: true + SpacingAroundUnaryOperator: + active: false + autoCorrect: true + SpacingBetweenDeclarationsWithAnnotations: + active: false + autoCorrect: true + SpacingBetweenDeclarationsWithComments: + active: false + autoCorrect: true + StringTemplate: + active: true + autoCorrect: true -code-smell: +naming: active: true - FeatureEnvy: - threshold: 0.5 - weight: 0.45 - base: 0.5 + ClassNaming: + active: true + excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**'] + classPattern: '[A-Z][a-zA-Z0-9]*' + ConstructorParameterNaming: + active: true + excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**'] + parameterPattern: '[a-z][A-Za-z0-9]*' + privateParameterPattern: '[a-z][A-Za-z0-9]*' + excludeClassPattern: '$^' + ignoreOverridden: true + EnumNaming: + active: true + excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**'] + enumEntryPattern: '[A-Z][_a-zA-Z0-9]*' + ForbiddenClassName: + active: false + excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**'] + forbiddenName: [] + FunctionMaxLength: + active: false + excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**'] + maximumFunctionNameLength: 30 + FunctionMinLength: + active: false + excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**'] + minimumFunctionNameLength: 3 + FunctionNaming: + active: true + excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**'] + functionPattern: '([a-z][a-zA-Z0-9]*)|(`.*`)' + excludeClassPattern: '$^' + ignoreOverridden: true + ignoreAnnotated: ['Composable'] + FunctionParameterNaming: + active: true + excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**'] + parameterPattern: '[a-z][A-Za-z0-9]*' + excludeClassPattern: '$^' + ignoreOverridden: true + InvalidPackageDeclaration: + active: false + excludes: ['*.kts'] + rootPackage: '' + MatchingDeclarationName: + active: true + mustBeFirst: true + MemberNameEqualsClassName: + active: true + ignoreOverridden: true + NoNameShadowing: + active: false + NonBooleanPropertyPrefixedWithIs: + active: false + excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**'] + ObjectPropertyNaming: + active: true + excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**'] + 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/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**'] + packagePattern: '[a-z]+(\.[a-z][A-Za-z0-9]*)*' + TopLevelPropertyNaming: + active: true + excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**'] + 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/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**'] + maximumVariableNameLength: 64 + VariableMinLength: + active: false + excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**'] + minimumVariableNameLength: 1 + VariableNaming: + active: true + excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**'] + variablePattern: '[a-z][A-Za-z0-9]*' + privateVariablePattern: '(_)?[a-z][A-Za-z0-9]*' + excludeClassPattern: '$^' + ignoreOverridden: true -style: +performance: active: true - ReturnCount: + ArrayPrimitive: active: true - max: 3 - ThrowsCount: + ForEachOnRange: active: true - max: 2 - NewLineAtEndOfFile: + excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**'] + SpreadOperator: active: true - OptionalAbstractKeyword: + excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**'] + UnnecessaryTemporaryInstantiation: active: true - OptionalWhenBraces: + +potential-bugs: + active: true + CastToNullableType: + active: false + Deprecation: + active: false + DontDowncastCollectionTypes: + active: false + DuplicateCaseInWhenExpression: + active: true + EqualsAlwaysReturnsTrueOrFalse: + active: true + EqualsWithHashCodeExist: + active: true + ExitOutsideMain: + active: false + ExplicitGarbageCollectionCall: + active: true + HasPlatformType: + active: false + IgnoredReturnValue: + active: false + restrictToAnnotatedMethods: true + returnValueAnnotations: ['*.CheckReturnValue', '*.CheckResult'] + ImplicitDefaultLocale: + active: true + ImplicitUnitReturnType: + active: false + allowExplicitReturnType: true + InvalidRange: + active: true + IteratorHasNextCallsNextMethod: + active: true + IteratorNotThrowingNoSuchElementException: + active: true + LateinitUsage: + active: false + excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**'] + excludeAnnotatedProperties: [] + ignoreOnClassesPattern: '' + MapGetWithNotNullAssertionOperator: + active: false + MissingWhenCase: + active: true + allowElseExpression: true + NullableToStringCall: + active: false + RedundantElseInWhen: + active: true + UnconditionalJumpStatementInLoop: + active: false + UnnecessaryNotNullOperator: + active: true + UnnecessarySafeCall: + active: true + UnreachableCatchBlock: + active: false + UnreachableCode: + active: true + UnsafeCallOnNullableType: + active: true + UnsafeCast: + active: true + UnusedUnaryOperator: + active: false + UselessPostfixExpression: + active: false + WrongEqualsTypeParameter: + active: true + +style: + active: true + ClassOrdering: active: false CollapsibleIfStatements: active: false + DataClassContainsFunctions: + active: false + conversionFunctionPrefix: 'to' + DataClassShouldBeImmutable: + active: false + DestructuringDeclarationWithTooManyEntries: + active: false + maxDestructuringEntries: 3 EqualsNullCall: + active: true + EqualsOnSignatureLine: active: false + ExplicitCollectionElementAccessMethod: + active: false + ExplicitItLambdaParameter: + active: false + ExpressionBodySyntax: + active: false + includeLineWrapping: false ForbiddenComment: active: true - values: 'TODO:,FIXME:,STOPSHIP:' + values: ['TODO:', 'FIXME:', 'STOPSHIP:'] + allowedPatterns: '' ForbiddenImport: active: false - imports: '' - SpacingBetweenPackageAndImports: + imports: [] + forbiddenPatterns: '' + ForbiddenMethodCall: active: false - LoopWithTooManyJumpStatements: - active: false - maxJumpCount: 1 - MethodNameEqualsClassName: + methods: ['kotlin.io.println', 'kotlin.io.print'] + ForbiddenPublicDataClass: + active: true + excludes: ['**'] + ignorePackages: ['*.internal', '*.internal.*'] + ForbiddenVoid: active: false - ignoreOverriddenFunction: true - ModifierOrder: + ignoreOverridden: false + ignoreUsageInGenerics: false + FunctionOnlyReturningConstant: active: true + ignoreOverridableFunction: true + ignoreActualFunction: true + excludedFunctions: 'describeContents' + excludeAnnotatedFunction: ['dagger.Provides'] + LibraryCodeMustSpecifyReturnType: + active: true + excludes: ['**'] + LibraryEntitiesShouldNotBePublic: + active: true + excludes: ['**'] + LoopWithTooManyJumpStatements: + active: true + maxJumpCount: 1 MagicNumber: active: true - ignoreNumbers: '-1,0,1,2' - ignoreHashCodeFunction: false + excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**'] + ignoreNumbers: ['-1', '0', '1', '2'] + ignoreHashCodeFunction: true ignorePropertyDeclaration: false + ignoreLocalVariableDeclaration: false ignoreConstantDeclaration: true ignoreCompanionObjectPropertyDeclaration: true ignoreAnnotation: false ignoreNamedArgument: true ignoreEnums: false - WildcardImport: - active: true - excludeImports: 'java.util.*,kotlinx.android.synthetic.*' - SafeCast: - active: true + ignoreRanges: false + ignoreExtensionFunctions: true + MandatoryBracesIfStatements: + active: false + MandatoryBracesLoops: + active: false MaxLineLength: active: true maxLineLength: 120 - excludePackageStatements: false - excludeImportStatements: false - PackageNaming: + excludePackageStatements: true + excludeImportStatements: true + excludeCommentStatements: false + MayBeConst: active: true - packagePattern: '^[a-z]+(\.[a-z][a-z0-9]*)*$' - ClassNaming: + ModifierOrder: active: true - classPattern: '[A-Z$][a-zA-Z$]*' - EnumNaming: + MultilineLambdaItParameter: + active: false + NestedClassesVisibility: active: true - enumEntryPattern: '^[A-Z$][a-zA-Z_$]*$' - FunctionNaming: + NewLineAtEndOfFile: active: true - functionPattern: '^([a-z$][a-zA-Z$0-9]*)|(`.*`)$' - FunctionMaxLength: + NoTabs: active: false - maximumFunctionNameLength: 30 - FunctionMinLength: - active: false - minimumFunctionNameLength: 3 - VariableNaming: - active: true - variablePattern: '^(_)?[a-z$][a-zA-Z$0-9]*$' - ConstantNaming: + OptionalAbstractKeyword: active: true - constantPattern: '^([A-Z_]*|serialVersionUID)$' - VariableMaxLength: + OptionalUnit: active: false - maximumVariableNameLength: 30 - VariableMinLength: + OptionalWhenBraces: active: false - minimumVariableNameLength: 3 - ForbiddenClassName: + PreferToOverPairSyntax: active: false - forbiddenName: '' ProtectedMemberInFinalClass: + active: true + RedundantExplicitType: active: false - SerialVersionUIDInSerializableClass: - active: false - UnnecessaryParentheses: + RedundantHigherOrderMapUsage: active: false - UnnecessaryInheritance: + RedundantVisibilityModifierRule: active: false - UtilityClassWithPublicConstructor: + ReturnCount: + active: true + max: 2 + excludedFunctions: 'equals' + excludeLabeled: false + excludeReturnFromLambda: true + excludeGuardClauses: false + SafeCast: + active: true + SerialVersionUIDInSerializableClass: + active: true + SpacingBetweenPackageAndImports: active: false - DataClassContainsFunctions: + ThrowsCount: + active: true + max: 2 + TrailingWhitespace: active: false - conversionFunctionPrefix: 'to' - UseDataClass: + UnderscoresInNumericLiterals: active: false + acceptableDecimalLength: 5 UnnecessaryAbstractClass: + active: true + excludeAnnotatedClasses: ['dagger.Module'] + UnnecessaryAnnotationUseSiteTarget: active: false - OptionalUnit: + UnnecessaryApply: + active: true + UnnecessaryFilter: + active: false + UnnecessaryInheritance: + active: true + UnnecessaryLet: active: false - OptionalReturnKeyword: + UnnecessaryParentheses: active: false - ExpressionBodySyntax: + UntilInsteadOfRangeTo: active: false UnusedImports: active: false - NestedClassesVisibility: + UnusedPrivateClass: + active: true + UnusedPrivateMember: + active: true + allowedNames: '(_|ignored|expected|serialVersionUID)' + UseArrayLiteralsInAnnotations: active: false - RedundantVisibilityModifierRule: + UseCheckNotNull: active: false - FunctionOnlyReturningConstant: + UseCheckOrError: active: false - ignoreOverridableFunction: true - excludedFunctions: 'describeContents' - -comments: - active: true - CommentOverPrivateFunction: + UseDataClass: active: false - CommentOverPrivateProperty: + excludeAnnotatedClasses: [] + allowVars: false + UseEmptyCounterpart: active: false - UndocumentedPublicClass: + UseIfEmptyOrIfBlank: active: false - searchInNestedClass: true - searchInInnerClass: true - searchInInnerObject: true - searchInInnerInterface: true - UndocumentedPublicFunction: + UseIfInsteadOfWhen: active: false - -# *experimental feature* -# Migration rules can be defined in the same config file or a new one -migration: - active: true - imports: - # your.package.Class: new.package.or.Class - # for example: - # io.gitlab.arturbosch.detekt.api.Rule: io.gitlab.arturbosch.detekt.rule.Rule + UseIsNullOrEmpty: + active: false + UseOrEmpty: + active: false + UseRequire: + active: false + UseRequireNotNull: + active: false + UselessCallOnNotNull: + active: true + UtilityClassWithPublicConstructor: + active: true + VarCouldBeVal: + active: true + WildcardImport: + active: true + excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**'] + excludeImports: ['java.util.*', 'kotlinx.android.synthetic.*'] diff --git a/quality/pre-push-recommended.sh b/quality/pre-push-recommended.sh index d4aebaaaa11..cbc1f6acd43 100755 --- a/quality/pre-push-recommended.sh +++ b/quality/pre-push-recommended.sh @@ -15,7 +15,7 @@ # output of `./gradlew tasks`. ./gradlew -q \ ktlint \ - detektCheck \ + detekt \ assembleFocusDebugAndroidTest \ testFocusDebugUnitTest diff --git a/tools/docker/Dockerfile b/tools/docker/Dockerfile index 78121d2f26c..44a02de26f9 100644 --- a/tools/docker/Dockerfile +++ b/tools/docker/Dockerfile @@ -59,7 +59,7 @@ RUN git clone https://github.com/mozilla-mobile/focus-android.git WORKDIR /opt/focus-android RUN ./gradlew assembleFocusDebug \ && ./gradlew testFocusDebugUnitTest \ - && ./gradlew detektCheck \ + && ./gradlew detekt \ && ./gradlew ktlint \ && ./gradlew clean diff --git a/tools/taskcluster/schedule-master-build.py b/tools/taskcluster/schedule-master-build.py index fee4650d139..7b078fbca6e 100644 --- a/tools/taskcluster/schedule-master-build.py +++ b/tools/taskcluster/schedule-master-build.py @@ -44,7 +44,7 @@ def generate_code_quality_task(buildTaskId): return taskcluster.slugId(), generate_task( name="(Focus for Android) Code quality", description="Run code quality tools on Focus/Klar for Android code base.", - command='echo "--" > .adjust_token && ./gradlew --no-daemon clean detektCheck ktlint lint', + command='echo "--" > .adjust_token && ./gradlew --no-daemon clean detekt ktlint lint', dependencies=[buildTaskId])