From 4bc6cd55da47a3bfdc63959f7cf5cb36902dacd8 Mon Sep 17 00:00:00 2001 From: DogFortune Date: Mon, 24 Nov 2025 19:42:43 +0900 Subject: [PATCH 01/19] =?UTF-8?q?tqdm=E3=81=8B=E3=82=89print=E3=81=AB?= =?UTF-8?q?=E7=A7=BB=E8=A1=8C=E4=B8=AD=20refs=20#4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/linkstat/analyzer.py | 30 ++++++++++++++---------------- tests/conftest.py | 4 ++-- tests/test_analyzer.py | 1 + tests/test_app.py | 3 +++ 4 files changed, 20 insertions(+), 18 deletions(-) diff --git a/src/linkstat/analyzer.py b/src/linkstat/analyzer.py index 5c9667a..a6cd438 100644 --- a/src/linkstat/analyzer.py +++ b/src/linkstat/analyzer.py @@ -5,7 +5,6 @@ from linkstat.reporter import ReportData from dataclasses import dataclass import re -from tqdm import tqdm URL_PATTERN = r'https?://[^\s\)\]>"]+' URL_RE = re.compile(URL_PATTERN) @@ -58,21 +57,20 @@ def check_links(links: dict[str, URLInfo]) -> list[ReportData]: :rtype: list[ReportData] """ results = [] - with tqdm(links.items()) as links_prog: - for file_path, link_items in links_prog: - links_prog.set_description(file_path) - for item in tqdm(link_items): - if not item.duplicate: - res = request(item.url) - data = ReportData( - file_path, - item.line, - item.url, - res.result, - res.code, - res.reason, - ) - results.append(data) + for file_path, link_items in links.items(): + for item in link_items: + if not item.duplicate: + res = request(item.url) + data = ReportData( + file_path, + item.line, + item.url, + res.result, + res.code, + res.reason, + ) + print(f"{data.url}: {data.result}") + results.append(data) return results diff --git a/tests/conftest.py b/tests/conftest.py index 71ff3d8..d67afa6 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -3,8 +3,8 @@ from urllib.error import HTTPError, URLError -@pytest.fixture(scope="session", autouse=True) -def check_mock_server(): +@pytest.fixture() +def use_mock_server(): """テスト実行前にモックサーバーの起動を確認""" mock_server_url = "http://localhost:8000/get" diff --git a/tests/test_analyzer.py b/tests/test_analyzer.py index bf6bc42..4f93ff2 100644 --- a/tests/test_analyzer.py +++ b/tests/test_analyzer.py @@ -13,6 +13,7 @@ pytest.param("http://127.0.0.1:800", "NG", None), ], ) +@pytest.mark.usefixtures("use_mock_server") def test_request(url: str, expected_result: str, expected_status_code: int): # アクセスチェックした時に想定しているリクエストが返ってくる事。 # 200系だけTrueで、それ以外はFalseで返ってくる事。 diff --git a/tests/test_app.py b/tests/test_app.py index 4ea939d..14f4a93 100644 --- a/tests/test_app.py +++ b/tests/test_app.py @@ -8,10 +8,12 @@ class TestValid: """正常系""" + @pytest.mark.usefixtures("use_mock_server") def test_main_with_minimal_arguments(self): """環境変数も引数も指定しない一気通貫のテスト""" app.main(["tests/sample_doc/"]) + @pytest.mark.usefixtures("use_mock_server") def test_main_with_output_json(self): """JSONファイルが出力されている事""" with TemporaryDirectory() as dir: @@ -30,6 +32,7 @@ def test_main_report_path_directory(self): ): app.main(["tests/sample_doc/", "--report-json", str(dir)]) + @pytest.mark.usefixtures("use_mock_server") def test_main_single_file(self): """単体のファイルを指定した場合も正しく動作する事""" app.main(["tests/sample_doc/doc1.md"]) From c478b3002b97d5e4986fe803561014d71fe19039 Mon Sep 17 00:00:00 2001 From: DogFortune Date: Mon, 24 Nov 2025 19:44:34 +0900 Subject: [PATCH 02/19] remove tqdm refs #4 --- Pipfile | 1 - Pipfile.lock | 59 +++++++++++++++++++--------------------------------- 2 files changed, 21 insertions(+), 39 deletions(-) diff --git a/Pipfile b/Pipfile index 8d3369a..5841a7f 100644 --- a/Pipfile +++ b/Pipfile @@ -4,7 +4,6 @@ verify_ssl = true name = "pypi" [packages] -tqdm = "*" dataclasses-json = "*" [dev-packages] diff --git a/Pipfile.lock b/Pipfile.lock index dab7dd2..848f2a1 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "abfbd1f0c8a48d405bf75c514ae132d96e9bde10fb1658471b8b1ea4f8100f2f" + "sha256": "9e66e1ea2350343ebaec3b0d2f37b9e39c682de843ac2ca9aab8113356b6a299" }, "pipfile-spec": 6, "requires": { @@ -16,14 +16,6 @@ ] }, "default": { - "colorama": { - "hashes": [ - "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", - "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5, 3.6'", - "version": "==0.4.6" - }, "dataclasses-json": { "hashes": [ "sha256:0dbf33f26c8d5305befd61b39d2b3414e8a407bedc2834dea9b8d642666fb40a", @@ -57,15 +49,6 @@ "markers": "python_version >= '3.8'", "version": "==25.0" }, - "tqdm": { - "hashes": [ - "sha256:26445eca388f82e72884e0d580d5464cd801a3ea01e63e5601bdff9ba6a48de2", - "sha256:f8aef9c52c08c13a65f30ea34f4e5aac3fd1a34959879d7e59e63027286627f2" - ], - "index": "pypi", - "markers": "python_version >= '3.7'", - "version": "==4.67.1" - }, "typing-extensions": { "hashes": [ "sha256:0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466", @@ -486,28 +469,28 @@ }, "uv": { "hashes": [ - "sha256:110fd2062dccc4825f96cef0007f6bbb6f5da117af50415bed6f6dcd5e1e3603", - "sha256:21981bc859802c94d4b8f026b8734d39e8146baac703f1e3eab2e2d87d65ca8c", - "sha256:3c133e34feca0823d952a1d323d1d47f2b35e13154de5ca293d188f5b8792a62", - "sha256:3c2ddc0bca2e4b7e31623a17d60ea5f8d1ee4ff3ee27ddbf884e089e57cd0c93", - "sha256:4e256d3cc542f73435b27a3d0bf2a6b0f9d2dd6dd5c8df1a8028834deb896819", - "sha256:516d1c5549912696ba68376d2652661ed327199a9ec15763f7baa29bc75b35ec", - "sha256:55ecddf19314f7da5b8dea6bcfcc86f5769dd7d22106c731e8e6cfbf3fa6b98d", - "sha256:5e7a86eb5edbb9064b1401522eb10c5bd25ff56c04cd0ed253d0cd088a448bef", - "sha256:763cf33c7c5ab490323fab667b24f66412c3c3ca58e86b56e13fc0109d031a1b", - "sha256:780a7af4a7dfb0894a8d367b5c3a48f926480f465a34aa4a8633d6e4f521e517", - "sha256:84128ca76a665fe0584bff6ef913741d5615a4187c1aaed81739d519e669cfbd", - "sha256:8c8969d54c9f603107445a23f36fba03a0dfa4c75b3ada2faf94ed371f26f3a4", - "sha256:92d4b58ef810eaf5edf95c607d613ff240ab903ee599af1d687f891ab64b4129", - "sha256:9ee9027eb98cf5a99d9a3d5ddab7048745e2e49d572869044f66772e17f57792", - "sha256:a02b27e00afe0d7908fbb9ec61ad5338508e02356138a8a718af239fe773dd2e", - "sha256:b0a0c4594871de9e8b12c9e10982dc83e2414b712a34e84860fac9fbc8510c5a", - "sha256:c9a326f04b670f1af2d9fa90e50af57a9a872a8dc90bb377d0c27b2030438ffc", - "sha256:d4903e73f5e281ce5c3def60014bef93d2d1a148901653e222470ce54987f4a1", - "sha256:dfcc3cd5765158e82a0f52066462e378887aac01b347b588907fe3290af92356" + "sha256:1f8afc13b3b94bce1e72514c598d41623387b2b61b68d7dbce9a01a0d8874860", + "sha256:48548a23fb5a103b8955dfafff7d79d21112b8e25ce5ff25e3468dc541b20e83", + "sha256:4907a696c745703542ed2559bdf5380b92c8b1d4bf290ebfed45bf9a2a2c6690", + "sha256:605a7a57f508aabd029fc0c5ef5c60a556f8c50d32e194f1a300a9f4e87f18d4", + "sha256:6a31b0bd4eaec59bf97816aefbcd75cae4fcc8875c4b19ef1846b7bff3d67c70", + "sha256:70137a46675bbecf3a8b43d292a61767f1b944156af3d0f8d5986292bd86f6cf", + "sha256:7d414cfa410f1850a244d87255f98d06ca61cc13d82f6413c4f03e9e0c9effc7", + "sha256:803f85cf25ab7f1fca10fe2e40a1b9f5b1d48efc25efd6651ba3c9668db6a19e", + "sha256:8abfb7d4b136de3e92dd239ea9a51d4b7bbb970dc1b33bec84d08facf82b9a6e", + "sha256:8cc86940d9b3a425575f25dc45247be2fb31f7fed7bf3394ae9daadd466e5b80", + "sha256:92ff773aa4193148019533c55382c2f9c661824bbf0c2e03f12aeefc800ede57", + "sha256:9ef1982295e5aaf909a9668d6fb6abfc5089666c699f585a36f3a67f1a22916a", + "sha256:af5fd91eecaa04b4799f553c726307200f45da844d5c7c5880d64db4debdd5dc", + "sha256:b5af9117bab6c4b3a1cacb0cddfb3cd540d0adfb13c7b8a9a318873cf2d07e52", + "sha256:c65a024ad98547e32168f3a52360fe73ff39cd609a8fb9dd2509aac91483cfc8", + "sha256:cb680948e678590b5960744af2ecea6f2c0307dbb74ac44daf5c00e84ad8c09f", + "sha256:d901269e1db72abc974ba61d37be6e56532e104922329e0b553d9df07ba224be", + "sha256:e97906ca1b90dac91c23af20e282e2e37c8eb80c3721898733928a295f2defda", + "sha256:edc14143d0ba086a7da4b737a77746bb36bc00e3d26466f180ea99e3bf795171" ], "markers": "python_version >= '3.8'", - "version": "==0.9.10" + "version": "==0.9.11" }, "virtualenv": { "hashes": [ From 9ca0d4837d61794b9d25aa8c9f58f4a2688a9d5e Mon Sep 17 00:00:00 2001 From: DogFortune Date: Mon, 24 Nov 2025 19:44:58 +0900 Subject: [PATCH 03/19] =?UTF-8?q?=E5=87=BA=E5=8A=9B=E3=83=86=E3=82=B9?= =?UTF-8?q?=E3=83=88=E7=94=A8=E3=81=AB=E8=BF=BD=E5=8A=A0=20refs=20#4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tests/test_app.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/test_app.py b/tests/test_app.py index 14f4a93..fdfd547 100644 --- a/tests/test_app.py +++ b/tests/test_app.py @@ -13,6 +13,9 @@ def test_main_with_minimal_arguments(self): """環境変数も引数も指定しない一気通貫のテスト""" app.main(["tests/sample_doc/"]) + # def test_awesome(self): + # app.main(["tmp/awesome-main"]) + @pytest.mark.usefixtures("use_mock_server") def test_main_with_output_json(self): """JSONファイルが出力されている事""" From 81692811c7aff6d350325bb6d4abd634d6a42132 Mon Sep 17 00:00:00 2001 From: DogFortune Date: Wed, 26 Nov 2025 11:43:03 +0900 Subject: [PATCH 04/19] =?UTF-8?q?=E3=82=B5=E3=83=9E=E3=83=AA=E3=83=BC?= =?UTF-8?q?=E5=87=BA=E5=8A=9B=E4=BD=9C=E6=88=90=E4=B8=AD=20refs=20#4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/linkstat/analyzer.py | 4 ++-- src/linkstat/app.py | 2 +- src/linkstat/reporter.py | 19 +++++++++++++++---- tests/test_analyzer.py | 14 +++++++++++--- tests/test_reporter.py | 2 +- 5 files changed, 30 insertions(+), 11 deletions(-) diff --git a/src/linkstat/analyzer.py b/src/linkstat/analyzer.py index a6cd438..9a6fe65 100644 --- a/src/linkstat/analyzer.py +++ b/src/linkstat/analyzer.py @@ -49,11 +49,11 @@ def request(url: str) -> AnalyzeResponse: def check_links(links: dict[str, URLInfo]) -> list[ReportData]: - """URLの疎通確認を行います。確認を行うのは重複していないものだけです。 + """URLの疎通確認を行います。確認を行うのは重複していないものだけ。 :param links: URLリスト :type links: dict[str, URLInfo] - :return: 確認結果 + :return: 確認結果(重複したURLは除く) :rtype: list[ReportData] """ results = [] diff --git a/src/linkstat/app.py b/src/linkstat/app.py index f42781d..9bbefdd 100644 --- a/src/linkstat/app.py +++ b/src/linkstat/app.py @@ -19,7 +19,7 @@ def __output(data: list[ReportData], format: OutputType, args): """ match format: case OutputType.Console: - line = reporter.console(data) + line = reporter.summary(data) print(line) case OutputType.Json: output_path = args.report_json diff --git a/src/linkstat/reporter.py b/src/linkstat/reporter.py index 03dea75..2449bf3 100644 --- a/src/linkstat/reporter.py +++ b/src/linkstat/reporter.py @@ -1,5 +1,6 @@ from dataclasses import dataclass from dataclasses_json import dataclass_json +from linkstat.enums import Result from pprint import pformat from typing import List import json @@ -12,7 +13,7 @@ class ReportData: file: str line: int url: str - result: str + result: Result code: int reason: str @@ -31,9 +32,19 @@ def default(self, obj): return super().default(obj) -def console(data: list[ReportData]): - # TODO: 出力形式は仮でpformatを設定中。 - line = pformat(data) +def summary(data: list[ReportData]): + """サマリーを出力します。 + チェックしたURLの数、OK,NGの数、NGのものはURLを出す。 + + :param data: _description_ + :type data: list[ReportData] + :return: _description_ + :rtype: _type_ + """ + total_count = len(data) + ok_count = len([item for item in data if item.result == Result.OK]) + ng_count = len([item for item in data if item.result == Result.NG]) + line = f"Total: {total_count} OK: {ok_count} NG: {ng_count}" return line diff --git a/tests/test_analyzer.py b/tests/test_analyzer.py index 4f93ff2..3faad4d 100644 --- a/tests/test_analyzer.py +++ b/tests/test_analyzer.py @@ -15,15 +15,23 @@ ) @pytest.mark.usefixtures("use_mock_server") def test_request(url: str, expected_result: str, expected_status_code: int): - # アクセスチェックした時に想定しているリクエストが返ってくる事。 - # 200系だけTrueで、それ以外はFalseで返ってくる事。 - # URLErrorが発生した(レスポンスが無く、そもそも接続できなかった)場合はFalseでステータスコードがNoneとなる事。 + """URLチェックのレスポンスの形式と挙動テスト。 + 想定している形式で返ってきている事と、URLErrorが発生する場合はステータスコードがNoneになっている事。 + + :param url: _description_ + :type url: str + :param expected_result: _description_ + :type expected_result: str + :param expected_status_code: _description_ + :type expected_status_code: int + """ res = analyzer.request(url) assert type(res) is analyzer.AnalyzeResponse assert res.result == expected_result assert res.code == expected_status_code assert res.url == url + # NGの場合は理由が必ず入っている事 if res.result.upper() == "NG": assert res.reason is not None diff --git a/tests/test_reporter.py b/tests/test_reporter.py index 968b849..6f2cd0d 100644 --- a/tests/test_reporter.py +++ b/tests/test_reporter.py @@ -24,7 +24,7 @@ class TestValid: def test_console(self, setup_report_data): """コンソール出力テスト。文字列が想定している形である事""" - output_line = reporter.console(setup_report_data) + output_line = reporter.summary(setup_report_data) assert output_line is not None From 71a21b0d1e195514e112cc34ae1025a4743e6e94 Mon Sep 17 00:00:00 2001 From: DogFortune Date: Wed, 26 Nov 2025 14:12:37 +0900 Subject: [PATCH 05/19] =?UTF-8?q?pytest=E3=81=A3=E3=81=BD=E3=81=84?= =?UTF-8?q?=E3=82=B5=E3=83=9E=E3=83=AA=E3=83=BC=E3=81=8C=E5=87=BA=E3=81=9B?= =?UTF-8?q?=E3=82=8B=E3=82=88=E3=81=86=E3=81=AB=20refs=20#4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/linkstat/reporter.py | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/src/linkstat/reporter.py b/src/linkstat/reporter.py index 2449bf3..ee88493 100644 --- a/src/linkstat/reporter.py +++ b/src/linkstat/reporter.py @@ -1,10 +1,10 @@ from dataclasses import dataclass from dataclasses_json import dataclass_json from linkstat.enums import Result -from pprint import pformat from typing import List import json import os +import shutil @dataclass_json @@ -42,9 +42,19 @@ def summary(data: list[ReportData]): :rtype: _type_ """ total_count = len(data) - ok_count = len([item for item in data if item.result == Result.OK]) - ng_count = len([item for item in data if item.result == Result.NG]) - line = f"Total: {total_count} OK: {ok_count} NG: {ng_count}" + ok_count = sum(item.result == Result.OK for item in data) + ng_items = [item for item in data if item.result == Result.NG] + summary = f" {total_count} Total, {ok_count} OK, {len(ng_items)} NG " + + terminal_width = shutil.get_terminal_size().columns + if terminal_width < 40: + terminal_width = 80 + + total_fill = terminal_width - len(summary) + left_fill = total_fill // 2 + right_fill = total_fill - left_fill + + line = f"{"="*left_fill}{summary}{"="*right_fill}" return line From dc0f31f0444d146c2cb2e94404e51668dbc1dec5 Mon Sep 17 00:00:00 2001 From: DogFortune Date: Wed, 26 Nov 2025 16:03:18 +0900 Subject: [PATCH 06/19] =?UTF-8?q?=E8=89=B2=E4=BB=98=E3=81=91=E5=AF=BE?= =?UTF-8?q?=E5=BF=9C=20refs=20#4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/linkstat/reporter.py | 33 +++++++++++++++++++++++++++------ 1 file changed, 27 insertions(+), 6 deletions(-) diff --git a/src/linkstat/reporter.py b/src/linkstat/reporter.py index ee88493..231b6fc 100644 --- a/src/linkstat/reporter.py +++ b/src/linkstat/reporter.py @@ -32,8 +32,19 @@ def default(self, obj): return super().default(obj) +class Colors: + """カラーコード""" + + RED = "\033[91m" + GREEN = "\033[92m" + YELLOW = "\033[93m" + BLUE = "\033[94m" + RESET = "\033[0m" + BOLD = "\033[1m" + + def summary(data: list[ReportData]): - """サマリーを出力します。 + """サマリーを作成します。 チェックしたURLの数、OK,NGの数、NGのものはURLを出す。 :param data: _description_ @@ -41,21 +52,31 @@ def summary(data: list[ReportData]): :return: _description_ :rtype: _type_ """ + fill_char = f"{Colors.GREEN}={Colors.RESET}" + total_count = len(data) ok_count = sum(item.result == Result.OK for item in data) ng_items = [item for item in data if item.result == Result.NG] - summary = f" {total_count} Total, {ok_count} OK, {len(ng_items)} NG " - terminal_width = shutil.get_terminal_size().columns + total_part = f"{Colors.GREEN}{total_count} Total{Colors.RESET}" + ok_part = f"{Colors.GREEN}{ok_count} OK{Colors.RESET}" + + # TODO: NGが無ければ作る必要が無いので工夫する。メッセージも同様。 + ng_part = f"{Colors.RED}{len(ng_items)} NG{Colors.RESET}" + + color_message = f" {total_part}, {ok_part}, {ng_part} " + plain_message = f" {total_count} Total, {ok_count} OK, {len(ng_items)} NG " + + terminal_width = shutil.get_terminal_size(fallback=(80, 24)).columns if terminal_width < 40: terminal_width = 80 - total_fill = terminal_width - len(summary) + total_fill = terminal_width - len(plain_message) left_fill = total_fill // 2 right_fill = total_fill - left_fill - line = f"{"="*left_fill}{summary}{"="*right_fill}" - return line + summary_message = f"{fill_char*left_fill}{color_message}{fill_char*right_fill}" + return summary_message def dump_json(data: list[ReportData], output_path: str): From 5d187ede83b6eda5a9fcdcacdfff65fc1660dc6d Mon Sep 17 00:00:00 2001 From: DogFortune Date: Thu, 27 Nov 2025 11:20:25 +0900 Subject: [PATCH 07/19] =?UTF-8?q?1=E3=81=A4=E3=81=A7=E3=82=82NG=E3=81=8C?= =?UTF-8?q?=E3=81=82=E3=81=A3=E3=81=9F=E3=82=89=E8=B5=A4=E8=89=B2=E3=81=AB?= =?UTF-8?q?=20refs=20#4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 他の文字が赤になっていないので要調整 リセットを含めないようにすれば効率いいのでは? --- src/linkstat/reporter.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/linkstat/reporter.py b/src/linkstat/reporter.py index 231b6fc..228d917 100644 --- a/src/linkstat/reporter.py +++ b/src/linkstat/reporter.py @@ -52,8 +52,6 @@ def summary(data: list[ReportData]): :return: _description_ :rtype: _type_ """ - fill_char = f"{Colors.GREEN}={Colors.RESET}" - total_count = len(data) ok_count = sum(item.result == Result.OK for item in data) ng_items = [item for item in data if item.result == Result.NG] @@ -75,6 +73,11 @@ def summary(data: list[ReportData]): left_fill = total_fill // 2 right_fill = total_fill - left_fill + if len(ng_items) > 0: + fill_char = f"{Colors.RED}={Colors.RESET}" + else: + fill_char = f"{Colors.GREEN}={Colors.RESET}" + summary_message = f"{fill_char*left_fill}{color_message}{fill_char*right_fill}" return summary_message From 4063bdeed464fb8d6410bbc5ed79451cdb842007 Mon Sep 17 00:00:00 2001 From: DogFortune Date: Thu, 27 Nov 2025 11:51:40 +0900 Subject: [PATCH 08/19] =?UTF-8?q?=E5=87=BA=E5=8A=9B=E7=B5=90=E6=9E=9C?= =?UTF-8?q?=E3=81=AE=E8=89=B2=E3=83=81=E3=82=A7=E3=83=83=E3=82=AF=E5=AE=9F?= =?UTF-8?q?=E8=A3=85=E4=B8=AD=20refs=20#4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tests/test_reporter.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tests/test_reporter.py b/tests/test_reporter.py index 6f2cd0d..7f31fdb 100644 --- a/tests/test_reporter.py +++ b/tests/test_reporter.py @@ -22,11 +22,13 @@ def setup_report_data(): class TestValid: """正常系""" - def test_console(self, setup_report_data): - """コンソール出力テスト。文字列が想定している形である事""" + def test_summary(self, setup_report_data): + """サマリー出力テスト。文字列が想定している形である事""" output_line = reporter.summary(setup_report_data) assert output_line is not None + assert reporter.Colors.RED in output_line + assert reporter.Colors.GREEN not in output_line def test_json(self, setup_report_data): with TemporaryDirectory() as dir: From f6b1184ab1bd1a9d732d9e052a88d0144c09c17f Mon Sep 17 00:00:00 2001 From: DogFortune Date: Thu, 27 Nov 2025 17:29:11 +0900 Subject: [PATCH 09/19] =?UTF-8?q?NG=E3=81=AF=E3=81=82=E3=82=8B=E6=99=82?= =?UTF-8?q?=E3=81=A0=E3=81=91=E8=A1=A8=E7=A4=BA=E3=81=99=E3=82=8B=E3=82=88?= =?UTF-8?q?=E3=81=86=E3=81=AB=20refs=20#4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/linkstat/reporter.py | 22 ++++++++++------------ tests/test_reporter.py | 20 +++++++++++++++++--- 2 files changed, 27 insertions(+), 15 deletions(-) diff --git a/src/linkstat/reporter.py b/src/linkstat/reporter.py index 228d917..ed1d114 100644 --- a/src/linkstat/reporter.py +++ b/src/linkstat/reporter.py @@ -15,7 +15,7 @@ class ReportData: url: str result: Result code: int - reason: str + reason: str | None @dataclass_json @@ -38,9 +38,7 @@ class Colors: RED = "\033[91m" GREEN = "\033[92m" YELLOW = "\033[93m" - BLUE = "\033[94m" RESET = "\033[0m" - BOLD = "\033[1m" def summary(data: list[ReportData]): @@ -59,11 +57,16 @@ def summary(data: list[ReportData]): total_part = f"{Colors.GREEN}{total_count} Total{Colors.RESET}" ok_part = f"{Colors.GREEN}{ok_count} OK{Colors.RESET}" - # TODO: NGが無ければ作る必要が無いので工夫する。メッセージも同様。 - ng_part = f"{Colors.RED}{len(ng_items)} NG{Colors.RESET}" + color_message = f" {total_part}, {ok_part}" + plain_message = f" {total_count} Total, {ok_count} OK" - color_message = f" {total_part}, {ok_part}, {ng_part} " - plain_message = f" {total_count} Total, {ok_count} OK, {len(ng_items)} NG " + if (ng_count := len(ng_items)) == 0: + fill_char = f"{Colors.GREEN}={Colors.RESET}" + else: + ng_part = f"{Colors.RED}{ng_count} NG{Colors.RESET}" + fill_char = f"{Colors.RED}={Colors.RESET}" + color_message += f", {ng_part} " + plain_message += f", {ng_count} NG " terminal_width = shutil.get_terminal_size(fallback=(80, 24)).columns if terminal_width < 40: @@ -73,11 +76,6 @@ def summary(data: list[ReportData]): left_fill = total_fill // 2 right_fill = total_fill - left_fill - if len(ng_items) > 0: - fill_char = f"{Colors.RED}={Colors.RESET}" - else: - fill_char = f"{Colors.GREEN}={Colors.RESET}" - summary_message = f"{fill_char*left_fill}{color_message}{fill_char*right_fill}" return summary_message diff --git a/tests/test_reporter.py b/tests/test_reporter.py index 7f31fdb..472da35 100644 --- a/tests/test_reporter.py +++ b/tests/test_reporter.py @@ -1,6 +1,5 @@ import pytest -from linkstat import reporter -from linkstat import analyzer +from linkstat import reporter, analyzer, enums from tempfile import TemporaryDirectory from pathlib import Path import os @@ -28,7 +27,22 @@ def test_summary(self, setup_report_data): assert output_line is not None assert reporter.Colors.RED in output_line - assert reporter.Colors.GREEN not in output_line + + def test_summary_all_ok(self): + """OKのものだけだった時はNGが入っておらず文字もグリーンのみである事""" + results_report_data = [] + results_report_data.append( + reporter.ReportData( + "path/to/doc1.md", 2, "https://example.com", enums.Result.OK, 200, None + ) + ) + summary_message = reporter.summary(results_report_data) + + assert summary_message is not None + assert "NG" not in summary_message + assert reporter.Colors.GREEN in summary_message + assert reporter.Colors.RED not in summary_message + assert reporter.Colors.YELLOW not in summary_message def test_json(self, setup_report_data): with TemporaryDirectory() as dir: From 9a202f48a2f46394c7cb9932dc66dee8048e32ce Mon Sep 17 00:00:00 2001 From: DogFortune Date: Thu, 11 Dec 2025 13:11:53 +0900 Subject: [PATCH 10/19] =?UTF-8?q?NG=E3=81=A0=E3=81=A3=E3=81=9FURL=E3=81=A8?= =?UTF-8?q?=E7=B5=90=E6=9E=9C=E3=82=92=E3=83=AA=E3=82=B9=E3=83=88=E3=81=AB?= =?UTF-8?q?=E3=81=97=E3=81=A6=E6=A0=BC=E7=B4=8D=20refs=20#4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/linkstat/reporter.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/linkstat/reporter.py b/src/linkstat/reporter.py index ed1d114..4cbe000 100644 --- a/src/linkstat/reporter.py +++ b/src/linkstat/reporter.py @@ -63,6 +63,7 @@ def summary(data: list[ReportData]): if (ng_count := len(ng_items)) == 0: fill_char = f"{Colors.GREEN}={Colors.RESET}" else: + ng_detail = "\n".join([f"{item.url}: {item.result}" for item in ng_items]) ng_part = f"{Colors.RED}{ng_count} NG{Colors.RESET}" fill_char = f"{Colors.RED}={Colors.RESET}" color_message += f", {ng_part} " From 2e6f161d2e8d98c658e3c0ebd98e51951a1f4bf8 Mon Sep 17 00:00:00 2001 From: DogFortune Date: Mon, 22 Dec 2025 10:16:42 +0900 Subject: [PATCH 11/19] =?UTF-8?q?=E3=83=81=E3=82=A7=E3=83=83=E3=82=AF?= =?UTF-8?q?=E9=96=8B=E5=A7=8B=E3=81=AE=E5=8D=B0=E3=82=92=E8=BF=BD=E5=8A=A0?= =?UTF-8?q?=20refs=20#4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit チェックがいつ始まったのかが分かりづらかった 最後のNGサマリーが見づらいので色を変える --- src/linkstat/app.py | 2 ++ src/linkstat/reporter.py | 21 +++++++++++++++++++-- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/src/linkstat/app.py b/src/linkstat/app.py index 9bbefdd..33f4af5 100644 --- a/src/linkstat/app.py +++ b/src/linkstat/app.py @@ -60,6 +60,8 @@ def main(args=None): format = __format_setting(parsed_args) src = parsed_args.src + start_msg = reporter.session_start() + print(start_msg) files = analyzer.search(src) links = analyzer.extract_url(files) report_data_list = analyzer.check_links(links) diff --git a/src/linkstat/reporter.py b/src/linkstat/reporter.py index 4cbe000..d808d8e 100644 --- a/src/linkstat/reporter.py +++ b/src/linkstat/reporter.py @@ -41,6 +41,21 @@ class Colors: RESET = "\033[0m" +def session_start(): + fill_char = "=" + message = " linkstat start " + terminal_width = shutil.get_terminal_size(fallback=(80, 24)).columns + if terminal_width < 40: + terminal_width = 80 + + total_fill = terminal_width - len(message) + left_fill = total_fill // 2 + right_fill = total_fill - left_fill + + start_message = f"{fill_char*left_fill}{message}{fill_char*right_fill}" + return start_message + + def summary(data: list[ReportData]): """サマリーを作成します。 チェックしたURLの数、OK,NGの数、NGのものはURLを出す。 @@ -59,11 +74,13 @@ def summary(data: list[ReportData]): color_message = f" {total_part}, {ok_part}" plain_message = f" {total_count} Total, {ok_count} OK" + summary_message = "" if (ng_count := len(ng_items)) == 0: fill_char = f"{Colors.GREEN}={Colors.RESET}" else: - ng_detail = "\n".join([f"{item.url}: {item.result}" for item in ng_items]) + ng_detail = "\n".join([f"{item.url}: {item.reason}" for item in ng_items]) + summary_message += f"{ng_detail}" + "\n" ng_part = f"{Colors.RED}{ng_count} NG{Colors.RESET}" fill_char = f"{Colors.RED}={Colors.RESET}" color_message += f", {ng_part} " @@ -77,7 +94,7 @@ def summary(data: list[ReportData]): left_fill = total_fill // 2 right_fill = total_fill - left_fill - summary_message = f"{fill_char*left_fill}{color_message}{fill_char*right_fill}" + summary_message += f"{fill_char*left_fill}{color_message}{fill_char*right_fill}" return summary_message From 7d1f957456a27501a5594767bd62360a6dfc0353 Mon Sep 17 00:00:00 2001 From: DogFortune Date: Mon, 22 Dec 2025 10:33:05 +0900 Subject: [PATCH 12/19] =?UTF-8?q?NG=E3=82=B5=E3=83=9E=E3=83=AA=E3=83=BC?= =?UTF-8?q?=E3=82=92=E5=87=BA=E3=81=99=E5=89=8D=E3=81=ABFAIL=E3=83=A1?= =?UTF-8?q?=E3=83=83=E3=82=BB=E3=83=BC=E3=82=B8=E3=82=92=E5=87=BA=E3=81=99?= =?UTF-8?q?=E3=82=88=E3=81=86=E3=81=AB=E3=81=97=E3=81=9F=20refs=20#4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/linkstat/app.py | 2 +- src/linkstat/reporter.py | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/linkstat/app.py b/src/linkstat/app.py index 33f4af5..05148de 100644 --- a/src/linkstat/app.py +++ b/src/linkstat/app.py @@ -60,7 +60,7 @@ def main(args=None): format = __format_setting(parsed_args) src = parsed_args.src - start_msg = reporter.session_start() + start_msg = reporter.fill_plain_message(" linkstat start ") print(start_msg) files = analyzer.search(src) links = analyzer.extract_url(files) diff --git a/src/linkstat/reporter.py b/src/linkstat/reporter.py index d808d8e..e098981 100644 --- a/src/linkstat/reporter.py +++ b/src/linkstat/reporter.py @@ -41,18 +41,17 @@ class Colors: RESET = "\033[0m" -def session_start(): +def fill_plain_message(msg: str) -> str: fill_char = "=" - message = " linkstat start " terminal_width = shutil.get_terminal_size(fallback=(80, 24)).columns if terminal_width < 40: terminal_width = 80 - total_fill = terminal_width - len(message) + total_fill = terminal_width - len(msg) left_fill = total_fill // 2 right_fill = total_fill - left_fill - start_message = f"{fill_char*left_fill}{message}{fill_char*right_fill}" + start_message = f"{fill_char*left_fill}{msg}{fill_char*right_fill}" return start_message @@ -79,6 +78,7 @@ def summary(data: list[ReportData]): if (ng_count := len(ng_items)) == 0: fill_char = f"{Colors.GREEN}={Colors.RESET}" else: + print(fill_plain_message(" FAILURES ")) ng_detail = "\n".join([f"{item.url}: {item.reason}" for item in ng_items]) summary_message += f"{ng_detail}" + "\n" ng_part = f"{Colors.RED}{ng_count} NG{Colors.RESET}" From 01f8fb8a7d6fa8e90af7cf860759ef1f36e70163 Mon Sep 17 00:00:00 2001 From: DogFortune Date: Mon, 22 Dec 2025 11:42:40 +0900 Subject: [PATCH 13/19] =?UTF-8?q?=E3=83=A1=E3=82=BD=E3=83=83=E3=83=89?= =?UTF-8?q?=E5=90=8D=E3=81=AE=E5=A4=89=E6=9B=B4=20refs=20#4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit より明確に --- src/linkstat/app.py | 4 ++-- src/linkstat/reporter.py | 16 ++++++++++++---- tests/test_reporter.py | 4 ++-- 3 files changed, 16 insertions(+), 8 deletions(-) diff --git a/src/linkstat/app.py b/src/linkstat/app.py index 05148de..0340ae0 100644 --- a/src/linkstat/app.py +++ b/src/linkstat/app.py @@ -19,7 +19,7 @@ def __output(data: list[ReportData], format: OutputType, args): """ match format: case OutputType.Console: - line = reporter.summary(data) + line = reporter.get_summary_message(data) print(line) case OutputType.Json: output_path = args.report_json @@ -60,7 +60,7 @@ def main(args=None): format = __format_setting(parsed_args) src = parsed_args.src - start_msg = reporter.fill_plain_message(" linkstat start ") + start_msg = reporter.get_fill_plain_message(" linkstat start ") print(start_msg) files = analyzer.search(src) links = analyzer.extract_url(files) diff --git a/src/linkstat/reporter.py b/src/linkstat/reporter.py index e098981..5ef9e8f 100644 --- a/src/linkstat/reporter.py +++ b/src/linkstat/reporter.py @@ -41,7 +41,15 @@ class Colors: RESET = "\033[0m" -def fill_plain_message(msg: str) -> str: +def get_fill_plain_message(msg: str) -> str: + """区切り線が入ったメッセージテキストを作成します。 + メソッド自体はメッセージを作るだけで、出力は呼び出し側が行って下さい。 + + :param msg: _description_ + :type msg: str + :return: _description_ + :rtype: str + """ fill_char = "=" terminal_width = shutil.get_terminal_size(fallback=(80, 24)).columns if terminal_width < 40: @@ -55,8 +63,8 @@ def fill_plain_message(msg: str) -> str: return start_message -def summary(data: list[ReportData]): - """サマリーを作成します。 +def get_summary_message(data: list[ReportData]): + """レポート内容を元にサマリーを作成します。 チェックしたURLの数、OK,NGの数、NGのものはURLを出す。 :param data: _description_ @@ -78,7 +86,7 @@ def summary(data: list[ReportData]): if (ng_count := len(ng_items)) == 0: fill_char = f"{Colors.GREEN}={Colors.RESET}" else: - print(fill_plain_message(" FAILURES ")) + print(get_fill_plain_message(" FAILURES ")) ng_detail = "\n".join([f"{item.url}: {item.reason}" for item in ng_items]) summary_message += f"{ng_detail}" + "\n" ng_part = f"{Colors.RED}{ng_count} NG{Colors.RESET}" diff --git a/tests/test_reporter.py b/tests/test_reporter.py index 472da35..71d8176 100644 --- a/tests/test_reporter.py +++ b/tests/test_reporter.py @@ -23,7 +23,7 @@ class TestValid: def test_summary(self, setup_report_data): """サマリー出力テスト。文字列が想定している形である事""" - output_line = reporter.summary(setup_report_data) + output_line = reporter.get_summary_message(setup_report_data) assert output_line is not None assert reporter.Colors.RED in output_line @@ -36,7 +36,7 @@ def test_summary_all_ok(self): "path/to/doc1.md", 2, "https://example.com", enums.Result.OK, 200, None ) ) - summary_message = reporter.summary(results_report_data) + summary_message = reporter.get_summary_message(results_report_data) assert summary_message is not None assert "NG" not in summary_message From f8ba9d274c45af74389f8a30ba17999abfbbbbb1 Mon Sep 17 00:00:00 2001 From: DogFortune Date: Mon, 22 Dec 2025 13:48:25 +0900 Subject: [PATCH 14/19] update README refs #4 refs #5 --- CONTRIBUTING.md | 8 ++++++++ README.md | 42 ++++++++++++++++++++++++++++++++++++++++++ README_JP.md | 12 ++++++++++++ 3 files changed, 62 insertions(+) create mode 100644 CONTRIBUTING.md diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..d8786e5 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,8 @@ +# Contribution Guide + +## Pull Request +We welcome anyone who can adhere to our [code of conduct.](CODE_OF_CONDUCT_JP.md) + +## Test +### Code Style +Please adhere to the `black` style guide. Please adhere to the `flake8` lint rules. \ No newline at end of file diff --git a/README.md b/README.md index 0a69fcd..d6c12e4 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,44 @@ # linkstat +
+[![test-lint-format](https://github.com/DogFortune/linkstat/actions/workflows/lint-test-format.yml/badge.svg?branch=main)](https://github.com/DogFortune/linkstat/actions) [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT) +
+ + + + + + + +
English日本語
+ +_linkstat_ is a script that verifies the connectivity of links documented in the documentation. By detecting broken links early, it maintains the integrity of the documentation. +Currently, only Markdown files (*.md) are supported. + +## Caution +This library accesses services during runtime, so executing it in large quantities will cause load on the target service. When performing functional verification or integrating into CI/CD, please ensure the load on the linked service is minimized as much as possible. + +## Install + +```sh +pip install linkstat +``` + +## Usage + +```sh +linkstat {source_file_or_directory} +``` + +If no path is specified, the current directory will be scanned. + +## Output + +You can output reports in JSON format by using the option. + +```sh +linkstat --report-json {path} {source_file_or_directory} +``` + +## Contribute +[Guideline](CONTRIBUTING.md) \ No newline at end of file diff --git a/README_JP.md b/README_JP.md index 2cc880f..e293b4d 100644 --- a/README_JP.md +++ b/README_JP.md @@ -3,9 +3,21 @@ [![test-lint-format](https://github.com/DogFortune/linkstat/actions/workflows/lint-test-format.yml/badge.svg?branch=main)](https://github.com/DogFortune/linkstat/actions) [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT) + + + + + + + +
English日本語
+ _linkstat_ はドキュメントに記載されているリンクの疎通確認を行うスクリプトです。リンク切れの早期発見を行う事でドキュメントの健全性を保ちます。 現在対応しているのはMarkdownファイル(*.md)のみです。 +## 注意 +本ライブラリは実行時にサービスへアクセスするため、大量に実行すると相手サービスに負荷が発生します。動作確認及びCI/CDに取り込む場合は、リンク先のサービス負荷は限りなく少なくして下さい。 + ## インストール ```sh From f8bf10625e21c723b24cd6fb984b310bfb348ffa Mon Sep 17 00:00:00 2001 From: DogFortune Date: Mon, 22 Dec 2025 13:49:28 +0900 Subject: [PATCH 15/19] remove tqdm refs #4 --- THIRD-PARTY-LICENSES.md | 5 ----- pyproject.toml | 2 +- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/THIRD-PARTY-LICENSES.md b/THIRD-PARTY-LICENSES.md index b4e25cd..8d41098 100644 --- a/THIRD-PARTY-LICENSES.md +++ b/THIRD-PARTY-LICENSES.md @@ -30,11 +30,6 @@ The MIT License (MIT) Copyright (c) 2018 Łukasz Langa https://github.com/psf/black/blob/43135e9fafccbca723910a45aa62f0f182e85e5f/LICENSE -## tqdm -MPL v2.0 and MIT -Copyright (c) 2013 noamraph -https://github.com/tqdm/tqdm/blob/0ed5d7f18fa3153834cbac0aa57e8092b217cc16/LICENCE - ## Dataclasses JSON The MIT License Copyright (c) 2019 Charles Li and contributors diff --git a/pyproject.toml b/pyproject.toml index 500e7b3..1a32029 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -6,7 +6,7 @@ license-files = ["LICENSE"] readme = "README.md" requires-python = ">=3.10" version = "0.0.2" -dependencies = ["tqdm", "dataclasses-json"] +dependencies = ["dataclasses-json"] keywords = ["check", "url", "link"] classifiers = [ "Development Status :: 3 - Alpha", From a2b1c5062b566e98d1bb2185fe06257ea5145955 Mon Sep 17 00:00:00 2001 From: DogFortune Date: Mon, 22 Dec 2025 13:53:40 +0900 Subject: [PATCH 16/19] =?UTF-8?q?=E3=83=87=E3=82=A3=E3=83=AC=E3=82=AF?= =?UTF-8?q?=E3=83=88=E3=83=AA=E3=82=92=E6=98=8E=E7=A4=BA=E7=9A=84=E3=81=AB?= =?UTF-8?q?=E6=8C=87=E5=AE=9A=E3=81=99=E3=82=8B=E6=96=B9=E5=BC=8F=E3=81=AB?= =?UTF-8?q?=E5=A4=89=E6=9B=B4=20refs=20#4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 -- README_JP.md | 2 -- src/linkstat/app.py | 2 +- 3 files changed, 1 insertion(+), 5 deletions(-) diff --git a/README.md b/README.md index d6c12e4..5c24ca3 100644 --- a/README.md +++ b/README.md @@ -30,8 +30,6 @@ pip install linkstat linkstat {source_file_or_directory} ``` -If no path is specified, the current directory will be scanned. - ## Output You can output reports in JSON format by using the option. diff --git a/README_JP.md b/README_JP.md index e293b4d..6c8f288 100644 --- a/README_JP.md +++ b/README_JP.md @@ -30,8 +30,6 @@ pip install linkstat linkstat {source_file_or_directory} ``` -パスを指定しない場合はカレントディレクトリを検査対象とします。 - ## 出力 オプションを使用することでJSON形式のレポートを出力できます。 diff --git a/src/linkstat/app.py b/src/linkstat/app.py index 0340ae0..63d0218 100644 --- a/src/linkstat/app.py +++ b/src/linkstat/app.py @@ -46,7 +46,7 @@ def __format_setting(args) -> OutputType: def create_parser(): parser = argparse.ArgumentParser() - parser.add_argument("src", default=os.environ.get("SRC_DIR", ".")) + parser.add_argument("src") parser.add_argument( "--report-json", type=str, help="Create json report file at given path" ) From 6cf11470c762b146a01f6f7088aece1e46220d17 Mon Sep 17 00:00:00 2001 From: DogFortune Date: Mon, 22 Dec 2025 13:57:46 +0900 Subject: [PATCH 17/19] start! refs #4 --- pyproject.toml | 4 ++-- src/linkstat/app.py | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 1a32029..f52b211 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -5,11 +5,11 @@ description = "Perform connectivity checks on URLs listed in the Markdown" license-files = ["LICENSE"] readme = "README.md" requires-python = ">=3.10" -version = "0.0.2" +version = "1.0.0" dependencies = ["dataclasses-json"] keywords = ["check", "url", "link"] classifiers = [ - "Development Status :: 3 - Alpha", + "Development Status :: 5 - Production/Stable", "Intended Audience :: Developers", "License :: OSI Approved :: MIT License", "Programming Language :: Python :: 3 :: Only", diff --git a/src/linkstat/app.py b/src/linkstat/app.py index 63d0218..75e72a0 100644 --- a/src/linkstat/app.py +++ b/src/linkstat/app.py @@ -1,4 +1,3 @@ -import os from pathlib import Path from . import analyzer from . import reporter From 172d38e2aed2611efdf385c10129f3b1d4903d20 Mon Sep 17 00:00:00 2001 From: DogFortune Date: Mon, 22 Dec 2025 14:44:53 +0900 Subject: [PATCH 18/19] update readme --- README_JP.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README_JP.md b/README_JP.md index 6c8f288..b253d5a 100644 --- a/README_JP.md +++ b/README_JP.md @@ -1,7 +1,7 @@ # linkstat -
-[![test-lint-format](https://github.com/DogFortune/linkstat/actions/workflows/lint-test-format.yml/badge.svg?branch=main)](https://github.com/DogFortune/linkstat/actions) [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT) -
+ +[![test-lint-format](https://github.com/DogFortune/linkstat/actions/workflows/lint-test-format.yml/badge.svg)](https://github.com/DogFortune/linkstat/actions/workflows/lint-test-format.yml) +[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT) From 335150369568db69c1279005676a99ccef50458b Mon Sep 17 00:00:00 2001 From: DogFortune Date: Mon, 22 Dec 2025 15:00:45 +0900 Subject: [PATCH 19/19] update readme refs #4 --- README.md | 11 ----------- README_JP.md | 9 --------- 2 files changed, 20 deletions(-) diff --git a/README.md b/README.md index 5c24ca3..03e9d51 100644 --- a/README.md +++ b/README.md @@ -1,16 +1,5 @@ # linkstat -
[![test-lint-format](https://github.com/DogFortune/linkstat/actions/workflows/lint-test-format.yml/badge.svg?branch=main)](https://github.com/DogFortune/linkstat/actions) [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT) -
- -
- - - - - - -
English日本語
_linkstat_ is a script that verifies the connectivity of links documented in the documentation. By detecting broken links early, it maintains the integrity of the documentation. Currently, only Markdown files (*.md) are supported. diff --git a/README_JP.md b/README_JP.md index b253d5a..e2e748b 100644 --- a/README_JP.md +++ b/README_JP.md @@ -3,15 +3,6 @@ [![test-lint-format](https://github.com/DogFortune/linkstat/actions/workflows/lint-test-format.yml/badge.svg)](https://github.com/DogFortune/linkstat/actions/workflows/lint-test-format.yml) [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT) - - - - - - - -
English日本語
- _linkstat_ はドキュメントに記載されているリンクの疎通確認を行うスクリプトです。リンク切れの早期発見を行う事でドキュメントの健全性を保ちます。 現在対応しているのはMarkdownファイル(*.md)のみです。