Skip to content

Commit

Permalink
feat: badges generator (#12)
Browse files Browse the repository at this point in the history
Co-authored-by: Pooya Parsa <pooya@pi0.io>
Co-authored-by: uncenter <47499684+uncenter@users.noreply.github.com>
  • Loading branch information
3 people authored Feb 7, 2024
1 parent c04df9d commit 8db8058
Show file tree
Hide file tree
Showing 7 changed files with 197 additions and 28 deletions.
54 changes: 41 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
# 🤖 automd

[![npm version][npm-version-src]][npm-version-href]
[![npm downloads][npm-downloads-src]][npm-downloads-href]
<!-- automd:badges -->

[![npm version](https://img.shields.io/npm/v/automd)](https://npmjs.com/package/automd)
[![npm downloads](https://img.shields.io/npm/dm/automd)](https://npmjs.com/package/automd)

<!-- /automd -->

Your automated markdown maintainer!

Expand All @@ -20,10 +24,8 @@ Automd scans for the annotation comments within the markdown document and update

The syntax is like this:

```md
<!-- automd:generator [...args] -->
<!-- /automd -->
```
<!-- automd:generator [...args] -->
<!-- /automd -->

### Using CLI

Expand Down Expand Up @@ -172,6 +174,39 @@ The `pm-x` generator generates commands for running a package through JavaScript
- `name`: The package name (by default tries to read from the `name` field in `package.json`).
- `usage`: An additional string appended at the end of each command suggesting usage. (defaults to `""`).

### `badges`

The `badges` generator generates badges for npm version, npm downloads and some optional ones like codecov and bundle.

#### Usage

<!-- automd:badges name=defu codecov bundlephobia -->
<!-- /automd -->

**Updated Result:**

<!-- automd:badges name=defu codecov bundlephobia -->

[![npm version](https://img.shields.io/npm/v/defu)](https://npmjs.com/package/defu)
[![npm downloads](https://img.shields.io/npm/dm/defu)](https://npmjs.com/package/defu)
[![bundle size](https://img.shields.io/bundlephobia/minzip/defu)](https://bundlephobia.com/package/defu)
[![codecov](https://img.shields.io/codecov/c/gh/unjs/automd)](https://codecov.io/gh/unjs/automd)

<!-- /automd -->

#### Arguments

- `name`: The npm package name. By default tries to infer from `package.json`.
- `github`: Github repository name. By default tries to infer from `package.json`.
- `bundlephobia`: Show [bundle-phobia](https://bundlephobia.com/) badge (requires `name`).
- `codecov`: Enable [codecov](https://codecov.io) badge (requires `github`).
- `no-npmDownloads`: Hide npm downloads badge.
- `no-npmVersion`: Hide npm version badge.
- `provider`: Can be one of `shields` (for [shields.io](https://shields.io/)) or `badgen` / `badgenClassic` (for [badgen.net](https://badgen.net/)). Default is `badgen`.

> [!TIP]
> You can use additional `style`, `labelColor` and `color` args for `shields` provider for example: `provider=shields style=flat-square labelColor=f0db4f color=18181b`.
## Development

- Clone this repository
Expand All @@ -186,10 +221,3 @@ The `pm-x` generator generates commands for running a package through JavaScript
Made with 💛

Published under [MIT License](./LICENSE).

<!-- Badges -->

[npm-version-src]: https://img.shields.io/npm/v/automd?style=flat&colorA=18181B&colorB=F0DB4F
[npm-version-href]: https://npmjs.com/package/automd
[npm-downloads-src]: https://img.shields.io/npm/dm/automd?style=flat&colorA=18181B&colorB=F0DB4F
[npm-downloads-href]: https://npmjs.com/package/automd
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
],
"scripts": {
"automd": "jiti src/cli.ts",
"build": "unbuild",
"build": "pnpm automd && unbuild",
"dev": "vitest",
"play": "pnpm automd --dir playground",
"lint": "eslint --cache --ext .ts,.js,.mjs,.cjs . && prettier -c src",
Expand All @@ -36,6 +36,7 @@
"c12": "^1.6.1",
"citty": "^0.1.5",
"consola": "^3.2.3",
"defu": "^6.1.4",
"destr": "^2.0.2",
"magic-string": "^0.30.7",
"omark": "^0.1.0",
Expand Down
12 changes: 12 additions & 0 deletions playground/README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,14 @@
# automd playground

<!-- automd:badges name=defu codecov bundlephobia -->

[![npm version](https://img.shields.io/npm/v/defu)](https://npmjs.com/package/defu)
[![npm downloads](https://img.shields.io/npm/dm/defu)](https://npmjs.com/package/defu)
[![bundle size](https://img.shields.io/bundlephobia/minzip/defu)](https://bundlephobia.com/package/defu)
[![codecov](https://img.shields.io/codecov/c/gh/unjs/automd)](https://codecov.io/gh/unjs/automd)

<!-- /automd -->

## Usage

<!-- automd:pm-x args=. -->
Expand Down Expand Up @@ -50,4 +61,5 @@ Adds two numbers together.
add(1, 2); // 3
```


<!-- /automd -->
3 changes: 3 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

45 changes: 31 additions & 14 deletions src/_utils.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,37 @@
import { readPackageJSON } from "pkg-types";
import { readPackageJSON, type PackageJson } from "pkg-types";
import _consola from "consola";
import { defu } from "defu";

export const consola = _consola.withTag("automd");

export async function getPkg(
dir: string,
input: { name?: string; version?: string } = {},
) {
if (input.name && input.version) {
return input;
}
export async function getPkg(dir: string, input: Record<string, string> = {}) {
const pkg = await readPackageJSON(dir).catch(() => undefined);
return {
name: process.env.npm_package_name,
version: process.env.npm_package_name,
...pkg,
...input,
};
return defu(
{
name: input.name,
version: input.version,
github: input.github || input.gh,
},
{
name: pkg?.name,
version: pkg?.version,
github: _getGitRepo(pkg?.repository),
},
{
name: process.env.npm_package_name,
version: process.env.npm_package_version,
},
);
}

function _getGitRepo(repo: PackageJson["repository"]) {
const url = typeof repo === "string" ? repo : repo?.url;
if (!url || typeof url !== "string") {
return;
}
const match =
/(?:https:\/\/github\.com\/|gh:|github:|)([\w-]+)\/([\w-]+)/.exec(url);
if (match && match[1] && match[2]) {
return `${match[1]}/${match[2]}`;
}
}
106 changes: 106 additions & 0 deletions src/generators/badges.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
import { image, link } from "omark";
import { defineGenerator } from "../generator";
import { getPkg } from "../_utils";

type BadgeType = keyof typeof badgeTypes;
type BadgeProvider = Record<BadgeType, string> & { _params?: string[] };

const badgeTypes = {
npmVersion: {
name: "npm version",
to: "https://npmjs.com/package/{name}",
},
npmDownloads: {
name: "npm downloads",
to: "https://npmjs.com/package/{name}",
},
bundlephobia: {
name: "bundle size",
to: "https://bundlephobia.com/package/{name}",
},
codecov: {
name: "codecov",
to: "https://codecov.io/gh/{github}",
},
};

const badgeProviders = <Record<string, BadgeProvider>>{
shields: {
_params: ["style", "color", "labelColor"],
npmVersion: "https://img.shields.io/npm/v/{name}",
npmDownloads: "https://img.shields.io/npm/dm/{name}",
bundlephobia: "https://img.shields.io/bundlephobia/minzip/{name}",
codecov: "https://img.shields.io/codecov/c/gh/{github}",
},
badgen: {
npmVersion: "https://flat.badgen.net/npm/v/{name}",
npmDownloads: "https://flat.badgen.net/npm/dm/{name}",
bundlephobia: "https://flat.badgen.net/bundlephobia/minzip/{name}",
codecov: "https://flat.badgen.net/codecov/c/github/{github}",
},
badgenClassic: {
npmVersion: "https://badgen.net/npm/v/{name}",
npmDownloads: "https://badgen.net/npm/dm/{name}",
bundlephobia: "https://badgen.net/bundlephobia/minzip/{name}",
codecov: "https://badgen.net/codecov/c/github/{github}",
},
};

export const badges = defineGenerator({
name: "badges",
async generate({ config, args }) {
const pkg = await getPkg(config.dir, args);
const ctx: Record<string, any> = {
name: pkg.name,
github: pkg.github,
...args,
};

const fillStr = (str: string) =>
str.replace(/{(\w+)}/g, (_, key) => ctx[key] || "");

const provider = badgeProviders[args.provider] || badgeProviders.shields;
const providerParams = (provider._params || [])
.filter((key) => ctx[key])
.map(
(key) => `${encodeURIComponent(key)}=${encodeURIComponent(ctx[key])}`,
)
.join("&");

const badges = {
npmVersion: {
enabled: ctx.name,
...badgeTypes.npmVersion,
},
npmDownloads: {
enabled: ctx.name,
...badgeTypes.npmDownloads,
},
bundlephobia: {
enabled: args.bundlephobia && ctx.name,
...badgeTypes.bundlephobia,
},
codecov: {
enabled: args.codecov && ctx.github,
...badgeTypes.codecov,
},
} as const;

const md: string[] = [];

for (const [badgeType, badge] of Object.entries(badges)) {
if (!badge.enabled || !provider[badgeType as BadgeType]) {
continue;
}
const to = fillStr(badge.to);
const imgURL =
fillStr(provider[badgeType as BadgeType]) +
(providerParams ? `?${providerParams}` : "");
md.push(link(to, image(imgURL, badge.name)));
}

return {
contents: md.join("\n"),
};
},
});
2 changes: 2 additions & 0 deletions src/generators/index.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import { Generator } from "../generator";
import { jsdocs } from "./jsdocs";
import { badges } from "./badges";
import { pmX, pmInstall } from "./pm";

export default {
jsdocs,
badges,
"pm-install": pmInstall,
"pm-x": pmX,
} as Record<string, Generator>;

0 comments on commit 8db8058

Please sign in to comment.