more robust config prompting
[build.git] / module-tag.py
index 26dfb0e..7079eda 100755 (executable)
@@ -98,20 +98,32 @@ class Svnpath:
 
 class Module:
 
-    # where to store user's config
-    config_storage="CONFIG"
-    # 
-    configKeys=[ ('svnpath',"Enter your toplevel svnpath (e.g. svn+ssh://thierry@svn.planet-lab.org/svn/)"),
-                 ('username',"Enter your firstname and lastname for changelogs"),
-                 ("email","Enter your email address for changelogs") ]
-    config={}
-
     svn_magic_line="--This line, and those below, will be ignored--"
     
     redirectors=[ ('module_name_varname','name'),
                   ('module_version_varname','version'),
                   ('module_taglevel_varname','taglevel'), ]
 
+    # where to store user's config
+    config_storage="CONFIG"
+    # 
+    config={}
+
+    import commands
+    configKeys=[ ('svnpath',"Enter your toplevel svnpath",
+                  "svn+ssh://%s@svn.planet-lab.org/svn/"%commands.getoutput("id -un")),
+                 ("build", "Enter the name of your build module","build"),
+                 ('username',"Enter your firstname and lastname for changelogs",""),
+                 ("email","Enter your email address for changelogs",""),
+                 ]
+
+    @staticmethod
+    def prompt_config ():
+        for (key,message,default) in Module.configKeys:
+            Module.config[key]=""
+            while not Module.config[key]:
+                Module.config[key]=raw_input("%s [%s] : "%(message,default)).strip() or default
+
     def __init__ (self,name,options):
         self.name=name
         self.options=options
@@ -138,15 +150,29 @@ class Module:
         if options.verbose:
             print 'Checking for',topdir
         storage="%s/%s"%(topdir,Module.config_storage)
+        # sanity check. Either the topdir exists AND we have a config/storage
+        # or topdir does not exist and we create it
+        # to avoid people use their own daily svn repo
+        if os.path.isdir(topdir) and not os.path.isfile(storage):
+            print """The directory %s exists and has no CONFIG file
+If this is your regular working directory, please provide another one as the
+module-* commands need a fresh working dir. Make sure that you do not use 
+that for other purposes than tagging"""%topdir
+            sys.exit(1)
         if not os.path.isdir (topdir):
-            # prompt for login or whatever svnpath
             print "Cannot find",topdir,"let's create it"
-            for (key,message) in Module.configKeys:
-                Module.config[key]=raw_input(message+" : ").strip()
+            Module.prompt_config()
+            print "Checking ...",
             Command("svn co -N %s %s"%(Module.config['svnpath'],topdir),options).run_fatal()
+            Command("svn co -N %s/%s %s/%s"%(Module.config['svnpath'],
+                                             Module.config['build'],
+                                             topdir,
+                                             Module.config['build']),options).run_fatal()
+            print "OK"
+            
             # store config
             f=file(storage,"w")
-            for (key,message) in Module.configKeys:
+            for (key,message,default) in Module.configKeys:
                 f.write("%s=%s\n"%(key,Module.config[key]))
             f.close()
             if options.debug:
@@ -159,10 +185,10 @@ class Module:
                 (key,value)=re.compile("^(.+)=(.+)$").match(line).groups()
                 Module.config[key]=value                
             f.close()
-            if options.debug:
-                print 'Using config'
-                for (key,message) in Module.configKeys:
-                    print key,'=',Module.config[key]
+        if options.verbose:
+            print '******** Using config'
+            for (key,message,default) in Module.configKeys:
+                print '\t',key,'=',Module.config[key]
 
     def init_moddir (self):
         if self.options.verbose:
@@ -190,7 +216,7 @@ class Module:
             return
         if self.options.verbose:
             print 'Updating',self.trunkdir
-        self.run_fatal("svn update %s"%self.trunkdir)
+        self.run_fatal("svn update -N %s"%self.trunkdir)
 
     def guess_specname (self):
         attempt="%s/%s.spec"%(self.trunkdir,self.name)
@@ -203,6 +229,9 @@ class Module:
                 print 'Cannot guess specfile for module %s'%self.name
                 sys.exit(1)
 
+    def all_specnames (self):
+        return glob("%s/*.spec"%self.trunkdir)
+
     def parse_spec (self, specfile, varnames):
         if self.options.debug:
             print 'parse_spec',specfile,
@@ -244,23 +273,23 @@ class Module:
         return result
 
     def patch_spec_var (self, patch_dict):
