1
0
mirror of https://github.com/openSUSE/osc.git synced 2025-02-09 20:45:47 +01:00

Merge branch 'master' of git://gitorious.org/opensuse/osc

This commit is contained in:
Marcus Huewe 2010-03-02 01:34:58 +01:00
commit 8e7a171cf2
18 changed files with 314 additions and 311 deletions

View File

@ -1,4 +1,4 @@
jw, Tue Oct 20 22:09:16 CEST 2009
jw, Tue Oct 20 22:09:16 CEST 2009
This is a feature suggestion for easier osc commandline handling.
Many commands require specifying Project and/or Package names.
@ -12,19 +12,19 @@ The current situation is not satisfying for the following reasons:
Examples as of osc version 0.123:
osc maintainer PRJ [PKG]
- does not look in the current directory.
- need at least PRJ.
- need at least PRJ.
osc list [PRJ [PKG]]
- Never looks at the current directory.
- Never looks at the current directory.
- lists all projects, if run without parameters.
osc checkout [PRJ] PKG
osc checkout PRJ
- takes project from current directory, if inside a checkout tree
- else operates on an entire project.
- else operates on an entire project.
osc checkin [ARG]
- defaults to current project and package,
- if arg is a subdirectory, project is taken from current directory
- if arg is a file, both project and package are taken from current
directory.
- if arg is a subdirectory, project is taken from current directory
- if arg is a file, both project and package are taken from current
directory.
osc results [PRJ PKG]
- takes either both or none from current directory.
- many commands do not look into the current directory,
@ -53,22 +53,22 @@ osc shall support aliases, to save typing. Some implicit aliases exist,
with well defined magic effects. Aliases substitution is literal.
They can replace options including their parameters, or just the option, or
just the parameters.
- (a dash) expands to --prj openSUSE:Factory
- (a dash) expands to --prj openSUSE:Factory
(or --prj followed by any other project as defined in
~/.oscrc:default_project )
--prj - is synonymous to just -, for consistency.
--prj - is synonymous to just -, for consistency.
. (a dot) evaluates the current working directory, searching for
.osc/_apiurl, .osc/_project, and .osc/_package
Implicit --apiurl, --prj, or --pkg options are constructed as far
as available from the current directory and as far as not already
present in the command line.
If a dot is used as parameter to an option, it has a more
deterministic meaning.
--apiurl . Substitute only the current apiurl,
--prj . Substitute the current project name, and provides
a default for --apiurl unless given.
--pkg . Substitures current package name likewise.
Implicit --apiurl, --prj, or --pkg options are constructed as far
as available from the current directory and as far as not already
present in the command line.
If a dot is used as parameter to an option, it has a more
deterministic meaning.
--apiurl . Substitute only the current apiurl,
--prj . Substitute the current project name, and provides
a default for --apiurl unless given.
--pkg . Substitures current package name likewise.
./. expands to --prj . --pkg .
./PKG expands to --prj . --pkg PKG
@ -83,10 +83,10 @@ printed as debug output.
online help of osc commands shall refer to the above syntax like this:
osc CMD ... PROJ/PACK
osc CMD ... PROJ/PACK
An additional help entry
osc help 'PROJ/PACK'
osc help 'PROJ/PACK'
shall explain the relevant details as presented herein.

33
README
View File

