-
Notifications
You must be signed in to change notification settings - Fork 0
/
README.ts
executable file
·105 lines (78 loc) · 3.1 KB
/
README.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
#!/usr/bin/env -S deno run --allow-read --allow-run=bash,git,cargo --allow-env --allow-sys
import * as zx from "npm:zx"
import { z, ZodSchema } from "https://deno.land/x/[email protected]/mod.ts"
import { assertEquals } from "https://jsr.io/@std/assert/1.0.0/equals.ts"
import { assert } from "https://jsr.io/@std/assert/1.0.0/assert.ts"
const CargoToml = z.object({
package: z.object({
name: z.string().min(1),
description: z.string().min(1),
repository: z.string().url().min(1),
metadata: z.object({
details: z.object({
title: z.string().min(1),
tagline: z.string(),
summary: z.string(),
}),
}),
}),
})
type CargoToml = z.infer<typeof CargoToml>
const CargoMetadataSchema = z.object({
packages: z.array(z.object({
name: z.string(),
targets: z.array(z.object({
name: z.string(),
})),
})),
})
type CargoMetadata = z.infer<typeof CargoMetadataSchema>
const Repo = z.object({
url: z.string().url(),
})
type Repo = z.infer<typeof Repo>
const $ = zx.$({
cwd: import.meta.dirname,
})
const parse = <T>(schema: ZodSchema<T>, input: zx.ProcessOutput) => schema.parse(JSON.parse(input.stdout))
const renderMarkdownList = (items: string[]) => items.map((bin) => `* ${bin}`).join("\n")
const theCargoToml: CargoToml = parse(CargoToml, await $`yj -t < Cargo.toml`)
const { package: { name, metadata: { details: { title } } } } = theCargoToml
const bin = name
const help = await $`cargo run --quiet --bin ${bin} -- --help`
const theCargoMetadata: CargoMetadata = parse(CargoMetadataSchema, await $`cargo metadata --format-version 1`)
const thePackageMetadata = theCargoMetadata.packages.find((p) => p.name == name)
assert(thePackageMetadata, "Could not find package metadata")
const target = thePackageMetadata.targets[0]
assert(target, "Could not find package first target")
const doc = await $`cargo doc2readme --template README.jl --target-name ${target.name} --out -`
const repo: Repo = parse(Repo, await $`gh repo view --json url`)
const extraBins = (await $`find src/bin/*.rs -type f -exec basename {} .rs \\;`).valueOf().split("\n")
assertEquals(repo.url, theCargoToml.package.repository)
const autogenerated = `
<!-- DO NOT EDIT -->
<!-- This file is automatically generated by README.ts. -->
<!-- Edit README.ts if you want to make changes. -->
`.trim()
console.info(`
${autogenerated}
# ${title}
[![Build](${repo.url}/actions/workflows/ci.yml/badge.svg)](${repo.url})
[![Documentation](https://docs.rs/${name}/badge.svg)](https://docs.rs/${name})
${doc.stdout.trim()}
## Installation
\`\`\`shell
cargo install --locked ${name}
\`\`\`
## Usage
\`\`\`
${help.stdout.trim()}
\`\`\`
## Additional binaries
${renderMarkdownList(extraBins.map((bin) => `\`${bin}\``))}
## Gratitude
Like the project? [⭐ Star this repo](${repo.url}) on GitHub!
## License
[Apache License 2.0](LICENSE-APACHE) or [MIT License](LICENSE-MIT) at your option.
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in this crate by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.
`.trim())