startype23 1.0.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.
- startype23-1.0.0/PKG-INFO +88 -0
- startype23-1.0.0/README.md +63 -0
- startype23-1.0.0/pyproject.toml +42 -0
- startype23-1.0.0/src/startype23/__init__.py +3 -0
- startype23-1.0.0/src/startype23/analyzer.py +131 -0
- startype23-1.0.0/src/startype23/charts.py +449 -0
- startype23-1.0.0/src/startype23/cli.py +120 -0
- startype23-1.0.0/src/startype23/extensions.py +551 -0
- startype23-1.0.0/uv.lock +85 -0
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: startype23
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: A CLI tool that analyzes a directory and displays a colourful chart of file type distribution.
|
|
5
|
+
Project-URL: Homepage, https://github.com/startype23/startype23
|
|
6
|
+
Project-URL: Source, https://github.com/startype23/startype23
|
|
7
|
+
Project-URL: Bug tracker, https://github.com/startype23/startype23/issues
|
|
8
|
+
Author-email: StarType23 <charts@startype23.dev>
|
|
9
|
+
License: MIT
|
|
10
|
+
Classifier: Development Status :: 4 - Beta
|
|
11
|
+
Classifier: Environment :: Console
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
14
|
+
Classifier: Programming Language :: Python :: 3
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
19
|
+
Classifier: Topic :: System :: Filesystems
|
|
20
|
+
Classifier: Topic :: Utilities
|
|
21
|
+
Requires-Python: >=3.10
|
|
22
|
+
Requires-Dist: click>=8.1.0
|
|
23
|
+
Requires-Dist: rich>=13.0.0
|
|
24
|
+
Description-Content-Type: text/markdown
|
|
25
|
+
|
|
26
|
+
# StarType23
|
|
27
|
+
|
|
28
|
+
A CLI tool that walks a directory, counts files by extension, and renders a
|
|
29
|
+
colourful file-type distribution chart in the terminal.
|
|
30
|
+
|
|
31
|
+
## Features
|
|
32
|
+
|
|
33
|
+
- Scans recursively and groups files by extension (count and disk size).
|
|
34
|
+
- Renders a stacked proportion bar + a table with coloured mini bars.
|
|
35
|
+
- Two modes: by **count** (`startype23`) or by **size** (`startype23 --size`).
|
|
36
|
+
- Built-in lookup table of ~500 extensions with file-type category and
|
|
37
|
+
one-line description (`--explain .py`).
|
|
38
|
+
- Column visibility toggles: `--filetype`, `--count`, `--percentage`,
|
|
39
|
+
`--distribution`.
|
|
40
|
+
- Skips `.git`, `.venv`, `node_modules`, `__pycache__`, and similar by
|
|
41
|
+
default.
|
|
42
|
+
- Flat-design pastel colour palette (no neon).
|
|
43
|
+
|
|
44
|
+
## Usage
|
|
45
|
+
|
|
46
|
+
```
|
|
47
|
+
uv run startype23 scan current directory
|
|
48
|
+
uv run startype23 --size scan by disk size
|
|
49
|
+
uv run startype23 --path /some/dir scan a specific directory
|
|
50
|
+
uv run startype23 --include-hidden include dotfiles
|
|
51
|
+
uv run startype23 --explain .py look up an extension
|
|
52
|
+
uv run startype23 --explain py leading dot is optional
|
|
53
|
+
uv run startype23 --exclude build skip extra directories
|
|
54
|
+
uv run startype23 --count --percentage show only selected columns
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
| Flag | Description |
|
|
58
|
+
|----------------------------|-----------------------------------------------|
|
|
59
|
+
| `--path` | Directory to scan (default: `.`) |
|
|
60
|
+
| `--exclude` / `-x` | Extra directory names to skip (repeatable) |
|
|
61
|
+
| `--include-hidden` | Include dotfiles in the scan |
|
|
62
|
+
| `--no-include-hidden` | Exclude dotfiles (default) |
|
|
63
|
+
| `--explain` / `-e` | Look up an extension and show its description |
|
|
64
|
+
| `--size` / `-s` | Size distribution instead of count |
|
|
65
|
+
| `--filetype` / `-ft` | Show the File Type column |
|
|
66
|
+
| `--count` / `-c` | Show the Count column |
|
|
67
|
+
| `--percentage` / `-p` | Show the Percentage column |
|
|
68
|
+
| `--distribution` / `-d` | Show the Distribution bar column |
|
|
69
|
+
|
|
70
|
+
When no column flags are given, all columns show. When one or more are
|
|
71
|
+
given, only those (plus Extension) are shown.
|
|
72
|
+
|
|
73
|
+
## Tools used to build this project
|
|
74
|
+
|
|
75
|
+
- **Python 3.10+** -- language runtime.
|
|
76
|
+
- **uv** -- package and project manager (install, build, publish).
|
|
77
|
+
- **click** -- CLI framework (arguments, options, help).
|
|
78
|
+
- **rich** -- terminal styling (tables, colours, text formatting).
|
|
79
|
+
- **hatchling** -- build backend (PEP 517).
|
|
80
|
+
- **Wikipedia's List of filename extensions** -- source for the ~500-entry
|
|
81
|
+
extension lookup table.
|
|
82
|
+
|
|
83
|
+
## Publishing
|
|
84
|
+
|
|
85
|
+
```bash
|
|
86
|
+
uv build
|
|
87
|
+
uv publish --token pypi-xxxxxxxx
|
|
88
|
+
```
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# StarType23
|
|
2
|
+
|
|
3
|
+
A CLI tool that walks a directory, counts files by extension, and renders a
|
|
4
|
+
colourful file-type distribution chart in the terminal.
|
|
5
|
+
|
|
6
|
+
## Features
|
|
7
|
+
|
|
8
|
+
- Scans recursively and groups files by extension (count and disk size).
|
|
9
|
+
- Renders a stacked proportion bar + a table with coloured mini bars.
|
|
10
|
+
- Two modes: by **count** (`startype23`) or by **size** (`startype23 --size`).
|
|
11
|
+
- Built-in lookup table of ~500 extensions with file-type category and
|
|
12
|
+
one-line description (`--explain .py`).
|
|
13
|
+
- Column visibility toggles: `--filetype`, `--count`, `--percentage`,
|
|
14
|
+
`--distribution`.
|
|
15
|
+
- Skips `.git`, `.venv`, `node_modules`, `__pycache__`, and similar by
|
|
16
|
+
default.
|
|
17
|
+
- Flat-design pastel colour palette (no neon).
|
|
18
|
+
|
|
19
|
+
## Usage
|
|
20
|
+
|
|
21
|
+
```
|
|
22
|
+
uv run startype23 scan current directory
|
|
23
|
+
uv run startype23 --size scan by disk size
|
|
24
|
+
uv run startype23 --path /some/dir scan a specific directory
|
|
25
|
+
uv run startype23 --include-hidden include dotfiles
|
|
26
|
+
uv run startype23 --explain .py look up an extension
|
|
27
|
+
uv run startype23 --explain py leading dot is optional
|
|
28
|
+
uv run startype23 --exclude build skip extra directories
|
|
29
|
+
uv run startype23 --count --percentage show only selected columns
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
| Flag | Description |
|
|
33
|
+
|----------------------------|-----------------------------------------------|
|
|
34
|
+
| `--path` | Directory to scan (default: `.`) |
|
|
35
|
+
| `--exclude` / `-x` | Extra directory names to skip (repeatable) |
|
|
36
|
+
| `--include-hidden` | Include dotfiles in the scan |
|
|
37
|
+
| `--no-include-hidden` | Exclude dotfiles (default) |
|
|
38
|
+
| `--explain` / `-e` | Look up an extension and show its description |
|
|
39
|
+
| `--size` / `-s` | Size distribution instead of count |
|
|
40
|
+
| `--filetype` / `-ft` | Show the File Type column |
|
|
41
|
+
| `--count` / `-c` | Show the Count column |
|
|
42
|
+
| `--percentage` / `-p` | Show the Percentage column |
|
|
43
|
+
| `--distribution` / `-d` | Show the Distribution bar column |
|
|
44
|
+
|
|
45
|
+
When no column flags are given, all columns show. When one or more are
|
|
46
|
+
given, only those (plus Extension) are shown.
|
|
47
|
+
|
|
48
|
+
## Tools used to build this project
|
|
49
|
+
|
|
50
|
+
- **Python 3.10+** -- language runtime.
|
|
51
|
+
- **uv** -- package and project manager (install, build, publish).
|
|
52
|
+
- **click** -- CLI framework (arguments, options, help).
|
|
53
|
+
- **rich** -- terminal styling (tables, colours, text formatting).
|
|
54
|
+
- **hatchling** -- build backend (PEP 517).
|
|
55
|
+
- **Wikipedia's List of filename extensions** -- source for the ~500-entry
|
|
56
|
+
extension lookup table.
|
|
57
|
+
|
|
58
|
+
## Publishing
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
uv build
|
|
62
|
+
uv publish --token pypi-xxxxxxxx
|
|
63
|
+
```
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "startype23"
|
|
3
|
+
version = "1.0.0"
|
|
4
|
+
description = "A CLI tool that analyzes a directory and displays a colourful chart of file type distribution."
|
|
5
|
+
readme = "README.md"
|
|
6
|
+
requires-python = ">=3.10"
|
|
7
|
+
license = { text = "MIT" }
|
|
8
|
+
authors = [
|
|
9
|
+
{ name = "StarType23", email = "charts@startype23.dev" },
|
|
10
|
+
]
|
|
11
|
+
classifiers = [
|
|
12
|
+
"Development Status :: 4 - Beta",
|
|
13
|
+
"Environment :: Console",
|
|
14
|
+
"Intended Audience :: Developers",
|
|
15
|
+
"License :: OSI Approved :: MIT License",
|
|
16
|
+
"Programming Language :: Python :: 3",
|
|
17
|
+
"Programming Language :: Python :: 3.10",
|
|
18
|
+
"Programming Language :: Python :: 3.11",
|
|
19
|
+
"Programming Language :: Python :: 3.12",
|
|
20
|
+
"Programming Language :: Python :: 3.13",
|
|
21
|
+
"Topic :: Utilities",
|
|
22
|
+
"Topic :: System :: Filesystems",
|
|
23
|
+
]
|
|
24
|
+
dependencies = [
|
|
25
|
+
"click>=8.1.0",
|
|
26
|
+
"rich>=13.0.0",
|
|
27
|
+
]
|
|
28
|
+
|
|
29
|
+
[project.urls]
|
|
30
|
+
Homepage = "https://github.com/startype23/startype23"
|
|
31
|
+
Source = "https://github.com/startype23/startype23"
|
|
32
|
+
"Bug tracker" = "https://github.com/startype23/startype23/issues"
|
|
33
|
+
|
|
34
|
+
[project.scripts]
|
|
35
|
+
startype23 = "startype23.cli:main"
|
|
36
|
+
|
|
37
|
+
[build-system]
|
|
38
|
+
requires = ["hatchling"]
|
|
39
|
+
build-backend = "hatchling.build"
|
|
40
|
+
|
|
41
|
+
[dependency-groups]
|
|
42
|
+
dev = []
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
"""Directory traversal and file extension aggregation."""
|
|
2
|
+
|
|
3
|
+
import os
|
|
4
|
+
from collections import Counter
|
|
5
|
+
from dataclasses import dataclass
|
|
6
|
+
from pathlib import Path
|
|
7
|
+
|
|
8
|
+
# Default directory names to skip during traversal.
|
|
9
|
+
DEFAULT_EXCLUDE_DIRS: set[str] = {
|
|
10
|
+
".git",
|
|
11
|
+
".hg",
|
|
12
|
+
".svn",
|
|
13
|
+
".venv",
|
|
14
|
+
"venv",
|
|
15
|
+
".tox",
|
|
16
|
+
".mypy_cache",
|
|
17
|
+
".pytest_cache",
|
|
18
|
+
"__pycache__",
|
|
19
|
+
"node_modules",
|
|
20
|
+
".idea",
|
|
21
|
+
".vscode",
|
|
22
|
+
".DS_Store",
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
@dataclass
|
|
27
|
+
class FileTypeInfo:
|
|
28
|
+
"""Aggregated statistics for a single file extension."""
|
|
29
|
+
|
|
30
|
+
extension: str
|
|
31
|
+
count: int
|
|
32
|
+
total_size: int = 0
|
|
33
|
+
percentage: float = 0.0
|
|
34
|
+
size_percentage: float = 0.0
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def scan_directory(
|
|
38
|
+
path: str = ".",
|
|
39
|
+
exclude_dirs: set[str] | None = None,
|
|
40
|
+
include_hidden: bool = False,
|
|
41
|
+
) -> list[FileTypeInfo]:
|
|
42
|
+
"""Walk *path* and aggregate file counts by extension.
|
|
43
|
+
|
|
44
|
+
Parameters
|
|
45
|
+
----------
|
|
46
|
+
path : str
|
|
47
|
+
Root directory to scan (defaults to current working directory).
|
|
48
|
+
exclude_dirs : set[str] or None
|
|
49
|
+
Directory names to skip. When ``None``, the built-in
|
|
50
|
+
``DEFAULT_EXCLUDE_DIRS`` set is used.
|
|
51
|
+
include_hidden : bool
|
|
52
|
+
If ``False``, files whose name starts with ``"."`` and directories
|
|
53
|
+
that have a leading dot are ignored.
|
|
54
|
+
|
|
55
|
+
Returns
|
|
56
|
+
-------
|
|
57
|
+
list[FileTypeInfo]
|
|
58
|
+
Sorted list (descending by count) of extension statistics.
|
|
59
|
+
"""
|
|
60
|
+
root = Path(path).resolve()
|
|
61
|
+
if not root.is_dir():
|
|
62
|
+
raise NotADirectoryError(f"Not a directory: {root}")
|
|
63
|
+
|
|
64
|
+
if exclude_dirs is None:
|
|
65
|
+
exclude_dirs = DEFAULT_EXCLUDE_DIRS
|
|
66
|
+
|
|
67
|
+
counter: Counter[str] = Counter()
|
|
68
|
+
size_map: dict[str, int] = {}
|
|
69
|
+
|
|
70
|
+
for dirpath_str, dirnames, filenames in os.walk(root):
|
|
71
|
+
dirpath = Path(dirpath_str)
|
|
72
|
+
|
|
73
|
+
# Filter out directories we should skip.
|
|
74
|
+
dirnames[:] = [
|
|
75
|
+
d
|
|
76
|
+
for d in dirnames
|
|
77
|
+
if d not in exclude_dirs and (include_hidden or not d.startswith("."))
|
|
78
|
+
]
|
|
79
|
+
|
|
80
|
+
for filename in filenames:
|
|
81
|
+
if not include_hidden and filename.startswith("."):
|
|
82
|
+
continue
|
|
83
|
+
|
|
84
|
+
ext = _extract_extension(filename)
|
|
85
|
+
counter[ext] += 1
|
|
86
|
+
|
|
87
|
+
try:
|
|
88
|
+
filepath = dirpath / filename
|
|
89
|
+
size_map[ext] = size_map.get(ext, 0) + filepath.stat().st_size
|
|
90
|
+
except OSError:
|
|
91
|
+
pass
|
|
92
|
+
|
|
93
|
+
total_files = sum(counter.values())
|
|
94
|
+
total_size_all = sum(size_map.values())
|
|
95
|
+
|
|
96
|
+
if total_files == 0:
|
|
97
|
+
return []
|
|
98
|
+
|
|
99
|
+
results: list[FileTypeInfo] = []
|
|
100
|
+
for ext, count in counter.most_common():
|
|
101
|
+
sz = size_map.get(ext, 0)
|
|
102
|
+
info = FileTypeInfo(
|
|
103
|
+
extension=ext,
|
|
104
|
+
count=count,
|
|
105
|
+
total_size=sz,
|
|
106
|
+
percentage=round((count / total_files) * 100, 1),
|
|
107
|
+
size_percentage=round((sz / total_size_all) * 100, 1)
|
|
108
|
+
if total_size_all
|
|
109
|
+
else 0.0,
|
|
110
|
+
)
|
|
111
|
+
results.append(info)
|
|
112
|
+
|
|
113
|
+
return results
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
# ---------------------------------------------------------------------------
|
|
117
|
+
# Internal helpers
|
|
118
|
+
# ---------------------------------------------------------------------------
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
def _extract_extension(filename: str) -> str:
|
|
122
|
+
"""Return the lowercase file extension including the leading dot.
|
|
123
|
+
|
|
124
|
+
Files without an extension are grouped under the label ``"[no extension]"``.
|
|
125
|
+
Files consisting solely of an extension (e.g. ``".gitignore"``) are treated
|
|
126
|
+
as having no extension.
|
|
127
|
+
"""
|
|
128
|
+
name, dot, ext = filename.rpartition(".")
|
|
129
|
+
if dot and name:
|
|
130
|
+
return f".{ext.lower()}"
|
|
131
|
+
return "[no extension]"
|