Skip to content

Commit 3b2fa9d

Browse files
committed
fix: update scripts
1 parent 156f119 commit 3b2fa9d

File tree

4 files changed

+122
-68
lines changed

4 files changed

+122
-68
lines changed

scripts/update-readme.ts

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,20 @@
1-
import fs from "fs/promises";
1+
import * as NodeContext from "@effect/platform-node/NodeContext";
2+
import * as NodeRuntime from "@effect/platform-node/NodeRuntime";
3+
import * as FileSystem from "@effect/platform/FileSystem";
4+
import * as Effect from "effect/Effect";
25

3-
await fs.copyFile(
4-
"README.md",
5-
"packages/plugins/eslint-plugin/README.md",
6-
);
6+
const program = Effect.gen(function*() {
7+
const fs = yield* FileSystem.FileSystem;
8+
const source = "README.md";
9+
const destination = "packages/plugins/eslint-plugin/README.md";
10+
11+
// Ensure the destination directory exists
12+
yield* fs.makeDirectory("packages/plugins/eslint-plugin", { recursive: true });
13+
14+
// Copy the README file
15+
yield* fs.copyFile(source, destination);
16+
17+
yield* Effect.log(`Copied ${source} to ${destination}`);
18+
});
19+
20+
program.pipe(Effect.provide(NodeContext.layer), NodeRuntime.runMain);

scripts/update-version.ts

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
1-
import * as NodeFileSystem from "@effect/platform-node/NodeFileSystem";
1+
import * as NodeContext from "@effect/platform-node/NodeContext";
22
import * as NodeRuntime from "@effect/platform-node/NodeRuntime";
33
import * as FileSystem from "@effect/platform/FileSystem";
44
import ansis from "ansis";
55
import * as Effect from "effect/Effect";
6+
import * as Fn from "effect/Function";
67
import { isMatching, match, P } from "ts-pattern";
78

89
import { ignores } from "./effects/ignores";
@@ -25,19 +26,17 @@ function update(filename: string) {
2526
}
2627
const newVersion = yield* version;
2728
const oldVersion = match(packageJson)
28-
.with({ version: P.select(P.string) }, (v) => v)
29+
.with({ version: P.select(P.string) }, Fn.identity)
2930
.otherwise(() => "0.0.0");
3031
if (oldVersion === newVersion) {
3132
yield* Effect.log(ansis.greenBright(`Skipping ${filename} as it's already on version ${newVersion}`));
32-
return false;
3333
}
3434
const packageJsonUpdated = {
3535
...packageJson,
3636
version: newVersion,
3737
};
3838
yield* fs.writeFileString(filename, `${JSON.stringify(packageJsonUpdated, null, 2)}\n`);
3939
yield* Effect.log(`Updated ${filename} to version ${packageJsonUpdated.version}`);
40-
return true;
4140
});
4241
}
4342

@@ -47,4 +46,4 @@ const program = Effect.gen(function*() {
4746
return yield* Effect.all(packageJsonFiles.map(update), { concurrency: 8 });
4847
});
4948

50-
program.pipe(Effect.provide(NodeFileSystem.layer), NodeRuntime.runMain);
49+
program.pipe(Effect.provide(NodeContext.layer), NodeRuntime.runMain);

scripts/update-website.ts

Lines changed: 94 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,72 +1,118 @@
1-
import fs from "node:fs/promises";
2-
import path from "node:path";
1+
import * as NodeContext from "@effect/platform-node/NodeContext";
2+
import * as NodeRuntime from "@effect/platform-node/NodeRuntime";
3+
import * as FileSystem from "@effect/platform/FileSystem";
4+
import * as Path from "@effect/platform/Path";
5+
import ansis from "ansis";
6+
import * as Effect from "effect/Effect";
37

48
import { glob } from "./utils/glob";
59

610
/**
711
* Build script for processing and copying documentation to the website
812
*
9-
* This script:
13+
* This script (Effect version):
1014
* 1. Collects rule documentation from ESLint Plugins
1115
* 2. Copies them to the website with proper naming
1216
* 3. Processes the changelog
13-
* 4. Sets up dependencies for the website build
17+
* 4. (TODO) Generates meta.json / rules data
1418
*/
1519

