proj-flow 0.21.0__py3-none-any.whl → 0.22.1__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.
- proj_flow/__init__.py +1 -1
- proj_flow/api/completers.py +1 -1
- proj_flow/api/env.py +37 -13
- proj_flow/api/release.py +1 -1
- proj_flow/api/step.py +7 -3
- proj_flow/{ext/cplusplus/cmake/presets.py → base/cmake_presets.py} +44 -24
- proj_flow/base/plugins.py +12 -7
- proj_flow/cli/finder.py +4 -3
- proj_flow/dependency.py +6 -2
- proj_flow/ext/cplusplus/cmake/__init__.py +2 -2
- proj_flow/ext/cplusplus/cmake/parser.py +4 -3
- proj_flow/ext/cplusplus/cmake/steps.py +3 -9
- proj_flow/ext/cplusplus/conan/__init__.py +6 -4
- proj_flow/ext/github/publishing.py +1 -0
- proj_flow/ext/python/rtdocs.py +2 -2
- proj_flow/ext/python/steps.py +5 -4
- proj_flow/ext/python/version.py +12 -12
- proj_flow/ext/sign/__init__.py +2 -2
- proj_flow/ext/test_runner/__init__.py +6 -0
- proj_flow/ext/test_runner/cli.py +416 -0
- proj_flow/ext/test_runner/driver/__init__.py +2 -0
- proj_flow/ext/test_runner/driver/commands.py +74 -0
- proj_flow/ext/test_runner/driver/test.py +610 -0
- proj_flow/ext/test_runner/driver/testbed.py +141 -0
- proj_flow/ext/test_runner/utils/__init__.py +2 -0
- proj_flow/ext/test_runner/utils/archives.py +56 -0
- proj_flow/log/release.py +7 -4
- proj_flow/log/rich_text/api.py +3 -4
- proj_flow/minimal/ext/bug_report.py +6 -4
- proj_flow/minimal/ext/versions.py +48 -0
- proj_flow/minimal/run.py +3 -2
- {proj_flow-0.21.0.dist-info → proj_flow-0.22.1.dist-info}/METADATA +1 -1
- {proj_flow-0.21.0.dist-info → proj_flow-0.22.1.dist-info}/RECORD +36 -27
- {proj_flow-0.21.0.dist-info → proj_flow-0.22.1.dist-info}/WHEEL +0 -0
- {proj_flow-0.21.0.dist-info → proj_flow-0.22.1.dist-info}/entry_points.txt +0 -0
- {proj_flow-0.21.0.dist-info → proj_flow-0.22.1.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
# Copyright (c) 2026 Marcin Zdun
|
|
2
|
+
# This code is licensed under MIT license (see LICENSE for details)
|
|
3
|
+
|
|
4
|
+
import os
|
|
5
|
+
import pprint
|
|
6
|
+
import random
|
|
7
|
+
import string
|
|
8
|
+
import sys
|
|
9
|
+
from dataclasses import dataclass, field, replace
|
|
10
|
+
from pathlib import Path
|
|
11
|
+
from typing import cast
|
|
12
|
+
|
|
13
|
+
from proj_flow.ext.test_runner.driver.test import Env, Test, fix_file_write, to_lines
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class color:
|
|
17
|
+
reset = "\033[m"
|
|
18
|
+
counter = "\033[2;49;92m"
|
|
19
|
+
name = "\033[0;49;90m"
|
|
20
|
+
failed = "\033[0;49;91m"
|
|
21
|
+
passed = "\033[2;49;92m"
|
|
22
|
+
skipped = "\033[0;49;34m"
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class TaskResult:
|
|
26
|
+
OK = 0
|
|
27
|
+
SKIPPED = 1
|
|
28
|
+
SAVED = 2
|
|
29
|
+
FAILED = 3
|
|
30
|
+
CLIP_FAILED = 4
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
@dataclass
|
|
34
|
+
class Counters:
|
|
35
|
+
error_counter: int = 0
|
|
36
|
+
skip_counter: int = 0
|
|
37
|
+
save_counter: int = 0
|
|
38
|
+
echo: list[str] = field(default_factory=list)
|
|
39
|
+
|
|
40
|
+
def report(self, outcome: int, test_id: str, message: str | None):
|
|
41
|
+
if outcome == TaskResult.SKIPPED:
|
|
42
|
+
print(f"{test_id} {color.skipped}SKIPPED{color.reset}")
|
|
43
|
+
self.skip_counter += 1
|
|
44
|
+
return
|
|
45
|
+
|
|
46
|
+
if outcome == TaskResult.SAVED:
|
|
47
|
+
print(f"{test_id} {color.skipped}saved{color.reset}")
|
|
48
|
+
self.skip_counter += 1
|
|
49
|
+
self.save_counter += 1
|
|
50
|
+
return
|
|
51
|
+
|
|
52
|
+
if outcome == TaskResult.CLIP_FAILED:
|
|
53
|
+
msg = f"{test_id} {color.failed}FAILED (unknown check '{message}'){color.reset}"
|
|
54
|
+
print(msg)
|
|
55
|
+
self.echo.append(msg)
|
|
56
|
+
self.error_counter += 1
|
|
57
|
+
return
|
|
58
|
+
|
|
59
|
+
if outcome == TaskResult.OK:
|
|
60
|
+
print(f"{test_id} {color.passed}PASSED{color.reset}")
|
|
61
|
+
return
|
|
62
|
+
|
|
63
|
+
if message is not None:
|
|
64
|
+
print(message)
|
|
65
|
+
msg = f"{test_id} {color.failed}FAILED{color.reset}"
|
|
66
|
+
print(msg)
|
|
67
|
+
self.echo.append(msg)
|
|
68
|
+
self.error_counter += 1
|
|
69
|
+
|
|
70
|
+
def summary(self, counter: int):
|
|
71
|
+
print(f"Failed {self.error_counter}/{counter}")
|
|
72
|
+
if self.skip_counter > 0:
|
|
73
|
+
skip_test = "test" if self.skip_counter == 1 else "tests"
|
|
74
|
+
if self.save_counter > 0:
|
|
75
|
+
print(
|
|
76
|
+
f"Skipped {self.skip_counter} {skip_test} (including {self.save_counter} due to saving)"
|
|
77
|
+
)
|
|
78
|
+
else:
|
|
79
|
+
print(f"Skipped {self.skip_counter} {skip_test}")
|
|
80
|
+
|
|
81
|
+
if len(self.echo):
|
|
82
|
+
print()
|
|
83
|
+
for echo in self.echo:
|
|
84
|
+
print(echo)
|
|
85
|
+
|
|
86
|
+
return self.error_counter == 0
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
def task(
|
|
90
|
+
env1: Env, tested: Test, current_counter: int
|
|
91
|
+
) -> tuple[int, str, str | None, str]:
|
|
92
|
+
temp_instance = "".join(random.choice(string.ascii_letters) for _ in range(16))
|
|
93
|
+
tempdir = f"{env1.tempdir}/{temp_instance}"
|
|
94
|
+
tempdir_alt = None
|
|
95
|
+
|
|
96
|
+
if env1.tempdir_alt is not None:
|
|
97
|
+
tempdir_alt = f"{env1.tempdir_alt}{os.sep}{temp_instance}"
|
|
98
|
+
|
|
99
|
+
env2 = replace(env1, tempdir=tempdir, tempdir_alt=tempdir_alt)
|
|
100
|
+
|
|
101
|
+
test_counter = f"{color.counter}[{current_counter:>{env2.counter_digits}}/{env2.counter_total}]{color.reset}"
|
|
102
|
+
test_name = f"{color.name}{tested.name}{color.reset}"
|
|
103
|
+
test_id = f"{test_counter} {test_name}"
|
|
104
|
+
|
|
105
|
+
print(test_id)
|
|
106
|
+
os.makedirs(tempdir, exist_ok=True)
|
|
107
|
+
|
|
108
|
+
actual = tested.run(env2)
|
|
109
|
+
if actual is None:
|
|
110
|
+
return (TaskResult.SKIPPED, test_id, None, tempdir)
|
|
111
|
+
|
|
112
|
+
if tested.expected is None:
|
|
113
|
+
is_json = tested.filename.suffix == ".json"
|
|
114
|
+
tested.data["expected"] = [
|
|
115
|
+
actual[0],
|
|
116
|
+
*[to_lines(stream, is_json) for stream in actual[1:3]],
|
|
117
|
+
]
|
|
118
|
+
tested.store()
|
|
119
|
+
return (TaskResult.SAVED, test_id, None, tempdir)
|
|
120
|
+
|
|
121
|
+
clipped = tested.clip(actual[:3])
|
|
122
|
+
|
|
123
|
+
if isinstance(clipped, str):
|
|
124
|
+
return (TaskResult.CLIP_FAILED, test_id, clipped, tempdir)
|
|
125
|
+
|
|
126
|
+
reports: list[str] = []
|
|
127
|
+
|
|
128
|
+
files = actual[3]
|
|
129
|
+
for file in files:
|
|
130
|
+
fixed = fix_file_write(file, env2, tested.cwd, tested.patches)
|
|
131
|
+
if fixed.generated.content != fixed.template.content:
|
|
132
|
+
reports.append(tested.report_file(fixed))
|
|
133
|
+
|
|
134
|
+
if actual[:3] != tested.expected and clipped != tested.expected:
|
|
135
|
+
reports.append(tested.report_io(actual[:3]))
|
|
136
|
+
|
|
137
|
+
if reports:
|
|
138
|
+
reports.append(tested.test_footer(env2, tempdir))
|
|
139
|
+
return (TaskResult.FAILED, test_id, "\n".join(reports), tempdir)
|
|
140
|
+
|
|
141
|
+
return (TaskResult.OK, test_id, None, tempdir)
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# Copyright (c) 2026 Marcin Zdun
|
|
2
|
+
# This code is licensed under MIT license (see LICENSE for details)
|
|
3
|
+
|
|
4
|
+
import os
|
|
5
|
+
import tarfile
|
|
6
|
+
import zipfile
|
|
7
|
+
from typing import Callable
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def _untar(src, dst):
|
|
11
|
+
with tarfile.open(src) as TAR:
|
|
12
|
+
|
|
13
|
+
def is_within_directory(directory, target):
|
|
14
|
+
abs_directory = os.path.abspath(directory)
|
|
15
|
+
abs_target = os.path.abspath(target)
|
|
16
|
+
|
|
17
|
+
prefix = os.path.commonprefix([abs_directory, abs_target])
|
|
18
|
+
|
|
19
|
+
return prefix == abs_directory
|
|
20
|
+
|
|
21
|
+
for member in TAR.getmembers():
|
|
22
|
+
member_path = os.path.join(dst, member.name)
|
|
23
|
+
if not is_within_directory(dst, member_path):
|
|
24
|
+
raise Exception(f"Attempted path traversal in Tar file: {member.name}")
|
|
25
|
+
|
|
26
|
+
TAR.extractall(dst)
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def _unzip(src, dst):
|
|
30
|
+
with zipfile.ZipFile(src) as ZIP:
|
|
31
|
+
ZIP.extractall(dst)
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
_tar = (_untar, ["tar", "-xf"])
|
|
35
|
+
|
|
36
|
+
Unpacker = Callable[[str, str], None]
|
|
37
|
+
UnpackInfo = tuple[Unpacker, list[str]]
|
|
38
|
+
|
|
39
|
+
ARCHIVES: dict[str, UnpackInfo] = {
|
|
40
|
+
".tar": _tar,
|
|
41
|
+
".tar.gz": _tar,
|
|
42
|
+
".zip": (_unzip, ["unzip"]),
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def locate_unpack(archive: str) -> UnpackInfo:
|
|
47
|
+
reminder, ext = os.path.splitext(archive)
|
|
48
|
+
_, mid = os.path.splitext(reminder)
|
|
49
|
+
if mid == ".tar":
|
|
50
|
+
ext = ".tar"
|
|
51
|
+
return ARCHIVES[ext]
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
del _tar
|
|
55
|
+
del _unzip
|
|
56
|
+
del _untar
|
proj_flow/log/release.py
CHANGED
|
@@ -18,13 +18,16 @@ OneOrMoreStrings = Union[str, Iterable[str]]
|
|
|
18
18
|
|
|
19
19
|
|
|
20
20
|
class VersionUpdater:
|
|
21
|
-
|
|
21
|
+
|
|
22
|
+
def on_version_change(
|
|
23
|
+
self, rt: env.Runtime, new_version: str
|
|
24
|
+
) -> Optional[OneOrMoreStrings]:
|
|
22
25
|
return None
|
|
23
26
|
|
|
24
27
|
def on_version_change_tags(
|
|
25
|
-
self, new_version: str, tags: list[str]
|
|
28
|
+
self, rt: env.Runtime, new_version: str, tags: list[str]
|
|
26
29
|
) -> Optional[OneOrMoreStrings]:
|
|
27
|
-
return self.on_version_change(new_version)
|
|
30
|
+
return self.on_version_change(rt, new_version)
|
|
28
31
|
|
|
29
32
|
|
|
30
33
|
version_updaters = registry.Registry[VersionUpdater]("VersionUpdater")
|
|
@@ -118,7 +121,7 @@ def add_release(
|
|
|
118
121
|
files_to_commit.append(version_path)
|
|
119
122
|
|
|
120
123
|
for updater in version_updaters.get():
|
|
121
|
-
modified = updater.on_version_change_tags(next_version, tags)
|
|
124
|
+
modified = updater.on_version_change_tags(rt, next_version, tags)
|
|
122
125
|
if modified is None:
|
|
123
126
|
continue
|
|
124
127
|
elif isinstance(modified, str):
|
proj_flow/log/rich_text/api.py
CHANGED
|
@@ -91,7 +91,7 @@ class ChangelogGenerator(abc.ABC):
|
|
|
91
91
|
|
|
92
92
|
entire_log.append(self.intro())
|
|
93
93
|
|
|
94
|
-
filename =
|
|
94
|
+
filename = rt.root / f"CHANGELOG{self.ext}"
|
|
95
95
|
with open(filename, "wb") as f:
|
|
96
96
|
for text in reversed(entire_log):
|
|
97
97
|
f.write(text.encode("UTF-8"))
|
|
@@ -106,8 +106,7 @@ class ChangelogGenerator(abc.ABC):
|
|
|
106
106
|
setup, commit.read_tag_date(setup.curr_tag or "HEAD", rt)
|
|
107
107
|
)
|
|
108
108
|
text = formatter.format_changelog(log)
|
|
109
|
-
|
|
110
|
-
path = os.path.join(rt.root, filename)
|
|
109
|
+
path = rt.root / self.filename
|
|
111
110
|
|
|
112
111
|
try:
|
|
113
112
|
with open(path, encoding="UTF-8") as f:
|
|
@@ -125,7 +124,7 @@ class ChangelogGenerator(abc.ABC):
|
|
|
125
124
|
if len(split) > 1:
|
|
126
125
|
new_text += "".join(split[1:])
|
|
127
126
|
|
|
128
|
-
with open(
|
|
127
|
+
with open(path, "wb") as f:
|
|
129
128
|
f.write(new_text.encode("UTF-8"))
|
|
130
129
|
|
|
131
130
|
|
|
@@ -8,14 +8,14 @@ next to CHANGELOG.rst.
|
|
|
8
8
|
|
|
9
9
|
import re
|
|
10
10
|
import sys
|
|
11
|
-
from typing import List, Tuple
|
|
12
11
|
|
|
12
|
+
from proj_flow.api import env
|
|
13
13
|
from proj_flow.log import release
|
|
14
14
|
|
|
15
15
|
YAML_PATH = ".github/ISSUE_TEMPLATE/bug_report.yaml"
|
|
16
16
|
|
|
17
17
|
|
|
18
|
-
def _version(ver: str) ->
|
|
18
|
+
def _version(ver: str) -> tuple[int, int, int, str]:
|
|
19
19
|
if ver[:1] == "v":
|
|
20
20
|
ver = ver[1:]
|
|
21
21
|
|
|
@@ -26,7 +26,7 @@ def _version(ver: str) -> Tuple[int, int, int, str]:
|
|
|
26
26
|
return (int(m.group(1)), int(m.group(2)), int(m.group(3)), ver)
|
|
27
27
|
|
|
28
28
|
|
|
29
|
-
def _prev_version(new_version: str, tags:
|
|
29
|
+
def _prev_version(new_version: str, tags: list[str]):
|
|
30
30
|
current = _version(new_version)
|
|
31
31
|
versions = [_version(tag) for tag in reversed(tags)]
|
|
32
32
|
index = 0
|
|
@@ -44,7 +44,9 @@ def _prev_version(new_version: str, tags: List[str]):
|
|
|
44
44
|
|
|
45
45
|
@release.version_updaters.add
|
|
46
46
|
class VersionUpdater(release.VersionUpdater):
|
|
47
|
-
def on_version_change_tags(
|
|
47
|
+
def on_version_change_tags(
|
|
48
|
+
self, rt: env.Runtime, new_version: str, tags: list[str]
|
|
49
|
+
):
|
|
48
50
|
old_version = _prev_version(new_version, tags)
|
|
49
51
|
|
|
50
52
|
range = [f" - Current (v{new_version})\n"]
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# Copyright (c) 2025 Marcin Zdun
|
|
2
|
+
# This code is licensed under MIT license (see LICENSE for details)
|
|
3
|
+
|
|
4
|
+
"""
|
|
5
|
+
The **proj_flow.minimal.ext.versions** update version schema files from version-updates
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from pathlib import Path
|
|
9
|
+
from typing import cast
|
|
10
|
+
|
|
11
|
+
from proj_flow.api import env
|
|
12
|
+
from proj_flow.log import release
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
@release.version_updaters.add
|
|
16
|
+
class VersionUpdater(release.VersionUpdater):
|
|
17
|
+
def on_version_change_tags(
|
|
18
|
+
self, rt: env.Runtime, new_version: str, tags: list[str]
|
|
19
|
+
) -> release.OneOrMoreStrings | None:
|
|
20
|
+
if not tags:
|
|
21
|
+
return None
|
|
22
|
+
prev_tag = tags[-1]
|
|
23
|
+
old_version = prev_tag[1:] if prev_tag.startswith("v") else prev_tag
|
|
24
|
+
|
|
25
|
+
files = cast(dict[str, str], rt._cfg.get("version-updates", {}))
|
|
26
|
+
changed_files: list[str] = []
|
|
27
|
+
|
|
28
|
+
rt.message("Config")
|
|
29
|
+
for key, value in files.items():
|
|
30
|
+
if "$VERSION" not in value:
|
|
31
|
+
continue
|
|
32
|
+
|
|
33
|
+
path = Path(key)
|
|
34
|
+
previous = value.replace("$VERSION", old_version)
|
|
35
|
+
next = value.replace("$VERSION", new_version)
|
|
36
|
+
rt.message(f" >> {key} :: {previous} -> {next}")
|
|
37
|
+
|
|
38
|
+
try:
|
|
39
|
+
content = path.read_text(encoding="UTF-8")
|
|
40
|
+
except FileNotFoundError:
|
|
41
|
+
rt.fatal(f"File not found: {key}")
|
|
42
|
+
|
|
43
|
+
new_content = content.replace(previous, next)
|
|
44
|
+
if new_content != content:
|
|
45
|
+
path.write_text(new_content, encoding="UTF-8")
|
|
46
|
+
changed_files.append(key)
|
|
47
|
+
|
|
48
|
+
return changed_files
|
proj_flow/minimal/run.py
CHANGED
|
@@ -9,6 +9,7 @@ import os
|
|
|
9
9
|
import shutil
|
|
10
10
|
import sys
|
|
11
11
|
from contextlib import contextmanager
|
|
12
|
+
from pathlib import Path
|
|
12
13
|
from typing import Annotated, List, Optional, Set, cast
|
|
13
14
|
|
|
14
15
|
from proj_flow import api, dependency
|
|
@@ -69,7 +70,7 @@ def gather_dependencies_for_all_configs(
|
|
|
69
70
|
def refresh_directories(
|
|
70
71
|
configs: Configs, rt: api.env.Runtime, steps: List[api.step.Step]
|
|
71
72
|
):
|
|
72
|
-
directories_to_refresh: Set[
|
|
73
|
+
directories_to_refresh: Set[Path] = set()
|
|
73
74
|
for config in configs.usable:
|
|
74
75
|
for step in steps:
|
|
75
76
|
if step.is_active(config, rt):
|
|
@@ -80,7 +81,7 @@ def refresh_directories(
|
|
|
80
81
|
for dirname in directories_to_refresh:
|
|
81
82
|
if not rt.silent:
|
|
82
83
|
printed = True
|
|
83
|
-
print(f"[-] {dirname}", file=sys.stderr)
|
|
84
|
+
print(f"[-] {dirname.as_posix()}", file=sys.stderr)
|
|
84
85
|
if not rt.dry_run:
|
|
85
86
|
shutil.rmtree(dirname, ignore_errors=True)
|
|
86
87
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: proj-flow
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.22.1
|
|
4
4
|
Summary: C++ project maintenance, automated
|
|
5
5
|
Project-URL: Changelog, https://github.com/mzdun/proj-flow/blob/main/CHANGELOG.rst
|
|
6
6
|
Project-URL: Documentation, https://proj-flow.readthedocs.io/en/latest/
|
|
@@ -1,51 +1,59 @@
|
|
|
1
|
-
proj_flow/__init__.py,sha256=
|
|
1
|
+
proj_flow/__init__.py,sha256=7tP0EcGLKC5fwA3PTFj4xAYTAJtwRuR1CO_ZEs1F_Sg,277
|
|
2
2
|
proj_flow/__main__.py,sha256=HUar_qQ9Ndmchmryegtzu__5wukwCLrFN_SGRl5Ol_M,233
|
|
3
|
-
proj_flow/dependency.py,sha256=
|
|
3
|
+
proj_flow/dependency.py,sha256=f2wjr_F7Cy_3I4R5AfT6R9Q28F3G3WrLKbqyEld_CF0,4765
|
|
4
4
|
proj_flow/api/__init__.py,sha256=gV2f6kll_5JXtvkGASvnx7CbOWr34PHOdck-4ce-qEk,378
|
|
5
5
|
proj_flow/api/arg.py,sha256=0sVVEqdIOCqWmZtST_-u4rP6JkrResGJsKERQp3WYgc,5392
|
|
6
|
-
proj_flow/api/completers.py,sha256=
|
|
6
|
+
proj_flow/api/completers.py,sha256=gZ50toLTWstKQbSV24gaNUzVjmrS0IjuYujzyMbp41A,2452
|
|
7
7
|
proj_flow/api/ctx.py,sha256=IJu0q0Chivo6b2M4MKkAlV09oi7Cn9VxtDFeAeL_tnc,6646
|
|
8
|
-
proj_flow/api/env.py,sha256=
|
|
8
|
+
proj_flow/api/env.py,sha256=8XN3N91iVzcgx2urYDy2IjqCk5CIzeCvFqN6FTK6YLo,13582
|
|
9
9
|
proj_flow/api/init.py,sha256=p4ZDGfq6fw4bXbJu2iq0vEmVxbS7nALIhZfe-XnEs44,565
|
|
10
10
|
proj_flow/api/makefile.py,sha256=q0fBSsWTWfR5YwunwiRjWJKtiLeHdSKUgUTEgo5I7dE,3863
|
|
11
|
-
proj_flow/api/release.py,sha256=
|
|
12
|
-
proj_flow/api/step.py,sha256=
|
|
11
|
+
proj_flow/api/release.py,sha256=JOddtYNH7J-GfUsvc1hOgKLzf56C6qvwF748n87MQFE,2821
|
|
12
|
+
proj_flow/api/step.py,sha256=npUREdBIJb6s4CPA7snVd83YvfhsfMx6mPYKiHFhVF4,5326
|
|
13
13
|
proj_flow/base/__cmake_version__.py,sha256=imja0GnhpBvS8Crz-64eOUKhc4i6FeRrjBGRB68x_p0,239
|
|
14
14
|
proj_flow/base/__init__.py,sha256=V6IFRRtwxzvHuvtog6LIG9_6oivNpdcR5UmGobypvTo,930
|
|
15
|
+
proj_flow/base/cmake_presets.py,sha256=tBgzKk8BU1Lz9oA7o3PdB2Z4nK9ftuLb2TgeUzVhABc,5618
|
|
15
16
|
proj_flow/base/cmd.py,sha256=XJk_r4Nlq_2XGgD_w92Us4WKwItmQAB8QWdT1pKxUFA,1746
|
|
16
17
|
proj_flow/base/inspect.py,sha256=lt5P19rvSZ-wMCTrCYAaQFCt2S9fUjEQXlrKK-Tmvwc,2786
|
|
17
18
|
proj_flow/base/matrix.py,sha256=kH2BB6JRrLYdR71VJiJp58zfQSazwEOeiRXOPrayAcI,8446
|
|
18
19
|
proj_flow/base/name_list.py,sha256=KiHSnbDgYplJc25O3EehYhFAhD7Z3mHVAK6UYOdg5PQ,416
|
|
19
|
-
proj_flow/base/plugins.py,sha256=
|
|
20
|
+
proj_flow/base/plugins.py,sha256=8mQfkrdF7UncJaWz6623oa4g9XiZjJWvTgU1pCEBkr0,1078
|
|
20
21
|
proj_flow/base/registry.py,sha256=zbkB9KNfHnyPtzOurdvjwt714jrFpGHyOqeZL5sMvzI,3745
|
|
21
22
|
proj_flow/base/uname.py,sha256=7Awb3Es0jTAKMpyRawdrC16xc5X9M97BlPqEfQibqIk,2295
|
|
22
23
|
proj_flow/cli/__init__.py,sha256=cMsZpECkXeSzY4Hv_ela3Ou-FhwE5w1A3ypMSnZZikM,1196
|
|
23
24
|
proj_flow/cli/argument.py,sha256=V242x0ziuvqqXl56TDXxVhN1llCRZRT3bUnw7GfGRIE,14341
|
|
24
|
-
proj_flow/cli/finder.py,sha256=
|
|
25
|
+
proj_flow/cli/finder.py,sha256=IHnX2tkD0Hq7N6hVDArGJIK8NFzD5isMZYugkArlS6Y,1439
|
|
25
26
|
proj_flow/ext/__init__.py,sha256=XD52rUFTPz3GnyRq6KZUNeWdMce7e0bB19iTx-zU6DE,169
|
|
26
27
|
proj_flow/ext/markdown_changelog.py,sha256=fRGL09jojnv2B-8vAX2prvgNp8e7uyq5NxboSZjFCJ8,436
|
|
27
28
|
proj_flow/ext/re_structured_changelog.py,sha256=UF23W9eu_YgPO42MiaoDbEKu8In_48mQg6rH9--mI30,459
|
|
28
29
|
proj_flow/ext/store.py,sha256=zc9yh9M042V5OSLUZjWe9KazhdZ35h1JJsWvKughM0Y,3385
|
|
29
30
|
proj_flow/ext/cplusplus/__init__.py,sha256=dAmLMyGVQq586jJM_jiAuo5Ecw9U8agpvSRbzzPgh3g,245
|
|
30
|
-
proj_flow/ext/cplusplus/cmake/__init__.py,sha256=
|
|
31
|
-
proj_flow/ext/cplusplus/cmake/parser.py,sha256=
|
|
32
|
-
proj_flow/ext/cplusplus/cmake/presets.py,sha256=hrAMgFj9TP8mguNsGgRKB4rDOMHIrC77sJKn2SzEAOM,5059
|
|
31
|
+
proj_flow/ext/cplusplus/cmake/__init__.py,sha256=XQ8l1WsEZAgcNX_A0KgY535VhF6s7glS0TW2L0EmdVc,346
|
|
32
|
+
proj_flow/ext/cplusplus/cmake/parser.py,sha256=GsySyYC3DES-3teKPvs5PFwl3hpQkvKkNhWGbpLa-Ww,3828
|
|
33
33
|
proj_flow/ext/cplusplus/cmake/project.py,sha256=Cp-5HwEsrQW4RjDThjMBQmaVJiRHo9QvYbw7IvjHKNQ,929
|
|
34
|
-
proj_flow/ext/cplusplus/cmake/steps.py,sha256=
|
|
35
|
-
proj_flow/ext/cplusplus/conan/__init__.py,sha256=
|
|
34
|
+
proj_flow/ext/cplusplus/cmake/steps.py,sha256=Xp7d-79wi759p4OqpRPfhNplUNbNa1Oi-_18_K5-Vs4,4256
|
|
35
|
+
proj_flow/ext/cplusplus/conan/__init__.py,sha256=hHxf9-7W5KGKOv2e1EBQj6sPDD-R7LMCXx5BlLETT8w,2052
|
|
36
36
|
proj_flow/ext/cplusplus/conan/_conan.py,sha256=9xnji-f8uN7huXLqavVBUDC33CgnjBIyZX6wVcGm2RA,3352
|
|
37
37
|
proj_flow/ext/github/__init__.py,sha256=Mgx19YS6SYBXYB66_pOgIgwuB2WKRxqp5UGutq0B9Xk,282
|
|
38
38
|
proj_flow/ext/github/cli.py,sha256=whK_VEUAG48tODyUYGfh3ZzZEa6vQgsNxY8yEfyDTzs,6441
|
|
39
39
|
proj_flow/ext/github/hosting.py,sha256=3iW8QjeJk7MyqKNbv92nB-5a_Yn_B5_eEIlw_cdgUT0,519
|
|
40
|
-
proj_flow/ext/github/publishing.py,sha256=
|
|
40
|
+
proj_flow/ext/github/publishing.py,sha256=IXiQ5O3dA5ctGa46rCynZofF4Ixg85QhMHBaPZ-Uk10,1947
|
|
41
41
|
proj_flow/ext/github/switches.py,sha256=Y3pqJdiHYLoveCQtqZqELR84Phb2YF4u5y78TU7n2CQ,752
|
|
42
42
|
proj_flow/ext/python/__init__.py,sha256=GbEKEJJZ3PJ4sRHEykAWjGIR6yyyrYdlUFulldvsAGI,252
|
|
43
|
-
proj_flow/ext/python/rtdocs.py,sha256=
|
|
44
|
-
proj_flow/ext/python/steps.py,sha256=
|
|
45
|
-
proj_flow/ext/python/version.py,sha256=
|
|
46
|
-
proj_flow/ext/sign/__init__.py,sha256=
|
|
43
|
+
proj_flow/ext/python/rtdocs.py,sha256=kNPlrnmFLXIbtWB-WuEAgwpymNnI-qXF0P1cHJXfgiM,7116
|
|
44
|
+
proj_flow/ext/python/steps.py,sha256=c2ZXaS6F0p1euQrsZMLuSjisUTmZd-CFKWhbk7RnOQI,1865
|
|
45
|
+
proj_flow/ext/python/version.py,sha256=wgrhWCYSnJsAg52rijvX7WxAyKQwgh-oSRIp5uRk5hs,3216
|
|
46
|
+
proj_flow/ext/sign/__init__.py,sha256=IMnFqRdl9e-EejXsIiifHs6dF4jkujQHbvbNXWjDP50,4298
|
|
47
47
|
proj_flow/ext/sign/api.py,sha256=l5SO5RHiHTwxg0aexkGOfApRdojWDcIBY_cfbKSKsC0,2286
|
|
48
48
|
proj_flow/ext/sign/win32.py,sha256=yMAmO-DdIWZdOi_NxycRym8XM9WIsrWKtFANdIwthJ4,4968
|
|
49
|
+
proj_flow/ext/test_runner/__init__.py,sha256=dgPOf6b4AnoHVtPvhHrfC46m_4I-CCXvhQUsI-rXD-E,163
|
|
50
|
+
proj_flow/ext/test_runner/cli.py,sha256=qxDx5GJwbxK7ULlbgWpNKY9m_bMrHlRe7JdIuabU0T4,11880
|
|
51
|
+
proj_flow/ext/test_runner/driver/__init__.py,sha256=VJs_ODnF7-8DE0MbYKX-Bs-JDNqHgGdMkk2w142bcYQ,101
|
|
52
|
+
proj_flow/ext/test_runner/driver/commands.py,sha256=TzG9aqdUZLNa7yI2DajK7M7Ehhi_t8D_nEY6m1uICLo,2217
|
|
53
|
+
proj_flow/ext/test_runner/driver/test.py,sha256=xcZcBLNMkIN-jIQjtd7ke6Ngs4laTTd0TtMG_x_GlvE,19213
|
|
54
|
+
proj_flow/ext/test_runner/driver/testbed.py,sha256=jhxRvOXT1iEFIut9LIgJbixk7mUta9nKrcBEicaGhZA,4256
|
|
55
|
+
proj_flow/ext/test_runner/utils/__init__.py,sha256=VJs_ODnF7-8DE0MbYKX-Bs-JDNqHgGdMkk2w142bcYQ,101
|
|
56
|
+
proj_flow/ext/test_runner/utils/archives.py,sha256=f7whwVUeh5YtRwXxGCDs7CCRLd38aWPjwfb4bHBXyvI,1325
|
|
49
57
|
proj_flow/ext/tools/__init__.py,sha256=m9iJeCkdmrqLjBWNx9hp4o1H2kgzIXpgypHiSf3SzKE,373
|
|
50
58
|
proj_flow/ext/tools/pragma_once.py,sha256=BiNvX5X5pX_bGPZwBaKISlL6KkxJJGWFeZGSO-UDAgo,1218
|
|
51
59
|
proj_flow/ext/tools/run_linter.py,sha256=_EdmTfITc_hwI5hgMc_mKFkbw4unnDGkWaFohs0RDr4,6145
|
|
@@ -82,11 +90,11 @@ proj_flow/log/error.py,sha256=65Nvhfs_d1xSY4EB-ISdWgjotvg-on3iKjhAWHpsBYM,841
|
|
|
82
90
|
proj_flow/log/fmt.py,sha256=o14aO3iEt5_KKp9SqcfkscqbMKuTI83NBoSXHcrb7Kg,330
|
|
83
91
|
proj_flow/log/format.py,sha256=gp1kUoW0nYj5e7Ysu1c29Fh2ssfE1KBSDIYeUbhzN9g,333
|
|
84
92
|
proj_flow/log/msg.py,sha256=zARmRZHFV3yG-fBnx00wal4Y0O5aGnL-6XcGwNBNKA4,6758
|
|
85
|
-
proj_flow/log/release.py,sha256=
|
|
93
|
+
proj_flow/log/release.py,sha256=h3DI7yqTjrnVIlbyfVyrsxQ4GDO9OXiAJKpn3esCL-Y,4520
|
|
86
94
|
proj_flow/log/hosting/__init__.py,sha256=9Teyw8jJcxeWH2MegqYEgW0n5OmSAWC7FFJj2u_UcrM,278
|
|
87
95
|
proj_flow/log/hosting/github.py,sha256=O2BdB50vzVSKKIu3qNEYBiBdEUIPqj6C2xVvGAKjTZ4,9123
|
|
88
96
|
proj_flow/log/rich_text/__init__.py,sha256=D3Y2jy9xlGgnQZdNC_ekoLzQtwkF_NTgLqDTWPvSRUk,279
|
|
89
|
-
proj_flow/log/rich_text/api.py,sha256=
|
|
97
|
+
proj_flow/log/rich_text/api.py,sha256=dJq2QMPbO4XczK4qux7q2Sb3vkGD_khUdn_N1FI8fBY,3513
|
|
90
98
|
proj_flow/log/rich_text/markdown.py,sha256=jBnNxxhBHzyIZ3Y4HXDfqpl7zlRbbKbKdwdnZwkmNAI,1623
|
|
91
99
|
proj_flow/log/rich_text/re_structured_text.py,sha256=DEl9KjBUF6cxfNWpQ7GVnHi7wKeuFnPGJwxQxjbCsnM,1823
|
|
92
100
|
proj_flow/minimal/__init__.py,sha256=Yv32uwmS5a9SXSjaMVK0xKla9sWtcA8QkJHt15ffhiU,354
|
|
@@ -94,9 +102,10 @@ proj_flow/minimal/base.py,sha256=jFAiJICAD6izCBqsNgt7syZ_lynpC5goNuEsaQv1a44,122
|
|
|
94
102
|
proj_flow/minimal/bootstrap.py,sha256=PcZfBsUmj8uDPGBC55iUgD5O7W4VSkpCQb6r9GEyAaQ,556
|
|
95
103
|
proj_flow/minimal/init.py,sha256=-ZNzhPFqAgZFAuN5hYOJFuFy_wHkPzjeSk90G2GUQfk,4365
|
|
96
104
|
proj_flow/minimal/list.py,sha256=FIp49D0BW2UcOggibP_-5Ar1Ao_UmERMqHMDxNO7fRQ,8338
|
|
97
|
-
proj_flow/minimal/run.py,sha256=
|
|
105
|
+
proj_flow/minimal/run.py,sha256=ASYisLyhPGVuDcaRIiZ5K7dtuaHXVihDskRSuveLccM,4702
|
|
98
106
|
proj_flow/minimal/system.py,sha256=9FliH5TD103JYSAe2O5EU7hkOHDgVzTqu0Exxk-WrXE,1579
|
|
99
|
-
proj_flow/minimal/ext/bug_report.py,sha256=
|
|
107
|
+
proj_flow/minimal/ext/bug_report.py,sha256=YxaS0LjSPaDQARuhQUVSCqe4URIOa4VIhKfzDJqCcYA,2341
|
|
108
|
+
proj_flow/minimal/ext/versions.py,sha256=nj_AMnDKbDnHF55UtPc0aX0F8MGQOM12DkCgNGjJb-4,1539
|
|
100
109
|
proj_flow/project/__init__.py,sha256=AROrwhbuMR5rJE-HC769eL4IXrMLQYpQb3HgpkOAYqg,293
|
|
101
110
|
proj_flow/project/api.py,sha256=j0j3UBWi8vwGLIScSL7t2fWUr2-ezAilYkc1FM-EfYM,2103
|
|
102
111
|
proj_flow/project/data.py,sha256=TluhBDoJEYL4dnyTpInmhQ49Uvf8mkWmpU-YMLQPNhE,317
|
|
@@ -160,8 +169,8 @@ proj_flow/template/licenses/MIT.mustache,sha256=NncPoQaNsuy-WmRmboik3fyhJJ8m5pc2
|
|
|
160
169
|
proj_flow/template/licenses/Unlicense.mustache,sha256=awOCsWJ58m_2kBQwBUGWejVqZm6wuRtCL2hi9rfa0X4,1211
|
|
161
170
|
proj_flow/template/licenses/WTFPL.mustache,sha256=lvF4V_PrKKfZPa2TC8CZo8tlqaKvs3Bpv9G6XsWWQ4k,483
|
|
162
171
|
proj_flow/template/licenses/Zlib.mustache,sha256=uIj-mhSjes2HJ3rRapyy2ALflKRz4xQgS4mVM9827C0,868
|
|
163
|
-
proj_flow-0.
|
|
164
|
-
proj_flow-0.
|
|
165
|
-
proj_flow-0.
|
|
166
|
-
proj_flow-0.
|
|
167
|
-
proj_flow-0.
|
|
172
|
+
proj_flow-0.22.1.dist-info/METADATA,sha256=dWZixZZDgrrewFkhT7yvGMRoYUIdGtVKdtDkek58UbM,3472
|
|
173
|
+
proj_flow-0.22.1.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
|
|
174
|
+
proj_flow-0.22.1.dist-info/entry_points.txt,sha256=d_OmGKZzpY7FCWz0sZ4wnBAPZC75oMEzTgJZWtpDELo,49
|
|
175
|
+
proj_flow-0.22.1.dist-info/licenses/LICENSE,sha256=vpOQJ5QlrTedF3coEWvA4wJzVJH304f66ZitR7Od4iU,1068
|
|
176
|
+
proj_flow-0.22.1.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|