Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .github/workflows/checks.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: actions/setup-node@v4
with:
node-version: 24
Expand All @@ -22,3 +24,4 @@ jobs:
- run: npm run format:check
- run: npm run lint
- run: npm test
- run: node dist-test/src/bin/simpledoc.js check
22 changes: 22 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,28 @@ npx -y @simpledoc/simpledoc migrate

This will start a step-by-step wizard to migrate existing documentation to SimpleDoc and add instructions to `AGENTS.md` to follow it.

## CI / Enforcement

To enforce SimpleDoc conventions in CI, add a step that fails when the repo needs migration:

```bash
npx -y @simpledoc/simpledoc check
```

### GitHub Actions example

SimpleDoc relies on git history for timestamps/authors, so ensure the repo is not a shallow clone:

```yaml
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: actions/setup-node@v4
with:
node-version: 24
- run: npx -y @simpledoc/simpledoc check
```

## Why?

If you have been a developer for a while, the conventions described above should be familiar and common sense to you. For some weird reason, a crystallized definition such as this one does not exist online, e.g. the way [JSend](https://github.com/omniti-labs/jsend) does for API responses. So this is an attempt to fill that gap.
Expand Down
1 change: 1 addition & 0 deletions docs/HOW_TO_DOC.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,3 +85,4 @@ SimpleDoc Guidelines:
- [ ] Timeless vs. dated classification is correct and filenames reflect the choice.
- [ ] Front matter is complete and accurate.
- [ ] Links to related documentation exist where applicable.
- [ ] Run `npx -y @simpledoc/simpledoc check` (or `simpledoc check`) to verify SimpleDoc conventions.
77 changes: 77 additions & 0 deletions src/cli/check.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import process from "node:process";

import {
formatActions,
planMigration,
type FrontmatterAction,
type ReferenceUpdateAction,
type RenameAction,
} from "../migrator.js";
import { MAX_STEP_FILE_PREVIEW_LINES, limitLines } from "./ui.js";

function getErrorMessage(err: unknown): string {
if (err instanceof Error) return err.message;
return String(err);
}

export async function runCheck(): Promise<void> {
try {
const plan = await planMigration();

const renames = plan.actions.filter(
(a): a is RenameAction => a.type === "rename",
);
const frontmatters = plan.actions.filter(
(a): a is FrontmatterAction => a.type === "frontmatter",
);
const references = plan.actions.filter(
(a): a is ReferenceUpdateAction => a.type === "references",
);

if (
renames.length === 0 &&
frontmatters.length === 0 &&
references.length === 0 &&
true
) {
process.stdout.write("OK: repo matches SimpleDoc conventions.\n");
return;
}

process.stdout.write("SimpleDoc check failed.\n\n");

const summaryLines: string[] = [];
if (renames.length > 0)
summaryLines.push(
`- Rename/move Markdown files: ${renames.length} file${renames.length === 1 ? "" : "s"}`,
);
if (frontmatters.length > 0)
summaryLines.push(
`- Insert YAML frontmatter: ${frontmatters.length} file${frontmatters.length === 1 ? "" : "s"}`,
);
if (references.length > 0)
summaryLines.push(
`- Update references to renamed docs: ${references.length} file${references.length === 1 ? "" : "s"}`,
);

process.stdout.write(`${summaryLines.join("\n")}\n\n`);

if (renames.length + frontmatters.length + references.length > 0) {
const previewLines: string[] = [];
if (renames.length > 0) previewLines.push(formatActions(renames));
if (frontmatters.length > 0)
previewLines.push(formatActions(frontmatters));
if (references.length > 0) previewLines.push(formatActions(references));

const preview = previewLines.filter(Boolean).join("\n");
const limited = limitLines(preview, MAX_STEP_FILE_PREVIEW_LINES);
process.stdout.write(`${limited}\n\n`);
}

process.stdout.write("Run `simpledoc migrate` to fix.\n");
process.exitCode = 1;
} catch (err) {
process.stderr.write(`${getErrorMessage(err)}\n`);
process.exitCode = 1;
}
}
8 changes: 8 additions & 0 deletions src/cli/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import process from "node:process";
import { Command, CommanderError } from "commander";

import { runCheck } from "./check.js";
import { runMigrate } from "./migrate.js";

type MigrateOptions = {
Expand Down Expand Up @@ -53,6 +54,13 @@ export async function runCli(argv: string[]): Promise<void> {
await runMigrate(options);
});

program
.command("check")
.description("Fail if the repo violates SimpleDoc conventions (use in CI).")
.action(async () => {
await runCheck();
});

const rest = argv.slice(2);
const argvToParse = shouldDefaultToMigrate(rest)
? [...argv.slice(0, 2), "migrate", ...rest]
Expand Down