| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270 |
- #!/usr/bin/python -u
- '''
- ADOdb release build script
- - Create release tag if it does not exist
- - Copy release files to target directory
- - Generate zip/tar balls
- -
- '''
- import errno
- import getopt
- import re
- import os
- from os import path
- import shutil
- import subprocess
- import sys
- import tempfile
- import updateversion
- # ADOdb Repository reference
- origin_repo = "https://github.com/ADOdb/ADOdb.git"
- release_branch = "master"
- release_prefix = "adodb"
- # Directories and files to exclude from release tarballs
- exclude_list = (".git*",
- "replicate",
- "scripts",
- "tests",
- # There are no png files in there...
- # "cute_icons_for_site/*.png",
- "hs~*.*",
- "adodb-text.inc.php",
- # This file does not exist in current repo
- # 'adodb-lite.inc.php'
- )
- # Command-line options
- options = "hb:dfk"
- long_options = ["help", "branch", "debug", "fresh", "keep"]
- # Global flags
- debug_mode = False
- fresh_clone = False
- cleanup = True
- def usage():
- print '''Usage: %s [options] version release_path
- Parameters:
- version ADOdb version to bundle (e.g. v5.19)
- release_path Where to save the release tarballs
- Options:
- -h | --help Show this usage message
- -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
- -k | --keep Keep build directories after completion
- (useful for debugging)
- ''' % (
- path.basename(__file__),
- release_branch
- )
- #end usage()
- def set_version_and_tag(version):
- '''
- '''
- global release_branch, debug_mode, fresh_clone, cleanup
- # Delete existing tag to force creation in debug mode
- if debug_mode:
- try:
- updateversion.tag_delete(version)
- except:
- pass
- # Checkout release branch
- subprocess.call("git checkout %s" % release_branch, shell=True)
- if not debug_mode:
- # Make sure we're up-to-date, ignore untracked files
- ret = subprocess.check_output(
- "git status --branch --porcelain --untracked-files=no",
- shell=True
- )
- if not re.search(release_branch + "$", ret):
- print "\nERROR: branch must be aligned with upstream"
- sys.exit(4)
- # Update the code, create commit and tag
- updateversion.version_set(version)
- # Make sure we don't delete the modified repo
- if fresh_clone:
- cleanup = False
- def main():
- global release_branch, debug_mode, fresh_clone, cleanup
- # Get command-line options
- try:
- opts, args = getopt.gnu_getopt(sys.argv[1:], options, long_options)
- except getopt.GetoptError, err:
- print str(err)
- usage()
- sys.exit(2)
- if len(args) < 2:
- usage()
- print "ERROR: please specify the version and release_path"
- sys.exit(1)
- for opt, val in opts:
- if opt in ("-h", "--help"):
- usage()
- sys.exit(0)
- elif opt in ("-b", "--branch"):
- release_branch = val
- elif opt in ("-d", "--debug"):
- debug_mode = True
- elif opt in ("-f", "--fresh"):
- fresh_clone = True
- elif opt in ("-k", "--keep"):
- cleanup = False
- # Mandatory parameters
- version = updateversion.version_check(args[0])
- release_path = args[1]
- # 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
- )
- if debug_mode:
- print "DEBUG MODE: ignoring upstream repository status"
- if fresh_clone:
- # Create a new repo clone
- print "Cloning a new repository"
- repo_path = tempfile.mkdtemp(prefix=release_prefix + "-",
- suffix=".git")
- subprocess.call(
- "git clone %s %s" % (origin_repo, repo_path),
- shell=True
- )
- os.chdir(repo_path)
- else:
- repo_path = subprocess.check_output('git root', shell=True).rstrip()
- os.chdir(repo_path)
- # Check for any uncommitted changes
- try:
- subprocess.check_output(
- "git diff --exit-code && "
- "git diff --cached --exit-code",
- shell=True
- )
- except:
- print "ERROR: there are uncommitted changes in the repository"
- sys.exit(3)
- # Update the repository
- if not debug_mode:
- print "Updating repository in '%s'" % os.getcwd()
- try:
- subprocess.check_output("git fetch", shell=True)
- except:
- print "ERROR: unable to fetch\n"
- sys.exit(3)
- # Check existence of Tag for version in repo, create if not found
- try:
- updateversion.tag_check(version)
- if debug_mode:
- set_version_and_tag(version)
- except:
- set_version_and_tag(version)
- # Copy files to release dir
- 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:
- shutil.copytree(
- repo_path,
- release_tmp_dir,
- ignore=shutil.ignore_patterns(*exclude_list)
- )
- break
- except OSError, err:
- # First try and file exists, try to delete dir
- if retry and err.errno == errno.EEXIST:
- print "WARNING: Directory '%s' exists, delete it and retry" % (
- release_tmp_dir
- )
- shutil.rmtree(release_tmp_dir)
- retry = False
- continue
- else:
- # We already tried to delete or some other error occured
- raise
- # Create tarballs
- print "Creating release tarballs..."
- 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_files),
- shell=True
- )
- print "- zip"
- subprocess.call(
- "zip -rq %s.zip %s" % (release_name, release_files),
- shell=True
- )
- if cleanup:
- print "Deleting working directories"
- shutil.rmtree(release_tmp_dir)
- if fresh_clone:
- shutil.rmtree(repo_path)
- else:
- print "\nThe following working directories were kept:"
- if fresh_clone:
- print "- '%s' (repo clone)" % repo_path
- print "- '%s' (release temp dir)" % release_tmp_dir
- print "Delete them manually when they are no longer needed."
- # Done
- print "\nADOdb release %s build complete, files saved in '%s'." % (
- version,
- release_path
- )
- print "Don't forget to generate a README file with the changelog"
- #end main()
- if __name__ == "__main__":
- main()
|