2020-04-18 21:26:31 +03:00
from pathlib import Path
2020-04-29 13:33:54 +03:00
from collections . abc import Iterable
2020-04-18 21:26:31 +03:00
import os
import random
import re
import subprocess
2020-04-21 22:23:56 +03:00
import sys
import time
2020-04-18 21:26:31 +03:00
SUBPROCESS_CALL = subprocess . call
DEFAULT = object ( )
2020-04-21 22:23:56 +03:00
def one_arg ( args , kwargs ) :
2020-04-29 13:33:54 +03:00
return not kwargs and len ( args ) == 1 and callable ( args [ 0 ] )
2020-04-21 22:23:56 +03:00
# apply decorator_factory if cond is True on args
def _make_conditional_d ( decorator_factory ) :
def df ( * df_args , cond = None , inverse = False , * * df_kwargs ) :
if cond is None :
cond = lambda x : True # noqa E731
def decorator ( prog ) :
def f ( args ) :
if cond ( args ) != inverse :
return decorator_factory ( * df_args , * * df_kwargs ) ( prog ) ( args )
else :
return prog ( args )
return f
return decorator
return df
def _decorator_add_factory_d ( decorator ) :
def df ( * df_args , * * df_kwargs ) :
if one_arg ( df_args , df_kwargs ) :
return decorator ( df_args [ 0 ] )
else :
def d ( f ) :
return decorator ( f )
return d
return df
def _factory_add_decorator_df ( * dff_args , * * dff_kwargs ) :
def dff ( decorator_factory ) :
def df ( * df_args , * * df_kwargs ) :
if one_arg ( df_args , df_kwargs ) :
return decorator_factory ( * dff_args , * * dff_kwargs ) ( df_args [ 0 ] )
else :
def df1 ( d ) :
if df_args :
args = df_args
else :
args = dff_args
kwargs = dff_kwargs . copy ( )
kwargs . update ( df_kwargs )
return decorator_factory ( * args , * * kwargs ) ( d )
return df1
return df
return dff
@_factory_add_decorator_df ( )
@_make_conditional_d
@_decorator_add_factory_d
def print_d ( func ) :
def f ( * args , * * kwargs ) :
sargs = list ( args )
sargs . extend ( f ' { k } = { v } ' for k , v in kwargs . items ( ) )
print ( f ' { func . __name__ } ( { sargs } ) ' , file = sys . stdout )
return func ( * args )
return f
@_factory_add_decorator_df ( )
@_make_conditional_d
@_decorator_add_factory_d
def nop_d ( func ) :
def f ( * args , * * kwargs ) :
pass
return f
@_make_conditional_d
def before_d ( func_before , * fb_args , * * fb_kwargs ) :
def d ( func ) :
def f ( * args , * * kwargs ) :
func_before ( * fb_args , * * fb_kwargs )
return func ( * args , * * kwargs )
return f
return d
@_make_conditional_d
def after_d ( func_after , * fa_args , save_rc = True , * * fa_kwargs ) :
def d ( func ) :
def f ( * args , * * kwargs ) :
old_rc = func ( * args , * * kwargs )
new_rc = func_after ( * fa_args , * * fa_kwargs )
if save_rc :
return old_rc
else :
return new_rc
return f
return d
@_factory_add_decorator_df ( 1 )
@_make_conditional_d
def sleep_d ( s ) :
def d ( func ) :
def f ( * args , * * kwargs ) :
time . sleep ( s )
return func ( * args , * * kwargs )
return f
return d
@_factory_add_decorator_df ( 1 )
@_make_conditional_d
def return_d ( rc ) :
def d ( func ) :
def f ( * args , * * kwargs ) :
func ( * args , * * kwargs )
return rc
return f
return d
2020-04-18 21:26:31 +03:00
def error_call ( args ) :
raise Exception ( f ' Not implemened call for ` { args } ` ' )
def git ( args ) :
if args [ 1 ] == ' clone ' :
target = Path ( args [ 3 ] )
os . makedirs ( target )
if target . name == ' mkimage-profiles ' :
os . makedirs ( target / ' conf.d ' )
os . makedirs ( target / ' features.in/build-ve/image-scripts.d ' )
else :
error_call ( args )
return 0
def make ( args ) :
for arg in args :
if arg . startswith ( ' IMAGE_OUTDIR= ' ) :
out_dir = Path ( arg . lstrip ( ' IMAGE_OUTDIR= ' ) )
if arg . startswith ( ' ARCH= ' ) :
arch = Path ( arg . lstrip ( ' ARCH= ' ) )
match = re . match ( r ' .*/([- \ w]*) \ .(.*) ' , args [ - 1 ] )
target , kind = match . groups ( )
2020-04-22 17:08:51 +03:00
image = out_dir / f ' { target } - { arch } . { kind } '
2020-04-18 21:26:31 +03:00
image . write_bytes (
bytes ( random . randint ( 0 , 255 ) for x in range ( random . randint ( 32 , 128 ) ) )
)
return 0
def gpg ( args ) :
Path ( f ' { args [ - 1 ] } .asc ' ) . touch ( )
return 0
def rsync ( args ) :
return SUBPROCESS_CALL ( args , stdout = subprocess . DEVNULL )
2020-04-21 22:23:56 +03:00
def decorate ( decorators , func ) :
for decorator in reversed ( decorators ) :
func = decorator ( func )
return func
2020-04-18 21:26:31 +03:00
class Call ( ) :
2020-04-21 22:23:56 +03:00
def __init__ ( self , progs = None , decorators = None ) :
2020-04-18 21:26:31 +03:00
self . progs = {
' git ' : git ,
' make ' : make ,
' gpg2 ' : gpg ,
' rsync ' : rsync ,
DEFAULT : error_call ,
}
if progs is not None :
self . progs . update ( progs )
2020-04-21 22:23:56 +03:00
if decorators is None :
decorators = { }
self . decorators = decorators
2020-04-18 21:26:31 +03:00
def __call__ ( self , args ) :
rc = None
prog = args [ 0 ]
2021-04-13 15:35:19 +03:00
func = self . progs . get ( prog , self . progs . get ( DEFAULT , error_call ) )
2020-04-21 22:23:56 +03:00
decorators = self . decorators . get ( prog , [ ] )
if not isinstance ( decorators , Iterable ) :
decorators = [ decorators ]
rc = decorate ( decorators , func ) ( args )
2020-04-18 21:26:31 +03:00
return rc