16-
// Find all rule documentation markdown files from the various plugins
17-
const docs = glob(["packages/plugins/eslint-plugin-react-*/src/rules/*.md"]);
18-
19-
// TODO: Generate the meta.json file as well
20-
// Process each documentation file:
21-
// - Extract plugin name and rule name
22-
// - Format destination path and rule title
23-
// - Build arrays of file paths and rule metadata
24-
const [
25-
files,
26-
// rules, // Currently commented out but would contain rule metadata
27-
] = Array.from(docs).reduce<readonly [[string, string][], [string, string][]]>(
28-
([files, rules], doc) => {
20+
const DOCS_GLOB = ["packages/plugins/eslint-plugin-react-*/src/rules/*.mdx"];
21+
22+
interface RuleMeta {
23+
name: string;
24+
title: string;
25+
destination: string;
26+
source: string;
27+
}
28+
29+
const collectDocs = Effect.gen(function*() {
30+
const path = yield* Path.Path;
31+
const docs = yield* Effect.sync(() => glob(DOCS_GLOB));
32+
return docs.map<RuleMeta>((doc) => {
2933
const catename = /^packages\/plugins\/eslint-plugin-react-([^/]+)/u.exec(doc)?.[1] ?? "";
3034
const basename = path.parse(path.basename(doc)).name;
3135

32-
// Special handling for "react-x" plugin (the core plugin)
3336
const isPluginX = catename === "x";
3437

35-
// Format the rule name differently based on which plugin it belongs to
36-
const name = isPluginX
37-
? basename // For react-x plugin: just use the rule name
38-
: `${catename}-${basename}`; // For other plugins: prefix with category
38+
const name = isPluginX ? basename : `${catename}-${basename}`;
39+
const title = isPluginX ? basename : `${catename}/${basename}`;
40+
41+
const destination = path.join("apps", "website", "content", "docs", "rules", `${name}.mdx`);
42+
43+
return {
44+
name,
45+
title,
46+
destination,
47+
source: doc,
48+
};
49+
});
50+
});
51+
52+
function copyRuleDoc(meta: RuleMeta) {
53+
return Effect.gen(function*() {
54+
const fs = yield* FileSystem.FileSystem;
55+
const path = yield* Path.Path;
56+
const dir = path.dirname(meta.destination);
57+
// Ensure destination directory exists
58+
yield* fs.makeDirectory(dir, { recursive: true });
59+
const content = yield* fs.readFileString(meta.source, "utf8");
60+
yield* fs.writeFileString(meta.destination, content);
61+
yield* Effect.log(ansis.green(`Copied ${meta.source} -> ${meta.destination}`));
62+
return meta;
63+
});
64+
}
65+
66+
const processChangelog = Effect.gen(function*() {
67+
const fs = yield* FileSystem.FileSystem;
68+
const path = yield* Path.Path;
69+
const changelogPath = "CHANGELOG.md";
70+
const targetPath = path.join("apps", "website", "content", "docs", "changelog.md");
71+
72+
const source = yield* fs.readFileString(changelogPath, "utf8");
73+
const wrapped = [
74+
"---",
75+
"title: Changelog",
76+
"---",
77+
"",
78+
source,
79+
].join("\n");
80+
81+
const dir = path.dirname(targetPath);
82+
yield* fs.makeDirectory(dir, { recursive: true });
83+
yield* fs.writeFileString(targetPath, wrapped);
84+
yield* Effect.log(ansis.cyan(`Processed changelog -> ${targetPath}`));
85+
});
3986

40-
// Format the rule title for display purposes
41-
const title = isPluginX
42-
? basename // For react-x plugin: just use the rule name
43-
: `${catename}/${basename}`; // For other plugins: use category/rule format
87+
const program = Effect.gen(function*() {
88+
yield* Effect.log(ansis.bold("Processing rule documentation..."));
4489

45-
// Define destination path in the website content directory
46-
const dest = path.join("apps", "website", "content", "docs", "rules", `${name}.mdx`);
90+
const metas = yield* collectDocs;
4791

48-
// Add to our accumulator arrays
49-
return [[...files, [doc, dest]], [...rules, [name, title]]] as const;
50-
},
51-
[[], []],
52-
);
92+
yield* Effect.log(
93+
metas.length === 0
94+
? ansis.yellow("No documentation files found.")
95+
: `Found ${ansis.bold(metas.length.toString())} rule documentation file(s).`,
96+
);
5397

54-
// Copy all documentation files to their respective destinations in parallel
55-
await Promise.all(files.map(([src, dest]) => fs.copyFile(src, dest)));
98+
// Copy in parallel with limited concurrency (adjust if needed)
99+
yield* Effect.forEach(metas, copyRuleDoc, { concurrency: 8 });
56100

57-
// Write rule metadata to a JSON file for the website
58-
// fs.writeFileSync(path.join("apps", "website", "content", "docs", "rules", "data.json"), JSON.stringify(rules, null, 2));
101+
// (Optional) Generate rules metadata JSON (still TODO)
102+
// const rulesData = metas.map(({ name, title }) => ({ name, title }));
103+
// const rulesDataPath = path.join("apps", "website", "content", "docs", "rules", "data.json");
104+
// yield* FileSystem.FileSystem.flatMap(fs =>
105+
// fs.makeDirectory(path.dirname(rulesDataPath), { recursive: true }).pipe(
106+
// Effect.zipRight(
107+
// fs.writeFileString(rulesDataPath, JSON.stringify(rulesData, null, 2) + "\n")
108+
// ),
109+
// Effect.tap(() => Effect.log(ansis.magenta(`Generated ${rulesDataPath}`)))
110+
// )
111+
// );
59112

60-
// Process the changelog file by adding frontmatter for the documentation system
61-
const changelog = await fs.readFile("CHANGELOG.md", "utf-8");
113+
yield* processChangelog;
62114

63-
const changelogWithFrontmatter = [
64-
"---",
65-
"title: Changelog",
66-
"---",
67-
"",
68-
changelog,
69-
].join("\n");
115+
yield* Effect.log(ansis.bold.green("Documentation processing completed."));
116+
});
70117

