diff --git a/README.md b/README.md
index 0c8387f..b74f0d6 100644
--- a/README.md
+++ b/README.md
@@ -194,6 +194,164 @@ def fizz_buzz():
と書く。
+### assert-codeblock upd-exact
+
+| 構文 | `assert-codeblock upd-exact 新ファイル名` |
+|--|--|
+| 役割 | ローカル実行時は、教材に引用されているコードで新ファイルを置き換える。
github-action 実行時は exact として動作する|
+
+たとえば、`sample_files/2-1.py` を
+
+```python
+def hello():
+ print("Hello, World!")
+
+hello()
+```
+
+としたいときは、
+
+````markdown
+
+
+```python
+def hello():
+ print("Hello, World!")
+
+hello()
+```
+````
+
+と書く。
+
+なお、upd-exact をローカル実行した場合は、置き換え処理だけが行われ検査は実行されない。
+対して、github-actionsで実行した場合は、exactとして起動するため完全一致を検査し、ファイルの置き換えは実行されない。
+
+### assert-codeblock upd-diff
+
+| 構文 | `assert-codeblock upd-diff 旧ファイル 新ファイル` |
+|--|--|
+| 役割 | ローカル実行時は、教材に引用されている diff 適用前のコードが旧ファイルと一致するかを検査する。問題なければ新ファイルに diff 適用後のファイルを書き出す。
github-action 実行時は diff として動作する |
+
+たとえば、`sample_files/2-1.py` に
+
+```python
+def hello():
+ print("Hello, World!")
+
+hello()
+```
+
+とあるとき、
+
+````markdown
+
+
+```diff-python
+ def hello():
+ print("Hello, World!")
+
+-hello()
++for x in range(6):
++ hello()
+```
+````
+
+と書く。
+
+検査が問題なければ、`sample_files/2-2.py` は以下の内容で更新される。
+
+```python
+def hello():
+ print("Hello, World!")
+
+for x in range(6):
+ hello()
+```
+
+なお、github-actions で実行した場合は、diff として起動するため、ファイルの置き換えは実行されない。
+
+### assert-codeblock upd-partial
+
+| 構文 | `assert-codeblock upd-partial 旧ファイル 新ファイル 行番号` |
+|--|--|
+| 役割 | 教材に引用されているコードを、旧ファイルの n 行目から適用して、新ファイルを書き出す。
github-action 実行時は、partial 新ファイル 行番号として起動する|
+
+たとえば、`sample_files/2-2.py` に
+
+```python
+def hello():
+ print("Hello, World!")
+
+for x in range(6):
+ hello()
+```
+
+と書いてあるとき、これの 7 行目から新たにコードを追加したい場合
+
+````markdown
+
+
+```python
+print("Hello")
+```
+````
+
+と書く。
+
+適用できれば、`sample_files/2-3.py` は以下の内容で更新される。
+
+```python
+def hello():
+ print("Hello, World!")
+
+for x in range(6):
+ hello()
+
+print("Hello")
+```
+
+なお、このコマンドは、通常のコードブロックを使って、コード追加する指示をしているときに使うことを想定している。
+コード解説のような、更新を指示しないものについては、partial や exact を利用する。
+
+他のコマンド同様に、github-actions で実行した場合は、partial として起動するため、ファイルの置き換えは実行されない。
+
+### assert-codeblock upd-diff-partial
+
+| 構文 | `assert-codeblock upd-diff-partial 旧ファイル名 新ファイル 行番号` |
+|--|--|
+| 役割 | ローカル実行時は、教材に n 行目から抜粋されている diff 適用前のコードが旧ファイルと一致するかを検査する。問題なければ新ファイルに diff 適用後のファイルを書き出す。
github-action 実行時は diff-partial として動作する |
+
+たとえば、`sample_files/2-3.py` に
+
+```python
+def hello():
+ print("Hello, World!")
+
+for x in range(6):
+ hello()
+
+print("Hello")
+```
+
+とあり、2行目から引用して、差分更新をしたい場合
+
+````markdown
+
+
+```diff-python
+ print("Hello, World!")
+
+-for x in range(6):
++for x in range(5):
+ hello()
+```
+
+````
+
+と書く。
+
+なお、github-actions で実行した場合は、diff-partial として起動するため、ファイルの置き換えは実行されない。
## テスト方法
diff --git a/assert-codeblock.js b/assert-codeblock.js
new file mode 100644
index 0000000..f5b6493
--- /dev/null
+++ b/assert-codeblock.js
@@ -0,0 +1,7 @@
+const AssertCodeblock = require('./dist/index');
+const config = {
+ src: "./sample_files/"
+};
+
+const textbook_filepath = `README.md`;
+AssertCodeblock.inspect_codeblock(textbook_filepath, config) // true
\ No newline at end of file
diff --git a/src/command.ts b/src/command.ts
index 02888da..18d27be 100644
--- a/src/command.ts
+++ b/src/command.ts
@@ -3,6 +3,7 @@ import path from 'node:path';
import { Config, FILTER, TestRes, WrongFileNameInCommandError, readFileSync, trimEndOnAllLines } from "./util";
import { structuredPatch } from 'diff';
import { PatchApplyError, apply_diff, apply_diff_on_lines } from "./apply_diff";
+import fs from "fs";
function handle_exact(textbook_filepath: string, command_args: string[], matched_file_content: string, src_folder: string, matched_label_line_num: number): TestRes {
const sample_file_name = command_args[1];
@@ -175,7 +176,7 @@ The line number "${command_args[2]}" is not a number`,
const sample_file_name = command_args[1];
- const sample_file_path = path.join(src_folder , sample_file_name);
+ const sample_file_path = path.join(src_folder, sample_file_name);
const sample_file_content = readFileSync(sample_file_path, command_args.join(" "), matched_label_line_num).replace(/\r?\n/g, "\n");
// 末尾の改行を削って行数を数える
@@ -277,8 +278,8 @@ ${mes}`,
}
}
- const old_sample_file_path = path.join(src_folder , old_sample_file_name);
- const new_sample_file_path = path.join(src_folder , new_sample_file_name);
+ const old_sample_file_path = path.join(src_folder, old_sample_file_name);
+ const new_sample_file_path = path.join(src_folder, new_sample_file_name);
const code_block_label = command_args.join(" ");
const oldStr = readFileSync(old_sample_file_path, code_block_label, matched_label_line_num);
const newStr = readFileSync(new_sample_file_path, code_block_label, matched_label_line_num);
@@ -381,8 +382,429 @@ with the code block labeled "${command_args.join(" ")}"`,
}
}
+function handle_upd_exact(textbook_filepath: string, command_args: string[], expected_new_content: string, src_folder: string, matched_line_num: number): TestRes {
+ const code_block_label = command_args.join(" ");
+ const new_sample_file_name = command_args[1];
+ const new_sample_file_path = path.join(src_folder, new_sample_file_name);
+ if (!fs.existsSync(new_sample_file_path)) {
+ fs.writeFileSync(new_sample_file_path, expected_new_content)
+ return {
+ is_success: true,
+ body: {
+ command_type: "UpdExact",
+ result_type: "CreatedFile",
+ message:
+ ` OK: "${textbook_filepath}:${matched_line_num}" のコードブロック "${code_block_label}" の内容で "${new_sample_file_path}" のファイルを作りました`,
+ textbook_filepath: textbook_filepath,
+ codeblock_line_num: matched_line_num,
+ codeblock_label: code_block_label,
+ }
+ };
+ }
+
+ const new_content = readFileSync(new_sample_file_path, code_block_label, matched_line_num).replace(/\r?\n/g, "\n");
+ if (expected_new_content !== new_content) {
+ fs.writeFileSync(new_sample_file_path, expected_new_content)
+ return {
+ is_success: true,
+ body: {
+ command_type: "UpdExact",
+ result_type: "UpdatedFile",
+ message:
+ ` OK: "${textbook_filepath}:${matched_line_num}" のコードブロック "${code_block_label}" と "${new_sample_file_path}" が不一致のため、ファイルを置き換えました`,
+ textbook_filepath: textbook_filepath,
+ codeblock_line_num: matched_line_num,
+ codeblock_label: code_block_label,
+ }
+ };
+ } else {
+ return {
+ is_success: true,
+ body: {
+ command_type: "UpdExact",
+ result_type: "Success",
+ message:
+ ` OK: "${textbook_filepath}:${matched_line_num}" のコードブロック "${code_block_label}" は "${new_sample_file_path}" と一致しています`,
+ textbook_filepath: textbook_filepath,
+ codeblock_line_num: matched_line_num,
+ codeblock_label: code_block_label,
+ }
+ };
+ }
+}
+
+function handle_upd_diff(textbook_filepath: string, command_args: string[], diff_content: string, src_folder: string, matched_line_num: number): TestRes {
+ const code_block_label = command_args.join(" ");
+ const old_sample_file_name = command_args[1];
+ const new_sample_file_name = command_args[2];
+ const old_sample_file_path = path.join(src_folder, old_sample_file_name);
+ const new_sample_file_path = path.join(src_folder, new_sample_file_name);
+ const old_content = readFileSync(old_sample_file_path, code_block_label, matched_line_num).replace(/\r?\n/g, "\n");
+ const old_diff_content = diff_content.split("\n").filter((line) => !(line[0] === "+")).map((line) => line.slice(1)).join("\n");
+
+ const actual_diff = (() => {
+ const diff = structuredPatch("textbook", old_sample_file_path, old_diff_content, old_content, "", "", { context: 1e6 });
+
+ const ret: string[] = [];
+ for (let i = 0; i < diff.hunks.length; i++) {
+ ret.push(...diff.hunks[i].lines);
+ }
+ return ret.join('\n');
+ })();
+
+ // パッチ適用前と旧ファイルに差がある場合は、エラーを吐く
+ if (actual_diff) {
+ return {
+ is_success: false,
+ body: {
+ command_type: "UpdDiff",
+ result_type: "Mismatch",
+ message: ` MISMATCH FOUND
+in ${textbook_filepath}:${matched_line_num}
+with the code block labeled "${code_block_label}"
+The diff of ${old_sample_file_path} with textbook is as follows: \n\`\`\`\n${actual_diff}\n\`\`\`
+`,
+ textbook_filepath: textbook_filepath,
+ codeblock_line_num: matched_line_num,
+ message_except_content: ` MISMATCH FOUND
+in ${textbook_filepath}:${matched_line_num}
+with the code block labeled "${code_block_label}"`,
+ codeblock_label: code_block_label,
+ textbook_content: diff_content,
+ sample_content: actual_diff,
+ }
+ };
+ }
+
+ try {
+ // パッチ適用後ファイルの作成
+ const expected_new_content = apply_diff(old_content, trimEndOnAllLines(diff_content))
+
+ // ファイルが無い場合は作成
+ if (!fs.existsSync(new_sample_file_path)) {
+ fs.writeFileSync(new_sample_file_path, expected_new_content)
+ return {
+ is_success: true,
+ body: {
+ command_type: "UpdDiff",
+ result_type: "CreatedFile",
+ message:
+ ` OK: "${textbook_filepath}:${matched_line_num}" のコードブロック "${code_block_label}" のパッチ適用前は旧ファイルと一致しています。新ファイルがないので、パッチ適用後の内容で新ファイルを作りました`,
+ textbook_filepath: textbook_filepath,
+ codeblock_line_num: matched_line_num,
+ codeblock_label: code_block_label,
+ }
+ };
+ }
+
+ // コンテンツに差がある場合は、置き換え
+ const new_content = readFileSync(new_sample_file_path, code_block_label, matched_line_num).replace(/\r?\n/g, "\n");
+ if (expected_new_content !== new_content) {
+ fs.writeFileSync(new_sample_file_path, expected_new_content)
+ return {
+ is_success: true,
+ body: {
+ command_type: "UpdDiff",
+ result_type: "UpdatedFile",
+ message:
+ ` OK: "${textbook_filepath}:${matched_line_num}" のコードブロック "${code_block_label}" のパッチ適用前は旧ファイルと一致しています。パッチ適用後の内容と新ファイルの内容が不一致のため、新ファイルを置き換えました`,
+ textbook_filepath: textbook_filepath,
+ codeblock_line_num: matched_line_num,
+ codeblock_label: code_block_label,
+ }
+ };
+ }
+
+ // コンテンツに差がない場合は、コメントのみ
+ return {
+ is_success: true,
+ body: {
+ command_type: "UpdDiff",
+ result_type: "Success",
+ message:
+ ` OK: "${textbook_filepath}" のコードブロック "${code_block_label}" のパッチ適用前は旧ファイルと、パッチ適用後は新ファイルと一致しています`,
+ textbook_filepath: textbook_filepath,
+ codeblock_line_num: matched_line_num,
+ codeblock_label: code_block_label,
+ }
+ };
+ } catch (e) {
+ if (e instanceof PatchApplyError) {
+ return {
+ is_success: false,
+ body: {
+ command_type: "UpdDiff",
+ result_type: "Mismatch",
+ message: ` CANNOT APPLY THE PATCH
+[original message: \`${e.message}\`]
+in ${textbook_filepath}:${matched_line_num}
+with the code block labeled "${code_block_label}"
+The content of ${old_sample_file_path} is as follows: \n\`\`\`\n${old_content}\`\`\`
+The patch in the textbook is as follows: \n\`\`\`\n${diff_content}\`\`\` `,
+ textbook_filepath: textbook_filepath,
+ codeblock_line_num: matched_line_num,
+ message_except_content: ` CANNOT APPLY THE PATCH
+[original message: \`${e.message}\`]
+in ${textbook_filepath}:${matched_line_num}
+with the code block labeled "${code_block_label}"`,
+ codeblock_label: code_block_label,
+ }
+ }
+ } else { throw e; }
+ }
+}
+
+function handle_upd_partial(textbook_filepath: string, command_args: string[], additional_content: string, src_folder: string, matched_line_num: number): TestRes {
+ const code_block_label = command_args.join(" ");
+ const old_sample_file_name = command_args[1];
+ const new_sample_file_name = command_args[2];
+
+ if (command_args[3] === undefined) {
+ return {
+ is_success: false,
+ body: {
+ command_type: "UpdPartial",
+ result_type: "LineNumMissing",
+ message: ` INSUFFICIENT ARGUMENT: LINE NUMBER MISSING
+in ${textbook_filepath}:${matched_line_num}
+with the code block labeled "${code_block_label}"
+Note that 'assert-codeblock upd-partial' requires two file names AND one's line number:
+for example, `,
+ textbook_filepath: textbook_filepath,
+ codeblock_line_num: matched_line_num,
+ codeblock_label: code_block_label,
+ }
+ }
+ }
+ const starting_line_num = Number(command_args[3]);
+
+ const old_sample_file_path = path.join(src_folder, old_sample_file_name);
+ const new_sample_file_path = path.join(src_folder, new_sample_file_name);
+
+ const old_content = readFileSync(old_sample_file_path, code_block_label.replace(/\r?\n/g, "\n"), matched_line_num);
+
+ // 末尾のブランクを削って行数を数える
+ const old_content_trimend = old_content.trimEnd();
+ const old_content_last_line_num = old_content_trimend.split("\n").length;
+
+ // 旧ファイルの行数とコードブロックの行番号が被っている場合、エラーを吐く
+ if (starting_line_num <= old_content_last_line_num) {
+ return {
+ is_success: false,
+ body: {
+ command_type: "UpdPartial",
+ result_type: "LineNumDuplication",
+ message: ` MISMATCH FOUND
+in ${textbook_filepath}:${matched_line_num}
+with the code block labeled "${code_block_label}"
+The content of ${old_sample_file_path} already has a line whose number is ${starting_line_num}`,
+ textbook_filepath: textbook_filepath,
+ codeblock_line_num: matched_line_num,
+ codeblock_label: code_block_label,
+ textbook_content: additional_content,
+ sample_content: old_content,
+ }
+ }
+ }
+
+ // 新ファイルの作成
+ const expected_new_content = old_content_trimend + "\n".repeat(starting_line_num - old_content_last_line_num) + additional_content;
+
+ if (!fs.existsSync(new_sample_file_path)) {
+ fs.writeFileSync(new_sample_file_path, expected_new_content)
+ return {
+ is_success: true,
+ body: {
+ command_type: "UpdPartial",
+ result_type: "CreatedFile",
+ message:
+ ` OK: "${textbook_filepath}:${matched_line_num}" のコードブロック "${code_block_label}" の内容で "${new_sample_file_path}" のファイルを作りました`,
+ textbook_filepath: textbook_filepath,
+ codeblock_line_num: matched_line_num,
+ codeblock_label: code_block_label,
+ }
+ };
+ }
+
+ // コンテンツに差がある場合は、置き換え
+ const newContent = readFileSync(new_sample_file_path, code_block_label, matched_line_num).replace(/\r?\n/g, "\n");
+ if (expected_new_content !== newContent) {
+ fs.writeFileSync(new_sample_file_path, expected_new_content)
+ return {
+ is_success: true,
+ body: {
+ command_type: "UpdPartial",
+ result_type: "UpdatedFile",
+ message:
+ ` OK: "${textbook_filepath}:${matched_line_num}" のコードブロック "${code_block_label}" は "${new_sample_file_path}" と一致しています`,
+ textbook_filepath: textbook_filepath,
+ codeblock_line_num: matched_line_num,
+ codeblock_label: code_block_label,
+ }
+ };
+ }
+
+ // コンテンツに差がない場合は、コメントのみ
+ return {
+ is_success: true,
+ body: {
+ command_type: "UpdPartial",
+ result_type: "Success",
+ message:
+ ` OK: "${textbook_filepath}:${matched_line_num}" のコードブロック "${code_block_label}" は "${new_sample_file_path}" と一致しています`,
+ textbook_filepath: textbook_filepath,
+ codeblock_line_num: matched_line_num,
+ codeblock_label: code_block_label,
+ }
+ };
+}
+
+function handle_upd_diff_partial(textbook_filepath: string, command_args: string[], diff_content: string, src_folder: string, matched_line_num: number): TestRes {
+ const code_block_label = command_args.join(" ");
+ const old_sample_file_name = command_args[1];
+ const new_sample_file_name = command_args[2];
+ if (command_args[3] === undefined) {
+ return {
+ is_success: false,
+ body: {
+ command_type: "UpdDiffPartial",
+ result_type: "LineNumMissing",
+ message: ` INSUFFICIENT ARGUMENT: LINE NUMBER MISSING
+in ${textbook_filepath}:${matched_line_num}
+with the code block labeled "${code_block_label}"
+Note that 'assert-codeblock upd-diff-partial' requires two file names AND one's line number at which the diff starts:
+for example, , in which the line numbers start at 13.`,
+ textbook_filepath: textbook_filepath,
+ codeblock_line_num: matched_line_num,
+ codeblock_label: code_block_label,
+ }
+ }
+ }
+ const starting_line_num = Number(command_args[3]) - 1;
+
+ const old_sample_file_path = path.join(src_folder, old_sample_file_name);
+ const new_sample_file_path = path.join(src_folder, new_sample_file_name);
+
+ const old_diff_str = diff_content.split("\n").filter((line) => !(line[0] === "+")).map((line, i) => (line.slice(1))).join("\n");
+ const old_diff_str_line_count = old_diff_str.split("\n").length - 1;
+ const old_content = readFileSync(old_sample_file_path, code_block_label, matched_line_num).replace(/\r?\n/g, "\n");
+ const old_str_front = old_content.split("\n").filter((line, i) => (i < starting_line_num)).map((line, i) => (line + "\n")).join("");
+ const old_str = old_content.split("\n").filter((line, i) => (i >= starting_line_num) && (i < starting_line_num + old_diff_str_line_count)).map((line, i) => (line + "\n")).join("");
+ const old_str_behind = old_content.split("\n").filter((line, i) => (i >= starting_line_num + old_diff_str_line_count)).join("\n");
+
+ const entire_diff = (() => {
+ const diff = structuredPatch("textbook", old_sample_file_path, old_diff_str, old_str, "", "", { context: 1e6 });
+
+ const ret: string[] = [];
+ for (let i = 0; i < diff.hunks.length; i++) {
+ ret.push(...diff.hunks[i].lines);
+ }
+ return ret.join('\n');
+ })();
+
+ // パッチ適用前と旧ファイルに差がある場合は、エラーを吐く
+ if (entire_diff) {
+ return {
+ is_success: false,
+ body: {
+ command_type: "UpdDiffPartial",
+ result_type: "Mismatch",
+ message: ` MISMATCH FOUND
+in ${textbook_filepath}:${matched_line_num}
+with the code block labeled "${code_block_label}"
+The diff of ${old_sample_file_path} with textbook is as follows: \n\`\`\`\n${entire_diff}\n\`\`\`
+`,
+ textbook_filepath: textbook_filepath,
+ codeblock_line_num: matched_line_num,
+ codeblock_label: code_block_label,
+ textbook_content: diff_content,
+ sample_content: entire_diff,
+ }
+ };
+ }
+
+ try {
+
+ // パッチ適用後ファイルの作成
+ const expected_new_content = old_str_front + apply_diff(old_str, trimEndOnAllLines(diff_content)) + old_str_behind;
+
+ // ファイルが無い場合は作成
+ if (!fs.existsSync(new_sample_file_path)) {
+ fs.writeFileSync(new_sample_file_path, expected_new_content)
+ return {
+ is_success: true,
+ body: {
+ command_type: "UpdDiffPartial",
+ result_type: "CreatedFile",
+ message:
+ ` OK: "${textbook_filepath}:${matched_line_num}" のコードブロック "${code_block_label}" のパッチ適用前の部分は旧ファイルの部分と一致しています。新ファイルがないので、パッチ適用後の内容で新ファイルを作りました`,
+ textbook_filepath: textbook_filepath,
+ codeblock_line_num: matched_line_num,
+ codeblock_label: code_block_label,
+ }
+ };
+ }
+
+ // コンテンツに差がある場合は、置き換え
+ const new_content = readFileSync(new_sample_file_path, code_block_label, matched_line_num).replace(/\r?\n/g, "\n");
+ if (expected_new_content !== new_content) {
+ fs.writeFileSync(new_sample_file_path, expected_new_content)
+ return {
+ is_success: true,
+ body: {
+ command_type: "UpdDiffPartial",
+ result_type: "UpdatedFile",
+ message:
+ ` OK: "${textbook_filepath}:${matched_line_num}" のコードブロック "${code_block_label}" のパッチ適用前の部分は旧ファイルの部分と一致しています。パッチ適用後の内容と新ファイルの内容が不一致のため、新ファイルを置き換えました`,
+ textbook_filepath: textbook_filepath,
+ codeblock_line_num: matched_line_num,
+ codeblock_label: code_block_label,
+ }
+ };
+ }
+
+ // コンテンツに差がない場合は、コメントのみ
+ return {
+ is_success: true,
+ body: {
+ command_type: "UpdDiffPartial",
+ result_type: "Success",
+ message:
+ ` OK: "${textbook_filepath}" のコードブロック "${code_block_label}" のパッチ適用前の部分は旧ファイルの部分と、パッチ適用後の内容は新ファイルの内容と一致しています`,
+ textbook_filepath: textbook_filepath,
+ codeblock_line_num: matched_line_num,
+ codeblock_label: code_block_label,
+ }
+ };
+ } catch (e) {
+ if (e instanceof PatchApplyError) {
+ return {
+ is_success: false,
+ body: {
+ command_type: "UpdDiffPartial",
+ result_type: "Mismatch",
+ message: ` CANNOT APPLY THE PATCH
+[original message: \`${e.message}\`]
+in ${textbook_filepath}:${matched_line_num}
+with the code block labeled "${code_block_label}"
+The partial content of ${old_sample_file_path} is as follows: \n\`\`\`\n${old_str}\`\`\`
+The partial patch in the textbook is as follows: \n\`\`\`\n${diff_content}\`\`\` `,
+ textbook_filepath: textbook_filepath,
+ codeblock_line_num: matched_line_num,
+ message_except_content: ` CANNOT APPLY THE PATCH
+[original message: \`${e.message}\`]
+in ${textbook_filepath}:${matched_line_num}
+with the code block labeled "${code_block_label}"`,
+ codeblock_label: code_block_label,
+ textbook_content: diff_content,
+ sample_content: old_str,
+ }
+ }
+ } else { throw e; }
+ }
+}
export function run_command_and_get_result(textbook_filepath: string, command: string, matched_file_content: string, config: Config, matched_line_num:number=-1): TestRes {
try {
@@ -395,6 +817,32 @@ export function run_command_and_get_result(textbook_filepath: string, command: s
return handle_partial(textbook_filepath, command_args, matched_file_content, config.src, matched_line_num);
} else if (command_args[0] === "diff-partial") {
return handle_diff_partial(textbook_filepath, command_args, matched_file_content, config.src, matched_line_num);
+ } else if (command_args[0] === "upd-exact") {
+ if (process.env.GITHUB_ACTIONS) {
+ return handle_exact(textbook_filepath, command_args, matched_file_content, config.src, matched_line_num);
+ } else {
+ return handle_upd_exact(textbook_filepath, command_args, matched_file_content, config.src, matched_line_num);
+ }
+ } else if (command_args[0] === "upd-diff") {
+ if (process.env.GITHUB_ACTIONS) {
+ return handle_diff(textbook_filepath, command_args, matched_file_content, config.src, matched_line_num);
+ } else {
+ return handle_upd_diff(textbook_filepath, command_args, matched_file_content, config.src, matched_line_num);
+ }
+ } else if (command_args[0] === "upd-partial") {
+
+ if (process.env.GITHUB_ACTIONS) {
+ command_args.splice(1, 1);
+ return handle_partial(textbook_filepath, command_args, matched_file_content, config.src, matched_line_num);
+ } else {
+ return handle_upd_partial(textbook_filepath, command_args, matched_file_content, config.src, matched_line_num);
+ }
+ } else if (command_args[0] === "upd-diff-partial") {
+ if (process.env.GITHUB_ACTIONS) {
+ return handle_diff_partial(textbook_filepath, command_args, matched_file_content, config.src, matched_line_num);
+ } else {
+ return handle_upd_diff_partial(textbook_filepath, command_args, matched_file_content, config.src, matched_line_num);
+ }
} else {
return {
is_success: false,
diff --git a/src/index.ts b/src/index.ts
index c8ffb3d..7ce0fc5 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -212,13 +212,17 @@ export async function rename_src_files(
}
}
- if (command_args[0] === "exact" || command_args[0] === "partial") {
+ if (["exact", "partial","upd-exact"].includes(command_args[0])) {
// `assert-codeblock exact ファイル名`
// `assert-codeblock partial ファイル名 行番号`
+ // `assert-codeblock upd-exact ファイル名`
command_args[1] = replace(command_args[1], replacements);
- } else if (command_args[0] === "diff" || command_args[0] === "diff-partial") {
+ } else if (["diff", "diff-partial", "upd-diff","upd-diff-partial","upd-partial"].includes(command_args[0])) {
// `assert-codeblock diff 旧ファイル 新ファイル`
- // `assert-codeblock diff-partial 旧ファイル名 新ファイル 行番号` または `assert-codeblock diff-partial 旧ファイル名 新ファイル 新ファイルの行番号 旧ファイルの行番号`
+ // `assert-codeblock diff-partial 旧ファイル名 新ファイル 行番号` または `assert-codeblock diff-partial 旧ファイル名 新ファイル 新ファイルの行番号 旧ファイルの行番号`
+ // `assert-codeblock upd-diff 旧ファイル 新ファイル`
+ // `assert-codeblock upd-diff-partial 旧ファイル名 新ファイル 行番号`
+ // `assert-codeblock upd-partial 旧ファイル名 新ファイル 行番号`
command_args[1] = replace(command_args[1], replacements);
command_args[2] = replace(command_args[2], replacements);
} else {
diff --git a/src/util.ts b/src/util.ts
index 263caf2..456e524 100644
--- a/src/util.ts
+++ b/src/util.ts
@@ -14,8 +14,30 @@ Cannot find a file "${file_name}" mentioned in the code block labeled "${code_bl
return fs.readFileSync(file_name, { encoding: "utf-8" });
}
-export type CommandType = "Exact" | "Diff" | "Partial" | "DiffPartial" | "Undefined";
-export type ResultType = "Success" | "Mismatch" | "TextbookNotFound" | "WrongFileNameInCommand" | "LineNumMismatch" | "LineNumMissing" | "LineNumNotNumber" | "UnknownCommand" | "UnknownError";
+export type CommandType =
+ | "Exact"
+ | "Diff"
+ | "Partial"
+ | "DiffPartial"
+ | "UpdExact"
+ | "UpdDiff"
+ | "UpdPartial"
+ | "UpdDiffPartial"
+ | "Undefined";
+
+export type ResultType =
+ | "Success"
+ | "CreatedFile"
+ | "UpdatedFile"
+ | "Mismatch"
+ | "TextbookNotFound"
+ | "WrongFileNameInCommand"
+ | "LineNumMismatch"
+ | "LineNumDuplication"
+ | "LineNumMissing"
+ | "LineNumNotNumber"
+ | "UnknownCommand"
+ | "UnknownError";
export type ResBody = {
command_type: CommandType,