ominfra 0.0.0.dev175__py3-none-any.whl → 0.0.0.dev176__py3-none-any.whl

Sign up to get free protection for your applications and to get access to all the features.
ominfra/configs.py CHANGED
@@ -6,7 +6,8 @@ import typing as ta
6
6
 
7
7
  from omdev.toml.parser import toml_loads
8
8
  from omlish.lite.check import check
9
- from omlish.lite.marshal import unmarshal_obj
9
+ from omlish.lite.marshal import OBJ_MARSHALER_MANAGER
10
+ from omlish.lite.marshal import ObjMarshalerManager
10
11
 
11
12
 
12
13
  T = ta.TypeVar('T')
@@ -46,6 +47,7 @@ def read_config_file(
46
47
  cls: ta.Type[T],
47
48
  *,
48
49
  prepare: ta.Optional[ta.Callable[[ConfigMapping], ConfigMapping]] = None,
50
+ msh: ObjMarshalerManager = OBJ_MARSHALER_MANAGER,
49
51
  ) -> T:
50
52
  with open(path) as cf:
51
53
  config_dct = parse_config_file(os.path.basename(path), cf)
@@ -53,7 +55,7 @@ def read_config_file(
53
55
  if prepare is not None:
54
56
  config_dct = prepare(config_dct)
55
57
 
56
- return unmarshal_obj(config_dct, cls)
58
+ return msh.unmarshal_obj(config_dct, cls)
57
59
 
58
60
 
59
61
  def build_config_named_children(
@@ -13,7 +13,7 @@ def install_command_marshaling(
13
13
  lambda c: c,
14
14
  lambda c: c.Output,
15
15
  ]:
16
- msh.register_opj_marshaler(
16
+ msh.set_obj_marshaler(
17
17
  fn(Command),
18
18
  PolymorphicObjMarshaler.of([
19
19
  PolymorphicObjMarshaler.Impl(
@@ -86,6 +86,8 @@ class DeployAppManager(DeployPathOwner):
86
86
  os.makedirs(deploy_dir, exist_ok=True)
87
87
 
88
88
  deploying_link = os.path.join(deploy_home, 'deploys/deploying')
89
+ if os.path.exists(deploying_link):
90
+ os.unlink(deploying_link)
89
91
  relative_symlink(
90
92
  deploy_dir,
91
93
  deploying_link,
@@ -4,6 +4,8 @@ import dataclasses as dc
4
4
  import typing as ta
5
5
 
6
6
  from omlish.lite.check import check
7
+ from omlish.lite.marshal import SingleFieldObjMarshaler
8
+ from omlish.lite.marshal import register_type_obj_marshaler
7
9
 
8
10
 
9
11
  ##
@@ -82,6 +84,8 @@ def _register_deploy_tag(cls):
82
84
  _DEPLOY_TAGS_BY_NAME[cls.tag_name] = cls
83
85
  _DEPLOY_TAGS_BY_KWARG[cls.tag_kwarg] = cls
84
86
 
87
+ register_type_obj_marshaler(cls, SingleFieldObjMarshaler(cls, 's'))
88
+
85
89
  return cls
86
90
 
87
91
 
@@ -6,7 +6,10 @@ TODO:
6
6
  """
7
7
  import os.path
8
8
 
9
+ from omdev.interp.resolvers import DEFAULT_INTERP_RESOLVER
10
+ from omdev.interp.types import InterpSpecifier
9
11
  from omlish.asyncs.asyncio.subprocesses import asyncio_subprocesses
12
+ from omlish.lite.check import check
10
13
  from omlish.os.atomics import AtomicPathSwapping
11
14
 
12
15
  from .specs import DeployVenvSpec
@@ -28,7 +31,14 @@ class DeployVenvManager:
28
31
  git_dir: str,
29
32
  venv_dir: str,
30
33
  ) -> None:
31
- sys_exe = 'python3'
34
+ if spec.interp is not None:
35
+ i = InterpSpecifier.parse(check.not_none(spec.interp))
36
+ o = check.not_none(await DEFAULT_INTERP_RESOLVER.resolve(i))
37
+ sys_exe = o.exe
38
+ else:
39
+ sys_exe = 'python3'
40
+
41
+ #
32
42
 
33
43
  # !! NOTE: (most) venvs cannot be relocated, so an atomic swap can't be used. it's up to the path manager to
34
44
  # garbage collect orphaned dirs.
ominfra/manage/main.py CHANGED
@@ -35,6 +35,8 @@ from .targets.targets import ManageTarget
35
35
 
36
36
  @dc.dataclass(frozen=True)
37
37
  class ManageConfig:
38
+ deploy_home: ta.Optional[str] = None
39
+
38
40
  targets: ta.Optional[ta.Mapping[str, ManageTarget]] = None
39
41
 
40
42
 
@@ -69,7 +71,8 @@ class MainCli(ArgparseCli):
69
71
  argparse_arg('--deploy-home'),
70
72
 
71
73
  argparse_arg('target'),
72
- argparse_arg('command', nargs='+'),
74
+ argparse_arg('-f', '--command-file', action='append'),
75
+ argparse_arg('command', nargs='*'),
73
76
  )
74
77
  async def run(self) -> None:
75
78
  bs = MainBootstrap(
@@ -80,7 +83,7 @@ class MainCli(ArgparseCli):
80
83
  ),
81
84
 
82
85
  deploy_config=DeployConfig(
83
- deploy_home=self.args.deploy_home,
86
+ deploy_home=self.args.deploy_home or self.config().deploy_home,
84
87
  ),
85
88
 
86
89
  remote_config=RemoteConfig(
@@ -115,13 +118,19 @@ class MainCli(ArgparseCli):
115
118
  #
116
119
 
117
120
  cmds: ta.List[Command] = []
121
+
118
122
  cmd: Command
119
- for c in self.args.command:
123
+
124
+ for c in self.args.command or []:
120
125
  if not c.startswith('{'):
121
126
  c = json.dumps({c: {}})
122
127
  cmd = msh.unmarshal_obj(json.loads(c), Command)
123
128
  cmds.append(cmd)
124
129
 
130
+ for cf in self.args.command_file or []:
131
+ cmd = read_config_file(cf, Command, msh=msh)
132
+ cmds.append(cmd)
133
+
125
134
  #
126
135
 
127
136
  async with injector[ManageTargetConnector].connect(tgt) as ce:
@@ -2686,6 +2686,18 @@ class FieldsObjMarshaler(ObjMarshaler):
2686
2686
  })
2687
2687
 
2688
2688
 
2689
+ @dc.dataclass(frozen=True)
2690
+ class SingleFieldObjMarshaler(ObjMarshaler):
2691
+ ty: type
2692
+ fld: str
2693
+
2694
+ def marshal(self, o: ta.Any, ctx: 'ObjMarshalContext') -> ta.Any:
2695
+ return getattr(o, self.fld)
2696
+
2697
+ def unmarshal(self, o: ta.Any, ctx: 'ObjMarshalContext') -> ta.Any:
2698
+ return self.ty(**{self.fld: o})
2699
+
2700
+
2689
2701
  @dc.dataclass(frozen=True)
2690
2702
  class PolymorphicObjMarshaler(ObjMarshaler):
2691
2703
  class Impl(ta.NamedTuple):
@@ -2760,7 +2772,7 @@ _DEFAULT_OBJ_MARSHALERS: ta.Dict[ta.Any, ObjMarshaler] = {
2760
2772
  **{t: IterableObjMarshaler(t, DynamicObjMarshaler()) for t in (list, tuple, set, frozenset)},
2761
2773
  **{t: MappingObjMarshaler(t, DynamicObjMarshaler(), DynamicObjMarshaler()) for t in (dict,)},
2762
2774
 
2763
- ta.Any: DynamicObjMarshaler(),
2775
+ **{t: DynamicObjMarshaler() for t in (ta.Any, object)},
2764
2776
 
2765
2777
  **{t: DatetimeObjMarshaler(t) for t in (datetime.date, datetime.time, datetime.datetime)},
2766
2778
  decimal.Decimal: DecimalObjMarshaler(),
@@ -2785,6 +2797,16 @@ _OBJ_MARSHALER_GENERIC_ITERABLE_TYPES: ta.Dict[ta.Any, type] = {
2785
2797
  ##
2786
2798
 
2787
2799
 
2800
+ _REGISTERED_OBJ_MARSHALERS_BY_TYPE: ta.MutableMapping[type, ObjMarshaler] = weakref.WeakKeyDictionary()
2801
+
2802
+
2803
+ def register_type_obj_marshaler(ty: type, om: ObjMarshaler) -> None:
2804
+ _REGISTERED_OBJ_MARSHALERS_BY_TYPE[ty] = om
2805
+
2806
+
2807
+ ##
2808
+
2809
+
2788
2810
  class ObjMarshalerManager:
2789
2811
  def __init__(
2790
2812
  self,
@@ -2794,6 +2816,8 @@ class ObjMarshalerManager:
2794
2816
  default_obj_marshalers: ta.Dict[ta.Any, ObjMarshaler] = _DEFAULT_OBJ_MARSHALERS, # noqa
2795
2817
  generic_mapping_types: ta.Dict[ta.Any, type] = _OBJ_MARSHALER_GENERIC_MAPPING_TYPES, # noqa
2796
2818
  generic_iterable_types: ta.Dict[ta.Any, type] = _OBJ_MARSHALER_GENERIC_ITERABLE_TYPES, # noqa
2819
+
2820
+ registered_obj_marshalers: ta.Mapping[type, ObjMarshaler] = _REGISTERED_OBJ_MARSHALERS_BY_TYPE,
2797
2821
  ) -> None:
2798
2822
  super().__init__()
2799
2823
 
@@ -2802,6 +2826,7 @@ class ObjMarshalerManager:
2802
2826
  self._obj_marshalers = dict(default_obj_marshalers)
2803
2827
  self._generic_mapping_types = generic_mapping_types
2804
2828
  self._generic_iterable_types = generic_iterable_types
2829
+ self._registered_obj_marshalers = registered_obj_marshalers
2805
2830
 
2806
2831
  self._lock = threading.RLock()
2807
2832
  self._marshalers: ta.Dict[ta.Any, ObjMarshaler] = dict(_DEFAULT_OBJ_MARSHALERS)
@@ -2817,6 +2842,9 @@ class ObjMarshalerManager:
2817
2842
  non_strict_fields: bool = False,
2818
2843
  ) -> ObjMarshaler:
2819
2844
  if isinstance(ty, type):
2845
+ if (reg := self._registered_obj_marshalers.get(ty)) is not None:
2846
+ return reg
2847
+
2820
2848
  if abc.ABC in ty.__bases__:
2821
2849
  impls = [ity for ity in deep_subclasses(ty) if abc.ABC not in ity.__bases__] # type: ignore
2822
2850
  if all(ity.__qualname__.endswith(ty.__name__) for ity in impls):
@@ -2881,9 +2909,15 @@ class ObjMarshalerManager:
2881
2909
 
2882
2910
  #
2883
2911
 
2884
- def register_opj_marshaler(self, ty: ta.Any, m: ObjMarshaler) -> None:
2912
+ def set_obj_marshaler(
2913
+ self,
2914
+ ty: ta.Any,
2915
+ m: ObjMarshaler,
2916
+ *,
2917
+ override: bool = False,
2918
+ ) -> None:
2885
2919
  with self._lock:
2886
- if ty in self._obj_marshalers:
2920
+ if not override and ty in self._obj_marshalers:
2887
2921
  raise KeyError(ty)
2888
2922
  self._obj_marshalers[ty] = m
2889
2923
 
@@ -2974,7 +3008,7 @@ class ObjMarshalContext:
2974
3008
 
2975
3009
  OBJ_MARSHALER_MANAGER = ObjMarshalerManager()
2976
3010
 
2977
- register_opj_marshaler = OBJ_MARSHALER_MANAGER.register_opj_marshaler
3011
+ set_obj_marshaler = OBJ_MARSHALER_MANAGER.set_obj_marshaler
2978
3012
  get_obj_marshaler = OBJ_MARSHALER_MANAGER.get_obj_marshaler
2979
3013
 
2980
3014
  marshal_obj = OBJ_MARSHALER_MANAGER.marshal_obj
@@ -3259,6 +3293,7 @@ def read_config_file(
3259
3293
  cls: ta.Type[T],
3260
3294
  *,
3261
3295
  prepare: ta.Optional[ta.Callable[[ConfigMapping], ConfigMapping]] = None,
3296
+ msh: ObjMarshalerManager = OBJ_MARSHALER_MANAGER,
3262
3297
  ) -> T:
3263
3298
  with open(path) as cf:
3264
3299
  config_dct = parse_config_file(os.path.basename(path), cf)
@@ -3266,7 +3301,7 @@ def read_config_file(
3266
3301
  if prepare is not None:
3267
3302
  config_dct = prepare(config_dct)
3268
3303
 
3269
- return unmarshal_obj(config_dct, cls)
3304
+ return msh.unmarshal_obj(config_dct, cls)
3270
3305
 
3271
3306
 
3272
3307
  def build_config_named_children(