2012-09-18 13:26:44 +04:00
#!/usr/bin/python -tt
# -*- coding: UTF-8 -*-
import sys
import argparse
2012-10-12 15:03:56 +04:00
from argparse import RawDescriptionHelpFormatter
2012-09-18 13:26:44 +04:00
import os
2012-09-19 13:38:52 +04:00
import shutil
2012-10-10 18:16:22 +04:00
from datetime import datetime
2012-10-11 18:13:59 +04:00
import pdb
2012-09-19 13:38:52 +04:00
2012-09-18 13:26:44 +04:00
from abf . console . config import Config
from abf . console . log import Log
cfg = Config ( )
log = Log ( ' abf ' )
from abf . console . misc import *
2012-10-10 18:16:22 +04:00
from abf . api . exceptions import *
from abf . model import *
2012-09-18 13:26:44 +04:00
domain = cfg [ ' main ' ] [ ' domain ' ]
login = cfg [ ' user ' ] [ ' login ' ]
password = cfg [ ' user ' ] [ ' password ' ]
2012-09-25 16:21:45 +04:00
default_group = cfg [ ' user ' ] [ ' default_group ' ]
2012-10-10 18:16:22 +04:00
default_build_platform = cfg [ ' user ' ] [ ' default_build_platform ' ]
2012-09-18 13:26:44 +04:00
#models = Models(domain, login, password)
2012-10-10 18:16:22 +04:00
#r = models.platforms[64]
#r = models.repositories[1]
#r = models.projects[('abf_core', 'abf_core')]
#r = models.projects['akirilenko/libqb']
#r = models.projects['akirilenko/fba']
#r = models.buildlists['715552']
#r = models.arches['1']
#r = models.get_user_platforms_main()
#r = models.get_user_platforms_personal()
#r = models.get_build_platforms()
#r = models.get_arches()
#print r
#print r.repositories
2012-10-11 18:13:59 +04:00
2012-09-18 13:26:44 +04:00
#exit()
2012-10-10 18:16:22 +04:00
2012-09-18 13:26:44 +04:00
def parse_command_line ( ) :
global command_line
2012-09-18 13:44:38 +04:00
parser = argparse . ArgumentParser ( description = ' ABF Console Client ' )
2012-10-12 15:03:56 +04:00
parser . add_argument ( ' -v ' , ' --verbose ' , action = ' store_true ' , help = ' be verbose, display even debug messages ' )
2012-10-10 18:16:22 +04:00
parser . add_argument ( ' -c ' , ' --clear-cache ' , action = ' store_true ' , help = ' clear cached information about repositories, platforms, projects, etc. ' )
2012-10-11 18:13:59 +04:00
parser . add_argument ( ' -q ' , ' --quiet ' , action = ' store_true ' , help = ' Do not display info messages ' )
2012-09-18 13:44:38 +04:00
subparsers = parser . add_subparsers ( )
2012-09-18 13:26:44 +04:00
2012-09-19 14:02:56 +04:00
# help
parser_get = subparsers . add_parser ( ' help ' , help = ' show a help for command ' )
2012-10-12 15:03:56 +04:00
parser_get . add_argument ( ' command ' , action = ' store ' , nargs = ' ? ' , help = ' a command to show help for ' )
2012-09-19 14:02:56 +04:00
parser_get . set_defaults ( func = help )
2012-09-18 13:26:44 +04:00
# get
2012-09-18 13:44:38 +04:00
parser_get = subparsers . add_parser ( ' get ' , help = ' clone a project from ABF ' )
2012-10-12 15:03:56 +04:00
parser_get . add_argument ( ' project ' , action = ' store ' , help = ' project name. ([group/]project). If no group specified, '
' it \' s assumed to be your default group. ' )
2012-09-18 13:26:44 +04:00
parser_get . add_argument ( ' -b ' , ' --branch ' , action = ' store ' , help = ' branch to checkout ' )
parser_get . set_defaults ( func = get )
# put
2012-10-12 15:03:56 +04:00
parser_get = subparsers . add_parser ( ' put ' , help = ' run " git add --all " , " git commit -m <your message> " , " git push " ' )
2012-09-18 13:44:38 +04:00
parser_get . add_argument ( ' message ' , action = ' store ' , help = ' a message to commit with ' )
2012-09-18 13:26:44 +04:00
parser_get . set_defaults ( func = put )
# build
2012-10-12 15:03:56 +04:00
parser_build = subparsers . add_parser ( ' build ' , help = ' Initiate a build task on ABF. ' , formatter_class = RawDescriptionHelpFormatter ,
epilog = ' NOTES: \n '
' API takes git commit hash to build. So client have to resolve it. \n '
' 1) If you \' ve specified commit hash - it will be used " as is " . \n '
' 2) If you \' ve specified branch or tag name - it will be resolved automatically \n '
' using ABF API. (the hash of top commit will be used for branch) \n '
' 3) If you \' ve specified no git commit related options and you \' ve \n '
' specified a project name - this project \' s default branch will be used. \n '
' 4) If you \' ve specified no git commit related options and you \' ve \n '
' not specified a project name (you have to be in a git repository) - \n '
' the top remote commit of your current branch will be used. \n ' )
parser_build . add_argument ( ' -p ' , ' --project ' , action = ' store ' , help = ' project name ([group/]project). If no group '
' specified, it is assumed to be your default group. If the option is not specified and you are in a git '
' repository directory - resolve a project name from it. ' )
2012-10-11 18:13:59 +04:00
parser_build . add_argument ( ' -b ' , ' --branch ' , action = ' store ' , help = ' branch to build. ' )
2012-10-12 15:03:56 +04:00
parser_build . add_argument ( ' -t ' , ' --tag ' , action = ' store ' , help = ' tag to build. ' )
parser_build . add_argument ( ' -c ' , ' --commit ' , action = ' store ' , help = ' commit sha hash to build. ' )
parser_build . add_argument ( ' -s ' , ' --save-to-repository ' , action = ' store ' , help = ' repository to save results to '
' ([platform/]repository). If no platform part specified, it is assumed to be " <default_group>_personal " . '
' If this option is not specified at all, " <default_group>_personal/main " will be used. ' )
parser_build . add_argument ( ' -a ' , ' --arch ' , action = ' append ' , help = ' architectures to build, '
' can be set more than once. If not set - use all the available architectures. ' )
parser_build . add_argument ( ' -r ' , ' --repository ' , action = ' append ' , help = ' repositories to build with ([platform/]repository). '
' Can be set more than once. If no platform part specified, it is assumed to be your " <default_build platform> " . '
' If no repositories were specified at all, use the " main " repository from save-to platform. ' )
parser_build . add_argument ( ' --auto-publish ' , action = ' store_true ' , help = ' enable automatic publishing. ' )
2012-10-11 18:13:59 +04:00
upd_types = [ ' security ' , ' bugfix ' , ' enhancement ' , ' recommended ' , ' newpackage ' ]
2012-10-12 15:03:56 +04:00
parser_build . add_argument ( ' --update-type ' , action = ' store ' , choices = upd_types , help = ' Update type. Default is " %s " . ' %
2012-10-11 18:13:59 +04:00
( BuildList . update_types [ 0 ] ) )
2012-09-18 13:26:44 +04:00
parser_build . set_defaults ( func = build )
2012-10-11 18:13:59 +04:00
# publish
2012-10-12 15:03:56 +04:00
parser_build = subparsers . add_parser ( ' publish ' , help = ' Publish the task that have already been built. ' )
parser_build . add_argument ( ' task_ids ' , action = ' store ' , nargs = " + " , help = ' The IDs of the tasks to publish. ' )
2012-10-11 18:13:59 +04:00
parser_build . set_defaults ( func = publish )
2012-09-19 13:38:52 +04:00
# backport
2012-10-12 15:03:56 +04:00
parser_build = subparsers . add_parser ( ' backport ' , help = ' Copy all the files from SRC_BRANCH to DST_BRANCH ' )
2012-09-19 13:38:52 +04:00
parser_build . add_argument ( ' src_branch ' , action = ' store ' , help = ' source branch ' )
2012-10-12 15:03:56 +04:00
parser_build . add_argument ( ' dst_branch ' , action = ' store ' , nargs = ' ? ' , help = ' destination branch. If not specified, it \' s assumed to be the current branch ' )
2012-09-19 13:38:52 +04:00
parser_build . add_argument ( ' -p ' , ' --pack ' , action = ' store_true ' , help = ' Create a tar.gz from the src_branch and put this archive and spec file to dst_branch ' )
parser_build . set_defaults ( func = backport )
2012-09-18 13:26:44 +04:00
# buildstatus
2012-10-12 15:03:56 +04:00
parser_build = subparsers . add_parser ( ' buildstatus ' , help = ' get a build-task status ' )
2012-09-18 13:44:38 +04:00
parser_build . add_argument ( ' ID ' , action = ' store ' , nargs = ' ? ' , help = ' build list ID ' )
2012-09-18 13:26:44 +04:00
parser_build . set_defaults ( func = buildstatus )
command_line = parser . parse_args ( sys . argv [ 1 : ] )
2012-09-19 14:02:56 +04:00
def help ( ) :
if command_line . command :
sys . argv = [ sys . argv [ 0 ] , command_line . command , ' -h ' ]
else :
sys . argv = [ sys . argv [ 0 ] , ' -h ' ]
parse_command_line ( )
2012-09-18 13:26:44 +04:00
def get ( ) :
log . debug ( ' GET started ' )
proj = command_line . project
tmp = proj . split ( ' / ' )
if len ( tmp ) > 2 :
log . error ( ' Specify a project name as " group_name/project_name " or just " project_name " ' )
exit ( 1 )
if len ( tmp ) == 1 :
proj = ' %s / %s ' % ( cfg [ ' user ' ] [ ' default_group ' ] , proj )
uri = " %s / %s .git " % ( cfg [ ' user ' ] [ ' git_uri ' ] , proj )
cmd = [ ' git ' , ' clone ' , uri ]
if command_line . branch :
cmd + = [ ' -b ' , command_line . branch ]
2012-09-25 16:21:45 +04:00
execute_command ( cmd , log = log , print_to_stdout = True , exit_on_error = True )
2012-09-18 13:26:44 +04:00
def put ( ) :
log . debug ( ' PUT started ' )
2012-10-12 15:03:56 +04:00
cmd = [ ' git ' , ' add ' , ' --all ' ]
execute_command ( cmd , log = log , print_to_stdout = True , exit_on_error = True )
cmd = [ ' git ' , ' commit ' , ' -m ' , command_line . message ]
2012-09-25 16:21:45 +04:00
execute_command ( cmd , log = log , print_to_stdout = True , exit_on_error = True )
2012-09-18 13:26:44 +04:00
log . info ( ' Commited. ' )
cmd = [ ' git ' , ' push ' ]
2012-09-25 16:21:45 +04:00
execute_command ( cmd , log = log , print_to_stdout = True , exit_on_error = True )
2012-09-18 13:26:44 +04:00
log . info ( ' Pushed ' )
2012-09-19 13:38:52 +04:00
def backport ( ) :
log . debug ( ' BACKPORT started ' )
sbrn = command_line . src_branch
start_branch = get_branch_name ( )
if not start_branch :
log . error ( " You are not in a git directory " )
exit ( 1 )
log . debug ( " Current brunch is " + start_branch )
if command_line . dst_branch :
dbrn = command_line . dst_branch
else :
dbrn = start_branch
if sbrn == dbrn :
log . error ( " Source and destination branches shold be different branches! " )
exit ( 1 )
path = get_root_git_dir ( )
log . debug ( " Repository root folder is " + path )
stage = 0
try :
if start_branch != dbrn :
cmd = [ ' git ' , ' checkout ' , dbrn ]
execute_command ( cmd , log , print_to_stdout = True , cwd = path )
stage = 1
cmd = [ ' rm ' , ' -rf ' , ' ./* ' ]
2012-09-25 16:21:45 +04:00
execute_command ( cmd , log = log , print_to_stdout = True , cwd = path )
2012-09-19 13:38:52 +04:00
stage = 2
cmd = [ ' git ' , ' checkout ' , sbrn , ' * ' ]
2012-09-25 16:21:45 +04:00
execute_command ( cmd , log = log , print_to_stdout = True , cwd = path )
2012-09-19 13:38:52 +04:00
stage = 3
if command_line . pack :
pack_project ( log , path )
cmd = [ ' git ' , ' reset ' ]
2012-09-25 16:21:45 +04:00
execute_command ( cmd , log = log , print_to_stdout = True , cwd = path )
2012-09-19 13:38:52 +04:00
except Exception , ex :
if type ( ex ) == ReturnCodeNotZero :
log . error ( str ( ex ) )
else :
log . exception ( ex )
if stage == 1 or stage == 2 :
log . info ( " Checking out the initial branch ( %s ) " % start_branch )
cmd = [ ' git ' , ' reset ' , ' --hard ' , start_branch ]
2012-09-25 16:21:45 +04:00
execute_command ( cmd , log = log , print_to_stdout = True , cwd = path )
2012-09-19 13:38:52 +04:00
log . info ( ' Done ' )
2012-09-18 13:26:44 +04:00
def build ( ) :
log . debug ( ' BUILD started ' )
2012-10-10 18:16:22 +04:00
2012-09-18 13:26:44 +04:00
IDs = {
' arches ' : [ ] ,
' version ' : None ,
' target_platform ' : None ,
' repositories ' : [ ] ,
}
2012-10-10 18:16:22 +04:00
models = Models ( domain , login , password )
2012-10-11 18:13:59 +04:00
2012-10-12 15:03:56 +04:00
2012-10-10 18:16:22 +04:00
# get project
2012-09-18 13:26:44 +04:00
if command_line . project :
tmp = command_line . project . split ( ' / ' )
2012-09-25 16:21:45 +04:00
if len ( tmp ) > 2 :
2012-10-10 18:16:22 +04:00
log . error ( ' The project format is " [owner_name/]project_name " ' )
2012-09-18 13:26:44 +04:00
exit ( 1 )
2012-09-25 16:21:45 +04:00
elif len ( tmp ) == 1 :
project_name = tmp [ 0 ]
log . info ( " The project group is assumed to be " + default_group )
owner_name = default_group
else : # len == 2
owner_name = tmp [ 0 ]
project_name = tmp [ 1 ]
2012-09-18 13:26:44 +04:00
else :
owner_name , project_name = get_project_name ( )
if not project_name :
2012-10-10 18:16:22 +04:00
log . error ( ' You are not in git repository directory. Specify the project name please! ' )
2012-09-18 13:26:44 +04:00
exit ( 1 )
2012-10-10 18:16:22 +04:00
try :
proj = models . projects [ ' %s / %s ' % ( owner_name , project_name ) ]
except PageNotFoundError :
2012-10-11 18:13:59 +04:00
log . error ( ' The project %s / %s does not exist! ' % ( owner_name , project_name ) )
2012-09-18 13:26:44 +04:00
exit ( 1 )
2012-10-10 18:16:22 +04:00
except ForbiddenError :
log . error ( ' You do not have acces to the project %s / %s ! ' % ( owner_name , project_name ) )
exit ( 1 )
log . debug ( ' Project: %s ' % proj )
if not proj . is_package :
log . error ( ' The project %s is not a package and can not be built. ' % proj )
exit ( 1 )
2012-09-18 13:26:44 +04:00
2012-10-10 18:16:22 +04:00
# get architectures
arches = [ ]
all_arches = models . get_arches ( )
2012-10-12 15:03:56 +04:00
if command_line . arch :
for arch in command_line . arch :
2012-10-10 18:16:22 +04:00
a = models . arches . get_string_key ( arch )
if not a :
log . error ( " Invalid architecture: %s " % arch )
2012-09-18 13:26:44 +04:00
exit ( 1 )
2012-10-10 18:16:22 +04:00
arches . append ( a )
2012-09-18 13:26:44 +04:00
else :
2012-10-10 18:16:22 +04:00
arches = all_arches
2012-09-25 16:21:45 +04:00
log . info ( " Arches are assumed to be " + str ( arches ) )
2012-10-10 18:16:22 +04:00
2012-09-18 13:26:44 +04:00
log . debug ( ' Architectures: %s ' % arches )
2012-10-10 18:16:22 +04:00
# get git commit hash
tag_def = bool ( command_line . tag )
branch_def = bool ( command_line . branch )
commit_def = bool ( command_line . commit )
2012-09-18 13:26:44 +04:00
2012-10-10 18:16:22 +04:00
tmp = tag_def + branch_def + commit_def
commit_hash = None
if tmp == 0 :
2012-10-11 18:13:59 +04:00
if command_line . project :
command_line . branch = proj . default_branch
else : # we are in a git repository and it the project we are building
2012-10-12 15:03:56 +04:00
command_line . branch = get_branch_name ( )
log . info ( ' The git branch is assumed to be " %s " ' % command_line . branch )
branch_def = True
tmp = 1
2012-10-11 18:13:59 +04:00
if tmp == 1 :
2012-10-10 18:16:22 +04:00
if commit_def :
commit_hash = command_line . commit
2012-09-18 13:26:44 +04:00
else :
2012-10-12 15:03:56 +04:00
to_resolve = command_line . branch or command_line . tag
ref_type = ( branch_def and ' commit ' ) or ( tag_def and ' tag ' )
refs = proj . get_refs_list ( models )
for ref in refs :
if ref [ ' ref ' ] == to_resolve and ref [ ' object ' ] [ ' type ' ] == ref_type :
commit_hash = ref [ ' object ' ] [ ' sha ' ]
if commit_hash == None :
log . error ( " Could not resolve hash for %s ' %s ' " % ( ref_type , to_resolve ) )
2012-10-11 18:13:59 +04:00
exit ( 1 )
if tmp > 1 :
2012-10-10 18:16:22 +04:00
log . error ( " You should specify ONLY ONE of the following options: branch, tag or commit. " )
2012-09-18 13:26:44 +04:00
exit ( 1 )
2012-10-10 18:16:22 +04:00
log . debug ( ' Git commit hash: %s ' % commit_hash )
2012-10-12 15:03:56 +04:00
2012-10-10 18:16:22 +04:00
# get save-to repository
save_to_repository = None
build_for_platform = None
2012-10-11 18:13:59 +04:00
available_repos = proj . repositories
2012-10-12 15:03:56 +04:00
if command_line . save_to_repository :
items = command_line . save_to_repository . split ( ' / ' )
else :
items = [ ]
2012-10-11 18:13:59 +04:00
if len ( items ) == 2 :
repo_name = items [ 1 ]
pl_name = items [ 0 ]
elif len ( items ) == 1 :
repo_name = items [ 0 ]
pl_name = default_group + ' _personal '
log . info ( " Save-to platform is assumed to be " + pl_name )
elif len ( items ) == 0 :
pl_name = default_group + ' _personal '
repo_name = ' main '
log . info ( " Save-to repository is assumed to be %s / %s " % ( pl_name , repo_name ) )
else :
log . error ( " save-to-repository option format: [platform/]repository " )
exit ( 1 )
pls = [ ]
for repo in available_repos :
if repo . platform . name == pl_name :
build_for_platform = repo . platform
pls . append ( repo . platform . name )
if not build_for_platform :
log . error ( " Can not build for platform %s . Select one of the following: \n %s " % ( pl_name , ' , ' . join ( pls ) ) )
exit ( 1 )
2012-09-18 13:26:44 +04:00
2012-10-11 18:13:59 +04:00
for repo in build_for_platform . repositories :
if repo . name == repo_name :
save_to_repository = repo
break
if not save_to_repository :
log . error ( " Incorrect save-to repository %s / %s . \n Select one of the following: \n %s " % ( pl_name , repo_name ,
' , ' . join ( [ str ( x ) for x in build_for_platform . repositories ] ) ) )
exit ( 1 )
2012-09-18 13:26:44 +04:00
2012-10-10 18:16:22 +04:00
log . debug ( ' Save-to repository: ' + str ( save_to_repository ) )
2012-09-18 13:26:44 +04:00
2012-10-11 18:13:59 +04:00
# get the list of build repositories
2012-10-10 18:16:22 +04:00
build_platforms = models . get_build_platforms ( )
build_platform_names = [ x . name for x in build_platforms ]
build_repositories = [ ]
2012-09-18 13:26:44 +04:00
if command_line . repository :
2012-09-25 16:21:45 +04:00
for repo in command_line . repository :
2012-10-10 18:16:22 +04:00
items = repo . split ( ' / ' )
if len ( items ) == 2 :
repo_name = items [ 1 ]
pl_name = items [ 0 ]
elif len ( items ) == 1 :
repo_name = items [ 0 ]
pl_name = default_build_platform
log . info ( " Platform for selected repository %s is assumed to be %s " % ( repo_name , pl_name ) )
else :
log . error ( " ' repository ' option format: [platform/]repository " )
exit ( 1 )
if pl_name not in build_platform_names :
2012-10-11 18:13:59 +04:00
log . error ( " Can not connect repositories from %s ! \n Select one of the following: \n %s " % ( pl_name ,
2012-10-10 18:16:22 +04:00
' , ' . join ( build_platform_names ) ) )
exit ( 1 )
for pl in build_platforms :
if pl . name == pl_name :
build_platform = pl
break
build_repo = None
for repo in build_platform . repositories :
if repo . name == repo_name :
build_repo = repo
break
if not build_repo :
log . error ( " Platform %s does not have repository %s ! \n Select one of the following: \n %s " % ( pl_name , repo_name ,
' , ' . join ( [ x . name for x in build_platform . repositories ] ) ) )
exit ( 1 )
build_repositories . append ( build_repo )
2012-10-11 18:13:59 +04:00
else :
build_platform = save_to_repository . platform
if build_platform . name not in build_platform_names or not build_platform . repositories :
log . error ( " Could not resolve repositories to build with. Please specify it (-r option) " )
exit ( 1 )
2012-09-18 13:26:44 +04:00
2012-10-11 18:13:59 +04:00
for repo in build_platform . repositories :
if repo . name == ' main ' :
log . info ( " The repository to build with is assumed to be " + str ( repo ) )
build_repositories = [ repo ]
2012-10-10 18:16:22 +04:00
2012-10-11 18:13:59 +04:00
if not build_repositories :
log . error ( " You have to specify the repository(s) to build with (-r option) " )
exit ( 1 )
2012-10-10 18:16:22 +04:00
log . debug ( " Build repositories: " + str ( build_repositories ) )
2012-10-11 18:13:59 +04:00
BuildList . new_build_task ( models , proj , save_to_repository , build_repositories , commit_hash ,
command_line . update_type or BuildList . update_types [ 0 ] , command_line . auto_publish , arches )
2012-10-10 18:16:22 +04:00
2012-10-11 18:13:59 +04:00
def publish ( ) :
log . debug ( ' PUBLISH started ' )
2012-10-12 15:03:56 +04:00
models = Models ( domain , login , password )
for task_id in command_line . task_ids :
try :
bl = models . buildlists [ task_id ]
if bl . status != 0 :
log . error ( " The status of build task %s is \" %s \" , can not publish it! " % ( bl . id , bl . status_by_id [ bl . status ] ) )
continue
res = bl . publish ( models )
except AbfApiException , ex :
log . error ( ' Could not publish task %s : %s ' % ( task_id , str ( ex ) ) )
2012-10-11 18:13:59 +04:00
2012-09-18 13:26:44 +04:00
def buildstatus ( ) :
log . debug ( ' BUILDSTATUS started ' )
if not command_line . ID :
log . error ( " Enter the ID, please. It can not be resolved automatically now (not implemented). " )
exit ( 1 )
2012-10-10 18:16:22 +04:00
try :
models = Models ( domain , login , password )
bl = models . buildlists [ command_line . ID ]
2012-10-11 18:13:59 +04:00
except AbfApiException , ex :
log . error ( str ( ex ) )
2012-10-10 18:16:22 +04:00
exit ( 3 )
print ' %-20s %s ' % ( ' Owner: ' , bl . owner [ ' name ' ] )
print ' %-20s %s ' % ( ' Status: ' , BuildList . status_by_id [ bl . status ] )
print ' %-20s %s ' % ( ' Build for platform: ' , bl . build_for_platform )
print ' %-20s %s ' % ( ' Save to repository: ' , bl . save_to_repository )
print ' %-20s %s ' % ( ' Build repositories: ' , bl . include_repos )
print ' %-20s %s ' % ( ' Architecture: ' , bl . arch . name )
print ' %-20s %s ' % ( ' Created at: ' , datetime . fromtimestamp ( float ( bl . created_at ) ) )
print ' %-20s %s ' % ( ' Updated at: ' , datetime . fromtimestamp ( float ( bl . updated_at ) ) )
2012-09-18 13:26:44 +04:00
if __name__ == ' __main__ ' :
parse_command_line ( )
if command_line . verbose :
Log . set_verbose ( )
2012-10-11 18:13:59 +04:00
if command_line . quiet :
Log . set_quiet ( )
2012-10-10 18:16:22 +04:00
if command_line . clear_cache :
Models . clear_cache ( )
2012-09-18 13:26:44 +04:00
command_line . func ( )