File osc-offline.patch of Package osc

Index: osc/build.py
===================================================================
--- osc/build.py	(revision 2459)
+++ osc/build.py	(working copy)
@@ -9,6 +9,8 @@
 
 import os
 import sys
+import time
+from stat import ST_MTIME, ST_SIZE
 from tempfile import NamedTemporaryFile
 from osc.fetch import *
 from osc.core import get_buildinfo, store_read_apiurl, store_read_project, store_read_package
@@ -228,7 +230,7 @@
 
 
     # make it possible to override configuration of the rc file
-    for var in ['OSC_PACKAGECACHEDIR', 'OSC_SU_WRAPPER', 'BUILD_ROOT', 'OSC_BUILD_ROOT']: 
+    for var in ['OSC_PACKAGECACHEDIR', 'OSC_SU_WRAPPER', 'BUILD_ROOT', 'OSC_BUILD_ROOT', 'BUILDINFODIR', 'OSC_BUILDINFODIR']: 
         val = os.getenv(var)
         if val:
             if var.startswith('OSC_'): var = var[4:]
@@ -240,25 +242,87 @@
 
     config['build-root'] = config['build-root'] % {'repo': repo, 'arch': arch}
 
-    print 'Getting buildinfo from server'
-    bi_file = NamedTemporaryFile(suffix='.xml', prefix='buildinfo.', dir = '/tmp')
-    try:
-        bi_text = ''.join(get_buildinfo(store_read_apiurl(os.curdir), 
-                                        store_read_project(os.curdir), 
-                                        store_read_package(os.curdir), 
-                                        repo, 
-                                        arch, 
-                                        specfile=open(spec).read(), 
-                                        addlist=opts.extra_pkgs))
+    bi_file_name = "%s/buildinfo.%s-%s-%s-%s-%s.xml" % (config['buildinfodir'],
+                                                        store_read_project(os.curdir),
+                                                        store_read_package(os.curdir),
+                                                        repo,
+                                                        arch,
+                                                        spec)
 
-    except:
-        print >>sys.stderr, 'wrong repo/arch?'
-        sys.exit(1)
-    bi_file.write(bi_text)
-    bi_file.flush()
+    # I guess caching this sort of thing for an hour is reasonable
+    cache_time = 60 * 60
+    
+    # if bi_file_name exists:
+    #     if use_cached_buildinfo == false:
+    #         download the new version
+    #     elif it is older than cache_time seconds and offline is false:
+    #         download the new version
+    #     else:
+    #         use the cached version
+    # else:
+    #     if offline is true:
+    #         fail
+    #     else:
+    #         download it
 
-    bi = Buildinfo(bi_file.name)
+    use_cached = False
+    if os.path.exists(bi_file_name):
+        modtime = os.stat(bi_file_name)[ST_MTIME]
+        size = os.stat(bi_file_name)[ST_SIZE]
+        now = time.time()
+        if opts.dont_use_cached_buildinfo == True:
+            use_cached = False
+        elif (now > (cache_time + modtime)) and not opts.offline:
+            use_cached = False
+        elif (size == 0):
+            # we end up with bogus files in the cache for some reason
+            use_cached = False
+        else:
+            use_cached = True
+    else:
+        print "opts.offline is %s" % opts.offline
+        if opts.offline:
+            # How best to fail?  Just let it happen later?
+            pass
+        else:
+            use_cached = False
+    bi = None
+    if use_cached:
+        print "Not getting buildinfo from server; using cached version instead"
+        bi = Buildinfo(bi_file_name)
+    else:
+        try:
+            os.unlink(bi_file_name)
+        except OSError:
+            print "%s probably doesn't exist" % bi_file_name
+            # This could be improved.
+            pass
 
