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-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 ( )
2012-10-25 15:26:22 +04:00
projects_cfg = Config ( conf_path = ' ~/.abf_projects ' , main_conf = False )
2012-09-18 13:26:44 +04:00
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
2012-11-14 15:04:19 +04:00
abf_url = cfg [ ' main ' ] [ ' abf_url ' ]
file_store_url = cfg [ ' main ' ] [ ' file_store_url ' ]
2012-09-18 13:26:44 +04:00
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-11-14 15:04:19 +04:00
models_params = ( ( abf_url , file_store_url , login , password ) )
2012-09-18 13:26:44 +04:00
2012-11-14 15:04:19 +04:00
models = Models ( * models_params )
#r = models.jsn.upload_file('/tmp/log')
2012-10-10 18:16:22 +04:00
2012-10-31 18:58:23 +04:00
#r = Group(models, 2)
2012-10-25 15:26:22 +04:00
#r = Platform(models, init_data={'id':64, 'name': 'AAAA'})
2012-10-10 18:16:22 +04:00
#r = models.platforms[64]
2012-10-25 15:26:22 +04:00
#r = Platform(models, ID=64)
#r = Repository(models, ID=71)
2012-10-31 18:58:23 +04:00
#r = Project.get_by_name(models, 'import/mock-urpm')
2012-10-25 15:26:22 +04:00
#r = BuildList(models, ID=750988)
2012-10-10 18:16:22 +04:00
#r = models.get_user_platforms_main()
#r = models.get_user_platforms_personal()
#r = models.get_build_platforms()
#r = models.get_arches()
2012-10-25 15:26:22 +04:00
#print r.repositories[0].platform.repositories[2].platform
2012-10-11 18:13:59 +04:00
2012-09-18 13:26:44 +04:00
#exit()
2012-11-14 15:04:19 +04:00
2012-09-18 13:26:44 +04:00
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-10-25 18:26:51 +04:00
subparsers = parser . add_subparsers ( title = ' command ' )
2012-09-18 13:26:44 +04:00
2012-09-19 14:02:56 +04:00
# help
2012-10-25 15:26:22 +04:00
parser_help = subparsers . add_parser ( ' help ' , help = ' show a help for command ' )
parser_help . add_argument ( ' command ' , action = ' store ' , nargs = ' ? ' , help = ' a command to show help for ' )
parser_help . set_defaults ( func = help )
2012-09-19 14:02:56 +04:00
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-11-14 15:04:19 +04:00
parser_put = subparsers . add_parser ( ' put ' , help = ' Upload large binary files to File-Store, commit all the changes (git add --all), commit with a message specified and push ' )
parser_put . add_argument ( ' -m ' , ' --message ' , action = ' store ' , help = ' A message to commit with. It is ignored in case of " --do-not-upload " ' )
parser_put . add_argument ( ' -u ' , ' --upload-only ' , action = ' store_true ' , help = ' Upload large files to file-store and exit ' )
parser_put . add_argument ( ' -d ' , ' --do-not-upload ' , action = ' store ' , help = ' Do nothing with .abf.yml, just add, commit and push ' )
2012-11-20 12:00:28 +04:00
parser_put . add_argument ( ' -s ' , ' --minimal-file-size ' , default = ' 0 ' , action = ' store ' , help = ' The minimal file size to upload to File-Store. '
' Default is 0B. ' )
2012-11-14 15:04:19 +04:00
parser_put . add_argument ( ' -r ' , ' --do-not-remove-files ' , action = ' store_true ' , help = ' By default files are being removed on uploading. Override this behavior. ' )
2012-10-25 15:26:22 +04:00
parser_put . set_defaults ( func = put )
2012-11-14 15:04:19 +04:00
# fetch
parser_fetch = subparsers . add_parser ( ' fetch ' , help = ' Download all the files listed in .abf.yml from File-Store to local directory. ' )
parser_fetch . add_argument ( ' -o ' , ' --only ' , action = ' store ' , nargs = ' + ' , help = ' Limit the list of downloaded files to this file name(s). This option can be specified more than once. ' )
parser_fetch . set_defaults ( func = fetch )
2012-10-25 15:26:22 +04:00
# show
parser_show = subparsers . add_parser ( ' show ' , help = ' show some general information. Bash autocomplete uses it. ' )
show_choices = [ ' build-repos ' , ' build-platforms ' , ' save-to-repos ' , ' save-to-platforms ' ]
parser_show . add_argument ( ' type ' , action = ' store ' , choices = show_choices , help = ' The type of information to show ' )
parser_show . add_argument ( ' -p ' , ' --project ' , action = ' store ' , help = ' Project to show information for (if needed). Format: '
' " [group/]name " . If no group specified, default group will be used. ' )
parser_show . set_defaults ( func = show )
# locate
2012-10-26 12:14:30 +04:00
parser_locate = subparsers . add_parser ( ' locate ' , help = ' tool can remember the project location and use it for some reasons (abfcd, etc.). ' ,
epilog = ' Every interaction with git repository (build, get, put, etc.) updates the cached location of the project (overriding '
' an existing one if needed). For any cached project you can execute " abfcd <project> " and you will cd to the project directory. ' )
2012-10-25 15:26:22 +04:00
locate_choices = [ ' update ' , ' update-recursive ' ]
parser_locate . add_argument ( ' action ' , action = ' store ' , choices = locate_choices , nargs = ' ? ' , help = ' The type of information to show ' )
parser_locate . add_argument ( ' -p ' , ' --project ' , action = ' store ' , help = ' Project to show information for (if needed). Format: '
' " [group/]name " . If no group specified, default group will be used. ' )
parser_locate . add_argument ( ' -d ' , ' --directory ' , action = ' store ' , help = ' Directory to update locations for. It should be a '
' git repository for " update " and any directory for " update-recursive " . If not specified - the current directory will be used ' )
parser_locate . set_defaults ( func = locate )
2012-09-18 13:26:44 +04:00
# 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). '
2012-11-14 18:29:38 +04:00
' Can be set more than once. If no platform part specified, it is assumed to be your " <default_build_platform> " . '
2012-10-12 15:03:56 +04:00
' 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-10-25 15:26:22 +04:00
parser_build . add_argument ( ' --skip-spec-check ' , action = ' store_true ' , help = ' Do not check spec file. ' )
2012-09-18 13:26:44 +04:00
parser_build . set_defaults ( func = build )
2012-11-14 18:29:38 +04:00
''' # localbuild-mock-urpm
parser_localbuild_mock_urpm = subparsers . add_parser ( ' localbuild-mock-urpm ' , help = ' Initiate a build task on ABF. ' )
parser_localbuild_mock_urpm . add_argument ( ' -b ' , ' --branch ' , action = ' store ' , help = ' branch to build. ' )
parser_localbuild_mock_urpm . add_argument ( ' -t ' , ' --tag ' , action = ' store ' , help = ' tag to build. ' )
parser_localbuild_mock_urpm . add_argument ( ' -c ' , ' --commit ' , action = ' store ' , help = ' commit sha hash to build. ' )
parser_localbuild_mock_urpm . 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_localbuild_mock_urpm . set_defaults ( func = localbuild_mock_urpm )
# localbuild-rpmbuild
parser_localbuild_rpmbuild = subparsers . add_parser ( ' localbuild-rpmbuild ' , help = ' Initiate a build task on ABF. ' )
parser_localbuild_rpmbuild . add_argument ( ' -b ' , ' --branch ' , action = ' store ' , help = ' branch to build. ' )
parser_localbuild_rpmbuild . add_argument ( ' -t ' , ' --tag ' , action = ' store ' , help = ' tag to build. ' )
parser_localbuild_rpmbuild . add_argument ( ' -c ' , ' --commit ' , action = ' store ' , help = ' commit sha hash to build. ' )
parser_localbuild_rpmbuild . 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_localbuild_rpmbuild . set_defaults ( func = localbuild_rpmbuild ) '''
2012-10-11 18:13:59 +04:00
# publish
2012-10-25 15:26:22 +04:00
parser_publish = subparsers . add_parser ( ' publish ' , help = ' Publish the task that have already been built. ' )
parser_publish . add_argument ( ' task_ids ' , action = ' store ' , nargs = " + " , help = ' The IDs of tasks to publish. ' )
parser_publish . set_defaults ( func = publish )
2012-10-11 18:13:59 +04:00
2012-09-19 13:38:52 +04:00
# backport
2012-10-25 15:26:22 +04:00
parser_backport = subparsers . add_parser ( ' backport ' , help = ' Copy all the files from SRC_BRANCH to DST_BRANCH ' )
parser_backport . add_argument ( ' src_branch ' , action = ' store ' , help = ' source branch ' )
parser_backport . add_argument ( ' dst_branch ' , action = ' store ' , nargs = ' ? ' , help = ' destination branch. If not specified, it \' s assumed to be the current branch ' )
parser_backport . 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_backport . set_defaults ( func = backport )
2012-09-19 13:38:52 +04:00
2012-09-18 13:26:44 +04:00
# buildstatus
2012-10-25 18:26:51 +04:00
parser_clean = subparsers . add_parser ( ' buildstatus ' , help = ' get a build-task status ' , epilog = ' If a project specified '
' or you are in a git repository - try to get the IDs from the last build task sent for this project. If you are not '
' in a git repository directory and project is not specified - try to get build IDs from the last build you \' ve done '
' with console client. ' )
parser_clean . add_argument ( ' ID ' , action = ' store ' , nargs = ' * ' , help = ' build list ID ' )
parser_clean . add_argument ( ' -p ' , ' --project ' , action = ' store ' , help = ' Project. If last IDs for this project can be found - use them ' )
parser_clean . add_argument ( ' -s ' , ' --short ' , action = ' store_true ' , help = ' Show one-line information including id, project, '
' arch and status ' )
2012-10-25 15:26:22 +04:00
parser_clean . set_defaults ( func = buildstatus )
# clean
parser_clean = subparsers . add_parser ( ' clean ' , help = ' Analyze spec file and show missing and unnecessary files from '
' the current git repository directory. ' )
parser_clean . add_argument ( ' --auto-remove ' , action = ' store_true ' , help = ' automatically remove all the unnecessary files ' )
parser_clean . set_defaults ( func = clean )
2012-09-18 13:26:44 +04:00
command_line = parser . parse_args ( sys . argv [ 1 : ] )
2012-09-19 14:02:56 +04:00
2012-11-14 18:29:38 +04:00
def localbuild_mock_urpm ( ) :
pass
def localbuild_rpmbuild ( ) :
log . debug ( ' LOCALBUILD started ' )
# get project
proj = get_project ( models , must_exist = True , name = command_line . project )
if not command_line . project and not command_line . skip_spec_check : # local git repository
find_spec_problems ( )
if not proj . is_package :
log . error ( ' The project %s is not a package and can not be built. ' % proj )
exit ( 1 )
# get architectures
arches = [ ]
all_arches = Arch . get_arches ( models )
if command_line . arch :
for arch in command_line . arch :
a = models . arches . get_string_key ( arch )
if not a :
log . error ( " Invalid architecture: %s " % arch )
exit ( 1 )
arches . append ( a )
else :
arches = all_arches
log . info ( " Arches are assumed to be " + str ( arches ) )
log . debug ( ' Architectures: %s ' % arches )
# get git commit hash
tag_def = bool ( command_line . tag )
branch_def = bool ( command_line . branch )
commit_def = bool ( command_line . commit )
tmp = tag_def + branch_def + commit_def
commit_hash = None
if tmp == 0 :
if command_line . project :
command_line . branch = proj . default_branch
else : # we are in a git repository and it the project we are building
command_line . branch = get_branch_name ( )
log . info ( ' The git branch is assumed to be " %s " ' % command_line . branch )
branch_def = True
tmp = 1
if tmp == 1 :
if commit_def :
commit_hash = command_line . commit
else :
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 ) )
exit ( 1 )
if tmp > 1 :
log . error ( " You should specify ONLY ONE of the following options: branch, tag or commit. " )
exit ( 1 )
log . debug ( ' Git commit hash: %s ' % commit_hash )
# get save-to repository
save_to_repository = None
build_for_platform = None
available_repos = proj . repositories
if command_line . save_to_repository :
items = command_line . save_to_repository . split ( ' / ' )
else :
items = [ ]
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 )
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 )
log . debug ( ' Save-to repository: ' + str ( save_to_repository ) )
# get the list of build repositories
build_platforms = Platform . get_build_platforms ( models )
build_platform_names = [ x . name for x in build_platforms ]
build_repositories = [ ]
if command_line . repository :
for repo in command_line . repository :
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 :
log . error ( " Can not connect repositories from %s ! \n Select one of the following: \n %s " % ( pl_name ,
' , ' . 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 )
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 )
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 ]
if not build_repositories :
log . error ( " You have to specify the repository(s) to build with (-r option) " )
exit ( 1 )
log . debug ( " Build repositories: " + str ( build_repositories ) )
build_ids = 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 )
ids = ' , ' . join ( [ str ( i ) for i in build_ids ] )
projects_cfg [ ' main ' ] [ ' last_build_ids ' ] = ids
projects_cfg [ str ( proj ) ] [ ' last_build_ids ' ] = ids
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-10-25 18:26:51 +04:00
def get_project_name_only ( must_exist = True , name = None ) :
2012-10-25 15:26:22 +04:00
if name :
tmp = name . split ( ' / ' )
if len ( tmp ) > 2 :
log . error ( ' The project format is " [owner_name/]project_name " ' )
exit ( 1 )
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 ]
else :
owner_name , project_name = get_project_name ( )
if not project_name :
if must_exist :
log . error ( ' You are not in a git repository directory. Specify the project name please! ' )
exit ( 1 )
else :
return None
_update_location ( )
2012-10-25 18:26:51 +04:00
return ( owner_name , project_name )
2012-10-25 15:26:22 +04:00
2012-10-25 18:26:51 +04:00
def get_project ( models , must_exist = True , name = None ) :
owner_name , project_name = get_project_name_only ( must_exist , name )
2012-10-25 15:26:22 +04:00
try :
2012-10-25 18:26:51 +04:00
proj = Project . get_by_name ( models , ' %s / %s ' % ( owner_name , project_name ) )
2012-10-25 15:26:22 +04:00
except PageNotFoundError :
log . error ( ' The project %s / %s does not exist! ' % ( owner_name , project_name ) )
exit ( 1 )
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 )
return proj
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 )
2012-10-25 15:26:22 +04:00
elif len ( tmp ) == 1 :
project_name = proj
2012-09-18 13:26:44 +04:00
proj = ' %s / %s ' % ( cfg [ ' user ' ] [ ' default_group ' ] , proj )
2012-10-25 15:26:22 +04:00
elif len ( tmp ) == 2 :
project_name = tmp [ 1 ]
2012-09-18 13:26:44 +04:00
uri = " %s / %s .git " % ( cfg [ ' user ' ] [ ' git_uri ' ] , proj )
cmd = [ ' git ' , ' clone ' , uri ]
if command_line . branch :
cmd + = [ ' -b ' , command_line . branch ]
2012-10-25 15:26:22 +04:00
execute_command ( cmd , print_to_stdout = True , exit_on_error = True )
projects_cfg [ proj ] [ ' location ' ] = os . path . join ( os . getcwd ( ) , project_name )
2012-11-14 15:04:19 +04:00
2012-09-18 13:26:44 +04:00
def put ( ) :
log . debug ( ' PUT started ' )
2012-10-25 15:26:22 +04:00
2012-11-14 15:04:19 +04:00
if not command_line . upload_only and not command_line . message :
log . error ( " Specify a message first! " )
exit ( 1 )
if command_line . upload_only and command_line . do_not_upload :
log . error ( " Conflicting options: --upload-only and --do-not-upload " )
exit ( 1 )
path = get_root_git_dir ( )
yaml_path = os . path . join ( path , ' .abf.yml ' )
if not path :
log . error ( " You have to be in a git repository directory " )
exit ( 1 )
2012-10-25 15:26:22 +04:00
_update_location ( )
2012-11-14 15:04:19 +04:00
if not command_line . do_not_upload :
try :
min_size = human2bytes ( command_line . minimal_file_size )
except ValueError , ex :
log . error ( ' Incorrect " --minimal-file-size " value: %s ' % command_line . minimal_file_size )
exit ( 1 )
2012-11-14 15:45:23 +04:00
error_count = upload_files ( models , min_size , remove_files = not command_line . do_not_remove_files , path = path )
2012-11-14 15:04:19 +04:00
if error_count :
log . info ( ' There were errors while uploading, stopping. ' )
2012-11-21 18:36:07 +04:00
exit ( 1 )
2012-11-14 15:04:19 +04:00
if command_line . upload_only :
return
2012-10-12 15:03:56 +04:00
cmd = [ ' git ' , ' add ' , ' --all ' ]
2012-10-25 15:26:22 +04:00
execute_command ( cmd , print_to_stdout = True , exit_on_error = True )
2012-10-12 15:03:56 +04:00
2012-11-14 15:04:19 +04:00
if os . path . isfile ( yaml_path ) :
cmd = [ ' git ' , ' add ' , ' -f ' , path ]
execute_command ( cmd , print_to_stdout = True , exit_on_error = True )
2012-10-12 15:03:56 +04:00
cmd = [ ' git ' , ' commit ' , ' -m ' , command_line . message ]
2012-10-25 15:26:22 +04:00
execute_command ( cmd , print_to_stdout = True , exit_on_error = True )
2012-09-18 13:26:44 +04:00
log . info ( ' Commited. ' )
cmd = [ ' git ' , ' push ' ]
2012-10-25 15:26:22 +04:00
execute_command ( cmd , print_to_stdout = True , exit_on_error = True )
2012-09-18 13:26:44 +04:00
log . info ( ' Pushed ' )
2012-11-14 15:04:19 +04:00
def fetch ( ) :
log . debug ( ' FETCH started ' )
path = get_root_git_dir ( )
if not path :
log . error ( " You have to be in a git repository directory " )
exit ( 1 )
path = os . path . join ( path , ' .abf.yml ' )
if not os . path . isfile ( path ) :
log . error ( ' File " %s " can not be found ' )
exit ( 1 )
fetch_files ( models , path , command_line . only )
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 )
2012-10-25 15:26:22 +04:00
_update_location ( path = path )
2012-09-19 13:38:52 +04:00
stage = 0
try :
if start_branch != dbrn :
cmd = [ ' git ' , ' checkout ' , dbrn ]
2012-10-25 15:26:22 +04:00
execute_command ( cmd , print_to_stdout = True , cwd = path )
2012-09-19 13:38:52 +04:00
stage = 1
cmd = [ ' rm ' , ' -rf ' , ' ./* ' ]
2012-10-25 15:26:22 +04:00
execute_command ( cmd , print_to_stdout = True , cwd = path )
2012-09-19 13:38:52 +04:00
stage = 2
cmd = [ ' git ' , ' checkout ' , sbrn , ' * ' ]
2012-10-25 15:26:22 +04:00
execute_command ( cmd , print_to_stdout = True , cwd = path )
2012-09-19 13:38:52 +04:00
stage = 3
if command_line . pack :
2012-10-25 15:26:22 +04:00
pack_project ( path )
2012-09-19 13:38:52 +04:00
cmd = [ ' git ' , ' reset ' ]
2012-10-25 15:26:22 +04:00
execute_command ( cmd , 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-10-25 15:26:22 +04:00
execute_command ( cmd , 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
# get project
2012-10-25 15:26:22 +04:00
proj = get_project ( models , must_exist = True , name = command_line . project )
if not command_line . project and not command_line . skip_spec_check : # local git repository
find_spec_problems ( )
2012-10-10 18:16:22 +04:00
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 = [ ]
2012-10-25 15:26:22 +04:00
all_arches = Arch . get_arches ( models )
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 :
2012-10-25 15:26:22 +04:00
2012-10-12 15:03:56 +04:00
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 )
# 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-25 15:26:22 +04:00
build_platforms = Platform . get_build_platforms ( models )
2012-10-10 18:16:22 +04:00
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-25 18:26:51 +04:00
build_ids = BuildList . new_build_task ( models , proj , save_to_repository , build_repositories , commit_hash ,
2012-10-11 18:13:59 +04:00
command_line . update_type or BuildList . update_types [ 0 ] , command_line . auto_publish , arches )
2012-10-25 18:26:51 +04:00
ids = ' , ' . join ( [ str ( i ) for i in build_ids ] )
projects_cfg [ ' main ' ] [ ' last_build_ids ' ] = ids
projects_cfg [ str ( proj ) ] [ ' last_build_ids ' ] = ids
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
for task_id in command_line . task_ids :
try :
2012-10-25 15:26:22 +04:00
bl = BuildList ( models , task_id )
2012-10-12 15:03:56 +04:00
if bl . status != 0 :
2012-10-25 15:26:22 +04:00
log . error ( " The status of build task %s is \" %s \" , can not publish it! " % ( bl . id , bl . status_string ) )
2012-10-12 15:03:56 +04:00
continue
2012-10-25 15:26:22 +04:00
res = bl . publish ( )
2012-10-12 15:03:56 +04:00
except AbfApiException , ex :
log . error ( ' Could not publish task %s : %s ' % ( task_id , str ( ex ) ) )
2012-10-11 18:13:59 +04:00
2012-10-25 18:26:51 +04:00
def _print_build_status ( models , ID ) :
2012-10-10 18:16:22 +04:00
try :
2012-10-25 18:26:51 +04:00
bl = BuildList ( models , ID )
2012-10-11 18:13:59 +04:00
except AbfApiException , ex :
2012-10-26 12:14:30 +04:00
log . error ( " Can not read buildlist %s : %s " % ( ID , ex ) )
2012-10-10 18:16:22 +04:00
exit ( 3 )
2012-10-25 18:26:51 +04:00
if command_line . short :
print repr ( bl )
else :
print ' %-20s %s ' % ( ' Buildlist ID: ' , bl . id )
print ' %-20s %s ' % ( ' Owner: ' , bl . owner . uname )
print ' %-20s %s ' % ( ' Project: ' , bl . project . fullname )
print ' %-20s %s ' % ( ' Status: ' , bl . status_string )
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: ' , bl . created_at )
print ' %-20s %s ' % ( ' Updated at: ' , bl . updated_at )
print ' '
def buildstatus ( ) :
log . debug ( ' BUILDSTATUS started ' )
ids = [ ]
if command_line . ID :
ids = command_line . ID
res = get_project_name_only ( must_exist = False , name = command_line . project )
if res :
proj = ' %s / %s ' % res
ids + = projects_cfg [ proj ] [ ' last_build_ids ' ] . split ( ' , ' )
elif not command_line . ID :
if ' main ' not in projects_cfg or ' last_build_ids ' not in projects_cfg [ ' main ' ] :
log . error ( " Can not find last build IDs. Specify a project name or ID " )
exit ( 1 )
ids + = projects_cfg [ ' main ' ] [ ' last_build_ids ' ] . split ( ' , ' )
ids = list ( set ( ids ) )
for i in ids :
2012-11-21 18:36:07 +04:00
try :
i = int ( i )
except :
log . error ( ' " %s " is not a number ' % i )
continue
2012-10-25 18:26:51 +04:00
_print_build_status ( models , i )
2012-10-25 15:26:22 +04:00
2012-10-26 12:14:30 +04:00
def _update_location ( path = None , silent = True ) :
2012-10-25 15:26:22 +04:00
try :
if not path :
path = os . getcwd ( )
log . debug ( " Updating project location for %s " % path )
group , name = get_project_name ( path )
if group :
proj = ' %s / %s ' % ( group , name )
projects_cfg [ proj ] [ ' location ' ] = path
2012-10-26 12:14:30 +04:00
text = " Project %s has been located in %s " % ( proj , path )
if silent :
log . debug ( text )
else :
log . info ( text )
2012-10-25 15:26:22 +04:00
except :
pass
def _update_location_recursive ( path ) :
items = os . listdir ( path )
if ' .git ' in items : # it's a git directory!
2012-10-26 12:14:30 +04:00
_update_location ( path , silent = False )
2012-10-25 15:26:22 +04:00
return
for item in items :
item_path = os . path . join ( path , item )
if not os . path . isdir ( item_path ) or os . path . islink ( item_path ) :
continue
_update_location_recursive ( item_path )
def locate ( ) :
log . debug ( ' LOCATE started ' )
if not command_line . action : # show location
if not command_line . project :
print " To show a project location, you have to specify a project name ( ' -p ' option) "
return
tmp = command_line . project . split ( ' / ' )
if len ( tmp ) > 2 :
log . error ( ' error: the project format is " [owner_name/]project_name " ' )
exit ( 1 )
elif len ( tmp ) == 1 :
proj = ' %s / %s ' % ( default_group , tmp [ 0 ] )
else : # len == 2
proj = command_line . project
if proj not in projects_cfg or ' location ' not in projects_cfg [ proj ] or not projects_cfg [ proj ] [ ' location ' ] :
print ' error: project %s can not be located ' % proj
exit ( 1 )
path = projects_cfg [ proj ] [ ' location ' ]
if not os . path . isdir ( path ) :
print ' error: project is not located in " %s " anymore ' % path
projects_cfg [ proj ] [ ' location ' ] = ' '
exit ( 1 )
print path
return
else :
if command_line . action == ' update ' :
path = command_line . directory or os . getcwd ( )
_update_location ( path )
elif command_line . action == ' update-recursive ' :
path = command_line . directory or os . getcwd ( )
_update_location_recursive ( path )
def show ( ) :
log . debug ( ' SHOW started ' )
Log . set_silent ( )
t = command_line . type
if t in [ ' build-platforms ' , ' build-repos ' ] :
build_platforms = Platform . get_build_platforms ( models )
platform_names = [ ]
repo_names = [ ]
for plat in build_platforms :
if plat . repositories :
platform_names . append ( plat . name )
for repo in plat . repositories :
repo_names . append ( str ( repo ) )
out = ( t == ' build-platforms ' and platform_names ) or ( t == ' build-repos ' and repo_names )
if t in [ ' save-to-platforms ' , ' save-to-repos ' ] :
proj = get_project ( models , must_exist = True , name = command_line . project )
repos = proj . repositories
platform_names = [ ]
repo_names = [ ]
for repo in repos :
platform_names . append ( repo . platform . name )
repo_names . append ( str ( repo ) )
platform_names = list ( set ( platform_names ) )
out = ( t == ' save-to-platforms ' and platform_names ) or ( t == ' save-to-repos ' and repo_names )
print ' ' . join ( out )
def clean ( ) :
log . debug ( " CLEAN started " )
_update_location ( )
find_spec_problems ( auto_remove = command_line . auto_remove )
2012-09-18 13:26:44 +04:00
if __name__ == ' __main__ ' :
parse_command_line ( )
2012-10-25 15:26:22 +04:00
2012-09-18 13:26:44 +04:00
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 ( )