abitree 0.1.0__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.
abitree-0.1.0/PKG-INFO ADDED
@@ -0,0 +1,87 @@
1
+ Metadata-Version: 2.4
2
+ Name: abitree
3
+ Version: 0.1.0
4
+ Summary: Generate beautiful file trees for your README
5
+ Author: Abidit Shrestha
6
+ License: MIT
7
+ Keywords: cli,tree,readme,file-tree,developer-tools
8
+ Classifier: Programming Language :: Python :: 3
9
+ Classifier: License :: OSI Approved :: MIT License
10
+ Classifier: Operating System :: OS Independent
11
+ Classifier: Environment :: Console
12
+ Requires-Python: >=3.9
13
+ Description-Content-Type: text/markdown
14
+
15
+ # 🌳 abitree
16
+
17
+ Generate beautiful, icon-rich file trees for your README — instantly.
18
+
19
+ ```
20
+ 📁 my-project/
21
+ ├── 📁 src/
22
+ │ ├── 🐍 main.py
23
+ │ ├── ⚛️ App.tsx
24
+ │ └── 🎨 styles.css
25
+ ├── 📦 package.json
26
+ ├── 🐳 Dockerfile
27
+ └── 📝 README.md
28
+ ```
29
+
30
+ ## Installation
31
+
32
+ ```bash
33
+ pip install abitree
34
+ ```
35
+
36
+ ## Usage
37
+
38
+ ```bash
39
+ # Current directory
40
+ abitree
41
+
42
+ # Specific path
43
+ abitree ./my-project
44
+
45
+ # Limit depth
46
+ abitree -L 2
47
+
48
+ # Output to file
49
+ abitree -o structure.md
50
+
51
+ # Wrap in markdown code block
52
+ abitree --md
53
+
54
+ # Directories only
55
+ abitree --dirs-only
56
+
57
+ # Ignore extra folders
58
+ abitree -i dist,build,.cache
59
+
60
+ # No icons (plain text)
61
+ abitree --no-icons
62
+ ```
63
+
64
+ ## Options
65
+
66
+ | Flag | Description |
67
+ |------|-------------|
68
+ | `path` | Directory to scan (default: `.`) |
69
+ | `-L, --level` | Max depth |
70
+ | `-o, --output` | Write output to file |
71
+ | `-i, --ignore` | Comma-separated ignore list |
72
+ | `--dirs-only` | Show directories only |
73
+ | `--no-icons` | Disable icons |
74
+ | `--no-default-ignore` | Don't ignore `.git`, `node_modules`, etc. |
75
+ | `--md` | Wrap output in markdown code block |
76
+
77
+ ## Default ignored
78
+
79
+ `.git`, `__pycache__`, `.DS_Store`, `.idea`, `.vscode`, `node_modules`
80
+
81
+ ## Author
82
+
83
+ Built by [Abidit Shrestha](https://github.com/abiditshrestha)
84
+
85
+ ## License
86
+
87
+ MIT
@@ -0,0 +1,73 @@
1
+ # 🌳 abitree
2
+
3
+ Generate beautiful, icon-rich file trees for your README — instantly.
4
+
5
+ ```
6
+ 📁 my-project/
7
+ ├── 📁 src/
8
+ │ ├── 🐍 main.py
9
+ │ ├── ⚛️ App.tsx
10
+ │ └── 🎨 styles.css
11
+ ├── 📦 package.json
12
+ ├── 🐳 Dockerfile
13
+ └── 📝 README.md
14
+ ```
15
+
16
+ ## Installation
17
+
18
+ ```bash
19
+ pip install abitree
20
+ ```
21
+
22
+ ## Usage
23
+
24
+ ```bash
25
+ # Current directory
26
+ abitree
27
+
28
+ # Specific path
29
+ abitree ./my-project
30
+
31
+ # Limit depth
32
+ abitree -L 2
33
+
34
+ # Output to file
35
+ abitree -o structure.md
36
+
37
+ # Wrap in markdown code block
38
+ abitree --md
39
+
40
+ # Directories only
41
+ abitree --dirs-only
42
+
43
+ # Ignore extra folders
44
+ abitree -i dist,build,.cache
45
+
46
+ # No icons (plain text)
47
+ abitree --no-icons
48
+ ```
49
+
50
+ ## Options
51
+
52
+ | Flag | Description |
53
+ |------|-------------|
54
+ | `path` | Directory to scan (default: `.`) |
55
+ | `-L, --level` | Max depth |
56
+ | `-o, --output` | Write output to file |
57
+ | `-i, --ignore` | Comma-separated ignore list |
58
+ | `--dirs-only` | Show directories only |
59
+ | `--no-icons` | Disable icons |
60
+ | `--no-default-ignore` | Don't ignore `.git`, `node_modules`, etc. |
61
+ | `--md` | Wrap output in markdown code block |
62
+
63
+ ## Default ignored
64
+
65
+ `.git`, `__pycache__`, `.DS_Store`, `.idea`, `.vscode`, `node_modules`
66
+
67
+ ## Author
68
+
69
+ Built by [Abidit Shrestha](https://github.com/abiditshrestha)
70
+
71
+ ## License
72
+
73
+ MIT
@@ -0,0 +1 @@
1
+ __version__ = '0.1.0'
@@ -0,0 +1,98 @@
1
+ import argparse
2
+ import sys
3
+ from .tree import generate_tree
4
+
5
+ DEFAULT_IGNORE = [".git", "__pycache__", ".DS_Store", ".idea", ".vscode", "node_modules"]
6
+
7
+
8
+ def main():
9
+ parser = argparse.ArgumentParser(
10
+ prog="abitree",
11
+ description="🌳 abitree — generate beautiful file trees for your README",
12
+ )
13
+
14
+ parser.add_argument(
15
+ "path",
16
+ nargs="?",
17
+ default=".",
18
+ help="Path to directory (default: current directory)",
19
+ )
20
+
21
+ parser.add_argument(
22
+ "-L", "--level",
23
+ type=int,
24
+ default=None,
25
+ metavar="DEPTH",
26
+ help="Max depth of the tree",
27
+ )
28
+
29
+ parser.add_argument(
30
+ "-o", "--output",
31
+ type=str,
32
+ default=None,
33
+ metavar="FILE",
34
+ help="Output to a file (e.g. README.md)",
35
+ )
36
+
37
+ parser.add_argument(
38
+ "-i", "--ignore",
39
+ type=str,
40
+ default=None,
41
+ metavar="PATTERNS",
42
+ help="Comma-separated list of names to ignore (e.g. node_modules,.git)",
43
+ )
44
+
45
+ parser.add_argument(
46
+ "--dirs-only",
47
+ action="store_true",
48
+ help="Show directories only",
49
+ )
50
+
51
+ parser.add_argument(
52
+ "--no-icons",
53
+ action="store_true",
54
+ help="Disable icons (plain text output)",
55
+ )
56
+
57
+ parser.add_argument(
58
+ "--no-default-ignore",
59
+ action="store_true",
60
+ help="Disable default ignored folders (.git, node_modules, etc.)",
61
+ )
62
+
63
+ parser.add_argument(
64
+ "--md",
65
+ action="store_true",
66
+ help="Wrap output in a markdown code block",
67
+ )
68
+
69
+ args = parser.parse_args()
70
+
71
+ # Build ignore list
72
+ ignore = [] if args.no_default_ignore else list(DEFAULT_IGNORE)
73
+ if args.ignore:
74
+ ignore += [i.strip() for i in args.ignore.split(",")]
75
+
76
+ tree = generate_tree(
77
+ path=args.path,
78
+ max_depth=args.level,
79
+ ignore=ignore,
80
+ dirs_only=args.dirs_only,
81
+ use_icons=not args.no_icons,
82
+ )
83
+
84
+ if args.md:
85
+ output = f"```\n{tree}\n```"
86
+ else:
87
+ output = tree
88
+
89
+ if args.output:
90
+ with open(args.output, "w") as f:
91
+ f.write(output + "\n")
92
+ print(f"✅ Tree written to {args.output}")
93
+ else:
94
+ print(output)
95
+
96
+
97
+ if __name__ == "__main__":
98
+ main()
@@ -0,0 +1,272 @@
1
+ ICONS = {
2
+ # Folders
3
+ "__folder__": "📁",
4
+
5
+ # Python
6
+ ".py": "🐍",
7
+ ".pyw": "🐍",
8
+ ".ipynb": "📓",
9
+ ".pyi": "🐍",
10
+ ".pyc": "🐍",
11
+
12
+ # JavaScript / TypeScript
13
+ ".js": "🟨",
14
+ ".mjs": "🟨",
15
+ ".cjs": "🟨",
16
+ ".ts": "🔷",
17
+ ".mts": "🔷",
18
+ ".cts": "🔷",
19
+ ".jsx": "⚛️",
20
+ ".tsx": "⚛️",
21
+
22
+ # Web
23
+ ".html": "🌐",
24
+ ".htm": "🌐",
25
+ ".css": "🎨",
26
+ ".scss": "🎨",
27
+ ".sass": "🎨",
28
+ ".less": "🎨",
29
+ ".styl": "🎨",
30
+
31
+ # Frameworks / Components
32
+ ".vue": "💚",
33
+ ".svelte": "🔥",
34
+ ".astro": "🚀",
35
+
36
+ # Rust
37
+ ".rs": "🦀",
38
+ ".toml": "⚙️",
39
+
40
+ # Go
41
+ ".go": "🐹",
42
+
43
+ # C / C++
44
+ ".c": "🔵",
45
+ ".h": "🔵",
46
+ ".cpp": "🔵",
47
+ ".cc": "🔵",
48
+ ".cxx": "🔵",
49
+ ".hpp": "🔵",
50
+ ".hxx": "🔵",
51
+
52
+ # Java / JVM
53
+ ".java": "☕",
54
+ ".class": "☕",
55
+ ".jar": "☕",
56
+ ".kt": "🟣",
57
+ ".kts": "🟣",
58
+ ".scala": "🔴",
59
+ ".groovy": "🟢",
60
+ ".gradle": "🟢",
61
+
62
+ # C# / .NET
63
+ ".cs": "🟦",
64
+ ".csx": "🟦",
65
+ ".vb": "🟦",
66
+ ".fs": "🟦",
67
+ ".fsx": "🟦",
68
+
69
+ # Ruby
70
+ ".rb": "💎",
71
+ ".erb": "💎",
72
+ ".gemspec": "💎",
73
+
74
+ # PHP
75
+ ".php": "🐘",
76
+ ".phtml": "🐘",
77
+
78
+ # Swift
79
+ ".swift": "🍎",
80
+
81
+ # Dart / Flutter
82
+ ".dart": "🎯",
83
+
84
+ # Lua
85
+ ".lua": "🌙",
86
+
87
+ # Shell / Bash
88
+ ".sh": "🐚",
89
+ ".bash": "🐚",
90
+ ".zsh": "🐚",
91
+ ".fish": "🐚",
92
+ ".ps1": "🪟",
93
+ ".psm1": "🪟",
94
+ ".bat": "🪟",
95
+ ".cmd": "🪟",
96
+
97
+ # R
98
+ ".r": "📊",
99
+ ".R": "📊",
100
+ ".rmd": "📊",
101
+ ".Rmd": "📊",
102
+
103
+ # Julia
104
+ ".jl": "🔵",
105
+
106
+ # Elixir / Erlang
107
+ ".ex": "💜",
108
+ ".exs": "💜",
109
+ ".erl": "💜",
110
+ ".hrl": "💜",
111
+
112
+ # Haskell
113
+ ".hs": "🟣",
114
+ ".lhs": "🟣",
115
+
116
+ # Clojure
117
+ ".clj": "🟢",
118
+ ".cljs": "🟢",
119
+ ".cljc": "🟢",
120
+
121
+ # Nim
122
+ ".nim": "🟡",
123
+
124
+ # Zig
125
+ ".zig": "🟠",
126
+
127
+ # Config / Infra
128
+ ".json": "📦",
129
+ ".jsonc": "📦",
130
+ ".json5": "📦",
131
+ ".yaml": "🔧",
132
+ ".yml": "🔧",
133
+ ".xml": "📄",
134
+ ".toml": "⚙️",
135
+ ".ini": "⚙️",
136
+ ".cfg": "⚙️",
137
+ ".conf": "⚙️",
138
+ ".config": "⚙️",
139
+ ".env": "🔒",
140
+ ".env.local": "🔒",
141
+ ".env.example": "🔒",
142
+
143
+ # Docker
144
+ "Dockerfile": "🐳",
145
+ ".dockerignore": "🐳",
146
+ "docker-compose.yml": "🐳",
147
+ "docker-compose.yaml": "🐳",
148
+
149
+ # Kubernetes
150
+ "k8s": "☸️",
151
+
152
+ # CI/CD
153
+ ".github": "🐙",
154
+ ".gitlab-ci.yml": "🦊",
155
+ "Jenkinsfile": "🔵",
156
+ ".circleci": "⭕",
157
+ ".travis.yml": "🔨",
158
+
159
+ # Package managers
160
+ "package.json": "📦",
161
+ "package-lock.json": "🔒",
162
+ "yarn.lock": "🔒",
163
+ "pnpm-lock.yaml": "🔒",
164
+ "Cargo.toml": "⚙️",
165
+ "Cargo.lock": "🔒",
166
+ "go.mod": "🐹",
167
+ "go.sum": "🔒",
168
+ "Gemfile": "💎",
169
+ "Gemfile.lock": "🔒",
170
+ "requirements.txt": "🐍",
171
+ "pyproject.toml": "🐍",
172
+ "setup.py": "🐍",
173
+ "setup.cfg": "🐍",
174
+ "Pipfile": "🐍",
175
+ "Pipfile.lock": "🔒",
176
+ "poetry.lock": "🔒",
177
+ "composer.json": "🐘",
178
+ "composer.lock": "🔒",
179
+ "pubspec.yaml": "🎯",
180
+ "pubspec.lock": "🔒",
181
+
182
+ # Docs
183
+ ".md": "📝",
184
+ ".mdx": "📝",
185
+ ".rst": "📝",
186
+ ".txt": "📄",
187
+ ".pdf": "📕",
188
+ ".doc": "📘",
189
+ ".docx": "📘",
190
+
191
+ # Data
192
+ ".csv": "📊",
193
+ ".tsv": "📊",
194
+ ".sql": "🗄️",
195
+ ".db": "🗄️",
196
+ ".sqlite": "🗄️",
197
+ ".sqlite3": "🗄️",
198
+ ".graphql": "🔺",
199
+ ".gql": "🔺",
200
+ ".proto": "📡",
201
+
202
+ # Media
203
+ ".png": "🖼️",
204
+ ".jpg": "🖼️",
205
+ ".jpeg": "🖼️",
206
+ ".gif": "🖼️",
207
+ ".svg": "🎨",
208
+ ".ico": "🖼️",
209
+ ".webp": "🖼️",
210
+ ".mp4": "🎥",
211
+ ".mp3": "🎵",
212
+ ".wav": "🎵",
213
+ ".woff": "🔤",
214
+ ".woff2": "🔤",
215
+ ".ttf": "🔤",
216
+ ".otf": "🔤",
217
+
218
+ # Git
219
+ ".gitignore": "🙈",
220
+ ".gitattributes": "🙈",
221
+ ".gitmodules": "🙈",
222
+
223
+ # Editor configs
224
+ ".editorconfig": "✏️",
225
+ ".eslintrc": "🔍",
226
+ ".eslintignore": "🔍",
227
+ ".prettierrc": "💅",
228
+ ".prettierignore": "💅",
229
+ ".stylelintrc": "💅",
230
+ ".babelrc": "🔄",
231
+ "babel.config.js": "🔄",
232
+ "webpack.config.js": "📦",
233
+ "vite.config.js": "⚡",
234
+ "vite.config.ts": "⚡",
235
+ "tailwind.config.js": "🌊",
236
+ "tailwind.config.ts": "🌊",
237
+ "tsconfig.json": "🔷",
238
+ "jsconfig.json": "🟨",
239
+
240
+ # Makefile / Build
241
+ "Makefile": "🔨",
242
+ "makefile": "🔨",
243
+ "CMakeLists.txt": "🔨",
244
+ "Taskfile.yml": "🔨",
245
+
246
+ # Notebooks / misc
247
+ ".ipynb": "📓",
248
+ ".http": "🌐",
249
+ ".rest": "🌐",
250
+ ".log": "📋",
251
+ ".lock": "🔒",
252
+ ".zip": "🗜️",
253
+ ".tar": "🗜️",
254
+ ".gz": "🗜️",
255
+ ".rar": "🗜️",
256
+
257
+ # Default
258
+ "__default__": "📄",
259
+ }
260
+
261
+
262
+ def get_icon(name: str, is_dir: bool = False) -> str:
263
+ if is_dir:
264
+ return ICONS["__folder__"]
265
+
266
+ # Check full filename first (e.g. Dockerfile, Makefile)
267
+ if name in ICONS:
268
+ return ICONS[name]
269
+
270
+ # Check extension
271
+ ext = "." + name.rsplit(".", 1)[-1] if "." in name else ""
272
+ return ICONS.get(ext, ICONS["__default__"])
@@ -0,0 +1,82 @@
1
+ import os
2
+ from .icons import get_icon
3
+
4
+
5
+ def build_tree(
6
+ root: str,
7
+ prefix: str = "",
8
+ max_depth: int = None,
9
+ current_depth: int = 0,
10
+ ignore: list = None,
11
+ dirs_only: bool = False,
12
+ use_icons: bool = True,
13
+ ) -> list:
14
+ if ignore is None:
15
+ ignore = []
16
+
17
+ if max_depth is not None and current_depth >= max_depth:
18
+ return []
19
+
20
+ try:
21
+ entries = sorted(os.scandir(root), key=lambda e: (not e.is_dir(), e.name.lower()))
22
+ except (PermissionError, OSError):
23
+ return []
24
+
25
+ # Skip symlinks that point to directories to avoid infinite loops
26
+ entries = [e for e in entries if not (e.is_symlink() and e.is_dir())]
27
+
28
+ # Filter ignored
29
+ entries = [e for e in entries if e.name not in ignore]
30
+
31
+ # Filter files if dirs only
32
+ if dirs_only:
33
+ entries = [e for e in entries if e.is_dir()]
34
+
35
+ lines = []
36
+ for i, entry in enumerate(entries):
37
+ is_last = i == len(entries) - 1
38
+ connector = "└── " if is_last else "├── "
39
+ extension = " " if is_last else "│ "
40
+
41
+ icon = get_icon(entry.name, entry.is_dir()) + " " if use_icons else ""
42
+ trail = "/" if entry.is_dir() else ""
43
+
44
+ lines.append(f"{prefix}{connector}{icon}{entry.name}{trail}")
45
+
46
+ if entry.is_dir():
47
+ lines.extend(
48
+ build_tree(
49
+ root=entry.path,
50
+ prefix=prefix + extension,
51
+ max_depth=max_depth,
52
+ current_depth=current_depth + 1,
53
+ ignore=ignore,
54
+ dirs_only=dirs_only,
55
+ use_icons=use_icons,
56
+ )
57
+ )
58
+
59
+ return lines
60
+
61
+
62
+ def generate_tree(
63
+ path: str = ".",
64
+ max_depth: int = None,
65
+ ignore: list = None,
66
+ dirs_only: bool = False,
67
+ use_icons: bool = True,
68
+ ) -> str:
69
+ path = os.path.abspath(path)
70
+ root_name = os.path.basename(path)
71
+ icon = get_icon(root_name, is_dir=True) + " " if use_icons else ""
72
+
73
+ lines = [f"{icon}{root_name}/"]
74
+ lines += build_tree(
75
+ root=path,
76
+ max_depth=max_depth,
77
+ ignore=ignore or [],
78
+ dirs_only=dirs_only,
79
+ use_icons=use_icons,
80
+ )
81
+
82
+ return "\n".join(lines)
@@ -0,0 +1,87 @@
1
+ Metadata-Version: 2.4
2
+ Name: abitree
3
+ Version: 0.1.0
4
+ Summary: Generate beautiful file trees for your README
5
+ Author: Abidit Shrestha
6
+ License: MIT
7
+ Keywords: cli,tree,readme,file-tree,developer-tools
8
+ Classifier: Programming Language :: Python :: 3
9
+ Classifier: License :: OSI Approved :: MIT License
10
+ Classifier: Operating System :: OS Independent
11
+ Classifier: Environment :: Console
12
+ Requires-Python: >=3.9
13
+ Description-Content-Type: text/markdown
14
+
15
+ # 🌳 abitree
16
+
17
+ Generate beautiful, icon-rich file trees for your README — instantly.
18
+
19
+ ```
20
+ 📁 my-project/
21
+ ├── 📁 src/
22
+ │ ├── 🐍 main.py
23
+ │ ├── ⚛️ App.tsx
24
+ │ └── 🎨 styles.css
25
+ ├── 📦 package.json
26
+ ├── 🐳 Dockerfile
27
+ └── 📝 README.md
28
+ ```
29
+
30
+ ## Installation
31
+
32
+ ```bash
33
+ pip install abitree
34
+ ```
35
+
36
+ ## Usage
37
+
38
+ ```bash
39
+ # Current directory
40
+ abitree
41
+
42
+ # Specific path
43
+ abitree ./my-project
44
+
45
+ # Limit depth
46
+ abitree -L 2
47
+
48
+ # Output to file
49
+ abitree -o structure.md
50
+
51
+ # Wrap in markdown code block
52
+ abitree --md
53
+
54
+ # Directories only
55
+ abitree --dirs-only
56
+
57
+ # Ignore extra folders
58
+ abitree -i dist,build,.cache
59
+
60
+ # No icons (plain text)
61
+ abitree --no-icons
62
+ ```
63
+
64
+ ## Options
65
+
66
+ | Flag | Description |
67
+ |------|-------------|
68
+ | `path` | Directory to scan (default: `.`) |
69
+ | `-L, --level` | Max depth |
70
+ | `-o, --output` | Write output to file |
71
+ | `-i, --ignore` | Comma-separated ignore list |
72
+ | `--dirs-only` | Show directories only |
73
+ | `--no-icons` | Disable icons |
74
+ | `--no-default-ignore` | Don't ignore `.git`, `node_modules`, etc. |
75
+ | `--md` | Wrap output in markdown code block |
76
+
77
+ ## Default ignored
78
+
79
+ `.git`, `__pycache__`, `.DS_Store`, `.idea`, `.vscode`, `node_modules`
80
+
81
+ ## Author
82
+
83
+ Built by [Abidit Shrestha](https://github.com/abiditshrestha)
84
+
85
+ ## License
86
+
87
+ MIT
@@ -0,0 +1,11 @@
1
+ README.md
2
+ pyproject.toml
3
+ abitree/__init__.py
4
+ abitree/cli.py
5
+ abitree/icons.py
6
+ abitree/tree.py
7
+ abitree.egg-info/PKG-INFO
8
+ abitree.egg-info/SOURCES.txt
9
+ abitree.egg-info/dependency_links.txt
10
+ abitree.egg-info/entry_points.txt
11
+ abitree.egg-info/top_level.txt
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ abitree = abitree.cli:main
@@ -0,0 +1 @@
1
+ abitree
@@ -0,0 +1,26 @@
1
+ [build-system]
2
+ requires = ["setuptools>=68", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "abitree"
7
+ version = "0.1.0"
8
+ description = "Generate beautiful file trees for your README"
9
+ authors = [{ name = "Abidit Shrestha" }]
10
+ readme = "README.md"
11
+ license = { text = "MIT" }
12
+ requires-python = ">=3.9"
13
+ keywords = ["cli", "tree", "readme", "file-tree", "developer-tools"]
14
+ classifiers = [
15
+ "Programming Language :: Python :: 3",
16
+ "License :: OSI Approved :: MIT License",
17
+ "Operating System :: OS Independent",
18
+ "Environment :: Console",
19
+ ]
20
+
21
+ [project.scripts]
22
+ abitree = "abitree.cli:main"
23
+
24
+ [tool.setuptools.packages.find]
25
+ where = ["."]
26
+ include = ["abitree*"]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+