@ 受影响/平板
管理部分:已划定 BEGIN编号 :END 块,其周围内容属于用户的文件。 一个工具拥有块,用户拥有其他一切,既不破坏另一个——一个生成的钩子背后的机制,一个管理的配置片段,或者任何文件,你的工具和用户都需要编辑.
预
1.0.0。 。 。 . 此软件包是@effected/*在稳定基础上建造的工具包 效应v4(effect~4.1.0) 并仍在0.x发展。 稳定效果 制作一个工具箱1.0.0可能,不是自动的。 为了保持你的effect财务报告和审定财务报表@effect/*该工具包在线上构建和测试、安装@effected/pnpm-plugin-effected。 。 。 .稳定:不稳定. 此软件包的 API 表面尚未考虑 完成并可能改变
0.x释放 定一个确切的版本——甚至 标记软件包 稳定 在此之前1.0.0可以引入突破性更改 和精确的针 变成一个类型检查错误 而不是一个 跑步时间惊喜。 完全政策: 释放策略。 。 。 .
为什么 @ effect/ templates
大多数"管理区段"执行将整个算法放入一个也做文件IO的服务中,因此最难的逻辑——决定改变什么,以及新块属于哪里——只能通过将文件写入磁盘来测试. 这个包裹将两者分开. SectionDocument 是一个纯字符串对字符串的核心,没有 Effect,没有IO和运行时间:分析文档,将已声明的一节与已声明的一节进行比较,核对整组内容,得出结果. ManagedSection 是一种读取文件、调用纯核心并只在文本实际更改时才写回的稀疏服务.
模糊性没有输入而不是通过猜测解决:未终止标记、孤儿 END,两个相重叠的部分,或两次声明的同一身份都是输入的 SectionParseError 命名行名, 绝不允许在下次运行时留下重复块的无声跳过。 线尾也是一种一等的不常态——文档中占主导地位的EOL在剖面上被检测出,并且每次比较都是EOL-正态的,因此一个CRLF文件不会永远报告漂移.
安装
npm install @effected/templates effect
pnpm add @effected/templates effect
需要节点.js~~24.11.0. effect v4是唯一的对等依赖. @effected/files 作为普通的依赖而出现, 它支持原子写作.
全体 @effected/* 软件包仅为无害环境管理:只公布出口地图 import 条件,所以 require() 包括解析 CJS 模式的工具 —— 与节点失败 ERR_PACKAGE_PATH_NOT_EXPORTED 而不是装入不存在的 CJS 建筑。 从ES模块导入.
FileSystem 来自 effect 核心,而不是从一个平台包,所以消费者提供一次在边缘(NodeFileSystem.layer 从 @effect/platform-node 在节点上. Path 也有必要NodePath.layer 在节点上 : 同步通过旁边的临时文件替换文件并重命名, 所以崩溃不能留下已切换的文件 .
快开始
宣布两节并同步成一个调用的文件 。 宣布的命令成为文件命令,所以 base 总是在前面 tool然而,用户可能已经手动重排文件:
import { CommentStyle, ManagedSection, SectionId } from "@effected/templates";
import * as NodeFileSystem from "@effect/platform-node/NodeFileSystem";
import * as NodePath from "@effect/platform-node/NodePath";
import { Effect, Layer } from "effect";
const Base = SectionId.make({ key: "base", commentStyle: CommentStyle.hash });
const Tool = SectionId.make({ key: "tool", commentStyle: CommentStyle.hash });
const program = Effect.gen(function* () {
const sections = yield* ManagedSection;
return yield* sections.syncAll(".husky/pre-commit", [Base.section("#!/usr/bin/env sh"), Tool.section("npx tool run")]);
});
Effect.runPromise(program.pipe(Effect.provide(ManagedSection.layer), Effect.provide(Layer.mergeAll(NodeFileSystem.layer, NodePath.layer)))).then((outcomes) =>
console.log(outcomes.map((o) => o._tag)),
);
// example output on a fresh file: [ "Created", "Created" ]
// example output on a second, identical run: [ "Unchanged", "Unchanged" ]
标记属性
A 类 BEGIN 标记可以携带 name="value" 因此,一个工具读取一个块的出处——它运行它,并且当——离开标记线而不打开块:
import { CommentStyle, SectionDocument, SectionId } from "@effected/templates";
import { Result } from "effect";
const Tool = SectionId.make({ key: "tool", commentStyle: CommentStyle.hash });
const doc = SectionDocument.parseResult("#!/usr/bin/env sh\n");
if (Result.isSuccess(doc)) {
const next = doc.success.reconcile([Tool.section("npx tool run", { origin: "ci", runId: "1873" })]);
console.log(Result.isSuccess(next) ? next.success.text : next.failure.message);
// #!/usr/bin/env sh
//
// # --- BEGIN tool MANAGED SECTION origin="ci" runId="1873" ---
// npx tool run
// # --- END tool MANAGED SECTION ---
}
属性是元数据, 永远不识别 : 一节是按键和注释样式单独找到的, 所以突起 runId 更新该块的位置, 而不是使它成为孤儿 并附加第二个。 它们确实算作是差别—— check 答题 Drifted 当一个已声明的属性对磁盘上的标记有异议时,这就是让一个工具重写一个唯一的更改是其元数据的块. 辩论和通过 {} 所以一个从未使用过属性的呼叫者 看不到赤裸的标记的漂移.
语法没有逃避,故意:名字匹配 [A-Za-z][A-Za-z0-9_-]*,数值为双引出,不带 " 或线条断开, 和任何外部的失败键入为 SectionRenderError 与 reason: "invalidAttribute" 命名属性——在字节被写入之前。 一个 END 标记从不携带属性,一个不清晰解析的属性运行(一对被mangled single,一个名称被声明了两次)使得整行的普通内容而不是标记.
属性标记是一个单向相容性中断:这个特性之前的扫描仪完全认不出一个,所以它打开的块停止成为该工具的一个被管理的部分. 将属性写入一个文件,另一个管理的工具是决定,而不是细节.
特征
SectionDocument纯核:parse编号 :read编号 :has编号 :check编号 :reconcile编号 :remove在一个平整的字符串上,没有Effect没有IO和运行时间 测试它.ManagedSection服务:read, (中文(简体) ),readAll, (中文(简体) ),isManaged, (中文(简体) ),sync, (中文(简体) ),syncAll, (中文(简体) ),check, (中文(简体) ),checkAll财务报告和审定财务报表remove,每个字只写回文本更改时.CommentStyle- 一套开放式的{prefix, suffix?}预设( e)hash, (中文(简体) ),slash, (中文(简体) ),semicolon, (中文(简体) ),dash, (中文(简体) ),html, (中文(简体) ),block)涵盖行评论和包裹评论,如:<!-- … -->,所以一个被管理的段落可以活在Markdown或HTML中,而不仅仅是源文件.- 标记属性 ——
name="value"在一对BEGIN标记,通过SectionId.section(content, attributes)财务报告和审定财务报表Section.attributes: 工具的元数据, 绝不是一节身份的一部分. SyncOutcome编号 :CheckOutcome- 贴有标签的结果(Created编号 :Updated编号 :Unchanged, (中文(简体) ),Absent编号 :UpToDate编号 :Drifted),承接相关段落,而不是diff,所以一个呼叫者进行精确的对比.- 管理区块外的字节保存:一个被宣布的区块外的每个字符都会通过一个同步,顺序包括一个领先的BOM.
- 由构建而来:同步一个已经更新的文档不会写出任何内容,也不会触动任何时间.