rtftree 1.0.0__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.
@@ -0,0 +1,264 @@
1
+ Metadata-Version: 2.4
2
+ Name: rtftree
3
+ Version: 1.0.0
4
+ Summary: Terraform Project Tree Generator CLI Tool
5
+ Author: Ritesh Sharma
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/riteshatri/tftree
8
+ Requires-Python: >=3.8
9
+ Description-Content-Type: text/markdown
10
+ License-File: LICENSE
11
+ Requires-Dist: rich>=13.0.0
12
+ Dynamic: license-file
13
+
14
+ # šŸš€ TFTree --- Terraform Project Tree Generator CLI
15
+
16
+ > A professional-grade CLI tool to generate clean, structured, and
17
+ > shareable Terraform project trees --- with smart exclude support,
18
+ > colored output, and Markdown export.
19
+
20
+ ------------------------------------------------------------------------
21
+
22
+ ![Python](https://img.shields.io/badge/python-3.8+-blue.svg)
23
+ ![License](https://img.shields.io/badge/license-MIT-green.svg)
24
+ ![CLI](https://img.shields.io/badge/type-CLI-orange.svg)
25
+ ![Terraform](https://img.shields.io/badge/terraform-supported-purple.svg)
26
+
27
+ ------------------------------------------------------------------------
28
+
29
+ ## šŸ“Œ Why TFTree?
30
+
31
+ Terraform projects often include:
32
+
33
+ - `.terraform/`
34
+ - `terraform.tfstate`
35
+ - `.terraform.lock.hcl`
36
+ - `.git/`
37
+ - Provider binaries
38
+ - Deeply nested modules
39
+
40
+ Sharing structure manually becomes messy and unreadable.
41
+
42
+ šŸ”„ **TFTree solves this problem** by generating a clean, structured tree
43
+ view of your infrastructure project --- ready for documentation,
44
+ sharing, and audits.
45
+
46
+ ------------------------------------------------------------------------
47
+
48
+ # ✨ Features
49
+
50
+ āœ… Beautiful tree-style output\
51
+ āœ… šŸŽØ Colored CLI output\
52
+ āœ… Optional file content preview\
53
+ āœ… Smart exclude support (like `.gitignore`)\
54
+ āœ… Wildcard pattern support (`*.exe`, `.terraform*`)\
55
+ āœ… Exclude via file (`--exclude-file`)\
56
+ āœ… Markdown export mode (`--markdown`)\
57
+ āœ… Output to file (`-o`)\
58
+ āœ… Lightweight & Fast\
59
+ āœ… Installable as a CLI tool
60
+
61
+ ------------------------------------------------------------------------
62
+
63
+ # šŸ“¦ Installation
64
+
65
+ ## šŸ”¹ Local Install (Development Mode)
66
+
67
+ ``` bash
68
+ python -m pip install -e .
69
+ ```
70
+
71
+ ## šŸ”¹ Standard Install
72
+
73
+ ``` bash
74
+ python -m pip install .
75
+ ```
76
+
77
+ ## šŸ”¹ After PyPI Publish (Global Install)
78
+
79
+ ``` bash
80
+ pip install tftree
81
+ ```
82
+
83
+ ------------------------------------------------------------------------
84
+
85
+ # šŸš€ Usage
86
+
87
+ ## Basic Usage
88
+
89
+ ``` bash
90
+ tftree <project-folder>
91
+ ```
92
+
93
+ Example:
94
+
95
+ ``` bash
96
+ tftree .
97
+ ```
98
+
99
+ ------------------------------------------------------------------------
100
+
101
+ ## šŸ“ Structure Only (No File Content)
102
+
103
+ ``` bash
104
+ tftree . --no-content
105
+ ```
106
+
107
+ ------------------------------------------------------------------------
108
+
109
+ ## 🚫 Exclude Files & Folders
110
+
111
+ ### Direct Patterns
112
+
113
+ ``` bash
114
+ tftree . --exclude .terraform .git terraform.tfstate *.exe
115
+ ```
116
+
117
+ ### Using Exclude File
118
+
119
+ ``` bash
120
+ tftree . --exclude-file exclude.txt
121
+ ```
122
+
123
+ Example `exclude.txt`:
124
+
125
+ .terraform
126
+ .git
127
+ terraform.tfstate
128
+ *.exe
129
+ .terraform.lock.hcl
130
+
131
+ Supported:
132
+
133
+ - Exact file names
134
+ - Folder names
135
+ - Wildcards
136
+
137
+ ------------------------------------------------------------------------
138
+
139
+ ## šŸ’¾ Save Output to File
140
+
141
+ ``` bash
142
+ tftree . -o infra_tree.txt
143
+ ```
144
+
145
+ ------------------------------------------------------------------------
146
+
147
+ ## šŸ“ Markdown Export Mode
148
+
149
+ Generate Markdown-ready structure:
150
+
151
+ ``` bash
152
+ tftree . --markdown -o structure.md
153
+ ```
154
+
155
+ Perfect for:
156
+
157
+ - GitHub documentation
158
+ - Wiki pages
159
+ - Confluence
160
+ - Client documentation
161
+
162
+ ------------------------------------------------------------------------
163
+
164
+ # šŸ–„ Example Output
165
+
166
+ šŸ“ Terraform Project: infra
167
+
168
+ ā”œā”€ā”€ šŸ“ modules
169
+ │ ā”œā”€ā”€ šŸ“„ main.tf
170
+ │ │ resource "azurerm_resource_group" "rg" {
171
+ │ │ name = "example"
172
+ │ │ location = "East US"
173
+ │ │ }
174
+ │ └── šŸ“„ variables.tf
175
+ │ variable "location" {
176
+ │ type = string
177
+ │ }
178
+ └── šŸ“„ provider.tf
179
+
180
+ ------------------------------------------------------------------------
181
+
182
+ # āš™ļø CLI Options
183
+
184
+ Option Description
185
+ ------------------ ------------------------------------
186
+ `--no-content` Show only folder/file structure
187
+ `--exclude` Space-separated patterns to ignore
188
+ `--exclude-file` Load exclude patterns from file
189
+ `--markdown` Export output in Markdown format
190
+ `-o`, `--output` Write output to file
191
+
192
+ ------------------------------------------------------------------------
193
+
194
+ # šŸ— Project Structure
195
+
196
+ tftree/
197
+ │
198
+ ā”œā”€ā”€ tftree/
199
+ │ ā”œā”€ā”€ __init__.py
200
+ │ └── cli.py
201
+ │
202
+ ā”œā”€ā”€ pyproject.toml
203
+ └── README.md
204
+
205
+ ------------------------------------------------------------------------
206
+
207
+ # šŸ”„ DevOps Use Cases
208
+
209
+ - Share Terraform structure in tickets
210
+ - Infrastructure documentation
211
+ - CI/CD pipeline documentation
212
+ - Client infrastructure overview
213
+ - Audit reporting
214
+ - Pre-deployment reviews
215
+
216
+ ------------------------------------------------------------------------
217
+
218
+ # šŸŒ PyPI Publishing
219
+
220
+ Once published to PyPI, anyone can install globally:
221
+
222
+ ``` bash
223
+ pip install tftree
224
+ ```
225
+
226
+ This makes TFTree a globally accessible DevOps utility tool.
227
+
228
+ ------------------------------------------------------------------------
229
+
230
+ # 🧠 Roadmap
231
+
232
+ - `.treeignore` auto-detection
233
+ - `--max-depth` option
234
+ - Terraform-only mode (`*.tf`)
235
+ - JSON export
236
+ - GitHub Action integration
237
+ - Auto documentation mode
238
+
239
+ ------------------------------------------------------------------------
240
+
241
+ # šŸ‘Øā€šŸ’» Author
242
+
243
+ **Ritesh Sharma**\
244
+ DevOps \| Azure \| Terraform \| Kubernetes
245
+
246
+ ------------------------------------------------------------------------
247
+
248
+ # šŸ“„ License
249
+
250
+ MIT License
251
+
252
+ ------------------------------------------------------------------------
253
+
254
+ # ⭐ Support
255
+
256
+ If you find this tool useful:
257
+
258
+ ⭐ Star the repository\
259
+ šŸš€ Share with DevOps community\
260
+ šŸ›  Contribute improvements
261
+
262
+ ------------------------------------------------------------------------
263
+
264
+ > Built with ā¤ļø for DevOps Engineers
@@ -0,0 +1,8 @@
1
+ rtftree-1.0.0.dist-info/licenses/LICENSE,sha256=gvNa--QRlkoYNwmgW3w6qUipDSAcRviLjzpNcT1m2-8,1088
2
+ tftree/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
+ tftree/cli.py,sha256=d5vgYqDPUrRGb44XIUwkXdFiC1fWV27XEscK5OlgI3g,6315
4
+ rtftree-1.0.0.dist-info/METADATA,sha256=9vRh6TD_ZyE5ExL-K0iZ2H6f7I6Yhz_P2GF47FnJVgw,6201
5
+ rtftree-1.0.0.dist-info/WHEEL,sha256=YCfwYGOYMi5Jhw2fU4yNgwErybb2IX5PEwBKV4ZbdBo,91
6
+ rtftree-1.0.0.dist-info/entry_points.txt,sha256=X6yqzcZFuyPTVZWslEoF4Z8iJodRfMuooU4eznT2iCw,43
7
+ rtftree-1.0.0.dist-info/top_level.txt,sha256=TdI56UgqazfjvwXhr86LbN-cg9672r-1kT41wJJrxTI,7
8
+ rtftree-1.0.0.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (82.0.0)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ tftree = tftree.cli:main
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Riteshatri
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.
@@ -0,0 +1 @@
1
+ tftree
tftree/__init__.py ADDED
File without changes
tftree/cli.py ADDED
@@ -0,0 +1,212 @@
1
+ import os
2
+ import argparse
3
+ import fnmatch
4
+ from rich.console import Console
5
+ from rich.tree import Tree
6
+ from rich.markdown import Markdown
7
+
8
+
9
+ # ---------------------------------------
10
+ # Utility Functions
11
+ # ---------------------------------------
12
+
13
+ def load_exclude_patterns(exclude_list, exclude_file):
14
+ patterns = exclude_list.copy()
15
+
16
+ if exclude_file and os.path.exists(exclude_file):
17
+ with open(exclude_file, "r", encoding="utf-8") as f:
18
+ for line in f:
19
+ line = line.strip()
20
+ if line and not line.startswith("#"):
21
+ patterns.append(line)
22
+
23
+ return patterns
24
+
25
+
26
+ def should_exclude(name, patterns):
27
+ for pattern in patterns:
28
+ if fnmatch.fnmatch(name, pattern):
29
+ return True
30
+ return False
31
+
32
+
33
+ # ---------------------------------------
34
+ # Tree Builder
35
+ # ---------------------------------------
36
+
37
+ def build_tree(directory, parent_tree, show_content=True, patterns=None):
38
+ patterns = patterns or []
39
+
40
+ try:
41
+ items = sorted(os.listdir(directory))
42
+ except PermissionError:
43
+ parent_tree.add("[red]Permission Denied")
44
+ return
45
+
46
+ for item in items:
47
+ if should_exclude(item, patterns):
48
+ continue
49
+
50
+ path = os.path.join(directory, item)
51
+
52
+ if os.path.isdir(path):
53
+ branch = parent_tree.add(f"[bold blue]šŸ“ {item}")
54
+ build_tree(path, branch, show_content, patterns)
55
+ else:
56
+ file_branch = parent_tree.add(f"[green]šŸ“„ {item}")
57
+
58
+ if show_content:
59
+ try:
60
+ with open(path, "r", encoding="utf-8") as f:
61
+ lines = f.readlines()
62
+ if not lines:
63
+ file_branch.add("[dim][empty file]")
64
+ else:
65
+ for line in lines[:20]:
66
+ file_branch.add(f"[dim]{line.rstrip()}")
67
+ except Exception:
68
+ file_branch.add("[red][Error reading file]")
69
+
70
+
71
+ # ---------------------------------------
72
+ # Markdown Builder
73
+ # ---------------------------------------
74
+
75
+ def build_markdown(directory, show_content=True, patterns=None, prefix=""):
76
+ patterns = patterns or []
77
+ output = ""
78
+
79
+ try:
80
+ items = sorted(os.listdir(directory))
81
+ except PermissionError:
82
+ return ""
83
+
84
+ for item in items:
85
+ if should_exclude(item, patterns):
86
+ continue
87
+
88
+ path = os.path.join(directory, item)
89
+
90
+ if os.path.isdir(path):
91
+ output += f"{prefix}- šŸ“ **{item}**\n"
92
+ output += build_markdown(path, show_content, patterns, prefix + " ")
93
+ else:
94
+ output += f"{prefix}- šŸ“„ `{item}`\n"
95
+
96
+ if show_content:
97
+ try:
98
+ with open(path, "r", encoding="utf-8") as f:
99
+ lines = f.readlines()
100
+ if lines:
101
+ output += f"{prefix} ```\n"
102
+ for line in lines[:20]:
103
+ output += f"{prefix} {line}"
104
+ output += f"{prefix} ```\n"
105
+ else:
106
+ output += f"{prefix} `[empty file]`\n"
107
+ except:
108
+ output += f"{prefix} `[Error reading file]`\n"
109
+
110
+ return output
111
+
112
+
113
+ # ---------------------------------------
114
+ # Main CLI
115
+ # ---------------------------------------
116
+
117
+ def main():
118
+
119
+ parser = argparse.ArgumentParser(
120
+ description="Terraform Tree CLI Tool",
121
+ formatter_class=argparse.RawTextHelpFormatter
122
+ )
123
+
124
+ parser.add_argument(
125
+ "folder",
126
+ help="Project folder path"
127
+ )
128
+
129
+ parser.add_argument(
130
+ "-o", "--output",
131
+ help="Output file path"
132
+ )
133
+
134
+ parser.add_argument(
135
+ "--exclude",
136
+ nargs="*",
137
+ default=[],
138
+ metavar="PATTERN",
139
+ help=(
140
+ "Exclude files/folders using names or wildcards.\n\n"
141
+ "Examples:\n"
142
+ " --exclude .terraform .git terraform.tfstate\n"
143
+ " --exclude *.exe *.lock.hcl\n\n"
144
+ "Supported:\n"
145
+ " • Exact file names (terraform.tfstate)\n"
146
+ " • Folder names (.terraform)\n"
147
+ " • Wildcards (*.exe, .terraform*)\n"
148
+ ),
149
+ )
150
+
151
+ parser.add_argument(
152
+ "--exclude-file",
153
+ help=(
154
+ "Path to file containing exclude patterns.\n"
155
+ "One pattern per line.\n"
156
+ "Lines starting with # are ignored."
157
+ )
158
+ )
159
+
160
+ parser.add_argument(
161
+ "--no-content",
162
+ action="store_true",
163
+ help="Show only folder/file structure (no file content preview)"
164
+ )
165
+
166
+ parser.add_argument(
167
+ "--markdown",
168
+ action="store_true",
169
+ help="Export output in Markdown format"
170
+ )
171
+
172
+ args = parser.parse_args()
173
+
174
+ patterns = load_exclude_patterns(args.exclude, args.exclude_file)
175
+ folder_name = os.path.basename(os.path.abspath(args.folder))
176
+
177
+ # MARKDOWN MODE
178
+ if args.markdown:
179
+ md_content = f"# šŸ“ Terraform Project: {folder_name}\n\n"
180
+ md_content += build_markdown(
181
+ args.folder,
182
+ show_content=not args.no_content,
183
+ patterns=patterns,
184
+ )
185
+
186
+ if args.output:
187
+ with open(args.output, "w", encoding="utf-8") as f:
188
+ f.write(md_content)
189
+ print(f"\nāœ… Markdown file written to: {args.output}")
190
+ else:
191
+ console = Console()
192
+ console.print(Markdown(md_content))
193
+ return
194
+
195
+ # TREE MODE
196
+ tree = Tree(f"[bold cyan]šŸ“ Terraform Project: {folder_name}")
197
+
198
+ build_tree(
199
+ args.folder,
200
+ tree,
201
+ show_content=not args.no_content,
202
+ patterns=patterns,
203
+ )
204
+
205
+ if args.output:
206
+ with open(args.output, "w", encoding="utf-8") as f:
207
+ file_console = Console(file=f, force_terminal=False, color_system=None)
208
+ file_console.print(tree)
209
+ print(f"\nāœ… File written to: {args.output}")
210
+ else:
211
+ console = Console()
212
+ console.print(tree)