summaryrefslogtreecommitdiff
path: root/scripts
diff options
context:
space:
mode:
authorDamien Regad <dregad@mantisbt.org>2016-09-19 17:48:42 +0200
committerDamien Regad <dregad@mantisbt.org>2016-09-20 08:29:42 +0200
commit49254f2f2f13fb0d28b518f0bcacd29f3c623b66 (patch)
treeb3885b82cec0ea3a510dcf902266f1bcec5b5ff0 /scripts
parente5b5773c387b0b7e4c651cf54b0b51fc6a362f96 (diff)
downloadadodb-49254f2f2f13fb0d28b518f0bcacd29f3c623b66.tar.gz
adodb-49254f2f2f13fb0d28b518f0bcacd29f3c623b66.tar.bz2
adodb-49254f2f2f13fb0d28b518f0bcacd29f3c623b66.zip
Align release scripts with master branch
Diffstat (limited to 'scripts')
-rwxr-xr-xscripts/buildrelease.py34
-rwxr-xr-xscripts/updateversion.py183
-rwxr-xr-xscripts/uploadrelease.py149
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()