treescript-builder 0.1.7__py3-none-any.whl → 0.1.9__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.
- treescript_builder/data/path_stack.py +1 -15
- treescript_builder/data/tree_state.py +9 -9
- treescript_builder/input/line_reader.py +58 -36
- {treescript_builder-0.1.7.dist-info → treescript_builder-0.1.9.dist-info}/METADATA +2 -1
- {treescript_builder-0.1.7.dist-info → treescript_builder-0.1.9.dist-info}/RECORD +9 -9
- {treescript_builder-0.1.7.dist-info → treescript_builder-0.1.9.dist-info}/WHEEL +0 -0
- {treescript_builder-0.1.7.dist-info → treescript_builder-0.1.9.dist-info}/entry_points.txt +0 -0
- {treescript_builder-0.1.7.dist-info → treescript_builder-0.1.9.dist-info}/licenses/LICENSE +0 -0
- {treescript_builder-0.1.7.dist-info → treescript_builder-0.1.9.dist-info}/top_level.txt +0 -0
@@ -11,7 +11,6 @@ class PathStack:
|
|
11
11
|
- push(str)
|
12
12
|
- pop: str?
|
13
13
|
- join_stack: Path
|
14
|
-
- create_path(str): Path
|
15
14
|
- reduce_depth(int): bool
|
16
15
|
- get_depth: int
|
17
16
|
"""
|
@@ -47,19 +46,6 @@ class PathStack:
|
|
47
46
|
return Path("./")
|
48
47
|
return Path(f"./{'/'.join(self._stack)}/")
|
49
48
|
|
50
|
-
def create_path(self, filename: str) -> Path:
|
51
|
-
""" Combines all Elements in the Stack and appends a File name.
|
52
|
-
|
53
|
-
**Parameters:**
|
54
|
-
- filename (str): The name of the file to append to the end of the path.
|
55
|
-
|
56
|
-
**Returns:**
|
57
|
-
Path - The Path to the file.
|
58
|
-
"""
|
59
|
-
if type(filename) is not str or len(filename) < 1:
|
60
|
-
return self.join_stack()
|
61
|
-
return self.join_stack() / filename
|
62
|
-
|
63
49
|
def reduce_depth(self, depth: int) -> bool:
|
64
50
|
""" Reduce the Depth of the Path Stack.
|
65
51
|
|
@@ -84,4 +70,4 @@ class PathStack:
|
|
84
70
|
**Returns:**
|
85
71
|
int - The number of elements in the Path Stack.
|
86
72
|
"""
|
87
|
-
return len(self._stack)
|
73
|
+
return len(self._stack)
|
@@ -102,18 +102,19 @@ class TreeState:
|
|
102
102
|
|
103
103
|
def process_stack(self, depth: int) -> Generator[Path, None, None]:
|
104
104
|
""" Pop the Stack to the Desired Depth.
|
105
|
+
- Combines all Elements in the Stack into a Directory Path.
|
105
106
|
|
106
|
-
Parameters
|
107
|
+
**Parameters:**
|
107
108
|
- depth (int): The depth to process the stack to.
|
108
109
|
|
109
|
-
|
110
|
-
|
110
|
+
**Yields:**
|
111
|
+
Path - A Path for every Directory in the Stack, from top to bottom.
|
111
112
|
"""
|
112
113
|
if depth < 0:
|
113
|
-
|
114
|
+
raise ValueError('Negative Depth.')
|
114
115
|
while depth < self._stack.get_depth():
|
115
116
|
if (entry := self._stack.pop()) is not None:
|
116
|
-
yield self._stack.
|
117
|
+
yield self._stack.join_stack() / entry
|
117
118
|
|
118
119
|
def reduce_depth(self, depth: int) -> bool:
|
119
120
|
""" Pop an element from the stack.
|
@@ -135,7 +136,6 @@ class TreeState:
|
|
135
136
|
Raises:
|
136
137
|
SystemExit - When the Line Number does not increase.
|
137
138
|
"""
|
138
|
-
if self._prev_line_number
|
139
|
-
|
140
|
-
|
141
|
-
exit("Invalid Tree Data Sequence")
|
139
|
+
if self._prev_line_number >= line_number:
|
140
|
+
exit("Invalid Tree Data Sequence")
|
141
|
+
self._prev_line_number = line_number
|
@@ -1,24 +1,34 @@
|
|
1
|
-
""" Line Reader.
|
1
|
+
""" Line Reader Module for Processing TreeScript.
|
2
2
|
|
3
3
|
The Default Input Reader.
|
4
4
|
- Processes a single line at a time, and determines its key properties.
|
5
5
|
- The Depth is the Integer number of directories between the current line and the root.
|
6
6
|
- The Directory Boolean indicates whether the line represents a Directory.
|
7
7
|
- The Name String is the name of the line.
|
8
|
+
- DataLabel is the first word after the Name, and it has a strict set of validation criteria.
|
9
|
+
- Comments are filtered out by starting a line with the # character. A comment after a file name is also filtered.
|
8
10
|
Author: DK96-OS 2024 - 2025
|
9
11
|
"""
|
10
|
-
from itertools import groupby, takewhile
|
11
12
|
from sys import exit
|
12
13
|
from typing import Generator
|
13
14
|
|
14
15
|
from treescript_builder.data.tree_data import TreeData
|
15
|
-
from treescript_builder.input.string_validation import validate_dir_name, validate_name
|
16
|
+
from treescript_builder.input.string_validation import validate_dir_name, validate_name, validate_data_label
|
16
17
|
|
17
18
|
|
18
19
|
SPACE_CHARS = (' ', ' ')
|
19
20
|
|
20
21
|
|
21
|
-
|
22
|
+
_INVALID_DEPTH_ERROR_MSG = "Invalid Depth (Number of Spaces) in Line: "
|
23
|
+
|
24
|
+
_INVALID_NODE_NAME_ERROR_MSG = "Invalid Name in Line: "
|
25
|
+
_INVALID_DATALABEL_ERROR_MSG = "Invalid DataLabel in Line: "
|
26
|
+
_MISSING_DATADIR_ERROR_MSG = "Missing DataDirectory for DataLabel in Line: "
|
27
|
+
|
28
|
+
|
29
|
+
def read_input_tree(
|
30
|
+
input_tree_data: str,
|
31
|
+
) -> Generator[TreeData, None, None]:
|
22
32
|
""" Generate structured Tree Data from the Input Data String.
|
23
33
|
|
24
34
|
**Parameters:**
|
@@ -30,15 +40,10 @@ def read_input_tree(input_tree_data: str) -> Generator[TreeData, None, None]:
|
|
30
40
|
**Raises:**
|
31
41
|
SystemExit - When any Line cannot be read successfully.
|
32
42
|
"""
|
33
|
-
line_number =
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
else:
|
38
|
-
line = ''.join(group)
|
39
|
-
if len(lstr := line.lstrip()) == 0 or lstr.startswith('#'):
|
40
|
-
continue
|
41
|
-
yield _process_line(line_number, line)
|
43
|
+
for line_number, line in enumerate(input_tree_data.splitlines(), start=1):
|
44
|
+
if len(lstr := line.lstrip()) == 0 or lstr.startswith('#'):
|
45
|
+
continue
|
46
|
+
yield _process_line(line_number, line)
|
42
47
|
|
43
48
|
|
44
49
|
def _process_line(
|
@@ -51,44 +56,59 @@ def _process_line(
|
|
51
56
|
**Parameters:**
|
52
57
|
- line_number (int): The line-number in the input tree structure, starting from 1.
|
53
58
|
- line (str): A line from the input tree structure.
|
59
|
+
- is_data_label_enabled (bool): Whether DataLabels are enabled. If the DataDirectory argument is not provided, DataLabels are disabled.
|
54
60
|
|
55
61
|
**Returns:**
|
56
|
-
|
62
|
+
TreeData - A Tree Node Data object.
|
57
63
|
|
58
64
|
**Raises:**
|
59
65
|
SystemExit - When Line cannot be read successfully.
|
60
66
|
"""
|
67
|
+
# Depth Depends on Leading Spaces
|
61
68
|
if (depth := _calculate_depth(line)) < 0:
|
62
|
-
exit(
|
63
|
-
#
|
69
|
+
exit(_INVALID_DEPTH_ERROR_MSG + str(line_number))
|
70
|
+
# Now remove Leading Spaces (and trailing)
|
64
71
|
args = line.strip()
|
65
|
-
# Try to split line into multiple arguments
|
72
|
+
# Try to split line into multiple arguments, on one of the SpaceChars.
|
66
73
|
for space_char in SPACE_CHARS:
|
67
74
|
if space_char in args:
|
68
75
|
args = args.split(space_char)
|
69
76
|
break
|
70
77
|
# Check whether line was split or not
|
71
78
|
if isinstance(args, str):
|
72
|
-
name = args
|
73
|
-
data_label =
|
79
|
+
name = args # Was Not Split
|
80
|
+
data_label = ''
|
74
81
|
elif isinstance(args, list) and len(args) >= 2:
|
75
|
-
name = args[0]
|
76
|
-
|
82
|
+
name = args[0] # First Word is the Tree Node Name.
|
83
|
+
# Second Word is the DataLabel.
|
84
|
+
data_label = _validate_data_label_argument(line_number, args[1])
|
85
|
+
# Additional Words are ignored. Comments after the DataLabel are possible, for now.
|
86
|
+
# Alternate LineReader Modules are likely to expand in this area:
|
77
87
|
else:
|
78
88
|
exit(f"Invalid Line: {line_number}")
|
79
|
-
# Validate the Node Name and Type.
|
89
|
+
# Validate the Node Name and Type (is_dir). The tuple is bool first, then node name.
|
80
90
|
if (node_info := _validate_node_name(name)) is None:
|
81
|
-
exit(
|
82
|
-
(is_dir, name) = node_info
|
91
|
+
exit(_INVALID_NODE_NAME_ERROR_MSG + str(line_number))
|
83
92
|
return TreeData(
|
84
|
-
line_number,
|
85
|
-
depth,
|
86
|
-
is_dir,
|
87
|
-
name,
|
88
|
-
data_label
|
93
|
+
line_number=line_number,
|
94
|
+
depth=depth,
|
95
|
+
is_dir=node_info[0],
|
96
|
+
name=node_info[1],
|
97
|
+
data_label=data_label,
|
89
98
|
)
|
90
99
|
|
91
100
|
|
101
|
+
def _validate_data_label_argument(
|
102
|
+
line_number: int,
|
103
|
+
argument: str,
|
104
|
+
) -> str:
|
105
|
+
if argument.startswith('#'): # Comment should be ignored.
|
106
|
+
return ''
|
107
|
+
elif not validate_data_label(argument):
|
108
|
+
exit(_INVALID_DATALABEL_ERROR_MSG + str(line_number))
|
109
|
+
return argument
|
110
|
+
|
111
|
+
|
92
112
|
def _validate_node_name(node_name: str) -> tuple[bool, str] | None:
|
93
113
|
""" Determine whether this Tree Node is a Directory, and validate the name.
|
94
114
|
|
@@ -96,7 +116,7 @@ def _validate_node_name(node_name: str) -> tuple[bool, str] | None:
|
|
96
116
|
- node_name (str): The argument received for the node name.
|
97
117
|
|
98
118
|
**Returns:**
|
99
|
-
tuple[bool, str] - Node information, first whether it is a directory, then the valid name of the node.
|
119
|
+
tuple[bool, str]? - Node information, first whether it is a directory, then the valid name of the node.
|
100
120
|
|
101
121
|
**Raises:**
|
102
122
|
SystemExit - When the directory name is invalid.
|
@@ -104,14 +124,14 @@ def _validate_node_name(node_name: str) -> tuple[bool, str] | None:
|
|
104
124
|
try:
|
105
125
|
# Check if the line contains any slash characters
|
106
126
|
if (dir_name := validate_dir_name(node_name)) is not None:
|
107
|
-
return
|
127
|
+
return True, dir_name
|
108
128
|
# Fall-Through to File Node
|
109
129
|
except ValueError:
|
110
130
|
# An error in the dir name, such that it cannot be a file either
|
111
131
|
return None
|
112
132
|
# Is a File
|
113
133
|
if validate_name(node_name):
|
114
|
-
return
|
134
|
+
return False, node_name
|
115
135
|
return None
|
116
136
|
|
117
137
|
|
@@ -122,11 +142,13 @@ def _calculate_depth(line: str) -> int:
|
|
122
142
|
- line (str): A line from the tree command output.
|
123
143
|
|
124
144
|
**Returns:**
|
125
|
-
int
|
145
|
+
int - The depth of the line in the tree structure, or -1 if space count is invalid.
|
126
146
|
"""
|
127
|
-
space_count =
|
128
|
-
|
129
|
-
|
147
|
+
space_count = 0
|
148
|
+
for char in line:
|
149
|
+
if char not in SPACE_CHARS:
|
150
|
+
break
|
151
|
+
space_count += 1
|
130
152
|
# Bit Shift Shuffle Equivalence Validation (space_count is divisible by 2)
|
131
153
|
if (depth := space_count >> 1) << 1 == space_count:
|
132
154
|
return depth
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: treescript-builder
|
3
|
-
Version: 0.1.
|
3
|
+
Version: 0.1.9
|
4
4
|
Summary: Builds File Trees from TreeScript. If DataLabels are present in TreeScript, a DataDirectory argument is required.
|
5
5
|
Home-page: https://github.com/DK96-OS/treescript-builder
|
6
6
|
Author: DK96-OS
|
@@ -16,6 +16,7 @@ Classifier: Programming Language :: Python :: 3
|
|
16
16
|
Classifier: Programming Language :: Python :: 3.11
|
17
17
|
Classifier: Programming Language :: Python :: 3.12
|
18
18
|
Classifier: Programming Language :: Python :: 3.13
|
19
|
+
Classifier: Programming Language :: Python :: 3.14
|
19
20
|
Requires-Python: >=3.11
|
20
21
|
Description-Content-Type: text/markdown
|
21
22
|
License-File: LICENSE
|
@@ -3,24 +3,24 @@ treescript_builder/__main__.py,sha256=IWk1m8kZFyd35b3HLGwcxqczqKWskt1keylKQFV7YN
|
|
3
3
|
treescript_builder/data/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
4
4
|
treescript_builder/data/data_directory.py,sha256=eqLLOyV2YTXHv1rU7xsE_Hn4oViJh4SrokRfbKfEgTA,3267
|
5
5
|
treescript_builder/data/instruction_data.py,sha256=VqJ25-1Na0b2KamuKaVDN6qGPn-8Mm89tS1rt7_RzCY,533
|
6
|
-
treescript_builder/data/path_stack.py,sha256=
|
6
|
+
treescript_builder/data/path_stack.py,sha256=2u7MKv57l_-YB1Cgr81woZGJdJCke7hCNR27T9r4za8,1932
|
7
7
|
treescript_builder/data/tree_data.py,sha256=iyo-op0AmM9i_ypGXSROkbdax_YJgGsYLXKIlvmXmQ0,1035
|
8
|
-
treescript_builder/data/tree_state.py,sha256=
|
8
|
+
treescript_builder/data/tree_state.py,sha256=luWdxLxMrqaDRuNVLz7BKy_ZW4nYrGUymUdshOHmkI0,4553
|
9
9
|
treescript_builder/input/__init__.py,sha256=JONsaG0Iq_w-b9BUpHPpc89DFG8sM8Dxrswb3tWvzY8,921
|
10
10
|
treescript_builder/input/argument_data.py,sha256=PFacb8g-RXh4-RH8foW4eINms6REWpm_knaehYAICfA,806
|
11
11
|
treescript_builder/input/argument_parser.py,sha256=ARPI-EFO5MkXSQqLjyiQPkxg-sB2jP14wf6K4y64Tog,2795
|
12
12
|
treescript_builder/input/file_validation.py,sha256=m0zxntGDkkzWLb3PQKKsxfRSSDgd0dhK35IbaUmN_gw,2404
|
13
13
|
treescript_builder/input/input_data.py,sha256=mP8FAI26UDRwfuEFWXsJJnw77Qxv_yjkuy4NFiTZVOg,479
|
14
|
-
treescript_builder/input/line_reader.py,sha256=
|
14
|
+
treescript_builder/input/line_reader.py,sha256=RDft2rW2Apkd56rQJ8_ngkVyrp3DOh2KtJT6DamXlqI,5492
|
15
15
|
treescript_builder/input/string_validation.py,sha256=6H17UWamTPp2aBC-EVX1P58E0a-F6eD1--HH8CWrmIQ,5020
|
16
16
|
treescript_builder/tree/__init__.py,sha256=3YgyrVcplTYEtFL9PuEM2k08LM8N8xsdRmNJR0rbA4s,1884
|
17
17
|
treescript_builder/tree/build_validation.py,sha256=huO_FRnq_anqGTaQaDfcmc_zU9pIuVaa0orglNDgQIc,4167
|
18
18
|
treescript_builder/tree/tree_builder.py,sha256=0OiJ_Rjpm9Ux1DXvP4d6lHw9CoUCpu6lTfxTmLVOTfQ,1862
|
19
19
|
treescript_builder/tree/tree_trimmer.py,sha256=4cYrnAPX4WQi9JW60K20KPWb9aAtkPYTZWeZ4scEjps,1581
|
20
20
|
treescript_builder/tree/trim_validation.py,sha256=Q49ufnISQxZDzsnvMWrF5cMxRSZQYAhgpY_2XdIjnzI,3353
|
21
|
-
treescript_builder-0.1.
|
22
|
-
treescript_builder-0.1.
|
23
|
-
treescript_builder-0.1.
|
24
|
-
treescript_builder-0.1.
|
25
|
-
treescript_builder-0.1.
|
26
|
-
treescript_builder-0.1.
|
21
|
+
treescript_builder-0.1.9.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
22
|
+
treescript_builder-0.1.9.dist-info/METADATA,sha256=G25tjXNH71GnYyOsMqchowmS1H3z3lw4kD4rrfjC6WE,5350
|
23
|
+
treescript_builder-0.1.9.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
24
|
+
treescript_builder-0.1.9.dist-info/entry_points.txt,sha256=eOmYzJQPcGaH2GGBfwwU6UH_33tGtsK_ogxB4DnVrFI,111
|
25
|
+
treescript_builder-0.1.9.dist-info/top_level.txt,sha256=parytS3LU7PXBsMVe_puiTOva14bUCzvFwcIwF_Y3Ks,19
|
26
|
+
treescript_builder-0.1.9.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|