@ -14,10 +14,11 @@ RPM packages are here (rpm-md repository):
http://download.opensuse.org/repositories/openSUSE:/Tools/
To install from svn, do
python setup.py build
python setup.py install
# create a symlink 'osc' in your path pointing to osc.py.
ln -s osc-wrapper.py /usr/bin/osc
python setup.py build
python setup.py install
# create a symlink 'osc' in your path pointing to osc.py.
ln -s osc-wrapper.py /usr/bin/osc
Alternatively, you can directly use osc-wrapper.py from the source dir
(which is easier if you develop on osc).
@ -132,21 +133,21 @@ USAGE EXAMPLES:
(online at http://en.opensuse.org/Build_Service/CLI )
To list existing content on the server
osc ls # list projects
osc ls Apache # list packages in a project
osc ls Apache subversion # list files of package of a project
osc ls # list projects
osc ls Apache # list packages in a project
osc ls Apache subversion # list files of package of a project
Check out content
osc co Apache # entire project
osc co Apache subversion # a package
osc co Apache subversion foo # single file
osc co Apache # entire project
osc co Apache subversion # a package
osc co Apache subversion foo # single file
Update a working copy
osc up
osc up [pac_dir] # update a single package by its path
osc up * # from within a project dir, update all packages
osc up # from within a project dir, update all packages
AND check out all newly added packages
osc up [pac_dir] # update a single package by its path
osc up * # from within a project dir, update all packages
osc up # from within a project dir, update all packages
# AND check out all newly added packages
If an update can't be merged automatically, a file is in 'C' (conflict)
state, and conflicts are marked with special <<<<<<< and >>>>>>> lines.
@ -154,7 +155,7 @@ After manually resolving the problem, use
osc resolved foo
Upload change content
osc ci # current dir
osc ci # current dir
osc ci <dir>
osc ci file1 file2 ...
@ -171,7 +172,7 @@ Adds all new files in local copy and removes all disappeared files.
osc addremove
Generates a diff, to view the changes
osc diff # current dir
osc diff # current dir
osc diff file1 file2 ...
Shows the build results of the package

View File

@ -96,8 +96,8 @@ def run(prg):
body = e.read()
if getattr(prg.options, 'debug', None) or \
getattr(prg.conf, 'config', {}).get('debug', None):
print >>sys.stderr, e.hdrs
print >>sys.stderr, body
print >>sys.stderr, e.hdrs
print >>sys.stderr, body
if e.code in [ 400, 403, 404, 500 ]:
if '<summary>' in body:
@ -119,7 +119,7 @@ def run(prg):
print >>sys.stderr, e.msg
if getattr(prg.options, 'debug', None) or \
getattr(prg.conf, 'config', {}).get('debug', None):
print >>sys.stderr, e.e
print >>sys.stderr, e.e
return 1
except (oscerr.WrongOptions, oscerr.WrongArgs), e:

View File

@ -623,9 +623,9 @@ def main(opts, argv):
os.makedirs(os.path.join(pradir))
if not os.path.exists(tffn):
if opts.linksources:
os.link(sffn, tffn)
os.link(sffn, tffn)
else:
os.symlink(sffn, tffn)
os.symlink(sffn, tffn)
if bi.pacsuffix == 'rpm':
if opts.no_verify or opts.noinit:
@ -654,7 +654,7 @@ def main(opts, argv):
else:
print 'WARNING: deb packages get not verified, they can compromise your system !'
else:
print 'WARNING: unknown packages get not verified, they can compromise your system !'
print 'WARNING: unknown packages get not verified, they can compromise your system !'
print 'Writing build configuration'

View File

@ -7,96 +7,95 @@ import rpm
import base64
class KeyError(Exception):
def __init__(self, key, *args):
Exception.__init__(self)
self.args = args
self.key = key
def __str__(self):
return ''+self.key+' :'+' '.join(self.args)
def __init__(self, key, *args):
Exception.__init__(self)
self.args = args
self.key = key
def __str__(self):
return ''+self.key+' :'+' '.join(self.args)
class Checker:
def __init__(self):
self.dbdir = mkdtemp(prefix='oscrpmdb')
self.imported = {}
rpm.addMacro('_dbpath', self.dbdir)
self.ts = rpm.TransactionSet()
self.ts.initDB()
self.ts.openDB()
self.ts.setVSFlags(0)
#self.ts.Debug(1)
def __init__(self):
self.dbdir = mkdtemp(prefix='oscrpmdb')
self.imported = {}
rpm.addMacro('_dbpath', self.dbdir)
self.ts = rpm.TransactionSet()
self.ts.initDB()
self.ts.openDB()
self.ts.setVSFlags(0)
#self.ts.Debug(1)
def readkeys(self, keys=[]):
rpm.addMacro('_dbpath', self.dbdir)
for key in keys:
self.readkey(key)
def readkeys(self, keys=[]):
rpm.addMacro('_dbpath', self.dbdir)
for key in keys:
self.readkey(key)
rpm.delMacro("_dbpath")
rpm.delMacro("_dbpath")
# python is an idiot
# def __del__(self):
# self.cleanup()
# def __del__(self):
# self.cleanup()
def cleanup(self):
self.ts.closeDB()
rmtree(self.dbdir)
def cleanup(self):
self.ts.closeDB()
rmtree(self.dbdir)
def readkey(self, file):
if file in self.imported:
return
def readkey(self, file):
if file in self.imported:
return
fd = open(file, "r")
line = fd.readline()
if line and line[0:14] == "-----BEGIN PGP":
line = fd.readline()
while line and line != "\n":
line = fd.readline()
if not line:
raise KeyError(file, "not a pgp public key")
else:
raise KeyError(file, "not a pgp public key")
fd = open(file, "r")
line = fd.readline()
if line and line[0:14] == "-----BEGIN PGP":
line = fd.readline()
while line and line != "\n":
line = fd.readline()
if not line:
raise KeyError(file, "not a pgp public key")
else:
raise KeyError(file, "not a pgp public key")
key = ''
line = fd.readline()
while line:
if line[0:12] == "-----END PGP":
break
line = line.rstrip()
key += line
line = fd.readline()
fd.close()
if not line or line[0:12] != "-----END PGP":
raise KeyError(file, "not a pgp public key")
key = ''
line = fd.readline()
while line:
if line[0:12] == "-----END PGP":
break
line = line.rstrip()
key += line
line = fd.readline()
fd.close()
if not line or line[0:12] != "-----END PGP":
raise KeyError(file, "not a pgp public key")
bkey = base64.b64decode(key)
bkey = base64.b64decode(key)
r = self.ts.pgpImportPubkey(bkey)
if r != 0:
raise KeyError(file, "failed to import pubkey")
self.imported[file] = 1
r = self.ts.pgpImportPubkey(bkey)
if r != 0:
raise KeyError(file, "failed to import pubkey")
self.imported[file] = 1
def check(self, pkg):
fd = os.open(pkg, os.O_RDONLY)
hdr = self.ts.hdrFromFdno(fd)
os.close(fd)
def check(self, pkg):
fd = os.open(pkg, os.O_RDONLY)
hdr = self.ts.hdrFromFdno(fd)
os.close(fd)
if __name__ == "__main__":
import sys
keyfiles = []
pkgs = []
for arg in sys.argv[1:]:
if arg[-4:] == '.rpm':
pkgs.append(arg)
else:
keyfiles.append(arg)
checker = Checker()
try:
checker.readkeys(keyfiles)
for pkg in pkgs:
checker.check(pkg)
except Exception, e:
checker.cleanup()
raise e
import sys
keyfiles = []
pkgs = []
for arg in sys.argv[1:]:
if arg[-4:] == '.rpm':
pkgs.append(arg)
else:
keyfiles.append(arg)
checker = Checker()
try:
checker.readkeys(keyfiles)
for pkg in pkgs:
checker.check(pkg)
except Exception, e:
checker.cleanup()
raise e
# vim: sw=4 et

View File

@ -28,11 +28,11 @@ MAN_FOOTER = r"""
Type 'osc help <subcommand>' for more detailed help on a specific subcommand.
.PP
For additional information, see
* http://www.opensuse.org/Build_Service_Tutorial
* http://www.opensuse.org/Build_Service/CLI
* http://en.opensuse.org/Build_Service_Tutorial
* http://en.opensuse.org/Build_Service/CLI
.PP
You can modify osc commands, or roll you own, via the plugin API:
* http://www.opensuse.org/Build_Service/osc_plugins
* http://en.opensuse.org/Build_Service/osc_plugins
.SH AUTHOR
osc was written by several authors. This man page is automatically generated.
"""
@ -48,11 +48,11 @@ class Osc(cmdln.Cmdln):
${help_list}
global ${option_list}
For additional information, see
* http://www.opensuse.org/Build_Service_Tutorial
* http://www.opensuse.org/Build_Service/CLI
* http://en.opensuse.org/Build_Service_Tutorial
* http://en.opensuse.org/Build_Service/CLI
You can modify osc commands, or roll you own, via the plugin API:
* http://www.opensuse.org/Build_Service/osc_plugins
* http://en.opensuse.org/Build_Service/osc_plugins
"""
name = 'osc'
conf = None
@ -393,7 +393,7 @@ class Osc(cmdln.Cmdln):
print "Creating initial patchinfo..."
query='cmd=createpatchinfo'
if args and args[0]:
query += "&name=" + args[0]
query += "&name=" + args[0]
url = makeurl(apiurl, ['source', project], query=query)
f = http_POST(url)
for p in meta_get_packagelist(apiurl, project):
@ -777,8 +777,8 @@ class Osc(cmdln.Cmdln):
for p in pac:
result = create_submit_request(apiurl, project, p)
if not result:
# sys.exit(result)
sys.exit("submit request creation failed")
# sys.exit(result)
sys.exit("submit request creation failed")
sr_ids.append(result)
# create submit requests for all found patchinfos
@ -804,7 +804,7 @@ class Osc(cmdln.Cmdln):
print "Requests created: ",
for i in sr_ids:
print i,
print i,
sys.exit('Successfull finished')
elif len(args) <= 2:
@ -2698,7 +2698,7 @@ Please submit there instead, or use --nodevelproject to force direct submission.
opts.name_filter = None
opts.status_filter = None
opts.vertical = None
self.do_prjresults('prjresults', opts, *args);
self.do_prjresults('prjresults', opts, *args)
sys.exit(0)
else:
project = store_read_project(wd)
@ -2819,21 +2819,21 @@ Please submit there instead, or use --nodevelproject to force direct submission.
def print_repos(self):
wd = os.curdir
doprint = False
if is_package_dir(wd):
str = "package"
doprint = True
elif is_project_dir(wd):
str = "project"
doprint = True
wd = os.curdir
doprint = False
if is_package_dir(wd):
str = "package"
doprint = True
elif is_project_dir(wd):
str = "project"
doprint = True
if doprint:
print 'Valid arguments for this %s are:' % str
print
self.do_repos(None, None)
print
raise oscerr.WrongArgs('Missing arguments')
if doprint:
print 'Valid arguments for this %s are:' % str
print
self.do_repos(None, None)
print
raise oscerr.WrongArgs('Missing arguments')
@cmdln.alias('rbl')
@cmdln.alias('rbuildlog')
@ -2960,9 +2960,9 @@ Please submit there instead, or use --nodevelproject to force direct submission.
if len(args) == 2: # 2
if is_package_dir('.'):
package = store_read_package(wd)
package = store_read_package(wd)
else:
raise oscerr.WrongArgs('package is not specified.')
raise oscerr.WrongArgs('package is not specified.')
project = store_read_project(wd)
apiurl = store_read_apiurl(wd)
repository = args[0]
@ -2982,9 +2982,9 @@ Please submit there instead, or use --nodevelproject to force direct submission.
reason = root.find('explain').text
print reason
if reason == "meta change":
print "changed keys:"
for package in root.findall('packagechange'):
print " ", package.get('change'), package.get('key')
print "changed keys:"
for package in root.findall('packagechange'):
print " ", package.get('change'), package.get('key')
# FIXME: the new osc syntax should allow to specify multiple packages
@ -3028,9 +3028,9 @@ Please submit there instead, or use --nodevelproject to force direct submission.
if len(args) < 3: # 2
if is_package_dir('.'):
packages = [store_read_package(wd)]
packages = [store_read_package(wd)]
elif not is_project_dir('.'):
raise oscerr.WrongArgs('Project and package is not specified.')
raise oscerr.WrongArgs('Project and package is not specified.')
project = store_read_project(wd)
apiurl = store_read_apiurl(wd)
repository = args[0]
@ -3058,7 +3058,7 @@ Please submit there instead, or use --nodevelproject to force direct submission.
for package in root.findall('package'):
print package.get('name'), ":"
for dep in package.findall('pkgdep'):
print " ", dep.text
print " ", dep.text
@cmdln.option('-x', '--extra-pkgs', metavar='PAC', action='append',

View File

@ -325,12 +325,12 @@ def init_basicauth(config):
import sys
if sys.version_info < (2, 6):
# HTTPS proxy is not supported in old urllib2. It only leads to an error
# or, at best, a warning.
if 'https_proxy' in os.environ:
del os.environ['https_proxy']
if 'HTTPS_PROXY' in os.environ:
del os.environ['HTTPS_PROXY']
# HTTPS proxy is not supported in old urllib2. It only leads to an error
# or, at best, a warning.
if 'https_proxy' in os.environ:
del os.environ['https_proxy']
if 'HTTPS_PROXY' in os.environ:
del os.environ['HTTPS_PROXY']
if config['http_debug']:
# brute force

View File

@ -2139,17 +2139,17 @@ def show_attribute_meta(apiurl, prj, pac, subpac, attribute, with_defaults, with
path.append('source')
path.append(prj)
if pac:
path.append(pac)
path.append(pac)
if pac and subpac:
path.append(subpac)
path.append(subpac)
path.append('_attribute')
if attribute:
path.append(attribute)
path.append(attribute)
query=[]
if with_defaults:
query.append("with_default=1")
query.append("with_default=1")
if with_project:
query.append("with_project=1")
query.append("with_project=1")
url = makeurl(apiurl, path, query)
try:
f = http_GET(url)
@ -2547,10 +2547,10 @@ def create_submit_request(apiurl,
# Yes, this kind of xml construction is horrible
targetxml = ""
if dst_project:
packagexml = ""
if dst_package:
packagexml = """package="%s" """ %( dst_package )
targetxml = """<target project="%s" %s /> """ %( dst_project, packagexml )
packagexml = ""
if dst_package:
packagexml = """package="%s" """ %( dst_package )
targetxml = """<target project="%s" %s /> """ %( dst_project, packagexml )
# XXX: keep the old template for now in order to work with old obs instances
xml = """\
<request type="submit">
@ -3496,7 +3496,9 @@ def get_results(apiurl, prj, package, lastbuild=None, repository=[], arch=[]):
rmap['status'] = ''
if rmap['status'] in ['expansion error', 'broken', 'blocked', 'finished']:
rmap['status'] += ': ' + statusnode.find('details').text
details = statusnode.find('details')
if details != None:
rmap['status'] += ': ' + details.text
if rmap['dirty'] == 'true':
rmap['status'] = 'state is outdated (was: %s)' % rmap['status']

View File

@ -114,9 +114,9 @@ class Fetcher:
pkgq = packagequery.PackageQuery.query(tmpfile, extra_rpmtags=(1044, 1051, 1052))
arch = pkgq.arch()
# SOURCERPM = 1044
if pkgq.filename_suffix == 'rpm' and not pkgq.getTag(1044):
if pkgq.filename_suffix == 'rpm' and not pkgq.gettag(1044):
# NOSOURCE = 1051, NOPATCH = 1052
if pkgq.getTag(1051) or pkgq.getTag(1052):
if pkgq.gettag(1051) or pkgq.gettag(1052):
arch = "nosrc"
else:
arch = "src"

View File

@ -2,6 +2,7 @@
class NoSecureSSLError(Exception):
def __init__(self, msg):
Exception.__init__(self)
self.msg = msg
def __str__(self):
return self.msg

View File

@ -104,7 +104,7 @@ class DebQuery(packagequery.PackageQuery):
def requires(self):
return self.fields['depends']
def getTag(self, num):
def gettag(self, num):
return self.fields.get(num, None)
@staticmethod

View File

@ -13,8 +13,8 @@ class PackageQueries(dict):
# map debian arches to common obs arches
architectureMap = {'i386': ['i586', 'i686'], 'amd64': ['x86_64']}
def __init__(self, wantedArchitecture):
self.wantedArchitecture = wantedArchitecture
def __init__(self, wanted_architecture):
self.wanted_architecture = wanted_architecture
super(PackageQueries, self).__init__()
def add(self, query):
@ -32,13 +32,13 @@ class PackageQueries(dict):
architecture = query.arch()
if (architecture in [self.wantedArchitecture, 'noarch', 'all'] or
self.wantedArchitecture in self.architectureMap.get(architecture,
if (architecture in [self.wanted_architecture, 'noarch', 'all'] or
self.wanted_architecture in self.architectureMap.get(architecture,
[])):
currentQuery = self.get(name)
current_query = self.get(name)
# if current query does not exist or is older than this new query
if currentQuery is None or currentQuery.vercmp(query) <= 0:
if current_query is None or current_query.vercmp(query) <= 0:
super(PackageQueries, self).__setitem__(name, query)
class PackageQuery:
@ -73,10 +73,10 @@ class PackageQuery:
def requires(self):
raise NotImplementedError
def getTag(self):
def gettag(self):
raise NotImplementedError
def vercmp(self, pkgq):
def vercmp(self, pkgquery):
raise NotImplementedError
@staticmethod
@ -85,20 +85,20 @@ class PackageQuery:
magic = f.read(7)
f.seek(0)
extra_tags = ()
pkgq = None
pkgquery = None
if magic[:4] == '\xed\xab\xee\xdb':
import rpmquery
pkgq = rpmquery.RpmQuery(f)
pkgquery = rpmquery.RpmQuery(f)
extra_tags = extra_rpmtags
elif magic == '!<arch>':
import debquery
pkgq = debquery.DebQuery(f)
pkgquery = debquery.DebQuery(f)
extra_tags = extra_debtags
else:
raise PackageError('unsupported package type. magic: \'%s\' (%s)' % (magic, filename))
pkgq.read(all_tags, *extra_tags)
pkgquery.read(all_tags, *extra_tags)
f.close()
return pkgq
return pkgquery
if __name__ == '__main__':
import sys

View File

@ -20,7 +20,7 @@ class RpmHeader:
def append(self, entry):
self.entries.append(entry)
def getTag(self, tag):
def gettag(self, tag):
for i in self.entries:
if i.tag == tag:
return i
@ -131,7 +131,7 @@ class RpmQuery(packagequery.PackageQuery):
entry.data = entry.data[0]
return
# get private i18n table
table = self.header.getTag(100)
table = self.header.gettag(100)
# just care about the country code
lang = lang.split('_', 1)[0]
cnt = 0
@ -147,9 +147,9 @@ class RpmQuery(packagequery.PackageQuery):
raise RpmHeaderError('unsupported tag type \'%d\' (tag: \'%s\'' % (entry.type, entry.tag))
def __reqprov(self, tag, flags, version):
pnames = self.header.getTag(tag).data
pflags = self.header.getTag(flags).data
pvers = self.header.getTag(version).data
pnames = self.header.gettag(tag).data
pflags = self.header.gettag(flags).data
pvers = self.header.gettag(version).data
if not (pnames and pflags and pvers):
raise RpmError('cannot get provides/requires, tags are missing')
res = []
@ -179,31 +179,31 @@ class RpmQuery(packagequery.PackageQuery):
# XXX: create dict for the tag => number mapping?!
def name(self):
return self.header.getTag(1000).data
return self.header.gettag(1000).data
def version(self):
return self.header.getTag(1001).data
return self.header.gettag(1001).data
def release(self):
return self.header.getTag(1002).data
return self.header.gettag(1002).data
def epoch(self):
epoch = self.header.getTag(1003)
epoch = self.header.gettag(1003)
if epoch is None:
return 0
return epoch.data[0]
def arch(self):
return self.header.getTag(1022).data
return self.header.gettag(1022).data
def summary(self):
return self.header.getTag(1004).data
return self.header.gettag(1004).data
def description(self):
return self.header.getTag(1005).data
return self.header.gettag(1005).data
def url(self):
entry = self.header.getTag(1020)
entry = self.header.gettag(1020)
if entry is None:
return None
return entry.data
@ -217,8 +217,8 @@ class RpmQuery(packagequery.PackageQuery):
def requires(self):
return self.__reqprov(1049, 1048, 1050)
def getTag(self, num):
return self.header.getTag(num)
def gettag(self, num):
return self.header.gettag(num)
@staticmethod
def query(filename):