Hello community, here is the log from the commit of package osc for openSUSE:Factory checked in at 2015-07-02 22:49:40 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/osc (Old) and /work/SRC/openSUSE:Factory/.osc.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "osc" Changes: -------- --- /work/SRC/openSUSE:Factory/osc/osc.changes 2015-05-16 07:14:35.000000000 +0200 +++ /work/SRC/openSUSE:Factory/.osc.new/osc.changes 2015-07-03 00:11:38.000000000 +0200 @@ -1,0 +2,11 @@ +Tue Jun 30 13:35:47 UTC 2015 - adr...@suse.de + +- 0.152.0 + - add support searching for groups via "group:" prefix + - show possible used incident projects on "maintained" command + OBS 2.7 only: + - support buildtime source services + - support maintenance_incident requests with acceptinfo data + - support maintenance_release requests with acceptinfo data + +------------------------------------------------------------------- Old: ---- osc-0.151.2.tar.gz New: ---- osc-0.152.0.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ osc.spec ++++++ --- /var/tmp/diff_new_pack.qXjUne/_old 2015-07-03 00:11:39.000000000 +0200 +++ /var/tmp/diff_new_pack.qXjUne/_new 2015-07-03 00:11:39.000000000 +0200 @@ -17,7 +17,7 @@ Name: osc -Version: 0.151.2 +Version: 0.152.0 Release: 0 Summary: openSUSE Build Service Commander License: GPL-2.0+ ++++++ PKGBUILD ++++++ --- /var/tmp/diff_new_pack.qXjUne/_old 2015-07-03 00:11:39.000000000 +0200 +++ /var/tmp/diff_new_pack.qXjUne/_new 2015-07-03 00:11:39.000000000 +0200 @@ -1,5 +1,5 @@ pkgname=osc -pkgver=0.151.2 +pkgver=0.152.0 pkgrel=0 pkgdesc="Open Build Service client" arch=('i686' 'x86_64') @@ -8,7 +8,7 @@ groups=('base-devel') depends=('python2' 'python2-m2crypto' 'urlgrabber') source=(osc-${pkgver}.tar.gz) -md5sums=('8acda45a7a4061de2db404d79dc17bb6') +md5sums=('4a0b1194f52280d42dd50fe2a8adaa3a') package() { msg "Installing osc ..." ++++++ _service ++++++ --- /var/tmp/diff_new_pack.qXjUne/_old 2015-07-03 00:11:39.000000000 +0200 +++ /var/tmp/diff_new_pack.qXjUne/_new 2015-07-03 00:11:39.000000000 +0200 @@ -1,7 +1,7 @@ <services> <service name="tar_scm" mode="disabled"> - <param name="version">0.151.2</param> - <param name="revision">0.151.2</param> + <param name="version">0.152.0</param> + <param name="revision">0.152.0</param> <param name="url">git://github.com/openSUSE/osc.git</param> <param name="scm">git</param> </service> ++++++ debian.changelog ++++++ --- /var/tmp/diff_new_pack.qXjUne/_old 2015-07-03 00:11:39.000000000 +0200 +++ /var/tmp/diff_new_pack.qXjUne/_new 2015-07-03 00:11:39.000000000 +0200 @@ -1,4 +1,4 @@ -osc (0.151.2) unstable; urgency=low +osc (0.152.0) unstable; urgency=low - Update to 0.135.0 -- Adrian Schroeter <adr...@suse.de> Wed, 28 Jun 2012 10:00:00 +0200 ++++++ osc-0.151.2.tar.gz -> osc-0.152.0.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/osc-0.151.2/NEWS new/osc-0.152.0/NEWS --- old/osc-0.151.2/NEWS 2015-03-26 14:53:16.000000000 +0100 +++ new/osc-0.152.0/NEWS 2015-06-30 15:35:32.000000000 +0200 @@ -1,3 +1,11 @@ +0.152 + - add support searching for groups via "group:" prefix + - show possible used incident projects on "maintained" command + OBS 2.7 only: + - support buildtime source services + - support maintenance_incident requests with acceptinfo data + - support maintenance_release requests with acceptinfo data + 0.151 - fixed shell command injection via crafted _service files (CVE-2015-0778) - fix times when data comes from OBS backend diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/osc-0.151.2/README new/osc-0.152.0/README --- old/osc-0.151.2/README 2015-03-26 14:53:16.000000000 +0100 +++ new/osc-0.152.0/README 2015-06-30 15:35:32.000000000 +0200 @@ -13,7 +13,7 @@ RPM packages are here (rpm-md repository): http://download.opensuse.org/repositories/openSUSE:/Tools/ -To install from svn, do +To install from git, do python setup.py build python setup.py install diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/osc-0.151.2/dist/complete.sh new/osc-0.152.0/dist/complete.sh --- old/osc-0.151.2/dist/complete.sh 2015-03-26 14:53:16.000000000 +0100 +++ new/osc-0.152.0/dist/complete.sh 2015-06-30 15:35:32.000000000 +0200 @@ -1,7 +1,6 @@ test -z "$BASH_VERSION" && return complete -o default _nullcommand >/dev/null 2>&1 || return complete -r _nullcommand >/dev/null 2>&1 || return -COMP_WORDBREAKS="${COMP_WORDBREAKS//:}" test -s /usr/share/osc/complete && complete -o default -C /usr/share/osc/complete osc test -s /usr/lib64/osc/complete && complete -o default -C /usr/lib64/osc/complete osc test -s /usr/lib/osc/complete && complete -o default -C /usr/lib/osc/complete osc diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/osc-0.151.2/dist/osc.complete new/osc-0.152.0/dist/osc.complete --- old/osc-0.151.2/dist/osc.complete 2015-03-26 14:53:16.000000000 +0100 +++ new/osc-0.152.0/dist/osc.complete 2015-06-30 15:35:32.000000000 +0200 @@ -6,7 +6,6 @@ # # usage with bash # -# COMP_WORDBREAKS="${COMP_WORDBREAKS//:}" # complete -C osc.complete osc # # Author: Werner Fink <wer...@suse.de> @@ -35,14 +34,19 @@ let colon=0 else COMMAND_LINE="${COMP_LINE:0:$COMP_POINT}" -# let colon=1 let colon=0 + case "$COMP_WORDBREAKS" in + *:*) let colon=1 + esac [[ $COMMAND_LINE =~ \\: ]] && COMMAND_LINE="${COMMAND_LINE//\\:/:}" fi IFS="${IFS}=" cmdline=($COMMAND_LINE) IFS="$OIFS" -test "${cmdline[0]}" != "osc" && exit 1 +case "${cmdline[0]}" in +iosc|isc|osc) ;; +*) exit 1 +esac let last=${#COMMAND_LINE} let last-- @@ -79,24 +83,64 @@ oscpkg="" lnkprj="" lnkpkg="" +apiurl="" +alias="" test -s ${PWD}/.osc/_project && read -t 1 oscprj < ${PWD}/.osc/_project test -s ${PWD}/.osc/_package && read -t 1 oscpkg < ${PWD}/.osc/_package if test -s ${PWD}/.osc/_files ; then lnkprj=$(command sed -rn '/<linkinfo/{s@.*[[:blank:]]project="([^"]+)".*@\1@p;}' < ${PWD}/.osc/_files) lnkpkg=$(command sed -rn '/<linkinfo/{s@.*[[:blank:]]package="([^"]+)".*@\1@p;}' < ${PWD}/.osc/_files) fi +if test -s ${PWD}/.osc/_apiurl ; then + read apiurl < ${PWD}/.osc/_apiurl + alias=$(sed -rn '\@^\['${apiurl}'@,\@=@{\@^aliases=@{s@[^=]+=([^,]+),.*@\1@p};}' < ~/.oscrc 2> /dev/null) +fi +if test "${cmdline[0]}" = isc ; then + alias=internal +fi + +projects=~/.osc.projects +command=osc + +case "${cmdline[1]}" in +-A|--apiurl) + if test -n "${cmdline[2]}" -a -s ~/.oscrc ; then + hints=($(sed -rn '/^(aliases=|\[http)/{s/,/ /g;s/(aliases=|\[|\])//gp}' < ~/.oscrc 2> /dev/null)) + for h in ${hints[@]} ; do + case "$h" in + http*) + tmp=$(sed -rn '\@^\['${h}'@,\@=@{\@^aliases=@{s@[^=]+=([^,]+),.*@\1@p};}' < ~/.oscrc 2> /dev/null) + if test "${cmdline[2]}" = "$h" ; then + alias=$tmp + break + fi + ;; + *) + if test "${cmdline[2]}" = "$h" ; then + alias=$h + break + fi + esac + done + fi +esac -if test -s ~/.osc.projects ; then - typeset -i ctime=$(command date -d "$(command stat -c '%z' ~/.osc.projects)" +'%s') +if test -n "$alias" ; then + projects="${projects}.${alias}" + command="$command -A $alias" +fi + +if test -s "${projects}" ; then + typeset -i ctime=$(command date -d "$(command stat -c '%z' ${projects})" +'%s') typeset -i now=$(command date -d now +'%s') if ((now - ctime > 86400)) ; then - if tmp=$(mktemp ~/.osc.projects.XXXXXX) ; then - command osc ls / >| $tmp - mv -uf $tmp ~/.osc.projects + if tmp=$(mktemp ${projects}.XXXXXX) ; then + command ${command} ls / >| $tmp + mv -uf $tmp ${projects} fi fi else - command osc ls / >| ~/.osc.projects + command ${command} ls / >| "${projects}" fi projects () @@ -104,7 +148,7 @@ local -a list local -a argv local -i argc=0 - local arg + local arg cur for arg; do if test $arg == "--" ; then let argc++ @@ -113,15 +157,18 @@ argv[argc++]=$arg done shift $argc - if test -n "$1" ; then - list=($(command grep -E "^$1" ~/.osc.projects)) + cur="$1" + if test -n "${cur}" ; then + list=($(command grep -E "^${cur}" ${projects})) else - list=($(command cat ~/.osc.projects)) + list=($(command cat ${projects})) fi if ((colon)) ; then - builtin compgen -W "${list[*]}" "$1"|sed -r 's@([^\\]):@\1\\:@g' + local colon_word + colon_word=${cur%${cur##*:}} + builtin compgen -W "${list[*]}" -- "${cur}" | sed -r "s@^${colon_word}@@g" else - builtin compgen -W "${list[*]}" -- ${1+"$@"} + builtin compgen -W "${list[*]}" -- "${cur}" fi } @@ -130,7 +177,7 @@ local -a list local -a argv local -i argc=0 - local arg + local arg cur for arg; do if test $arg == "--" ; then let argc++ @@ -139,12 +186,13 @@ argv[argc++]=$arg done shift $argc - if test -n "$1" ; then - list=($(command osc ls ${argv[@]}|command grep -E "^$1")) + cur="$1" + if test -n "${cur}" ; then + list=($(command ${command} ls ${argv[@]}|command grep -E "^${cur}")) else - list=($(command osc ls ${argv[@]})) + list=($(command ${command} ls ${argv[@]})) fi - builtin compgen -W "${list[*]}" -- ${1+"$@"} + builtin compgen -W "${list[*]}" -- "${cur}" } repositories () @@ -162,11 +210,11 @@ done shift $argc if test -n "$1" ; then - list=($(command osc meta prj ${argv[@]}|\ + list=($(command ${command} meta prj ${argv[@]}|\ command sed -rn '/<repository/{s@^\s*<.*name="([^"]*)".*@\1@p}'|\ command sort -u|command grep -E "^$1")) else - list=($(command osc meta prj ${argv[@]}|\ + list=($(command ${command} meta prj ${argv[@]}|\ command sed -rn '/<repository/{s@^\s*<.*name="([^"]*)".*@\1@p}'|\ command sort -u)) fi @@ -188,11 +236,11 @@ done shift $argc if test -n "$1" ; then - list=($(command osc meta prj ${argv[@]}|\ + list=($(command ${command} meta prj ${argv[@]}|\ command sed -rn '/<arch>/{s@^\s*<arch>(.*)</arch>@\1@p}'|\ command sort -u|command grep -E "^$1")) else - list=($(command osc meta prj ${argv[@]}|\ + list=($(command ${command} meta prj ${argv[@]}|\ command sed -rn '/<arch>/{s@^\s*<arch>(.*)</arch>@\1@p}'|\ command sort -u)) fi @@ -223,8 +271,8 @@ users () { - if test -s ~/.osc.projects ; then - command sed -rn "/^home:$1/{ s/^home:([^:]*):.*/\1/p}" ~/.osc.projects|command sort -u + if test -s ${projects} ; then + command sed -rn "/^home:$1/{ s/^home:([^:]*):.*/\1/p}" ${projects}|command sort -u elif test -s ~/.oscrc; then command sed -rn '/^(user=)/{s/(user=)//p}' ~/.oscrc|command sort -u else @@ -350,7 +398,7 @@ fi ;; build) - opts=(--help --oldpackages --disable-cpio-bulk-download --download-api-only --release --baselibs + opts=(--help --oldpackages --disable-cpio-bulk-download --release --baselibs --disable-debuginfo --debuginfo --alternative-project --vm-type --linksources --local-package --build-uid --userootforbuild --define --without --with --ccache --icecream --jobs --root --extra-pkgs --keep-pkgs --prefer-pkgs @@ -437,9 +485,8 @@ done fi if ((count == 2)) ; then - specs=($(command ls *.spec 2>/dev/null)) - images=($(command ls *.kiwi 2>/dev/null)) - builtin compgen -W "${opts[*]} ${specs[*]} ${images[*]}" -- "${cmdline[count]}" + specs=($(command ls *.spec)) + builtin compgen -W "${opts[*]} ${specs[*]}" -- "${cmdline[count]}" fi ;; branch|getpac|bco|branchco) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/osc-0.151.2/osc/build.py new/osc-0.152.0/osc/build.py --- old/osc-0.151.2/osc/build.py 2015-03-26 14:53:16.000000000 +0100 +++ new/osc-0.152.0/osc/build.py 2015-06-30 15:35:32.000000000 +0200 @@ -66,7 +66,7 @@ 'armv5tel': [ 'armv4l', 'armv5el', 'armv5tel' ], 's390x': ['s390' ], 'ppc64': [ 'ppc', 'ppc64', 'ppc64p7', 'ppc64le' ], - 'ppc64le': [ 'ppc64le' ], + 'ppc64le': [ 'ppc64le', 'ppc64' ], 'i586': [ 'i386' ], 'i686': [ 'i586', 'i386' ], 'x86_64': ['i686', 'i586', 'i386' ], @@ -211,13 +211,15 @@ self.mp['apiurl'] = apiurl if pacsuffix == 'deb': - filename = debquery.DebQuery.filename(self.mp['name'], self.mp['epoch'], self.mp['version'], self.mp['release'], self.mp['arch']) + canonname = debquery.DebQuery.filename(self.mp['name'], self.mp['epoch'], self.mp['version'], self.mp['release'], self.mp['arch']) elif pacsuffix == 'arch': - filename = archquery.ArchQuery.filename(self.mp['name'], self.mp['epoch'], self.mp['version'], self.mp['release'], self.mp['arch']) + canonname = archquery.ArchQuery.filename(self.mp['name'], self.mp['epoch'], self.mp['version'], self.mp['release'], self.mp['arch']) else: - filename = rpmquery.RpmQuery.filename(self.mp['name'], self.mp['epoch'], self.mp['version'], self.mp['release'], self.mp['arch']) + canonname = rpmquery.RpmQuery.filename(self.mp['name'], self.mp['epoch'], self.mp['version'], self.mp['release'], self.mp['arch']) - self.mp['filename'] = node.get('binary') or filename + self.mp['canonname'] = canonname + # maybe we should rename filename key to binary + self.mp['filename'] = node.get('binary') or canonname if self.mp['repopackage'] == '_repository': self.mp['repofilename'] = self.mp['name'] else: @@ -238,7 +240,7 @@ # or if-modified-since, so the caching is simply name-based (on the assumption # that the filename is suitable as identifier) self.localdir = '%s/%s/%s/%s' % (cachedir, self.project, self.repository, self.arch) - self.fullfilename = os.path.join(self.localdir, self.filename) + self.fullfilename = os.path.join(self.localdir, self.canonname) self.url_local = 'file://%s' % self.fullfilename # first, add the local URL @@ -444,6 +446,8 @@ build_root = opts.root if opts.target: buildargs.append('--target=%s' % opts.target) + if opts.threads: + buildargs.append('--threads=%s' % opts.threads) if opts.jobs: buildargs.append('--jobs=%s' % opts.jobs) elif config['build-jobs'] > 1: @@ -567,13 +571,21 @@ build_descr_data = s + build_descr_data cpiodata = None + servicefile = os.path.join(os.path.dirname(build_descr), "_service") + if not os.path.isfile(servicefile): + servicefile = os.path.join(os.path.dirname(build_descr), "_service") + if not os.path.isfile(servicefile): + servicefile = None + else: + print('Using local _service file') buildenvfile = os.path.join(os.path.dirname(build_descr), "_buildenv." + repo + "." + arch) if not os.path.isfile(buildenvfile): buildenvfile = os.path.join(os.path.dirname(build_descr), "_buildenv") if not os.path.isfile(buildenvfile): buildenvfile = None - if buildenvfile: - print('Using buildenv file: %s' % os.path.basename(buildenvfile)) + else: + print('Using local buildenv file: %s' % os.path.basename(buildenvfile)) + if buildenvfile or servicefile: from .util import cpio if not cpiodata: cpiodata = cpio.CpioWrite() @@ -590,6 +602,8 @@ # buildenv must come last for compatibility reasons... if buildenvfile: cpiodata.add("buildenv", open(buildenvfile).read()) + if servicefile: + cpiodata.add("_service", open(servicefile).read()) build_descr_data = cpiodata.get() # special handling for overlay and rsync-src/dest @@ -753,8 +767,9 @@ enable_cpio = not opts.disable_cpio_bulk_download, cookiejar=cookiejar) - # implicitly trust the project we are building for - check_trusted_projects(apiurl, [ i for i in bi.projects.keys() if not i == prj ]) + if not opts.trust_all_projects: + # implicitly trust the project we are building for + check_trusted_projects(apiurl, [ i for i in bi.projects.keys() if not i == prj ]) # now update the package cache fetcher.run(bi) @@ -991,7 +1006,7 @@ my_build_swap = build_root + '/swap' vm_options = [ '--vm-type=%s' % vm_type ] - if vm_type != 'lxc' and vm_type != 'emulator': + if vm_type != 'lxc': vm_options += [ '--vm-disk=' + my_build_device ] vm_options += [ '--vm-swap=' + my_build_swap ] vm_options += [ '--logfile=%s/.build.log' % build_root ] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/osc-0.151.2/osc/commandline.py new/osc-0.152.0/osc/commandline.py --- old/osc-0.151.2/osc/commandline.py 2015-03-26 14:53:16.000000000 +0100 +++ new/osc-0.152.0/osc/commandline.py 2015-06-30 15:35:32.000000000 +0200 @@ -1748,10 +1748,10 @@ @cmdln.option('-m', '--message', metavar='TEXT', help='specify message TEXT') - @cmdln.option('-r', '--repository', metavar='TEXT', - help='specify message TEXT') - @cmdln.option('--accept-in-hours', metavar='TEXT', - help='specify message time when request shall get accepted automatically. Only works with write permissions in target.') + @cmdln.option('-r', '--repository', metavar='REPOSITORY', + help='specify repository') + @cmdln.option('--accept-in-hours', metavar='HOURS', + help='specify time when request shall get accepted automatically. Only works with write permissions in target.') @cmdln.alias("dr") @cmdln.alias("dropreq") @cmdln.alias("droprequest") @@ -2236,8 +2236,8 @@ except HTTPError as e: # for OBS 2.0 and before sr_actions = r.get_actions('submit') - if not sr_actions: - raise oscerr.WrongOptions('\'--diff\' not possible (request has no \'submit\' actions)') + if not r.get_actions('submit') and not r.get_actions('maintenance_incident') and not r.get_actions('maintenance_release'): + raise oscerr.WrongOptions('\'--diff\' not possible (request has no supported actions)') for action in sr_actions: diff += 'old: %s/%s\nnew: %s/%s\n' % (action.src_project, action.src_package, action.tgt_project, action.tgt_package) @@ -3062,7 +3062,10 @@ if opts.dryrun: for r in result.findall('package'): - print("%s/%s"%(r.get('project'), r.get('package'))) + line="%s/%s"%(r.get('project'), r.get('package')) + for d in r.findall('devel'): + line+=" using sources from %s/%s"%(d.get('project'), d.get('package')) + print(line) return apiopt = '' @@ -3318,6 +3321,33 @@ delete_project(apiurl, prj, opts.force, msg) + def do_lock(self, subcmd, opts, project, package=None): + """${cmd_name}: Locks a project or package. + + usage: + osc lock PROJECT [PACKAGE] + + ${cmd_option_list} + """ + apiurl = self.get_api_url() + kind = 'prj' + path_args = (project,) + if package is not None: + kind = 'pkg' + path_args = (project, package) + meta = meta_exists(kind, path_args, create_new=False, apiurl=apiurl) + root = ET.fromstring(''.join(meta)) + if root.find('lock') is not None: + print('Already locked', file=sys.stderr) + sys.exit(1) + # alternatively, we could also use the set_flag api call + # instead of manually manipulating the xml + lock = ET.SubElement(root, 'lock') + ET.SubElement(lock, 'enable') + meta = ET.tostring(root) + edit_meta(kind, path_args=path_args, data=meta) + + @cmdln.option('-m', '--message', metavar='TEXT', help='specify log message TEXT') def do_unlock(self, subcmd, opts, *args): @@ -3951,8 +3981,12 @@ else: raise oscerr.WrongArgs('Wrong number of arguments') - # XXX: API should somehow tell that - url_tmpl = 'http://download.opensuse.org/repositories/%s/%s/%s.repo' + root = ET.fromstring(''.join(show_configuration(apiurl))) + elm = root.find('download_url') + if elm is None or not elm.text: + raise oscerr.APIError('download_url configuration element expected') + + url_tmpl = elm.text + '/%s/%s/%s.repo' repos = get_repositories_of_project(apiurl, project) for repo in repos: print(url_tmpl % (project.replace(':', ':/'), repo, project)) @@ -5527,6 +5561,8 @@ help='Build in specified directory') @cmdln.option('-j', '--jobs', metavar='N', help='Compile with N jobs') + @cmdln.option('-t', '--threads', metavar='N', + help='Compile with N threads') @cmdln.option('--icecream', metavar='N', help='use N parallel build jobs with icecream') @cmdln.option('--ccache', action='store_true', @@ -5574,6 +5610,8 @@ help=SUPPRESS_HELP) @cmdln.option('--host', metavar='HOST', help='perform the build on a remote server - user@server:~/remote/directory') + @cmdln.option('--trust-all-projects', action='store_true', + help='trust packages from all projects') def do_build(self, subcmd, opts, *args): """${cmd_name}: Build a package on your local machine @@ -5821,10 +5859,10 @@ @cmdln.option('-o', '--offline', action='store_true', help='Use cached data without contacting the api server') def do_chroot(self, subcmd, opts, *args): - """${cmd_name}: chroot into the buildchroot + """${cmd_name}: opens a shell inside of the build root - chroot into the buildchroot for the given repository, arch and build description - (NOTE: this command does not work if "build-type" is set in the config) + chroot into the build root for the given repository, arch and build description + (NOTE: this command does not work if a VM is used) usage: osc chroot [OPTS] REPOSITORY ARCH BUILD_DESCR @@ -5836,7 +5874,7 @@ """ if len(args) > 3: raise oscerr.WrongArgs('Too many arguments') - if conf.config['build-type']: + if conf.config['build-type'] and conf.config['build-type'] != "lxc": print('Not implemented for VMs', file=sys.stderr) sys.exit(1) @@ -5886,6 +5924,8 @@ ${cmd_option_list} """ + args = slash_split(args) + if len(args) < 2 and is_package_dir('.'): self.print_repos() @@ -6651,7 +6691,7 @@ @cmdln.option('-V', '--version', action='store_true', help='show package version, revision, and srcmd5. CAUTION: This is slow and unreliable') @cmdln.option('-i', '--involved', action='store_true', - help='show projects/packages where given person (or myself) is involved as bugowner or maintainer') + help='show projects/packages where given person (or myself) is involved as bugowner or maintainer [[{group|person}/]<name>] default: person') @cmdln.option('-b', '--bugowner', action='store_true', help='as -i, but only bugowner') @cmdln.option('-m', '--maintainer', action='store_true', @@ -6742,14 +6782,25 @@ # role filter role_filter = '' if opts.bugowner or opts.maintainer or opts.involved: - xpath = xpath_join(xpath, 'person/@userid = \'%s\'' % search_term, inner=True) - role_filter = '%s (%s)' % (search_term, 'person') + tmp = search_term.split(':') + if len(tmp) > 1: + search_type, search_term = [tmp[0], tmp[1]] + else: + search_type = 'person' + search_dict = { 'person' : 'userid', + 'group' : 'groupid' } + try: + search_id = search_dict[ search_type ] + except KeyError: + search_type, search_id = [ 'person', 'userid' ] + xpath = xpath_join(xpath, '%s/@%s = \'%s\'' % (search_type, search_id, search_term), inner=True) + role_filter = '%s (%s)' % (search_term, search_type) role_filter_xpath = xpath if opts.bugowner and not opts.maintainer: - xpath = xpath_join(xpath, 'person/@role=\'bugowner\'', op='and') + xpath = xpath_join(xpath, '%s/@role=\'bugowner\'' % search_type, op='and') role_filter = 'bugowner' elif not opts.bugowner and opts.maintainer: - xpath = xpath_join(xpath, 'person/@role=\'maintainer\'', op='and') + xpath = xpath_join(xpath, '%s/@role=\'maintainer\'' % search_type, op='and') role_filter = 'maintainer' if opts.limit_to_attribute: xpath = xpath_join(xpath, 'attribute/@name=\'%s\'' % opts.limit_to_attribute, op='and') diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/osc-0.151.2/osc/core.py new/osc-0.152.0/osc/core.py --- old/osc-0.151.2/osc/core.py 2015-03-26 14:53:16.000000000 +0100 +++ new/osc-0.152.0/osc/core.py 2015-06-30 15:35:33.000000000 +0200 @@ -5,7 +5,7 @@ from __future__ import print_function -__version__ = '0.151' +__version__ = '0.152' # __store_version__ is to be incremented when the format of the working copy # "store" changes in an incompatible way. Please add any needed migration @@ -81,7 +81,7 @@ <enable /> </build> <debuginfo> - <disable /> + <enable /> </debuginfo> <!-- remove this comment to enable one or more build targets @@ -91,23 +91,23 @@ <arch>x86_64</arch> <arch>i586</arch> </repository> - <repository name="openSUSE_11.2"> - <path project="openSUSE:11.2" repository="standard"/> + <repository name="openSUSE_13.2"> + <path project="openSUSE:13.2" repository="standard"/> <arch>x86_64</arch> <arch>i586</arch> </repository> - <repository name="openSUSE_11.1"> - <path project="openSUSE:11.1" repository="standard"/> + <repository name="openSUSE_13.1"> + <path project="openSUSE:13.1" repository="standard"/> <arch>x86_64</arch> <arch>i586</arch> </repository> - <repository name="Fedora_12"> - <path project="Fedora:12" repository="standard" /> + <repository name="Fedora_21"> + <path project="Fedora:21" repository="standard" /> <arch>x86_64</arch> <arch>i586</arch> </repository> - <repository name="SLE_11"> - <path project="SUSE:SLE-11" repository="standard" /> + <repository name="SLE_12"> + <path project="SUSE:SLE-12:GA" repository="standard" /> <arch>x86_64</arch> <arch>i586</arch> </repository> @@ -389,6 +389,8 @@ for service in allservices: if singleservice and service['name'] != singleservice: continue + if service['mode'] == "buildtime": + continue if service['mode'] == "serveronly" and callmode != "disabled": continue if service['mode'] == "disabled" and callmode != "disabled": @@ -405,7 +407,7 @@ raise oscerr.PackageNotInstalled("obs-service-%s"%cmd[0]) cmd[0] = "/usr/lib/obs/service/"+cmd[0] cmd = cmd + [ "--outdir", temp_dir ] - if conf.config['verbose'] > 1 or verbose: + if conf.config['verbose'] > 1 or verbose or conf.config['debug']: print("Run source service:", ' '.join(cmd)) r = run_external(*cmd) @@ -2516,8 +2518,10 @@ 'set_bugowner': ('tgt_project', 'tgt_package', 'person_name', 'group_name'), 'maintenance_release': ('src_project', 'src_package', 'src_rev', 'tgt_project', 'tgt_package', 'person_name', 'acceptinfo_rev', 'acceptinfo_srcmd5', 'acceptinfo_xsrcmd5', 'acceptinfo_osrcmd5', + 'acceptinfo_oxsrcmd5', 'acceptinfo_oproject', 'acceptinfo_opackage'), + 'maintenance_incident': ('src_project', 'src_package', 'src_rev', 'tgt_project', 'tgt_package', 'tgt_releaseproject', 'person_name', 'opt_sourceupdate', 'opt_makeoriginolder', + 'acceptinfo_rev', 'acceptinfo_srcmd5', 'acceptinfo_xsrcmd5', 'acceptinfo_osrcmd5', 'acceptinfo_oxsrcmd5'), - 'maintenance_incident': ('src_project', 'src_package', 'src_rev', 'tgt_project', 'tgt_releaseproject', 'person_name', 'opt_sourceupdate', 'opt_makeoriginolder'), 'delete': ('tgt_project', 'tgt_package', 'tgt_repository'), 'change_devel': ('src_project', 'src_package', 'tgt_project', 'tgt_package'), 'group': ('grouped_id', )} @@ -3443,6 +3447,11 @@ e.osc_msg = 'show_pattern_meta: Error getting pattern \'%s\' for project \'%s\'' % (pattern, prj) raise +def show_configuration(apiurl): + u = makeurl(apiurl, ['public', 'configuration']) + f = http_GET(u) + return f.readlines() + class metafile: """metafile that can be manipulated and is stored back after manipulation.""" @@ -4001,6 +4010,7 @@ raise oscerr.APIError("Server did not define a default maintenance project, can't submit.") tproject = project.get('name') r = create_maintenance_request(apiurl, src_project, [src_package], tproject, dst_project, src_update, message) + r = r.reqid else: raise @@ -4044,12 +4054,8 @@ ['request', reqid], query=query) f = http_POST(u, data=message) - r = f.read() - if r.startswith('<status code="'): - r = r.split('<status code="')[1] - r = r.split('" />')[0] - - return r + root = ET.parse(f).getroot() + return root.get('code', 'unknown') def change_request_state_template(req, newstate): if not len(req.actions): @@ -5635,7 +5641,7 @@ # to protect us against control characters import string all_bytes = string.maketrans('', '') - remove_bytes = all_bytes[:9] + all_bytes[11:32] # accept tabs and newlines + remove_bytes = all_bytes[:8] + all_bytes[14:32] # accept tabs and newlines query = {'nostream' : '1', 'start' : '%s' % offset} if last: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/osc-0.151.2/osc/fetch.py new/osc-0.152.0/osc/fetch.py --- old/osc-0.151.2/osc/fetch.py 2015-03-26 14:53:16.000000000 +0100 +++ new/osc-0.152.0/osc/fetch.py 2015-06-30 15:35:33.000000000 +0200 @@ -217,7 +217,7 @@ fullfilename = os.path.join(destdir, canonname) if pac_obj is not None: - pac_obj.filename = canonname + pac_obj.canonname = canonname pac_obj.fullfilename = fullfilename shutil.move(tmpfile, fullfilename) os.chmod(fullfilename, 0o644) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/osc-0.151.2/osc/util/archquery.py new/osc-0.152.0/osc/util/archquery.py --- old/osc-0.151.2/osc/util/archquery.py 2015-03-26 14:53:16.000000000 +0100 +++ new/osc-0.152.0/osc/util/archquery.py 2015-06-30 15:35:33.000000000 +0200 @@ -10,7 +10,7 @@ class ArchError(packagequery.PackageError): pass -class ArchQuery(packagequery.PackageQuery): +class ArchQuery(packagequery.PackageQuery, packagequery.PackageQueryResult): def __init__(self, fh): self.__file = fh self.__path = os.path.abspath(fh.name) @@ -36,6 +36,7 @@ if self_provides: prv = '%s = %s' % (self.name(), self.fields['pkgver'][0]) self.fields.setdefault('provides', []).append(prv) + return self def vercmp(self, archq): res = cmp(int(self.epoch()), int(archq.epoch())) @@ -98,6 +99,10 @@ pkgver = self.fields['pkgver'][0] if 'pkgver' in self.fields else None return self.name() + '-' + pkgver + '-' + self.arch() + '.' + self.pkgsuffix + def gettag(self, tag): + # implement me, if needed + return None + @staticmethod def query(filename, all_tags = False, *extra_tags): f = open(filename, 'rb') diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/osc-0.151.2/osc/util/debquery.py new/osc-0.152.0/osc/util/debquery.py --- old/osc-0.151.2/osc/util/debquery.py 2015-03-26 14:53:16.000000000 +0100 +++ new/osc-0.152.0/osc/util/debquery.py 2015-06-30 15:35:33.000000000 +0200 @@ -10,7 +10,7 @@ class DebError(packagequery.PackageError): pass -class DebQuery(packagequery.PackageQuery): +class DebQuery(packagequery.PackageQuery, packagequery.PackageQueryResult): default_tags = ('package', 'version', 'release', 'epoch', 'architecture', 'description', 'provides', 'depends', 'pre_depends', 'conflicts', 'breaks') @@ -43,6 +43,7 @@ except KeyError: raise DebError(self.__path, 'missing \'control\' file in control.tar.gz') self.__parse_control(control, all_tags, self_provides, *extra_tags) + return self def __parse_control(self, control, all_tags=False, self_provides=True, *extra_tags): data = control.readline().strip() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/osc-0.151.2/osc/util/packagequery.py new/osc-0.152.0/osc/util/packagequery.py --- old/osc-0.151.2/osc/util/packagequery.py 2015-03-26 14:53:16.000000000 +0100 +++ new/osc-0.152.0/osc/util/packagequery.py 2015-06-30 15:35:33.000000000 +0200 @@ -48,8 +48,52 @@ class PackageQuery: """abstract base class for all package types""" def read(self, all_tags = False, *extra_tags): + """Returns a PackageQueryResult instance""" raise NotImplementedError + # Hmmm... this should be a module function (inherting this stuff + # does not make much sense) (the same is true for the queryhdrmd5 method) + @staticmethod + def query(filename, all_tags=False, extra_rpmtags=(), extra_debtags=(), self_provides=True): + f = open(filename, 'rb') + magic = f.read(7) + f.seek(0) + extra_tags = () + pkgquery = None + if magic[:4] == '\xed\xab\xee\xdb': + from . import rpmquery + pkgquery = rpmquery.RpmQuery(f) + extra_tags = extra_rpmtags + elif magic == '!<arch>': + from . import debquery + pkgquery = debquery.DebQuery(f) + extra_tags = extra_debtags + elif magic[:5] == '<?xml': + f.close() + return None + elif magic[:5] == '\375\067zXZ' or magic[:2] == '\037\213': + from . import archquery + pkgquery = archquery.ArchQuery(f) + else: + raise PackageError(filename, 'unsupported package type. magic: \'%s\'' % magic) + pkgqueryresult = pkgquery.read(all_tags, self_provides, *extra_tags) + f.close() + return pkgqueryresult + + @staticmethod + def queryhdrmd5(filename): + f = open(filename, 'rb') + magic = f.read(7) + f.seek(0) + if magic[:4] == '\xed\xab\xee\xdb': + from . import rpmquery + f.close() + return rpmquery.RpmQuery.queryhdrmd5(filename) + return None + + +class PackageQueryResult: + """abstract base class that represents the result of a package query""" def name(self): raise NotImplementedError @@ -83,7 +127,7 @@ def obsoletes(self): raise NotImplementedError - def gettag(self): + def gettag(self, tag): raise NotImplementedError def vercmp(self, pkgquery): @@ -99,44 +143,6 @@ evr = epoch + ":" + evr return evr - @staticmethod - def query(filename, all_tags=False, extra_rpmtags=(), extra_debtags=(), self_provides=True): - f = open(filename, 'rb') - magic = f.read(7) - f.seek(0) - extra_tags = () - pkgquery = None - if magic[:4] == '\xed\xab\xee\xdb': - from . import rpmquery - pkgquery = rpmquery.RpmQuery(f) - extra_tags = extra_rpmtags - elif magic == '!<arch>': - from . import debquery - pkgquery = debquery.DebQuery(f) - extra_tags = extra_debtags - elif magic[:5] == '<?xml': - f.close() - return None - elif magic[:5] == '\375\067zXZ' or magic[:2] == '\037\213': - from . import archquery - pkgquery = archquery.ArchQuery(f) - else: - raise PackageError(filename, 'unsupported package type. magic: \'%s\'' % magic) - pkgquery.read(all_tags, self_provides, *extra_tags) - f.close() - return pkgquery - - @staticmethod - def queryhdrmd5(filename): - f = open(filename, 'rb') - magic = f.read(7) - f.seek(0) - if magic[:4] == '\xed\xab\xee\xdb': - from . import rpmquery - f.close() - return rpmquery.RpmQuery.queryhdrmd5(filename) - return None - if __name__ == '__main__': import sys try: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/osc-0.151.2/osc/util/repodata.py new/osc-0.152.0/osc/util/repodata.py --- old/osc-0.151.2/osc/util/repodata.py 2015-03-26 14:53:16.000000000 +0100 +++ new/osc-0.152.0/osc/util/repodata.py 2015-06-30 15:35:33.000000000 +0200 @@ -13,6 +13,7 @@ # project modules import osc.util.rpmquery +import osc.util.packagequery def namespace(name): return "{http://linux.duke.edu/metadata/%s}" % name @@ -52,7 +53,7 @@ @param directory path to a repository directory (parent directory of repodata directory) - @return list of RepoDataQuery instances + @return list of RepoDataQueryResult instances @raise IOError if repomd.xml contains no primary location """ path = primaryPath(directory) @@ -63,16 +64,16 @@ packageQueries = [] for packageElement in root: - packageQuery = RepoDataQuery(directory, packageElement) + packageQuery = RepoDataQueryResult(directory, packageElement) packageQueries.append(packageQuery) return packageQueries -class RepoDataQuery(object): - """PackageQuery that reads in data from the repodata directory files.""" +class RepoDataQueryResult(osc.util.packagequery.PackageQueryResult): + """PackageQueryResult that reads in data from the repodata directory files.""" def __init__(self, directory, element): - """Creates a RepoDataQuery from the a package Element under a metadata + """Creates a RepoDataQueryResult from the a package Element under a metadata Element in a primary.xml file. @param directory repository directory path. Used to convert relative @@ -147,6 +148,20 @@ def requires(self): return self.__parseEntryCollection("requires") + def conflicts(self): + return self.__parseEntryCollection('conflicts') + + def obsoletes(self): + return self.__parseEntryCollection('obsoletes') + + def canonname(self): + return osc.util.rpmquery.RpmQuery.filename(self.name(), None, + self.version(), self.release(), self.arch()) + + def gettag(self, tag): + # implement me, if needed + return None + def vercmp(self, other): res = osc.util.rpmquery.RpmQuery.rpmvercmp(str(self.epoch()), str(other.epoch())) if res != 0: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/osc-0.151.2/osc/util/rpmquery.py new/osc-0.152.0/osc/util/rpmquery.py --- old/osc-0.151.2/osc/util/rpmquery.py 2015-03-26 14:53:16.000000000 +0100 +++ new/osc-0.152.0/osc/util/rpmquery.py 2015-06-30 15:35:33.000000000 +0200 @@ -48,7 +48,7 @@ self.count = count self.data = None -class RpmQuery(packagequery.PackageQuery): +class RpmQuery(packagequery.PackageQuery, packagequery.PackageQueryResult): LEAD_SIZE = 96 LEAD_MAGIC = 0xedabeedb HEADER_MAGIC = 0x8eade801 @@ -101,6 +101,7 @@ try: # this may fail for -debug* packages self.__read_data(i, data) except: pass + return self def __read_lead(self): data = self.__file.read(self.LEAD_SIZE) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/osc-0.151.2/osc-wrapper.py new/osc-0.152.0/osc-wrapper.py --- old/osc-0.151.2/osc-wrapper.py 2015-03-26 14:53:16.000000000 +0100 +++ new/osc-0.152.0/osc-wrapper.py 2015-06-30 15:35:32.000000000 +0200 @@ -5,6 +5,7 @@ import locale import sys +import os from osc import commandline, babysitter @@ -21,6 +22,20 @@ #reload, neither setdefaultencoding are in python3 pass +# avoid buffering output on pipes (bnc#930137) +# Basically, a "print('foo')" call is translated to a corresponding +# fwrite call that writes to the stdout stream (cf. string_print +# (Objects/stringobject.c) and builtin_print (Python/bltinmodule.c)); +# If no pipe is used, stdout is a tty/refers to a terminal => +# the stream is line buffered (see _IO_file_doallocate (libio/filedoalloc.c)). +# If a pipe is used, stdout does not refer to a terminal anymore => +# the stream is fully buffered by default (see _IO_file_doallocate). +# The following fdopen call makes stdout line buffered again (at least on +# systems that support setvbuf - if setvbuf is not supported, the stream +# remains fully buffered (see PyFile_SetBufSize (Objects/fileobject.c))). +if not os.isatty(sys.stdout.fileno()): + sys.stdout = os.fdopen(sys.stdout.fileno(), sys.stdout.mode, 1) + osccli = commandline.Osc() r = babysitter.run(osccli) ++++++ osc.dsc ++++++ --- /var/tmp/diff_new_pack.qXjUne/_old 2015-07-03 00:11:40.000000000 +0200 +++ /var/tmp/diff_new_pack.qXjUne/_new 2015-07-03 00:11:40.000000000 +0200 @@ -1,6 +1,6 @@ Format: 1.0 Source: osc -Version: 0.151.2 +Version: 0.152.0 Binary: osc Maintainer: Adrian Schroeter <adr...@suse.de> Architecture: any