proj-flow 0.9.4__py3-none-any.whl → 0.11.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 +6 -1
- proj_flow/api/arg.py +47 -24
- proj_flow/api/ctx.py +43 -23
- proj_flow/api/env.py +65 -2
- proj_flow/api/step.py +3 -5
- proj_flow/{ext/cplusplus/cmake/__version__.py → base/__cmake_version__.py} +5 -0
- proj_flow/base/name_list.py +19 -0
- proj_flow/base/registry.py +23 -3
- proj_flow/cli/__init__.py +1 -1
- proj_flow/cli/argument.py +2 -2
- proj_flow/{flow/dependency.py → dependency.py} +1 -1
- proj_flow/ext/cplusplus/cmake/__init__.py +2 -2
- proj_flow/ext/cplusplus/cmake/steps.py +1 -1
- proj_flow/ext/cplusplus/conan/__init__.py +2 -4
- proj_flow/ext/cplusplus/conan/_conan.py +1 -1
- proj_flow/ext/github/cli.py +2 -11
- proj_flow/ext/github/switches.py +2 -2
- proj_flow/flow/__init__.py +2 -2
- proj_flow/minimal/base.py +1 -0
- proj_flow/minimal/init.py +43 -10
- proj_flow/minimal/run.py +1 -2
- proj_flow/project/__init__.py +11 -0
- proj_flow/project/api.py +51 -0
- proj_flow/project/cplusplus/__init__.py +10 -0
- proj_flow/{ext/cplusplus/cmake/context.py → project/cplusplus/cmake_context.py} +10 -7
- proj_flow/project/cplusplus/conan_context.py +12 -0
- proj_flow/project/cplusplus/project.py +16 -0
- proj_flow/project/data.py +14 -0
- proj_flow/project/interact.py +255 -0
- {proj_flow-0.9.4.dist-info → proj_flow-0.11.0.dist-info}/METADATA +2 -2
- {proj_flow-0.9.4.dist-info → proj_flow-0.11.0.dist-info}/RECORD +34 -28
- proj_flow/flow/init.py +0 -65
- proj_flow/flow/interact.py +0 -134
- {proj_flow-0.9.4.dist-info → proj_flow-0.11.0.dist-info}/WHEEL +0 -0
- {proj_flow-0.9.4.dist-info → proj_flow-0.11.0.dist-info}/entry_points.txt +0 -0
- {proj_flow-0.9.4.dist-info → proj_flow-0.11.0.dist-info}/licenses/LICENSE +0 -0
proj_flow/__init__.py
CHANGED
|
@@ -1,4 +1,9 @@
|
|
|
1
1
|
# Copyright (c) 2025 Marcin Zdun
|
|
2
2
|
# This code is licensed under MIT license (see LICENSE for details)
|
|
3
3
|
|
|
4
|
-
|
|
4
|
+
"""
|
|
5
|
+
The **proj_flow** contains only ``__version__`` to be updated, nothing more.
|
|
6
|
+
This is in an attempt to make this module easy to load initially.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
__version__ = "0.11.0"
|
proj_flow/api/arg.py
CHANGED
|
@@ -12,48 +12,71 @@ from dataclasses import dataclass, field
|
|
|
12
12
|
|
|
13
13
|
from proj_flow.base import inspect as _inspect
|
|
14
14
|
|
|
15
|
+
T = typing.TypeVar("T")
|
|
16
|
+
LazyArgument = typing.Union[T, typing.Callable[[], T]]
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def _eval(arg: LazyArgument[T]) -> T:
|
|
20
|
+
if callable(arg):
|
|
21
|
+
return typing.cast(T, arg())
|
|
22
|
+
return arg
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class _Completable(typing.Protocol):
|
|
26
|
+
completer: _inspect.Function
|
|
27
|
+
|
|
15
28
|
|
|
16
29
|
@dataclass
|
|
17
30
|
class Argument:
|
|
18
|
-
help: str = ""
|
|
31
|
+
help: LazyArgument[str] = ""
|
|
19
32
|
pos: bool = False
|
|
20
|
-
names: typing.List[str] = field(default_factory=list)
|
|
21
|
-
nargs: typing.Union[str, int, None] = None
|
|
22
|
-
opt: typing.Optional[bool] = None
|
|
23
|
-
meta: typing.Optional[str] = None
|
|
24
|
-
action: typing.Union[str, argparse.Action, None] = None
|
|
25
|
-
default: typing.Optional[typing.Any] = None
|
|
26
|
-
choices: typing.Optional[typing.List[str]] = None
|
|
33
|
+
names: LazyArgument[typing.List[str]] = field(default_factory=list)
|
|
34
|
+
nargs: LazyArgument[typing.Union[str, int, None]] = None
|
|
35
|
+
opt: LazyArgument[typing.Optional[bool]] = None
|
|
36
|
+
meta: LazyArgument[typing.Optional[str]] = None
|
|
37
|
+
action: LazyArgument[typing.Union[str, argparse.Action, None]] = None
|
|
38
|
+
default: LazyArgument[typing.Optional[typing.Any]] = None
|
|
39
|
+
choices: LazyArgument[typing.Optional[typing.List[str]]] = None
|
|
27
40
|
completer: typing.Optional[_inspect.Function] = None
|
|
28
41
|
|
|
29
42
|
def visit(self, parser: argparse.ArgumentParser, name: str):
|
|
30
43
|
kwargs = {}
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
if
|
|
42
|
-
kwargs["
|
|
44
|
+
|
|
45
|
+
self_help = _eval(self.help)
|
|
46
|
+
self_names = _eval(self.names)
|
|
47
|
+
self_nargs = _eval(self.nargs)
|
|
48
|
+
self_opt = _eval(self.opt)
|
|
49
|
+
self_meta = _eval(self.meta)
|
|
50
|
+
self_action = _eval(self.action)
|
|
51
|
+
self_default = _eval(self.default)
|
|
52
|
+
self_choices = _eval(self.choices)
|
|
53
|
+
|
|
54
|
+
if self_help is not None:
|
|
55
|
+
kwargs["help"] = self_help
|
|
56
|
+
if self_nargs is not None:
|
|
57
|
+
kwargs["nargs"] = self_nargs
|
|
58
|
+
if self_meta is not None:
|
|
59
|
+
kwargs["metavar"] = self_meta
|
|
60
|
+
if self_default is not None:
|
|
61
|
+
kwargs["default"] = self_default
|
|
62
|
+
if self_action is not None:
|
|
63
|
+
kwargs["action"] = self_action
|
|
64
|
+
if self_choices is not None:
|
|
65
|
+
kwargs["choices"] = self_choices
|
|
43
66
|
|
|
44
67
|
names = (
|
|
45
|
-
[name] if self.pos else
|
|
68
|
+
[name] if self.pos else self_names if len(self_names) > 0 else [f"--{name}"]
|
|
46
69
|
)
|
|
47
70
|
|
|
48
71
|
if self.pos:
|
|
49
|
-
kwargs["nargs"] = "?" if
|
|
72
|
+
kwargs["nargs"] = "?" if self_opt else 1
|
|
50
73
|
else:
|
|
51
74
|
kwargs["dest"] = name
|
|
52
|
-
kwargs["required"] = not
|
|
75
|
+
kwargs["required"] = not self_opt
|
|
53
76
|
|
|
54
77
|
action = parser.add_argument(*names, **kwargs)
|
|
55
78
|
if self.completer:
|
|
56
|
-
action.completer = self.completer
|
|
79
|
+
typing.cast(_Completable, action).completer = self.completer
|
|
57
80
|
|
|
58
81
|
return action
|
|
59
82
|
|
proj_flow/api/ctx.py
CHANGED
|
@@ -9,9 +9,10 @@ import datetime
|
|
|
9
9
|
import inspect
|
|
10
10
|
import os
|
|
11
11
|
from dataclasses import dataclass
|
|
12
|
-
from typing import Callable, Dict, Iterable, List, Optional, Union
|
|
12
|
+
from typing import Any, Callable, Dict, Iterable, List, Optional, Union, cast
|
|
13
13
|
|
|
14
14
|
from proj_flow.base import cmd
|
|
15
|
+
from proj_flow.base import inspect as _inspect
|
|
15
16
|
|
|
16
17
|
package_root = os.path.dirname(os.path.dirname(__file__))
|
|
17
18
|
template_dir = "template"
|
|
@@ -26,32 +27,44 @@ SettingsType = Dict[str, StrOrBool]
|
|
|
26
27
|
class Setting:
|
|
27
28
|
json_key: str
|
|
28
29
|
prompt: str = ""
|
|
29
|
-
value: Union[Values, Callable[[], Values]] = ""
|
|
30
|
+
value: Union[Values, Callable[[], Values], Callable[[SettingsType], Values]] = ""
|
|
30
31
|
fix: Optional[str] = None
|
|
31
32
|
force_fix: bool = False
|
|
33
|
+
project: Optional[str] = None
|
|
32
34
|
|
|
33
35
|
def calc_value(self, previous: SettingsType):
|
|
34
|
-
if
|
|
36
|
+
if callable(self.value):
|
|
35
37
|
kwargs = {}
|
|
36
38
|
|
|
37
39
|
params = inspect.signature(self.value).parameters
|
|
38
40
|
if "settings" in params:
|
|
39
41
|
kwargs["settings"] = previous
|
|
40
42
|
|
|
41
|
-
return self.value(**kwargs)
|
|
43
|
+
return cast(_inspect.Function, self.value)(**kwargs)
|
|
42
44
|
|
|
43
45
|
return self.value
|
|
44
46
|
|
|
45
47
|
|
|
46
|
-
def register_init_setting(*
|
|
48
|
+
def register_init_setting(*settings: Setting, is_hidden=False, project: Optional[str]):
|
|
49
|
+
if project is not None:
|
|
50
|
+
for setting in settings:
|
|
51
|
+
setting.project = project
|
|
52
|
+
(hidden if is_hidden else defaults).extend(settings)
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def register_common_init_setting(*setting: Setting, is_hidden=False):
|
|
47
56
|
(hidden if is_hidden else defaults).extend(setting)
|
|
48
57
|
|
|
49
58
|
|
|
50
|
-
def register_switch(key: str, prompt: str, enabled: bool):
|
|
59
|
+
def register_switch(key: str, prompt: str, enabled: bool, project: Optional[str]):
|
|
60
|
+
switches.append(Setting(key, prompt, value=enabled, project=project))
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def register_common_switch(key: str, prompt: str, enabled: bool):
|
|
51
64
|
switches.append(Setting(key, prompt, value=enabled))
|
|
52
65
|
|
|
53
66
|
|
|
54
|
-
def register_internal(key: str, value:
|
|
67
|
+
def register_internal(key: str, value: Any):
|
|
55
68
|
internals[key] = value
|
|
56
69
|
|
|
57
70
|
|
|
@@ -59,17 +72,20 @@ def _git_config(name: str):
|
|
|
59
72
|
def wrap():
|
|
60
73
|
proc = cmd.run("git", "config", name, capture_output=True)
|
|
61
74
|
if proc is None or proc.returncode != 0:
|
|
62
|
-
return
|
|
75
|
+
return ""
|
|
63
76
|
return proc.stdout.strip()
|
|
64
77
|
|
|
65
78
|
return wrap
|
|
66
79
|
|
|
67
80
|
|
|
68
|
-
def move_to_front(preferred: str, values: Iterable[str]):
|
|
81
|
+
def move_to_front(preferred: str, values: Iterable[Optional[str]]):
|
|
69
82
|
result: List[str] = []
|
|
70
83
|
|
|
71
84
|
has_preferred = False
|
|
72
85
|
for value in values:
|
|
86
|
+
if value is None:
|
|
87
|
+
continue
|
|
88
|
+
|
|
73
89
|
if value == preferred:
|
|
74
90
|
has_preferred = True
|
|
75
91
|
else:
|
|
@@ -94,7 +110,7 @@ def _enum_licenses():
|
|
|
94
110
|
root = os.path.abspath(os.path.join(package_root, template_dir, "licenses"))
|
|
95
111
|
for _, dirnames, filenames in os.walk(root):
|
|
96
112
|
dirnames[:] = []
|
|
97
|
-
iter =
|
|
113
|
+
iter = map(_as_mustache, filenames)
|
|
98
114
|
return move_to_front("MIT", iter)
|
|
99
115
|
return []
|
|
100
116
|
|
|
@@ -114,11 +130,11 @@ def _get_nothing(_: SettingsType) -> StrOrBool:
|
|
|
114
130
|
|
|
115
131
|
|
|
116
132
|
def _map(internal_key: str):
|
|
117
|
-
def impl(key:
|
|
133
|
+
def impl(key: StrOrBool) -> StrOrBool:
|
|
118
134
|
mapped = internals.get(internal_key)
|
|
119
135
|
if not isinstance(mapped, dict):
|
|
120
|
-
return
|
|
121
|
-
return mapped.get(key)
|
|
136
|
+
return ""
|
|
137
|
+
return mapped.get(key, "")
|
|
122
138
|
|
|
123
139
|
return impl
|
|
124
140
|
|
|
@@ -152,12 +168,12 @@ def _build_fixup(settings: SettingsType, fixup: str):
|
|
|
152
168
|
value = code(settings)
|
|
153
169
|
|
|
154
170
|
if result:
|
|
155
|
-
result
|
|
171
|
+
result = f"{result}{value}"
|
|
156
172
|
else:
|
|
157
173
|
result = value
|
|
158
174
|
|
|
159
175
|
if verbose:
|
|
160
|
-
result
|
|
176
|
+
result = f"{result}{verbose}"
|
|
161
177
|
|
|
162
178
|
return result
|
|
163
179
|
|
|
@@ -169,7 +185,7 @@ def _fixed(fixup: str):
|
|
|
169
185
|
return wrap
|
|
170
186
|
|
|
171
187
|
|
|
172
|
-
internals = {}
|
|
188
|
+
internals: Dict[str, Any] = {}
|
|
173
189
|
|
|
174
190
|
switches: List[Setting] = []
|
|
175
191
|
|
|
@@ -200,18 +216,21 @@ defaults: List[Setting] = [
|
|
|
200
216
|
"INCLUDE_PREFIX",
|
|
201
217
|
'Prefix for includes (as in #include "{PREFIX}/version.hpp")',
|
|
202
218
|
_fixed("{PROJECT.NAME}"),
|
|
219
|
+
project="cxx",
|
|
203
220
|
),
|
|
204
221
|
Setting(
|
|
205
222
|
"NAME_PREFIX",
|
|
206
223
|
"CMake variable name prefix",
|
|
207
224
|
_fixed("{PROJECT.NAME$safe$upper}"),
|
|
225
|
+
project="cxx",
|
|
208
226
|
),
|
|
209
227
|
Setting(
|
|
210
228
|
"NAMESPACE",
|
|
211
229
|
"C++ namespace for the project",
|
|
212
230
|
_fixed("{PROJECT.NAME$safe}"),
|
|
231
|
+
project="cxx",
|
|
213
232
|
),
|
|
214
|
-
Setting("EXT", "Extension for code files", _list_ext),
|
|
233
|
+
Setting("EXT", "Extension for code files", _list_ext, project="cxx"),
|
|
215
234
|
Setting("SRCDIR", "Directory for code files", "src"),
|
|
216
235
|
Setting(
|
|
217
236
|
"INCLUDEDIR",
|
|
@@ -219,20 +238,21 @@ defaults: List[Setting] = [
|
|
|
219
238
|
"include",
|
|
220
239
|
"{INCLUDEDIR}/{INCLUDE_PREFIX}",
|
|
221
240
|
force_fix=True,
|
|
241
|
+
project="cxx",
|
|
222
242
|
),
|
|
223
243
|
]
|
|
224
244
|
|
|
225
245
|
hidden: List[Setting] = [
|
|
226
|
-
Setting("EXT.cxx", fix="{EXT}"),
|
|
227
|
-
Setting("EXT.hxx", fix="{EXT.cxx$header}"),
|
|
246
|
+
Setting("EXT.cxx", fix="{EXT}", project="cxx"),
|
|
247
|
+
Setting("EXT.hxx", fix="{EXT.cxx$header}", project="cxx"),
|
|
228
248
|
]
|
|
229
249
|
|
|
230
250
|
_fileext = {".cc": ".hh", ".cxx": ".hxx", ".cpp": ".hpp"}
|
|
231
251
|
|
|
232
252
|
|
|
233
253
|
_filters: Dict[str, Callable[[StrOrBool], StrOrBool]] = {
|
|
234
|
-
"safe": lambda value: value.replace("-", "_"),
|
|
235
|
-
"upper": lambda value: value.upper(),
|
|
236
|
-
"lower": lambda value: value.lower(),
|
|
237
|
-
"header": lambda cxx_ext: _fileext.get(cxx_ext, ".hpp"),
|
|
254
|
+
"safe": lambda value: str(value).replace("-", "_"),
|
|
255
|
+
"upper": lambda value: str(value).upper(),
|
|
256
|
+
"lower": lambda value: str(value).lower(),
|
|
257
|
+
"header": lambda cxx_ext: _fileext.get(str(cxx_ext), ".hpp"),
|
|
238
258
|
}
|
proj_flow/api/env.py
CHANGED
|
@@ -23,6 +23,7 @@ from dataclasses import dataclass
|
|
|
23
23
|
from enum import Enum
|
|
24
24
|
from typing import Any, Callable, Dict, List, Optional, Union, cast
|
|
25
25
|
|
|
26
|
+
from proj_flow.api import ctx
|
|
26
27
|
from proj_flow.base import plugins, uname
|
|
27
28
|
|
|
28
29
|
platform = uname.uname()[0]
|
|
@@ -115,6 +116,59 @@ class RunAlias:
|
|
|
115
116
|
return RunAlias(name, doc, steps)
|
|
116
117
|
|
|
117
118
|
|
|
119
|
+
def _merge_dicts(dst: dict, src: dict):
|
|
120
|
+
for key in src:
|
|
121
|
+
if key not in dst:
|
|
122
|
+
dst[key] = src[key]
|
|
123
|
+
continue
|
|
124
|
+
|
|
125
|
+
src_val = src[key]
|
|
126
|
+
dst_val = dst[key]
|
|
127
|
+
|
|
128
|
+
if isinstance(src_val, dict):
|
|
129
|
+
if isinstance(dst_val, dict):
|
|
130
|
+
_merge_dicts(dst_val, src_val)
|
|
131
|
+
continue
|
|
132
|
+
|
|
133
|
+
dst[key] = src_val
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
def _flatten_dict(dst: ctx.SettingsType, defaults: Dict[str, Any], prefix=""):
|
|
137
|
+
for key, val in defaults.items():
|
|
138
|
+
this_key = f"{prefix}{key}"
|
|
139
|
+
|
|
140
|
+
if isinstance(val, dict):
|
|
141
|
+
_flatten_dict(dst, val, f"{this_key}.")
|
|
142
|
+
continue
|
|
143
|
+
|
|
144
|
+
if val is None:
|
|
145
|
+
dst[this_key] = ""
|
|
146
|
+
continue
|
|
147
|
+
|
|
148
|
+
if isinstance(val, bool):
|
|
149
|
+
dst[this_key] = val
|
|
150
|
+
continue
|
|
151
|
+
|
|
152
|
+
dst[this_key] = str(val)
|
|
153
|
+
|
|
154
|
+
|
|
155
|
+
def _merge(cfg: dict, defaults: ctx.SettingsType, path: str):
|
|
156
|
+
config = plugins.load_data(path)
|
|
157
|
+
if not isinstance(config, dict):
|
|
158
|
+
return
|
|
159
|
+
|
|
160
|
+
stored_defaults = config.get("defaults", {})
|
|
161
|
+
try:
|
|
162
|
+
del config["defaults"]
|
|
163
|
+
except KeyError:
|
|
164
|
+
pass
|
|
165
|
+
|
|
166
|
+
_merge_dicts(cfg, config)
|
|
167
|
+
|
|
168
|
+
if isinstance(stored_defaults, dict):
|
|
169
|
+
_flatten_dict(defaults, stored_defaults)
|
|
170
|
+
|
|
171
|
+
|
|
118
172
|
class FlowConfig:
|
|
119
173
|
_cfg: dict
|
|
120
174
|
steps: list = []
|
|
@@ -129,9 +183,18 @@ class FlowConfig:
|
|
|
129
183
|
self.root = cfg.root
|
|
130
184
|
else:
|
|
131
185
|
self.root = os.path.abspath(root)
|
|
132
|
-
|
|
133
|
-
|
|
186
|
+
defaults: ctx.SettingsType = {}
|
|
187
|
+
dest: dict = {}
|
|
188
|
+
|
|
189
|
+
_merge(
|
|
190
|
+
dest,
|
|
191
|
+
defaults,
|
|
192
|
+
os.path.join(os.path.expanduser("~"), ".config", "proj-flow.json"),
|
|
134
193
|
)
|
|
194
|
+
_merge(dest, defaults, os.path.join(self.root, ".flow", "config.json"))
|
|
195
|
+
|
|
196
|
+
self._cfg = dest
|
|
197
|
+
self._cfg["defaults"] = defaults
|
|
135
198
|
|
|
136
199
|
self._propagate_compilers()
|
|
137
200
|
self._load_extensions()
|
proj_flow/api/step.py
CHANGED
|
@@ -12,6 +12,7 @@ from typing import List, cast
|
|
|
12
12
|
from proj_flow.api.env import Config, Runtime
|
|
13
13
|
from proj_flow.base import inspect as _inspect
|
|
14
14
|
from proj_flow.base import matrix
|
|
15
|
+
from proj_flow.base.name_list import name_list
|
|
15
16
|
|
|
16
17
|
|
|
17
18
|
class Step(ABC):
|
|
@@ -111,11 +112,8 @@ def _name_list(label: str, names: List[str], template="`{}`") -> str:
|
|
|
111
112
|
if len(names) == 0:
|
|
112
113
|
return ""
|
|
113
114
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
if prefix:
|
|
117
|
-
prefix += " and "
|
|
118
|
-
return f"\n:{label}: {prefix}{em[-1]}"
|
|
115
|
+
joined = name_list([template.format(name) for name in names])
|
|
116
|
+
return f"\n:{label}: {joined}"
|
|
119
117
|
|
|
120
118
|
|
|
121
119
|
def _make_private(f: _inspect.Function):
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# Copyright (c) 2025 Marcin Zdun
|
|
2
|
+
# This code is licensed under MIT license (see LICENSE for details)
|
|
3
|
+
|
|
4
|
+
"""
|
|
5
|
+
The **proj_flow.base.name_list** provides name list helper for arguments with
|
|
6
|
+
choices
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from typing import List
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def name_list(names: List[str]) -> str:
|
|
13
|
+
if len(names) == 0:
|
|
14
|
+
return ""
|
|
15
|
+
|
|
16
|
+
prefix = ", ".join(names[:-1])
|
|
17
|
+
if prefix:
|
|
18
|
+
prefix += " and "
|
|
19
|
+
return f"{prefix}{names[-1]}"
|
proj_flow/base/registry.py
CHANGED
|
@@ -7,6 +7,7 @@ to register the plugins with a decorator.
|
|
|
7
7
|
"""
|
|
8
8
|
|
|
9
9
|
import typing
|
|
10
|
+
from collections import OrderedDict
|
|
10
11
|
|
|
11
12
|
T = typing.TypeVar("T")
|
|
12
13
|
K = typing.TypeVar("K")
|
|
@@ -97,10 +98,29 @@ class Registry(typing.Generic[T]):
|
|
|
97
98
|
|
|
98
99
|
_debug_copies: typing.List[Registry] = []
|
|
99
100
|
|
|
101
|
+
def quoted(s: str) -> str:
|
|
102
|
+
if '"' in s:
|
|
103
|
+
return "'{}'".format(s.replace("\\", r"\\").replace("'", r"\'"))
|
|
104
|
+
if "'" in s or " " in s:
|
|
105
|
+
return '"{}"'.format(s)
|
|
106
|
+
return s
|
|
100
107
|
|
|
101
108
|
def verbose_info():
|
|
102
109
|
for registry in _debug_copies:
|
|
103
110
|
for item in registry.container:
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
)
|
|
111
|
+
full_name = f"{item.__module__}.{item.__class__.__name__}"
|
|
112
|
+
|
|
113
|
+
kw = OrderedDict()
|
|
114
|
+
|
|
115
|
+
if hasattr(item, "name"):
|
|
116
|
+
kw["name"] = quoted(getattr(item, "name"))
|
|
117
|
+
elif hasattr(item, "__name__"):
|
|
118
|
+
kw["name"] = quoted(getattr(item, "__name__"))
|
|
119
|
+
|
|
120
|
+
if hasattr(item, "id"):
|
|
121
|
+
kw["id"] = quoted(getattr(item, "id"))
|
|
122
|
+
|
|
123
|
+
items = ", ".join([f"{key}={value}" for key, value in kw.items()])
|
|
124
|
+
if len(items) > 0:
|
|
125
|
+
items = f" ({items})"
|
|
126
|
+
print(f"-- {registry.name}: adding `{full_name}`{items}")
|
proj_flow/cli/__init__.py
CHANGED
|
@@ -29,7 +29,7 @@ def main():
|
|
|
29
29
|
def _change_dir():
|
|
30
30
|
root = argparse.ArgumentParser(
|
|
31
31
|
prog="proj-flow",
|
|
32
|
-
usage="proj-flow [-h] [--version] [-C [dir]]
|
|
32
|
+
usage="proj-flow [-h] [--version] [-C [dir]] command ...",
|
|
33
33
|
add_help=False,
|
|
34
34
|
)
|
|
35
35
|
root.add_argument("-C", dest="cd", nargs="?")
|
proj_flow/cli/argument.py
CHANGED
|
@@ -192,7 +192,7 @@ class Command:
|
|
|
192
192
|
if len(self.children):
|
|
193
193
|
subparsers = parser.add_subparsers(
|
|
194
194
|
dest=f"command_{level}",
|
|
195
|
-
metavar="
|
|
195
|
+
metavar="command",
|
|
196
196
|
help="Known command name, see below",
|
|
197
197
|
)
|
|
198
198
|
subparsers.parent = parser # type: ignore
|
|
@@ -254,7 +254,7 @@ def _argparse_visit_all(
|
|
|
254
254
|
parser.shortcuts = shortcut_configs
|
|
255
255
|
|
|
256
256
|
subparsers = parser.add_subparsers(
|
|
257
|
-
dest="command", metavar="
|
|
257
|
+
dest="command", metavar="command", help="Known command name, see below"
|
|
258
258
|
)
|
|
259
259
|
|
|
260
260
|
subparsers.parent = parser # type: ignore
|
|
@@ -7,6 +7,6 @@ The **proj_flow.ext.cplusplus.cmake** provides ``"CMake"``, ``"Build"``,
|
|
|
7
7
|
context.
|
|
8
8
|
"""
|
|
9
9
|
|
|
10
|
-
from . import
|
|
10
|
+
from . import parser, steps, version
|
|
11
11
|
|
|
12
|
-
__all__ = ["
|
|
12
|
+
__all__ = ["parser", "steps", "version"]
|
|
@@ -9,7 +9,8 @@ import os
|
|
|
9
9
|
import textwrap
|
|
10
10
|
from typing import List
|
|
11
11
|
|
|
12
|
-
from proj_flow.api import
|
|
12
|
+
from proj_flow.api import env, step
|
|
13
|
+
from proj_flow.project import cplusplus
|
|
13
14
|
|
|
14
15
|
from ._conan import conan_api
|
|
15
16
|
|
|
@@ -62,6 +63,3 @@ class ConanConfig:
|
|
|
62
63
|
if not rt.dry_run and os.path.exists("CMakeUserPresets.json"):
|
|
63
64
|
os.remove("CMakeUserPresets.json")
|
|
64
65
|
return 0
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
ctx.register_switch("with_conan", "Use Conan for dependency manager", True)
|
proj_flow/ext/github/cli.py
CHANGED
|
@@ -16,22 +16,13 @@ import typing
|
|
|
16
16
|
|
|
17
17
|
from proj_flow import log
|
|
18
18
|
from proj_flow.api import arg, env
|
|
19
|
+
from proj_flow.base.name_list import name_list
|
|
19
20
|
from proj_flow.flow.configs import Configs
|
|
20
21
|
from proj_flow.log import commit, hosting, rich_text
|
|
21
22
|
|
|
22
23
|
FORCED_LEVEL_CHOICES = list(commit.FORCED_LEVEL.keys())
|
|
23
24
|
|
|
24
25
|
|
|
25
|
-
def _name_list(names: typing.List[str]) -> str:
|
|
26
|
-
if len(names) == 0:
|
|
27
|
-
return ""
|
|
28
|
-
|
|
29
|
-
prefix = ", ".join(names[:-1])
|
|
30
|
-
if prefix:
|
|
31
|
-
prefix += " and "
|
|
32
|
-
return f"{prefix}{names[-1]}"
|
|
33
|
-
|
|
34
|
-
|
|
35
26
|
@arg.command("github")
|
|
36
27
|
def github():
|
|
37
28
|
"""Interact with GitHub workflows and releases"""
|
|
@@ -81,7 +72,7 @@ def release(
|
|
|
81
72
|
typing.Optional[str],
|
|
82
73
|
arg.Argument(
|
|
83
74
|
help="Ignore the version change from changelog and instead use this value. "
|
|
84
|
-
f"Allowed values are: {
|
|
75
|
+
f"Allowed values are: {name_list(FORCED_LEVEL_CHOICES)}",
|
|
85
76
|
meta="level",
|
|
86
77
|
choices=FORCED_LEVEL_CHOICES,
|
|
87
78
|
),
|
proj_flow/ext/github/switches.py
CHANGED
|
@@ -7,7 +7,7 @@ projects.
|
|
|
7
7
|
|
|
8
8
|
from proj_flow.api import ctx
|
|
9
9
|
|
|
10
|
-
ctx.
|
|
11
|
-
ctx.
|
|
10
|
+
ctx.register_common_switch("with_github_actions", "Use Github Actions", True)
|
|
11
|
+
ctx.register_common_switch(
|
|
12
12
|
"with_github_social", "Use Github ISSUE_TEMPLATE, CONTRIBUTING.md, etc.", True
|
|
13
13
|
)
|
proj_flow/flow/__init__.py
CHANGED
|
@@ -6,6 +6,6 @@ The **proj_flow.flow** contains the inner workings of various *Project Flow*
|
|
|
6
6
|
components.
|
|
7
7
|
"""
|
|
8
8
|
|
|
9
|
-
from . import configs,
|
|
9
|
+
from . import configs, layer, steps
|
|
10
10
|
|
|
11
|
-
__all__ = ["configs", "
|
|
11
|
+
__all__ = ["configs", "layer", "steps"]
|