Hello community, here is the log from the commit of package osc for openSUSE:Factory checked in at 2017-03-12 20:03:54 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/osc (Old) and /work/SRC/openSUSE:Factory/.osc.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "osc" Sun Mar 12 20:03:54 2017 rev:117 rq:477742 version:0.157.1 Changes: -------- --- /work/SRC/openSUSE:Factory/osc/osc.changes 2016-12-29 22:44:28.479330863 +0100 +++ /work/SRC/openSUSE:Factory/.osc.new/osc.changes 2017-03-12 20:03:55.414405854 +0100 @@ -1,0 +2,23 @@ +Wed Mar 8 12:14:32 UTC 2017 - [email protected] + +- 0.157.1 + - fix local build of kiwi images using obsrepositories:// + +------------------------------------------------------------------- +Wed Mar 8 08:57:31 UTC 2017 - [email protected] + +- 0.157 + - add unpublish command (requires OBS 2.8) + - add blame command (requires OBS 2.9) + - results: show multibuild results by default + - getbinaries: make .AppImage files executable + - support operation in checked out package for cat/less/blame + - add comment command + - improved build recipe selection + - added multibuild (-M) to commands: + buildlog, remotebuildlog, buildinfo, build, buildhistory, jobhistory, + rebuild, restartbuild/abortbuild, wipebinaries, getbinaries + - add checkconstraints command + - add workerinfo command + +------------------------------------------------------------------- Old: ---- osc-0.156.0.tar.gz New: ---- osc-0.157.1.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ osc.spec ++++++ --- /var/tmp/diff_new_pack.nweu3z/_old 2017-03-12 20:03:56.254287010 +0100 +++ /var/tmp/diff_new_pack.nweu3z/_new 2017-03-12 20:03:56.262285878 +0100 @@ -1,7 +1,7 @@ # # spec file for package osc # -# Copyright (c) 2016 SUSE LINUX GmbH, Nuernberg, Germany. +# Copyright (c) 2017 SUSE LINUX GmbH, Nuernberg, Germany. # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -16,10 +16,10 @@ # -%define version_unconverted 0.156.0 +%define version_unconverted 0.157.1 Name: osc -Version: 0.156.0 +Version: 0.157.1 Release: 0 Summary: Open Build Service Commander License: GPL-2.0+ ++++++ PKGBUILD ++++++ --- /var/tmp/diff_new_pack.nweu3z/_old 2017-03-12 20:03:56.302280219 +0100 +++ /var/tmp/diff_new_pack.nweu3z/_new 2017-03-12 20:03:56.302280219 +0100 @@ -1,5 +1,5 @@ pkgname=osc -pkgver=0.156.0 +pkgver=0.157.1 pkgrel=0 pkgdesc="Open Build Service client" arch=('i686' 'x86_64') ++++++ _service ++++++ --- /var/tmp/diff_new_pack.nweu3z/_old 2017-03-12 20:03:56.326276823 +0100 +++ /var/tmp/diff_new_pack.nweu3z/_new 2017-03-12 20:03:56.330276257 +0100 @@ -1,7 +1,7 @@ <services> <service name="tar_scm" mode="disabled"> - <param name="version">0.156.0</param> - <param name="revision">0.156.0</param> + <param name="version">0.157.1</param> + <param name="revision">0.157.1</param> <param name="url">git://github.com/openSUSE/osc.git</param> <param name="scm">git</param> </service> ++++++ debian.changelog ++++++ --- /var/tmp/diff_new_pack.nweu3z/_old 2017-03-12 20:03:56.362271730 +0100 +++ /var/tmp/diff_new_pack.nweu3z/_new 2017-03-12 20:03:56.374270032 +0100 @@ -1,4 +1,4 @@ -osc (0.156.0) unstable; urgency=low +osc (0.157.1) unstable; urgency=low - Install bash completion -- Nick Brown <[email protected]> Wed, 26 Oct 2016 10:00:00 +0200 ++++++ osc-0.156.0.tar.gz -> osc-0.157.1.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/osc-0.156.0/NEWS new/osc-0.157.1/NEWS --- old/osc-0.156.0/NEWS 2016-12-19 14:47:45.000000000 +0100 +++ new/osc-0.157.1/NEWS 2017-03-08 13:10:35.000000000 +0100 @@ -1,3 +1,21 @@ +0.158 + - + +0.157 + - add unpublish command (requires OBS 2.8) + - add blame command (requires OBS 2.9) + - results: show multibuild results by default + - getbinaries: make .AppImage files executable + - support operation in checked out package for cat/less/blame + - add comment command + - improved build recipe selection + - added multibuild (-M) to commands: + buildlog, remotebuildlog, buildinfo, build, buildhistory, jobhistory, + rebuild, restartbuild/abortbuild, wipebinaries, getbinaries + - add checkconstraints command + - add workerinfo command + - fix local build of kiwi images using obsrepositories:// + 0.156 - highlight scheduled jobs with dispatch problems (due to constraints) - allow to specify a log message in lock command diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/osc-0.156.0/dist/osc.complete new/osc-0.157.1/dist/osc.complete --- old/osc-0.156.0/dist/osc.complete 2016-12-19 14:47:45.000000000 +0100 +++ new/osc-0.157.1/dist/osc.complete 2017-03-08 13:10:35.000000000 +0100 @@ -59,8 +59,8 @@ --debug --apiurl -A --config -c --no-keyring --no-gnome-keyring --verbose --quiet) osccmds=(abortbuild add addremove aggregatepac api ar bco bl blt branch branchco bsdevelproject bse bugowner build buildconfig buildhist buildhistory buildinfo - buildlog buildlogtail cat changedevelreq changedevelrequest checkin checkout - chroot ci co commit config copypac cr createincident createrequest creq del + buildlog buildlogtail cat changedevelreq changedevelrequest checkconstraints checkin checkout + chroot ci co comment commit config copypac cr createincident createrequest creq del delete deletereq deleterequest dependson detachbranch develproject di diff distributions dists dr dropreq droprequest getbinaries getpac help importsrcpkg info init jobhist jobhistory lbl ldiff less linkdiff linkpac linktobranch list @@ -73,11 +73,13 @@ resolved results revert review rm rq rremove se search service setlinkrev signkey sm sr st status submitpac submitreq submitrequest tr triggerreason undelete unlock up update updatepacmetafromspec user vc whatdependson who whois - wipebinaries) + wipebinaries workerinfo) oscreq=(list log show accept decline revoke reopen setincident supersede approvenew checkout clone) oscrev=(show list add accept decline reopen supersede) oscmy=(work pkg prj rq sr) +osccmt=(list create delete) +osccmtkind=(package project request) oscprj="" oscpkg="" @@ -1095,6 +1097,16 @@ builtin compgen -W "${opts[*]}" -- "${cmdline[3]}" fi ;; +comment) + opts=(--comment --parent) + if ((count == 1)) ; then + builtin compgen -W "${osccmds[*]}" -- "${cmdline[count]}" + elif ((count == 2)) ; then + builtin compgen -W "${opts[*]} ${osccmt[*]}" -- "${cmdline[2]}" + elif ((count == 3)) ; then + builtin compgen -W "${opts[*]} ${osccmtkind[*]}" -- "${cmdline[3]}" + fi + ;; copypac|linkpac) opts=(--help --expand --to-apiurl --revision --keep-develproject --keep-link --keep-maintainers --client-side-copy) @@ -1396,7 +1408,7 @@ opts=(--help --role --delete --set-bugowner-request --set-bugowner --all --add --devel-project --verbose --nodevelproject --email --bugowner --bugowner-only) if ((count == 1)) ; then - builtin compgen -W "${osccmds[*]}" -- "${cmdline[count]}" + builtin compgen -W "${osccmds[*]}" -- "${cmdline[count]}" elif ((count >= 2)) ; then for ((off=2; off<=count; off++)) ; do while test "${cmdline[off+remove]::1}" = "-" ; do @@ -1812,6 +1824,30 @@ builtin compgen -W "${opts[*]}" -- "${cmdline[count]}" fi ;; +workerinfo) + opts=(--help) + if ((count == 1)) ; then + builtin compgen -W "${osccmds[*]} ${oscopts[*]}" -- "${cmdline[count]}" + elif ((count >= 2)) ; then + if test "${cmdline[count]::1}" = "-" ; then + builtin compgen -W "${opts[*]}" -- "${cmdline[count]}" + else + targets ${opts[*]} -- "${cmdline[count]}" + fi + fi + ;; +checkconstraints) + opts=(--help --ignore-file) + if ((count == 1)) ; then + builtin compgen -W "${osccmds[*]} ${oscopts[*]}" -- "${cmdline[count]}" + elif ((count >= 2)) ; then + if test "${cmdline[count]::1}" = "-" ; then + builtin compgen -W "${opts[*]}" -- "${cmdline[count]}" + else + targets ${opts[*]} -- "${cmdline[count]}" + fi + fi + ;; *) opts=(--help) if ((count == 1)) ; then @@ -1822,5 +1858,5 @@ else targets ${opts[*]} -- "${cmdline[count]}" fi - fi + fi esac diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/osc-0.156.0/osc/babysitter.py new/osc-0.157.1/osc/babysitter.py --- old/osc-0.156.0/osc/babysitter.py 2016-12-19 14:47:45.000000000 +0100 +++ new/osc-0.157.1/osc/babysitter.py 2017-03-08 13:10:35.000000000 +0100 @@ -143,7 +143,7 @@ print('Failed to reach a server:\n', e.reason, file=sys.stderr) return 1 except URLGrabError as e: - print('Failed to grab %s: %s' % (e.url, e.exception), file=sys.stderr) + print('Failed to grab %s: %s' % (e.url, e.strerror), file=sys.stderr) return 1 except IOError as e: # ignore broken pipe diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/osc-0.156.0/osc/build.py new/osc-0.157.1/osc/build.py --- old/osc-0.156.0/osc/build.py 2016-12-19 14:47:45.000000000 +0100 +++ new/osc-0.157.1/osc/build.py 2017-03-08 13:10:35.000000000 +0100 @@ -1009,7 +1009,7 @@ buildargs.append('--kiwi-parameter') buildargs.append('--add-repo') buildargs.append('--kiwi-parameter') - buildargs.append("repos/"+path) + buildargs.append("dir://./repos/"+path) buildargs.append('--kiwi-parameter') buildargs.append('--add-repotype') buildargs.append('--kiwi-parameter') @@ -1027,7 +1027,7 @@ buildargs.append('--kiwi-parameter') buildargs.append('--add-repo') buildargs.append('--kiwi-parameter') - buildargs.append("repos/"+project+"/"+repo) + buildargs.append("dir://./repos/"+project+"/"+repo) buildargs.append('--kiwi-parameter') buildargs.append('--add-repotype') buildargs.append('--kiwi-parameter') diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/osc-0.156.0/osc/commandline.py new/osc-0.157.1/osc/commandline.py --- old/osc-0.156.0/osc/commandline.py 2016-12-19 14:47:45.000000000 +0100 +++ new/osc-0.157.1/osc/commandline.py 2017-03-08 13:10:35.000000000 +0100 @@ -441,6 +441,7 @@ opts.expand = True if fname and print_not_found: print('file \'%s\' does not exist' % fname) + return 1 @cmdln.option('-s', '--skip-disabled', action='store_true', @@ -724,6 +725,8 @@ fd = urlopen(req, data=None) print(fd.read()) else: + if args and args[0] in ['create', 'delete', 'trigger']: + raise oscerr.WrongArgs("Did you mean --" + args[0] + "?") # just list token for data in streamfile(url, http_GET): sys.stdout.write(data) @@ -1078,6 +1081,20 @@ ${cmd_option_list} """ + def _check_service(root): + serviceinfo = root.find('serviceinfo') + if serviceinfo is not None: + # code "running" is ok, because the api will choke when trying + # to create the sr (if it is still running) + if serviceinfo.get('code') not in ('running', 'succeeded'): + print('A service run for package %s %s:' + % (root.get('name'), serviceinfo.get('code')), + file=sys.stderr) + error = serviceinfo.find('error') + if error is not None: + print('\n'.join(error.text.split('\\n'))) + sys.exit('\nPlease fix this first') + if opts.cleanup and opts.no_cleanup: raise oscerr.WrongOptions('\'--cleanup\' and \'--no-cleanup\' are mutually exclusive') @@ -1176,14 +1193,8 @@ print("Skipping package ", p, " since it is a source link pointing inside the project.") continue - serviceinfo = root.find('serviceinfo') - if serviceinfo != None: - if serviceinfo.get('code') != "succeeded": - print("Package ", p, " has a ", serviceinfo.get('code'), " source service") - sys.exit("Please fix this first") - if serviceinfo.get('error'): - print("Package ", p, " contains a failed source service.") - sys.exit("Please fix this first") + # check for failed source service + _check_service(root) # submitting this package if opts.separate_requests or opts.seperate_requests: @@ -1269,18 +1280,11 @@ raise oscerr.WrongArgs('Incorrect number of arguments.\n\n' \ + self.get_cmd_help('request')) - # check for running source service + # check for failed source service u = makeurl(apiurl, ['source', src_project, src_package]) f = http_GET(u) root = ET.parse(f).getroot() - serviceinfo = root.find('serviceinfo') - if serviceinfo != None: - if serviceinfo.get('code') != "succeeded": - print("Package ", src_package, " has a ", serviceinfo.get('code'), " source service") - sys.exit("Please fix this first") - if serviceinfo.get('error'): - print("Package ", src_package, " contains a failed source service.") - sys.exit("Please fix this first") + _check_service(root) if not opts.nodevelproject: devloc = None @@ -1332,7 +1336,7 @@ return supersede_existing = False reqs = [] - if not opts.supersede: + if not opts.supersede and not opts.yes: (supersede_existing, reqs) = check_existing_requests(apiurl, src_project, src_package, @@ -2944,7 +2948,7 @@ def do_releaserequest(self, subcmd, opts, *args): """${cmd_name}: Create a request for releasing a maintenance update. - [See http://doc.opensuse.org/products/draft/OBS/obs-reference-guide_draft/cha.obs.maintenance_setup.html + [See http://openbuildservice.org/help/manuals/obs-reference-guide/cha.obs.maintenance_setup.html for information on this topic.] This command is used by the maintence team to start the release process of a maintenance update. @@ -2990,7 +2994,7 @@ def do_createincident(self, subcmd, opts, *args): """${cmd_name}: Create a maintenance incident - [See http://doc.opensuse.org/products/draft/OBS/obs-reference-guide_draft/cha.obs.maintenance_setup.html + [See http://openbuildservice.org/help/manuals/obs-reference-guide/cha.obs.maintenance_setup.html for information on this topic.] This command is asking to open an empty maintence incident. This can usually only be done by a responsible @@ -3062,7 +3066,7 @@ def do_maintenancerequest(self, subcmd, opts, *args): """${cmd_name}: Create a request for starting a maintenance incident. - [See http://doc.opensuse.org/products/draft/OBS/obs-reference-guide_draft/cha.obs.maintenance_setup.html + [See http://openbuildservice.org/help/manuals/obs-reference-guide/cha.obs.maintenance_setup.html for information on this topic.] This command is asking the maintence team to start a maintence incident based on a @@ -4185,10 +4189,10 @@ @cmdln.option('-M', '--meta', action='store_true', help='checkout out meta data instead of sources' ) @cmdln.option('-c', '--current-dir', action='store_true', - help='place PACKAGE folder in the current directory' \ + help='place PACKAGE folder in the current directory ' \ 'instead of a PROJECT/PACKAGE directory') @cmdln.option('-o', '--output-dir', metavar='outdir', - help='place package in the specified directory' \ + help='place package in the specified directory ' \ 'instead of a PROJECT/PACKAGE directory') @cmdln.option('-s', '--source-service-files', action='store_true', help='Run source services.' ) @@ -4977,8 +4981,8 @@ help='Show results only for specified architecture(s)') @cmdln.option('-v', '--verbose', action='store_true', default=False, help='more verbose output') - @cmdln.option('-m', '--multibuild', action='store_true', default=False, - help='Show results for all packages in multibuild') + @cmdln.option('--no-multibuild', action='store_true', default=False, + help='Disable results for all direct affect packages inside of the project') @cmdln.option('-M', '--multibuild-package', action='append', default=[], help='Only show results for the specified multibuild package') @cmdln.option('-w', '--watch', action='store_true', default=False, @@ -5040,16 +5044,17 @@ 'lastbuild': opts.last_build, 'repository': opts.repo, 'arch': opts.arch, 'wait': opts.watch} if opts.multibuild_package: - opts.multibuild = True + opts.no_multibuild = False kwargs['multibuild_packages'] = opts.multibuild_package - kwargs['multibuild'] = kwargs['locallink'] = opts.multibuild + if not opts.no_multibuild: + kwargs['multibuild'] = kwargs['locallink'] = True if opts.xml or opts.csv: for xml in get_package_results(**kwargs): if opts.xml: print(xml, end='') else: # csv formatting - results = result_xml_to_dicts(xml) + results = [r for r, _ in result_xml_to_dicts(xml)] print('\n'.join(format_results(results, opts.format))) else: kwargs['verbose'] = opts.verbose @@ -5137,6 +5142,8 @@ @cmdln.alias('buildlogtail') @cmdln.option('-l', '--last', action='store_true', help='Show the last finished log file') + @cmdln.option('-M', '--multibuild-package', metavar='MPAC', + help='get log of the specified multibuild package') @cmdln.option('-o', '--offset', metavar='OFFSET', help='get log start or end from the offset') @cmdln.option('-s', '--strip-time', action='store_true', @@ -5184,6 +5191,9 @@ repository = args[0] arch = args[1] + if opts.multibuild_package: + package = package + ":" + opts.multibuild_package + offset = 0 if subcmd == "blt" or subcmd == "buildlogtail": query = { 'view': 'entry' } @@ -5231,6 +5241,8 @@ @cmdln.alias('remotebuildlogtail') @cmdln.option('-l', '--last', action='store_true', help='Show the last finished log file') + @cmdln.option('-M', '--multibuild-package', metavar='MPAC', + help='show log file for specified multibuild package') @cmdln.option('-o', '--offset', metavar='OFFSET', help='get log starting or ending from the offset') @cmdln.option('-s', '--strip-time', action='store_true', @@ -5263,6 +5275,9 @@ else: project, package, repository, arch = args + if opts.multibuild_package: + package = package + ":" + opts.multibuild_package + offset = 0 if subcmd == "rblt" or subcmd == "rbuildlogtail" or subcmd == "remotebuildlogtail": query = { 'view': 'entry' } @@ -5491,6 +5506,8 @@ @cmdln.option('-d', '--debug', action='store_true', help='verbose output of build dependencies') + @cmdln.option('-M', '--multibuild-package', metavar='MPAC', + help='Show the buildinfo of the specified multibuild package') @cmdln.option('-x', '--extra-pkgs', metavar='PAC', action='append', help='Add this package when computing the buildinfo') @cmdln.option('-p', '--prefer-pkgs', metavar='DIR', action='append', @@ -5538,7 +5555,7 @@ raise oscerr.WrongArgs('Incorrect number of arguments (Note: \'.\' is no package wc)') project = store_read_project('.') package = store_read_package('.') - repository, arch, build_descr = self.parse_repoarchdescr(args, ignore_descr=True) + repository, arch, build_descr = self.parse_repoarchdescr(args, ignore_descr=True, multibuild_package=opts.multibuild_package) elif len(args) == 4 or len(args) == 5: project = args[0] package = args[1] @@ -5567,6 +5584,9 @@ cpiodata.add(os.path.basename(build_descr), build_descr_data) build_descr_data = cpiodata.get() + if opts.multibuild_package: + package = package + ":" + opts.multibuild_package + print(''.join(get_buildinfo(apiurl, project, package, repository, arch, specfile=build_descr_data, @@ -5617,6 +5637,74 @@ print(''.join(get_buildconfig(apiurl, project, repository))) + def do_workerinfo(self, subcmd, opts, worker): + """${cmd_name}: gets the information to a worker from the server + + Examples: + osc workerinfo <workername> + + ${cmd_usage} + ${cmd_option_list} + """ + apiurl = self.get_api_url() + print(''.join(get_worker_info(apiurl, worker))) + + + @cmdln.option('', '--ignore-file', action='store_true', + help='ignore _constraints file and only check project constraints') + def do_checkconstraints(self, subcmd, opts, *args): + """${cmd_name}: check the constraints and view compliant workers + + Checks the constraints for compliant workers. + + usage: + in a package working copy: + osc checkconstraints [OPTS] REPOSITORY ARCH CONSTRAINTSFILE + osc checkconstraints [OPTS] CONSTRAINTSFILE + osc checkconstraints [OPTS] + + ${cmd_option_list} + """ + repository = arch = constraintsfile = None + project = store_read_project('.') + package = store_read_package('.') + if len(args) == 1: + constraintsfile = args[0] + elif len(args) == 2 or len(args) == 3: + repository = args[0] + arch = args[1] + if len(args) == 3: + constraintsfile = args[2] + + constraintsfile_data = None + if constraintsfile is not None: + constraintsfile_data = open(constraintsfile, 'r').read() + elif not opts.ignore_file: + if os.path.isfile("_constraints"): + constraintsfile_data = open("_constraints", 'r').read() + else: + print("No local _constraints file. Using just the project constraints") + + apiurl = self.get_api_url() + r = [] + if not arch and not repository: + result_line_templ = '%(name)-25s %(arch)-25s %(comp_workers)s' + for repo in get_repos_of_project(apiurl, project): + rmap = {} + rmap['name'] = repo.name + rmap['arch'] = repo.arch + workers = check_constraints(apiurl, project, repo.name, repo.arch, package, constraintsfile_data) + rmap['comp_workers'] = len(workers) + r.append(result_line_templ % rmap) + r.insert(0, 'Repository Arch Worker') + r.insert(1, '---------- ---- ------') + else: + r = check_constraints(apiurl, project, repository, arch, package, constraintsfile_data) + r.insert(0, 'Worker') + r.insert(1, '------') + + print('\n'.join(r)) + @cmdln.alias('repos') @cmdln.alias('platforms') def do_repositories(self, subcmd, opts, *args): @@ -5669,10 +5757,11 @@ print(row) - def parse_repoarchdescr(self, args, noinit = False, alternative_project = None, ignore_descr = False, vm_type = None): + def parse_repoarchdescr(self, args, noinit = False, alternative_project = None, ignore_descr = False, vm_type = None, multibuild_package = None): """helper to parse the repo, arch and build description from args""" import osc.build import glob + import tempfile arg_arch = arg_repository = arg_descr = None if len(args) < 3: # some magic, works only sometimes, but people seem to like it :/ @@ -5717,15 +5806,18 @@ # only persist our own repos Repo.tofile(repolistfile, repositories) + no_repo = False repo_names = sorted(set([r.name for r in repositories])) if not arg_repository and repositories: # XXX: we should avoid hardcoding repository names # Use a default value from config, but just even if it's available # unless try standard, or openSUSE_Factory, or openSUSE_Tumbleweed + no_repo = True arg_repository = repositories[-1].name for repository in (conf.config['build_repository'], 'standard', 'openSUSE_Factory', 'openSUSE_Tumbleweed'): if repository in repo_names: arg_repository = repository + no_repo = False break if not arg_repository: @@ -5749,22 +5841,39 @@ elif not arg_descr: msg = None if len(descr) > 1: - # guess/prefer build descrs like the following: - # <pac>-<repo>.<ext> > <pac>.<ext> - # no guessing for arch's PKGBUILD files (the backend does not do any guessing, too) + if no_repo: + raise oscerr.WrongArgs("Repository is missing. Cannot guess build description without repository") + apiurl = self.get_api_url() + project = store_read_project('.') + bc = get_buildconfig(apiurl, project, arg_repository) + with tempfile.NamedTemporaryFile() as f: + f.write(bc) + f.flush() + recipe = return_external('/usr/lib/build/queryconfig', '--dist', f.name, 'type') + recipe = recipe.strip() + if recipe == 'arch': + recipe = 'PKGBUILD' pac = os.path.basename(os.getcwd()) if is_package_dir(os.getcwd()): pac = store_read_package(os.getcwd()) - extensions = ['spec', 'dsc', 'kiwi', 'livebuild'] - cands = [i for i in descr for ext in extensions if i == '%s-%s.%s' % (pac, arg_repository, ext)] + if multibuild_package: + pac = multibuild_package + if recipe == 'PKGBUILD': + cands = [d for d in descr if d.startswith(recipe)] + else: + cands = [d for d in descr if d.endswith('.' + recipe)] + if len(cands) > 1: + repo_cands = [d for d in cands if d == '%s-%s.%s' % (pac, arg_repository, recipe)] + if repo_cands: + cands = repo_cands + else: + pac_cands = [d for d in cands if d == '%s.%s' % (pac, recipe)] + if pac_cands: + cands = pac_cands if len(cands) == 1: arg_descr = cands[0] - else: - cands = [i for i in descr for ext in extensions if i == '%s.%s' % (pac, ext)] - if len(cands) == 1: - arg_descr = cands[0] if not arg_descr: - msg = 'Multiple build description files found: %s' % ', '.join(descr) + msg = 'Multiple build description files found: %s' % ', '.join(cands) elif not ignore_descr: msg = 'Missing argument: build description (spec, dsc, kiwi or livebuild file)' try: @@ -5805,6 +5914,8 @@ help='Prefer packages from this directory when installing the build-root') @cmdln.option('-k', '--keep-pkgs', metavar='DIR', help='Save built packages into this directory') + @cmdln.option('-M', '--multibuild-package', metavar='MPAC', + help='Build the specified multibuild package') @cmdln.option('-x', '--extra-pkgs', metavar='PAC', action='append', help='Add this package when installing the build-root') @cmdln.option('--root', metavar='ROOT', @@ -5923,7 +6034,7 @@ if len(args) > 3: raise oscerr.WrongArgs('Too many arguments') - args = self.parse_repoarchdescr(args, opts.noinit or opts.offline, opts.alternative_project, False, opts.vm_type) + args = self.parse_repoarchdescr(args, opts.noinit or opts.offline, opts.alternative_project, False, opts.vm_type, opts.multibuild_package) # check for source services r = None @@ -6201,6 +6312,8 @@ help='generate output in CSV (separated by |)') @cmdln.option('-l', '--limit', metavar='limit', help='for setting the number of results') + @cmdln.option('-M', '--multibuild-package', metavar= 'MPAC', + help='Show the buildhistory of the specified multibuild package') @cmdln.alias('buildhist') def do_buildhistory(self, subcmd, opts, *args): """${cmd_name}: Shows the build history of a package @@ -6235,6 +6348,9 @@ else: raise oscerr.WrongArgs('Wrong number of arguments') + if opts.multibuild_package: + package = package + ":" + opts.multibuild_package + format = 'text' if opts.csv: format = 'csv' @@ -6245,6 +6361,8 @@ help='generate output in CSV (separated by |)') @cmdln.option('-l', '--limit', metavar='limit', help='for setting the number of results') + @cmdln.option('-M', '--multibuild-package', metavar='MPAC', + help='get jobhistory for the specified multibuild package') @cmdln.alias('jobhist') def do_jobhistory(self, subcmd, opts, *args): """${cmd_name}: Shows the job history of a project @@ -6287,6 +6405,9 @@ else: raise oscerr.WrongArgs('Wrong number of arguments') + if opts.multibuild_package and package is not None: + package = package + ":" + opts.multibuild_package + format = 'text' if opts.csv: format = 'csv' @@ -6449,6 +6570,8 @@ help='trigger rebuilds for a specific repository') @cmdln.option('-f', '--failed', action='store_true', help='rebuild all failed packages') + @cmdln.option('-M', '--multibuild-package', action='append', + help='rebuild specified multibuild package') @cmdln.option('--all', action='store_true', help='Rebuild all packages of entire project') @cmdln.alias('rebuildpac') @@ -6505,7 +6628,15 @@ if not (opts.all or package or repo or arch or code): raise oscerr.WrongOptions('No option has been provided. If you want to rebuild all packages of the entire project, use --all option.') - print(rebuild(apiurl, project, package, repo, arch, code)) + packages = [] + if opts.multibuild_package: + for subpackage in opts.multibuild_package: + packages.append(package + ":" + subpackage) + else: + packages.append(package) + + for package in packages: + print(rebuild(apiurl, project, package, repo, arch, code)) def do_info(self, subcmd, opts, *args): @@ -6527,6 +6658,8 @@ @cmdln.option('-a', '--arch', metavar='ARCH', help='Restart builds for a specific architecture') + @cmdln.option('-M', '--multibuild-package', action='append', + help='Restart builds for specified multibuild package') @cmdln.option('-r', '--repo', metavar='REPO', help='Restart builds for a specific repository') @cmdln.option('--all', action='store_true', @@ -6573,11 +6706,21 @@ if not (opts.all or package or repo or arch): raise oscerr.WrongOptions('No option has been provided. If you want to restart all packages of the entire project, use --all option.') - print(cmdbuild(apiurl, subcmd, project, package, arch, repo)) + packages = [] + if opts.multibuild_package: + for subpackage in opts.multibuild_package: + packages.append(package + ":" + subpackage) + else: + packages.append(package) + + for package in packages: + print(cmdbuild(apiurl, subcmd, project, package, arch, repo)) @cmdln.option('-a', '--arch', metavar='ARCH', help='Delete all binary packages for a specific architecture') + @cmdln.option('-M', '--multibuild-package', action='append', + help='Delete all binary packages for specified multibuild package') @cmdln.option('-r', '--repo', metavar='REPO', help='Delete all binary packages for a specific repository') @cmdln.option('--build-disabled', action='store_true', @@ -6590,6 +6733,7 @@ help='Delete all binaries of packages which have dependency errors') @cmdln.option('--all', action='store_true', help='Delete all binaries regardless of the package status (previously default)') + @cmdln.alias("unpublish") def do_wipebinaries(self, subcmd, opts, *args): """${cmd_name}: Delete all binary packages of a certain project/package @@ -6599,6 +6743,8 @@ usage: osc wipebinaries OPTS # works in checked out project dir osc wipebinaries OPTS PROJECT [PACKAGE] + osc unpublish OPTS # works in checked out project dir + osc unpublish OPTS PROJECT [PACKAGE] ${cmd_option_list} """ @@ -6641,15 +6787,28 @@ if len(codes) == 0: raise oscerr.WrongOptions('No option has been provided. If you want to delete all binaries, use --all option.') - # make a new request for each code= parameter - for code in codes: - print(wipebinaries(apiurl, project, package, opts.arch, opts.repo, code)) + packages = [] + if opts.multibuild_package: + for subpackage in opts.multibuild_package: + packages.append(package + ":" + subpackage) + else: + packages.append(package) + + # make a new request for each code= parameter and for each package in packages + for package in packages: + for code in codes: + if subcmd == 'unpublish': + print(unpublish(apiurl, project, package, opts.arch, opts.repo, code)) + else: + print(wipebinaries(apiurl, project, package, opts.arch, opts.repo, code)) @cmdln.option('-q', '--quiet', action='store_true', help='do not show downloading progress') @cmdln.option('-d', '--destdir', default='./binaries', metavar='DIR', help='destination directory') + @cmdln.option('-M', '--multibuild-package', action='append', + help='get binaries from specified multibuild package') @cmdln.option('--sources', action="store_true", help='also fetch source packages') @cmdln.option('--debug', action="store_true", @@ -6713,10 +6872,17 @@ if architecture is None: arches = [i.arch for i in repos if repository == i.name] + if package is None: package = meta_get_packagelist(apiurl, project) else: - package = [package] + if opts.multibuild_package: + packages = [] + for subpackage in opts.multibuild_package: + packages.append(package + ":" + subpackage) + package = packages + else: + package = [package] # Set binary target directory and create if not existing target_dir = os.path.normpath(opts.destdir) @@ -7768,16 +7934,24 @@ help='always work with unexpanded packages.') @cmdln.option('-M', '--meta', action='store_true', help='list meta data files') + @cmdln.alias('blame') @cmdln.alias('less') def do_cat(self, subcmd, opts, *args): """${cmd_name}: Output the content of a file to standard output Examples: + osc cat file osc cat project package file osc cat project/package/file osc cat http://api.opensuse.org/build/.../_log osc cat http://api.opensuse.org/source/../_link + osc less file + osc less project package file + + osc blame file + osc blame project package file + ${cmd_usage} ${cmd_option_list} """ @@ -7790,22 +7964,32 @@ opts.file = None return self.do_api('list', opts, *args) - - args = slash_split(args) - if len(args) != 3: + project = package = filename = None + if len(args) == 3: + project = args[0] + package = args[1] + filename = args[2] + elif len(args) == 1 and is_package_dir(os.getcwd()): + project = store_read_project(os.curdir) + package = store_read_package(os.curdir) + filename = args[0] + else: raise oscerr.WrongArgs('Wrong number of arguments.') + rev, dummy = parseRevisionOption(opts.revision) apiurl = self.get_api_url() query = { } + if subcmd == 'blame': + query['view'] = "blame" if opts.meta: query['meta'] = 1 if opts.revision: query['rev'] = opts.revision if opts.expand: - query['rev'] = show_upstream_srcmd5(apiurl, args[0], args[1], expand=True, revision=opts.revision, meta=opts.meta) - u = makeurl(apiurl, ['source', args[0], args[1], args[2]], query=query) + query['rev'] = show_upstream_srcmd5(apiurl, project, package, expand=True, revision=opts.revision, meta=opts.meta) + u = makeurl(apiurl, ['source', project, package, filename], query=query) try: if subcmd == 'less': f = http_GET(u) @@ -7816,8 +8000,8 @@ except HTTPError as e: if e.code == 404 and not opts.expand and not opts.unexpand: print('expanding link...', file=sys.stderr) - query['rev'] = show_upstream_srcmd5(apiurl, args[0], args[1], expand=True, revision=opts.revision) - u = makeurl(apiurl, ['source', args[0], args[1], args[2]], query=query) + query['rev'] = show_upstream_srcmd5(apiurl, project, package, expand=True, revision=opts.revision) + u = makeurl(apiurl, ['source', project, package, filename], query=query) if subcmd == "less": f = http_GET(u) run_pager(''.join(f.readlines())) @@ -8571,6 +8755,73 @@ if not opts.dry_run: os.unlink(os.path.join(p.absdir, filename)) + @cmdln.option('-c', '--comment', + help='comment text', metavar='COMMENT') + @cmdln.option('-p', '--parent', + help='reply to comment with parent id', metavar='PARENT') + def do_comment(self, subcmd, opts, *args): + """${cmd_name}: List / create / delete comments + + On create: + If -p is given a reply to the ID is created. Otherwise + a toplevel comment is created. + If -c is not given the default editor will be opened and + you can type your comment + + usage: + osc comment list package PROJECT PACKAGE + osc comment list project PROJECT + osc comment list request REQUEST_ID + + osc comment create [-p PARENT_ID] [-c COMMENT] package PROJECT PACKAGE + osc comment create [-p PARENT_ID] [-c COMMENT] project PROJECT + osc comment create [-p PARENT_ID] [-c COMMENT] request REQUEST_ID + + osc comment delete ID + + """ + + comment = None + args = slash_split(args) + apiurl = self.get_api_url() + + if len(args) < 2: + raise oscerr.WrongArgs('Incorrect number of arguments.\n\n' \ + + self.get_cmd_help('comment')) + + cmds = ['list', 'create', 'delete'] + if args[0] not in cmds: + raise oscerr.WrongArgs('Unknown comment action %s. Choose one of %s.' \ + % (args[0], ', '.join(cmds))) + + comment_targets = ['package', 'project', 'request'] + if args[0] != 'delete' and args[1] not in comment_targets: + raise oscerr.WrongArgs('Unknown comment target %s. Choose one of %s.' \ + % (args[1], ', '.join(comment_targets))) + + if args[1] == 'package' and len(args) != 4: + raise oscerr.WrongArgs('Please use PROJECT PACKAGE') + elif args[1] == 'project' and len(args) != 3: + raise oscerr.WrongArgs('Please use PROJECT') + elif args[1] == 'request' and len(args) != 3: + raise oscerr.WrongArgs('Please use REQUEST') + elif args[0] == 'delete' and len(args) != 2: + raise oscerr.WrongArgs('Please use COMMENT_ID') + if not opts.comment and args[0] == 'create': + comment = edit_text() + else: + comment = opts.comment + + if args[0] == 'list': + print_comments(apiurl, args[1], *args[2:]) + elif args[0] == 'create': + result = create_comment(apiurl, args[1], comment, + *args[2:], parent=opts.parent) + print(result) + elif args[0] == 'delete': + result = delete_comment(apiurl, args[1]) + print(result) + def _load_plugins(self): plugin_dirs = [ '/usr/lib/osc-plugins', diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/osc-0.156.0/osc/core.py new/osc-0.157.1/osc/core.py --- old/osc-0.156.0/osc/core.py 2016-12-19 14:47:45.000000000 +0100 +++ new/osc-0.157.1/osc/core.py 2017-03-08 13:10:35.000000000 +0100 @@ -5,7 +5,7 @@ from __future__ import print_function -__version__ = '0.156' +__version__ = '0.157' # __store_version__ is to be incremented when the format of the working copy # "store" changes in an incompatible way. Please add any needed migration @@ -3918,8 +3918,9 @@ tmpfile.write(message) tmpfile.flush() pager = os.getenv('PAGER', default=get_default_pager()) + cmd = shlex.split(pager) + [tmpfile.name] try: - run_external(pager, tmpfile.name) + run_external(*cmd) finally: tmpfile.close() @@ -4511,6 +4512,8 @@ where = package or '_repository' u = makeurl(apiurl, ['build', prj, repo, arch, where, filename]) download(u, target_filename, progress_obj, target_mtime) + if target_filename.endswith('.AppImage'): + os.chmod(target_filename, 0o755) def dgst_from_string(str): # Python 2.5 depracates the md5 modules @@ -4799,16 +4802,19 @@ # if project roots were previously inconsistent root_dots = "../../" if is_project_dir(root_dots): + oldproj = store_read_project(root_dots) if conf.config['checkout_no_colon']: - oldproj = store_read_project(root_dots) n = len(oldproj.split(':')) else: n = 1 + if root_dots == '.': + root_dots = '' root_dots = root_dots + "../" * n if root_dots != '.': if conf.config['verbose']: - print("found root of %s at %s" % (oldproj, root_dots)) + print("%s is project dir of %s. Root found at %s" % + (prj_dir, oldproj, os.path.abspath(root_dots))) prj_dir = root_dots + prj_dir if not pathname: @@ -4816,7 +4822,7 @@ # before we create directories and stuff, check if the package actually # exists - show_package_meta(apiurl, project, package, meta) + show_package_meta(apiurl, quote_plus(project), quote_plus(package), meta) isfrozen = False if expand_link: @@ -5894,7 +5900,26 @@ f = http_GET(u) return f.read() - + +def get_worker_info(apiurl, worker): + u = makeurl(apiurl, ['worker', worker]) + f = http_GET(u) + + return f.read() + + +def check_constraints(apiurl, prj, repository, arch, package, constraintsfile=None): + query = {'cmd': 'checkconstraints'} + query['project'] = prj + query['package'] = package + query['repository'] = repository + query['arch'] = arch + u = makeurl(apiurl, ['worker'], query) + f = http_POST(u, data=constraintsfile) + root = ET.fromstring(''.join(f)) + return [node.get('name') for node in root.findall('entry')] + + def get_source_rev(apiurl, project, package, revision=None): # API supports ?deleted=1&meta=1&rev=4 # but not rev=current,rev=latest,rev=top, or anything like this. @@ -6237,6 +6262,9 @@ def restartbuild(apiurl, project, package=None, arch=None, repo=None): return cmdbuild(apiurl, 'restartbuild', project, package, arch, repo) +def unpublish(apiurl, project, package=None, arch=None, repo=None, code=None): + return cmdbuild(apiurl, 'unpublish', project, package, arch, repo, code) + def wipebinaries(apiurl, project, package=None, arch=None, repo=None, code=None): return cmdbuild(apiurl, 'wipe', project, package, arch, repo, code) @@ -7288,6 +7316,32 @@ raise raise oscerr.ExtRuntimeError(e.strerror, filename) +def return_external(filename, *args, **kwargs): + """Executes the program filename via subprocess.check_output. + + *args are additional arguments which are passed to the + program filename. **kwargs specify additional arguments for + the subprocess.check_output function. + if no args are specified the plain filename is passed + to subprocess.check_output (this can be used to execute a shell + command). Otherwise [filename] + list(args) is passed + to the subprocess.check_output function. + + Returns the output of the command. + + """ + if args: + cmd = [filename] + list(args) + else: + cmd = filename + + try: + return subprocess.check_output(cmd, **kwargs) + except OSError as e: + if e.errno != errno.ENOENT: + raise + raise oscerr.ExtRuntimeError(e.strerror, filename) + # backward compatibility: local role filtering def filter_role(meta, user, role): """ @@ -7353,26 +7407,40 @@ return None -def get_comments(apiurl, kind, name): - url = makeurl(apiurl, ['comments', kind, name]) +def get_comments(apiurl, kind, *args): + url = makeurl(apiurl, ('comments', kind) + args) f = http_GET(url) return ET.parse(f).getroot() -def print_comments(apiurl, kind, name): +def print_comments(apiurl, kind, *args): def print_rec(comments, indent=''): for comment in comments: print(indent, end='') - print('On', comment.get('when'), comment.get('who'), 'wrote:') + print('(', comment.get('id'), ')', 'On', comment.get('when'), comment.get('who'), 'wrote:') text = indent + comment.text.replace('\r\n',' \n') print(('\n' + indent).join(text.split('\n'))) print() print_rec([c for c in root if c.get('parent') == comment.get('id')], indent + ' ') - - root = get_comments(apiurl, kind, name) + root = get_comments(apiurl, kind, *args) comments = [c for c in root if c.get('parent') is None] if comments: print('\nComments:') print_rec(comments) +def create_comment(apiurl, kind, comment, *args, **kwargs): + query = {} + if kwargs.get('parent') is not None: + query = {'parent_id': kwargs['parent']} + u = makeurl(apiurl, ('comments', kind) + args, query=query) + f = http_POST(u, data=comment) + ret = ET.fromstring(f.read()).find('summary') + return ret.text + +def delete_comment(apiurl, cid): + u = makeurl(apiurl, ['comment', cid]) + f = http_DELETE(u) + ret = ET.fromstring(f.read()).find('summary') + return ret.text + # vim: sw=4 et diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/osc-0.156.0/osc/oscssl.py new/osc-0.157.1/osc/oscssl.py --- old/osc-0.156.0/osc/oscssl.py 2016-12-19 14:47:45.000000000 +0100 +++ new/osc-0.157.1/osc/oscssl.py 2017-03-08 13:10:35.000000000 +0100 @@ -249,13 +249,36 @@ self.appname = kwargs.pop('appname', 'generic') M2Crypto.httpslib.HTTPSConnection.__init__(self, *args, **kwargs) - def connect(self, *args): - self.sock = SSL.Connection(self.ssl_ctx) + def _connect(self, family): + self.sock = SSL.Connection(self.ssl_ctx, family=family) if self.session: self.sock.set_session(self.session) if hasattr(self.sock, 'set_tlsext_host_name'): self.sock.set_tlsext_host_name(self.host) self.sock.connect((self.host, self.port)) + return True + + def connect(self): + # based on M2Crypto.httpslib.HTTPSConnection.connect + last_exc = None + connected = False + for addrinfo in socket.getaddrinfo(self.host, self.port, + socket.AF_UNSPEC, + socket.SOCK_STREAM, + 0, 0): + try: + connected = self._connect(addrinfo[0]) + break + except socket.error as e: + last_exc = e + finally: + if not connected and self.sock is not None: + self.sock.close() + if not connected: + if last_exc is None: + raise RuntimeError('getaddrinfo returned empty list') + raise last_exc + # ok we are connected, verify cert verify_certificate(self) def getHost(self): ++++++ osc.dsc ++++++ --- /var/tmp/diff_new_pack.nweu3z/_old 2017-03-12 20:03:56.802209477 +0100 +++ /var/tmp/diff_new_pack.nweu3z/_new 2017-03-12 20:03:56.802209477 +0100 @@ -1,6 +1,6 @@ Format: 1.0 Source: osc -Version: 0.156.0 +Version: 0.157.1 Binary: osc Maintainer: Adrian Schroeter <[email protected]> Architecture: any
