Compare commits

...

2 Commits

Author SHA1 Message Date
7566bf8612 copy other 2022-04-22 22:51:41 +09:00
ebabd956e0 doc detail 2022-04-22 16:08:44 +09:00
5 changed files with 78 additions and 28 deletions

View File

@ -7,3 +7,14 @@
mdbook serve mdbook serve
``` ```
를 통해서 [문서](http://localhost:3000)을 웹브라우저로 볼 수 있습니다. 를 통해서 [문서](http://localhost:3000)을 웹브라우저로 볼 수 있습니다.
## cli.py
deno가 설치되어 있어야 합니다.
처음 실행시 issue를 가지고 오는 작업이 필요합니다. 먼저, `GITHUB_TOKEN` 환경변수에 깃헛 token을 설정해주세요. `.env`를 지원합니다.
토큰을 발급받기 위해선 [다음 링크](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/creating-a-personal-access-token)를 참조하면 됩니다.
```bash
./cli.py build --update_issues
```
를 실행해 주세요.

View File

@ -3,9 +3,12 @@ import { Issue } from "./githubType.ts";
import { copy } from "https://deno.land/std@0.136.0/fs/mod.ts"; import { copy } from "https://deno.land/std@0.136.0/fs/mod.ts";
import { readAll } from "https://deno.land/std@0.135.0/streams/mod.ts" import { readAll } from "https://deno.land/std@0.135.0/streams/mod.ts"
import { parse as argParse } from "https://deno.land/std@0.135.0/flags/mod.ts"; import { parse as argParse } from "https://deno.land/std@0.135.0/flags/mod.ts";
import { normalize, join as pathJoin, fromFileUrl, parse as parsePath import {
, relative } from "https://deno.land/std@0.135.0/path/mod.ts"; normalize, join as pathJoin, fromFileUrl, parse as parsePath
, relative
} from "https://deno.land/std@0.135.0/path/mod.ts";
import * as Eta from "https://deno.land/x/eta@v1.12.3/mod.ts"; import * as Eta from "https://deno.land/x/eta@v1.12.3/mod.ts";
import { createReactive } from "./reactivity.ts";
async function readContent(path?: string): Promise<string> { async function readContent(path?: string): Promise<string> {
let content = "[]"; let content = "[]";
@ -69,16 +72,17 @@ async function readAndPrint(args: {
async function main() { async function main() {
const parsedArg = argParse(Deno.args); const parsedArg = argParse(Deno.args);
const { issue_path, outDir, w, watch } = parsedArg; const { issue_path, outDirArg, w, watch } = parsedArg;
const watchMode = w || watch; const watchMode = w || watch;
if (typeof issue_path !== "undefined" && typeof issue_path !== "string") { if (typeof issue_path !== "undefined" && typeof issue_path !== "string") {
console.log("Please provide a path to the json file."); console.log("Please provide a path to the json file.");
Deno.exit(1); Deno.exit(1);
} }
if (typeof outDir !== "undefined" && typeof outDir !== "string") { if (typeof outDirArg !== "undefined" && typeof outDirArg !== "string") {
console.log("Please provide a path to the output file."); console.log("Please provide a path to the output file.");
Deno.exit(1); Deno.exit(1);
} }
const outDir = (outDirArg ?? "build");
if (typeof watchMode !== "undefined" && typeof watchMode !== "boolean") { if (typeof watchMode !== "undefined" && typeof watchMode !== "boolean") {
console.log("Please provide a boolean value for w."); console.log("Please provide a boolean value for w.");
Deno.exit(1); Deno.exit(1);
@ -95,14 +99,29 @@ async function main() {
views: viewPath, views: viewPath,
"view cache": false, "view cache": false,
}); });
const issuesR = await createReactive(async () => {
const c = await readContent(issue_path); const c = await readContent(issue_path);
const issues = JSON.parse(c) as Issue[]; const issues = JSON.parse(c) as Issue[];
issues.sort((a, b) => a.number - b.number); issues.sort((a, b) => a.number - b.number);
return issues;
});
const targets = ["SUMMARY.md", "overall.md", "specific.md", "intro.md", "support.md"]; const targets = ["SUMMARY.md", "overall.md", "specific.md", "intro.md", "support.md"];
await readAndPrint({ issue_path, outDir, targets }); const targetsR = await Promise.all(targets.map(async (t) => {
return await createReactive(() => {
return readAndPrint({ issue_path, outDir, targets:[t] });
});
}
));
issuesR.wireTo(...targetsR);
const copyOp = await createReactive(async () => {
const files = [...Deno.readDirSync(viewPath)].map(x => x.name).filter(x => !x.endsWith(".md"));
const op = files.map(x => copy(pathJoin(viewPath, x), pathJoin(outDir, x), { overwrite: true }));
await Promise.all(op);
});
if (watchMode) { if (watchMode) {
const watcher = Deno.watchFs([viewPath, issue_path as string]); const watcher = Deno.watchFs([viewPath, issue_path as string]);
for await (const event of watcher) { for await (const event of watcher) {
@ -111,28 +130,20 @@ async function main() {
new TextEncoder().encode("\x1b[2J\x1b[0f"), new TextEncoder().encode("\x1b[2J\x1b[0f"),
); );
console.log(`reloading ${event.paths.join(", ")}`); console.log(`reloading ${event.paths.join(", ")}`);
let reloadAll = false;
for (const path of event.paths) { for (const path of event.paths) {
const p = parsePath(path); const p = parsePath(path);
if (targets.includes(p.base)) { if (p.dir === viewPath) {
readAndPrint({ if(p.ext === ".md") {
issue_path: issue_path as string, targetsR[targets.indexOf(p.base)].update();
outDir: outDir as string, }
targets: [p.base] else{
}); copyOp.update();
}
} }
else{ else if (p.base === "issues.json") {
reloadAll = true; await issuesR.update();
break;
} }
} }
if (reloadAll) {
readAndPrint({
issue_path: issue_path as string,
outDir: outDir as string,
targets: targets
});
}
} }
} }
} }

28
tools/reactivity.ts Normal file
View File

@ -0,0 +1,28 @@
interface Reactive<T>{
readonly value: T;
update: () => Promise<void>;
wireTo(...r: Reactive<unknown>[]): void;
unwireTo(r: Reactive<unknown>): void;
}
export async function createReactive<T>(fn: () => Promise<T>): Promise<Reactive<T>> {
let v = await fn();
let listeners: Reactive<unknown>[] = [];
return {
get value() : T {
return v;
},
async update(){
const ret = await fn();
v = ret;
await Promise.all(listeners.map(o => o.update()));
},
wireTo(...r: Reactive<unknown>[]) {
listeners.push(...r);
},
unwireTo(r: Reactive<unknown>) {
listeners = listeners.filter(o => o !== r);
}
};
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

View File

@ -125,7 +125,7 @@ classDiagram
### 3.7.2. 사용자 인터페이스 상세 ### 3.7.2. 사용자 인터페이스 상세
![interface](./interface.png)
### 3.7.4. 특징(Feature) ### 3.7.4. 특징(Feature)