Skip to content

Commit

Permalink
Initial draft of Rules Marketplace
Browse files Browse the repository at this point in the history
  • Loading branch information
cortinico committed Aug 6, 2022
1 parent 6061f29 commit 7e8e060
Show file tree
Hide file tree
Showing 6 changed files with 243 additions and 0 deletions.
5 changes: 5 additions & 0 deletions website/docusaurus.config.js
Expand Up @@ -106,6 +106,11 @@ const config = {
position: 'left',
label: 'API',
},
{
to: "/marketplace",
label: "Marketplace",
position: "left",
},
{
type: "docsVersionDropdown",
position: "right",
Expand Down
74 changes: 74 additions & 0 deletions website/src/data/rulesmarketplace.js
@@ -0,0 +1,74 @@
/*
* ADD YOUR RULES TO THE DETEKT RULES 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
* - `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.
* - Open a PR and check for reported CI errors
*/

// Add sites to this list
// prettier-ignore
export const rulesets = [
{
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'],
usesTypeResolution: true,
},
{
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'],
usesTypeResolution: false,
},
{
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'],
usesTypeResolution: false,
},
{
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'],
usesTypeResolution: false,
},
{
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'],
usesTypeResolution: true,
},
/*
Pro Tip: add your ruleset in alphabetical order.
Appending your ruleset here (at the end) is more likely to produce Git conflicts.
*/
];
@@ -0,0 +1,44 @@
import React from "react";
import Link from "@docusaurus/Link";
import styles from "./styles.module.css";

function MarketplaceCard(input) {
const ruleset = input.ruleset;
return (
<li key={ruleset.title} className="card shadow--md">
<div className="card__body">
<div className={styles.marketplaceCardHeader}>
<h3 className={styles.marketplaceCardTitle}>
<Link href={ruleset.repo} className={styles.marketplaceCardLink}>
{ruleset.title}
</Link>
</h3>
</div>
<div className={styles.marketplaceCardBody}>
<p>{ruleset.description}</p>
<h5>Coordinates</h5>
<p>
<code>detektPlugins("{ruleset.mavenCoordinates}")</code> on{" "}
<strong>{ruleset.mavenRepo}</strong>
</p>
<h5>Rules</h5>
<p>
Uses type resolution:{" "}
<strong>{ruleset.usesTypeResolution.toString()}</strong>
</p>
<p>
<ul>
{ruleset.rules.map((rule) => (
<li>
<code>{rule}</code>
</li>
))}
</ul>
</p>
</div>
</div>
</li>
);
}

export default React.memo(MarketplaceCard);
@@ -0,0 +1,26 @@
.marketplaceCardHeader {
display: flex;
align-items: center;
margin-bottom: 12px;
}

.marketplaceCardTitle {
margin-bottom: 0;
flex: 1 1 auto;
}

.marketplaceCardTitle a {
text-decoration: none;
background: linear-gradient(var(--ifm-color-primary),
var(--ifm-color-primary)) 0% 100% / 0% 1px no-repeat;
transition: background-size ease-out 200ms;
}

.marketplaceCardTitle a:not(:focus):hover {
background-size: 100% 1px;
}

.marketplaceCardBody {
font-size: smaller;
line-height: 1.66;
}
85 changes: 85 additions & 0 deletions website/src/pages/marketplace/index.jsx
@@ -0,0 +1,85 @@
import React from "react";
import clsx from "clsx";
import Layout from "@theme/Layout";
import { rulesets } from "@site/src/data/rulesmarketplace";
import MarketplaceCard from "./_components/MarketplaceCard";
import styles from "./styles.module.css";

const TITLE = "Detekt 3rd Party Rules Marketplace";
const DESCRIPTION =
"List of Detekt Rules that have been built by the community 🎉";
const SUBMIT_URL =
"https://github.com/detekt/detekt/blob/main/website/src/data/rulesmarketplace.js";
const SEARCH_RULES_URL = "https://github.com/topics/detekt-rules";

function MarketplaceHeader() {
return (
<section className="margin-top--lg margin-bottom--lg text--center">
<h1>Detekt 3rd Party Rules Marketplace</h1>
<p>List of Detekt Rules that have been built by the community.</p>
<a
className={clsx(
"button",
"button--primary",
styles.marketplaceHeaderButton
)}
href={SUBMIT_URL}
target="_blank"
rel="noreferrer"
>
🙏 Please add your ruleset
</a>
<a
className={clsx(
"button",
"button--secondary",
styles.marketplaceHeaderButton
)}
href={SEARCH_RULES_URL}
target="_blank"
rel="noreferrer"
>
Find more rules on Github
</a>
</section>
);
}

function MarketplaceCards() {
// No Results scenario
if (rulesets.length === 0) {
return (
<section className="margin-top--lg margin-bottom--xl">
<div className="container padding-vert--md text--center">
<h2>No results</h2>
</div>
</section>
);
}

return (
<section className="margin-top--lg margin-bottom--xl">
<>
<div className="container margin-top--lg">
<h2 className={styles.marketplaceHeader}>All rulesets</h2>
<ul className={clsx("clean-list", styles.marketplaceList)}>
{rulesets.map((ruleset) => (
<MarketplaceCard key={ruleset.title} ruleset={ruleset} />
))}
</ul>
</div>
</>
</section>
);
}

export default function Marketplace() {
return (
<Layout title={TITLE} description={DESCRIPTION}>
<main className="margin-vert--lg">
<MarketplaceHeader />
<MarketplaceCards />
</main>
</Layout>
);
}
9 changes: 9 additions & 0 deletions website/src/pages/marketplace/styles.module.css
@@ -0,0 +1,9 @@
.marketplaceList {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(420px, 1fr));
gap: 24px;
}

.marketplaceHeaderButton {
margin: 8px;
}

0 comments on commit 7e8e060

Please sign in to comment.