71-
// Write the processed changelog to the website content directory
72-
await fs.writeFile(path.join("apps", "website", "content", "docs", "changelog.md"), changelogWithFrontmatter);
118+
program.pipe(Effect.provide(NodeContext.layer), NodeRuntime.runMain);

scripts/verify-lockfile.ts

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
import { Command, CommandExecutor } from "@effect/platform";
2-
import { NodeCommandExecutor, NodeFileSystem, NodeRuntime } from "@effect/platform-node";
1+
import * as NodeContext from "@effect/platform-node/NodeContext";
2+
import * as NodeRuntime from "@effect/platform-node/NodeRuntime";
3+
import * as Command from "@effect/platform/Command";
4+
import * as CommandExecutor from "@effect/platform/CommandExecutor";
35
import { Effect } from "effect";
4-
import * as Fn from "effect/Function";
5-
import * as Layer from "effect/Layer";
66

77
const command = Command.make("git", "diff", "HEAD@{1}", "--stat", "--", "./pnpm-lock.yaml");
88
const program = Effect.gen(function*() {
@@ -15,9 +15,4 @@ const program = Effect.gen(function*() {
1515
yield* Effect.logWarning("Please run `pnpm install --fix-lockfile && pnpm dedupe` to update local dependencies.");
1616
});
1717

18-
const MainLive = Fn.pipe(
19-
NodeCommandExecutor.layer,
20-
Layer.provideMerge(NodeFileSystem.layer),
21-
);
22-
23-
program.pipe(Effect.provide(MainLive), NodeRuntime.runMain);
18+
program.pipe(Effect.provide(NodeContext.layer), NodeRuntime.runMain);

0 commit comments

Comments
 (0)