File: util.py

package info (click to toggle)
python-pathspec 0.12.1-1
  • links: PTS, VCS
  • area: main
  • in suites: sid, trixie
  • size: 368 kB
  • sloc: python: 2,907; makefile: 14
file content (148 lines) | stat: -rw-r--r-- 3,728 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
"""
This module provides utility functions shared by tests.
"""

import itertools
import os
import os.path
import pathlib

from typing import (
	Iterable,  # Replaced by `collections.abc.Iterable` in 3.9.
	List,  # Replaced by `set` in 3.9.
	Set,  # Replaced by `set` in 3.9.
	Tuple,  # Replaced by `tuple` in 3.9.
	cast)

from pathspec import (
	PathSpec,
	RegexPattern)
from pathspec.util import (
	CheckResult,
	TStrPath)


def debug_results(spec: PathSpec, results: Iterable[CheckResult[str]]) -> str:
	"""
	Format the check results message.

	*spec* (:class:`~pathspec.PathSpec`) is the path-spec.

	*results* (:class:`~collections.abc.Iterable` or :class:`~pathspec.util.CheckResult`)
	yields each file check result.

	Returns the message (:class:`str`).
	"""
	patterns = cast(List[RegexPattern], spec.patterns)

	pattern_table = []
	for index, pattern in enumerate(patterns, 1):
		pattern_table.append((f"{index}:{pattern.pattern}", repr(pattern.regex.pattern)))

	result_table = []
	for result in results:
		if result.index is not None:
			pattern = patterns[result.index]
			result_table.append((f"{result.index + 1}:{pattern.pattern}", result.file))
		else:
			result_table.append(("-", result.file))

	result_table.sort(key=lambda r: r[1])

	first_max_len = max((
		len(__row[0]) for __row in itertools.chain(pattern_table, result_table)
	), default=0)
	first_width = min(first_max_len, 20)

	pattern_lines = []
	for row in pattern_table:
		pattern_lines.append(f" {row[0]:<{first_width}}  {row[1]}")

	result_lines = []
	for row in result_table:
		result_lines.append(f" {row[0]:<{first_width}}  {row[1]}")

	return "\n".join([
		"\n",
		" DEBUG ".center(32, "-"),
		*pattern_lines,
		"-"*32,
		*result_lines,
		"-"*32,
	])


def get_includes(results: Iterable[CheckResult[TStrPath]]) -> Set[TStrPath]:
	"""
	Get the included files from the check results.

	*results* (:class:`~collections.abc.Iterable` or :class:`~pathspec.util.CheckResult`)
	yields each file check result.

	Returns the included files (:class:`set` of :class:`str`).
	"""
	return {__res.file for __res in results if __res.include}


def make_dirs(temp_dir: pathlib.Path, dirs: Iterable[str]) -> None:
	"""
	Create the specified directories.

	*temp_dir* (:class:`pathlib.Path`) is the temporary directory to use.

	*dirs* (:class:`Iterable` of :class:`str`) is the POSIX directory
	paths (relative to *temp_dir*) to create.
	"""
	for dir in dirs:
		os.mkdir(temp_dir / ospath(dir))


def make_files(temp_dir: pathlib.Path, files: Iterable[str]) -> None:
	"""
	Create the specified files.

	*temp_dir* (:class:`pathlib.Path`) is the temporary directory to use.

	*files* (:class:`Iterable` of :class:`str`) is the POSIX file paths
	(relative to *temp_dir*) to create.
	"""
	for file in files:
		mkfile(temp_dir / ospath(file))


def make_links(temp_dir: pathlib.Path, links: Iterable[Tuple[str, str]]) -> None:
	"""
	Create the specified links.

	*temp_dir* (:class:`pathlib.Path`) is the temporary directory to use.

	*links* (:class:`Iterable` of :class:`tuple`) contains the POSIX links
	to create relative to *temp_dir*. Each link (:class:`tuple`) contains
	the destination link path (:class:`str`) and source node path
	(:class:`str`).
	"""
	for link, node in links:
		src = temp_dir / ospath(node)
		dest = temp_dir / ospath(link)
		os.symlink(src, dest)


def mkfile(file: pathlib.Path) -> None:
	"""
	Creates an empty file.

	*file* (:class:`pathlib.Path`) is the native file path to create.
	"""
	with open(file, 'wb'):
		pass


def ospath(path: str) -> str:
	"""
	Convert the POSIX path to a native OS path.

	*path* (:class:`str`) is the POSIX path.

	Returns the native path (:class:`str`).
	"""
	return os.path.join(*path.split('/'))