#
# Repo: https://gitlab.com/aeon.org/builder
#
# Installation:
#
# Download builder.py and put in your PYTHONPATH. That's it! )
#
# First script
#
# Create deploy.json file with the content in the example below:
#
# {
# "deploy" : {
# "host" : "your-ftp-host" , "user" : "your-ftp-user" ,
# "password" : "your-ftp-password" , "path" : "path-on-your-ftp-server"
# } ,
# "order" : [
# { "step" : "deploy" , "type" : "ftp" }
# ]
# }
#
# Then create script deploy.py with the below code:
#
# import builder
# builder.run()
#
# When you run this script - it will deploy all the files from the directory in wich it was run
#
# More documentation can be found here: https://gitlab.com/aeon.org/builder/wikis/builder.py-home
#
# If you have any questions or advises - feel free to contact with the author by email alexey@dodonov.pro
# Or create ticket here https://gitlab.com/aeon.org/builder/issues
#
import ftplib , os , io , sys , subprocess , shutil , json , hashlib , re
from subprocess import check_output
from datetime import datetime
from datetime import time
from shutil import copyfile
from os import walk
from os.path import splitext , join , split
#
# Settings
#
service_folders = [
'./conf', './tests', './tmp', './vendor', './vendor/{service-name}', './vendor/{service-name}/conf',
'./vendor/{service-name}/include', './vendor/{service-name}/include/php', './vendor/{service-name}/include/js',
'./vendor/{service-name}/tests', './vendor/{service-name}/vendor', './vendor/{service-name}/vendor/{service-name}-logic',
'./vendor/{service-name}/vendor/{service-name}-logic/tests' ,
'./dns' , './dns/conf' , './dns/include' , './dns/include/php' ,
'./vendor/{service-name}/vendor/{service-name}-model'
]
common_service_file_templates = {
'./.htaccess': "# show php errors\nphp_flag display_startup_errors on\nphp_flag display_errors on\nphp_flag html_errors on\n\n\n Allow from all\n\n\n# use mod_rewrite for pretty URL support\nRewriteEngine on\n\nRewriteRule ^data/files/(.*)$ data/files/$1 [L]\n\nRewriteRule ^vendor/(.*).css$ vendor/$1.css [L]\nRewriteRule ^res/css/(.*)$ res/css/$1 [L]\n\nRewriteRule ^vendor/(.*).js$ vendor/$1.js [L]\nRewriteRule ^res/js/(.*)$ res/js/$1 [L]\n\nRewriteRule ^vendor/(.*).woff2$ vendor/$1.woff2 [L]\nRewriteRule ^res/fonts/(.*)$ res/fonts/$1 [L]\n\nRewriteRule ^vendor/(.*).(jpg|jpeg)$ vendor/$1.$2 [L]\nRewriteRule ^res/images/(.*)$ res/images/$1 [L]\n\nRewriteRule ^res/images/(.*)$ res/images/$1 [L]\nRewriteRule ^([a-z0-9A-Z_\/\.\-\@%\ :,]+)/?(.*)$ index.php?r=$1&%{QUERY_STRING} [L]\nRewriteRule ^/?(.*)$ index.php?r=index&%{QUERY_STRING} [L]" ,
'./build.py' : "import builder\n\nbuilder.run()",
'./vendor/{service-name}/test-unit.json' : "{\n\t\"tests\": [\n\t\t\"./tests\"\n\t]\n}",
'./vendor/{service-name}/test-unit.py' : "import builder\n\nbuilder.run()" ,
'./test-service.json' : "{\n\t\"tests\": [\n\t\t\"--filter {service-class-name}ServiceTest ./tests\"\n\t]\n}" ,
'./test-service.py' : "import builder\n\nbuilder.run()" ,
'./vendor/{service-name}/vendor/{service-name}-logic/test-unit.json' : "{\n\t\"tests\": [\n\t\t\"./tests\"\n\t]\n}",
'./vendor/{service-name}/vendor/{service-name}-logic/test-unit.py' : "import builder\n\nbuilder.run()" ,
'./dns/records.php' : "" ,
'./dns/include/php/dns-utils.php' : "" ,
'./dns/conf/conf-local.php' : " 'http://auth-srv',\n\t'author' => 'http://author-srv',\n];\n\nfunction get_dns_records()\n{\n\tglobal $DNSRecords;\n\n\treturn ($DNSRecords);\n}\n\n?>" ,
'./dns/conf/conf-ft.php' : " 'http://auth-srv',\n\t'author' => 'http://author-srv',\n];\n\nfunction get_dns_records()\n{\n\tglobal $DNSRecords;\n\n\treturn ($DNSRecords);\n}\n\n?>" ,
'./dns/conf/conf-prod.php' : " 'http://auth-srv',\n\t'author' => 'http://author-srv',\n];\n\nfunction get_dns_records()\n{\n\tglobal $DNSRecords;\n\n\treturn ($DNSRecords);\n}\n\n?>" ,
}
service_file_templates = {
'./index.php' : "",
'./build.json' : "{\n\t\"vendor-repo\" : [\n\t\t{\n\t\t\t\"vendors\" : [ \n\t\t\t\t\"dns-client\"\n\t\t\t] , \n\t\t\t\"path\" : \"C:/Users/kcher/YandexDisk-gdever/enterprise/\"\n\t\t} , \n\t\t{\n\t\t\t\"vendors\" : [ \n\t\t\t\t\"router\" , \"service\"\n\t\t\t] , \n\t\t\t\"path\" : \"C:/Users/kcher/YandexDisk-gdever/mezon/vendor/\"\n\t\t}\n\t]\n}",
'./vendor/{service-name}/tests/{service-class-name}UnitTest.php' : "",
'./tests/{service-class-name}ServiceTest.php' : "" ,
'./vendor/{service-name}/vendor/{service-name}-logic/{service-name}-logic.php' : "" ,
'./vendor/{service-name}/{service-name}.php' : "ServiceTransport->add_route('/route/path/', 'method_name', 'GET', 'public_call', [\n\t\t// 'content_type' => 'text/html; charset=utf-8'\n\t\t//]);\n\t}\n}\n\n?>" ,
'./vendor/{service-name}/vendor/{service-name}-logic/tests/{service-class-name}LogicUnitTest.php' : "ClassName = '{service-class-name}Logic';\n\t}\n}\n\n?>" ,
}
crud_service_file_templates = {
'./build.json' : "{\n\t\"vendor-repo\" : [\n\t\t{\n\t\t\t\"vendors\" : [ \n\t\t\t\t\"auth-php-client\" , \"author-php-client\" , \"dns-client\" , \"auth-security-provider\"\n\t\t\t] , \n\t\t\t\"path\" : \"C:/Users/kcher/YandexDisk-gdever/enterprise/\"\n\t\t} , \n\t\t{\n\t\t\t\"vendors\" : [ \n\t\t\t\t\"conf\" , \"functional\" , \"custom-client\" , \"mezon\" , \"pdo-crud\" , \"rest-client\" , \"rest-exception\" , \"router\" , \"service\" , \"singleton\" , \"template-engine\" , \"crud-service\"\n\t\t\t] , \n\t\t\t\"path\" : \"C:/Users/kcher/YandexDisk-gdever/mezon/vendor/\"\n\t\t}\n\t]\n}" ,
'./index.php' : "" ,
'./tests/{service-class-name}ServiceTest.php' : "" ,
'./vendor/{service-name}/tests/{service-class-name}UnitTest.php' : "" ,
'./vendor/{service-name}/{service-name}.php' : " [\n\t\t\t\t'type' => 'integer',\n\t\t\t\t'title' => 'id'\n\t\t\t]\n\t\t];\n\n\t\tparent::__construct('{service-name}', $Fields, '{service-name}', [], $ServiceTransport, $SecurityProvider, $ServiceLogic, $ServiceModel);\n\t}\n}\n\n?>" ,
'./vendor/{service-name}/vendor/{service-name}-logic/{service-name}-logic.php' : "" ,
'./vendor/{service-name}/vendor/{service-name}-logic/tests/{service-class-name}LogicUnitTest.php' : "ClassName = '{service-class-name}Logic';\n\t}\n}\n\n?>" ,
'./vendor/{service-name}/vendor/{service-name}-logic/phpunit.xml' : "\n\n\t\n\t\t\n\t\n\n\t\n\t\t\n\t\t\ttests\n\t\t\n\t\n\n\t\n\t\t\n\t\t\t./\n\t\t\t\n\t\t\t\t\t./tests\n\t\t\t\n\t\t\n\t\n\n\t\n\t\t\n\t\t\n\t\n" ,
'./vendor/{service-name}/vendor/{service-name}-model/{service-name}-model.php' : "" ,
'./conf/conf.php' : ""
}
not_skippable_vendor_files = [
'__pycache__' , '/tmp/' , '\\tmp\\' , '\\tmp/' , '/tmp\\' ,
'phpMyAdmin' , '.settings' , '.buildpath' , '.project' , '.pydevproject' , '.git' , '.sass', '.map' , '.scss' , '.pyc'
]
non_deployable_files = [
'__pycache__' , '/tmp/' , '\\tmp\\' , '\\tmp/' , '/tmp\\' ,
'phpMyAdmin' , '.settings' , '.buildpath' , '.project' , '.pydevproject' , '.git' , '.sass', '.map' , '.scss' , '.pyc' ,
'/tests/' , '.git' , '.sass', '.map' , '.scss' , '.py' , 'prod.json' , 'test.json' , 'build.json' , 'service.json' , 'unit.json' ,
'local.json' , '.md' , 'phpunit.xml' , '/tests\\' , '\\tests/' , '\\tests\\'
]
#
# Globals
#
ftp_connection = False
make_ftp_folder_structure_created_paths = []
run_settings = '.build'
temporary_vendors = []
#
# Method builds folder tree
#
def select_files(root , files):
selected_files = []
for file in files:
# do concatenation here to get full path
full_path = join(root , file)
selected_files.append(full_path)
return selected_files
#
# Method builds folder tree
#
def build_recursive_dir_tree(path):
if(os.path.isdir(path) == False):
raise Exception('Directory ' + path + ' does not exists')
selected_files = []
for root , dirs , files in walk(path):
selected_files += select_files(root , files)
return selected_files
#
# Method returns not skippable files
#
def not_skippable_masks_files(masks , files):
result = []
for file in files:
if(not_skippable_masks_file(masks , file)):
result.append(file)
return(result)
#
# Method returns true if the file is not skippable
#
def not_skippable_masks_file(masks , file):
for mask in masks:
if(mask in file):
return False
return True
#
# Method returns last build date
#
def get_last_build_date():
try:
file_stream = open('./tmp/' + run_settings , 'rt')
last_build_date = file_stream.readline()
file_stream.close()
except io.UnsupportedOperation:
last_build_date = '2000-01-01 00:00:00.000000'
except FileNotFoundError:
last_build_date = '2000-01-01 00:00:00.000000'
return(last_build_date)
#
# Method returns updated files since the last build
#
def get_updated_files(path):
# getting all files
files = build_recursive_dir_tree(path)
# getting date and time ofthe last build
last_build_date = get_last_build_date()
result = [];
# filtering files and getting only updated ones
for file in files:
file_update_time = os.path.getmtime(file)
file_update_time = datetime.fromtimestamp(file_update_time).strftime('%Y-%m-%d %H:%M:%S.%f')
if(file_update_time > last_build_date):
result.append(file)
return(result)
#
# Method calculatesmd5 hashof the file
#
def md5(path):
hash_md5 = hashlib.md5()
with open(path, "rb") as f:
for chunk in iter(lambda: f.read(4096), b""):
hash_md5.update(chunk)
return hash_md5.hexdigest()
#
# Method returns updated files since the last build
#
def get_updated_files_ex(src_path, dst_path):
# getting all files
files = build_recursive_dir_tree(src_path)
# Filtering files needed to be skipped
files = not_skippable_masks_files(not_skippable_vendor_files , files)
result = [];
# filtering files and getting only updated ones
for file in files:
to_path = dst_path + os.path.relpath(file , src_path)
if(os.path.isfile(to_path) == False):
result.append(file)
else:
if(md5(to_path) != md5(file)):
# copy only if src file is newer than dst one
src_file_update_time = os.path.getmtime(file)
src_file_update_time = datetime.fromtimestamp(src_file_update_time).strftime('%Y-%m-%d %H:%M:%S.%f')
dst_file_update_time = os.path.getmtime(to_path)
dst_file_update_time = datetime.fromtimestamp(dst_file_update_time).strftime('%Y-%m-%d %H:%M:%S.%f')
if(dst_file_update_time < src_file_update_time):
result.append(file)
return(result)
#
# Function safely creates folder
#
def safe_create_folder(folder):
try:
os.mkdir(folder)
except FileExistsError:
pass;
#
# Creating folder structure via FTP
#
def make_ftp_folder_structure(ftp_session , path):
path = path.replace('/' , '\\')
if(path in make_ftp_folder_structure_created_paths):
return
else:
make_ftp_folder_structure_created_paths.append(path)
path = path.split('\\')
for i in range(0 , len(path)):
try:
ftp_session.mkd('/'.join(path[ 0 : i + 1 ]))
except ftplib.error_perm:
pass
#
# Exception class
#
class FTPError(Exception):
def __init__(self , message):
self.Message = message
#
# Method establishes FTP connection and moves to the directory
#
def make_ftp_connection(host , login , password):
try:
# connecting to the server and store file
ftp_session = ftplib.FTP(host , login , password)
except ftplib.error_perm:
raise Exception('Login error with login = ' + login + ' and password = ' + password)
return(ftp_session)
#
# Method establishes FTP connection and moves to the directory
#
def make_ftp_connection_to_path(host , login , password , server_path):
ftp_session = make_ftp_connection(host , login , password)
make_ftp_folder_structure(ftp_session , server_path)
ftp_session.cwd(server_path)
return(ftp_session)
#
# Method copies files to the server
#
def copy_files_to_ftp(ftp_session , files , local_path , server_path):
i = 1
if(len(files)):
for file in files:
path = os.path.dirname(os.path.relpath(file , local_path))
file_stream = open(file , 'rb')
make_ftp_folder_structure(ftp_session , path)
ftp_session.cwd(path.replace('\\' , '/'))
ftp_session.storbinary('STOR ' + os.path.basename(file) , file_stream)
ftp_session.cwd('/' + server_path)
file_stream.close()
print('UPLOADED: ' + str(i) + ' of ' + str(len(files)) + ' ' + file.replace('\\' , '/'))
i += 1
else:
print('UPLOADED: All files are up-to-date')
#
# Method sends sources to FTP server
#
def copy_sources_to_ftp(host , login , password , server_path , files):
ftp_session = make_ftp_connection_to_path(host , login , password , server_path)
copy_files_to_ftp(ftp_session , files , './' , server_path)
ftp_session.quit()
#
# Method returns a list of updated or all prohect's filestobe deployed
#
def get_files_to_deploy(dir , only_updated=True):
if only_updated:
raw = get_updated_files(dir)
else:
raw = build_recursive_dir_tree(dir)
files = []
for file in raw:
if(not_skippable_masks_file(non_deployable_files , file)):
files.append(file)
return(files)
#
# Method copies all sources to ftp server
#
def redeploy_to_ftp(host , login , password , server_path):
files = get_files_to_deploy('./' , False);
copy_sources_to_ftp(host , login , password , server_path , files)
#
# Method copies diff sources to ftp server
#
def deploy_to_ftp(host , login , password , server_path):
files = get_files_to_deploy('./' , True);
copy_sources_to_ftp(host , login , password , server_path , files)
#
# Method connects to the FTP server
#
def connect_to_ftp(host , login , password):
global ftp_connection
ftp_connection = make_ftp_connection(host , login , password)
global make_ftp_folder_structure_created_paths
make_ftp_folder_structure_created_paths = []
#
# Class for getting single char from input
#
class CrossPlatformGetch:
def __init__(self):
try:
self.impl = _GetchWindows()
except ImportError:
self.impl = _GetchUnix()
self.impl()
#
# Getting char method
#
def getch():
CrossPlatformGetch()
#
# Getting single char from input on Unix
#
class _GetchUnix:
def __init__(self):
import tty
def __call__(self):
import tty, termios
fd = sys.stdin.fileno()
old_settings = termios.tcgetattr(fd)
try:
tty.setraw(sys.stdin.fileno())
ch = sys.stdin.read(1)
finally:
termios.tcsetattr(fd , termios.TCSADRAIN , old_settings)
return ch
#
# Getting single char from input on Windows
#
class _GetchWindows:
def __init__(self):
import msvcrt
def __call__(self):
import msvcrt
return msvcrt.getch()
#
# Method runs phpunit
#
def run_phpunit(path , module=''):
try:
result = check_output('php c:/php/phpunit.phar ' + path , shell=True)
matches = re.search('Lines:[ ]{1,}([0-9]{1,2})\.([0-9]{1,2})\%', str(result, 'utf-8'))
target_threshold = 75
if(not(matches is None) and int(matches.group(1)) < target_threshold):
raise Exception('Module test ' + ('' if module == '' else module + ' ') + 'failed. Target threshold is ' + str(target_threshold) + '. Actual is ' + matches.group(1))
print('SUCCESS : Module ' + ('' if module == '' else module + ' ') + 'checked')
except subprocess.CalledProcessError as Err:
print(Err.output.decode('utf-8' , 'ignore').replace('\n' , "\n"))
print('FAILED : Module check failed')
raise Exception('Module test failed')
#
# Final actions
#
def finish_actions():
safe_create_folder('./tmp/')
file_stream = open('./tmp/' + run_settings , 'wt')
file_stream.write(str(datetime.now()))
file_stream.close()
clear_temporary_vendors()
#
# Finish method body
#
def finish_verbose():
finish_actions()
# final messaging
print("Success!")
sys.exit()
#
# Finishing building
#
def finish():
finish_actions()
# final messaging
print("Success!")
getch()
sys.exit()
#
# Method finishes building process
#
def finish_building():
finish()
#
# Final messaging
#
def final_messaging(error_message):
print(error_message)
getch()
sys.exit(1)
#
# Method cancels building
#
def cancel(error_message):
clear_temporary_vendors()
# final messaging
final_messaging(error_message)
#
# Method cancels building
#
def cancel_verbose(error_message):
clear_temporary_vendors()
# final messaging
print(error_message)
sys.exit(1)
#
# Method cancels building
#
def cancel_building(error_message):
cancel(error_message)
#
# Uploading vendor sources
#
def upload_component_sources(files , component , src_path , dst_path , action):
if(len(files) == 0):
print('SKIPPED : ' + component + ' ' + action)
return
print(action + ' : ' + src_path + component)
counter = 1;
for file in files:
print('UPLOADED: ' + str(counter) + ' of ' + str(len(files)))
if(not_skippable_masks_file(not_skippable_vendor_files , file)):
try:
to_path = dst_path + os.path.relpath(file , src_path)
os.makedirs(os.path.dirname(to_path) , exist_ok=True)
copyfile(file , to_path)
except FileNotFoundError as Err:
raise Exception(dst_path + file.lstrip('./\\'))
counter = counter + 1
#
# Uploading vendor sources
#
def upload_component_sources_with_skippped(files , component , src_path , dst_path , action):
if(len(files) == 0):
print('SKIPPED : ' + component + ' ' + action)
return
print(action + ' : ' + src_path + component)
counter = 1;
for file in files:
print('UPLOADED: ' + str(counter) + ' of ' + str(len(files)))
# Here we do not check do we need to skip file
try:
to_path = dst_path + os.path.relpath(file , src_path)
os.makedirs(os.path.dirname(to_path) , exist_ok=True)
copyfile(file , to_path)
except FileNotFoundError as Err:
raise Exception(dst_path + file.lstrip('./\\'))
counter = counter + 1
#
# Method performs action for the component
#
def process_component(component , src_path , dst_path , action , only_updated=True):
# create vendor folder
safe_create_folder(dst_path)
# getting files
if(only_updated):
files = get_updated_files_ex(src_path + component + '/' , dst_path + component + '/')
else:
files = build_recursive_dir_tree(src_path + component + '/')
# uploading sources
upload_component_sources_with_skippped(files , component , src_path , dst_path , action)
#
# Method processes self update
#
def process_self(component , src_path , dst_path , action , only_updated=True):
# getting files
if(only_updated):
files = get_updated_files(src_path + '/')
else:
files = build_recursive_dir_tree(src_path + '/')
# uploading sources
upload_component_sources(files , component , src_path , dst_path , action)
#
# Method recopies vendor.
#
def copy_vendors(vendors , src_path):
for vendor in vendors:
process_component(vendor , src_path , './vendor/' , 'REFRESH' , True)
#
# Method processess temporary repo step
#
def process_temporary_repo_step(batches):
for batch in batches:
install_temporary_vendors(batch.get('vendors') , batch.get('path') , batch.get('dst-path' , './vendor/'))
#
# Method processess tests step
#
def process_tests_step(tests):
for test in tests:
run_phpunit(test , os.path.basename(os.path.dirname(test)))
#
# Method processess shell step
#
def process_shell_step(shell):
for command in shell:
print('RUN SHELL: ' + command)
check_output(command , shell=True)
#
# Method executes script's commands ina special way
#
def run_steps_in_custom_order(config):
for step in config.get('order'):
if(step.get('type') == 'temporary-repo'):
process_temporary_repo_step(config.get(step.get('step')))
if(step.get('type') == 'tests'):
process_tests_step(config.get(step.get('step')))
if(step.get('type') == 'shell'):
process_shell_step(config.get(step.get('step')))
if(step.get('type') == 'ftp'):
if 'mode' in config.get(step.get('step')).keys() and config.get(step.get('step')).get('mode') == 'redeploy':
redeploy_to_ftp(
config.get(step.get('step')).get('host') , config.get(step.get('step')).get('user') ,
config.get(step.get('step')).get('password') , config.get(step.get('step')).get('path')
)
else:
deploy_to_ftp(
config.get(step.get('step')).get('host') , config.get(step.get('step')).get('user') ,
config.get(step.get('step')).get('password') , config.get(step.get('step')).get('path')
)
#
# Method runs JSON config
#
def run_script(config):
if('order' in config):
run_steps_in_custom_order(config)
if('repo' in config):
for batch in config.get('repo'):
copy_vendors(batch.get('vendors') , batch.get('path'))
if('vendor-repo' in config):
for batch in config.get('vendor-repo'):
copy_vendors(batch.get('vendors') , batch.get('path'))
if('self-repo' in config):
process_self('SELF' , config.get('self-repo').get('path') , './' , 'COPY' , False)
if('temporary-repo' in config):
process_temporary_repo_step(config.get('temporary-repo'))
if('tests' in config):
process_tests_step(config.get('tests'))
if('ftp' in config):
if 'mode' in config.get('ftp').keys() and config.get('ftp').get('mode') == 'redeploy':
redeploy_to_ftp(
config.get('ftp').get('host') , config.get('ftp').get('user') ,
config.get('ftp').get('password') , config.get('ftp').get('path')
)
else:
deploy_to_ftp(
config.get('ftp').get('host') , config.get('ftp').get('user') ,
config.get('ftp').get('password') , config.get('ftp').get('path')
)
#
# Run method body
#
def run_body():
startup()
file_name = os.path.splitext(os.path.basename(sys.argv[ 0 ]))[ 0 ]
global run_settings
run_settings = '.' + file_name
with open('./' + file_name + '.json') as JSONFile:
config = json.load(JSONFile)
run_script(config)
#
# Method configures/deploys project
#
def run():
try:
run_body()
finish()
except Exception as Err:
cancel(Err)
#
# Method runs script in verbose way
#
def run_verbose():
try:
run_body()
finish_verbose()
except(Exception) as Err:
cancel_verbose(Err)
#
# Method reads service name
#
def read_service_name(message):
print(message)
service_name = os.read(0, 100)
service_name = str(service_name, "ascii").lower().strip()
return service_name
#
#
#
def create_service_folders(service_name):
# Creating folders
global service_folders
for folder_path in service_folders:
folder_path = folder_path.replace('{service-name}', service_name)
safe_create_folder(folder_path)
#
# Method creates files from templates
#
def create_files_from_templates(templates, service_name, service_class_name):
for key in templates:
file_path = key.replace('{service-name}', service_name)
file_path = file_path.replace('{service-class-name}', service_class_name)
if(os.path.isfile(file_path) == False):
file_content = templates[key].replace('{service-name}', service_name)
file_content = file_content.replace('{service-class-name}', service_class_name)
with open(file_path, 'w') as file:
file.write(file_content)
#
# Method creates common service's parts
#
def init_common_service_part():
startup()
service_name = read_service_name("Input name of the service")
create_service_folders(service_name)
parts = service_name.split("-")
service_class_name = ''
for part in parts:
service_class_name = service_class_name + part.capitalize()
# creating common files
global common_service_file_templates
create_files_from_templates(common_service_file_templates, service_name, service_class_name)
return service_name , service_class_name
#
# Method runs final initializations
#
def final_init(config):
run_script(json.loads(config))
print("Success!")
#
# Method inits new service
#
def init_service():
try:
service_name , service_class_name = init_common_service_part()
# creating service files
global service_file_templates
create_files_from_templates(service_file_templates, service_name, service_class_name)
final_init(service_file_templates['./build.json'])
except Exception as Err:
final_messaging(Err)
#
# Method creates crud service
#
def init_crud_service():
try:
service_name , service_class_name = init_common_service_part()
# creating CRUD service files
global crud_service_file_templates
create_files_from_templates(crud_service_file_templates, service_name, service_class_name)
final_init(crud_service_file_templates['./build.json'])
except Exception as Err:
final_messaging(Err)
#
# Method installs vendor for temporary usage
#
def install_temporary_vendor(vendor , src_path , dst_path='./vendor/'):
# create vendor folder
safe_create_folder(dst_path)
# getting ALL files
files = build_recursive_dir_tree(src_path + vendor + '/')
# uploading sources
upload_component_sources(files , vendor , src_path , dst_path , 'INSTALL')
# store processed component so it can be rolled back
temporary_vendors.append(dst_path + vendor)
#
# Method installs temporary vendors for the service
#
def install_temporary_vendors(vendors , src_path , dst_path='./vendor/'):
for vendor in vendors:
install_temporary_vendor(vendor , src_path , dst_path)
#
# Method lears temporary vendors
#
def clear_temporary_vendors():
try:
for vendor in temporary_vendors:
print('UNINSTALL: ' + vendor)
clear_directory(vendor + '/')
os.rmdir(vendor)
except:
pass
#
# Method clears directory
#
def clear_directory(dir):
try:
for file in os.listdir(dir):
file_path = os.path.join(dir , file)
try:
if os.path.isfile(file_path):
os.unlink(file_path)
elif os.path.isdir(file_path): shutil.rmtree(file_path)
except Exception as e:
print(e)
except FileNotFoundError as Err:
pass
shutil.rmtree(dir , ignore_errors=True)
#
# Method setups script
#
def startup():
# os.chdir( os.getcwd() )
os.chdir(os.path.dirname(sys.argv[ 0 ]))