+        print 'Getting buildinfo from server'
+
+        bi_file = open(bi_file_name, 'a')
+                        
+        try:
+            bi_text = ''.join(get_buildinfo(store_read_apiurl(os.curdir), 
+                                            store_read_project(os.curdir), 
+                                            store_read_package(os.curdir), 
+                                            repo, 
+                                            arch, 
+                                            specfile=open(spec).read(), 
+                                            addlist=opts.extra_pkgs))
+            
+        except:
+            print >>sys.stderr, 'wrong repo/arch?'
+            sys.exit(1)
+        bi_file.write(bi_text)
+        bi_file.flush()
+
+        # now cache what we've got
+
+
+    bi = Buildinfo(bi_file_name)
+
+    
     rpmlist_prefers = []
     if opts.prefer_pkgs:
         print 'Evaluating preferred packages'
@@ -308,21 +372,59 @@
     rpmlist_file.flush()
     os.fsync(rpmlist_file)
 
+    # We use the same logic here as above with buildinfo
 
+    bc_file_name = "%s/buildconfig.%s-%s-%s-%s-%s" % (config['buildinfodir'],
+                                                      store_read_project(os.curdir),
+                                                      store_read_package(os.curdir),
+                                                      repo,
+                                                      arch,
+                                                      spec)
 
-    print 'Getting buildconfig from server'
-    bc_file = NamedTemporaryFile(prefix='buildconfig.', dir = '/tmp')
-    rc = os.system('osc buildconfig %s %s > %s' % (repo, arch, bc_file.name))
-    if rc: sys.exit(rc)
+    use_cached = False
+    if os.path.exists(bc_file_name):
+        modtime = os.stat(bc_file_name)[ST_MTIME]
+        size = os.stat(bc_file_name)[ST_SIZE]
+        now = time.time()
+        if opts.dont_use_cached_buildinfo == True:
+            use_cached = False
+        elif (now > (cache_time + modtime)) and not opts.offline:
+            use_cached = False
+        elif size == 0:
+            use_cached = False
+        else:
+            use_cached = True
+    else:
+        if opts.offline:
+            # Again, how best to fail?  Just let it happen later?
+            pass
+        else:
+            use_cached = False
+    
+    if use_cached:
+        print "Not getting buildconfig from server; using cached version instead"
+    else:
+        try:
+            os.unlink(bc_file_name)
+        except OSError:
+            print "%s probably doesn't exist" % bc_file_name
+        
 
+        print 'Getting buildconfig from server'
+        rc = os.system('touch %s' % bc_file_name)
+        if rc: sys.exit(rc)
 
+        rc = os.system('osc buildconfig %s %s > %s' % (repo, arch, bc_file_name))
+        if rc: sys.exit(rc)
+
+
     print 'Running build'
 
     cmd = '%s --root=%s --rpmlist=%s --dist=%s %s %s' \
                  % (config['build-cmd'],
                     config['build-root'],
                     rpmlist_file.name, 
-                    bc_file.name, 
+                    bc_file_name, 
                     spec, 
                     buildargs)
 
Index: osc/conf.py
===================================================================
--- osc/conf.py	(revision 2459)
+++ osc/conf.py	(working copy)
@@ -42,6 +42,7 @@
              'scheme': 'https',
              'user': 'your_username',
              'packagecachedir': '/var/tmp/osbuild-packagecache',
+             'buildinfodir': '/var/tmp/oscbuild-buildinfodir',
              'su-wrapper': 'su -c',
              'build-cmd': '/usr/bin/build',
              'build-root': '/var/tmp/build-root',
Index: osc/commandline.py
===================================================================
--- osc/commandline.py	(revision 2459)
+++ osc/commandline.py	(working copy)
@@ -1318,6 +1318,10 @@
                   help='Delete old build root before initializing it')
     @cmdln.option('--no-changelog', action='store_true',
                   help='don\'t update the package changelog from a changes file')
+    @cmdln.option('--dont-use-cached-buildinfo', action='store_true',
+                  help="Don't use cached buildinfo even if it exists")
+    @cmdln.option('--offline', action='store_true',
+                  help="Don't phone home for building; instead use cached data if it exists")
     @cmdln.option('--noinit', '--no-init', action='store_true',
                   help='Skip initialization of build root and start with build immediately.')
     @cmdln.option('-p', '--prefer-pkgs', metavar='DIR', action='append',
openSUSE Build Service is sponsored by