-        specfile=self.guess_specname()
-        newspecfile=specfile+".new"
-        if self.options.verbose:
-            print 'Patching',specfile,'for',patch_dict.keys()
-        spec=open (specfile)
-        new=open(newspecfile,"w")
-
-        for line in spec.readlines():
-            if self.varmatcher.match(line):
-                (var,value)=self.varmatcher.match(line).groups()
-                if var in patch_dict.keys():
-                    new.write('%%define %s %s\n'%(var,patch_dict[var]))
-                    continue
-            new.write(line)
-        spec.close()
-        new.close()
-        os.rename(newspecfile,specfile)
+        for specfile in self.all_specnames():
+            newspecfile=specfile+".new"
+            if self.options.verbose:
+                print 'Patching',specfile,'for',patch_dict.keys()
+            spec=open (specfile)
+            new=open(newspecfile,"w")
+
+            for line in spec.readlines():
+                if self.varmatcher.match(line):
+                    (var,value)=self.varmatcher.match(line).groups()
+                    if var in patch_dict.keys():
+                        new.write('%%define %s %s\n'%(var,patch_dict[var]))
+                        continue
+                new.write(line)
+            spec.close()
+            new.close()
+            os.rename(newspecfile,specfile)
 
     def unignored_lines (self, logfile):
         result=[]
@@ -273,27 +302,27 @@ class Module:
         return result
 
     def insert_changelog (self, logfile, oldtag, newtag):
-        specfile=self.guess_specname()
-        newspecfile=specfile+".new"
-        if self.options.verbose:
-            print 'Inserting changelog from %s into %s'%(logfile,specfile)
-        spec=open (specfile)
-        new=open(newspecfile,"w")
-        for line in spec.readlines():
-            new.write(line)
-            if re.compile('%changelog').match(line):
-                dateformat="* %a %b %d %Y"
-                datepart=time.strftime(dateformat)
-                logpart="%s <%s> - %s %s"%(Module.config['username'],
-                                             Module.config['email'],
-                                             oldtag,newtag)
-                new.write(datepart+" "+logpart+"\n")
-                for logline in self.unignored_lines(logfile):
-                    new.write("- " + logline)
-                new.write("\n")
-        spec.close()
-        new.close()
-        os.rename(newspecfile,specfile)
+        for specfile in self.all_specnames():
+            newspecfile=specfile+".new"
+            if self.options.verbose:
+                print 'Inserting changelog from %s into %s'%(logfile,specfile)
+            spec=open (specfile)
+            new=open(newspecfile,"w")
+            for line in spec.readlines():
+                new.write(line)
+                if re.compile('%changelog').match(line):
+                    dateformat="* %a %b %d %Y"
+                    datepart=time.strftime(dateformat)
+                    logpart="%s <%s> - %s %s"%(Module.config['username'],
+                                                 Module.config['email'],
+                                                 oldtag,newtag)
+                    new.write(datepart+" "+logpart+"\n")
+                    for logline in self.unignored_lines(logfile):
+                        new.write("- " + logline)
+                    new.write("\n")
+            spec.close()
+            new.close()
+            os.rename(newspecfile,specfile)
             
     def show_dict (self, spec_dict):
         if self.options.verbose:
@@ -316,12 +345,11 @@ class Module:
         self.revert_trunkdir()
         self.update_trunkdir()
         print '==============================',self.name
-        #for (key,message) in Module.configKeys:
-        #    print key,':',Module.config[key]
         spec_dict = self.spec_dict()
         print 'trunk url',self.trunk_url()
         print 'latest tag url',self.tag_url(spec_dict)
-        print 'specfile:',self.guess_specname()
+        print 'main specfile:',self.guess_specname()
+        print 'specfiles:',self.all_specnames()
         for varname in self.varnames:
             if not spec_dict.has_key(varname):
                 print 'Could not find %%define for %s'%varname
@@ -446,11 +474,11 @@ The module-init function has the following limitations
         # so we can provide useful information, such as version numbers and diff
         # in the same file
         changelog="/tmp/%s-%d.txt"%(self.name,os.getpid())
-        file(changelog,"w").write("""Tagging module %s  -- from %s to %s
+        file(changelog,"w").write("""Tagging module %s - %s
 
 %s
 Please write a changelog for this new tag in the section above
-"""%(self.name,old_tag_name,new_tag_name,Module.svn_magic_line))
+"""%(self.name,new_tag_name,Module.svn_magic_line))
 
         if not self.options.verbose or prompt('Want to see diffs while writing changelog',True):
             file(changelog,"a").write('DIFF=========\n' + diff_output)
@@ -465,7 +493,11 @@ Please write a changelog for this new tag in the section above
             self.insert_changelog (changelog,old_tag_name,new_tag_name)
 
         ## update build
-        build = Module(self.options.build,self.options)
+        try:
+            buildname=Module.config['build']
+        except:
+            buildname="build"
+        build = Module(buildname,self.options)
         build.init_moddir()
         build.init_trunkdir()
         build.revert_trunkdir()
@@ -544,8 +576,6 @@ def main():
     parser.add_option("-w","--workdir", action="store", dest="workdir", 
                       default="%s/%s"%(os.getenv("HOME"),"modules"),
                       help="name for workdir - defaults to ~/modules")
-    parser.add_option("-B","--build", action="store", dest="build", default="build",
-                      help="set module name for build, defaults to build")
     parser.add_option("-v","--verbose", action="store_true", dest="verbose", default=False, 
                       help="run in verbose mode")
     parser.add_option("-d","--debug", action="store_true", dest="debug", default=False,