mirror of https://github.com/apache/openjpa.git
180 lines
6.4 KiB
Python
180 lines
6.4 KiB
Python
|
#!/usr/bin/python
|
||
|
"""
|
||
|
Licensed to the Apache Software Foundation (ASF) under one
|
||
|
or more contributor license agreements. See the NOTICE file
|
||
|
distributed with this work for additional information
|
||
|
regarding copyright ownership. The ASF licenses this file
|
||
|
to you under the Apache License, Version 2.0 (the
|
||
|
"License"); you may not use this file except in compliance
|
||
|
with the License. You may obtain a copy of the License at
|
||
|
|
||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||
|
|
||
|
Unless required by applicable law or agreed to in writing,
|
||
|
software distributed under the License is distributed on an
|
||
|
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||
|
KIND, either express or implied. See the License for the
|
||
|
specific language governing permissions and limitations
|
||
|
under the License.
|
||
|
"""
|
||
|
|
||
|
from optparse import OptionParser
|
||
|
from zipfile import ZipFile
|
||
|
from subprocess import Popen,PIPE
|
||
|
from glob import glob
|
||
|
import os,re
|
||
|
|
||
|
def main() :
|
||
|
usage= "usage: %prog [optons]"
|
||
|
description = "Generate a jar file which contains the OpenJPA class files which have been changed. The output from svn info and svn diff may also be included. A typical \
|
||
|
use is to run from the same directory as the parent pom. This will automatically include all changed files with a .java extension."
|
||
|
version = "$prog 0.5"
|
||
|
parser = OptionParser(usage=usage, version=version, description = description)
|
||
|
parser.add_option("-f", "--files", dest="files", help="list of filenames to include")
|
||
|
parser.add_option("-p", "--patchfile", dest="patchfile", help="patch file name", default="patch.jar")
|
||
|
parser.add_option("-i", "--noinfo", action="store_false", dest="includeInfo", help="exclude output from svn info", default=True)
|
||
|
parser.add_option("-d", "--nodiff", action="store_false", dest="includeDiff", help="exclude output from svn diff",default=True)
|
||
|
parser.add_option("-v", "--verbose", action="store_true", dest="verbose", help="print debug information",default=False)
|
||
|
# parser.add_option("-p", "--pattern", dest="pattern", help="regex of filenames to match")
|
||
|
|
||
|
global options
|
||
|
(options,args) = parser.parse_args()
|
||
|
|
||
|
genZip(options)
|
||
|
|
||
|
def genZip(options):
|
||
|
""" generate the zip file """
|
||
|
if options.files == None:
|
||
|
files = getAllFiles()
|
||
|
else :
|
||
|
files = getFilesFromList(options.files)
|
||
|
|
||
|
zip = ZipFile(options.patchfile, 'w')
|
||
|
|
||
|
if options.includeInfo:
|
||
|
writeInfo(zip, files)
|
||
|
if options.includeDiff:
|
||
|
writeDiff(zip, files)
|
||
|
|
||
|
writeClasses(zip, files)
|
||
|
|
||
|
zip.close()
|
||
|
|
||
|
print 'Wrote patch to %s. ' % (options.patchfile)
|
||
|
if options.verbose:
|
||
|
print 'Files in patch: %s' % ("\n".join(files))
|
||
|
|
||
|
def getAllFiles():
|
||
|
""" get the list of all modified files. Only Added or Modified .java, .properties files will be considered """
|
||
|
if options.verbose:
|
||
|
print ' > getAllFiles'
|
||
|
files = []
|
||
|
|
||
|
commandOutput = Popen(['svn', 'stat'], stdout=PIPE).communicate()[0].splitlines()
|
||
|
prog = re.compile('([A|M] *)(.*\.java)')
|
||
|
for candidate in commandOutput:
|
||
|
match = prog.match(candidate)
|
||
|
if match :
|
||
|
files.append(match.group(2))
|
||
|
|
||
|
prog = re.compile('([A|M] *)(.*\.properties)')
|
||
|
for candidate in commandOutput:
|
||
|
match = prog.match(candidate)
|
||
|
if match :
|
||
|
files.append(match.group(2))
|
||
|
|
||
|
|
||
|
if options.verbose:
|
||
|
print 'Found modified files : ' + str(files)
|
||
|
print ' < getAllFiles'
|
||
|
return files
|
||
|
|
||
|
def getFilesFromList(files) :
|
||
|
""" get a list of modified files from a comma separated list usually from the command line """
|
||
|
|
||
|
if options.verbose :
|
||
|
print ' > getFilesFromList'
|
||
|
print ' returning ' + str(files.split(','))
|
||
|
print ' < getFilesFromList'
|
||
|
|
||
|
return files.split(',')
|
||
|
|
||
|
def writeInfo(zip, files=None):
|
||
|
""" write the output of svn info to a temp file and store in a zip """
|
||
|
if options.verbose :
|
||
|
print ' > writeInfo'
|
||
|
|
||
|
patchFile = open('info.txt', 'w')
|
||
|
args = ['svn', 'info']
|
||
|
|
||
|
if files:
|
||
|
args.extend(files)
|
||
|
|
||
|
Popen(args=args, stdout=patchFile).communicate()[0]
|
||
|
|
||
|
zip.write(patchFile.name)
|
||
|
patchFile.close()
|
||
|
os.remove(patchFile.name)
|
||
|
|
||
|
if options.verbose:
|
||
|
print ' < writeInfo'
|
||
|
|
||
|
def writeDiff(zip, files=None):
|
||
|
""" Write the output of svn diff to a temp file and store in a zip """
|
||
|
if options.verbose:
|
||
|
print ' > writeDiff'
|
||
|
|
||
|
patchFile = open('patch.txt', 'w')
|
||
|
args = ['svn', 'diff']
|
||
|
if files:
|
||
|
args.extend(files)
|
||
|
|
||
|
Popen(args=args, stdout=patchFile).communicate()[0]
|
||
|
|
||
|
zip.write(patchFile.name)
|
||
|
patchFile.close()
|
||
|
os.remove(patchFile.name)
|
||
|
|
||
|
if options.verbose:
|
||
|
print ' < writeDiff'
|
||
|
|
||
|
def javaToClass(file) :
|
||
|
""" simple helper function, converts a string from svn stat (or command line) to its corresponding
|
||
|
.class file
|
||
|
"""
|
||
|
|
||
|
rval = file.replace('src','target').replace('main','classes').replace('test','test-classes').replace('.java', '.class').replace('java','').replace('\\\\','\\')
|
||
|
return rval;
|
||
|
|
||
|
def javaToInnerClass(file):
|
||
|
""" helper function, converts .java file to a glob pattern that matches inner classes """
|
||
|
return javaToClass(file).replace('.class', '$*.class')
|
||
|
|
||
|
def writeClasses(zip, files=None):
|
||
|
""" Write class files to a zip """
|
||
|
|
||
|
prog = re.compile('(.*classes.)(.*)')
|
||
|
propertiesProg = re.compile('(.*resources.)(.*)')
|
||
|
|
||
|
for file in files :
|
||
|
if str(file).endswith('.java'):
|
||
|
for globMatch in glob(javaToClass(file)) :
|
||
|
if(prog.match(globMatch)):
|
||
|
target = prog.match(globMatch).group(2)
|
||
|
zip.write(os.path.realpath(globMatch), target)
|
||
|
|
||
|
# match again on inner classes, not sure if glob supports optional matches.
|
||
|
for globMatch in glob(javaToInnerClass(file)) :
|
||
|
if(prog.match(globMatch)):
|
||
|
target = prog.match(globMatch).group(2)
|
||
|
zip.write(os.path.realpath(globMatch), target)
|
||
|
elif str(file).endswith('.properties'):
|
||
|
for globMatch in glob(file) :
|
||
|
if(propertiesProg.match(globMatch)):
|
||
|
target = propertiesProg.match(globMatch).group(2)
|
||
|
zip.write(os.path.realpath(globMatch), target)
|
||
|
|
||
|
if __name__ == "__main__":
|
||
|
main()
|
||
|
|