@@ -184,7 +184,131 @@ def _is_file(value):
184184def _is_runfiles (value ):
185185 return type (value ) == "runfiles"
186186
187+ def _Optional (* initial ):
188+ if len (initial ) > 1 :
189+ fail ("only one positional arg allowed" )
190+
191+ # buildifier: disable=uninitialized
192+ self = struct (
193+ _value = list (initial ),
194+ present = lambda * a , ** k : _Optional_present (self , * a , ** k ),
195+ set = lambda * a , ** k : _Optional_set (self , * a , ** k ),
196+ get = lambda * a , ** k : _Optional_get (self , * a , ** k ),
197+ )
198+ return self
199+
200+ def _Optional_set (self , v ):
201+ if len (self ._value ) == 0 :
202+ self ._value .append (v )
203+ else :
204+ self ._value [0 ] = v
205+
206+ def _Optional_get (self ):
207+ if not len (self ._value ):
208+ fail ("Value not present" )
209+ return self ._value [0 ]
210+
211+ def _Optional_present (self ):
212+ return len (self ._value ) > 0
213+
214+ def _TransitionBuilder (implementation = None , inputs = None , outputs = None , ** kwargs ):
215+ # buildifier: disable=uninitialized
216+ self = struct (
217+ implementation = _Optional (implementation ),
218+ inputs = _SetBuilder (inputs ),
219+ outputs = _SetBuilder (outputs ),
220+ kwargs = kwargs ,
221+ build = lambda * a , ** k : _TransitionBuilder_build (self , * a , ** k ),
222+ )
223+ return self
224+
225+ def _TransitionBuilder_build (self ):
226+ return transition (
227+ implementation = self .implementation .get (),
228+ inputs = self .inputs .build (),
229+ outputs = self .outputs .build (),
230+ ** self .kwargs
231+ )
232+
233+ def _SetBuilder (initial = None ):
234+ initial = {} if not initial else {v : None for v in initial }
235+
236+ # buildifier: disable=uninitialized
237+ self = struct (
238+ _values = initial ,
239+ extend = lambda * a , ** k : _SetBuilder_extend (self , * a , ** k ),
240+ build = lambda * a , ** k : _SetBuilder_build (self , * a , ** k ),
241+ )
242+ return self
243+
244+ def _SetBuilder_build (self ):
245+ return self ._values .keys ()
246+
247+ def _SetBuilder_extend (self , values ):
248+ for v in values :
249+ if v not in self ._values :
250+ self ._values [v ] = None
251+
252+ def _RuleBuilder (implementation = None , ** kwargs ):
253+ # buildifier: disable=uninitialized
254+ self = struct (
255+ attrs = dict (kwargs .pop ("attrs" , None ) or {}),
256+ cfg = kwargs .pop ("cfg" , None ) or _TransitionBuilder (),
257+ exec_groups = dict (kwargs .pop ("exec_groups" , None ) or {}),
258+ executable = _Optional (),
259+ fragments = list (kwargs .pop ("fragments" , None ) or []),
260+ implementation = _Optional (implementation ),
261+ extra_kwargs = kwargs ,
262+ provides = list (kwargs .pop ("provides" , None ) or []),
263+ test = _Optional (),
264+ toolchains = list (kwargs .pop ("toolchains" , None ) or []),
265+ build = lambda * a , ** k : _RuleBuilder_build (self , * a , ** k ),
266+ to_kwargs = lambda * a , ** k : _RuleBuilder_to_kwargs (self , * a , ** k ),
267+ )
268+ if "test" in kwargs :
269+ self .test .set (kwargs .pop ("test" ))
270+ if "executable" in kwargs :
271+ self .executable .set (kwargs .pop ("executable" ))
272+ return self
273+
274+ def _RuleBuilder_build (self , debug = "" ):
275+ kwargs = self .to_kwargs ()
276+ if debug :
277+ lines = ["=" * 80 , "rule kwargs: {}:" .format (debug )]
278+ for k , v in sorted (kwargs .items ()):
279+ lines .append (" {}={}" .format (k , v ))
280+
281+ # buildifier: disable=print
282+ print ("\n " .join (lines ))
283+ return rule (** kwargs )
284+
285+ def _RuleBuilder_to_kwargs (self ):
286+ kwargs = {}
287+ if self .executable .present ():
288+ kwargs ["executable" ] = self .executable .get ()
289+ if self .test .present ():
290+ kwargs ["test" ] = self .test .get ()
291+
292+ kwargs .update (
293+ implementation = self .implementation .get (),
294+ cfg = self .cfg .build (),
295+ attrs = {
296+ k : (v .build () if hasattr (v , "build" ) else v )
297+ for k , v in self .attrs .items ()
298+ },
299+ exec_groups = self .exec_groups ,
300+ fragments = self .fragments ,
301+ provides = self .provides ,
302+ toolchains = self .toolchains ,
303+ )
304+ kwargs .update (self .extra_kwargs )
305+ return kwargs
306+
187307builders = struct (
188308 DepsetBuilder = _DepsetBuilder ,
189309 RunfilesBuilder = _RunfilesBuilder ,
310+ RuleBuilder = _RuleBuilder ,
311+ TransitionBuilder = _TransitionBuilder ,
312+ SetBuilder = _SetBuilder ,
313+ Optional = _Optional ,
190314)
0 commit comments