treeing 1.0.1__tar.gz
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.
- treeing-1.0.1/LICENSE +21 -0
- treeing-1.0.1/PKG-INFO +112 -0
- treeing-1.0.1/README.md +85 -0
- treeing-1.0.1/pyproject.toml +46 -0
- treeing-1.0.1/setup.cfg +4 -0
- treeing-1.0.1/treeing/__init__.py +7 -0
- treeing-1.0.1/treeing/_release_defaults.py +3 -0
- treeing-1.0.1/treeing/assets/icon.icns +0 -0
- treeing-1.0.1/treeing/assets/icon.ico +0 -0
- treeing-1.0.1/treeing/assets/icon.png +0 -0
- treeing-1.0.1/treeing/cli/__init__.py +5 -0
- treeing-1.0.1/treeing/cli/confirm.py +197 -0
- treeing-1.0.1/treeing/cli/help_text.py +311 -0
- treeing-1.0.1/treeing/cli/io.py +72 -0
- treeing-1.0.1/treeing/cli/main.py +427 -0
- treeing-1.0.1/treeing/cli/report.py +104 -0
- treeing-1.0.1/treeing/cli_entry.py +16 -0
- treeing-1.0.1/treeing/config.py +205 -0
- treeing-1.0.1/treeing/core/__init__.py +15 -0
- treeing-1.0.1/treeing/core/constants.py +20 -0
- treeing-1.0.1/treeing/core/generator.py +567 -0
- treeing-1.0.1/treeing/core/parser.py +407 -0
- treeing-1.0.1/treeing/core/preview.py +98 -0
- treeing-1.0.1/treeing/gui/__init__.py +5 -0
- treeing-1.0.1/treeing/gui/app.py +886 -0
- treeing-1.0.1/treeing/gui/dnd.py +124 -0
- treeing-1.0.1/treeing/gui/icon.py +69 -0
- treeing-1.0.1/treeing/gui/preview.py +9 -0
- treeing-1.0.1/treeing/gui/settings.py +80 -0
- treeing-1.0.1/treeing/gui/tooltip.py +234 -0
- treeing-1.0.1/treeing/gui_entry.py +39 -0
- treeing-1.0.1/treeing/main.py +21 -0
- treeing-1.0.1/treeing/path_checks.py +87 -0
- treeing-1.0.1/treeing/strings.bootstrap.json +7 -0
- treeing-1.0.1/treeing/strings.json +222 -0
- treeing-1.0.1/treeing.egg-info/PKG-INFO +112 -0
- treeing-1.0.1/treeing.egg-info/SOURCES.txt +38 -0
- treeing-1.0.1/treeing.egg-info/dependency_links.txt +1 -0
- treeing-1.0.1/treeing.egg-info/entry_points.txt +3 -0
- treeing-1.0.1/treeing.egg-info/top_level.txt +1 -0
treeing-1.0.1/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 MING
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
treeing-1.0.1/PKG-INFO
ADDED
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: treeing
|
|
3
|
+
Version: 1.0.1
|
|
4
|
+
Summary: ASCII tree → directory/file generator
|
|
5
|
+
Author: MING
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/xiao-ming-b65536/treeing
|
|
8
|
+
Project-URL: Source, https://github.com/xiao-ming-b65536/treeing
|
|
9
|
+
Project-URL: Issue Tracker, https://github.com/xiao-ming-b65536/treeing/issues
|
|
10
|
+
Project-URL: Changelog, https://github.com/xiao-ming-b65536/treeing/blob/main/CHANGELOG.md
|
|
11
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
12
|
+
Classifier: Environment :: Console
|
|
13
|
+
Classifier: Environment :: X11 Applications
|
|
14
|
+
Classifier: Intended Audience :: Developers
|
|
15
|
+
Classifier: Operating System :: OS Independent
|
|
16
|
+
Classifier: Programming Language :: Python :: 3
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
21
|
+
Classifier: Topic :: Software Development :: Build Tools
|
|
22
|
+
Classifier: Topic :: Utilities
|
|
23
|
+
Requires-Python: >=3.11
|
|
24
|
+
Description-Content-Type: text/markdown
|
|
25
|
+
License-File: LICENSE
|
|
26
|
+
Dynamic: license-file
|
|
27
|
+
|
|
28
|
+
# Treeing — ASCII tree → directory/file generator
|
|
29
|
+
|
|
30
|
+
Turn directory-tree text (e.g. output from the `tree` command) into real folders and empty files.
|
|
31
|
+
|
|
32
|
+
## Features
|
|
33
|
+
|
|
34
|
+
- Common `tree` output formats: Unicode box-drawing, pipe style, Windows `tree`, space-indented trees.
|
|
35
|
+
- Automatic indent repair (disable with `--no-fix` or the GUI checkbox).
|
|
36
|
+
- Both a GUI and a CLI.
|
|
37
|
+
- Cross-platform: Windows, macOS, Linux.
|
|
38
|
+
- User-visible strings live in `treeing/strings.json` (bootstrap errors in `treeing/strings.bootstrap.json`).
|
|
39
|
+
|
|
40
|
+
## Preview
|
|
41
|
+
|
|
42
|
+

