tree2project 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.
- tree2project-0.1.0/LICENSE +0 -0
- tree2project-0.1.0/PKG-INFO +23 -0
- tree2project-0.1.0/README.md +0 -0
- tree2project-0.1.0/pyproject.toml +52 -0
- tree2project-0.1.0/setup.cfg +4 -0
- tree2project-0.1.0/src/tree2project/__init__.py +3 -0
- tree2project-0.1.0/src/tree2project/cli.py +89 -0
- tree2project-0.1.0/src/tree2project/commands/create.py +89 -0
- tree2project-0.1.0/src/tree2project/commands/export.py +35 -0
- tree2project-0.1.0/src/tree2project/commands/validate.py +43 -0
- tree2project-0.1.0/src/tree2project/creator.py +41 -0
- tree2project-0.1.0/src/tree2project/exporter.py +42 -0
- tree2project-0.1.0/src/tree2project/parser.py +64 -0
- tree2project-0.1.0/src/tree2project/validator.py +25 -0
- tree2project-0.1.0/src/tree2project/version.py +1 -0
- tree2project-0.1.0/src/tree2project.egg-info/PKG-INFO +23 -0
- tree2project-0.1.0/src/tree2project.egg-info/SOURCES.txt +21 -0
- tree2project-0.1.0/src/tree2project.egg-info/dependency_links.txt +1 -0
- tree2project-0.1.0/src/tree2project.egg-info/entry_points.txt +2 -0
- tree2project-0.1.0/src/tree2project.egg-info/requires.txt +1 -0
- tree2project-0.1.0/src/tree2project.egg-info/top_level.txt +1 -0
- tree2project-0.1.0/tests/test_exporter.py +17 -0
- tree2project-0.1.0/tests/test_parser.py +16 -0
|
File without changes
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: tree2project
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Create project folder structures from tree-format files
|
|
5
|
+
Author-email: Dinesh kumar ummaneni <dineshkumarummaneni@gmail.com>
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/yourname/tree2project
|
|
8
|
+
Project-URL: Repository, https://github.com/yourname/tree2project
|
|
9
|
+
Keywords: cli,filesystem,project-generator,scaffold,tree
|
|
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.9
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
19
|
+
Requires-Python: >=3.9
|
|
20
|
+
Description-Content-Type: text/markdown
|
|
21
|
+
License-File: LICENSE
|
|
22
|
+
Requires-Dist: rich>=13.7.0
|
|
23
|
+
Dynamic: license-file
|
|
File without changes
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=68.0", "wheel"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "tree2project"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
description = "Create project folder structures from tree-format files"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.9"
|
|
11
|
+
license = { text = "MIT" }
|
|
12
|
+
|
|
13
|
+
authors = [
|
|
14
|
+
{ name = "Dinesh kumar ummaneni", email = "dineshkumarummaneni@gmail.com" }
|
|
15
|
+
]
|
|
16
|
+
|
|
17
|
+
keywords = [
|
|
18
|
+
"cli",
|
|
19
|
+
"filesystem",
|
|
20
|
+
"project-generator",
|
|
21
|
+
"scaffold",
|
|
22
|
+
"tree"
|
|
23
|
+
]
|
|
24
|
+
|
|
25
|
+
classifiers = [
|
|
26
|
+
"Development Status :: 4 - Beta",
|
|
27
|
+
"Environment :: Console",
|
|
28
|
+
"Intended Audience :: Developers",
|
|
29
|
+
"License :: OSI Approved :: MIT License",
|
|
30
|
+
"Programming Language :: Python :: 3",
|
|
31
|
+
"Programming Language :: Python :: 3.9",
|
|
32
|
+
"Programming Language :: Python :: 3.10",
|
|
33
|
+
"Programming Language :: Python :: 3.11",
|
|
34
|
+
"Programming Language :: Python :: 3.12"
|
|
35
|
+
]
|
|
36
|
+
|
|
37
|
+
dependencies = [
|
|
38
|
+
"rich>=13.7.0"
|
|
39
|
+
]
|
|
40
|
+
|
|
41
|
+
[project.urls]
|
|
42
|
+
Homepage = "https://github.com/yourname/tree2project"
|
|
43
|
+
Repository = "https://github.com/yourname/tree2project"
|
|
44
|
+
|
|
45
|
+
[project.scripts]
|
|
46
|
+
tree2project = "tree2project.cli:main"
|
|
47
|
+
|
|
48
|
+
[tool.setuptools]
|
|
49
|
+
package-dir = {"" = "src"}
|
|
50
|
+
|
|
51
|
+
[tool.setuptools.packages.find]
|
|
52
|
+
where = ["src"]
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import argparse
|
|
2
|
+
|
|
3
|
+
from tree2project.commands.create import (
|
|
4
|
+
run as create_run
|
|
5
|
+
)
|
|
6
|
+
from tree2project.commands.export import (
|
|
7
|
+
run as export_run
|
|
8
|
+
)
|
|
9
|
+
from tree2project.commands.validate import (
|
|
10
|
+
run as validate_run
|
|
11
|
+
)
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def main():
|
|
15
|
+
parser = argparse.ArgumentParser(
|
|
16
|
+
prog="tree2project"
|
|
17
|
+
)
|
|
18
|
+
|
|
19
|
+
subparsers = parser.add_subparsers(
|
|
20
|
+
dest="command"
|
|
21
|
+
)
|
|
22
|
+
|
|
23
|
+
create_parser = subparsers.add_parser(
|
|
24
|
+
"create",
|
|
25
|
+
help="Create structure"
|
|
26
|
+
)
|
|
27
|
+
|
|
28
|
+
create_parser.add_argument(
|
|
29
|
+
"structure_file"
|
|
30
|
+
)
|
|
31
|
+
|
|
32
|
+
create_parser.add_argument(
|
|
33
|
+
"--target"
|
|
34
|
+
)
|
|
35
|
+
|
|
36
|
+
create_parser.add_argument(
|
|
37
|
+
"--dry-run",
|
|
38
|
+
action="store_true"
|
|
39
|
+
)
|
|
40
|
+
|
|
41
|
+
export_parser = subparsers.add_parser(
|
|
42
|
+
"export",
|
|
43
|
+
help="Export structure"
|
|
44
|
+
)
|
|
45
|
+
|
|
46
|
+
export_parser.add_argument(
|
|
47
|
+
"directory"
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
export_parser.add_argument(
|
|
51
|
+
"--output"
|
|
52
|
+
)
|
|
53
|
+
|
|
54
|
+
validate_parser = subparsers.add_parser(
|
|
55
|
+
"validate",
|
|
56
|
+
help="Validate structure"
|
|
57
|
+
)
|
|
58
|
+
|
|
59
|
+
validate_parser.add_argument(
|
|
60
|
+
"structure_file"
|
|
61
|
+
)
|
|
62
|
+
|
|
63
|
+
validate_parser.add_argument(
|
|
64
|
+
"--target",
|
|
65
|
+
required=True
|
|
66
|
+
)
|
|
67
|
+
|
|
68
|
+
args = parser.parse_args()
|
|
69
|
+
|
|
70
|
+
if args.command == "create":
|
|
71
|
+
raise SystemExit(
|
|
72
|
+
create_run(args)
|
|
73
|
+
)
|
|
74
|
+
|
|
75
|
+
elif args.command == "export":
|
|
76
|
+
raise SystemExit(
|
|
77
|
+
export_run(args)
|
|
78
|
+
)
|
|
79
|
+
|
|
80
|
+
elif args.command == "validate":
|
|
81
|
+
raise SystemExit(
|
|
82
|
+
validate_run(args)
|
|
83
|
+
)
|
|
84
|
+
|
|
85
|
+
parser.print_help()
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
if __name__ == "__main__":
|
|
89
|
+
main()
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
from pathlib import Path
|
|
2
|
+
|
|
3
|
+
from rich.console import Console
|
|
4
|
+
from rich.table import Table
|
|
5
|
+
|
|
6
|
+
from tree2project.parser import parse_structure
|
|
7
|
+
from tree2project.creator import create_structure
|
|
8
|
+
|
|
9
|
+
console = Console()
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def run(args):
|
|
13
|
+
structure_file = Path(args.structure_file)
|
|
14
|
+
|
|
15
|
+
if not structure_file.exists():
|
|
16
|
+
console.print(
|
|
17
|
+
f"[red]File not found:[/red] {structure_file}"
|
|
18
|
+
)
|
|
19
|
+
return 1
|
|
20
|
+
|
|
21
|
+
with open(
|
|
22
|
+
structure_file,
|
|
23
|
+
"r",
|
|
24
|
+
encoding="utf-8"
|
|
25
|
+
) as f:
|
|
26
|
+
lines = f.readlines()
|
|
27
|
+
|
|
28
|
+
paths = parse_structure(lines)
|
|
29
|
+
|
|
30
|
+
target = (
|
|
31
|
+
Path(args.target).expanduser().resolve()
|
|
32
|
+
if args.target
|
|
33
|
+
else Path(
|
|
34
|
+
console.input(
|
|
35
|
+
"Target directory: "
|
|
36
|
+
)
|
|
37
|
+
).expanduser().resolve()
|
|
38
|
+
)
|
|
39
|
+
|
|
40
|
+
table = Table(title="Structure Preview")
|
|
41
|
+
|
|
42
|
+
table.add_column("Type")
|
|
43
|
+
table.add_column("Path")
|
|
44
|
+
|
|
45
|
+
for path, is_dir in paths:
|
|
46
|
+
table.add_row(
|
|
47
|
+
"DIR" if is_dir else "FILE",
|
|
48
|
+
str(target / path)
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
console.print(table)
|
|
52
|
+
|
|
53
|
+
if args.dry_run:
|
|
54
|
+
console.print(
|
|
55
|
+
"[yellow]Dry run complete.[/yellow]"
|
|
56
|
+
)
|
|
57
|
+
return 0
|
|
58
|
+
|
|
59
|
+
confirm = console.input(
|
|
60
|
+
"Create structure? [y/N]: "
|
|
61
|
+
)
|
|
62
|
+
|
|
63
|
+
if confirm.lower() != "y":
|
|
64
|
+
console.print(
|
|
65
|
+
"[yellow]Cancelled[/yellow]"
|
|
66
|
+
)
|
|
67
|
+
return 0
|
|
68
|
+
|
|
69
|
+
result = create_structure(
|
|
70
|
+
paths,
|
|
71
|
+
target
|
|
72
|
+
)
|
|
73
|
+
|
|
74
|
+
console.print(
|
|
75
|
+
f"[green]Directories:[/green] "
|
|
76
|
+
f"{len(result['created_dirs'])}"
|
|
77
|
+
)
|
|
78
|
+
|
|
79
|
+
console.print(
|
|
80
|
+
f"[green]Files:[/green] "
|
|
81
|
+
f"{len(result['created_files'])}"
|
|
82
|
+
)
|
|
83
|
+
|
|
84
|
+
console.print(
|
|
85
|
+
f"[yellow]Skipped:[/yellow] "
|
|
86
|
+
f"{len(result['skipped_files'])}"
|
|
87
|
+
)
|
|
88
|
+
|
|
89
|
+
return 0
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
from pathlib import Path
|
|
2
|
+
|
|
3
|
+
from rich.console import Console
|
|
4
|
+
|
|
5
|
+
from tree2project.exporter import export_structure
|
|
6
|
+
|
|
7
|
+
console = Console()
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def run(args):
|
|
11
|
+
root = Path(args.directory)
|
|
12
|
+
|
|
13
|
+
if not root.exists():
|
|
14
|
+
console.print(
|
|
15
|
+
f"[red]Directory not found:[/red] {root}"
|
|
16
|
+
)
|
|
17
|
+
return 1
|
|
18
|
+
|
|
19
|
+
structure = export_structure(root)
|
|
20
|
+
|
|
21
|
+
if args.output:
|
|
22
|
+
with open(
|
|
23
|
+
args.output,
|
|
24
|
+
"w",
|
|
25
|
+
encoding="utf-8"
|
|
26
|
+
) as f:
|
|
27
|
+
f.write(structure)
|
|
28
|
+
|
|
29
|
+
console.print(
|
|
30
|
+
f"[green]Saved:[/green] {args.output}"
|
|
31
|
+
)
|
|
32
|
+
else:
|
|
33
|
+
console.print(structure)
|
|
34
|
+
|
|
35
|
+
return 0
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
from pathlib import Path
|
|
2
|
+
|
|
3
|
+
from rich.console import Console
|
|
4
|
+
|
|
5
|
+
from tree2project.parser import parse_structure
|
|
6
|
+
from tree2project.validator import (
|
|
7
|
+
validate_structure
|
|
8
|
+
)
|
|
9
|
+
|
|
10
|
+
console = Console()
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def run(args):
|
|
14
|
+
structure_file = Path(args.structure_file)
|
|
15
|
+
|
|
16
|
+
with open(
|
|
17
|
+
structure_file,
|
|
18
|
+
"r",
|
|
19
|
+
encoding="utf-8"
|
|
20
|
+
) as f:
|
|
21
|
+
lines = f.readlines()
|
|
22
|
+
|
|
23
|
+
paths = parse_structure(lines)
|
|
24
|
+
|
|
25
|
+
result = validate_structure(
|
|
26
|
+
paths,
|
|
27
|
+
args.target
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
if result["valid"]:
|
|
31
|
+
console.print(
|
|
32
|
+
"[green]Structure valid[/green]"
|
|
33
|
+
)
|
|
34
|
+
return 0
|
|
35
|
+
|
|
36
|
+
console.print(
|
|
37
|
+
"[red]Missing paths:[/red]"
|
|
38
|
+
)
|
|
39
|
+
|
|
40
|
+
for item in result["missing"]:
|
|
41
|
+
console.print(item)
|
|
42
|
+
|
|
43
|
+
return 1
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
from pathlib import Path
|
|
2
|
+
|
|
3
|
+
def create_structure(paths, target_dir, dry_run=False):
|
|
4
|
+
target_dir = Path(target_dir)
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
created_dirs = []
|
|
8
|
+
created_files = []
|
|
9
|
+
skipped_files = []
|
|
10
|
+
|
|
11
|
+
for relative_path, is_dir in paths:
|
|
12
|
+
full_path = target_dir / relative_path
|
|
13
|
+
|
|
14
|
+
if dry_run:
|
|
15
|
+
continue
|
|
16
|
+
|
|
17
|
+
if is_dir:
|
|
18
|
+
full_path.mkdir(
|
|
19
|
+
parents=True,
|
|
20
|
+
exist_ok=True
|
|
21
|
+
)
|
|
22
|
+
created_dirs.append(str(full_path))
|
|
23
|
+
else:
|
|
24
|
+
full_path.parent.mkdir(
|
|
25
|
+
parents=True,
|
|
26
|
+
exist_ok=True
|
|
27
|
+
)
|
|
28
|
+
|
|
29
|
+
if full_path.exists():
|
|
30
|
+
skipped_files.append(str(full_path))
|
|
31
|
+
continue
|
|
32
|
+
|
|
33
|
+
full_path.touch()
|
|
34
|
+
created_files.append(str(full_path))
|
|
35
|
+
|
|
36
|
+
return {
|
|
37
|
+
"created_dirs": created_dirs,
|
|
38
|
+
"created_files": created_files,
|
|
39
|
+
"skipped_files": skipped_files,
|
|
40
|
+
}
|
|
41
|
+
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
|
|
2
|
+
from pathlib import Path
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
def export_structure(root_path):
|
|
6
|
+
root = Path(root_path)
|
|
7
|
+
|
|
8
|
+
if not root.exists():
|
|
9
|
+
raise FileNotFoundError(root)
|
|
10
|
+
|
|
11
|
+
lines = [f"{root.name}/"]
|
|
12
|
+
|
|
13
|
+
def walk(directory, prefix=""):
|
|
14
|
+
items = sorted(
|
|
15
|
+
directory.iterdir(),
|
|
16
|
+
key=lambda p: (p.is_file(), p.name.lower())
|
|
17
|
+
)
|
|
18
|
+
|
|
19
|
+
for idx, item in enumerate(items):
|
|
20
|
+
last = idx == len(items) - 1
|
|
21
|
+
|
|
22
|
+
connector = "└── " if last else "├── "
|
|
23
|
+
|
|
24
|
+
if item.is_dir():
|
|
25
|
+
lines.append(
|
|
26
|
+
f"{prefix}{connector}{item.name}/"
|
|
27
|
+
)
|
|
28
|
+
|
|
29
|
+
extension = " " if last else "│ "
|
|
30
|
+
|
|
31
|
+
walk(
|
|
32
|
+
item,
|
|
33
|
+
prefix + extension
|
|
34
|
+
)
|
|
35
|
+
else:
|
|
36
|
+
lines.append(
|
|
37
|
+
f"{prefix}{connector}{item.name}"
|
|
38
|
+
)
|
|
39
|
+
|
|
40
|
+
walk(root)
|
|
41
|
+
|
|
42
|
+
return "\n".join(lines)
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
from pathlib import Path
|
|
2
|
+
import re
|
|
3
|
+
|
|
4
|
+
def parse_structure(lines):
|
|
5
|
+
paths = []
|
|
6
|
+
stack = []
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
for raw in lines:
|
|
10
|
+
line = raw.rstrip("\n")
|
|
11
|
+
|
|
12
|
+
if not line.strip():
|
|
13
|
+
continue
|
|
14
|
+
|
|
15
|
+
stripped = line.strip()
|
|
16
|
+
|
|
17
|
+
if re.fullmatch(r"[│\s]+", stripped):
|
|
18
|
+
continue
|
|
19
|
+
|
|
20
|
+
if not any(token in line for token in ("├──", "└──")):
|
|
21
|
+
name = stripped.rstrip("/")
|
|
22
|
+
|
|
23
|
+
if stripped.endswith("/"):
|
|
24
|
+
stack = [name]
|
|
25
|
+
paths.append((Path(name), True))
|
|
26
|
+
else:
|
|
27
|
+
paths.append((Path(name), False))
|
|
28
|
+
|
|
29
|
+
continue
|
|
30
|
+
|
|
31
|
+
prefix = (
|
|
32
|
+
line.split("├──")[0]
|
|
33
|
+
if "├──" in line
|
|
34
|
+
else line.split("└──")[0]
|
|
35
|
+
)
|
|
36
|
+
|
|
37
|
+
depth = len(prefix) // 4
|
|
38
|
+
|
|
39
|
+
name = re.sub(
|
|
40
|
+
r"^[ │]*(├──|└──)\s*",
|
|
41
|
+
"",
|
|
42
|
+
line,
|
|
43
|
+
).strip()
|
|
44
|
+
|
|
45
|
+
is_dir = name.endswith("/")
|
|
46
|
+
name = name.rstrip("/")
|
|
47
|
+
|
|
48
|
+
while len(stack) > depth + 1:
|
|
49
|
+
stack.pop()
|
|
50
|
+
|
|
51
|
+
parent = Path(*stack) if stack else Path()
|
|
52
|
+
current = parent / name
|
|
53
|
+
|
|
54
|
+
paths.append((current, is_dir))
|
|
55
|
+
|
|
56
|
+
if is_dir:
|
|
57
|
+
if len(stack) == depth + 1:
|
|
58
|
+
stack.append(name)
|
|
59
|
+
else:
|
|
60
|
+
stack = stack[: depth + 1]
|
|
61
|
+
stack.append(name)
|
|
62
|
+
|
|
63
|
+
return paths
|
|
64
|
+
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
from pathlib import Path
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
def validate_structure(paths, target_dir):
|
|
5
|
+
target_dir = Path(target_dir)
|
|
6
|
+
|
|
7
|
+
missing = []
|
|
8
|
+
|
|
9
|
+
for relative_path, is_dir in paths:
|
|
10
|
+
full_path = target_dir / relative_path
|
|
11
|
+
|
|
12
|
+
if not full_path.exists():
|
|
13
|
+
missing.append(str(full_path))
|
|
14
|
+
continue
|
|
15
|
+
|
|
16
|
+
if is_dir and not full_path.is_dir():
|
|
17
|
+
missing.append(str(full_path))
|
|
18
|
+
|
|
19
|
+
if not is_dir and not full_path.is_file():
|
|
20
|
+
missing.append(str(full_path))
|
|
21
|
+
|
|
22
|
+
return {
|
|
23
|
+
"valid": len(missing) == 0,
|
|
24
|
+
"missing": missing,
|
|
25
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
version = "0.1.0"
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: tree2project
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Create project folder structures from tree-format files
|
|
5
|
+
Author-email: Dinesh kumar ummaneni <dineshkumarummaneni@gmail.com>
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/yourname/tree2project
|
|
8
|
+
Project-URL: Repository, https://github.com/yourname/tree2project
|
|
9
|
+
Keywords: cli,filesystem,project-generator,scaffold,tree
|
|
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.9
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
19
|
+
Requires-Python: >=3.9
|
|
20
|
+
Description-Content-Type: text/markdown
|
|
21
|
+
License-File: LICENSE
|
|
22
|
+
Requires-Dist: rich>=13.7.0
|
|
23
|
+
Dynamic: license-file
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
LICENSE
|
|
2
|
+
README.md
|
|
3
|
+
pyproject.toml
|
|
4
|
+
src/tree2project/__init__.py
|
|
5
|
+
src/tree2project/cli.py
|
|
6
|
+
src/tree2project/creator.py
|
|
7
|
+
src/tree2project/exporter.py
|
|
8
|
+
src/tree2project/parser.py
|
|
9
|
+
src/tree2project/validator.py
|
|
10
|
+
src/tree2project/version.py
|
|
11
|
+
src/tree2project.egg-info/PKG-INFO
|
|
12
|
+
src/tree2project.egg-info/SOURCES.txt
|
|
13
|
+
src/tree2project.egg-info/dependency_links.txt
|
|
14
|
+
src/tree2project.egg-info/entry_points.txt
|
|
15
|
+
src/tree2project.egg-info/requires.txt
|
|
16
|
+
src/tree2project.egg-info/top_level.txt
|
|
17
|
+
src/tree2project/commands/create.py
|
|
18
|
+
src/tree2project/commands/export.py
|
|
19
|
+
src/tree2project/commands/validate.py
|
|
20
|
+
tests/test_exporter.py
|
|
21
|
+
tests/test_parser.py
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
rich>=13.7.0
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
tree2project
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
from pathlib import Path
|
|
2
|
+
|
|
3
|
+
from tree2project.exporter import (
|
|
4
|
+
export_structure
|
|
5
|
+
)
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def test_export(tmp_path):
|
|
9
|
+
root = tmp_path / "sample"
|
|
10
|
+
|
|
11
|
+
root.mkdir()
|
|
12
|
+
|
|
13
|
+
(root / "README.md").touch()
|
|
14
|
+
|
|
15
|
+
output = export_structure(root)
|
|
16
|
+
|
|
17
|
+
assert "README.md" in output
|