From 2ffd46a9c2dc15c7f7c7602a2b16b87a6e4f5563 Mon Sep 17 00:00:00 2001 From: Marcus Huewe Date: Mon, 30 Aug 2010 13:46:49 +0200 Subject: [PATCH] - get rid of the init_package_dir mess moved code into the staticmethod "init_package" of the Package class. Cleaned up "checkout_package" --- osc/commandline.py | 12 ++-- osc/core.py | 91 ++++++++++---------------- tests/common.py | 8 +-- tests/init_package_fixtures/oscrc | 104 ++++++++++++++++++++++++++++++ tests/suite.py | 2 + tests/test_init_package.py | 81 +++++++++++++++++++++++ 6 files changed, 228 insertions(+), 70 deletions(-) create mode 100644 tests/init_package_fixtures/oscrc create mode 100644 tests/test_init_package.py diff --git a/osc/commandline.py b/osc/commandline.py index a9fd33cf..cd18f7cf 100644 --- a/osc/commandline.py +++ b/osc/commandline.py @@ -189,7 +189,8 @@ class Osc(cmdln.Cmdln): init_project_dir(apiurl, os.curdir, project) print 'Initializing %s (Project: %s)' % (os.curdir, project) else: - init_package_dir(apiurl, project, package, os.path.curdir) + Package.init_package(apiurl, project, package, os.curdir) + store_write_string(os.curdir, '_files', show_files_meta(apiurl, project, package)) print 'Initializing %s (Project: %s, Package: %s)' % (os.curdir, project, package) @cmdln.alias('ls') @@ -5069,9 +5070,7 @@ Please submit there instead, or use --nodevelproject to force direct submission. edit_meta(metatype='pkg', path_args=(quote_plus(project), quote_plus(pac)), data = data, apiurl=apiurl) - os.mkdir(os.path.join(project_dir, pac)) - os.chdir(os.path.join(project_dir, pac)) - init_package_dir(apiurl, project, pac, os.path.join(project, pac)) + Package.init_package(apiurl, project, pac, os.path.join(project, pac)) else: print >>sys.stderr, 'error - local package already exists' sys.exit(1) @@ -5496,10 +5495,7 @@ Please submit there instead, or use --nodevelproject to force direct submission. shutil.rmtree(destdir) os.mkdir(destdir) - olddir=os.getcwd() - os.chdir(destdir) - init_package_dir(apiurl, target_prj, target_package, destdir, files=False) - os.chdir(olddir) + Package.init_package(apiurl, target_prj, target_package, destdir) store_write_string(destdir, '_files', ''.join(meta)) store_write_string(destdir, '_linkrepair', '') pac = Package(destdir) diff --git a/osc/core.py b/osc/core.py index fc14d8cf..1d0f3684 100644 --- a/osc/core.py +++ b/osc/core.py @@ -1845,6 +1845,27 @@ rev: %s self.to_be_added.remove(filename) self.write_addlist() + @staticmethod + def init_package(apiurl, project, package, dir, limit_size=None, meta=False, progress_obj=None): + if not os.path.exists(dir): + os.mkdir(dir) + elif not os.path.isdir(dir): + raise IOError('error: \'%s\' is no directory' % dir) + if os.path.exists(os.path.join(dir, store)): + raise IOError('error: \'%s\' is already an initialized osc working copy' % dir) + else: + os.mkdir(os.path.join(dir, store)) + store_write_project(dir, project) + store_write_string(dir, '_package', package + '\n') + store_write_apiurl(dir, apiurl) + if meta: + store_write_string(dir, '_meta_mode', '') + if limit_size: + store_write_string(dir, '_size_limit', str(limit_size) + '\n') + store_write_string(dir, '_files', '' + '\n') + store_write_string(dir, '_osclib_version', __store_version__ + '\n') + return Package(dir, progress_obj=progress_obj, limit_size=limit_size) + class ReviewState: """for objects to represent the review state in a request""" def __init__(self, state=None, by_user=None, by_group=None, who=None, when=None, comment=None): @@ -2401,33 +2422,6 @@ def init_project_dir(apiurl, dir, project): if conf.config['do_package_tracking']: store_write_initial_packages(dir, project, []) -# XXX: the chdir semantics for this are really broken -# it's expected that we're already in "dir" (which doesn't make sense...) when -# calling this method -def init_package_dir(apiurl, project, package, dir, revision=None, files=True, limit_size=None, meta=False): - if not os.path.isdir(store): - os.mkdir(store) - os.chdir(store) - store_write_string(os.pardir, '_project', project) - store_write_string(os.pardir, '_package', package) - - if meta: - store_write_string(os.pardir, '_meta_mode', '') - - if limit_size: - store_write_string(os.pardir, '_size_limit', str(limit_size)) - - if files: - fmeta = ''.join(show_files_meta(apiurl, project, package, revision=revision, limit_size=limit_size, meta=meta)) - store_write_string(os.pardir, '_files', fmeta) - else: - # create dummy - ET.ElementTree(element=ET.Element('directory')).write('_files') - - store_write_string(os.pardir, '_osclib_version', __store_version__ + '\n') - store_write_apiurl(os.pardir, apiurl) - os.chdir(os.pardir) - def check_store_version(dir): versionfile = os.path.join(dir, store, '_osclib_version') try: @@ -3454,9 +3448,9 @@ def make_dir(apiurl, project, package, pathname=None, prj_dir=None): if not os.path.exists(os.path.join(prj_dir, package)): print statfrmt('A', pathname) os.mkdir(os.path.join(prj_dir, package)) - os.mkdir(os.path.join(prj_dir, package, store)) +# os.mkdir(os.path.join(prj_dir, package, store)) - return(os.path.join(prj_dir, package)) + return os.path.join(prj_dir, package) def checkout_package(apiurl, project, package, @@ -3485,7 +3479,7 @@ def checkout_package(apiurl, project, package, # exists show_package_meta(apiurl, project, package, meta) - isfrozen = 0 + isfrozen = False if expand_link: # try to read from the linkinfo # if it is a link we use the xsrcmd5 as the revision to be @@ -3495,34 +3489,23 @@ def checkout_package(apiurl, project, package, except: x = show_upstream_xsrcmd5(apiurl, project, package, revision=revision, meta=meta, linkrev='base') if x: - isfrozen = 1 + isfrozen = True if x: revision = x - directory = os.path.abspath(make_dir(apiurl, project, package, pathname, prj_dir)) - os.chdir(directory) - init_package_dir(apiurl, project, package, directory, revision, limit_size=limit_size, meta=meta) - os.chdir(os.pardir) - p = Package(directory, progress_obj=progress_obj) + directory = make_dir(apiurl, project, package, pathname, prj_dir) + p = Package.init_package(apiurl, project, package, directory, limit_size, meta, progress_obj) if isfrozen: p.mark_frozen() - for filename in p.filenamelist: - if filename in p.skipped: - continue - if server_service_files or not filename.startswith('_service:'): - p.updatefile(filename, revision) - # print 'A ', os.path.join(project, package, filename) - print statfrmt('A', os.path.join(pathname, filename)) if conf.config['do_package_tracking']: # check if we can re-use an existing project object - if prj_obj == None: - prj_obj = Project(os.getcwd()) + if prj_obj is None: + prj_obj = Project(prj_dir) prj_obj.set_state(p.name, ' ') prj_obj.write_packages() + p.update(revision, server_service_files, limit_size) if service_files: - print "Running local source services" + print 'Running local source services' p.run_source_services() - os.chdir(olddir) - def replace_pkg_meta(pkgmeta, new_name, new_prj, keep_maintainers = False, dst_userid = None, keep_develproject = False): @@ -4921,12 +4904,7 @@ def createPackageDir(pathname, prj_obj=None): if not os.path.exists(pac_dir): prj = prj_obj or Project(prj_dir, False) prj.addPackage(pac_dir) - os.mkdir(pathname) - os.chdir(pathname) - init_package_dir(prj.apiurl, - prj.name, - pac_dir, pac_dir, files=False) - os.chdir(prj.absdir) + Package.init_package(prj.apiurl, prj.name, pac_dir, pac_dir) print statfrmt('A', os.path.normpath(pathname)) else: raise oscerr.OscIOError(None, 'file or directory \'%s\' already exists' % pathname) @@ -4998,12 +4976,9 @@ def addFiles(filenames, prj_obj = None): prj_dir, pac_dir = getPrjPacPaths(filename) if not is_package_dir(filename) and os.path.isdir(filename) and is_project_dir(prj_dir) \ and conf.config['do_package_tracking']: - old_dir = os.getcwd() prj_name = store_read_project(prj_dir) prj_apiurl = store_read_apiurl(prj_dir) - os.chdir(filename) - init_package_dir(prj_apiurl, prj_name, pac_dir, pac_dir, files=False) - os.chdir(old_dir) + Package.init_package(prj_apiurl, prj_name, pac_dir, pac_dir) elif is_package_dir(filename) and conf.config['do_package_tracking']: raise oscerr.PackageExists(store_read_project(filename), store_read_package(filename), 'osc: warning: \'%s\' is already under version control' % filename) diff --git a/tests/common.py b/tests/common.py index a955a91e..5c18a3b4 100644 --- a/tests/common.py +++ b/tests/common.py @@ -89,19 +89,19 @@ class OscTestCase(unittest.TestCase): def _change_to_pkg(self, name): os.chdir(os.path.join(self.tmpdir, 'osctest', name)) - def __check_list(self, fname, exp): + def _check_list(self, fname, exp): fname = os.path.join('.osc', fname) self.assertTrue(os.path.exists(fname)) self.assertEqual(open(fname, 'r').read(), exp) def _check_addlist(self, exp): - self.__check_list('_to_be_added', exp) + self._check_list('_to_be_added', exp) def _check_deletelist(self, exp): - self.__check_list('_to_be_deleted', exp) + self._check_list('_to_be_deleted', exp) def _check_conflictlist(self, exp): - self.__check_list('_in_conflict', exp) + self._check_list('_in_conflict', exp) def _check_status(self, p, fname, exp): self.assertEqual(p.status(fname), exp) diff --git a/tests/init_package_fixtures/oscrc b/tests/init_package_fixtures/oscrc new file mode 100644 index 00000000..04b2b0ab --- /dev/null +++ b/tests/init_package_fixtures/oscrc @@ -0,0 +1,104 @@ +[general] +# URL to access API server, e.g. https://api.opensuse.org +# you also need a section [https://api.opensuse.org] with the credentials +apiurl = http://localhost +# Downloaded packages are cached here. Must be writable by you. +#packagecachedir = /var/tmp/osbuild-packagecache +# Wrapper to call build as root (sudo, su -, ...) +#su-wrapper = su -c +# rootdir to setup the chroot environment +# can contain %(repo)s, %(arch)s, %(project)s and %(package)s for replacement, e.g. +# /srv/oscbuild/%(repo)s-%(arch)s or +# /srv/oscbuild/%(repo)s-%(arch)s-%(project)s-%(package)s +#build-root = /var/tmp/build-root +# compile with N jobs (default: "getconf _NPROCESSORS_ONLN") +#build-jobs = N +# build-type to use - values can be (depending on the capabilities of the 'build' script) +# empty - chroot build +# kvm - kvm VM build (needs build-device, build-swap, build-memory) +# xen - xen VM build (needs build-device, build-swap, build-memory) +# experimental: +# qemu - qemu VM build +# lxc - lxc build +#build-type = +# build-device is the disk-image file to use as root for VM builds +# e.g. /var/tmp/FILE.root +#build-device = /var/tmp/FILE.root +# build-swap is the disk-image to use as swap for VM builds +# e.g. /var/tmp/FILE.swap +#build-swap = /var/tmp/FILE.swap +# build-memory is the amount of memory used in the VM +# value in MB - e.g. 512 +#build-memory = 512 +# build-vmdisk-rootsize is the size of the disk-image used as root in a VM build +# values in MB - e.g. 4096 +#build-vmdisk-rootsize = 4096 +# build-vmdisk-swapsize is the size of the disk-image used as swap in a VM build +# values in MB - e.g. 1024 +#build-vmdisk-swapsize = 1024 +# Numeric uid:gid to assign to the "abuild" user in the build-root +# or "caller" to use the current users uid:gid +# This is convenient when sharing the buildroot with ordinary userids +# on the host. +# This should not be 0 +# build-uid = +# extra packages to install when building packages locally (osc build) +# this corresponds to osc build's -x option and can be overridden with that +# -x '' can also be given on the command line to override this setting, or +# you can have an empty setting here. +#extra-pkgs = vim gdb strace +# build platform is used if the platform argument is omitted to osc build +#build_repository = openSUSE_Factory +# default project for getpac or bco +#getpac_default_project = openSUSE:Factory +# alternate filesystem layout: have multiple subdirs, where colons were. +#checkout_no_colon = 0 +# local files to ignore with status, addremove, .... +#exclude_glob = .osc CVS .svn .* _linkerror *~ #*# *.orig *.bak *.changes.* +# keep passwords in plaintext. If you see this comment, your osc +# already uses the encrypted password, and only keeps them in plain text +# for backwards compatibility. Default will change to 0 in future releases. +# You can remove the plaintext password without harm, if you do not need +# backwards compatibility. +#plaintext_passwd = 1 +# limit the age of requests shown with 'osc req list'. +# this is a default only, can be overridden by 'osc req list -D NNN' +# Use 0 for unlimted. +#request_list_days = 0 +# show info useful for debugging +#debug = 1 +# show HTTP traffic useful for debugging +#http_debug = 1 +# Skip signature verification of packages used for build. +#no_verify = 1 +# jump into the debugger in case of errors +#post_mortem = 1 +# print call traces in case of errors +#traceback = 1 +# use KDE/Gnome/MacOS/Windows keyring for credentials if available +#use_keyring = 1 +# check for unversioned/removed files before commit +#check_filelist = 1 +# check for pending requests after executing an action (e.g. checkout, update, commit) +#check_for_request_on_action = 0 +# what to do with the source package if the submitrequest has been accepted. If +# nothing is specified the API default is used +#submitrequest_on_accept_action = cleanup|update|noupdate +#review requests interactively (default: off) +#request_show_review = 1 +# Directory with executables to validate sources, esp before committing +#source_validator_directory = /usr/lib/osc/source_validators + +[http://localhost] +user = Admin +pass = opensuse +passx = QlpoOTFBWSZTWeTSblkAAAGBgAIBygAgADDACGNEHxaYXckU4UJDk0m5ZA== +# set aliases for this apiurl +# aliases = foo, bar +# email used in .changes, unless the one from osc meta prj will be used +# email = +# additional headers to pass to a request, e.g. for special authentication +#http_headers = Host: foofoobar, +# User: mumblegack +# Force using of keyring for this API +#keyring = 1 diff --git a/tests/suite.py b/tests/suite.py index b7ded1ec..866f1f85 100644 --- a/tests/suite.py +++ b/tests/suite.py @@ -4,6 +4,7 @@ import test_addfiles import test_deletefiles import test_revertfiles import test_difffiles +import test_init_package suite = unittest.TestSuite() suite.addTests(test_addfiles.suite()) @@ -11,4 +12,5 @@ suite.addTests(test_deletefiles.suite()) suite.addTests(test_revertfiles.suite()) suite.addTests(test_update.suite()) suite.addTests(test_difffiles.suite()) +suite.addTests(test_init_package.suite()) unittest.TextTestRunner(verbosity=1).run(suite) diff --git a/tests/test_init_package.py b/tests/test_init_package.py new file mode 100644 index 00000000..8f376070 --- /dev/null +++ b/tests/test_init_package.py @@ -0,0 +1,81 @@ +import osc.core +import osc.oscerr +import os +import sys +from common import GET, OscTestCase +FIXTURES_DIR = os.path.join(os.getcwd(), 'init_package_fixtures') + +def suite(): + import unittest + return unittest.makeSuite(TestInitPackage) + +class TestInitPackage(OscTestCase): + def _get_fixtures_dir(self): + return FIXTURES_DIR + + def test_simple(self): + """initialize a package dir""" + pac_dir = os.path.join(self.tmpdir, 'testpkg') + osc.core.Package.init_package('http://localhost', 'osctest', 'testpkg', pac_dir) + storedir = os.path.join(pac_dir, osc.core.store) + self.assertFalse(os.path.exists(os.path.join(storedir, '_meta_mode'))) + self.assertFalse(os.path.exists(os.path.join(storedir, '_size_limit'))) + self._check_list(os.path.join(storedir, '_project'), 'osctest\n') + self._check_list(os.path.join(storedir, '_package'), 'testpkg\n') + self._check_list(os.path.join(storedir, '_files'), '\n') + self._check_list(os.path.join(storedir, '_apiurl'), 'http://localhost\n') + + def test_limit_size(self): + """initialize a package dir with limit_size parameter""" + pac_dir = os.path.join(self.tmpdir, 'testpkg') + osc.core.Package.init_package('http://localhost', 'osctest', 'testpkg', pac_dir, limit_size=42) + storedir = os.path.join(pac_dir, osc.core.store) + self.assertFalse(os.path.exists(os.path.join(storedir, '_meta_mode'))) + self._check_list(os.path.join(storedir, '_size_limit'), '42\n') + self._check_list(os.path.join(storedir, '_project'), 'osctest\n') + self._check_list(os.path.join(storedir, '_package'), 'testpkg\n') + self._check_list(os.path.join(storedir, '_files'), '\n') + self._check_list(os.path.join(storedir, '_apiurl'), 'http://localhost\n') + + def test_meta_mode(self): + """initialize a package dir with meta paramter""" + pac_dir = os.path.join(self.tmpdir, 'testpkg') + osc.core.Package.init_package('http://localhost', 'osctest', 'testpkg', pac_dir, meta=True) + storedir = os.path.join(pac_dir, osc.core.store) + self.assertFalse(os.path.exists(os.path.join(storedir, '_size_limit'))) + self._check_list(os.path.join(storedir, '_meta_mode'), '') + self._check_list(os.path.join(storedir, '_project'), 'osctest\n') + self._check_list(os.path.join(storedir, '_package'), 'testpkg\n') + self._check_list(os.path.join(storedir, '_files'), '\n') + self._check_list(os.path.join(storedir, '_apiurl'), 'http://localhost\n') + + def test_dirExists(self): + """initialize a package dir (dir already exists)""" + pac_dir = os.path.join(self.tmpdir, 'testpkg') + os.mkdir(pac_dir) + osc.core.Package.init_package('http://localhost', 'osctest', 'testpkg', pac_dir) + storedir = os.path.join(pac_dir, osc.core.store) + self.assertFalse(os.path.exists(os.path.join(storedir, '_meta_mode'))) + self.assertFalse(os.path.exists(os.path.join(storedir, '_size_limit'))) + self._check_list(os.path.join(storedir, '_project'), 'osctest\n') + self._check_list(os.path.join(storedir, '_package'), 'testpkg\n') + self._check_list(os.path.join(storedir, '_files'), '\n') + self._check_list(os.path.join(storedir, '_apiurl'), 'http://localhost\n') + + def test_storedirExists(self): + """initialize a package dir (dir+storedir already exists)""" + pac_dir = os.path.join(self.tmpdir, 'testpkg') + os.mkdir(pac_dir) + os.mkdir(os.path.join(pac_dir, osc.core.store)) + self.assertRaises(IOError, osc.core.Package.init_package, 'http://localhost', 'osctest', 'testpkg', pac_dir) + + def test_dirIsFile(self): + """initialize a package dir (dir is a file)""" + pac_dir = os.path.join(self.tmpdir, 'testpkg') + os.mkdir(pac_dir) + open(os.path.join(pac_dir, osc.core.store), 'w').write('foo\n') + self.assertRaises(IOError, osc.core.Package.init_package, 'http://localhost', 'osctest', 'testpkg', pac_dir) + +if __name__ == '__main__': + import unittest + unittest.main()