diff --git a/README.md b/README.md index 9f353115772..d042adec0ad 100644 --- a/README.md +++ b/README.md @@ -171,12 +171,7 @@ Integrations: - [GitHub Action: Setup detekt](https://github.com/marketplace/actions/setup-detekt) - [Sonatype Lift](https://github.com/marketplace/muse-dev) -Custom rules and reports from 3rd parties: - -- [detekt-verify-implementation](https://github.com/cph-cachet/detekt-verify-implementation) by cph-cachet -- [detekt-hint](https://github.com/mkohm/detekt-hint) by mkohm is a plugin to detekt that provides detection of design principle violations through integration with Danger -- [GitLab report format](https://gitlab.com/cromefire_/detekt-gitlab-report) -- There are more third-party plugins out there. You can find some of them [in this list](https://github.com/topics/detekt-plugin). +Custom rules and reports from 3rd parties can be found on our [**Detekt Marketplace**](https://detekt.dev/marketplace). #### Credits diff --git a/website/src/data/rulesmarketplace.js b/website/src/data/rulesmarketplace.js index 3c4a0fec377..8e6e9f9a4de 100644 --- a/website/src/data/rulesmarketplace.js +++ b/website/src/data/rulesmarketplace.js @@ -1,71 +1,138 @@ /* - * ADD YOUR RULES TO THE DETEKT RULES MARKETPLACE + * ADD YOUR REPOSITORY TO THE DETEKT MARKETPLACE * - * Instructions for adding your ruleset: - * - Add your third-party rule in the json array below - * - `title` is the repository name name - * - `description` is a short (≤120 characters) description of the ruleset + * We're allowing third-party repositories that contains rulesets, + * custom processors, custom reporters and external plugins that work with Detekt. + * + * You can read more about how to extend Detekt here: + * https://detekt.dev/docs/introduction/extensions + * + * Instructions for adding your repository: + * + * - Add your third-party repository in the json array below + * - `title` is the repository name + * - `description` is a short (≤120 characters) description of the repository. * - `repo` is the repository URL - * - `mavenCoordinates` are the maven coordinates of the ruleset so users can easily copy them - * - `mavenRepo` is the maven repository where they're hosted. - * - `ruleset` is the ID of the ruleset - * - `rules` is an array of rules your ruleset is offering - * - `usesTypeResolution` a boolean weather or not your ruleset uses type resolution. + * - `ruleset` (Optional) is the ID of the ruleset + * - `rules` (Optional) is an array of rules your ruleset is offering + * - `usesTypeResolution` (Optional) a boolean weather or not your ruleset uses type resolution. * - Open a PR and check for reported CI errors */ +export const tagTypes = { + ruleset: { + color: "#39ca30", + description: "A collection of custom rules for Detekt", + }, + processor: { + color: "#e9669e", + description: "A custom processor for Detekt", + }, + reporter: { + color: "#fe6829", + description: "A custom reporter for Detekt", + }, + plugin: { + color: "#a44fb7", + description: "A plugin or a tool built on top of Detekt", + }, +}; + // Add sites to this list -// prettier-ignore -export const rulesets = [ +export const extensions = [ { - title: 'Compiler', - description: 'A ruleset that wraps the warnings and info messages of the Kotlin compiler as detekt findings..', - repo: 'https://github.com/BraisGabin/detekt-compiler-rules', - mavenCoordinates: 'com.github.BraisGabin:detekt-compiler-rules:+', - mavenRepo: 'Jitpack', - ruleset: 'compiler', - rules: ['CompilerInfo', 'CompilerWarning'], + title: "Compiler", + description: + "A ruleset that wraps the warnings and info messages of the Kotlin compiler as detekt findings..", + repo: "https://github.com/BraisGabin/detekt-compiler-rules", + ruleset: "compiler", + rules: ["CompilerInfo", "CompilerWarning"], usesTypeResolution: true, + tags: ["ruleset"], }, - { - title: 'Compose', - description: 'A set of Detekt rules to help prevent common errors in projects using Jetpack Compose.', - repo: 'https://github.com/appKODE/detekt-rules-compose', - mavenCoordinates: 'ru.kode:detekt-rules-compose:+', - mavenRepo: 'MavenCentral', - ruleset: 'compose', - rules: ['ReusedModifierInstance', 'UnnecessaryEventHandlerParameter', 'ComposableEventParameterNaming', 'ModifierHeightWithText', 'ModifierParameterPosition', 'ModifierDefaultValue', 'MissingModifierDefaultValue', 'PublicComposablePreview'], + { + title: "Compose", + description: + "A set of Detekt rules to help prevent common errors in projects using Jetpack Compose.", + repo: "https://github.com/appKODE/detekt-rules-compose", + ruleset: "compose", + rules: [ + "ReusedModifierInstance", + "UnnecessaryEventHandlerParameter", + "ComposableEventParameterNaming", + "ModifierHeightWithText", + "ModifierParameterPosition", + "ModifierDefaultValue", + "MissingModifierDefaultValue", + "PublicComposablePreview", + ], usesTypeResolution: false, + tags: ["ruleset"], }, { - title: 'Doist', - description: 'This repository contains custom detekt rules based on Doist internal coding conventions.', - repo: 'https://github.com/Doist/detekt-rules', - mavenCoordinates: 'com.doist.detekt:detekt-rules:+', - mavenRepo: 'GithubPackages', - ruleset: 'DoistRuleSet', - rules: ['NoBlankNewLineAfterClassHeader', 'ConsistentWhenEntries', 'SingleLineWhenEntryExpressionsAreWrapped', 'MutableObservablePropertyIsPrivate', 'NoNotNullOperator', 'TodoPattern'], + title: "Doist detekt-rules", + description: + "This repository contains custom detekt rules based on Doist internal coding conventions.", + repo: "https://github.com/Doist/detekt-rules", + ruleset: "DoistRuleSet", + rules: [ + "NoBlankNewLineAfterClassHeader", + "ConsistentWhenEntries", + "SingleLineWhenEntryExpressionsAreWrapped", + "MutableObservablePropertyIsPrivate", + "NoNotNullOperator", + "TodoPattern", + ], usesTypeResolution: false, + tags: ["ruleset"], + }, + { + title: "Hint", + description: + "A ruleset to implement detection of violation of programming principles. detekt-hint offers also instructions on how to integrate with Danger and Github Actions", + repo: "https://github.com/mkohm/detekt-hint", + tags: ["plugin", "ruleset"], + ruleset: "detekt-hint", + rules: [ + "InterfaceSegregationPrinciple", + "LackOfCohesionMethods", + "OpenClosedPrinciple", + "UseCompositionInsteadOfInheritance", + ], + usesTypeResolution: true, + }, + { + title: "Gitlab Report", + description: + "A reporter to export Detekt findings to GitLab Code Quality (and other code climate compatible tools).\nThis is designed for use with GitLab, but should also work fine with everything else that accepts the code climate format.", + repo: "https://gitlab.com/cromefire/detekt-gitlab-report", + tags: ["reporter"], }, { - title: 'Operator', - description: 'Rules to prefer expressions over named functions for kotlin operators.', - repo: 'https://github.com/colematthew4/detekt-operator', - mavenCoordinates: 'io.cole.matthew.detekt.operator:detekt-operator:+', - mavenRepo: 'GithubPackages', - ruleset: 'detekt-operator', - rules: ['PreferInOverContainsSyntax', 'PreferUnaryPrefixOverFunctionSyntax', 'PreferUnaryPostfixOverFunctionSyntax', 'PreferArithmeticSymbolSyntax', 'PreferBracketAccessorOverFunctionSyntax'], + title: "Operator", + description: + "Rules to prefer expressions over named functions for kotlin operators.", + repo: "https://github.com/colematthew4/detekt-operator", + ruleset: "detekt-operator", + rules: [ + "PreferInOverContainsSyntax", + "PreferUnaryPrefixOverFunctionSyntax", + "PreferUnaryPostfixOverFunctionSyntax", + "PreferArithmeticSymbolSyntax", + "PreferBracketAccessorOverFunctionSyntax", + ], usesTypeResolution: false, + tags: ["ruleset"], }, { - title: 'Verify Implementation', - description: 'A ruleset which enables verifying whether concrete classes are implemented as specified according to annotations applied to base types.', - repo: 'https://github.com/cph-cachet/detekt-verify-implementation', - mavenCoordinates: 'dk.cachet.detekt.extensions:detekt-verify-implementation:+', - mavenRepo: 'GithubPackages', - ruleset: 'verify-implementation', - rules: ['Immutable', 'DataClass'], + title: "Verify Implementation", + description: + "A ruleset which enables verifying whether concrete classes are implemented as specified according to annotations applied to base types.", + repo: "https://github.com/cph-cachet/detekt-verify-implementation", + ruleset: "verify-implementation", + rules: ["Immutable", "DataClass"], usesTypeResolution: true, + tags: ["ruleset"], }, /* Pro Tip: add your ruleset in alphabetical order. diff --git a/website/src/pages/marketplace/_components/MarketplaceCard/index.jsx b/website/src/pages/marketplace/_components/MarketplaceCard/index.jsx index 82271256e36..dfe0f23de7d 100644 --- a/website/src/pages/marketplace/_components/MarketplaceCard/index.jsx +++ b/website/src/pages/marketplace/_components/MarketplaceCard/index.jsx @@ -1,40 +1,61 @@ import React from "react"; +import clsx from "clsx"; import Link from "@docusaurus/Link"; import styles from "./styles.module.css"; +import MarketplaceCardTag from "../MarketplaceCardTag"; function MarketplaceCard(input) { - const ruleset = input.ruleset; + const extension = input.extension; return ( -
  • +
  • - - {ruleset.title} - + {extension.title}

    +
      + {extension.tags.map((tag) => ( +
    • + +
    • + ))} +
    + {/* {extension.tags.map((tag) => ( + // +

    {tag}

    + ))} */} + + Source +
    -

    {ruleset.description}

    -
    Coordinates
    -

    - detektPlugins("{ruleset.mavenCoordinates}") on{" "} - {ruleset.mavenRepo} -

    -
    Rules
    -

    - Uses type resolution:{" "} - {ruleset.usesTypeResolution.toString()} -

    -

    -

      - {ruleset.rules.map((rule) => ( -
    • - {rule} -
    • - ))} -
    -

    +

    {extension.description}

    + {extension.rules && ( +

    +

    Rules
    +

    + Uses type resolution:{" "} + {extension.usesTypeResolution.toString()} +

    +

    +

      + {extension.rules.map((rule) => ( +
    • + {rule} +
    • + ))} +
    +

    +

    + )}
  • diff --git a/website/src/pages/marketplace/_components/MarketplaceCard/styles.module.css b/website/src/pages/marketplace/_components/MarketplaceCard/styles.module.css index cb2d6e716be..541f9ca952d 100644 --- a/website/src/pages/marketplace/_components/MarketplaceCard/styles.module.css +++ b/website/src/pages/marketplace/_components/MarketplaceCard/styles.module.css @@ -1,5 +1,6 @@ .marketplaceCardHeader { display: flex; + flex-wrap: wrap; align-items: center; margin-bottom: 12px; } @@ -9,6 +10,11 @@ flex: 1 1 auto; } +.marketplaceCardButton { + margin-bottom: 0; + flex: 1 1 auto; +} + .marketplaceCardTitle a { text-decoration: none; background: linear-gradient(var(--ifm-color-primary), @@ -24,3 +30,9 @@ font-size: smaller; line-height: 1.66; } + +.tagContainer { + display: flex; + flex-wrap: wrap; + list-style: none; +} \ No newline at end of file diff --git a/website/src/pages/marketplace/_components/MarketplaceCardTag/index.jsx b/website/src/pages/marketplace/_components/MarketplaceCardTag/index.jsx new file mode 100644 index 00000000000..c4bf56e8566 --- /dev/null +++ b/website/src/pages/marketplace/_components/MarketplaceCardTag/index.jsx @@ -0,0 +1,53 @@ +import React from "react"; +import { tagTypes } from "../../../../data/rulesmarketplace"; +import styles from "./styles.module.css"; + +// const TagComp = React.forwardRef( +// ({label, color, description}, ref) => ( +//
  • +// {label.toLowerCase()} +// +//
  • +// ), +// ); + +function MarketplaceCardTag(input) { + + const tag = input.tag; + + function getColorForTag(tag) { + if (tag in tagTypes) { + return tagTypes[tag].color; + } else { + return null; + } + } + + function getDescriptionForTag(tag) { + if (tag in tagTypes) { + return tagTypes[tag].description; + } else { + return null; + } + } + + return ( +
  • + {input.tag.toLowerCase()} + +
  • + // + // + // + ); +} + +export default React.memo(MarketplaceCardTag); diff --git a/website/src/pages/marketplace/_components/MarketplaceCardTag/styles.module.css b/website/src/pages/marketplace/_components/MarketplaceCardTag/styles.module.css new file mode 100644 index 00000000000..5c171555201 --- /dev/null +++ b/website/src/pages/marketplace/_components/MarketplaceCardTag/styles.module.css @@ -0,0 +1,22 @@ +.tag { + font-size: 0.675rem; + border: 1px solid var(--ifm-color-secondary-darkest); + cursor: default; + margin-right: 6px; + margin-bottom: 6px !important; + border-radius: 12px; + display: inline-flex; + align-items: center; +} + +.tag .textLabel { + margin-left: 8px; +} + +.tag .colorLabel { + width: 7px; + height: 7px; + border-radius: 50%; + margin-left: 6px; + margin-right: 6px; +} \ No newline at end of file diff --git a/website/src/pages/marketplace/index.jsx b/website/src/pages/marketplace/index.jsx index 3500e649bdc..6ff981fc389 100644 --- a/website/src/pages/marketplace/index.jsx +++ b/website/src/pages/marketplace/index.jsx @@ -1,11 +1,11 @@ import React from "react"; import clsx from "clsx"; import Layout from "@theme/Layout"; -import { rulesets } from "@site/src/data/rulesmarketplace"; +import { extensions } from "@site/src/data/rulesmarketplace"; import MarketplaceCard from "./_components/MarketplaceCard"; import styles from "./styles.module.css"; -const TITLE = "Detekt 3rd Party Rules Marketplace"; +const TITLE = "Detekt 3rd-party Marketplace"; const DESCRIPTION = "List of Detekt Rules that have been built by the community 🎉"; const SUBMIT_URL = @@ -15,8 +15,10 @@ const SEARCH_RULES_URL = "https://github.com/topics/detekt-rules"; function MarketplaceHeader() { return (
    -

    Detekt 3rd Party Rules Marketplace

    -

    List of Detekt Rules that have been built by the community.

    +

    {TITLE}

    +

    + List of Detekt Rules, Extensions & Plugins that have been built by the community. +

    @@ -61,10 +63,10 @@ function MarketplaceCards() {
    <>
    -

    All rulesets

    +

    All extensions

      - {rulesets.map((ruleset) => ( - + {extensions.map((extension) => ( + ))}