proj-flow 0.20.2__py3-none-any.whl → 0.21.0__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 CHANGED
@@ -6,4 +6,4 @@ The **proj_flow** contains only ``__version__`` to be updated, nothing more.
6
6
  This is in an attempt to make this module easy to load initially.
7
7
  """
8
8
 
9
- __version__ = "0.20.2"
9
+ __version__ = "0.21.0"
proj_flow/api/arg.py CHANGED
@@ -159,6 +159,8 @@ def command(*name: str):
159
159
  doc = orig_doc or ""
160
160
  if doc:
161
161
  doc += "\n\n"
162
+ doc += f":call: ``proj-flow {' '.join(name)}``\n\n"
163
+ doc += f":call: ``./flow {' '.join(name)}``\n\n"
162
164
 
163
165
  for arg in _inspect.signature(entry):
164
166
  help = ""
proj_flow/api/env.py CHANGED
@@ -173,12 +173,18 @@ def load_extensions(extensions: List[str]):
173
173
  for extension in extensions:
174
174
  try:
175
175
  importlib.import_module(extension)
176
- except ModuleNotFoundError:
176
+ except ImportError as ex:
177
177
  print(
178
- f"-- error: module `{extension}` was no found, ignoring",
178
+ f"-- error: loading module `{extension}` resulted in import error: {ex}",
179
+ file=sys.stderr,
180
+ )
181
+ except BaseException as ex:
182
+ print(
183
+ f"-- error: there was an error while loading module `{extension}`: {ex}",
179
184
  file=sys.stderr,
180
185
  )
181
186
 
187
+
182
188
  class FlowConfig:
183
189
  _cfg: dict
184
190
  steps: list = []
@@ -253,6 +259,10 @@ class FlowConfig:
253
259
  def postproc_exclude(self) -> List[dict]:
254
260
  return self.postproc.get("exclude", [])
255
261
 
262
+ @property
263
+ def postproc_include(self) -> List[dict]:
264
+ return self.postproc.get("include", [])
265
+
256
266
  @property
257
267
  def shortcuts(self) -> Dict[str, dict]:
258
268
  return self._cfg.get("shortcuts", {})
proj_flow/api/step.py CHANGED
@@ -87,8 +87,10 @@ def _register_step(step: Step, replace: bool):
87
87
  return
88
88
 
89
89
  if "READTHEDOCS" not in os.environ:
90
- raise NameError(f"Step {name} is marked as replacing, but there is no previous step with that name")
91
-
90
+ raise NameError(
91
+ f"Step {name} is marked as replacing, but there is no previous step with that name"
92
+ )
93
+
92
94
  if name in [step.name for step in __steps]:
93
95
  if "READTHEDOCS" not in os.environ:
94
96
  raise NameError(f"Step {name} already registered")
@@ -133,6 +135,12 @@ def _make_private(f: _inspect.Function):
133
135
  f.__doc__ = ":meta private:\n"
134
136
 
135
137
 
138
+ def _make_private_property(f):
139
+ if isinstance(f, property):
140
+ _make_private(cast(_inspect.Function, f))
141
+ return
142
+
143
+
136
144
  _dummy_config = Config(
137
145
  {
138
146
  "os": "${os}",
@@ -163,6 +171,9 @@ def _extend_docstring(conv, step: Step):
163
171
  doc = conv.__doc__ or "*Docstring is missing!*"
164
172
  conv.__doc__ = f"{doc}\n{info}"
165
173
 
174
+ _make_private_property(conv.name)
175
+ _make_private_property(conv.runs_before)
176
+ _make_private_property(conv.runs_after)
166
177
  _make_private(conv.is_active)
167
178
  _make_private(conv.run)
168
179
  _make_private(conv.platform_dependencies)
proj_flow/base/matrix.py CHANGED
@@ -86,6 +86,29 @@ def matches(tested: dict, test: dict) -> bool:
86
86
  return True
87
87
 
88
88
 
89
+ def partially_matches(tested: dict, test: dict) -> bool:
90
+ """
91
+ Checks, if the tested dictionary contains some of the values from test
92
+ dictionary, with non-zero intersection between both dictionaries.
93
+
94
+ :param tested: Dictionary to check
95
+ :param test: Dictionary to check against
96
+
97
+ :returns: `True`, if all keys from `test` are in `tested` and have the same
98
+ values, `False` otherwise.
99
+ """
100
+
101
+ intersection_size = 0
102
+ for key, value in test.items():
103
+ if key not in tested:
104
+ continue
105
+ val = tested.get(key)
106
+ if val != value:
107
+ return False
108
+ intersection_size += 1
109
+ return intersection_size > 0
110
+
111
+
89
112
  def matches_any(tested: dict, tests: List[dict]):
90
113
  """
