fix dependency check logic cause config always disabled
[lunaix-os.git] / lunaix-os / scripts / build-tools / lbuild / scope.py
1 import inspect
2 from lib.utils import Schema
3 from .common import DirectoryTracker
4
5 class ScopeProvider:
6     Enumerables = Schema(Schema.Union(list, tuple))
7     Primitives = Schema(Schema.Union(str, int, bool))
8     
9     def __init__(self, name):
10         super().__init__()
11         self.name = name
12         self.__accessors = {}
13
14     def __add_accessor(self, accessor, type):
15         acc = accessor
16         if isinstance(accessor, str):
17             acc = type(accessor)
18         self.__accessors[acc.name] = acc
19
20     def subscope(self, accessor):
21         self.__add_accessor(accessor, ScopeAccessor)
22
23     def file_subscope(self, accessor):
24         self.__add_accessor(accessor, FileScopeAccessor)
25
26     def accessors(self):
27         return self.__accessors.values()
28     
29     def reset(self):
30         for v in self.__accessors.values():
31             v.reset()
32
33     def context_name(self):
34         return f"__SC{self.name}"
35
36     def __getitem__(self, name):
37         if name not in self.__accessors:
38             return None
39         return self.__accessors[name]
40     
41     def __setitem__(self, name, val):
42         pass
43
44 class ScopeAccessor:
45     def __init__(self, name):
46         super().__init__()
47         self.name = name
48         self.__values = []
49         self._active_context = None
50
51     def values(self):
52         return self.__values
53     
54     def reset(self):
55         self.__values.clear()
56
57     def add(self, x):
58         self.__load_build_context()
59
60         if ScopeProvider.Enumerables == x:
61             for v in x:
62                 self.add(v)
63             return
64         
65         if ScopeProvider.Primitives == x:
66             self.put_value(x)
67             return
68         
69         raise Exception(f"invalid value '{x}' of type ('{type(x).__name__}')")
70     
71     def put_value(self, x):
72         self.__values.append(x)
73
74     def __load_build_context(self):
75         self._active_context = None
76         for f in inspect.stack():
77             if "__LBUILD__" not in f.frame.f_globals:
78                 continue
79             self._active_context = f.frame.f_globals
80         
81         if not self._active_context:
82             raise Exception(
83                 f"unable to modify '{self.name}' outside build context)")
84
85     def __iadd__(self, other):
86         self.add(other)
87
88 class FileScopeAccessor(ScopeAccessor):
89     def __init__(self, name):
90         super().__init__(name)
91
92     def put_value(self, x):
93         tracker = DirectoryTracker.get(self._active_context)
94         x = str(tracker.active_relative() / x)
95         return super().put_value(x)
96