diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5927c34..1b330c9 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -6,6 +6,20 @@ on: - develop jobs: + lint: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Setup Bun + uses: oven-sh/setup-bun@v2 + + - name: Lint all code + run: bunx prettier --check . + build: env: GH_TOKEN: ${{ github.token }} diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000..0967ef4 --- /dev/null +++ b/.prettierrc @@ -0,0 +1 @@ +{} diff --git a/README.md b/README.md index 2ad20ea..d0073ca 100644 --- a/README.md +++ b/README.md @@ -12,10 +12,10 @@ This is a great process for bug fixes, simple features and purely additive chang However, if you are making a significant change to the way Vortex functions, you may need to write an RFC first. Some example changes that would require an RFC: -* Making a risky change to the format, such as adding new required fields to file metadata -* Rearchitecting core components of Vortex, or wide-ranging refactors that might break language bindings -* Creating new libraries or SDKs that we expect others to adopt -* Making changes to subsystems that are likely to affect performance if not done thoughfully, such as the core IO traits +- Making a risky change to the format, such as adding new required fields to file metadata +- Rearchitecting core components of Vortex, or wide-ranging refactors that might break language bindings +- Creating new libraries or SDKs that we expect others to adopt +- Making changes to subsystems that are likely to affect performance if not done thoughfully, such as the core IO traits ## Process @@ -70,3 +70,14 @@ Remove the build output: ```sh bun run clean ``` + +### Formatting + +We use [`prettiest`](https://prettier.io/) to format the code and documents, and check it in CI. + +Running it is as easy as: + +```sh +bunx prettier --write . +bunx prettier --check . +``` diff --git a/bun.lock b/bun.lock index fb39207..f87bb78 100644 --- a/bun.lock +++ b/bun.lock @@ -1,11 +1,11 @@ { "lockfileVersion": 1, - "configVersion": 1, "workspaces": { "": { "name": "vortexrfc", "devDependencies": { "@types/bun": "latest", + "prettier": "^3.8.1", }, "peerDependencies": { "typescript": "^5", @@ -19,6 +19,8 @@ "bun-types": ["bun-types@1.3.9", "", { "dependencies": { "@types/node": "*" } }, "sha512-+UBWWOakIP4Tswh0Bt0QD0alpTY8cb5hvgiYeWCMet9YukHbzuruIEeXC2D7nMJPB12kbh8C7XJykSexEqGKJg=="], + "prettier": ["prettier@3.8.1", "", { "bin": { "prettier": "bin/prettier.cjs" } }, "sha512-UOnG6LftzbdaHZcKoPFtOcCKztrQ57WkHDeRD9t/PTQtmT0NHSeWWepj6pS0z/N7+08BHFDQVUrfmfMRcZwbMg=="], + "typescript": ["typescript@5.9.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw=="], "undici-types": ["undici-types@7.18.2", "", {}, "sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w=="], diff --git a/index.ts b/index.ts index 0b1f5a9..9d6b2a8 100644 --- a/index.ts +++ b/index.ts @@ -74,9 +74,17 @@ const LIVE_RELOAD_SCRIPT = ` })(); `; -function baseHTML(title: string, content: string, cssPath: string = "styles.css", liveReload: boolean = false, repoUrl: string | null = null): string { +function baseHTML( + title: string, + content: string, + cssPath: string = "styles.css", + liveReload: boolean = false, + repoUrl: string | null = null, +): string { const basePath = cssPath === "styles.css" ? "./" : "../"; - const githubLink = repoUrl ? `${ICON_GITHUB}` : ""; + const githubLink = repoUrl + ? `${ICON_GITHUB}` + : ""; return ` @@ -119,24 +127,31 @@ function escapeHTML(str: string): string { .replace(/"/g, """); } -function indexPage(rfcs: RFC[], repoUrl: string | null, liveReload: boolean = false): string { +function indexPage( + rfcs: RFC[], + repoUrl: string | null, + liveReload: boolean = false, +): string { // Sort in reverse numeric order (newest first) const sorted = [...rfcs].sort((a, b) => b.number.localeCompare(a.number)); - const list = sorted.map(rfc => { - const dateStr = rfc.git.accepted ? formatDate(rfc.git.accepted.date) : ""; + const list = sorted + .map((rfc) => { + const dateStr = rfc.git.accepted ? formatDate(rfc.git.accepted.date) : ""; - let authorHTML = ""; - if (rfc.git.author && rfc.git.accepted) { - const commitUrl = repoUrl ? `${repoUrl}/commit/${rfc.git.accepted.hash}` : `https://github.com/${rfc.git.author.login}`; - authorHTML = ` + let authorHTML = ""; + if (rfc.git.author && rfc.git.accepted) { + const commitUrl = repoUrl + ? `${repoUrl}/commit/${rfc.git.accepted.hash}` + : `https://github.com/${rfc.git.author.login}`; + authorHTML = ` ${rfc.git.author.login} ${rfc.git.author.login} `; - } + } - return ` + return `
  • RFC ${rfc.number} @@ -144,7 +159,8 @@ function indexPage(rfcs: RFC[], repoUrl: string | null, liveReload: boolean = fa ${dateStr} ${authorHTML}
  • `; - }).join("\n"); + }) + .join("\n"); const content = `

    Request for Comments

    @@ -164,7 +180,11 @@ function formatDate(date: Date): string { }); } -function rfcPage(rfc: RFC, repoUrl: string | null, liveReload: boolean = false): string { +function rfcPage( + rfc: RFC, + repoUrl: string | null, + liveReload: boolean = false, +): string { let gitHeader = ""; if (rfc.git.accepted || rfc.git.author) { @@ -218,7 +238,13 @@ function rfcPage(rfc: RFC, repoUrl: string | null, liveReload: boolean = false): ${rfc.html} `; - return baseHTML(`RFC ${rfc.number} - ${rfc.title}`, content, "../styles.css", liveReload, repoUrl); + return baseHTML( + `RFC ${rfc.number} - ${rfc.title}`, + content, + "../styles.css", + liveReload, + repoUrl, + ); } function parseRFCNumber(filename: string): string { @@ -245,10 +271,14 @@ async function getGitHubRepoUrl(): Promise { } } -async function getGitHubAuthor(repoPath: string, commitHash: string): Promise { +async function getGitHubAuthor( + repoPath: string, + commitHash: string, +): Promise { try { // Use gh CLI to fetch commit info from GitHub API - const result = await $`gh api repos/${repoPath}/commits/${commitHash} --jq '.author.login, .author.avatar_url, .author.html_url'`.quiet(); + const result = + await $`gh api repos/${repoPath}/commits/${commitHash} --jq '.author.login, .author.avatar_url, .author.html_url'`.quiet(); const lines = result.stdout.toString().trim().split("\n"); if (lines.length >= 3 && lines[0] && lines[1] && lines[2]) { @@ -264,9 +294,13 @@ async function getGitHubAuthor(repoPath: string, commitHash: string): Promise { +async function getGitHistory( + filepath: string, + repoPath: string | null, +): Promise { try { - const result = await $`git log --follow --format=%H\ %aI -- ${filepath}`.quiet(); + const result = + await $`git log --follow --format=%H\ %aI -- ${filepath}`.quiet(); const lines = result.stdout.toString().trim().split("\n").filter(Boolean); if (lines.length === 0) { @@ -284,7 +318,9 @@ async function getGitHistory(filepath: string, repoPath: string | null): Promise const oldest = parseCommit(lines[lines.length - 1]!); // Fetch author info from the first commit - const author = repoPath ? await getGitHubAuthor(repoPath, oldest.hash) : null; + const author = repoPath + ? await getGitHubAuthor(repoPath, oldest.hash) + : null; // If only one commit, or same commit, don't show lastUpdated if (lines.length === 1 || mostRecent.hash === oldest.hash) { @@ -479,7 +515,7 @@ async function startDevServer() { headers: { "Content-Type": "text/event-stream", "Cache-Control": "no-cache", - "Connection": "keep-alive", + Connection: "keep-alive", }, }); } @@ -503,9 +539,11 @@ async function startDevServer() { if (isDev) { startDevServer().catch(console.error); } else { - build().then(count => { - if (count > 0) { - console.log("Output directory: ./dist/"); - } - }).catch(console.error); + build() + .then((count) => { + if (count > 0) { + console.log("Output directory: ./dist/"); + } + }) + .catch(console.error); } diff --git a/package.json b/package.json index fd90889..b539045 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,8 @@ "clean": "rm -rf dist" }, "devDependencies": { - "@types/bun": "latest" + "@types/bun": "latest", + "prettier": "^3.8.1" }, "peerDependencies": { "typescript": "^5" diff --git a/styles.css b/styles.css index d74bf70..4f65a45 100644 --- a/styles.css +++ b/styles.css @@ -59,7 +59,16 @@ html { } body { - font-family: "Inter", "SF Pro Display", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; + font-family: + "Inter", + "SF Pro Display", + -apple-system, + BlinkMacSystemFont, + "Segoe UI", + Roboto, + Helvetica, + Arial, + sans-serif; background: var(--bg); color: var(--fg); line-height: 1.6; @@ -130,7 +139,9 @@ header h1 a:hover { height: 36px; border-radius: 50%; color: var(--fg-muted); - transition: color 0.15s ease, box-shadow 0.15s ease; + transition: + color 0.15s ease, + box-shadow 0.15s ease; } .github-link:hover { @@ -174,17 +185,33 @@ main { min-height: calc(100vh - 200px); } -h1, h2, h3, h4, h5, h6 { +h1, +h2, +h3, +h4, +h5, +h6 { font-weight: 600; margin-top: 2rem; margin-bottom: 1rem; color: var(--accent); } -h1 { font-size: 1.75rem; margin-top: 0; } -h2 { font-size: 1.375rem; } -h3 { font-size: 1.125rem; } -h4, h5, h6 { font-size: 1rem; } +h1 { + font-size: 1.75rem; + margin-top: 0; +} +h2 { + font-size: 1.375rem; +} +h3 { + font-size: 1.125rem; +} +h4, +h5, +h6 { + font-size: 1rem; +} p { margin-bottom: 1rem; @@ -200,7 +227,8 @@ a:hover { text-decoration: underline; } -ul, ol { +ul, +ol { margin-bottom: 1rem; padding-left: 1.5rem; } @@ -210,7 +238,8 @@ li { } code { - font-family: "IBM Plex Mono", "SF Mono", "Menlo", "Monaco", "Consolas", monospace; + font-family: + "IBM Plex Mono", "SF Mono", "Menlo", "Monaco", "Consolas", monospace; background: var(--code-bg); padding: 0.125rem 0.375rem; border-radius: 3px; @@ -218,7 +247,8 @@ code { } pre { - font-family: "IBM Plex Mono", "SF Mono", "Menlo", "Monaco", "Consolas", monospace; + font-family: + "IBM Plex Mono", "SF Mono", "Menlo", "Monaco", "Consolas", monospace; background: var(--code-bg); border: 1px solid var(--border); border-radius: 4px; @@ -254,7 +284,8 @@ table { margin-bottom: 1rem; } -th, td { +th, +td { border: 1px solid var(--border); padding: 0.5rem 0.75rem; text-align: left; @@ -278,7 +309,9 @@ th { padding: 0.75rem 1rem; margin: 0 -1rem; border-radius: 4px; - transition: box-shadow 0.15s ease, background 0.15s ease; + transition: + box-shadow 0.15s ease, + background 0.15s ease; } .rfc-list li:hover { @@ -306,7 +339,8 @@ th { } .rfc-item .rfc-number { - font-family: "IBM Plex Mono", "SF Mono", "Menlo", "Monaco", "Consolas", monospace; + font-family: + "IBM Plex Mono", "SF Mono", "Menlo", "Monaco", "Consolas", monospace; color: var(--fg-muted); font-size: 0.875rem; flex-shrink: 0;