Mailinglist Archive: opensuse-commit (2092 mails)

< Previous Next >
commit osc
  • From: root@xxxxxxxxxxxxxxx (h_root)
  • Date: Thu, 09 Aug 2007 20:43:11 +0200
  • Message-id: <20070809184311.B9EA767832C@xxxxxxxxxxxxxxx>

Hello community,

here is the log from the commit of package osc
checked in at Thu Aug 9 20:43:11 CEST 2007.

--------
--- osc/osc.changes     2007-07-18 15:22:59.000000000 +0200
+++ /mounts/work_src_done/STABLE/osc/osc.changes        2007-08-09 00:55:04.000000000 +0200
@@ -1,0 +2,45 @@
+Thu Aug  9 00:54:21 CEST 2007 - poeml@xxxxxxx
+
+- update to r1947:
+  - commit: fixed possible "UnboundLocalError" with -m. Thanks to
+    judas_iscariote for spotting this issue, and Marcus for fixing
+    it.
+
+-------------------------------------------------------------------
+Wed Aug  8 20:49:24 CEST 2007 - poeml@xxxxxxx
+
+- update to r1946:
+  - avoid warning/error with unsupported HTTPS_PROXY [#214983][#298378]
+  - importsrcpkg:
+    * changed default behaviour - the files will not be committed by
+      default. To commit them use the --commit switch.
+    * added --delete-old-files option switch to delete old files from
+      the server.
+    * allow to import source rpms by specifying an URL
+    * use rpm-python
+  - fix for "osc prjconf <project> -e".
+  - add Recommends: rpm-python
+
+-------------------------------------------------------------------
+Wed Jul 25 13:04:37 CEST 2007 - poeml@xxxxxxx
+
+- update to r1884:
+  - added new importfromsrcpkg command, to import a package src.rpm
+    (we owe this to Marcus)
+  - added new req command, to issue arbitrary requests to the API
+  - append missing newline if do_commits=False [#293672]
+  - make delete_package() and delete_project() more userfriendly
+    (added trivial exception handling..)
+  - expand ~ to users home for packagecachedir in .oscrc [#293675]
+
+-------------------------------------------------------------------
+Thu Jul 19 14:28:51 CEST 2007 - poeml@xxxxxxx
+
+- update to r1871:
+  - meta: allow for editing patterns
+  - small fixes:
+    - fix error message which osc issues if build package is too old
+    - results: result code can be empty when package has just been created
+    - fix name of 10.2 product in the template for new projects
+
+-------------------------------------------------------------------

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ osc.spec ++++++
--- /var/tmp/diff_new_pack.p25263/_old  2007-08-09 20:42:15.000000000 +0200
+++ /var/tmp/diff_new_pack.p25263/_new  2007-08-09 20:42:15.000000000 +0200
@@ -13,7 +13,7 @@
 Name:           osc
 BuildRequires:  python-devel
 Version:        0.97
-Release:        4
+Release:        13
 Group:          Development/Tools/Other
 License:        GPL v2 or later
 BuildRoot:      %{_tmppath}/%{name}-%{version}-build
@@ -29,6 +29,9 @@
 %else
 Requires:       python-xml
 %endif
+%if %suse_version > 1000
+Recommends:     rpm-python
+%endif
 %endif
 #
 %if 0%{?fedora_version}
@@ -75,6 +78,39 @@
 %doc README TODO NEWS
 
 %changelog
+* Thu Aug 09 2007 - poeml@xxxxxxx
+- update to r1947:
+  - commit: fixed possible "UnboundLocalError" with -m. Thanks to
+  judas_iscariote for spotting this issue, and Marcus for fixing
+  it.
+* Wed Aug 08 2007 - poeml@xxxxxxx
+- update to r1946:
+  - avoid warning/error with unsupported HTTPS_PROXY [#214983][#298378]
+  - importsrcpkg:
+  * changed default behaviour - the files will not be committed by
+  default. To commit them use the --commit switch.
+  * added --delete-old-files option switch to delete old files from
+  the server.
+  * allow to import source rpms by specifying an URL
+  * use rpm-python
+  - fix for "osc prjconf <project> -e".
+  - add Recommends: rpm-python
+* Wed Jul 25 2007 - poeml@xxxxxxx
+- update to r1884:
+  - added new importfromsrcpkg command, to import a package src.rpm
+  (we owe this to Marcus)
+  - added new req command, to issue arbitrary requests to the API
+  - append missing newline if do_commits=False [#293672]
+  - make delete_package() and delete_project() more userfriendly
+  (added trivial exception handling..)
+  - expand ~ to users home for packagecachedir in .oscrc [#293675]
+* Thu Jul 19 2007 - poeml@xxxxxxx
+- update to r1871:
+  - meta: allow for editing patterns
+  - small fixes:
+    - fix error message which osc issues if build package is too old
+    - results: result code can be empty when package has just been created
+    - fix name of 10.2 product in the template for new projects
 * Wed Jul 18 2007 - poeml@xxxxxxx
 - update to r1861:
   - commit (using the currently documented way):

++++++ debian.changelog ++++++
--- osc/debian.changelog        2007-07-18 15:24:27.000000000 +0200
+++ /mounts/work_src_done/STABLE/osc/debian.changelog   2007-08-09 00:55:39.000000000 +0200
@@ -1,3 +1,51 @@
+osc (0.97-7) unstable; urgency=high
+
+  * update to r1947:
+    - commit: fixed possible "UnboundLocalError" with -m. Thanks to 
+      judas_iscariote for spotting this issue, and Marcus for fixing
+      it.
+
+ -- Peter Poeml <poeml@xxxxxxx>  Thu,  9 Aug  2007 00:00:00 +0200
+
+osc (0.97-6) unstable; urgency=high
+
+  * update to r1946:
+    - avoid warning/error with unsupported HTTPS_PROXY [#214983][#298378]
+    - importsrcpkg:
+      * changed default behaviour - the files will not be committed by
+        default. To commit them use the --commit switch.
+      * added --delete-old-files option switch to delete old files from
+        the server.
+      * allow to import source rpms by specifying an URL
+      * use rpm-python
+    - fix for "osc prjconf <project> -e".
+
+ -- Peter Poeml <poeml@xxxxxxx>  Wed,  8 Aug  2007 00:00:00 +0200
+
+osc (0.97-5) unstable; urgency=high
+
+  * update to r1884:
+    - added new importfromsrcpkg command, to import a package src.rpm
+      (we owe this to Marcus)
+    - added new req command, to issue arbitrary requests to the API
+    - append missing newline if do_commits=False [#293672]
+    - make delete_package() and delete_project() more userfriendly
+      (added trivial exception handling..)
+    - expand ~ to users home for packagecachedir in .oscrc [#293675]
+
+ -- Peter Poeml <poeml@xxxxxxx>  Wed, 25 Jul  2007 00:00:00 +0200
+
+osc (0.97-4) unstable; urgency=high
+
+  * update to r1811:
+    - meta: allow for editing patterns
+    - small fixes:
+      - fix error message which osc issues if build package is too old
+      - results: result code can be empty when package has just been created
+      - fix name of 10.2 product in the template for new projects
+
+ -- Peter Poeml <poeml@xxxxxxx>  Thu, 19 Jul  2007 00:00:00 +0200
+
 osc (0.97-3) unstable; urgency=high
 
   * update to r1861:

++++++ osc-0.97.tar.gz ++++++
diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/osc-0.97/NEWS new/osc-0.97/NEWS
--- old/osc-0.97/NEWS   2007-07-16 19:30:48.000000000 +0200
+++ new/osc-0.97/NEWS   2007-07-23 11:28:15.000000000 +0200
@@ -3,6 +3,7 @@
 - added initial search support
 - new meta command, replacing editmeta, editprj, createprj,
   editpac, createpac, edituser
+- allow editing patterns (osc meta pattern -e) 
 - show helpful xml error messages if broken metadata is uploaded
 - implementing a log command to review the commit log
 - renamed previous "log" command to "buildlog" (short: bl)
diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/osc-0.97/osc/commandline.py new/osc-0.97/osc/commandline.py
--- old/osc-0.97/osc/commandline.py     2007-07-18 15:20:59.000000000 +0200
+++ new/osc-0.97/osc/commandline.py     2007-08-08 21:48:38.000000000 +0200
@@ -137,10 +137,12 @@
                         '\'-\' denotes standard input. ')
     @cmdln.option('-e', '--edit', action='store_true',
                         help='edit metadata')
+    @cmdln.option('--delete', action='store_true',
+                        help='delete a pattern file')
     def do_meta(self, subcmd, opts, *args):
         """${cmd_name}: Show meta information, or edit it
 
-        Show or edit build service metadata of type <prj|pkg|prjconf|user>.
+        Show or edit build service metadata of type <prj|pkg|prjconf|user|pattern>.
 
         This command displays metadata on buildservice objects like projects,
         packages, or users. The type of metadata is specified by the word after
@@ -150,6 +152,10 @@
         prjconf denotes the (build) configuration of a project.
         pkg denotes metadata of a buildservice package.
         user denotes the metadata of a user.
+        pattern denotes installation patterns defined for a project.
+
+        To list patterns, use 'osc meta pattern PRJ'. An additional argument
+        will be the pattern file to view or edit.
 
         With the --edit switch, the metadata can be edited. Per default, osc
         opens the program specified by the environmental variable EDITOR with a
@@ -162,9 +168,10 @@
         while it is edited.
 
         usage:
-            osc meta <prj|pkg|prjconf|user> ARGS...
-            osc meta <prj|pkg|prjconf|user> -e|--edit [-c|--create] ARGS...
-            osc meta <prj|pkg|prjconf|user> -F|--file ARGS...
+            osc meta <prj|pkg|prjconf|user|pattern> ARGS...
+            osc meta <prj|pkg|prjconf|user|pattern> -e|--edit [-c|--create] ARGS...
+            osc meta <prj|pkg|prjconf|user|pattern> -F|--file ARGS...
+            osc meta pattern --delete PRJ PATTERN
         ${cmd_option_list}
         """
 
@@ -177,14 +184,16 @@
         cmd = args[0]
         del args[0]
 
-        if cmd == 'pkg':
-            required_args = 2
+        if cmd in ['pkg']:
+            min_args, max_args = 2, 2
+        elif cmd in ['pattern']:
+            min_args, max_args = 1, 2
         else:
-            required_args = 1
-        if len(args) < required_args:
+            min_args, max_args = 1, 1
+        if len(args) < min_args:
             print >>sys.stderr, 'Too few arguments.'
             return 2
-        if len(args) > required_args:
+        if len(args) > max_args:
             print >>sys.stderr, 'Too many arguments.'
             return 2
 
@@ -197,9 +206,18 @@
             project = args[0]
         elif cmd == 'user':
             user = args[0]
+        elif cmd == 'pattern':
+            project = args[0]
+            if len(args) > 1:
+                pattern = args[1]
+            else:
+                pattern = None
+                # enforce pattern argument if needed
+                if opts.edit or opts.file:
+                    sys.exit('a pattern file argument is required.')
 
         # show 
-        if not opts.edit:
+        if not opts.edit and not opts.file and not opts.delete:
             if cmd == 'prj':
                 sys.stdout.write(''.join(show_project_meta(conf.config['apiurl'], project)))
             elif cmd == 'pkg':
@@ -210,6 +228,15 @@
                 r = get_user_meta(conf.config['apiurl'], user)
                 if r:
                     sys.stdout.write(''.join(r))
+            elif cmd == 'pattern':
+                if pattern:
+                    r = show_pattern_meta(conf.config['apiurl'], project, pattern)
+                    if r:
+                        sys.stdout.write(''.join(r))
+                else:
+                    r = show_pattern_metalist(conf.config['apiurl'], project)
+                    if r:
+                        sys.stdout.write('\n'.join(r) + '\n')
 
         # edit
         if opts.edit and not opts.file:
@@ -233,6 +260,11 @@
                           edit=True,
                           path_args=(quote_plus(user)),
                           template_args=(user, user))
+            elif cmd == 'pattern':
+                edit_meta(metatype='pattern', 
+                          edit=True,
+                          path_args=(project, pattern),
+                          template_args=None)
 
         # upload file
         if opts.file:
@@ -265,6 +297,21 @@
                           data=f,
                           edit=opts.edit,
                           path_args=(quote_plus(user)))
+            elif cmd == 'pattern':
+                edit_meta(metatype='pattern', 
+                          data=f,
+                          edit=opts.edit,
+                          path_args=(project, pattern))
+
+
+        # delete
+        if opts.delete:
+            path = metatypes[cmd]['path']
+            if cmd == 'pattern':
+                path = path % (project, pattern)
+                u = makeurl(conf.config['apiurl'], [path])
+            else:
+                sys.exit('The --delete switch is only for pattern metadata.')
 
 
 
@@ -404,7 +451,7 @@
 
 
     def do_deletepac(self, subcmd, opts, project, package):
-        """${cmd_name}: Delete a packge on the repository server
+        """${cmd_name}: Delete a package on the repository server
 
         ${cmd_usage}
         ${cmd_option_list}
@@ -729,7 +776,6 @@
             osc add FILE [FILE...]
         ${cmd_option_list}
         """
-
         if not args:
             print >>sys.stderr, 'Missing argument.'
             self.do_help([None, 'add'])
@@ -822,7 +868,7 @@
             conf.config['do_commits'] = True
 
         for p in pacs:
-
+            msg = ''
             if conf.config['do_commits']:
                 if opts.message:
                     msg = opts.message
@@ -831,48 +877,7 @@
                         msg = open(opts.file).read()
                     except:
                         sys.exit('could not open file \'%s\'.' % opts.file)
-                else:
-                    msg = ''
-
-            # commit only if the upstream revision is the same as the working copy's
-            upstream_rev = show_upstream_rev(p.apiurl, p.prjname, p.name)
-            if p.rev != upstream_rev:
-                print >>sys.stderr, 'Working copy \'%s\' is out of date (rev %s vs rev %s).' \
-                    % (p.absdir, p.rev, upstream_rev)
-                print >>sys.stderr, 'Looks as if you need to update it first.'
-                return 1
-
-            if not p.todo:
-                p.todo = p.filenamelist_unvers + p.filenamelist
-
-            for filename in p.todo:
-                st = p.status(filename)
-                if st == 'A' or st == 'M':
-                    p.todo_send.append(filename)
-                    print 'Sending        %s' % filename
-                elif st == 'D':
-                    p.todo_delete.append(filename)
-                    print 'Deleting       %s' % filename
-
-            if not p.todo_send and not p.todo_delete:
-                print 'nothing to do for package %s' % p.name
-                continue
-
-            print 'Transmitting file data ', 
-            for filename in p.todo_delete:
-                p.delete_source_file(filename)
-                p.to_be_deleted.remove(filename)
-            for filename in p.todo_send:
-                sys.stdout.write('.')
-                sys.stdout.flush()
-                p.put_source_file(filename)
-            if conf.config['do_commits']:
-                p.rev = p.commit(msg=msg)
-                print
-                print 'Committed revision %s.' % p.rev
-
-            p.update_local_filesmeta()
-            p.write_deletelist()
+            p.commit(msg)
 
 
     @cmdln.option('-r', '--revision', metavar='rev',
@@ -1331,7 +1336,7 @@
         import osc.build
 
         if not os.path.exists('/usr/lib/build/debtransform'):
-            sys.stderr.write('Error: you need build.rpm with version 2006.6.14 or newer.\n')
+            sys.stderr.write('Error: you need build.rpm with version 2007.3.12 or newer.\n')
             sys.stderr.write('See http://download.opensuse.org/repositories/openSUSE:/Tools/\n')
             return 1
 
@@ -1609,6 +1614,189 @@
             else:
                print 'No matches found for \'%s\' in %ss' % (args[0], kind)
 
+
+    @cmdln.option('-p', '--project', metavar='project',
+                        help='specify a project name')
+    @cmdln.option('-n', '--name', metavar='name',
+                        help='specify a package name')
+    @cmdln.option('-t', '--title', metavar='title',
+                        help='set a title')
+    @cmdln.option('-d', '--description', metavar='description',
+                        help='set the description of the package')
+    @cmdln.option('',   '--delete-old-files', action='store_true',
+                        help='delete existing files from the server')
+    @cmdln.option('-c',   '--commit', action='store_true',
+                        help='commit the new files')
+    def do_importsrcpkg(self, subcmd, opts, srpm):
+        """${cmd_name}: import a new package from a src.rpm
+
+        A new package dir will be created inside the project dir
+        (if no project is specified and the current working dir is a
+        project dir the package will be created in this project). If
+        the package does not exist on the server it will be created
+        too otherwise the meta data of the existing package will be
+        updated (<title /> and <description />).
+        The src.rpm will be extracted into the package dir. If the
+        --disable-commit switch is not used all changes will be
+        committed.
+
+        SRPM is the path of the src.rpm in the local filesystem,
+        or an URL.
+
+        ${cmd_usage}
+        ${cmd_option_list}
+        """
+        import glob
+
+        if '://' in srpm:
+            print 'trying to fetch', srpm
+            import urlgrabber
+            urlgrabber.urlgrab(srpm)
+            srpm = os.path.basename(srpm)
+
+        srpm = os.path.abspath(srpm)
+
+        if opts.project:
+            project_dir = opts.project
+        else:
+            project_dir = os.getcwd()
+
+        if not is_project_dir(project_dir):
+            print >>sys.stderr, 'project dir \'%s\' does not exist' % project
+            sys.exit(1)
+        else:
+            project = store_read_project(project_dir)
+
+        rpm_data = data_from_rpm(srpm, 'Name:', 'Summary:', '%description')
+        if rpm_data:
+            title, pac, descr = ( v for k, v in rpm_data.iteritems() )
+        else:
+            title = pac = descr = ''
+
+        if opts.title:
+            title = opts.title
+        if opts.name:
+            pac = opts.name
+        if opts.description:
+            descr = opts.description
+        
+        # title and description can be empty
+        if not pac:
+            print >>sys.stderr, 'please specify a package name with the \'--name\' option. ' \
+                                'The automatic detection failed'
+            sys.exit(1)
+
+        if not os.path.exists(os.path.join(project_dir, pac)):
+            os.mkdir(os.path.join(project_dir, pac))
+            os.chdir(os.path.join(project_dir, pac))
+            data = meta_exists(metatype='pkg',
+                               path_args=(quote_plus(project), quote_plus(pac)),
+                               template_args=(pac, conf.config['user']))
+            if data:
+                data = ET.fromstring(''.join(data))
+                data.find('title').text = title
+                data.find('description').text = ''.join(descr)
+                data = ET.tostring(data)
+            else:
+                print >>sys.stderr, 'error - cannot get meta data'
+                sys.exit(1)
+            edit_meta(metatype='pkg',
+                      path_args=(quote_plus(project), quote_plus(pac)),
+                      data = data)
+            init_package_dir(conf.config['apiurl'], project, pac, os.path.join(project, pac))
+            unpack_srcrpm(srpm, os.getcwd())
+            p = Package(os.getcwd())
+            if len(p.filenamelist) == 0 and opts.commit:
+                # TODO: moving this into the Package class
+                print 'Adding files to working copy...'
+                self.do_add(None, None, *glob.glob('*'))
+                p.commit()
+            elif opts.commit and opts.delete_old_files:
+                delete_server_files(conf.config['apiurl'], project, pac, p.filenamelist)
+                p.update_local_filesmeta()
+                # TODO: moving this into the Package class
+                print 'Adding files to working copy...'
+                self.do_add(None, None, *glob.glob('*'))
+                p.update_datastructs()
+                p.commit()
+            else:
+                print 'No files were committed to the server. Please ' \
+                      'commit them manually.'
+                print 'Package \'%s\' only imported locally' % pac
+                sys.exit(1)
+        else:
+            print >>sys.stderr, 'error - local package already exists'
+            sys.exit(1)
+
+        print 'Package \'%s\' imported successfully' % pac
+
+
+    @cmdln.option('-m', '--method', default='GET', metavar='HTTP_METHOD',
+                        help='specify HTTP method to use (GET|PUT|DELETE|POST)')
+    @cmdln.option('-d', '--data', default=None, metavar='STRING',
+                        help='specify string data for e.g. POST')
+    @cmdln.option('-f', '--file', default=None, metavar='FILE',
+                        help='specify filename for e.g. PUT or DELETE')
+    def do_req(self, subcmd, opts, url):
+        """${cmd_name}: Issue an arbitrary request to the API
+
+        Useful for testing.
+
+        URL can be specified either partially (only the path component), or fully
+        with URL scheme and hostname ('http://...').
+
+        Note the global -A and -H options (see osc help).
+
+        Examples:
+          osc req /source/home:poeml
+          osc req -m PUT -f /etc/fstab source/home:poeml/test5/myfstab
+
+        ${cmd_usage}
+        ${cmd_option_list}
+        """
+
+        if not opts.method in ['GET', 'PUT', 'POST', 'DELETE']:
+            sys.exit('unknown method %s' % opts.method)
+
+        if not url.startswith('http'):
+            if not url.startswith('/'):
+                url = '/' + url
+            url = conf.config['apiurl'] + url
+
+        try:
+            r = http_request(opts.method, 
+                             url, 
+                             data=opts.data, 
+                             file=opts.file) 
+
+        except urllib2.HTTPError, e:
+            if e.code == 400:
+                print >>sys.stderr, e
+                print >>sys.stderr, e.read()
+                sys.exit(1)
+            if e.code == 500:
+                print >>sys.stderr, e
+                # this may be unhelpful... because it may just print a big blob of uninteresting
+                # ichain html and javascript... however it could potentially be useful if the orign
+                # server returns an information body
+                if conf.config['http_debug']:
+                    print >>sys.stderr, e.read()
+                sys.exit(1)
+            else:
+                sys.exit('unexpected error')
+
+        try:
+            out = r.read()
+        except:
+            sys.exit('failed to read from file object')
+
+        sys.stdout.write(out)
+
+
+
+# fini!
+###############################################################################
+        
     # load subcommands plugged-in locally
     plugin_dirs = ['/var/lib/osc-plugins', os.path.expanduser('~/.osc-plugins')]
     for plugin_dir in plugin_dirs:
diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/osc-0.97/osc/conf.py new/osc-0.97/osc/conf.py
--- old/osc-0.97/osc/conf.py    2007-07-16 11:45:17.000000000 +0200
+++ new/osc-0.97/osc/conf.py    2007-08-08 15:24:52.000000000 +0200
@@ -122,6 +122,15 @@
 
     global cookiejar
 
+    # HTTPS proxy is not supported by urllib2. It only leads to an error
+    # or, at best, a warning.
+    # https://bugzilla.novell.com/show_bug.cgi?id=214983
+    # https://bugzilla.novell.com/show_bug.cgi?id=298378
+    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
         def urllib2_debug_init(self, debuglevel=0):
@@ -225,6 +234,8 @@
         except:
             sys.exit('option %s requires an integer value' % i)
 
+    packagecachedir = os.path.expanduser(config['packagecachedir'])
+
     # transform 'url1, url2, url3' form into a list
     if type(config['urllist']) == str:
         config['urllist'] = [ i.strip() for i in config['urllist'].split(',') ]
diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/osc-0.97/osc/core.py new/osc-0.97/osc/core.py
--- old/osc-0.97/osc/core.py    2007-07-16 19:06:06.000000000 +0200
+++ new/osc-0.97/osc/core.py    2007-08-04 23:11:31.000000000 +0200
@@ -57,8 +57,8 @@
     <arch>x86_64</arch>
     <arch>i586</arch>
   </repository>
-  <repository name="SUSE_Linux_10.2">
-    <path project="SUSE:SL-10.2" repository="standard" />
+ <repository name="openSUSE_10.2">
+    <path project="openSUSE:10.2" repository="standard"/>
     <arch>x86_64</arch>
     <arch>i586</arch>
   </repository>
@@ -132,6 +132,13 @@
 Revision: %s
 """
 
+new_pattern_template = """\
+<!-- See http://svn.opensuse.org/svn/zypp/trunk/libzypp/zypp/parser/yum/schema/patterns.rng -->
+
+<pattern>
+</pattern>
+"""
+
 buildstatus_symbols = {'succeeded':       '.',
                        'disabled':        ' ',
                        'expansion error': 'E',
@@ -192,7 +199,6 @@
 class Package:
     """represent a package (its directory) and read/keep/write its metadata"""
     def __init__(self, workingdir):
-        import fnmatch
         self.dir = workingdir
         self.absdir = os.path.abspath(self.dir)
         self.storedir = os.path.join(self.dir, store)
@@ -203,41 +209,12 @@
         self.name = store_read_package(self.dir)
         self.apiurl = store_read_apiurl(self.dir)
 
-        files_tree = read_filemeta(self.dir)
-        files_tree_root = files_tree.getroot()
-
-        self.rev = files_tree_root.get('rev')
-        self.srcmd5 = files_tree_root.get('srcmd5')
-
-        self.filenamelist = []
-        self.filelist = []
-        for node in files_tree_root.findall('entry'):
-            try: 
-                f = File(node.get('name'), 
-                         node.get('md5'), 
-                         int(node.get('size')), 
-                         int(node.get('mtime')))
-            except: 
-                # okay, a very old version of _files, which didn't contain any metadata yet... 
-                f = File(node.get('name'), '', 0, 0)
-            self.filelist.append(f)
-            self.filenamelist.append(f.name)
-
-        self.to_be_deleted = read_tobedeleted(self.dir)
-        self.in_conflict = read_inconflict(self.dir)
+        self.update_datastructs()
 
         self.todo = []
         self.todo_send = []
         self.todo_delete = []
 
-        # gather unversioned files, but ignore some stuff
-        self.excluded = [ i for i in os.listdir(self.dir) 
-                          for j in exclude_stuff 
-                          if fnmatch.fnmatch(i, j) ]
-        self.filenamelist_unvers = [ i for i in os.listdir(self.dir)
-                                     if i not in self.excluded
-                                     if i not in self.filenamelist ]
-
     def info(self):
         return info_templ % (self.dir, self.apiurl, self.srcmd5, self.rev)
 
@@ -320,18 +297,57 @@
         shutil.copy2(os.path.join(self.dir, n), os.path.join(self.storedir, n))
 
     def commit(self, msg=''):
-        
-        query = []
-        query.append('cmd=commit')
-        query.append('rev=upload')
-        query.append('user=%s' % conf.config['user'])
-        query.append('comment=%s' % quote_plus(msg))
-        u = makeurl(self.apiurl, ['source', self.prjname, self.name], query=query)
-        #print u
-        f = http_POST(u)
-        root = ET.parse(f).getroot()
-        rev = int(root.get('rev'))
-        return rev
+        # commit only if the upstream revision is the same as the working copy's
+        upstream_rev = show_upstream_rev(self.apiurl, self.prjname, self.name)
+        if self.rev != upstream_rev:
+            print >>sys.stderr, 'Working copy \'%s\' is out of date (rev %s vs rev %s).' \
+                                % (self.absdir, self.rev, upstream_rev)
+            print >>sys.stderr, 'Looks as if you need to update it first.'
+            sys.exit(1)
+
+        if not self.todo:
+            self.todo = self.filenamelist_unvers + self.filenamelist
+
+        for filename in self.todo:
+            st = self.status(filename)
+            if st == 'A' or st == 'M':
+                self.todo_send.append(filename)
+                print 'Sending        %s' % filename
+            elif st == 'D':
+                self.todo_delete.append(filename)
+                print 'Deleting       %s' % filename
+
+        if not self.todo_send and not self.todo_delete:
+            print 'nothing to do for package %s' % self.name
+            sys.exit(1)
+
+        print 'Transmitting file data ', 
+        for filename in self.todo_delete:
+            self.delete_source_file(filename)
+            self.to_be_deleted.remove(filename)
+        for filename in self.todo_send:
+            sys.stdout.write('.')
+            sys.stdout.flush()
+            self.put_source_file(filename)
+        # all source files are committed - now comes the log
+        if conf.config['do_commits']:
+            query = []
+            query.append('cmd=commit')
+            query.append('rev=upload')
+            query.append('user=%s' % conf.config['user'])
+            query.append('comment=%s' % quote_plus(msg))
+            u = makeurl(self.apiurl, ['source', self.prjname, self.name], query=query)
+            #print u
+            f = http_POST(u)
+            root = ET.parse(f).getroot()
+            self.rev = int(root.get('rev'))
+            print
+            print 'Committed revision %s.' % self.rev
+        else:
+            print
+
+        self.update_local_filesmeta()
+        self.write_deletelist()
 
     def write_conflictlist(self):
         if len(self.in_conflict) == 0:
@@ -409,7 +425,45 @@
         f = open(os.path.join(self.storedir, '_files'), 'w')
         f.write(meta)
         f.close()
-        
+
+    def update_datastructs(self):
+        """
+        Update the internal data structures if the local _files
+        file has changed (e.g. update_local_filesmeta() has been
+        called).
+        """
+        import fnmatch
+        files_tree = read_filemeta(self.dir)
+        files_tree_root = files_tree.getroot()
+
+        self.rev = files_tree_root.get('rev')
+        self.srcmd5 = files_tree_root.get('srcmd5')
+
+        self.filenamelist = []
+        self.filelist = []
+        for node in files_tree_root.findall('entry'):
+            try: 
+                f = File(node.get('name'), 
+                         node.get('md5'), 
+                         int(node.get('size')), 
+                         int(node.get('mtime')))
+            except: 
+                # okay, a very old version of _files, which didn't contain any metadata yet... 
+                f = File(node.get('name'), '', 0, 0)
+            self.filelist.append(f)
+            self.filenamelist.append(f.name)
+
+        self.to_be_deleted = read_tobedeleted(self.dir)
+        self.in_conflict = read_inconflict(self.dir)
+
+        # gather unversioned files, but ignore some stuff
+        self.excluded = [ i for i in os.listdir(self.dir) 
+                          for j in exclude_stuff 
+                          if fnmatch.fnmatch(i, j) ]
+        self.filenamelist_unvers = [ i for i in os.listdir(self.dir)
+                                     if i not in self.excluded
+                                     if i not in self.filenamelist ]
+
     def update_local_pacmeta(self):
         """
         Update the local _meta file in the store.
@@ -550,14 +604,9 @@
                       'with --specfile'
                 sys.exit(1)     
 
-        summary, descr = read_meta_from_spec(specfile)
-        
-        if not summary and not descr:
-            print >>sys.stderr, 'aborting'
-            sys.exit(1)
-        else:
-            self.summary = summary
-            self.descr = descr
+        data = read_meta_from_spec(specfile, 'Summary:', '%description')
+        self.summary = data['Summary:']
+        self.descr = data['%description']
 
 
     def update_package_meta(self):
@@ -902,6 +951,26 @@
     return f.readlines()
 
 
+def show_pattern_metalist(apiurl, prj):
+    url = makeurl(apiurl, ['source', prj, '_pattern'])
+    f = http_GET(url)
+    tree = ET.parse(f)
+    r = [ node.get('name') for node in tree.getroot() ]
+    r.sort()
+    return r
+
+
+def show_pattern_meta(apiurl, prj, pattern):
+    url = makeurl(apiurl, ['source', prj, '_pattern', pattern])
+    try:
+        f = http_GET(url)
+    except urllib2.HTTPError, e:
+        print >>sys.stderr, 'error getting pattern \'%s\' for project \'%s\'' % (pattern, prj)
+        print >>sys.stderr, e
+        sys.exit(1)
+    return f.readlines()
+
+
 class metafile:
     """metafile that can be manipulated and is stored back after manipulation."""
     def __init__(self, url, input, change_is_required=False):
@@ -965,41 +1034,59 @@
               'user':    { 'path': 'person/%s',
                            'template': new_user_template,
                          },
+              'pattern': { 'path': 'source/%s/_pattern/%s',
+                           'template': new_pattern_template,
+                         },
             }
 
-def edit_meta(metatype, 
-              path_args=None, 
-              data=None, 
-              template_args=None, 
-              edit=False,
-              change_is_required=False):
+def meta_exists(metatype,
+                path_args=None,
+                template_args=None,
+                create_new=True):
 
+    data = None
+    url = make_meta_url(metatype, path_args)
+    try:
+        data = http_GET(url).readlines()
+    except urllib2.HTTPError, e:
+        if e.code == 404:
+            if create_new:
+                data = metatypes[metatype]['template']
+                if template_args:
+                    data = data % template_args
+        else:
+            print >>sys.stderr, 'error getting metadata for type \'%s\' at URL \'%s\':' \
+                                % (metatype, url)
+    return data
+
+def make_meta_url(metatype, path_args=None):
     if metatype not in metatypes.keys():
         sys.exit('unknown metatype %s' % metatype)
-
     path = metatypes[metatype]['path']
+
     if path_args:
         path = path % path_args
 
-    url = makeurl(conf.config['apiurl'], [path])
+    return makeurl(conf.config['apiurl'], [path])
+
+
+def edit_meta(metatype, 
+              path_args=None, 
+              data=None, 
+              template_args=None, 
+              edit=False,
+              change_is_required=False):
 
     if not data:
-        try:
-            data = http_GET(url).readlines() 
-        except urllib2.HTTPError, e:
-            if e.code == 404:
-                data = metatypes[metatype]['template']
-                if template_args:
-                    data = data % template_args
-            else:
-                print >>sys.stderr, 'error getting metadata for type \'%s\' at URL \'%s\':' \
-                                     % (metatype, url)
-                print >>sys.stderr, e
-                sys.exit(1)
+        data = meta_exists(metatype,
+                           path_args,
+                           template_args,
+                           create_new=True)
 
     if edit:
         change_is_required = True
 
+    url = make_meta_url(metatype, path_args)
     f=metafile(url, data, change_is_required)
 
     if edit:
@@ -1033,45 +1120,62 @@
     return ET.parse(StringIO(''.join(m))).getroot().get('rev')
 
 
-def read_meta_from_spec(specfile):
+def read_meta_from_spec(specfile, *args):
     import codecs, locale
-    """read Name, Summary and %description from spec file"""
+    """
+    Read tags and sections from spec file. To read out
+    a tag the passed argument must end with a colon. To
+    read out a section the passed argument must start with
+    a '%'.
+    This method returns a dictionary which contains the
+    requested data.
+    """
 
     if not os.path.isfile(specfile):
         print 'file \'%s\' is not a readable file' % specfile
-        return (None, None)
+        sys.exit(1)
 
     try:
         lines = codecs.open(specfile, 'r', locale.getpreferredencoding()).readlines()
     except UnicodeDecodeError:
         lines = open(specfile).readlines()
 
-    for line in lines:
-        if line.startswith('Name:'):
-            name = line.split(':')[1].strip()
-            break
-   
-    summary = None
-    for line in lines:
-        if line.startswith('Summary:'):
-            summary = line.split(':')[1].strip()
-            break
-    if summary == None:
-        print 'cannot find \'Summary:\' tag'
-        return (None, None)
+    tags = []
+    sections = []
+    spec_data = {}
+
+    for itm in args:
+        if itm.endswith(':'):
+            tags.append(itm)
+        elif itm.startswith('%'):
+            sections.append(itm)
+        else:
+            print >>sys.stderr, 'error - \'%s\' is not a tag nor a section' % itm
+            sys.exit(1)
 
-    descr = []
-    try:
-        start = lines.index('%description\n') + 1
-    except ValueError:
-        print 'cannot find %description'
-        return (None, None)
-    for line in lines[start:]:
-        if line.startswith('%'):
-            break
-        descr.append(line)
-    
-    return (summary, descr)
+    for tag in tags:
+        for line in lines:
+            if line.startswith(tag):
+                spec_data[tag] = line.split(':')[1].strip()
+                break
+        if not spec_data.has_key(tag):
+            print >>sys.stderr, 'error - tag \'%s\' does not exist' % tag
+            sys.exit(1)
+
+    for section in sections:
+        try:
+            start = lines.index(section + '\n') + 1
+        except ValueError:
+            print >>sys.stderr, 'error - section \'%s\' does not exist' % section
+            sys.exit(1)
+        data = []
+        for line in lines[start:]:
+            if line.startswith('%'):
+                break
+            data.append(line)
+        spec_data[section] = data
+
+    return spec_data
 
 
 def get_user_meta(apiurl, user):
@@ -1300,15 +1404,31 @@
 
 
 def delete_package(apiurl, prj, pac):
-    
     u = makeurl(apiurl, ['source', prj, pac])
-    http_DELETE(u)
+    try:
+        http_DELETE(u)
+    except urllib2.HTTPError, e:
+        if e.code == 404:
+            print >>sys.stderr, 'Package \'%s\' does not exist' % pac
+            sys.exit(1)
+        else:
+            print >>sys.stderr, 'an unexpected error occured while deleting ' \
+                                '\'%s\'' % pac
+            sys.exit(1)            
 
 
 def delete_project(apiurl, prj):
-    
     u = makeurl(apiurl, ['source', prj])
-    http_DELETE(u)
+    try:
+        http_DELETE(u)
+    except urllib2.HTTPError, e:
+        if e.code == 404:
+            print >>sys.stderr, 'Package \'%s\' does not exist' % pac
+            sys.exit(1)
+        else:
+            print >>sys.stderr, 'an unexpected error occured while deleting ' \
+                                '\'%s\'' % pac
+            sys.exit(1)
 
 
 def get_platforms(apiurl):
@@ -1367,7 +1487,11 @@
         rmap['arch'] = node.get('arch')
 
         statusnode =  node.find('status')
-        rmap['status'] = statusnode.get('code')
+        try:
+            rmap['status'] = statusnode.get('code')
+        except:
+            # code can be missing when package is too new:
+            return {}
 
         if rmap['status'] in ['expansion error', 'broken']:
             rmap['status'] += ': ' + statusnode.find('details').text
@@ -1780,3 +1904,151 @@
         return result
     else:
         return None
+
+def delete_tmpdir(tmpdir):
+    """
+    This method deletes a tempdir. This tempdir
+    must be located under /tmp/$DIR. If "tmpdir" is not
+    a valid tempdir it'll return False. If os.unlink() / os.rmdir()
+    throws an exception we will return False too - otherwise
+    True.
+    """
+
+    # small security checks
+    if os.path.islink(tmpdir):
+        return False
+    elif os.path.abspath(tmpdir) == '/':
+        return False
+    
+    head, tail = os.path.split(tmpdir)
+    if not head.startswith('/tmp') or not tail:
+        return False
+
+    if not os.path.isdir(tmpdir):
+        return False
+
+    for dirpath, dirnames, filenames in os.walk(tmpdir, topdown=False):
+        for file in filenames:
+            try:
+                os.unlink(os.path.join(dirpath, file))
+            except:
+                return False
+        for dirname in dirnames:
+            try:
+                os.rmdir(os.path.join(dirpath, dirname))
+            except:
+                return False
+    try:
+        os.rmdir(tmpdir)
+    except:
+        return False
+    return True
+
+def unpack_srcrpm(srpm, dir, *files):
+    """
+    This method unpacks the passed srpm into the
+    passed dir. If arguments are passed to the \'files\' tuple
+    only this files will be unpacked.
+    """
+    if not is_srcrpm(srpm):
+        print >>sys.stderr, 'error - \'%s\' is not a source rpm.' % srpm
+        sys.exit(1)
+    curdir = os.getcwd()
+    if not os.path.isdir(dir):
+        dir = curdir
+    else:
+        os.chdir(dir)
+    cmd = 'rpm2cpio %s | cpio -i %s &> /dev/null' % (srpm, ' '.join(files))
+    ret = os.system(cmd)
+    if ret != 0:
+        print >>sys.stderr, 'error \'%s\' - cannot extract \'%s\'' % (ret, srpm)
+        sys.exit(1)
+    os.chdir(curdir)
+
+def tag_to_rpmpy(tag):
+    """
+    maps a spec file tag/section to a valid
+    rpm-python RPMTAG
+    """
+
+    try:
+        import rpm
+        tags = { 'Name:' : rpm.RPMTAG_NAME,
+                 'Summary:' : rpm.RPMTAG_SUMMARY,
+                 '%description' : rpm.RPMTAG_DESCRIPTION
+               }
+        if tag in tags.keys():
+            return tags[tag]
+        else:
+            return None
+    except ImportError:
+        return None
+
+def data_from_rpm(rpm_file, *rpmdata):
+    """
+    This method reads the given rpmdata
+    from a rpm.
+    """
+
+    try:
+        import rpm
+        ts = rpm.TransactionSet()
+        file = open(rpm_file, 'r')
+        header = ts.hdrFromFdno(file.fileno())
+        file.close()
+        data = {}
+        for itm in rpmdata:
+            rpmpy = tag_to_rpmpy(itm)
+            if rpmpy:
+                data[itm] = header[rpmpy]
+            else:
+                print >>sys.stderr, 'invalid data \'%s\'' % itm
+                sys.exit(1)
+        return data
+    except ImportError:
+        print >>sys.stderr, 'warning: rpm-python not found'
+        return None
+
+def is_rpm(f):
+    """check if the named file is an RPM package"""
+    try:                                                                                                                                
+        h = open(f).read(4)
+    except:
+        return False
+
+    if h == '\xed\xab\xee\xdb':
+        return True
+    else:
+        return False
+
+def is_srcrpm(f):
+    """check if the named file is a source RPM"""
+
+    if not is_rpm(f):
+        return False
+
+    try:
+        h = open(f).read(8)
+    except:
+        return False
+
+    if h[7] == '\x01':
+        return True
+    else:
+        return False   
+
+def delete_server_files(apiurl, prj, pac, files):
+    """
+    This method deletes the given filelist on the
+    server. No local data will be touched.
+    """
+
+    for file in files:
+        try:
+            u = makeurl(apiurl, ['source', prj, pac, file])
+            http_DELETE(u)
+        except:
+            # we do not handle all exceptions here - we need another solution
+            # see bug #280034
+            print >>sys.stderr, 'error while deleting file \'%s\'' % file
+            sys.exit(1)



++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++



Remember to have fun...

---------------------------------------------------------------------
To unsubscribe, e-mail: opensuse-commit+unsubscribe@xxxxxxxxxxxx
For additional commands, e-mail: opensuse-commit+help@xxxxxxxxxxxx

< Previous Next >
This Thread
  • No further messages