|
|
43
|
+
|
|
44
|
+
> Screenshot: Windows, English UI, parsing a sample project tree.
|
|
45
|
+
|
|
46
|
+
## Quick start
|
|
47
|
+
|
|
48
|
+
### Install from PyPI
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
pip install treeing
|
|
52
|
+
treeing -i tree.txt -o ./out # CLI
|
|
53
|
+
treeing-gui # GUI
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
The CLI needs only the Python standard library. The GUI uses `tkinter`; on Linux install it with `sudo apt-get install python3-tk` (it ships with Python on Windows and macOS).
|
|
57
|
+
|
|
58
|
+
### Run from source
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
python -m venv .venv
|
|
62
|
+
# Windows: .\.venv\Scripts\pip install -r requirements-build.txt
|
|
63
|
+
# Unix: .venv/bin/pip install -r requirements-build.txt
|
|
64
|
+
|
|
65
|
+
python -m treeing.main # GUI
|
|
66
|
+
python -m treeing.main -i tree.txt -o ./out # CLI
|
|
67
|
+
python -m treeing.main --help # CLI help
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
### Run a prebuilt executable
|
|
71
|
+
|
|
72
|
+
Prebuilt binaries are attached to each [release](https://github.com/xiao-ming-b65536/treeing/releases) (Windows, Linux, macOS ARM, macOS x86). Pick the archive for your platform (replace `vX.Y.Z` with the actual version):
|
|
73
|
+
|
|
74
|
+
| Platform | Archives |
|
|
75
|
+
|---|---|
|
|
76
|
+
| Windows | `treeing-cli-windows-vX.Y.Z.zip`, `treeing-gui-windows-vX.Y.Z.zip` |
|
|
77
|
+
| Linux | `treeing-cli-linux-vX.Y.Z.tar.gz`, `treeing-gui-linux-vX.Y.Z.tar.gz` |
|
|
78
|
+
| macOS (Apple Silicon) | `treeing-cli-macos-arm64-vX.Y.Z.tar.gz`, `treeing-gui-macos-arm64-vX.Y.Z.tar.gz` |
|
|
79
|
+
| macOS (Intel) | `treeing-cli-macos-x86_64-vX.Y.Z.tar.gz`, `treeing-gui-macos-x86_64-vX.Y.Z.tar.gz` |
|
|
80
|
+
|
|
81
|
+
CLI and GUI are packaged separately; download whichever you need. Verify against `SHA256SUMS.txt` in the same release.
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
treeing-gui # GUI — Linux / macOS
|
|
85
|
+
treeing-gui.exe # GUI — Windows
|
|
86
|
+
|
|
87
|
+
treeing-cli -i tree.txt -o ./out # CLI — Linux / macOS
|
|
88
|
+
treeing-cli.exe -i tree.txt -o ./out # CLI — Windows
|
|
89
|
+
treeing-cli --help # CLI help — Linux / macOS
|
|
90
|
+
treeing-cli.exe --help # CLI help — Windows
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
### Build executables yourself
|
|
94
|
+
|
|
95
|
+
```bash
|
|
96
|
+
pip install -r requirements-build.txt
|
|
97
|
+
python build.py --target all # outputs to dist/<platform>/
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
## Documentation
|
|
101
|
+
|
|
102
|
+
See [docs/USER_GUIDE.md](docs/USER_GUIDE.md) for a unified guide covering source runs and prebuilt executables on Windows, macOS ARM, macOS x86, and Linux.
|
|
103
|
+
|
|
104
|
+
## Legal
|
|
105
|
+
|
|
106
|
+
- **Licence** — MIT; see [LICENSE](LICENSE).
|
|
107
|
+
- **Privacy Policy** — see [PRIVACY.md](PRIVACY.md).
|
|
108
|
+
- **Terms of Use** — see [TERMS.md](TERMS.md).
|
|
109
|
+
|
|
110
|
+
## AI Disclosure
|
|
111
|
+
|
|
112
|
+
Parts of this source code were written with assistance from AI coding tools.
|
treeing-1.0.1/README.md
ADDED
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
# Treeing — ASCII tree → directory/file generator
|
|
2
|
+
|
|
3
|
+
Turn directory-tree text (e.g. output from the `tree` command) into real folders and empty files.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- Common `tree` output formats: Unicode box-drawing, pipe style, Windows `tree`, space-indented trees.
|
|
8
|
+
- Automatic indent repair (disable with `--no-fix` or the GUI checkbox).
|
|
9
|
+
- Both a GUI and a CLI.
|
|
10
|
+
- Cross-platform: Windows, macOS, Linux.
|
|
11
|
+
- User-visible strings live in `treeing/strings.json` (bootstrap errors in `treeing/strings.bootstrap.json`).
|
|
12
|
+
|
|
13
|
+
## Preview
|
|
14
|
+
|
|
15
|
+

|
|
16
|
+
|
|
17
|
+
> Screenshot: Windows, English UI, parsing a sample project tree.
|
|
18
|
+
|
|
19
|
+
## Quick start
|
|
20
|
+
|
|
21
|
+
### Install from PyPI
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
pip install treeing
|
|
25
|
+
treeing -i tree.txt -o ./out # CLI
|
|
26
|
+
treeing-gui # GUI
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
The CLI needs only the Python standard library. The GUI uses `tkinter`; on Linux install it with `sudo apt-get install python3-tk` (it ships with Python on Windows and macOS).
|
|
30
|
+
|
|
31
|
+
### Run from source
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
python -m venv .venv
|
|
35
|
+
# Windows: .\.venv\Scripts\pip install -r requirements-build.txt
|
|
36
|
+
# Unix: .venv/bin/pip install -r requirements-build.txt
|
|
37
|
+
|
|
38
|
+
python -m treeing.main # GUI
|
|
39
|
+
python -m treeing.main -i tree.txt -o ./out # CLI
|
|
40
|
+
python -m treeing.main --help # CLI help
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### Run a prebuilt executable
|
|
44
|
+
|
|
45
|
+
Prebuilt binaries are attached to each [release](https://github.com/xiao-ming-b65536/treeing/releases) (Windows, Linux, macOS ARM, macOS x86). Pick the archive for your platform (replace `vX.Y.Z` with the actual version):
|
|
46
|
+
|
|
47
|
+
| Platform | Archives |
|
|
48
|
+
|---|---|
|
|
49
|
+
| Windows | `treeing-cli-windows-vX.Y.Z.zip`, `treeing-gui-windows-vX.Y.Z.zip` |
|
|
50
|
+
| Linux | `treeing-cli-linux-vX.Y.Z.tar.gz`, `treeing-gui-linux-vX.Y.Z.tar.gz` |
|
|
51
|
+
| macOS (Apple Silicon) | `treeing-cli-macos-arm64-vX.Y.Z.tar.gz`, `treeing-gui-macos-arm64-vX.Y.Z.tar.gz` |
|
|
52
|
+
| macOS (Intel) | `treeing-cli-macos-x86_64-vX.Y.Z.tar.gz`, `treeing-gui-macos-x86_64-vX.Y.Z.tar.gz` |
|
|
53
|
+
|
|
54
|
+
CLI and GUI are packaged separately; download whichever you need. Verify against `SHA256SUMS.txt` in the same release.
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
treeing-gui # GUI — Linux / macOS
|
|
58
|
+
treeing-gui.exe # GUI — Windows
|
|
59
|
+
|
|
60
|
+
treeing-cli -i tree.txt -o ./out # CLI — Linux / macOS
|
|
61
|
+
treeing-cli.exe -i tree.txt -o ./out # CLI — Windows
|
|
62
|
+
treeing-cli --help # CLI help — Linux / macOS
|
|
63
|
+
treeing-cli.exe --help # CLI help — Windows
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
### Build executables yourself
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
pip install -r requirements-build.txt
|
|
70
|
+
python build.py --target all # outputs to dist/<platform>/
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
## Documentation
|
|
74
|
+
|
|
75
|
+
See [docs/USER_GUIDE.md](docs/USER_GUIDE.md) for a unified guide covering source runs and prebuilt executables on Windows, macOS ARM, macOS x86, and Linux.
|
|
76
|
+
|
|
77
|
+
## Legal
|
|
78
|
+
|
|
79
|
+
- **Licence** — MIT; see [LICENSE](LICENSE).
|
|
80
|
+
- **Privacy Policy** — see [PRIVACY.md](PRIVACY.md).
|
|
81
|
+
- **Terms of Use** — see [TERMS.md](TERMS.md).
|
|
82
|
+
|
|
83
|
+
## AI Disclosure
|
|
84
|
+
|
|
85
|
+
Parts of this source code were written with assistance from AI coding tools.
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "treeing"
|
|
3
|
+
version = "1.0.1"
|
|
4
|
+
description = "ASCII tree → directory/file generator"
|
|
5
|
+
readme = "README.md"
|
|
6
|
+
license = "MIT"
|
|
7
|
+
requires-python = ">=3.11"
|
|
8
|
+
authors = [
|
|
9
|
+
{name = "MING"},
|
|
10
|
+
]
|
|
11
|
+
classifiers = [
|
|
12
|
+
"Development Status :: 5 - Production/Stable",
|
|
13
|
+
"Environment :: Console",
|
|
14
|
+
"Environment :: X11 Applications",
|
|
15
|
+
"Intended Audience :: Developers",
|
|
16
|
+
"Operating System :: OS Independent",
|
|
17
|
+
"Programming Language :: Python :: 3",
|
|
18
|
+
"Programming Language :: Python :: 3.11",
|
|
19
|
+
"Programming Language :: Python :: 3.12",
|
|
20
|
+
"Programming Language :: Python :: 3.13",
|
|
21
|
+
"Programming Language :: Python :: 3.14",
|
|
22
|
+
"Topic :: Software Development :: Build Tools",
|
|
23
|
+
"Topic :: Utilities",
|
|
24
|
+
]
|
|
25
|
+
dependencies = []
|
|
26
|
+
|
|
27
|
+
[project.scripts]
|
|
28
|
+
treeing = "treeing.cli.main:cli_main"
|
|
29
|
+
treeing-gui = "treeing.gui_entry:run_gui"
|
|
30
|
+
|
|
31
|
+
[project.urls]
|
|
32
|
+
Homepage = "https://github.com/xiao-ming-b65536/treeing"
|
|
33
|
+
Source = "https://github.com/xiao-ming-b65536/treeing"
|
|
34
|
+
"Issue Tracker" = "https://github.com/xiao-ming-b65536/treeing/issues"
|
|
35
|
+
Changelog = "https://github.com/xiao-ming-b65536/treeing/blob/main/CHANGELOG.md"
|
|
36
|
+
|
|
37
|
+
[build-system]
|
|
38
|
+
requires = ["setuptools>=64"]
|
|
39
|
+
build-backend = "setuptools.build_meta"
|
|
40
|
+
|
|
41
|
+
[tool.setuptools]
|
|
42
|
+
packages = ["treeing", "treeing.cli", "treeing.core", "treeing.gui", "treeing.assets"]
|
|
43
|
+
include-package-data = true
|
|
44
|
+
|
|
45
|
+
[tool.setuptools.package-data]
|
|
46
|
+
treeing = ["strings.json", "strings.bootstrap.json", "assets/*"]
|
treeing-1.0.1/setup.cfg
ADDED
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
"""
|
|
2
|
+
treeing/cli/confirm.py
|
|
3
|
+
|
|
4
|
+
Defines the pre-write confirmation logic: interactive --confirm, headless
|
|
5
|
+
--yes, and the TREEING_YES environment variable. Provides
|
|
6
|
+
`gate_before_write` as the unified entry point, handling TTY detection,
|
|
7
|
+
confirmation prompts and mode resolution.
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
from __future__ import annotations
|
|
11
|
+
|
|
12
|
+
import os
|
|
13
|
+
import sys
|
|
14
|
+
|
|
15
|
+
from ..config import get_string
|
|
16
|
+
from .io import cli_err, cli_out, cli_warn
|
|
17
|
+
|
|
18
|
+
ENV_ASSUME_YES = 'TREEING_YES'
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def assume_yes_from_env() -> bool:
|
|
22
|
+
"""
|
|
23
|
+
Check whether the TREEING_YES environment variable is truthy (1/true/yes/on).
|
|
24
|
+
|
|
25
|
+
Used by gate_before_write to auto-confirm in non-interactive or CI
|
|
26
|
+
environments; the check is case-insensitive.
|
|
27
|
+
"""
|
|
28
|
+
val = os.environ.get(ENV_ASSUME_YES, '').strip().lower()
|
|
29
|
+
if not val:
|
|
30
|
+
return False
|
|
31
|
+
return val in ('1', 'true', 'yes', 'on')
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def is_interactive_tty() -> bool:
|
|
35
|
+
"""
|
|
36
|
+
Return whether the current session is an interactive TTY (both stdin and stderr are ttys).
|
|
37
|
+
|
|
38
|
+
Only treats the session as interactive when both are ttys; returns False
|
|
39
|
+
under pipes or redirection.
|
|
40
|
+
"""
|
|
41
|
+
return bool(sys.stdin.isatty() and sys.stderr.isatty())
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def read_yes_no(*, default: bool = False) -> bool:
|
|
45
|
+
"""
|
|
46
|
+
Read a y/n answer from the user; the default is controlled by `default`.
|
|
47
|
+
|
|
48
|
+
Windows uses msvcrt; Unix uses /dev/tty.
|
|
49
|
+
"""
|
|
50
|
+
suffix = '[Y/n] ' if default else '[y/N] '
|
|
51
|
+
cli_err(get_string('cli_confirm_prompt', suffix=suffix), end='')
|
|
52
|
+
if sys.platform == 'win32':
|
|
53
|
+
return _read_yes_no_windows(default=default)
|
|
54
|
+
return _read_yes_no_unix(default=default)
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
def _read_yes_no_windows(*, default: bool) -> bool:
|
|
58
|
+
"""
|
|
59
|
+
Read a single y/n character on Windows (no Enter needed).
|
|
60
|
+
|
|
61
|
+
Accepts only y/n; Enter falls back to the default; other keys keep waiting.
|
|
62
|
+
"""
|
|
63
|
+
import msvcrt
|
|
64
|
+
|
|
65
|
+
while True:
|
|
66
|
+
ch = msvcrt.getwch()
|
|
67
|
+
if ch in '\r\n':
|
|
68
|
+
cli_err('')
|
|
69
|
+
return default
|
|
70
|
+
lower = ch.lower()
|
|
71
|
+
if lower in ('y', 'n'):
|
|
72
|
+
cli_err(ch)
|
|
73
|
+
return lower == 'y'
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
def _read_yes_no_unix(*, default: bool) -> bool:
|
|
77
|
+
"""
|
|
78
|
+
Read a line on Unix (via /dev/tty to avoid pipe interference).
|
|
79
|
+
|
|
80
|
+
Returns the default on a blank line or read failure; only the first
|
|
81
|
+
character is consulted.
|
|
82
|
+
"""
|
|
83
|
+
try:
|
|
84
|
+
with open('/dev/tty', encoding='utf-8', errors='replace') as tty:
|
|
85
|
+
line = tty.readline()
|
|
86
|
+
except OSError:
|
|
87
|
+
return default
|
|
88
|
+
answer = line.strip().lower()
|
|
89
|
+
if not answer:
|
|
90
|
+
return default
|
|
91
|
+
return answer in ('y', 'yes')
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
def warn_confirm_ignored_on_dry_run() -> None:
|
|
95
|
+
"""
|
|
96
|
+
Warn that --confirm is ignored under --dry-run.
|
|
97
|
+
|
|
98
|
+
Because dry-run writes nothing, asking the user to confirm is pointless.
|
|
99
|
+
"""
|
|
100
|
+
cli_warn(get_string('cli_confirm_dry_run_ignored'))
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
def audit_yes_confirmed(*, path: str, node_count: int, quiet: bool) -> None:
|
|
104
|
+
"""
|
|
105
|
+
In headless mode (--yes / env), print a confirmation summary.
|
|
106
|
+
|
|
107
|
+
Even though the interactive prompt is skipped, the log still shows
|
|
108
|
+
"confirmed: N nodes will be created".
|
|
109
|
+
"""
|
|
110
|
+
if quiet:
|
|
111
|
+
return
|
|
112
|
+
cli_out(get_string('cli_confirm_yes_audit', count=node_count, path=path))
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
def prompt_generate_confirm(
|
|
116
|
+
*,
|
|
117
|
+
path: str,
|
|
118
|
+
node_count: int,
|
|
119
|
+
fail_on_conflict: bool,
|
|
120
|
+
warn_count: int,
|
|
121
|
+
) -> bool:
|
|
122
|
+
"""
|
|
123
|
+
In interactive mode, print the generation confirmation prompt and read the user's answer.
|
|
124
|
+
|
|
125
|
+
Returns True if the user confirms, False if cancelled.
|
|
126
|
+
"""
|
|
127
|
+
cli_err(get_string(
|
|
128
|
+
'cli_msg_generate_confirm',
|
|
129
|
+
path=path,
|
|
130
|
+
count=node_count,
|
|
131
|
+
conflict_hint=get_string(
|
|
132
|
+
'cli_confirm_conflict_enabled' if fail_on_conflict
|
|
133
|
+
else 'cli_confirm_conflict_disabled',
|
|
134
|
+
),
|
|
135
|
+
warn_hint=get_string(
|
|
136
|
+
'cli_confirm_warn_count', count=warn_count,
|
|
137
|
+
) if warn_count else get_string('cli_confirm_no_warnings'),
|
|
138
|
+
))
|
|
139
|
+
return read_yes_no(default=False)
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
def resolve_confirm_mode(args) -> str | None:
|
|
143
|
+
"""
|
|
144
|
+
Resolve the confirmation mode from the arguments: yes / env / interactive / None.
|
|
145
|
+
|
|
146
|
+
Priority: --yes > TREEING_YES > --confirm.
|
|
147
|
+
"""
|
|
148
|
+
if getattr(args, 'yes', False):
|
|
149
|
+
return 'yes'
|
|
150
|
+
if assume_yes_from_env():
|
|
151
|
+
return 'env'
|
|
152
|
+
if getattr(args, 'confirm', False):
|
|
153
|
+
return 'interactive'
|
|
154
|
+
return None
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
def gate_before_write(
|
|
158
|
+
args,
|
|
159
|
+
*,
|
|
160
|
+
path: str,
|
|
161
|
+
node_count: int,
|
|
162
|
+
fail_on_conflict: bool,
|
|
163
|
+
warn_count: int,
|
|
164
|
+
) -> tuple[int | None, str | None]:
|
|
165
|
+
"""
|
|
166
|
+
Pre-write confirmation entry point.
|
|
167
|
+
|
|
168
|
+
Returns (early_exit_code, confirm_mode). A non-None early_exit_code means
|
|
169
|
+
the run should exit early and skip writing.
|
|
170
|
+
"""
|
|
171
|
+
if args.dry_run:
|
|
172
|
+
if args.confirm:
|
|
173
|
+
warn_confirm_ignored_on_dry_run()
|
|
174
|
+
return None, None
|
|
175
|
+
|
|
176
|
+
mode = resolve_confirm_mode(args)
|
|
177
|
+
if mode in ('yes', 'env'):
|
|
178
|
+
audit_yes_confirmed(path=path, node_count=node_count, quiet=args.quiet)
|
|
179
|
+
return None, mode
|
|
180
|
+
|
|
181
|
+
if not args.confirm:
|
|
182
|
+
return None, None
|
|
183
|
+
|
|
184
|
+
if not is_interactive_tty():
|
|
185
|
+
cli_err(get_string('cli_error_confirm_not_tty'))
|
|
186
|
+
return 1, None
|
|
187
|
+
|
|
188
|
+
if not prompt_generate_confirm(
|
|
189
|
+
path=path,
|
|
190
|
+
node_count=node_count,
|
|
191
|
+
fail_on_conflict=fail_on_conflict,
|
|
192
|
+
warn_count=warn_count,
|
|
193
|
+
):
|
|
194
|
+
cli_err(get_string('cli_confirm_cancelled'))
|
|
195
|
+
return 0, None
|
|
196
|
+
|
|
197
|
+
return None, 'interactive'
|