def bump_version(new_version): """Set new base version to base version file and commit""" v = utils.get_vcs_info() mode = utils.get_build_mode() # Check that new base version is valid python_version(new_version, v, mode) repo = utils.get_repository() toplevel = repo.working_dir old_version = get_base_version(v) sys.stdout.write("Current base version is '%s'\n" % old_version) version_file = os.path.join(toplevel, "version") sys.stdout.write("Updating version file %s from version '%s' to '%s'\n" % (version_file, old_version, new_version)) f = open(version_file, "rw+") lines = f.readlines() for i in range(0, len(lines)): if not lines[i].startswith("#"): lines[i] = lines[i].replace(old_version, new_version) f.seek(0) f.truncate(0) f.writelines(lines) f.close() repo.git.add(version_file) repo.git.commit(m="Bump version to %s" % new_version) sys.stdout.write("Update version file and commited\n")
def update_version(): """Generate or replace version files Helper function for generating/replacing version files containing version information. """ v = utils.get_vcs_info() toplevel = v.toplevel config = utils.get_config() if not v: # Return early if not in development environment raise RuntimeError("Can not compute version outside of a git" " repository.") b = get_base_version(v) mode = utils.get_build_mode() version = python_version(b, v, mode) debian_version_ = debian_version_from_python_version(version) env = { "DEVFLOW_VERSION": version, "DEVFLOW_DEBIAN_VERSION": debian_version_, "DEVFLOW_BRANCH": v.branch, "DEVFLOW_REVISION_ID": v.revid, "DEVFLOW_REVISION_NUMBER": v.revno, "DEVFLOW_USER_EMAIL": v.email, "DEVFLOW_USER_NAME": v.name, } for _pkg_name, pkg_info in config["packages"].items(): version_filename = pkg_info.get("version_file") if not version_filename: continue version_template = pkg_info.get("version_template") if version_template: vtemplate_file = os.path.join(toplevel, version_template) try: with file(vtemplate_file) as f: content = f.read(-1) % env except IOError as e: if e.errno == 2: raise RuntimeError( "devflow.conf contains '%s' as a" " version template file, but file does" " not exists!" % vtemplate_file ) else: raise else: content = DEFAULT_VERSION_FILE % env with file(os.path.join(toplevel, version_filename), "w+") as f: log.info("Updating version file '%s'" % version_filename) f.write(content)
def main(): v = utils.get_vcs_info() b = get_base_version(v) mode = utils.get_build_mode() try: arg = sys.argv[1] assert arg == "python" or arg == "debian" except IndexError: raise ValueError("A single argument, 'python' or 'debian is required") if arg == "python": print python_version(b, v, mode) elif arg == "debian": print debian_version(b, v, mode)
def update_version(): """Generate or replace version files Helper function for generating/replacing version files containing version information. """ v = utils.get_vcs_info() toplevel = v.toplevel config = utils.get_config() if not v: # Return early if not in development environment raise RuntimeError("Can not compute version outside of a git" " repository.") b = get_base_version(v) check_obsolete_version(b) mode = utils.get_build_mode() version = python_version(b, v, mode) debian_version_ = debian_version_from_python_version(version) env = {"DEVFLOW_VERSION": version, "DEVFLOW_DEBIAN_VERSION": debian_version_, "DEVFLOW_BRANCH": v.branch, "DEVFLOW_REVISION_ID": v.revid, "DEVFLOW_REVISION_NUMBER": v.revno, "DEVFLOW_USER_EMAIL": v.email, "DEVFLOW_USER_NAME": v.name} for _pkg_name, pkg_info in config['packages'].items(): if pkg_info.get("version_file"): version_filenames = pkg_info.as_list("version_file") else: continue if pkg_info.get('version_template'): version_templates = pkg_info.as_list("version_template") else: version_templates = itertools.repeat(None, len(version_filenames)) version_templates = list(version_templates) if len(version_filenames) != len(version_templates): raise RuntimeError( "devflow.conf contains '%s' version files and '%s' version " "templates. The number of version files and templates must " "match." % (len(version_filenames), len(version_templates))) v_files_templates = zip(version_filenames, version_templates) for (vfilename, vtemplate) in v_files_templates: if vtemplate: vtemplate_file = os.path.join(toplevel, vtemplate) try: with file(vtemplate_file) as f: content = f.read(-1) % env except IOError as e: if e.errno == 2: raise RuntimeError("devflow.conf contains '%s' as a" " version template file, but file" " does not exists!" % vtemplate_file) else: raise else: content = DEFAULT_VERSION_FILE % env with file(os.path.join(toplevel, vfilename), 'w+') as f: log.info("Updating version file '%s'" % vfilename) f.write(content)
def get_debian_version(): v = utils.get_vcs_info() b = get_base_version(v) mode = utils.get_build_mode() return debian_version(b, v, mode)
def main(): from devflow.version import __version__ # pylint: disable=E0611,F0401 parser = OptionParser(usage="usage: %prog [options] mode", version="devflow %s" % __version__, add_help_option=False) parser.add_option("-h", "--help", action="store_true", default=False, help="show this help message") parser.add_option("-k", "--keep-repo", action="store_true", dest="keep_repo", default=False, help="Do not delete the cloned repository") parser.add_option("-b", "--build-dir", dest="build_dir", default=None, help="Directory to store created pacakges") parser.add_option("-r", "--repo-dir", dest="repo_dir", default=None, help="Directory to clone repository") parser.add_option("-d", "--dirty", dest="force_dirty", default=False, action="store_true", help="Do not check if working directory is dirty") parser.add_option("-c", "--config-file", dest="config_file", help="Override default configuration file") parser.add_option("--no-sign", dest="sign", action="store_false", default=True, help="Do not sign the packages") parser.add_option("--key-id", dest="keyid", help="Use this keyid for gpg signing") parser.add_option("--dist", dest="dist", default=None, help="Force distribution in Debian changelog") parser.add_option("-S", "--source-only", dest="source_only", default=False, action="store_true", help="Specifies a source-only build, no binary packages" " need to be made.") parser.add_option("--debian-branch", dest="debian_branch", default=None, help="Use this debian branch, instead of" "auto-discovering the debian branch to use") parser.add_option("--push-back", dest="push_back", default=False, action="store_true", help="Automatically push branches and tags to repo.") parser.add_option("--color", dest="color_output", default="auto", help="Enable/disable colored output. Default mode is" + " auto, available options are yes/no") (options, args) = parser.parse_args() if options.color_output == "yes": use_colors = True elif options.color_output == "no": use_colors = False else: if sys.stdout.isatty(): use_colors = True else: use_colors = False red = lambda x: x green = lambda x: x if use_colors: try: import colors red = colors.red green = colors.green except AttributeError: pass print_red = lambda x: sys.stdout.write(red(x) + "\n") print_green = lambda x: sys.stdout.write(green(x) + "\n") if options.help: print_help(parser.get_prog_name()) parser.print_help() return # Get build mode try: mode = args[0] except IndexError: mode = utils.get_build_mode() if mode not in AVAILABLE_MODES: raise ValueError(red("Invalid argument! Mode must be one: %s" % ", ".join(AVAILABLE_MODES))) # Load the repository original_repo = utils.get_repository() # Check that repository is clean toplevel = original_repo.working_dir if original_repo.is_dirty() and not options.force_dirty: raise RuntimeError(red("Repository %s is dirty." % toplevel)) # Get packages from configuration file config = utils.get_config(options.config_file) packages = config['packages'].keys() print_green("Will build the following packages:\n" + "\n".join(packages)) # Get current branch name and type and check if it is a valid one branch = original_repo.head.reference.name branch = utils.undebianize(branch) branch_type_str = utils.get_branch_type(branch) if branch_type_str not in BRANCH_TYPES.keys(): allowed_branches = ", ".join(BRANCH_TYPES.keys()) raise ValueError("Malformed branch name '%s', cannot classify as" " one of %s" % (branch, allowed_branches)) # Fix needed environment variables v = utils.get_vcs_info() os.environ["DEVFLOW_BUILD_MODE"] = mode os.environ["DEBFULLNAME"] = v.name os.environ["DEBEMAIL"] = v.email # Check that base version file and branch are correct versioning.get_python_version() # Get the debian branch if options.debian_branch: debian_branch = options.debian_branch else: debian_branch = utils.get_debian_branch(branch) origin_debian = "origin/" + debian_branch # Clone the repo repo_dir = options.repo_dir or create_temp_directory("df-repo") repo_dir = os.path.abspath(repo_dir) repo = original_repo.clone(repo_dir, branch=branch) print_green("Cloned repository to '%s'." % repo_dir) build_dir = options.build_dir or create_temp_directory("df-build") build_dir = os.path.abspath(build_dir) print_green("Build directory: '%s'" % build_dir) # Create the debian branch repo.git.branch(debian_branch, origin_debian) print_green("Created branch '%s' to track '%s'" % (debian_branch, origin_debian)) # Go to debian branch repo.git.checkout(debian_branch) print_green("Changed to branch '%s'" % debian_branch) # Merge with starting branch repo.git.merge(branch) print_green("Merged branch '%s' into '%s'" % (branch, debian_branch)) # Compute python and debian version cd(repo_dir) python_version = versioning.get_python_version() debian_version = versioning.\ debian_version_from_python_version(python_version) print_green("The new debian version will be: '%s'" % debian_version) # Update the version files versioning.update_version() if not options.sign: sign_tag_opt = None elif options.keyid: sign_tag_opt = "-u=%s" % options.keyid elif mode == "release": sign_tag_opt = "-s" else: sign_tag_opt = None # Tag branch with python version branch_tag = python_version tag_message = "%s version %s" % (mode.capitalize(), python_version) try: repo.git.tag(branch_tag, branch, sign_tag_opt, "-m %s" % tag_message) except GitCommandError: # Tag may already exist, if only the debian branch has changed pass upstream_tag = "upstream/" + branch_tag repo.git.tag(upstream_tag, branch) # Update changelog dch = git_dch("--debian-branch=%s" % debian_branch, "--git-author", "--ignore-regex=\".*\"", "--multimaint-merge", "--since=HEAD", "--new-version=%s" % debian_version) print_green("Successfully ran '%s'" % " ".join(dch.cmd)) if options.dist is not None: distribution = options.dist elif mode == "release": distribution = utils.get_distribution_codename() else: distribution = "unstable" f = open("debian/changelog", 'r+') lines = f.readlines() lines[0] = lines[0].replace("UNRELEASED", distribution) lines[2] = lines[2].replace("UNRELEASED", "%s build" % mode) f.seek(0) f.writelines(lines) f.close() if mode == "release": call("vim debian/changelog") # Add changelog to INDEX repo.git.add("debian/changelog") # Commit Changes repo.git.commit("-s", "debian/changelog", m="Bump version to %s" % debian_version) # Tag debian branch debian_branch_tag = "debian/" + utils.version_to_tag(debian_version) tag_message = "%s version %s" % (mode.capitalize(), debian_version) if mode == "release": repo.git.tag(debian_branch_tag, sign_tag_opt, "-m %s" % tag_message) # Create debian packages cd(repo_dir) version_files = [] for _, pkg_info in config['packages'].items(): if pkg_info.get("version_file"): version_files.extend(pkg_info.as_list('version_file')) # Add version.py files to repo repo.git.add("-f", *version_files) # Export version info to debuilg environment os.environ["DEB_DEVFLOW_DEBIAN_VERSION"] = debian_version os.environ["DEB_DEVFLOW_VERSION"] = python_version build_cmd = "git-buildpackage --git-export-dir=%s"\ " --git-upstream-branch=%s --git-debian-branch=%s"\ " --git-export=INDEX --git-ignore-new -sa"\ " --source-option=--auto-commit"\ " --git-upstream-tag=%s"\ % (build_dir, branch, debian_branch, upstream_tag) if options.source_only: build_cmd += " -S" if not options.sign: build_cmd += " -uc -us" elif options.keyid: build_cmd += " -k\"'%s'\"" % options.keyid call(build_cmd) # Remove cloned repo if mode != 'release' and not options.keep_repo: print_green("Removing cloned repo '%s'." % repo_dir) rm("-r", repo_dir) # Print final info info = (("Version", debian_version), ("Upstream branch", branch), ("Upstream tag", branch_tag), ("Debian branch", debian_branch), ("Debian tag", debian_branch_tag), ("Repository directory", repo_dir), ("Packages directory", build_dir)) print_green("\n".join(["%s: %s" % (name, val) for name, val in info])) # Print help message if mode == "release": origin = original_repo.remote().url repo.create_remote("original_origin", origin) print_green("Created remote 'original_origin' for the repository '%s'" % origin) print_green("To update repositories '%s' and '%s' go to '%s' and run:" % (toplevel, origin, repo_dir)) for remote in ['origin', 'original_origin']: objects = [debian_branch, branch_tag, debian_branch_tag] print_green("git push %s %s" % (remote, " ".join(objects))) if options.push_back: objects = [debian_branch, branch_tag, debian_branch_tag] repo.git.push("origin", *objects) print_green("Automatically updated origin repo.")