Given a directory path, print a visual tree structure.
Output and highlight the content of 'pyenv-virtualenv' project property files with colors:
84):
85
86 if isinstance(root_path, str):
87 root_path = Path(root_path)
88
89 files = 0
90 directories = 0
91
92 def is_junction(path: str) -> bool:
93 import os
94 try:
95 return bool(os.readlink(path))
96 except OSError:
97 return False
98
99 def inner(
100 dir_path: Path,
101 prefix: str= '',
102 level: int = -1,
103 excl: tuple = ()
104 ):
105 nonlocal files, directories
106 if not level:
107 return
108
109 if limit_to_directories:
110 objects = dir_path.iterdir()
111 contents = [d for d in objects if d.is_dir()]
112 contents1 = list(objects)
113 else:
114 contents = list(dir_path.iterdir())
115 contents1 = contents
116
117 excl1 = excl
118 for content in contents1:
119 if content.is_file() and (content.name == '.tree-excludes'):
120 with open(content, 'r') as f:
121 excl1 = eval(f.read())
122 if content not in contents:
123 contents.insert(0, content)
124 break
125
126
127 pointers = [tee] * (len(contents) - 1) + [last]
128 for pointer, path in zip(pointers, contents):
129 if path.is_dir():
130
131 excluded = False
132 for item in excl1:
133 if path.parts[-1] == item:
134 excluded = True
135 break
136
137
138 if excluded: continue
139
140 name = path.name
141 if (
142 (hasattr(path, 'is_junction') and path.is_junction())
143 or
144 (is_junction(str(path)))
145 ):
146 name = '\x1b[105m {} \x1b[0m \x1b[95m→\x1b[0m \x1b[104m {} \x1b[0m'.format(
147 name,
148 str(path.readlink()).split('\\\\?\\')[-1]
149 )
150 else:
151 name = '\x1b[104m {} \x1b[0m'.format(name)
152 yield prefix + pointer + name
153 directories += 1
154 extension = branch if pointer == tee else space
155
156 yield from inner(
157 path,
158 prefix=prefix+extension,
159 level=level - 1,
160 excl=excl1
161 )
162 elif not limit_to_directories:
163
164 name = path.name
165 if path.is_symlink():
166 name1 = '\x1b[95m● {}\x1b[0m'.format(name)
167 if name == '.python-version':
168 name1 += ' \x1b[96m({})\x1b[0m'.format(
169 getProjectPropertyFileStr(str(path))
170 )
171 elif name == '.python-env':
172 name1 += ' \x1b[93m({})\x1b[0m'.format(
173 getProjectPropertyFileStr(str(path))
174 )
175 elif name == '.tree-excludes':
176 name1 += ' \x1b[95m{}\x1b[0m'.format(
177 getProjectPropertyFileStr(str(path))
178 )
179 else:
180 name1 = '\x1b[95m● {} → \x1b[37m● {}\x1b[0m'.format(
181 name,
182 str(path.readlink())
183 )
184 else:
185 name1 = '\x1b[37m● {}\x1b[0m'.format(name)
186 if name == '.python-version':
187 name1 += ' \x1b[96m({})\x1b[0m'.format(
188 getProjectPropertyFileStr(str(path))
189 )
190 elif name == '.python-env':
191 name1 += ' \x1b[93m({})\x1b[0m'.format(
192 getProjectPropertyFileStr(str(path))
193 )
194 elif name == '.tree-excludes':
195 name1 += ' \x1b[95m{}\x1b[0m'.format(
196 getProjectPropertyFileStr(str(path))
197 )
198 else:
199 name1 = '\x1b[37m● {}\x1b[0m'.format(name)
200 yield prefix + pointer + name1
201 files += 1
202
203
204 print('\x1b[104m {} \x1b[0m'.format(str(root_path)))
205
206 for excl_item in exclude:
207 if root_path.parts[-1] == excl_item:
208 return
209
210 iterator = inner(
211 root_path,
212 level=recursion_level,
213 excl=exclude
214 )
215
216 for line in islice(iterator, length_limit):
217 print(line)
218 if next(iterator, None):
219
220 print('... length_limit, {}, reached, counted:'.format(length_limit))
221
222 print(
223 '\n{} directories'.format(directories) + (
224 ', {} files'.format(files) if files else ''
225 )
226 )
227
228
229