91
114
  Checks, if the tested dictionary contains all the values from at least one
@@ -135,10 +135,14 @@ class Presets:
135
135
 
136
136
  @staticmethod
137
137
  def __load_file(filename: Path):
138
- with open(filename, encoding="UTF-8") as f:
139
- data = json.load(f)
140
- includes = cast(list[str], data.get("include", []))
141
- presets = cast(list[dict], data.get("configurePresets", []))
138
+ try:
139
+ with open(filename, encoding="UTF-8") as f:
140
+ data = json.load(f)
141
+ includes = cast(list[str], data.get("include", []))
142
+ presets = cast(list[dict], data.get("configurePresets", []))
143
+ except FileNotFoundError:
144
+ includes: list[str] = []
145
+ presets: list[dict] = []
142
146
 
143
147
  return (includes, presets)
144
148
 
@@ -22,14 +22,17 @@ class CMakeBase(api.step.Step):
22
22
 
23
23
  @property
24
24
  def name(self):
25
+ """:meta private:"""
25
26
  return self._name
26
27
 
27
28
  @property
28
29
  def runs_after(self):
30
+ """:meta private:"""
29
31
  return self._runs_after
30
32
 
31
33
  @property
32
34
  def runs_before(self):
35
+ """:meta private:"""
33
36
  return self._runs_before
34
37
 
