stbkit 0.1.0a9.dev1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- stbkit/__main__.py +10 -0
- stbkit/api/__init__.py +48 -0
- stbkit/api/experimental/__init__.py +19 -0
- stbkit/api/experimental/repository/__init__.py +30 -0
- stbkit/api/py.typed +0 -0
- stbkit/api/stb_latest.py +7 -0
- stbkit/api/stb_v2_0_2.py +11 -0
- stbkit/api/stb_v2_1_1.py +9 -0
- stbkit/cli/__init__.py +17 -0
- stbkit/cli/_internal/cli_main.py +114 -0
- stbkit/cli/_internal/common.py +126 -0
- stbkit/cli/_internal/constants_exit_code.py +59 -0
- stbkit/cli/_internal/converter.py +693 -0
- stbkit/cli/_internal/diff.py +213 -0
- stbkit/cli/_internal/entry_points.py +25 -0
- stbkit/cli/_internal/global_parent.py +70 -0
- stbkit/cli/_internal/show_versions.py +36 -0
- stbkit/cli/_internal/validate.py +310 -0
- stbkit/cli/commands/convert.py +16 -0
- stbkit/cli/commands/diff.py +16 -0
- stbkit/cli/commands/validate.py +16 -0
- stbkit/cli/py.typed +0 -0
- stbkit/tools/__init__.py +12 -0
- stbkit/tools/_internal/__init__.py +5 -0
- stbkit/tools/_internal/constants.py +21 -0
- stbkit/tools/_internal/data_model/building_geometry.py +1208 -0
- stbkit/tools/_internal/data_model/building_geometry_web.py +106 -0
- stbkit/tools/_internal/data_model/element_data.py +93 -0
- stbkit/tools/_internal/data_model/ifc_data/entity_data.py +67 -0
- stbkit/tools/_internal/data_model/ifc_data/entity_names.py +32 -0
- stbkit/tools/_internal/data_model/shape_data.py +1089 -0
- stbkit/tools/_internal/diff/__init__.py +5 -0
- stbkit/tools/_internal/diff/common.py +50 -0
- stbkit/tools/_internal/diff/diff_xml.py +796 -0
- stbkit/tools/_internal/matrix.py +51 -0
- stbkit/tools/_internal/optional_dependencies/__init__.py +5 -0
- stbkit/tools/_internal/optional_dependencies/ifc_common.py +28 -0
- stbkit/tools/_internal/optional_dependencies/ifc_exporter/ifc_entity_exporter.py +473 -0
- stbkit/tools/_internal/optional_dependencies/ifc_exporter/ifc_profile_exporter.py +267 -0
- stbkit/tools/_internal/optional_dependencies/ifc_exporter/ifc_representation_exporter.py +178 -0
- stbkit/tools/_internal/optional_dependencies/ifc_pipeline.py +133 -0
- stbkit/tools/_internal/optional_dependencies/ifc_to_building_geometry.py +64 -0
- stbkit/tools/_internal/stb_io.py +116 -0
- stbkit/tools/_internal/stb_repair/_common.py +24 -0
- stbkit/tools/_internal/stb_repair/_stb_repair.py +197 -0
- stbkit/tools/_internal/stb_repair/_stb_v2_0_2_repair.py +53 -0
- stbkit/tools/_internal/stb_repair/_stb_v2_1_0_repair.py +109 -0
- stbkit/tools/_internal/stb_repair/_stb_v2_1_1_repair.py +109 -0
- stbkit/tools/_internal/studio_report.py +49 -0
- stbkit/tools/_internal/utils/atomic_writer.py +57 -0
- stbkit/tools/_internal/utils/float_rounding.py +49 -0
- stbkit/tools/_internal/utils/girder_utils.py +91 -0
- stbkit/tools/_internal/utils/guid_utils.py +30 -0
- stbkit/tools/_internal/utils/mesh_utils.py +1305 -0
- stbkit/tools/_internal/utils/node_utils.py +50 -0
- stbkit/tools/_internal/utils/unit_utils.py +23 -0
- stbkit/tools/_internal/vectors.py +222 -0
- stbkit/tools/converters/__init__.py +39 -0
- stbkit/tools/converters/_internal/__init__.py +5 -0
- stbkit/tools/converters/_internal/building_geometry_to_ply_text.py +32 -0
- stbkit/tools/converters/_internal/coord_converter.py +151 -0
- stbkit/tools/converters/_internal/element_data_to_building_geometry.py +549 -0
- stbkit/tools/converters/_internal/ifc_to_ply_text.py +21 -0
- stbkit/tools/converters/_internal/name_converter.py +23 -0
- stbkit/tools/converters/_internal/pipeline/__init__.py +5 -0
- stbkit/tools/converters/_internal/pipeline/data.py +188 -0
- stbkit/tools/converters/_internal/pipeline/execution.py +569 -0
- stbkit/tools/converters/_internal/pipeline/ply_pipeline.py +52 -0
- stbkit/tools/converters/_internal/pipeline/stb_pipeline.py +226 -0
- stbkit/tools/converters/_internal/pipeline/stb_pipeline_latest.py +39 -0
- stbkit/tools/converters/_internal/pipeline/step.py +139 -0
- stbkit/tools/converters/_internal/stb_latest_to_element_data/__init__.py +17 -0
- stbkit/tools/converters/_internal/stb_latest_to_element_data/_stb_latest_to_element_data.py +186 -0
- stbkit/tools/converters/_internal/stb_latest_to_element_data/member/member_footing.py +49 -0
- stbkit/tools/converters/_internal/stb_latest_to_element_data/member/member_line.py +533 -0
- stbkit/tools/converters/_internal/stb_latest_to_element_data/member/member_pile.py +100 -0
- stbkit/tools/converters/_internal/stb_latest_to_element_data/member/member_plane.py +103 -0
- stbkit/tools/converters/_internal/stb_latest_to_element_data/open.py +70 -0
- stbkit/tools/converters/_internal/stb_latest_to_element_data/section/sec.py +214 -0
- stbkit/tools/converters/_internal/stb_latest_to_element_data/section/sec_beam_rc.py +67 -0
- stbkit/tools/converters/_internal/stb_latest_to_element_data/section/sec_beam_s.py +97 -0
- stbkit/tools/converters/_internal/stb_latest_to_element_data/section/sec_beam_src.py +28 -0
- stbkit/tools/converters/_internal/stb_latest_to_element_data/section/sec_brace_s.py +49 -0
- stbkit/tools/converters/_internal/stb_latest_to_element_data/section/sec_column_cft.py +217 -0
- stbkit/tools/converters/_internal/stb_latest_to_element_data/section/sec_column_rc.py +41 -0
- stbkit/tools/converters/_internal/stb_latest_to_element_data/section/sec_column_s.py +127 -0
- stbkit/tools/converters/_internal/stb_latest_to_element_data/section/sec_column_src.py +173 -0
- stbkit/tools/converters/_internal/stb_latest_to_element_data/section/sec_foundation.py +225 -0
- stbkit/tools/converters/_internal/stb_latest_to_element_data/section/sec_parapet_rc.py +53 -0
- stbkit/tools/converters/_internal/stb_latest_to_element_data/section/sec_pile_rc.py +106 -0
- stbkit/tools/converters/_internal/stb_latest_to_element_data/section/sec_pile_s.py +100 -0
- stbkit/tools/converters/_internal/stb_latest_to_element_data/section/sec_steel.py +432 -0
- stbkit/tools/converters/_internal/stb_to_building_geometry.py +44 -0
- stbkit/tools/converters/_internal/stb_to_ifc_data/__init__.py +5 -0
- stbkit/tools/converters/_internal/stb_to_ifc_data/_stb_to_ifc_data.py +59 -0
- stbkit/tools/converters/_internal/stb_to_ifc_data/convert_option.py +22 -0
- stbkit/tools/converters/_internal/stb_to_ply_text.py +22 -0
- stbkit/tools/py.typed +0 -0
- stbkit/tools/upgrade/__init__.py +13 -0
- stbkit/tools/upgrade/_internal/__init__.py +5 -0
- stbkit/tools/upgrade/_internal/common.py +205 -0
- stbkit/tools/upgrade/_internal/upgrade.py +228 -0
- stbkit/tools/upgrade/_internal/v2_0_2_to_v2_1_0/__init__.py +60 -0
- stbkit/tools/upgrade/_internal/v2_0_2_to_v2_1_0/hook_funcs/hook_common.py +62 -0
- stbkit/tools/upgrade/_internal/v2_0_2_to_v2_1_0/hook_funcs/hook_joint_beam_shape_h.py +44 -0
- stbkit/tools/upgrade/_internal/v2_0_2_to_v2_1_0/hook_funcs/hook_sec_pile_rc.py +101 -0
- stbkit/tools/upgrade/_internal/v2_0_2_to_v2_1_0/hook_funcs/hook_sec_pile_s.py +78 -0
- stbkit/tools/upgrade/_internal/v2_0_2_to_v2_1_0/hook_funcs/hook_sec_slab_deck.py +56 -0
- stbkit/tools/upgrade/_internal/v2_0_2_to_v2_1_0/hook_funcs/hook_sec_slab_rc.py +128 -0
- stbkit/tools/upgrade/_internal/v2_0_2_to_v2_1_0/hook_funcs/post_girder.py +126 -0
- stbkit/tools/upgrade/_internal/v2_0_2_to_v2_1_0/hook_funcs/post_open.py +110 -0
- stbkit/tools/upgrade/_internal/v2_0_2_to_v2_1_0/hook_funcs/post_sec_beam_rc.py +227 -0
- stbkit/tools/upgrade/_internal/v2_0_2_to_v2_1_0/hook_funcs/post_sec_beam_s.py +1153 -0
- stbkit/tools/upgrade/_internal/v2_0_2_to_v2_1_0/hooks.py +22 -0
- stbkit/tools/upgrade/_internal/v2_0_2_to_v2_1_0/post.py +42 -0
- stbkit/tools/upgrade/_internal/v2_0_2_to_v2_1_0/tables.py +99 -0
- stbkit/tools/upgrade/_internal/v2_1_0_to_v2_1_1/__init__.py +58 -0
- stbkit/tools/upgrade/_internal/v2_1_0_to_v2_1_1/hooks.py +32 -0
- stbkit/tools/upgrade/_internal/v2_1_0_to_v2_1_1/tables.py +56 -0
- stbkit-0.1.0a9.dev1.dist-info/METADATA +196 -0
- stbkit-0.1.0a9.dev1.dist-info/RECORD +125 -0
- stbkit-0.1.0a9.dev1.dist-info/WHEEL +5 -0
- stbkit-0.1.0a9.dev1.dist-info/entry_points.txt +2 -0
- stbkit-0.1.0a9.dev1.dist-info/licenses/LICENSE +373 -0
- stbkit-0.1.0a9.dev1.dist-info/top_level.txt +1 -0
stbkit/__main__.py
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# Copyright 2025-2026 TAISEI CORPORATION
|
|
2
|
+
# SPDX-License-Identifier: MPL-2.0
|
|
3
|
+
# This Source Code Form is subject to the terms of the Mozilla Public
|
|
4
|
+
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
5
|
+
# file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
6
|
+
|
|
7
|
+
from .cli import main
|
|
8
|
+
|
|
9
|
+
if __name__ == "__main__":
|
|
10
|
+
main()
|
stbkit/api/__init__.py
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# Copyright 2026 TAISEI CORPORATION
|
|
2
|
+
# SPDX-License-Identifier: MPL-2.0
|
|
3
|
+
# This Source Code Form is subject to the terms of the Mozilla Public
|
|
4
|
+
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
5
|
+
# file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
6
|
+
|
|
7
|
+
"""stbkitの基本機能をまとめたAPI
|
|
8
|
+
|
|
9
|
+
ST-Bridgeファイルの読み書き、バージョンアップ、他形式への変換を提供します。
|
|
10
|
+
バージョンごとのデータモデルはstb_latest、stb_v2_0、stb_v2_1から利用してください。
|
|
11
|
+
|
|
12
|
+
読み込みは、ファイルのバージョンをそのまま扱うload・loadsと、
|
|
13
|
+
読み込んでから最新版へ変換するload_latest・loads_latestがあります。
|
|
14
|
+
|
|
15
|
+
IFCへの変換を利用する場合はifcopenshellのインストールが必要です。
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
from stbkit.core.data_model.common import StBridgeElement as StBridgeElement
|
|
19
|
+
from stbkit.core.data_model.common import StBridgeRoot as StBridgeRoot
|
|
20
|
+
from stbkit.core.stb_exceptions import NoneAccessError as NoneAccessError
|
|
21
|
+
from stbkit.core.stb_io import dump as dump
|
|
22
|
+
from stbkit.core.stb_io import dumps as dumps
|
|
23
|
+
from stbkit.core.stb_io import load as load
|
|
24
|
+
from stbkit.core.stb_io import loads as loads
|
|
25
|
+
from stbkit.core.validation import validate_schema as validate_schema
|
|
26
|
+
|
|
27
|
+
from stbkit.tools._internal.stb_io import load_latest as load_latest
|
|
28
|
+
from stbkit.tools._internal.stb_io import loads_latest as loads_latest
|
|
29
|
+
from stbkit.tools.converters import to_ifc as to_ifc
|
|
30
|
+
from stbkit.tools.upgrade import upgrade_to_latest as upgrade_to_latest
|
|
31
|
+
|
|
32
|
+
__all__ = [
|
|
33
|
+
"NoneAccessError",
|
|
34
|
+
"StBridgeElement",
|
|
35
|
+
"StBridgeRoot",
|
|
36
|
+
"dump",
|
|
37
|
+
"dumps",
|
|
38
|
+
"load",
|
|
39
|
+
"load_latest",
|
|
40
|
+
"loads",
|
|
41
|
+
"loads_latest",
|
|
42
|
+
"stb_latest",
|
|
43
|
+
"stb_v2_0",
|
|
44
|
+
"stb_v2_1",
|
|
45
|
+
"to_ifc",
|
|
46
|
+
"upgrade_to_latest",
|
|
47
|
+
"validate_schema",
|
|
48
|
+
]
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# Copyright 2026 TAISEI CORPORATION
|
|
2
|
+
# SPDX-License-Identifier: MPL-2.0
|
|
3
|
+
# This Source Code Form is subject to the terms of the Mozilla Public
|
|
4
|
+
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
5
|
+
# file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
6
|
+
|
|
7
|
+
"""将来の公開を意図した、暫定公開API
|
|
8
|
+
|
|
9
|
+
※このモジュール内のAPIは暫定的なものであり、今後変更される可能性があります。
|
|
10
|
+
仕様が固まったものはstbkit.apiへ移し、このモジュールからは段階的に外します。
|
|
11
|
+
継続的に利用するコードから使う場合は、この点を了解したうえで、バージョンを固定して使用してください。
|
|
12
|
+
互換性に関する方針は、GitHubリポジトリのCOMPATIBILITY.mdを参照してください。
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
from stbkit.core.repository import get_repository as get_repository
|
|
16
|
+
from stbkit.core.serialization import from_dict as from_dict
|
|
17
|
+
from stbkit.core.serialization import to_dict as to_dict
|
|
18
|
+
|
|
19
|
+
__all__ = ["from_dict", "get_repository", "to_dict"]
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# Copyright 2026 TAISEI CORPORATION
|
|
2
|
+
# SPDX-License-Identifier: MPL-2.0
|
|
3
|
+
# This Source Code Form is subject to the terms of the Mozilla Public
|
|
4
|
+
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
5
|
+
# file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
6
|
+
|
|
7
|
+
"""バージョンごとのリポジトリ
|
|
8
|
+
|
|
9
|
+
リポジトリは、読み込んだST-Bridgeの参照解決や検索を行うクラスです。
|
|
10
|
+
型注釈を利用したい場合に利用します。
|
|
11
|
+
インスタンスはstbkit.api.experimental.get_repositoryを使って取得できます。
|
|
12
|
+
モデルのバージョンに対応する型を選ぶため、バージョンごとの分岐が不要になります。
|
|
13
|
+
|
|
14
|
+
※このモジュール内のAPIは暫定的なものであり、今後変更される可能性があります。
|
|
15
|
+
仕様が固まったものはstbkit.apiへ移し、このモジュールからは段階的に外します。
|
|
16
|
+
継続的に利用するコードから使う場合は、この点を了解したうえで、バージョンを固定して使用してください。
|
|
17
|
+
互換性に関する方針は、GitHubリポジトリのCOMPATIBILITY.mdを参照してください。
|
|
18
|
+
"""
|
|
19
|
+
|
|
20
|
+
from stbkit.core.repository import RepositoryV2_0_2 as RepositoryV2_0_2
|
|
21
|
+
from stbkit.core.repository import RepositoryV2_1_0 as RepositoryV2_1_0
|
|
22
|
+
from stbkit.core.repository import RepositoryV2_1_1 as RepositoryLatest
|
|
23
|
+
from stbkit.core.repository import RepositoryV2_1_1 as RepositoryV2_1_1
|
|
24
|
+
|
|
25
|
+
__all__ = [
|
|
26
|
+
"RepositoryLatest",
|
|
27
|
+
"RepositoryV2_0_2",
|
|
28
|
+
"RepositoryV2_1_0",
|
|
29
|
+
"RepositoryV2_1_1",
|
|
30
|
+
]
|
stbkit/api/py.typed
ADDED
|
File without changes
|
stbkit/api/stb_latest.py
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
# Copyright 2026 TAISEI CORPORATION
|
|
2
|
+
# SPDX-License-Identifier: MPL-2.0
|
|
3
|
+
# This Source Code Form is subject to the terms of the Mozilla Public
|
|
4
|
+
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
5
|
+
# file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
6
|
+
|
|
7
|
+
from stbkit.core.data_model.stb_v2_1_1 import *
|
stbkit/api/stb_v2_0_2.py
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# Copyright 2026 TAISEI CORPORATION
|
|
2
|
+
# SPDX-License-Identifier: MPL-2.0
|
|
3
|
+
# This Source Code Form is subject to the terms of the Mozilla Public
|
|
4
|
+
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
5
|
+
# file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
6
|
+
|
|
7
|
+
"""ST-Bridge v2.0.2のデータモデル
|
|
8
|
+
|
|
9
|
+
WARNING: ST-Bridge 2.0.xは、2027年末でサポート終了となります。v2.1.xへの移行を推奨します。"""
|
|
10
|
+
|
|
11
|
+
from stbkit.core.data_model.stb_v2_0_2 import *
|
stbkit/api/stb_v2_1_1.py
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# Copyright 2026 TAISEI CORPORATION
|
|
2
|
+
# SPDX-License-Identifier: MPL-2.0
|
|
3
|
+
# This Source Code Form is subject to the terms of the Mozilla Public
|
|
4
|
+
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
5
|
+
# file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
6
|
+
|
|
7
|
+
"""ST-Bridge v2.1.1のデータモデル"""
|
|
8
|
+
|
|
9
|
+
from stbkit.core.data_model.stb_v2_1_1 import *
|
stbkit/cli/__init__.py
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# Copyright 2025-2026 TAISEI CORPORATION
|
|
2
|
+
# SPDX-License-Identifier: MPL-2.0
|
|
3
|
+
# This Source Code Form is subject to the terms of the Mozilla Public
|
|
4
|
+
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
5
|
+
# file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
6
|
+
|
|
7
|
+
"""cliのエントリポイント
|
|
8
|
+
|
|
9
|
+
※このモジュール内のAPIは暫定的なものであり、今後変更される可能性があります。
|
|
10
|
+
継続的に利用するコードから使う場合は、この点を了解したうえで、バージョンを固定して使用してください。
|
|
11
|
+
互換性に関する方針は、GitHubリポジトリのCOMPATIBILITY.mdを参照してください。
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
from ._internal.cli_main import main as main
|
|
15
|
+
|
|
16
|
+
if __name__ == "__main__":
|
|
17
|
+
main()
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
# Copyright 2025-2026 TAISEI CORPORATION
|
|
2
|
+
# SPDX-License-Identifier: MPL-2.0
|
|
3
|
+
# This Source Code Form is subject to the terms of the Mozilla Public
|
|
4
|
+
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
5
|
+
# file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
6
|
+
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
import sys
|
|
10
|
+
import traceback
|
|
11
|
+
from argparse import ArgumentParser, Namespace, _SubParsersAction
|
|
12
|
+
from importlib import metadata
|
|
13
|
+
from typing import Any, Never
|
|
14
|
+
|
|
15
|
+
from .constants_exit_code import (
|
|
16
|
+
EXIT_EXECUTION_ERROR,
|
|
17
|
+
EXIT_INTERRUPTED,
|
|
18
|
+
EXIT_INVALID_ARGUMENT,
|
|
19
|
+
)
|
|
20
|
+
from .entry_points import load_command_entry_points
|
|
21
|
+
from .global_parent import make_global_parent
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class SubcommandHelpArgumentParser(ArgumentParser):
|
|
25
|
+
def __init__(self, *args: Any, **kwargs: Any) -> None:
|
|
26
|
+
super().__init__(*args, **kwargs)
|
|
27
|
+
self.subparsers_action: _SubParsersAction[ArgumentParser] | None = None
|
|
28
|
+
|
|
29
|
+
def add_subparsers(self, *args: Any, **kwargs: Any) -> _SubParsersAction[Any]:
|
|
30
|
+
self.subparsers_action = super().add_subparsers(*args, **kwargs)
|
|
31
|
+
return self.subparsers_action
|
|
32
|
+
|
|
33
|
+
def error(self, message: str) -> Never:
|
|
34
|
+
self._print_message(f"error: {message}\n", sys.stderr)
|
|
35
|
+
if self.subparsers_action:
|
|
36
|
+
for subcmd in self.subparsers_action.choices:
|
|
37
|
+
if subcmd in sys.argv:
|
|
38
|
+
self.subparsers_action.choices[subcmd].print_help()
|
|
39
|
+
self.exit(EXIT_INVALID_ARGUMENT)
|
|
40
|
+
self.print_help()
|
|
41
|
+
self.exit(EXIT_INVALID_ARGUMENT)
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def main() -> None:
|
|
45
|
+
"""stbkitのcliを実行する"""
|
|
46
|
+
try:
|
|
47
|
+
_main()
|
|
48
|
+
# 想定外例外がそのまま投げられると、終了コードが1になるが、
|
|
49
|
+
# 1はバリデーションや比較の結果に利用したいため終了コードを変更する。
|
|
50
|
+
except KeyboardInterrupt:
|
|
51
|
+
# Ctrl+Cによる中断。
|
|
52
|
+
raise SystemExit(EXIT_INTERRUPTED) from None
|
|
53
|
+
except Exception: # noqa: BLE001
|
|
54
|
+
# 終了コードを変更するための最後の受け皿なので種類を問わずキャッチする。
|
|
55
|
+
traceback.print_exc()
|
|
56
|
+
raise SystemExit(EXIT_EXECUTION_ERROR) from None
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
def _main() -> None:
|
|
60
|
+
parser: ArgumentParser = SubcommandHelpArgumentParser(
|
|
61
|
+
prog="stbkit", parents=[make_global_parent()]
|
|
62
|
+
)
|
|
63
|
+
subparsers: _SubParsersAction[Any] = parser.add_subparsers(dest="command")
|
|
64
|
+
entry_points: metadata.EntryPoints = load_command_entry_points()
|
|
65
|
+
|
|
66
|
+
for entry_point in entry_points:
|
|
67
|
+
register: Any = entry_point.load()
|
|
68
|
+
try:
|
|
69
|
+
register(subparsers)
|
|
70
|
+
except Exception as e: # noqa: BLE001
|
|
71
|
+
print(
|
|
72
|
+
f"不明なサブコマンドを登録しようとして失敗しました[{entry_point.name}]: {e}",
|
|
73
|
+
file=sys.stderr,
|
|
74
|
+
)
|
|
75
|
+
|
|
76
|
+
if ("--interactive" in sys.argv) and (
|
|
77
|
+
len([a for a in sys.argv[1:] if not a.startswith("-")]) == 0
|
|
78
|
+
):
|
|
79
|
+
subcommands = list(subparsers.choices.keys())
|
|
80
|
+
print("利用可能なサブコマンド:")
|
|
81
|
+
for idx, cmd in enumerate(subcommands, 1):
|
|
82
|
+
print(f" {idx}: {cmd}")
|
|
83
|
+
while True:
|
|
84
|
+
print("実行するサブコマンドの番号またはコマンド名を入力してください: ")
|
|
85
|
+
choice = input().strip()
|
|
86
|
+
if choice.isdigit():
|
|
87
|
+
idx = int(choice)
|
|
88
|
+
if 1 <= idx <= len(subcommands):
|
|
89
|
+
selected = subcommands[idx - 1]
|
|
90
|
+
break
|
|
91
|
+
else:
|
|
92
|
+
print("無効な番号です。")
|
|
93
|
+
elif choice in subcommands:
|
|
94
|
+
selected = choice
|
|
95
|
+
break
|
|
96
|
+
else:
|
|
97
|
+
print("無効な入力です。番号またはコマンド名を入力してください。")
|
|
98
|
+
insert_pos = 1
|
|
99
|
+
sys.argv.insert(insert_pos, selected)
|
|
100
|
+
args: Namespace = parser.parse_args()
|
|
101
|
+
# エラーメッセージを拾いやすいように改行を挟む
|
|
102
|
+
print()
|
|
103
|
+
else:
|
|
104
|
+
args = parser.parse_args()
|
|
105
|
+
|
|
106
|
+
if getattr(args, "version", False):
|
|
107
|
+
from .show_versions import show_versions
|
|
108
|
+
|
|
109
|
+
show_versions(entry_points)
|
|
110
|
+
return
|
|
111
|
+
if getattr(args, "command", None):
|
|
112
|
+
args.func(args)
|
|
113
|
+
return
|
|
114
|
+
parser.print_help()
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
# Copyright 2026 TAISEI CORPORATION
|
|
2
|
+
# SPDX-License-Identifier: MPL-2.0
|
|
3
|
+
# This Source Code Form is subject to the terms of the Mozilla Public
|
|
4
|
+
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
5
|
+
# file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
6
|
+
|
|
7
|
+
import sys
|
|
8
|
+
from argparse import ArgumentParser, Namespace
|
|
9
|
+
from collections.abc import Sequence
|
|
10
|
+
from pathlib import Path
|
|
11
|
+
from typing import IO
|
|
12
|
+
|
|
13
|
+
from stbkit.core.stb_exceptions import XmlLimitExceededError, XmlLimitKind
|
|
14
|
+
from stbkit.core.stb_io._internal.loader import _detect_encoding
|
|
15
|
+
|
|
16
|
+
from stbkit.tools._internal.utils.atomic_writer import (
|
|
17
|
+
write_text_with_temp_file as _write_text_via_temporary_file,
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
from .global_parent import get_interactive
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def use_input(parser: ArgumentParser) -> None:
|
|
24
|
+
parser.add_argument(
|
|
25
|
+
"input", nargs="?", help="入力ファイルのパス。-で標準入力を使用します。"
|
|
26
|
+
)
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def read_stdin_xml(*, max_size: int, encoding: str | None = None) -> str:
|
|
30
|
+
# 端末のエンコーディング設定だとST-Bridgeに記載のencodingを読めないため、bytesとして受け取り、XML宣言から判定する。
|
|
31
|
+
# encodingを明示した場合は判定より優先する。
|
|
32
|
+
buffer: IO[bytes] | None = getattr(sys.stdin, "buffer", None)
|
|
33
|
+
if buffer is None:
|
|
34
|
+
text: str = sys.stdin.read(max_size + 1)
|
|
35
|
+
if len(text) > max_size:
|
|
36
|
+
raise XmlLimitExceededError(kind=XmlLimitKind.SIZE, limit=max_size)
|
|
37
|
+
return text
|
|
38
|
+
|
|
39
|
+
raw: bytes = buffer.read(max_size + 1)
|
|
40
|
+
if len(raw) > max_size:
|
|
41
|
+
raise XmlLimitExceededError(kind=XmlLimitKind.SIZE, limit=max_size)
|
|
42
|
+
return raw.decode(encoding or _detect_encoding(raw))
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def get_input(args: Namespace) -> str:
|
|
46
|
+
interactive: bool = get_interactive(args)
|
|
47
|
+
input_path: str = args.input
|
|
48
|
+
if not input_path and interactive:
|
|
49
|
+
print("入力ファイルパスを入力してください: ")
|
|
50
|
+
input_path = input().strip()
|
|
51
|
+
if not input_path:
|
|
52
|
+
input_path = "-"
|
|
53
|
+
return input_path
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def use_output(parser: ArgumentParser) -> None:
|
|
57
|
+
parser.add_argument(
|
|
58
|
+
"-o",
|
|
59
|
+
"--output",
|
|
60
|
+
default="-",
|
|
61
|
+
help="出力ファイルのパス。-で標準出力を使用します。",
|
|
62
|
+
)
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
def get_output(args: Namespace) -> str:
|
|
66
|
+
interactive: bool = get_interactive(args)
|
|
67
|
+
output_path: str = args.output
|
|
68
|
+
if not output_path and interactive:
|
|
69
|
+
print("出力ファイルパスを入力してください: ")
|
|
70
|
+
output_path = input().strip()
|
|
71
|
+
if not output_path:
|
|
72
|
+
output_path = "-"
|
|
73
|
+
return output_path
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
def use_yes(parser: ArgumentParser) -> None:
|
|
77
|
+
parser.add_argument(
|
|
78
|
+
"-y", "--yes", action="store_true", help="確認なしで上書きします。"
|
|
79
|
+
)
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
def get_yes(args: Namespace) -> bool:
|
|
83
|
+
yes: bool = args.yes
|
|
84
|
+
return yes
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
def use_quiet(parser: ArgumentParser) -> None:
|
|
88
|
+
parser.add_argument("--quiet", action="store_true", help="エラーのみを表示します。")
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
def get_quiet(args: Namespace) -> bool:
|
|
92
|
+
quiet: bool = args.quiet
|
|
93
|
+
return quiet
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
def ensure_output_not_input(output: str, input_paths: Sequence[Path]) -> None:
|
|
97
|
+
if output == "-":
|
|
98
|
+
return
|
|
99
|
+
|
|
100
|
+
output_path = Path(output).resolve()
|
|
101
|
+
for input_path in input_paths:
|
|
102
|
+
resolved_input = input_path.resolve()
|
|
103
|
+
is_same_resolved_path = output_path == resolved_input
|
|
104
|
+
is_same_file = output_path.exists() and output_path.samefile(resolved_input)
|
|
105
|
+
if is_same_resolved_path or is_same_file:
|
|
106
|
+
raise ValueError("出力先に入力ファイルは指定できません。")
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
def confirm_overwrite(*, output: str, yes: bool, interactive: bool) -> bool:
|
|
110
|
+
if output == "-":
|
|
111
|
+
return True
|
|
112
|
+
|
|
113
|
+
output_path = Path(output)
|
|
114
|
+
if not output_path.exists() or yes:
|
|
115
|
+
return True
|
|
116
|
+
if not interactive:
|
|
117
|
+
return False
|
|
118
|
+
|
|
119
|
+
response = input(f"{output_path}は既に存在します。上書きしますか?(y/N):")
|
|
120
|
+
return response.strip().casefold() in {"y", "yes"}
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
def write_text_via_temporary_file(
|
|
124
|
+
*, output: str, text: str, encoding: str = "utf-8"
|
|
125
|
+
) -> None:
|
|
126
|
+
_write_text_via_temporary_file(Path(output), text, encoding=encoding)
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# Copyright 2026 TAISEI CORPORATION
|
|
2
|
+
# SPDX-License-Identifier: MPL-2.0
|
|
3
|
+
# This Source Code Form is subject to the terms of the Mozilla Public
|
|
4
|
+
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
5
|
+
# file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
6
|
+
|
|
7
|
+
"""CLIの終了コード
|
|
8
|
+
|
|
9
|
+
同系統の結果は、サブコマンドが違っても同じ値を返すようにする。
|
|
10
|
+
0と1は「処理を正常に実行できた」場合、2以降は「処理が実行できなかった」場合。
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
from typing import Final
|
|
14
|
+
|
|
15
|
+
EXIT_OK: Final[int] = 0
|
|
16
|
+
"""処理が正常に終了した。バリデーション比較、diff差分なし等"""
|
|
17
|
+
|
|
18
|
+
EXIT_ISSUE_FOUND: Final[int] = 1
|
|
19
|
+
"""処理は正常に実行できたが、対象に問題または差分あり。
|
|
20
|
+
|
|
21
|
+
バリデーションNG、diffで差分有り、変換の実行はできたがエラーが出た場合が該当。
|
|
22
|
+
|
|
23
|
+
1は正常に実行した結果でエラーではないが、検査や比較を行うツールの慣習に合わせている。
|
|
24
|
+
grepの一致なし、diffの差分あり、`git diff --exit-code`の差分有り等は`1を返す。
|
|
25
|
+
|
|
26
|
+
想定外例外がそのまま投げられると、終了コードが1になってしまうが、
|
|
27
|
+
1はバリデーションや比較の結果に利用したいため、混ざらないように終了コードを変更する処理を行う。
|
|
28
|
+
"""
|
|
29
|
+
|
|
30
|
+
EXIT_INVALID_ARGUMENT: Final[int] = 2
|
|
31
|
+
"""引数や指定の間違いで、処理が開始できなかった。
|
|
32
|
+
|
|
33
|
+
未知のオプション、非対応の変換の指定、存在しないパスの指定等。
|
|
34
|
+
|
|
35
|
+
argparseが引数エラーに2を使うため、それに合わせている。
|
|
36
|
+
stbkitで把握しきれなかった引数エラーが素通りしても同じ値になる。
|
|
37
|
+
grepやdiffも異常に2を使い、シェルの慣習でもビルトインの誤用が2。
|
|
38
|
+
"""
|
|
39
|
+
|
|
40
|
+
EXIT_EXECUTION_ERROR: Final[int] = 3
|
|
41
|
+
"""処理の実行中に失敗した。
|
|
42
|
+
|
|
43
|
+
入出力の失敗など、引数の誤りでも実行結果の問題でもない場合。
|
|
44
|
+
想定外の例外もこれで終了する。
|
|
45
|
+
"""
|
|
46
|
+
|
|
47
|
+
EXIT_OPTIONAL_DEPENDENCY_MISSING: Final[int] = 4
|
|
48
|
+
"""オプション依存パッケージがなく、処理を実行できなかった。
|
|
49
|
+
|
|
50
|
+
ifcopenshellやxmlschemaを必要とする処理を指定したのにインストールされていない場合。
|
|
51
|
+
利用者の環境によって結果が変わるため、EXIT_EXECUTION_ERRORとは分ける。
|
|
52
|
+
"""
|
|
53
|
+
|
|
54
|
+
EXIT_INTERRUPTED: Final[int] = 130
|
|
55
|
+
"""中断(Ctrl+C)で終了した。
|
|
56
|
+
|
|
57
|
+
シグナルnによる終了を128+nで表す慣習に合わせている(128+2=130)。
|
|
58
|
+
Pythonの既定ではKeyboardInterruptが1になるため、キャッチして変更する。
|
|
59
|
+
"""
|