diff options
| author | Damien Regad <dregad@mantisbt.org> | 2016-09-19 17:48:42 +0200 |
|---|---|---|
| committer | Damien Regad <dregad@mantisbt.org> | 2016-09-20 08:29:42 +0200 |
| commit | 49254f2f2f13fb0d28b518f0bcacd29f3c623b66 (patch) | |
| tree | b3885b82cec0ea3a510dcf902266f1bcec5b5ff0 /scripts | |
| parent | e5b5773c387b0b7e4c651cf54b0b51fc6a362f96 (diff) | |
| download | adodb-49254f2f2f13fb0d28b518f0bcacd29f3c623b66.tar.gz adodb-49254f2f2f13fb0d28b518f0bcacd29f3c623b66.tar.bz2 adodb-49254f2f2f13fb0d28b518f0bcacd29f3c623b66.zip | |
Align release scripts with master branch
Diffstat (limited to 'scripts')
| -rwxr-xr-x | scripts/buildrelease.py | 34 | ||||
| -rwxr-xr-x | scripts/updateversion.py | 183 | ||||
| -rwxr-xr-x | scripts/uploadrelease.py | 149 |
3 files changed, 257 insertions, 109 deletions
diff --git a/scripts/buildrelease.py b/scripts/buildrelease.py index ca2f8bc0..0b37b97b 100755 --- a/scripts/buildrelease.py +++ b/scripts/buildrelease.py @@ -59,7 +59,8 @@ def usage(): Options: -h | --help Show this usage message - -b | --branch <branch> Use specified branch (defaults to %s) + -b | --branch <branch> Use specified branch (defaults to '%s' for '.0' + releases, or 'hotfix/<version>' for patches) -d | --debug Debug mode (ignores upstream: no fetch, allows build even if local branch is not in sync) -f | --fresh Create a fresh clone of the repository @@ -88,9 +89,9 @@ def set_version_and_tag(version): subprocess.call("git checkout %s" % release_branch, shell=True) if not debug_mode: - # Make sure we're up-to-date + # Make sure we're up-to-date, ignore untracked files ret = subprocess.check_output( - "git status --branch --porcelain", + "git status --branch --porcelain --untracked-files=no", shell=True ) if not re.search(release_branch + "$", ret): @@ -142,12 +143,15 @@ def main(): version = updateversion.version_check(args[0]) release_path = args[1] - global release_prefix - release_prefix += version.split(".")[0] + # Default release branch + if updateversion.version_is_patch(version): + release_branch = 'hotfix/' + version # ------------------------------------------------------------------------- # Start the build # + global release_prefix + print "Building ADOdb release %s into '%s'\n" % ( version, release_path @@ -199,8 +203,9 @@ def main(): set_version_and_tag(version) # Copy files to release dir - release_tmp_dir = path.join(release_path, release_prefix) - print "Copying files to '%s'" % release_path + release_files = release_prefix + version.split(".")[0] + release_tmp_dir = path.join(release_path, release_files) + print "Copying release files to '%s'" % release_tmp_dir retry = True while True: try: @@ -225,28 +230,21 @@ def main(): # Create tarballs print "Creating release tarballs..." - release_name = release_prefix + version.split(".")[1] + release_name = release_prefix + '-' + version + print release_prefix, version, release_name os.chdir(release_path) print "- tar" subprocess.call( - "tar -czf %s.tar.gz %s" % (release_name, release_prefix), + "tar -czf %s.tar.gz %s" % (release_name, release_files), shell=True ) print "- zip" subprocess.call( - "zip -rq %s.zip %s" % (release_name, release_prefix), + "zip -rq %s.zip %s" % (release_name, release_files), shell=True ) - print "Copying documentation" - docs = path.join(release_path, "docs") - shutil.rmtree(docs, ignore_errors=True) - shutil.copytree( - path.join(release_tmp_dir, "docs"), - path.join(release_path, "docs") - ) - if cleanup: print "Deleting working directories" shutil.rmtree(release_tmp_dir) diff --git a/scripts/updateversion.py b/scripts/updateversion.py index 97f3b5fc..0c39fd53 100755 --- a/scripts/updateversion.py +++ b/scripts/updateversion.py @@ -2,7 +2,7 @@ ''' ADOdb version update script - Updates the version number, and release date in all php, txt and htm files + Updates the version number, and release date in all php and html files ''' from datetime import date @@ -15,8 +15,9 @@ import sys # ADOdb version validation regex +# These are used by sed - they are not PCRE ! _version_dev = "dev" -_version_regex = "[Vv]?[0-9]\.[0-9]+(%s|[a-z]|\.[0-9])?" % _version_dev +_version_regex = "[Vv]?([0-9]\.[0-9]+)(\.([0-9]+))?(-?%s)?" % _version_dev _release_date_regex = "[0-9?]+-.*-[0-9]+" _changelog_file = "docs/changelog.md" @@ -44,24 +45,59 @@ def usage(): #end usage() +def version_is_dev(version): + ''' Returns true if version is a development release + ''' + return version.endswith(_version_dev) + + +def version_is_patch(version): + ''' Returns true if version is a patch release (i.e. X.Y.Z with Z > 0) + ''' + return not version.endswith('.0') + + +def version_parse(version): + ''' Breakdown the version into groups (Z and -dev are optional) + 1:(X.Y), 2:(.Z), 3:(Z), 4:(-dev) + ''' + return re.match(r'^%s$' % _version_regex, version) + + def version_check(version): ''' Checks that the given version is valid, exits with error if not. - Returns the version without the "v" prefix + Returns the SemVer-normalized version without the "v" prefix + - add '.0' if missing patch bit + - add '-' before dev release suffix if needed ''' - if not re.search("^%s$" % _version_regex, version): + vparse = version_parse(version) + if not vparse: usage() print "ERROR: invalid version ! \n" sys.exit(1) - return version.lstrip("Vv") + vnorm = vparse.group(1) + + # Add .patch version component + if vparse.group(2): + vnorm += vparse.group(2) + else: + # None was specified, assume a .0 release + vnorm += '.0' + # Normalize version number + if version_is_dev(version): + vnorm += '-' + _version_dev -def release_date(version): + return vnorm + + +def get_release_date(version): ''' Returns the release date in DD-MMM-YYYY format For development releases, DD-MMM will be ??-??? ''' # Development release - if version.endswith(_version_dev): + if version_is_dev(version): date_format = "??-???-%Y" else: date_format = "%d-%b-%Y" @@ -75,11 +111,11 @@ def sed_script(version): ''' # Version number and release date - script = "s/%s\s+%s/v%s %s/\n" % ( + script = r"s/{}\s+(-?)\s+{}/v{} \5 {}/".format( _version_regex, _release_date_regex, version, - release_date(version) + get_release_date(version) ) return script @@ -88,13 +124,15 @@ def sed_script(version): def sed_filelist(): ''' Build list of files to update ''' - def sed_filter(name): - return name.lower().endswith((".php", ".htm", ".txt")) - dirlist = [] for root, dirs, files in os.walk(".", topdown=True): - for name in filter(sed_filter, files): - dirlist.append(path.join(root, name)) + # Filter files by extensions + files = [ + f for f in files + if re.search(r'\.(php|html?)$', f, re.IGNORECASE) + ] + for fname in files: + dirlist.append(path.join(root, fname)) return dirlist @@ -133,7 +171,7 @@ def tag_create(version): "git tag --sign --message '%s' %s" % ( "ADOdb version %s released %s" % ( version, - release_date(version) + get_release_date(version) ), tag_name(version) ), @@ -142,52 +180,120 @@ def tag_create(version): return result == 0 +def section_exists(filename, version, print_message=True): + ''' Checks given file for existing section with specified version + ''' + script = True + for i, line in enumerate(open(filename)): + if re.search(r'^## ' + version, line): + if print_message: + print " Existing section for v%s found," % version, + return True + return False + + +def version_get_previous(version): + ''' Returns the previous version number + Don't decrease major versions (raises exception) + ''' + vprev = version.split('.') + item = len(vprev) - 1 + + while item > 0: + val = int(vprev[item]) + if val > 0: + vprev[item] = str(val - 1) + break + else: + item -= 1 + + if item == 0: + raise ValueError('Refusing to decrease major version number') + + return '.'.join(vprev) + + def update_changelog(version): ''' Updates the release date in the Change Log ''' print "Updating Changelog" + vparse = version_parse(version) + + # Version number without '-dev' suffix + version_release = vparse.group(1) + vparse.group(2) + version_previous = version_get_previous(version_release) + + if not section_exists(_changelog_file, version_previous, False): + raise ValueError( + "ERROR: previous version %s does not exist in changelog" % + version_previous + ) + + # Check if version already exists in changelog + version_exists = section_exists(_changelog_file, version_release) + if (not version_exists + and not version_is_patch(version) + and not version_is_dev(version)): + version += '-' + _version_dev + + release_date = get_release_date(version) + # Development release # Insert a new section for next release before the most recent one - if version.endswith(_version_dev): - version_release = version[:-len(_version_dev)] + if version_is_dev(version): + # Check changelog file for existing section + if version_exists: + print "nothing to do" + return - version_previous = version_release.split(".") - version_previous[1] = str(int(version_previous[1]) - 1) - version_previous = ".".join(version_previous) - - print " Inserting new section for v%s" % version_release - script = "1,/^##/s/^##.*$/## %s - %s\\n\\n\\0/" % ( + # No existing section found, insert new one + if version_is_patch(version_release): + print " Inserting new section for hotfix release v%s" % version + else: + print " Inserting new section for v%s" % version_release + # Adjust previous version number (remove patch component) + version_previous = version_parse(version_previous).group(1) + script = "1,/^## {0}/s/^## {0}.*$/## {1} - {2}\\n\\n\\0/".format( + version_previous, version_release, - release_date(version) + release_date ) - # Stable release (X.Y.0 or X.Y) - # Replace the occurence of markdown level 2 header matching version + # Stable release (X.Y.0) + # Replace the 1st occurence of markdown level 2 header matching version # and release date patterns - elif version.endswith(".0") or re.match('[Vv]?[0-9]\.[0-9]+$', version): + elif not version_is_patch(version): print " Updating release date for v%s" % version - script = "1,/^##/s/^(## )%s - %s.*$/\\1%s - %s/" % ( - _version_regex, + script = r"s/^(## ){0}(\.0)? - {1}.*$/\1{2} - {3}/".format( + vparse.group(1), _release_date_regex, version, - release_date(version) + release_date ) - # Hotfix release (X.Y.[0-9] or X.Y[a-z]) + # Hotfix release (X.Y.[0-9]) # Insert a new section for the hotfix release before the most recent # section for version X.Y and display a warning message else: - version_parent = re.match('[Vv]?([0-9]\.[0-9]+)', version).group(1) - print " Inserting new section for hotfix release v%s" % version + if version_exists: + print 'updating release date' + script = "s/^## {0}.*$/## {1} - {2}/".format( + version.replace('.', '\.'), + version, + release_date + ) + else: + print " Inserting new section for hotfix release v%s" % version + script = "1,/^## {0}/s/^## {0}.*$/## {1} - {2}\\n\\n\\0/".format( + version_previous, + version, + release_date + ) + print " WARNING: review '%s' to ensure added section is correct" % ( _changelog_file ) - script = "1,/^## {0}/s/^## {0}.*$/## {1} - {2}\\n\\n\\0/".format( - version_parent, - version, - release_date(version) - ) subprocess.call( "sed -r -i '%s' %s " % ( @@ -284,6 +390,7 @@ def main(): version = version_check(args[0]) # Let's do it + os.chdir(subprocess.check_output('git root', shell=True).rstrip()) version_set(version, do_commit, do_tag) #end main() diff --git a/scripts/uploadrelease.py b/scripts/uploadrelease.py index 8a27a6bb..5b295cbb 100755 --- a/scripts/uploadrelease.py +++ b/scripts/uploadrelease.py @@ -3,23 +3,23 @@ ADOdb release upload script ''' +from distutils.version import LooseVersion import getopt import glob import os from os import path +import re import subprocess import sys # Directories and files to exclude from release tarballs -sf_files = "frs.sourceforge.net:/home/frs/project/adodb" \ - "/adodb-php5-only/adodb-{ver}-for-php5/" -sf_doc = "web.sourceforge.net:/home/project-web/adodb/htdocs/" +sf_files = "frs.sourceforge.net:/home/frs/project/adodb/" rsync_cmd = "rsync -vP --rsh ssh {opt} {src} {usr}@{dst}" # Command-line options -options = "hfd" -long_options = ["help", "files", "doc"] +options = "hn" +long_options = ["help", "dry-run"] def usage(): @@ -35,15 +35,75 @@ def usage(): Options: -h | --help Show this usage message - -f | --files Upload release files only - -d | --doc Upload documentation only + -n | --dry-run Do not upload the files ''' % ( path.basename(__file__) ) #end usage() -def main(): +def call_rsync(usr, opt, src, dst): + ''' Calls rsync to upload files with given parameters + usr = ssh username + opt = options + src = source directory + dst = target directory + ''' + global dry_run + + command = rsync_cmd.format(usr=usr, opt=opt, src=src, dst=dst) + + if dry_run: + print command + else: + subprocess.call(command, shell=True) + + +def get_release_version(): + ''' Get the version number from the zip file to upload + ''' + try: + zipfile = glob.glob('adodb-*.zip')[0] + except IndexError: + print "ERROR: release zip file not found in '%s'" % release_path + sys.exit(1) + + try: + version = re.search( + "^adodb-([\d]+\.[\d]+\.[\d]+)\.zip$", + zipfile + ).group(1) + except AttributeError: + print "ERROR: unable to extract version number from '%s'" % zipfile + print " Only 3 groups of digits separated by periods are allowed" + sys.exit(1) + + return version + + +def sourceforge_target_dir(version): + ''' Returns the sourceforge target directory + Base directory as defined in sf_files global variable, plus + - if version >= 5.21: adodb-X.Y + - for older versions: adodb-XYZ-for-php5 + ''' + # Keep only X.Y (discard patch number) + short_version = version.rsplit('.', 1)[0] + + directory = 'adodb-php5-only/' + if LooseVersion(version) >= LooseVersion('5.21'): + directory += "adodb-" + short_version + else: + directory += "adodb-{}-for-php5".format(short_version.replace('.', '')) + + return directory + + +def process_command_line(): + ''' Retrieve command-line options and set global variables accordingly + ''' + global upload_files, upload_doc, dry_run, username, release_path + # Get command-line options try: opts, args = getopt.gnu_getopt(sys.argv[1:], options, long_options) @@ -57,71 +117,54 @@ def main(): print "ERROR: please specify the Sourceforge user and release_path" sys.exit(1) - upload_files = True - upload_doc = True + # Default values for flags + dry_run = False for opt, val in opts: if opt in ("-h", "--help"): usage() sys.exit(0) - elif opt in ("-f", "--files"): - upload_files = False - - elif opt in ("-d", "--doc"): - upload_doc = False + elif opt in ("-n", "--dry-run"): + dry_run = True # Mandatory parameters username = args[0] + # Change to release directory, current if not specified try: release_path = args[1] os.chdir(release_path) except IndexError: release_path = os.getcwd() - # Get the version number from the zip file to upload - try: - zipfile = glob.glob('*.zip')[0] - except IndexError: - print "ERROR: release zip file not found in '%s' " % release_path - sys.exit(1) - version = zipfile[5:8] + +def upload_release_files(): + ''' Upload release files from source directory to SourceForge + ''' + version = get_release_version() + target = sf_files + sourceforge_target_dir(version) + + print + print "Uploading release files..." + print " Source:", release_path + print " Target: " + target + print + call_rsync( + username, + "", + path.join(release_path, "*"), + target + ) + + +def main(): + process_command_line() # Start upload process print "ADOdb release upload script" - # Upload release files - if upload_files: - target = sf_files.format(ver=version) - print - print "Uploading release files..." - print " Target: " + target - print - subprocess.call( - rsync_cmd.format( - usr=username, - opt="--exclude=docs", - src=path.join(release_path, "*"), - dst=target - ), - shell=True - ) - - # Upload documentation - if upload_doc: - print - print "Uploading documentation..." - print - subprocess.call( - rsync_cmd.format( - usr=username, - opt="", - src=path.join(release_path, "docs", "*"), - dst=sf_doc - ), - shell=True - ) + upload_release_files() #end main() |