35
38
  def __init__(
@@ -47,6 +50,7 @@ class CMakeBase(api.step.Step):
47
50
  return [f"cmake>={CMAKE_VERSION}"]
48
51
 
49
52
  def dep_with_tool(self, tool: str):
53
+ """:meta private:"""
50
54
  return [f"cmake>={CMAKE_VERSION}", f"{tool}>={CMAKE_VERSION}"]
51
55
 
52
56
 
@@ -64,7 +68,9 @@ class CMakeConfig(CMakeBase):
64
68
  def directories_to_remove(self, config: env.Config) -> List[str]:
65
69
  binary_dir = self.binary_dirs.get(f"{config.preset}-{config.build_generator}")
66
70
  if not binary_dir:
67
- return []
71
+ if "READTHEDOCS" not in os.environ:
72
+ return []
73
+ return [f"build/{config.preset}"]
68
74
  return [binary_dir]
69
75
 
70
76
  def run(self, config: env.Config, rt: env.Runtime) -> int:
@@ -78,10 +84,10 @@ class CMakeConfig(CMakeBase):
78
84
  value = value[1:]
79
85
 
80
86
  if value.startswith("config:"):
81
- value = value[len("config:"):]
87
+ value = value[len("config:") :]
82
88
  value = config.get_path(value)
83
89
  elif value.startswith("runtime:"):
84
- value = value[len("runtime:"):]
90
+ value = value[len("runtime:") :]
85
91
  value = getattr(rt, value, None)
86
92
 
87
93
  if is_flag:
@@ -23,7 +23,9 @@ CONAN_PROFILE_GEN = "_profile-build_type"
23
23
  class ConanConfig:
24
24
  """Configures the project for ``preset`` config using ``build_type`` config."""
25
25
 
26
+ #: :meta private:
26
27
  name = "Conan"
28
+ #: :meta private:
27
29
  runs_before = ["CMake"]
28
30
 
29
31
  def platform_dependencies(self):
@@ -32,6 +32,7 @@ def github():
32
32
 
33
33
  @arg.command("github", "matrix")
34
34
  def matrix(
35
+ pretty: typing.Annotated[bool, arg.FlagArgument(help="Indent JSON document")],
35
36
  official: typing.Annotated[
36
37
  bool, arg.FlagArgument(help="Cut matrix to release builds only")
37
38
  ],
@@ -60,6 +61,8 @@ def matrix(
60
61
  print(f"matrix={var}", file=github_output)
61
62
  else:
62
63
  print(f"matrix={var}")
64
+ elif pretty:
65
+ json.dump(usable, sys.stdout, indent=2)
63
66
  else:
64
67
  json.dump(usable, sys.stdout)
65
68
 
@@ -3,7 +3,7 @@
3
3
 
4
4
  """
5
5
  The **proj_flow.ext.python.rtdocs** defines RTDocs step (`"RTD"`), which uses
6
- .readthedocs.yaml to build the HTML documentation.
6
+ ``.readthedocs.yaml`` to build the HTML documentation.
7
7
  """
8
8
 
9
9
  import os
@@ -20,7 +20,11 @@ from proj_flow.base import cmd
20
20
 
21
21
  @step.register
22
22
  class RTDocs:
23
- name = "RTD"
23
+ """Runs the jobs defined by ``.readthedocs.yaml`` to build the docs"""
24
+
25
+ @property
26
+ def name(self):
27
+ return "RTD"
24
28
 
25
29
  def platform_dependencies(self):
26
30
  return ["python -m PyYAML"]
@@ -100,6 +104,8 @@ class RTDocs:
100
104
 
101
105
 
102
106
  class Builder(ABC):
107
+ """Base class for any recognized builder in the ``.readthedocs.yaml`` config."""
108
+
103
109
  @property
104
110
  @abstractmethod
105
111
  def READTHEDOCS_OUTPUT(self) -> str: ...
@@ -112,17 +118,40 @@ class Builder(ABC):
112
118
 
113
119
 
114
120
  class Sphinx(Builder):
115
- READTHEDOCS_OUTPUT: str = ""
121
+ """Builder used, if Sphinx config is found in the config file.
122
+
123
+ :param config: filename of a Python script Sphinx should use for the configuration
124
+ """
125
+
126
+ @property
127
+ def READTHEDOCS_OUTPUT(self) -> str:
128
+ """A ``build/`` subdirectory placed in the same dir, as ``config`` parameter"""
129
+ return self.output
116
130
 
117
131
  def __init__(self, config: str):
118
132
  self.config = config
119
133
  self.source = os.path.dirname(config)
120
- self.READTHEDOCS_OUTPUT = os.path.join(os.path.dirname(self.source), "build")
134
+ self.output = os.path.join(os.path.dirname(self.source), "build")
121
135
 
122
- def build(self, target: str):
136
+ def build(self, target: str) -> int:
137
+ """Uses ``spinx-build`` to create the documentation.
138
+
139
+ :param target: name of the docs format from YAML config
140
+ :returns: exit code forwarded from the build tool
141
+ """
123
142
  builder = "latex" if target == "pdf" else target
143
+ print(shutil.which("sphinx-build"))
144
+
124
145
  return subprocess.run(
125
- ["sphinx-build", "-M", builder, self.source, self.READTHEDOCS_OUTPUT],
146
+ [
147
+ PYTHON_EXECUTABLE,
148
+ "-m",
149
+ "sphinx.cmd.build",
150
+ "-M",
151
+ builder,
152
+ self.source,
153
+ self.READTHEDOCS_OUTPUT,
154
+ ],
126
155
  shell=False,
127
156
  ).returncode
128
157
 
proj_flow/flow/configs.py CHANGED
@@ -9,6 +9,7 @@ using ``-D`` switches.
9
9
 
10
10
 
11
11
  import argparse
12
+ import copy
12
13
  import datetime
13
14
  import os
14
15
  import sys
@@ -152,6 +153,19 @@ def _load_flow_data(rt: env.Runtime):
152
153
  return configs, keys
153
154
 
154
155
 
156
+ def _apply_postproc_includes(config: dict, postproc_include: List[dict]):
157
+ clone = copy.deepcopy(config)
158
+ for ext in postproc_include:
159
+ if not matrix.partially_matches(config, ext):
160
+ continue
161
+
162
+ for key, value in ext.items():
163
+ if key in config:
164
+ continue
165
+ clone[key] = value
166
+ return clone
167
+
168
+
155
169
  class Configs:
156
170
  usable: List[env.Config] = []
157
171
 
@@ -186,8 +200,9 @@ class Configs:
186
200
  )
187
201
 
188
202
  postproc_exclude = rt.postproc_exclude
203
+ postproc_include = rt.postproc_include
189
204
  usable = [
190
- config
205
+ _apply_postproc_includes(config, postproc_include)
191
206
  for config in turned
192
207
  if len(postproc_exclude) == 0
193
208
  or not matrix.matches_any(config, postproc_exclude)
proj_flow/minimal/list.py CHANGED
@@ -6,12 +6,20 @@ The **proj_flow.minimal.list** implements ``./flow list`` command.
6
6
  """
7
7
 
8
8
  import os
9
- from typing import Annotated, Dict, List, Set, cast
9
+ import re
10
+ import sys
11
+ from typing import Annotated, Dict, Iterable, List, Set, cast
10
12
 
11
13
  from proj_flow import cli
12
14
  from proj_flow.api import arg, env, step
13
15
  from proj_flow.base import matrix
14
16
 
17
+ if sys.platform == "win32":
18
+ import ctypes
19
+ import ctypes.wintypes
20
+ else:
21
+ import termios
22
+
15
23
 
16
24
  @arg.command("list")
17
25
  def main(
@@ -39,10 +47,7 @@ def main(
39
47
  configs = True
40
48
 
41
49
  if builtin:
42
- root = menu
43
- while root.parent is not None:
44
- root = root.parent
45
- builtin_entries = list(sorted((cmd.name, cmd.doc) for cmd in root.children))
50
+ builtin_entries = list(sorted(_walk_menu(menu)))
46
51
  if not pipe and len(builtin_entries) > 0:
47
52
  print("Builtin commands")
48
53
  print("----------------")
@@ -54,7 +59,10 @@ def main(
54
59
 
55
60
  name = f"{bold}{entry_name}{reset}"
56
61
  if entry_doc:
57
- print(f"- {name}: {entry_doc}")
62
+ print(f"- {name}:", end=" ")
63
+ _write_console_para(
64
+ " ".join(para.split("\n")) for para in entry_doc.split("\n\n")
65
+ )
58
66
  else:
59
67
  print(f"- {name}")
60
68
 
@@ -76,7 +84,8 @@ def main(
76
84
  continue
77
85
 
78
86
  name = f"{bold}{run_alias.name}{reset}"
79
- print(f"- {name}: {', '.join(run_alias.steps)}")
87
+ print(f"- {name}:", end=" ")
88
+ _write_console_para([", ".join(run_alias.steps)])
80
89
 
81
90
  printed_something = True
82
91
 
@@ -109,8 +118,10 @@ def main(
109
118
  print(f"- {name}*")
110
119
 
111
120
  if some_unused:
112
- print(
113
- f"*step can only be run by explicitly calling through {bold}run{reset}."
121
+ _write_console_para(
122
+ [
123
+ f"*step can only be run by explicitly calling through {bold}run{reset}."
124
+ ]
114
125
  )
115
126
 
116
127
  printed_something = True
@@ -147,7 +158,8 @@ def main(
147
158
  value = ", ".join(values.get(key, empty))
148
159
  name = f"{bold}{key}{reset}"
149
160
  if value:
150
- print(f"- {name}: {value}")
161
+ print(f"- {name}:", end=" ")
162
+ _write_console_para([value])
151
163
  else:
152
164
  print(f"- {name}")
153
165
 
@@ -157,6 +169,110 @@ def main(
157
169
  print(f"Use {bold}--help{reset} to see, which listings are available")
158
170
 
159
171
 
172
+ def _iterate_levels(menu: cli.argument.Command, prefix: str):
173
+ yield [(f"{prefix}{cmd.name}", cmd.doc) for cmd in menu.children]
174
+ for cmd in menu.children:
175
+ child_prefix = f"{prefix}{cmd.name} "
176
+ for layer in _iterate_levels(cmd, child_prefix):
177
+ yield layer
178
+
179
+
180
+ def _walk_menu(menu: cli.argument.Command):
181
+ root = menu
182
+ while root.parent is not None:
183
+ root = root.parent
184
+
185
+ items: list[tuple[str, str]] = []
186
+ for layer in _iterate_levels(root, ""):
187
+ items.extend(layer)
188
+
189
+ return items
190
+
191
+
192
+ def _cursor_pos():
193
+ if sys.platform == "win32":
194
+ old_stdin_mode = ctypes.wintypes.DWORD()
195
+ old_stdout_mode = ctypes.wintypes.DWORD()
196
+ kernel32 = ctypes.windll.kernel32
197
+ kernel32.GetConsoleMode(
198
+ kernel32.GetStdHandle(-10), ctypes.byref(old_stdin_mode)
199
+ )
200
+ kernel32.SetConsoleMode(kernel32.GetStdHandle(-10), 0)
201
+ kernel32.GetConsoleMode(
202
+ kernel32.GetStdHandle(-11), ctypes.byref(old_stdout_mode)
203
+ )
204
+ kernel32.SetConsoleMode(kernel32.GetStdHandle(-11), 7)
205
+ else:
206
+ old_stdin_mode = termios.tcgetattr(sys.stdin)
207
+ _ = termios.tcgetattr(sys.stdin)
208
+ _[3] = _[3] & ~(termios.ECHO | termios.ICANON)
209
+ termios.tcsetattr(sys.stdin, termios.TCSAFLUSH, _)
210
+ try:
211
+ _ = ""
212
+ sys.stdout.write("\x1b[6n")
213
+ sys.stdout.flush()
214
+ while not (_ := _ + sys.stdin.read(1)).endswith("R"):
215
+ pass
216
+ res = re.match(r".*\[(?P<y>\d*);(?P<x>\d*)R", _)
217
+ finally:
218
+ if sys.platform == "win32":
219
+ kernel32.SetConsoleMode(kernel32.GetStdHandle(-10), old_stdin_mode)
220
+ kernel32.SetConsoleMode(kernel32.GetStdHandle(-11), old_stdout_mode)
221
+ else:
222
+ termios.tcsetattr(sys.stdin, termios.TCSAFLUSH, old_stdin_mode)
223
+ if res:
224
+ return (int(res.group("x")), int(res.group("y")))
225
+ return (1, 1)
226
+
227
+
228
+ def _write_console_para(text: Iterable[str]):
229
+ term_width = os.get_terminal_size().columns
230
+ margin = min(_cursor_pos()[0], term_width // 2) - 1
231
+ width = term_width - 1
232
+ pos = margin
233
+ for para in text:
234
+ for word in para.split():
235
+ if not word:
236
+ continue
237
+ word_len = len(word)
238
+ next_pos = pos + word_len + 1
239
+
240
+ if next_pos >= width:
241
+ orig = pos
242
+ if orig == margin:
243
+ pos = margin - word_len
244
+ print(word, end="")
245
+
246
+ print()
247
+ print(" " * margin, end="")
248
+
249
+ if orig != margin:
250
+ pos = margin
251
+ print(word, end=" ")
252
+ else:
253
+ print(word, end=" ")
254
+
255
+ pos += word_len + 1
256
+
257
+ continue
258
+ if (word_len + 1) > term_width:
259
+ first_word = pos == margin
260
+ if first_word:
261
+ print(word, end="")
262
+
263
+ print(f"\n{' ' * margin}", end="")
264
+ pos = margin
265
+
266
+ if not first_word:
267
+ print(word, "", end="")
268
+ pos += word_len + 1
269
+ continue
270
+
271
+ print(word, "", end="")
272
+ pos += word_len + 1
273
+ print()
274
+
275
+
160
276
  def _load_flow_data(rt: env.Runtime):
161
277
  paths = [os.path.join(".flow", "matrix.yml")]
162
278
  m, keys = matrix.load_matrix(*paths)
proj_flow/project/api.py CHANGED
@@ -67,5 +67,6 @@ def get_project_type(id: str):
67
67
  raise ProjectNotFound(id)
68
68
  return result
69
69
 
70
+
70
71
  def load_common_init_setting_extensions():
71
72
  env.load_extensions(["proj_flow.ext.github.switches"])
@@ -1,12 +1,13 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: proj-flow
3
- Version: 0.20.2
3
+ Version: 0.21.0
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/
7
7
  Project-URL: Homepage, https://pypi.org/project/proj-flow/
8
8
  Project-URL: Source Code, https://github.com/mzdun/proj-flow
9
9
  Author-email: Marcin Zdun <marcin.zdun@gmail.com>
10
+ License-Expression: MIT
10
11
  License-File: LICENSE
11
12
  Keywords: C/C++,build-tool,c++,ci-cd,continuous-integration,cpp,dependencies,dependency-manager,developer,developer-tools,development,meta-build-tool,pipeline,tools-and-automation
12
13
  Classifier: Development Status :: 4 - Beta
@@ -17,13 +18,22 @@ Classifier: Programming Language :: Python :: 3
17
18
  Classifier: Programming Language :: Python :: 3.10
18
19
  Classifier: Topic :: Software Development :: Build Tools
19
20
  Requires-Python: >=3.10
20
- Requires-Dist: argcomplete
21
+ Requires-Dist: argcomplete~=3.5
21
22
  Requires-Dist: chevron2021
22
- Requires-Dist: prompt-toolkit
23
- Requires-Dist: pywebidl2
24
- Requires-Dist: pyyaml
25
- Requires-Dist: requests-cache
26
- Requires-Dist: toml
23
+ Requires-Dist: prompt-toolkit~=3.0
24
+ Requires-Dist: pywebidl2~=0.1
25
+ Requires-Dist: pyyaml~=6.0
26
+ Requires-Dist: requests-cache~=1.3
27
+ Requires-Dist: toml~=0.10
28
+ Provides-Extra: dev
29
+ Requires-Dist: black~=25.0; extra == 'dev'
30
+ Requires-Dist: build~=1.4; extra == 'dev'
31
+ Requires-Dist: isort~=6.0; extra == 'dev'
32
+ Requires-Dist: sphinx~=9.1; extra == 'dev'
33
+ Requires-Dist: twine<=6.0.1; extra == 'dev'
34
+ Requires-Dist: types-chevron~=0.14; extra == 'dev'
35
+ Requires-Dist: types-pyyaml~=6.0; extra == 'dev'
36
+ Requires-Dist: types-toml~=0.10; extra == 'dev'
27
37
  Description-Content-Type: text/markdown
28
38
 
29
39
  # Project Flow
@@ -1,20 +1,20 @@
1
- proj_flow/__init__.py,sha256=PkM-YJk5w2cnqbyXWisD3JS7cOhRZPxAmQnEVbPSL4Q,277
1
+ proj_flow/__init__.py,sha256=Ef26YQuXsAeNUbAaqbrbiJborj7G6r-Xkd-gLQdaSLQ,277
2
2
  proj_flow/__main__.py,sha256=HUar_qQ9Ndmchmryegtzu__5wukwCLrFN_SGRl5Ol_M,233
3
3
  proj_flow/dependency.py,sha256=CpcnR6El8AO9hlLc9lQtYQADYlkx3GMHlkLYbEAtdMI,4639
4
4
  proj_flow/api/__init__.py,sha256=gV2f6kll_5JXtvkGASvnx7CbOWr34PHOdck-4ce-qEk,378
5
- proj_flow/api/arg.py,sha256=3XqPAucon0k3yyYsqzSp7X9HGMZ_sNJNo8Z4hf-0erY,5275
5
+ proj_flow/api/arg.py,sha256=0sVVEqdIOCqWmZtST_-u4rP6JkrResGJsKERQp3WYgc,5392
6
6
  proj_flow/api/completers.py,sha256=NapNVu6QAQ_iF6dqcAzOV5kDHKD9MAMVX209Bklq-Mw,2464
7
7
  proj_flow/api/ctx.py,sha256=IJu0q0Chivo6b2M4MKkAlV09oi7Cn9VxtDFeAeL_tnc,6646
8
- proj_flow/api/env.py,sha256=rbNtMB6bBRhUb6bolNduWVWZ7a5CIsnv8EEZsamT9Ek,12678
8
+ proj_flow/api/env.py,sha256=Tjgz73TPF6SotyxsZy1L7oid2FSnBQwJu8r1qDyC7WU,12994
9
9
  proj_flow/api/init.py,sha256=p4ZDGfq6fw4bXbJu2iq0vEmVxbS7nALIhZfe-XnEs44,565
10
10
  proj_flow/api/makefile.py,sha256=q0fBSsWTWfR5YwunwiRjWJKtiLeHdSKUgUTEgo5I7dE,3863
11
11
  proj_flow/api/release.py,sha256=IM4axJ6dfyilCmpwL_Z8q43XGKsfHaPoMAdqSziwT7s,2810
12
- proj_flow/api/step.py,sha256=C6LfjAN5edYjlpkhd6k9eMO9SLfLtyS2ZG1Rg_dLcjg,4926
12
+ proj_flow/api/step.py,sha256=3yxWWCRqWB-2iro7oA_247xqykiMCrI4hKQV5uemJak,5205
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
15
  proj_flow/base/cmd.py,sha256=XJk_r4Nlq_2XGgD_w92Us4WKwItmQAB8QWdT1pKxUFA,1746
16
16
  proj_flow/base/inspect.py,sha256=lt5P19rvSZ-wMCTrCYAaQFCt2S9fUjEQXlrKK-Tmvwc,2786
17
- proj_flow/base/matrix.py,sha256=8XBFGYOwW6Myt_4h3WNk36V2bJ5xeqUv6DvzF4B3q_g,7767
17
+ proj_flow/base/matrix.py,sha256=kH2BB6JRrLYdR71VJiJp58zfQSazwEOeiRXOPrayAcI,8446
18
18
  proj_flow/base/name_list.py,sha256=KiHSnbDgYplJc25O3EehYhFAhD7Z3mHVAK6UYOdg5PQ,416
19
19
  proj_flow/base/plugins.py,sha256=evn2Dym_NeoBaIZAu2YUtRd--15PCFpHD0h5zSsWkQE,978
20
20
  proj_flow/base/registry.py,sha256=zbkB9KNfHnyPtzOurdvjwt714jrFpGHyOqeZL5sMvzI,3745
@@ -29,18 +29,18 @@ proj_flow/ext/store.py,sha256=zc9yh9M042V5OSLUZjWe9KazhdZ35h1JJsWvKughM0Y,3385
29
29
  proj_flow/ext/cplusplus/__init__.py,sha256=dAmLMyGVQq586jJM_jiAuo5Ecw9U8agpvSRbzzPgh3g,245
30
30
  proj_flow/ext/cplusplus/cmake/__init__.py,sha256=uQPclC2Bs5qVR_VnoYYPGUbzkzR2gU4RLThcTumYXUE,366
31
31
  proj_flow/ext/cplusplus/cmake/parser.py,sha256=ZqQRZqS_VU5VtC8uwax-dknh7sfuLEvtazG8ChSqHDQ,3814
32
- proj_flow/ext/cplusplus/cmake/presets.py,sha256=iYtSlkIoY3fEa6GL95zJugJbmleV5NPPB9UhME8RbSA,4922
32
+ proj_flow/ext/cplusplus/cmake/presets.py,sha256=hrAMgFj9TP8mguNsGgRKB4rDOMHIrC77sJKn2SzEAOM,5059
33
33
  proj_flow/ext/cplusplus/cmake/project.py,sha256=Cp-5HwEsrQW4RjDThjMBQmaVJiRHo9QvYbw7IvjHKNQ,929
34
- proj_flow/ext/cplusplus/cmake/steps.py,sha256=MnxPTR9tD2O8_DaRSe-fkvkpoM-DZc2zqt-J84xA_fI,4353
35
- proj_flow/ext/cplusplus/conan/__init__.py,sha256=Fv839SWsKPWMZs9ox9T-bofZ4xDJXOI5UfWKQkm0Vtg,1924
34
+ proj_flow/ext/cplusplus/cmake/steps.py,sha256=t4izW8CByc-kgzJEDoqGcKNh3c77e3GcwbsnCVSBkw4,4569
35
+ proj_flow/ext/cplusplus/conan/__init__.py,sha256=3PdwAeNthjg6rK4EaNDphMVVHvcG4Dx0vtYzSmBIgJY,1968
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
- proj_flow/ext/github/cli.py,sha256=F7kkrngeTp76_FCfGA7olVzf38I6aj8S8-fXpiYYp04,6293
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
40
  proj_flow/ext/github/publishing.py,sha256=5dUNFq47X_g9vo25R3lQRkSjV2IiAm2zkIhNe8gLDKs,1921
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=mICD6EAFgAkWG4wcQZG2_7Ito4lxo7Vl_GdM6-4K9hY,6249
43
+ proj_flow/ext/python/rtdocs.py,sha256=tbWYKVg8BL2aGAjCDGPms-7EOth9PsB5B5E1N3tuCeE,7146
44
44
  proj_flow/ext/python/steps.py,sha256=pDHGAe_CDzzdRFAzM1AIBvkbc14KB3SNUunusKZAaaY,1815
45
45
  proj_flow/ext/python/version.py,sha256=pnyuKATyZwBh1p0gf9KmqbRSZx8hJ5285CiFK_tHEaY,3159
46
46
  proj_flow/ext/sign/__init__.py,sha256=b9AN1_BalPtVy7YLBjvGhLamTujHEKcZP7npgDDDuSI,4296
@@ -73,7 +73,7 @@ proj_flow/ext/webidl/model/__init__.py,sha256=VJs_ODnF7-8DE0MbYKX-Bs-JDNqHgGdMkk
73
73
  proj_flow/ext/webidl/model/ast.py,sha256=_CzJPAarYruonVbK6mxfUc7MgFoxFDpXWjX4OEkOp3M,19238
74
74
  proj_flow/ext/webidl/model/builders.py,sha256=Ukjyhn4yJrSlU01P8VkLf0TE0kLqKlYw2KlyATceOpo,7665
75
75
  proj_flow/flow/__init__.py,sha256=5Zo97zJsR7HMbl64jeMB9PbUuxCxpOlNuLmo3apWSVU,277
76
- proj_flow/flow/configs.py,sha256=PQZ5pLPmWwHJtSWmuy04bsnO-VvfWcJyP_UyKjiaG1g,6535
76
+ proj_flow/flow/configs.py,sha256=zg32AXal2qbVOG6ToTfD05CTwRwt5rwF8yd-9UuB1nc,6999
77
77
  proj_flow/flow/layer.py,sha256=IUANtCSOvlfzNSnq0VDdGdaXfB70Yr-rDGFxPDQTmpg,6187
78
78
  proj_flow/flow/steps.py,sha256=PN_C_B6vNvqOsjpDpa5ESvH30Sc6RM1fSSqWqXgqg-4,2804
79
79
  proj_flow/log/__init__.py,sha256=02EIgasE-K7mmbbNiIdX0IebWQMp2Co_D6H4ZBhJgcs,365
@@ -93,12 +93,12 @@ proj_flow/minimal/__init__.py,sha256=Yv32uwmS5a9SXSjaMVK0xKla9sWtcA8QkJHt15ffhiU
93
93
  proj_flow/minimal/base.py,sha256=jFAiJICAD6izCBqsNgt7syZ_lynpC5goNuEsaQv1a44,1227
94
94
  proj_flow/minimal/bootstrap.py,sha256=PcZfBsUmj8uDPGBC55iUgD5O7W4VSkpCQb6r9GEyAaQ,556
95
95
  proj_flow/minimal/init.py,sha256=-ZNzhPFqAgZFAuN5hYOJFuFy_wHkPzjeSk90G2GUQfk,4365
96
- proj_flow/minimal/list.py,sha256=RlOqammE8olNKXsnbv1enF5uriu0MZ2wFbht37Z2ETw,4810
96
+ proj_flow/minimal/list.py,sha256=FIp49D0BW2UcOggibP_-5Ar1Ao_UmERMqHMDxNO7fRQ,8338
97
97
  proj_flow/minimal/run.py,sha256=4qvGLqz2ayCZDvVBrq4tG094fjfcmDPon-xcGPQkM_U,4665
98
98
  proj_flow/minimal/system.py,sha256=9FliH5TD103JYSAe2O5EU7hkOHDgVzTqu0Exxk-WrXE,1579
99
99
  proj_flow/minimal/ext/bug_report.py,sha256=dKy2FzVanoF3LISN5fsoaj-0TatGvVnahKuhy9HE4os,2311
100
100
  proj_flow/project/__init__.py,sha256=AROrwhbuMR5rJE-HC769eL4IXrMLQYpQb3HgpkOAYqg,293
101
- proj_flow/project/api.py,sha256=sWGrNisx6VwWxq5kwzBLkETkWshYrQOlKMBjZANMu2Y,2102
101
+ proj_flow/project/api.py,sha256=j0j3UBWi8vwGLIScSL7t2fWUr2-ezAilYkc1FM-EfYM,2103
102
102
  proj_flow/project/data.py,sha256=TluhBDoJEYL4dnyTpInmhQ49Uvf8mkWmpU-YMLQPNhE,317
103
103
  proj_flow/project/interact.py,sha256=t9brVfLC0HR3LUWs2RSBjMi7NgCBQc9_Ip1ut5oYVa4,9522
104
104
  proj_flow/project/cplusplus/__init__.py,sha256=cBjTOL8unMiPBWx9QkY4-vahzlHXNVNAxdaUTtVBjZM,302
@@ -160,8 +160,8 @@ proj_flow/template/licenses/MIT.mustache,sha256=NncPoQaNsuy-WmRmboik3fyhJJ8m5pc2
160
160
  proj_flow/template/licenses/Unlicense.mustache,sha256=awOCsWJ58m_2kBQwBUGWejVqZm6wuRtCL2hi9rfa0X4,1211
161
161
  proj_flow/template/licenses/WTFPL.mustache,sha256=lvF4V_PrKKfZPa2TC8CZo8tlqaKvs3Bpv9G6XsWWQ4k,483
162
162
  proj_flow/template/licenses/Zlib.mustache,sha256=uIj-mhSjes2HJ3rRapyy2ALflKRz4xQgS4mVM9827C0,868
163
- proj_flow-0.20.2.dist-info/METADATA,sha256=n_KqwMfHH1mhITMqq81WLyb3emTL2UDsD_2u3Qv1plM,3035
164
- proj_flow-0.20.2.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
165
- proj_flow-0.20.2.dist-info/entry_points.txt,sha256=d_OmGKZzpY7FCWz0sZ4wnBAPZC75oMEzTgJZWtpDELo,49
166
- proj_flow-0.20.2.dist-info/licenses/LICENSE,sha256=vpOQJ5QlrTedF3coEWvA4wJzVJH304f66ZitR7Od4iU,1068
167
- proj_flow-0.20.2.dist-info/RECORD,,
163
+ proj_flow-0.21.0.dist-info/METADATA,sha256=sTxFh9SPVTvanRQf1ccSU9Yo4_YbElioA_G5pI0YIW8,3472
164
+ proj_flow-0.21.0.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
165
+ proj_flow-0.21.0.dist-info/entry_points.txt,sha256=d_OmGKZzpY7FCWz0sZ4wnBAPZC75oMEzTgJZWtpDELo,49
166
+ proj_flow-0.21.0.dist-info/licenses/LICENSE,sha256=vpOQJ5QlrTedF3coEWvA4wJzVJH304f66ZitR7Od4iU,1068
167
+ proj_flow-0.21.0.dist-info/RECORD,,