#!/usr/bin/python #-*- coding: UTF-8 -*- #************************************************ # updateCVS # # updateCVS is made to automatically update a CVS # repository with the newest version of a sotware # It works from a source file (*.tar.gz) or a url # (http://...*.tar.gz) # # # Made by Pierre-Yves chibon # # Version 1.2 -- 25th June 2008 # * Correction of a typo # # Version 1.1 -- 6th June 2008 # * Enable to start the build and not wait for its end # (Thanks Spot ;) ) # * Enable to update all the directories at once # # Version 1.0 -- 26th May 2008 # * Works from an url # * Works from a .tar.gz # * Takes into account the rmodule # * Takes into accound prefix # * Works for a specific version or a set of version # # * Needs configuration for each packager # # Distributed under License GPLv3 or later # You can find a copy of this license on the website # http://www.gnu.org/licenses/gpl.html # #*********************************************** ### Packager information #packager=packager.new() packagerName="" packagerEmail="" ### # Global variable no=['no', 'n', 'N', 'No', 'NO'] current_version=["devel", "F-9", "F-8"] ################################################# import os, getopt, sys, string, re, datetime, shutil try: from cvs import * except: pass ################################################# USAGE =""" This programm is designed to update a spec files onto a cvs repository Usage: From a url updateCVS -u updateCVS --url= From a tarball updateCVS -s folder/folder/ updateCVS --source= To define the CVSROOT updateCVS --cvsroot= For R libraries updateCVS --rmodule If the RPM contains a prefix (such as "perl-") updateCVS --prefix= The source can be in the same directory or in a subdirectory. """ ################################################# ################################################# ### download_source # Download the source from the argument given def download_source(url): source=url.rsplit('/',1)[1] # Check the presence of the source, download only if they are not already in the working directory exist = os.path.isfile(source) if exist == True: print "The file "+source+" already exist, there is no need to download it again." else: cmd = "wget "+url print cmd os.system(cmd) #sys.exit(1) ################################################# ################################################# ### argument # retrieve the arguments given and show the help when needed def argument(): try: opts, args = getopt.getopt(sys.argv[1:], "u:s:", ["url=", "source=","cvsroot=","rmodule","prefix="]) except getopt.GetoptError: print USAGE sys.exit(1) url = None source = None cvsroot = None rmodule = None prefix = None for option, argument in opts: if option in ("-u", "--url"): url = argument if option in ("-s", "--source"): source = argument if option in ("--cvsroot"): cvsroot = argument if option in ("--rmodule"): rmodule= 'yes' if option in ("--prefix"): prefix = argument return (source,url,cvsroot,rmodule,prefix) ################################################ ################################################# ### cvsroot # retrieve the cvs from the sys def cvsroot_retrieve(): test=os.environ.get('CVSROOT') #print test," <= test\n", # for debugging purpose #print len(test.split(':')) # for debugging purpose if len(test.split(':')) > 4: #print test.split(':',2),"\n" # for debugging purpose text="What is the position the correct cvsroot ? [1:",len(test.split(':',2)),"] (q to quit)" position=raw_input(text) if position=='q': exit(0) print position cvsroot=test.split(':',2)[int(position)-1] else: cvsroot=test.split(':',2)[2] #print cvsroot," <= cvsroot" # for debugging purpose return(cvsroot) ################################################ ################################################# ### download_source # Download the source from the argument given def download_source(url): source=url.rsplit('/',1)[1] # Check the presence of the source, download only if they are not already in the working directory exist = os.path.isfile(source) if exist == True: print "The file "+source+" already exist, there is no need to download it again." else: cmd = "wget "+url print cmd os.system(cmd) #sys.exit(1) ################################################# ################################################# ### name_retrieve() # retrieve the name of the package from the source or the url def name_retrieve(url,source): if url != None: package=url.rsplit('/',1)[1].split('_')[0] else: package=source.split('_')[0] try: package=package.rsplit('/',1)[1] except: package=package return(package) ################################################# ################################################# ### source_retrieve() # retrieve the name of the source from the source or the url def source_retrieve(url,source): if url != None: package=url.rsplit('/',1)[1] else: package=source try: package=package.rsplit('/',1)[1] except: package=package return(package) ################################################# ################################################# ### version_retrieve() # retrieve the version from the source def version_retrieve(package): newVersion=package.split('_')[1] newVersion=newVersion.split('.tar')[0] return(newVersion) ################################################# ################################################# ### arch_retrieve() # retrieve the arch of the system def arch_retrieve(): import commands arch=commands.getoutput('uname -p') return(arch) ################################################# ################################################# ### updateVersion() # update the version def updateVersion(file,newVersion): version = None versionMotif = re.compile('Version:.*') try: version = versionMotif.findall(file)[0] versionNum = version.split('Version: ')[1] #print versionNum versionNum=versionNum.replace(' ','') try: version = version.split('-')[0] except: pass except: version = "" newVersion=version.replace(versionNum,newVersion) #print oldVersion, version #for debugging purpose return(version,newVersion) ################################################# ################################################# ### updateRelease() # update the release def updateRelease(file): release = None releaseMotif = re.compile('Release:.*') try: release = releaseMotif.findall(file)[0] releaseNum = release.split('Release: ')[1] releaseNum = releaseNum.split('%{?dist}')[0] releaseNum=releaseNum.replace(' ','') #print releaseNum try: release = release.split('-')[0] except: pass except: release = "" newRelease=release.replace(releaseNum,'1') #print oldVersion, version #for debugging purpose return(release,newRelease) ################################################# ################################################# ### getDate() # Get the current date def getDate(): date= datetime.datetime.now().strftime("%a %b %d %Y") return date ################################################# ################################################# ### updateLog() # update the changelog def updateLog(file,version): log = None logMotif = re.compile('changelog') log = logMotif.findall(file)[0] log=log.replace(' ','') newlog=log+"\n* "+getDate()+" "+packagerName+" <"+packagerEmail+"> "+version+"-1"+"\n"+"- Update to version "+version+"\n" newlog=log.replace(log,newlog) #print log, newlog #for debugging purpose return(log,newlog) ################################################# ################################################# ### makeSource() # make the new source def makeSource(home, package): cmd='make new-sources FILES="'+home+"/"+package+'"' print "\n","*"*50,"\n" print cmd os.system(cmd) print "\n","*"*50,"\n" ################################################# ################################################# ### getFolder(name) # Return only the folder in the directory def getFolder(name): files=os.listdir('./') folder=[] for file in files: if( os.path.isdir(file)!=False ): folder.append(file) #print folder #For debugging purpose return(folder) ################################################# ################################################# ### updateSpec() # update the spec file def updateSpec(newVersion): # Read the spec file f=open(name+'.spec', 'r') file = f.read() f.close() # update the version (oldVersionToSpec,newVersionToSpec)=updateVersion(file,newVersion) print "New version= \n"+newVersionToSpec #update the release (oldReleaseToSpec,newReleaseToSpec)=updateRelease(file) print "New release= \n"+newReleaseToSpec # update changelog (oldlogToSpec, newlogToSpec)=updateLog(file,newVersion) print "New log entrie=\n"+newlogToSpec # update the spec file file=file.replace(oldVersionToSpec,newVersionToSpec) file=file.replace(oldlogToSpec,newlogToSpec) file=file.replace(oldReleaseToSpec,newReleaseToSpec) #print "\n","*"*50,"\n",file # For debugging purpose print "\n","*"*50,"\n" os.unlink(name+'.spec') f=open(name+'.spec', 'a') f.write(file) f.close() ################################################# ################################################# ### menu() # show the main menu def menu(): #Save current directory home=os.getcwd() # Change directory to the os.chdir(name) #or exit("This directory "+name+" does not exist") #does not work.... folder=getFolder(name) # Propose the choice of the version to update print "Enter the name of the folder you would like to update : \nAvailable:\n",folder," + All \n(q to quit)" version=raw_input('> ') if version =='q': exit(0) print "You chose to update ",version if version =='All': print "=>",current_version,"\n" else: print "\n" if version =='All': for version in current_version: update(home,version) else: update(home,version) os.chdir(home) menu() ################################################# ################################################# ### update() # update def update(home,version): #Enter into the folder to update try: os.chdir(version) #or exit("This directory "+version+" does not exist") except: exit("This directory "+version+" does not exist") #print os.getcwd() # move the sources shutil.copy(home+"/"+package, os.getcwd()) #make new source makeSource(home,package) ## update the spec print "\n","*"*50,"\n Update the spec file\n" # Retrieve the new Version number newVersion=version_retrieve(package) # Update the spec file updateSpec(newVersion) # Check the changes made print "\n","*"*50,"\n Diff of the file\n" cmd="cvs diff -u" os.system(cmd) print "Do you want to continue with these changes ? [Y/n]" version=raw_input('> ') if version in no: print "You refused these changes\n" #exit(0) menu() print "You chose to continue the update \n" print "\n","*"*50 # Retrieve arch arch=arch_retrieve() # Compile for the correct arch print "\n","*"*50,"\n make RPM \n" cmd="make "+arch os.system(cmd) # Run rpmlint print "\n","*"*50,"\n rpmlint \n" cmd="find ./ -name *.rpm |xargs rpmlint " #cmd="rpmlint ./*.rpm" os.system(cmd) print "\n","*"*50 print "Do you want to *commit* these changes ? [Y/n]" version=raw_input('> ') if version in no: print "You decided to stop\n" #exit(0) menu() print "You chose to continue the update \n" print "\n","*"*50 # Commit the changes print "\n","*"*50,"\n commit cvs\n" cmd="cvs commit" os.system(cmd) print "\n","*"*50 # make tag && build print "\n","*"*50,"\n make tag\n" cmd="make tag" os.system(cmd) print "\n","*"*50 print "\n","*"*50,"\n make build\n" cmd="BUILD_FLAGS=\"--nowait\" make build" # Thank you Spot ;) os.system(cmd) print "\n","*"*50 os.chdir(home) ################################################# # Main if packagerName==None or packagerName=="": print "You need to configure this script for yourself" sys.exit(0) if packagerEmail==None or packagerEmail=="": print "You need to configure this script for yourself" sys.exit(0) (source,url,cvsroot,rmodule,prefix)=argument() # Show all the argument given #Debugging purpose #print "\nSource from sys.argv ==> ", source,"\n" #print "\nurl from sys.argv ==> ", url,"\n" #print "\nCVSroot from sys.argv ==> ", cvsroot,"\n" # Return the usage message if no arguments are given if(url ==None and source ==None): print USAGE sys.exit(0) # Return an error message if there is 2 arguments given if (url !=None and source !=None): sys.exit("\n*** Please give only one argument ***\n") # Check wether the url or the source exist and if so check wether they are http:// and tar.gz if(url != None): # Check wether the url start with http:// position = url.find('http://') if position != 0: sys.exit("Your URL does not start with http:// => "+url) # Check wether the url refers to a .tar.gz p= re.compile('http://.*tar.gz') url2 = p.findall(url) if url2 == []: sys.exit("Your URL does not link to a tarball file "+url) print "URL = ", url , "\n"#, url2 # Download the source download_source(url) # Retrieve the name of the package name=name_retrieve(url,source) # Retrieve the name of the source package=source_retrieve(url, source) #add R- to package if it is a R module if rmodule=='yes' and prefix!='R-': name="R-"+name #add the prefix to the package if required if prefix != None: name=prefix+name # Retrieve the cvsroot if cvsroot == None: cvsroot=cvsroot_retrieve() # cvs co print "\n","*"*50,"\n cvs co "+name+"\n" try: checkout(cvsroot,name) except: cmd="cvs co "+name os.system(cmd) print "*"*50,"\n" menu()