def diff(version, new_version, bump_only=False, no_diff=False, version_tag_style=None): if bump_only or no_diff: return vtag_from = guess.version2tag(version, version_tag_style) vtag_to = guess.version2tag(new_version, version_tag_style) git('--no-pager', 'diff', '--stat', '%s..%s' % (vtag_from, vtag_to), direct=True) try: reqdiff(vtag_from, vtag_to) except Exception: pass raw_input("Press <Enter> to continue after you inspected the diff. ")
def diff(version, new_version, bump_only=False, no_diff=False, version_tag_style=None, unattended=False): if bump_only or no_diff or unattended: return vtag_from = guess.version2tag(version, version_tag_style) vtag_to = guess.version2tag(new_version, version_tag_style) git('--no-pager', 'diff', '--stat', '%s..%s' % (vtag_from, vtag_to), direct=True) try: reqdiff(vtag_from, vtag_to) except Exception: pass input("Press <Enter> to continue after you inspected the diff. ")
def prep_new_patches_branch(new_version, local_patches_branch, patches_branch, local_patches=False, bump_only=False, patches_style=None, version_tag_style=None, unattended=False, no_push_patches=False): if patches_style == 'review': if no_push_patches: return new_version_tag = guess.version2tag(new_version, version_tag_style) try: remote, branch = git.remote_branch_split(patches_branch) if unattended: log.warn('Unattended mode: force pushing patches') else: helpers.confirm("Push %s to %s/%s (with --force)?" % ( new_version_tag, remote, branch)) git('branch', '--force', local_patches_branch, new_version_tag) git('push', '--force', remote, '%s:%s' % (local_patches_branch, branch)) # push the tag git('push', '--force', remote, new_version_tag) except exception.UserAbort: pass else: if not (local_patches or bump_only): _reset_branch(local_patches_branch, remote_branch=patches_branch)
def rebase_patches_branch(new_version, local_patches_branch, patches_branch=None, local_patches=False, patches_style=None, version_tag_style=None, bump_only=False): if bump_only: return git.checkout(local_patches_branch) new_version_tag = guess.version2tag(new_version, version_tag_style) git('rebase', new_version_tag, direct=True) if patches_style != 'review': if local_patches or not patches_branch: return if _is_same_commit(local_patches_branch, patches_branch): log.info("%s is up to date, no need for push." % patches_branch) return try: remote, branch = git.remote_branch_split(patches_branch) helpers.confirm("Push %s to %s / %s (with --force)?" % ( local_patches_branch, remote, branch)) git('push', '--force', remote, '%s:%s' % (local_patches_branch, branch)) # push the tag git('push', '--force', remote, new_version_tag) except exception.UserAbort: pass
def prep_new_patches_branch(new_version, local_patches_branch, patches_branch, local_patches=False, bump_only=False, patches_style=None, version_tag_style=None, unattended=False, no_push_patches=False): if patches_style == 'review': if no_push_patches: return new_version_tag = guess.version2tag(new_version, version_tag_style) try: remote, branch = git.remote_branch_split(patches_branch) if unattended: log.warn('Unattended mode: force pushing patches') else: helpers.confirm("Push %s to %s/%s (with --force)?" % (new_version_tag, remote, branch)) git('branch', '--force', local_patches_branch, new_version_tag) git('push', '--force', remote, '%s:%s' % (local_patches_branch, branch)) # push the tag git('push', '--force', remote, new_version_tag) except exception.UserAbort: pass else: if not (local_patches or bump_only): _reset_branch(local_patches_branch, remote_branch=patches_branch)
def show_patch_log(version, patches_branch, version_tag_style=None): tag = guess.version2tag(version, version_tag_style) patches = git.get_commit_bzs(tag, patches_branch) spec = specfile.Spec() n_excluded = spec.get_n_excluded_patches() print("\nPatches branch {t.bold}{pb}{t.normal} is at version {t.bold}" "{ver}{t.normal}".format(t=log.term, pb=patches_branch, ver=version)) _print_patch_log(patches, tag, n_excluded)
def show_patch_log(version, patches_branch, version_tag_style=None): tag = guess.version2tag(version, version_tag_style) patches = git.get_commit_bzs(tag, patches_branch) spec = specfile.Spec() n_excluded = spec.get_n_excluded_patches() print("\nPatches branch {t.bold}{pb}{t.normal} is at version {t.bold}" "{ver}{t.normal}".format( t=log.term, pb=patches_branch, ver=version)) _print_patch_log(patches, tag, n_excluded)
def check_new_patches(version, local_patches_branch, patches_style=None, local_patches=False, patches_branch=None, changes=None, version_tag_style=None): if not changes: changes = [] if local_patches or patches_style == 'review': head = local_patches_branch else: if not patches_branch: raise exception.RequiredActionArgumentNotAvailable( action='check_new_patches', arg='patches_branch') head = patches_branch version_tag = guess.version2tag(version, version_tag_style) patches = git.get_commit_bzs(version_tag, head) spec = specfile.Spec() n_git_patches = len(patches) n_spec_patches = spec.get_n_patches() n_skip_patches = spec.get_n_excluded_patches() n_ignore_patches = 0 ignore_regex = spec.get_patches_ignore_regex() if ignore_regex: patches = (flatten(_partition_patches(patches, ignore_regex))) n_ignore_patches = n_git_patches - len(patches) patch_subjects = [] for hash, subject, bzs in patches: subj = subject bzstr = ' '.join(map(lambda x: 'rhbz#%s' % x, bzs)) if bzstr != '': subj += ' (%s)' % bzstr patch_subjects.append(subj) n_base_patches = n_skip_patches + n_spec_patches log.debug("Total patches in git:%d spec:%d skip:%d ignore:%d" % ( n_git_patches, n_spec_patches, n_skip_patches, n_ignore_patches)) if n_base_patches > 0: patch_subjects = patch_subjects[0:-n_base_patches] if not patch_subjects: log.warn("No new patches detected in %s." % head) helpers.confirm("Do you want to continue anyway?", default_yes=False) changes.extend(patch_subjects) return {'changes': changes}
def check_new_patches(version, local_patches_branch, patches_style=None, local_patches=False, patches_branch=None, changes=None, version_tag_style=None, changelog=None, no_bump=False): if no_bump: return if not changes: changes = [] if changelog: changelog = changelog.lower() else: # default changelog format changelog = 'detect' if changelog == 'detect' or changelog == 'count': if local_patches or patches_style == 'review': head = local_patches_branch else: if not patches_branch: raise exception.RequiredActionArgumentNotAvailable( action='check_new_patches', arg='patches_branch') head = patches_branch version_tag = guess.version2tag(version, version_tag_style) patches = git.get_commit_bzs(version_tag, head) old_patches = specfile.get_patches_from_files() spec = specfile.Spec() n_git_patches = len(patches) n_ignore_patches = 0 ignore_regex = spec.get_patches_ignore_regex() if ignore_regex: patches = (flatten(_partition_patches(patches, ignore_regex))) n_ignore_patches = n_git_patches - len(patches) n_skip_patches = spec.get_n_excluded_patches() if n_skip_patches > 0: patches = patches[0:-n_skip_patches] log.debug("Total patches in git:%d skip:%d ignore:%d" % ( n_git_patches, n_skip_patches, n_ignore_patches)) if changelog == 'detect': # detect new/old patches by hash/subject def _patch_filter(c): hash, subj, bzs = c for _, old_hash, old_subj in old_patches: if helpers.is_same_hash(hash, old_hash): return False if helpers.is_same_subject(subj, old_subj): # maybe more relaxed match on subjects? return False return True patches = filter(_patch_filter, patches) elif changelog == 'count': # assume no removed patches, include new ones in changelog n_base_patches = n_skip_patches + spec.get_n_patches() if n_base_patches > 0: patches = patches[0:-n_base_patches] for _, subj, bzs in patches: bzstr = ' '.join(map(lambda x: 'rhbz#%s' % x, bzs)) if bzstr: subj += ' (%s)' % bzstr changes.append(subj) elif changelog == 'plain': # just leave a generic message without inspecting commits (see below) pass else: raise exception.InvalidUsage( why="Not a valid changelog format: %s" % changelog) if not changes: changes.append('Update patches') return {'changes': changes}
def check_new_patches(version, local_patches_branch, patches_style=None, local_patches=False, patches_branch=None, changes=None, version_tag_style=None, changelog=None, no_bump=False): if no_bump: return if not changes: changes = [] if changelog: changelog = changelog.lower() else: # default changelog format changelog = 'detect' if changelog == 'detect' or changelog == 'count': if local_patches or patches_style == 'review': head = local_patches_branch else: if not patches_branch: raise exception.RequiredActionArgumentNotAvailable( action='check_new_patches', arg='patches_branch') head = patches_branch version_tag = guess.version2tag(version, version_tag_style) patches = git.get_commit_bzs(version_tag, head) old_patches = specfile.get_patches_from_files() spec = specfile.Spec() n_git_patches = len(patches) n_ignore_patches = 0 ignore_regex = spec.get_patches_ignore_regex() if ignore_regex: patches = (flatten(_partition_patches(patches, ignore_regex))) n_ignore_patches = n_git_patches - len(patches) n_skip_patches = spec.get_n_excluded_patches() if n_skip_patches > 0: patches = patches[0:-n_skip_patches] log.debug("Total patches in git:%d skip:%d ignore:%d" % (n_git_patches, n_skip_patches, n_ignore_patches)) if changelog == 'detect': # detect new/old patches by hash/subject def _patch_filter(c): hash, subj, bzs = c for _, old_hash, old_subj in old_patches: if helpers.is_same_hash(hash, old_hash): return False if helpers.is_same_subject(subj, old_subj): # maybe more relaxed match on subjects? return False return True patches = filter(_patch_filter, patches) elif changelog == 'count': # assume no removed patches, include new ones in changelog n_base_patches = n_skip_patches + spec.get_n_patches() if n_base_patches > 0: patches = patches[0:-n_base_patches] for _, subj, bzs in patches: bzstr = ' '.join(map(lambda x: 'rhbz#%s' % x, bzs)) if bzstr: subj += ' (%s)' % bzstr changes.append(subj) elif changelog == 'plain': # just leave a generic message without inspecting commits (see below) pass else: raise exception.InvalidUsage(why="Not a valid changelog format: %s" % changelog) if not changes: changes.append('Update patches') return {'changes': changes}
def new_version_setup(patches_branch=None, local_patches=False, version=None, new_version=None, version_tag_style=None, new_sources=None, no_new_sources=None): args = {} if new_version: # support both version and tag ver, _ = guess.tag2version(new_version) if ver != new_version: new_version = ver args['new_version'] = new_version new_version_tag = guess.version2tag(new_version, version_tag_style) else: ub = guess.upstream_branch() if not git.ref_exists('refs/remotes/%s' % ub): msg = ("Upstream branch not found: %s\n" "Can't guess latest version.\n\n" "a) provide new version (git tag) yourself\n" " $ rdopkg new-version 1.2.3\n\n" "b) add upstream git remote:\n" " $ git remote add -f upstream GIT_URL\n" % ub) raise exception.CantGuess(msg=msg) new_version_tag = git.get_latest_tag(ub) new_version, _ = guess.tag2version(new_version_tag) args['new_version'] = new_version log.info("Latest version detected from %s: %s" % (ub, new_version)) if version == new_version: helpers.confirm( msg="It seems the package is already at version %s\n\n" "Run new-version anyway?" % version, default_yes=False) args['changes'] = ['Update to %s' % new_version] args['new_patches_base'] = new_version_tag spec = specfile.Spec() rpm_version = spec.get_tag('Version') rpm_milestone = spec.get_milestone() new_rpm_version, new_milestone = specfile.version_parts(new_version) args['new_rpm_version'] = new_rpm_version if new_milestone: args['new_milestone'] = new_milestone if (rpm_version != new_rpm_version or bool(new_milestone) != bool(rpm_milestone)): if new_milestone: args['new_release'] = '0.1' else: args['new_release'] = '1' if not local_patches: if not patches_branch or \ not git.ref_exists('refs/remotes/' + patches_branch): log.warn("Patches branch '%s' not found. Running in --bump-only " "mode." % patches_branch) args['bump_only'] = True if new_sources or no_new_sources: if new_sources and no_new_sources: raise exception.InvalidUsage( msg="DOES NOT COMPUTE: both -n and -N don't make sense.") # new_sources == not no_new_sources else: new_sources = guess.new_sources() args['new_sources'] = new_sources return args
def test_version2tag_type2(): assert 'V1.2.3' == guess.version2tag('1.2.3', 'VX.Y.Z')
def test_version2tag_type1(): assert 'v1.2.3' == guess.version2tag('1.2.3', 'vX.Y.Z')
def test_version2tag_simple(): assert '1.2.3' == guess.version2tag('1.2.3')
def update_patches(branch, local_patches_branch, bump_only=False, version=None, new_version=None, version_tag_style=None): if bump_only: return target_version = new_version or version if not target_version: raise exception.RequiredActionArgumentNotAvailable( action='update_patches', arg='version or new_version') tag = guess.version2tag(target_version, version_tag_style) _ensure_branch(local_patches_branch) patches = list(git.get_commits(tag, local_patches_branch)) n_patches = len(patches) _ensure_branch(branch) spec = specfile.Spec() spec.sanity_check() patches_base, n_excluded = spec.get_patches_base() ignore_regex = spec.get_patches_ignore_regex() if ignore_regex and patches_base is None: # TODO: patches_base and patches_ignore should be independent # patches_ignore feature tests should help with this a lot raise exception.OnlyPatchesIgnoreUsed() pass patch_fns = spec.get_patch_fns() for pfn in patch_fns: git('rm', '-f', '--ignore-unmatch', pfn) patch_fns = [] if n_excluded > 0: patches = patches[:-n_excluded] patches.reverse() ranges = [patches] filtered_patches = patches if ignore_regex: ranges = _partition_patches(patches, ignore_regex) filtered_patches = flatten(ranges) n_filtered_out = len(patches) - len(filtered_patches) if ignore_regex: fmt = ('\nUsing {t.bold}patches_ignore={t.normal}{t.magenta}%s' '{t.normal} regexp to filter out patches.' ) % ignore_regex.pattern else: fmt = ('\nNo valid {t.bold}patches_ignore{t.normal} ' 'filtering regex found in the .spec file.') log.info(fmt.format(t=log.term)) log.info( "\n{t.bold}{n} patches{t.normal} on top of {t.bold}{tag}{t.normal}" ", {t.bold}{ne}{t.normal} excluded by base" ", {t.bold}{nf}{t.normal} filtered out by regex.".format( t=log.term, n=n_patches, tag=tag, ne=n_excluded, nf=n_filtered_out)) if patches and filtered_patches: for hsh, title in reversed(filtered_patches): log.info("%s %s" % (log.term.green(hsh), title)) log.info("") patch_fns = [] for patch_range in ranges: start_commit, _title = patch_range[0] end_commit, _title = patch_range[-1] start_number = len(patch_fns) + 1 rng = git.rev_range(start_commit + '~', end_commit) format_patch_cmd = ['-c', 'core.abbrev=7', 'format-patch', '--no-renames', '--no-signature', '-N', '--ignore-submodules', '--stat=80', '--summary', '--start-number', str(start_number), rng] o = git(*format_patch_cmd) range_files = git._parse_output(o) patch_fns.extend(range_files) for pfn in patch_fns: git('add', pfn) spec.set_new_patches(patch_fns) patches_branch_ref = git('rev-parse', local_patches_branch, log_cmd=False) spec.set_commit_ref_macro(patches_branch_ref) spec.save()
def show_package_env(package, version, branch, patches_branch, local_patches_branch, release_bump_index, version_tag_style=None, patches_style=None, gerrit_patches_chain=None): def _putv(title, val): print("{t.bold}{title}{t.normal} {val}".format(title=title, val=val, t=log.term)) osdist = guess.osdist() upstream_branch = guess.upstream_branch() if not git.ref_exists('refs/remotes/%s' % upstream_branch): upstream_version = log.term.yellow('upstream remote/branch not found') else: upstream_version = guess.upstream_version(branch=upstream_branch) if not upstream_version: upstream_version = log.term.yellow('no version tag found') remote_hash = git.get_latest_commit_hash(patches_branch) local_hash = git.get_latest_commit_hash(local_patches_branch) upstream_hash = git.get_latest_commit_hash(upstream_branch) if remote_hash: remote_str = ("{t.green}{hash}{t.normal}".format(hash=remote_hash[:6], t=log.term)) else: remote_str = log.term.red("not found") if local_hash: color = 'yellow' if local_hash == remote_hash: color = 'green' local_str = (("{t.%s}{hash}{t.normal}" % color).format( hash=local_hash[:6], t=log.term)) else: local_str = log.term.yellow("not found") if upstream_hash: upstream_str = ("{t.green}{hash}{t.normal}".format( hash=upstream_hash[:6], t=log.term)) else: upstream_str = log.term.yellow("not found") if patches_style == 'review': if not gerrit_patches_chain: gerrit_patches_chain = guess.gerrit_patches_chain(verbose=False) gerrit_review_url = rpmfactory.review_url(gerrit_patches_chain) or \ 'unknown' spec = specfile.Spec() vr = spec.get_vr() spec_version = spec.get_tag('Version') patches_apply_method = spec.patches_apply_method() patches_base, pbn = spec.get_patches_base() patches_base_str = patches_base or '' if pbn: patches_base_str += "{t.magenta}+{n}{t.normal}".format(n=pbn, t=log.term) if not patches_base_str: patches_base_str = "N/A" patches_base_tag = guess.version2tag(version, version_tag_style) patches_base_ref_str = patches_base_tag if git.ref_exists('refs/tags/' + patches_base_tag): pbref_exists = '{t.green}existing git tag{t.normal}' else: ot = git.object_type(patches_base_tag) if ot: pbref_exists = '{t.green}existing git %s{t.normal}' % ot else: pbref_exists = '{t.red}invalid git reference{t.normal}' patches_base_ref_str += ' : ' + pbref_exists.format(t=log.term) release = spec.get_tag('Release') release_style = guess.release_style() for name, i in specfile.RELEASE_PARTS_SEMVER.items(): if release_bump_index == str(i): # show release part name as well if available (MAJOR/MINOR/PATCH) release_bump_index = '%s / %s' % (release_bump_index, name) break print('') _putv('Package: ', package) _putv('VR: ', vr) _putv('Version: ', spec_version) _putv('Upstream: ', upstream_version) _putv('Release: ', release) _putv('Release style: ', release_style) _putv('Rls bump index:', release_bump_index) _putv('Tag style: ', version_tag_style or 'X.Y.Z') print('') _putv('Dist-git branch: ', branch) _putv('Patches style: ', patches_style) _putv('Patches base: ', patches_base_str) _putv('Patches base ref: ', patches_base_ref_str) _putv('Local patches branch: ', '%s : %s' % (local_patches_branch, local_str)) _putv('Remote patches branch: ', '%s : %s' % (patches_branch, remote_str)) _putv('Remote upstream branch:', '%s : %s' % (upstream_branch, upstream_str)) if patches_style == 'review': _putv('Patches chain: ', gerrit_review_url) print('') _putv('OS dist: ', osdist) _putv('Patches apply method: ', patches_apply_method)
def update_patches(branch, local_patches_branch, bump_only=False, version=None, new_version=None, version_tag_style=None): if bump_only: return target_version = new_version or version if not target_version: raise exception.RequiredActionArgumentNotAvailable( action='update_patches', arg='version or new_version') tag = guess.version2tag(target_version, version_tag_style) _ensure_branch(local_patches_branch) patches = list(git.get_commits(tag, local_patches_branch)) n_patches = len(patches) _ensure_branch(branch) spec = specfile.Spec() spec.sanity_check() patches_base, n_excluded = spec.get_patches_base() ignore_regex = spec.get_patches_ignore_regex() if ignore_regex and patches_base is None: # TODO: patches_base and patches_ignore should be independent # patches_ignore feature tests should help with this a lot raise exception.OnlyPatchesIgnoreUsed() pass patch_fns = spec.get_patch_fns() for pfn in patch_fns: git('rm', '-f', '--ignore-unmatch', pfn) patch_fns = [] if n_excluded > 0: patches = patches[:-n_excluded] patches.reverse() ranges = [patches] filtered_patches = patches if ignore_regex: ranges = _partition_patches(patches, ignore_regex) filtered_patches = flatten(ranges) n_filtered_out = len(patches) - len(filtered_patches) if ignore_regex: fmt = ( '\nUsing {t.bold}patches_ignore={t.normal}{t.magenta}%s' '{t.normal} regexp to filter out patches.') % ignore_regex.pattern else: fmt = ('\nNo valid {t.bold}patches_ignore{t.normal} ' 'filtering regex found in the .spec file.') log.info(fmt.format(t=log.term)) log.info( "\n{t.bold}{n} patches{t.normal} on top of {t.bold}{tag}{t.normal}" ", {t.bold}{ne}{t.normal} excluded by base" ", {t.bold}{nf}{t.normal} filtered out by regex.".format( t=log.term, n=n_patches, tag=tag, ne=n_excluded, nf=n_filtered_out)) if patches and filtered_patches: for hsh, title in reversed(filtered_patches): log.info("%s %s" % (log.term.green(hsh), title)) log.info("") patch_fns = [] for patch_range in ranges: start_commit, _title = patch_range[0] end_commit, _title = patch_range[-1] start_number = len(patch_fns) + 1 rng = git.rev_range(start_commit + '~', end_commit) format_patch_cmd = [ '-c', 'core.abbrev=7', 'format-patch', '--no-renames', '--no-signature', '-N', '--ignore-submodules', '--start-number', str(start_number), rng ] o = git(*format_patch_cmd) range_files = git._parse_output(o) patch_fns.extend(range_files) for pfn in patch_fns: git('add', pfn) spec.set_new_patches(patch_fns) patches_branch_ref = git('rev-parse', local_patches_branch, log_cmd=False) spec.set_commit_ref_macro(patches_branch_ref) spec.save()
def main(): parser = argparse.ArgumentParser( formatter_class=argparse.RawDescriptionHelpFormatter, ) parser.add_argument( '--patches-branch', help='Specify another local "patches" branch, like "ceph-5.0-rhel-patches-bz12345"', ) args = parser.parse_args() spec = specfile.Spec() name = spec.get_tag('Name', expand_macros=True) # "ceph" version = spec.get_tag('Version', expand_macros=True) # "12.2.8" orig_commit = spec.get_macro('commit') # "9e20ef1b14ac70dea53123" branch = git.current_branch() # "ceph-3.2-rhel-7" tag_style = guess.version_tag_style(version=version) # "vX.Y.Z" base_tag = guess.version2tag(version, tag_style) # "v12.2.8" osdist = guess.osdist() # "ceph-3.2-rhel-patches" if args.patches_branch: patches_branch = args.patches_branch else: remote_patches_branch = guess.patches_branch(branch, pkg=name, osdist=osdist) patches_branch = remote_patches_branch.partition('/')[2] patches_sha = git('rev-parse', patches_branch) # "9e20ef1b14ac70dea53123" archive_basename = '%s-%s' % (name, version) # "ceph-12.2.8" patches_base, patches_base_commits = spec.get_patches_base() if patches_base_commits != 0: # We don't yet support the "+n_commits" syntax for patches_base. raise NotImplementedError('use a plain ref in patches_base') if patches_base is None: patches_base = base_tag filenames = diff_filenames(patches_base, patches_branch) if not filenames: # todo: make this a silent no-op eventually log.warning('%s identical to %s' % (patches_branch, patches_base)) raise RuntimeError(patches_base) tarball = archive_files(archive_basename, patches_sha, filenames) log.info('wrote %s' % tarball) # Ensure our spec file will reference this tarball. spec.set_macro('commit', patches_sha) set_source1(spec) spec.save() # Find the changelog entries from the Git -patches branch. changes = check_new_commits(patches_base, orig_commit, patches_sha) if not changes: log.info('no changes. exiting') raise SystemExit(1) # Bump the release and add the %changelog entries. # Insert %changelog. rdopkg.actions.distgit.actions.update_spec(branch=branch, changes=changes) # add + upload this new tarball. if guess.new_sources(): fedpkg = 'fedpkg' if osdist.startswith('RH'): fedpkg = 'rhpkg' clear_old_changes_sources() run(fedpkg, 'upload', tarball, direct=True) # Commit everything to dist-git rdopkg.actions.distgit.actions.commit_distgit_update(branch=branch, local_patches_branch=patches_branch) # Show the final commit rdopkg.actions.distgit.actions.final_spec_diff(branch=branch)
def new_version_setup(patches_branch=None, local_patches=False, version=None, new_version=None, version_tag_style=None, new_sources=None, no_new_sources=None, unattended=False, bug=None, bump_only=False): args = {} if new_version: # support both version and tag ver, _ = guess.tag2version(new_version) if ver != new_version: new_version = ver args['new_version'] = new_version new_version_tag = guess.version2tag(new_version, version_tag_style) if not bump_only and not git.object_type(new_version_tag): raise exception.InvalidGitRef(ref=new_version_tag) else: ub = guess.upstream_branch() if not git.ref_exists('refs/remotes/%s' % ub): msg = ("Upstream branch not found: %s\n" "Can't guess latest version.\n\n" "a) provide new version (git tag) yourself\n" " $ rdopkg new-version 1.2.3\n\n" "b) add upstream git remote:\n" " $ git remote add -f upstream GIT_URL\n" % ub) raise exception.CantGuess(msg=msg) new_version_tag = git.get_latest_tag(ub) new_version, _ = guess.tag2version(new_version_tag) args['new_version'] = new_version log.info("Latest version detected from %s: %s" % (ub, new_version)) if version == new_version: if unattended: log.info("Package is already at version %s\n" % version) raise exception.UserAbort(exit_code=0) helpers.confirm( msg="It seems the package is already at version %s\n\n" "Run new-version anyway?" % version, default_yes=False) changelog = 'Update to %s' % new_version if bug: changelog += ' (%s)' % bug args['changes'] = [changelog] args['new_patches_base'] = new_version_tag spec = specfile.Spec() rpm_version = spec.get_tag('Version') rpm_milestone = spec.get_milestone() new_rpm_version, new_milestone = specfile.version_parts(new_version) args['new_rpm_version'] = new_rpm_version if new_milestone: args['new_milestone'] = new_milestone if (rpm_version != new_rpm_version or bool(new_milestone) != bool(rpm_milestone)): if new_milestone: args['new_release'] = '0.1' else: args['new_release'] = '1' if not local_patches and not bump_only: if not patches_branch or \ not git.ref_exists('refs/remotes/' + patches_branch): log.warn("Patches branch '%s' not found. Running in --bump-only " "mode." % patches_branch) args['bump_only'] = True if new_sources or no_new_sources: if new_sources and no_new_sources: raise exception.InvalidUsage( msg="DOES NOT COMPUTE: both -n and -N don't make sense.") # new_sources == not no_new_sources else: new_sources = guess.new_sources() args['new_sources'] = new_sources return args
def update_patches(branch, local_patches_branch, version=None, new_version=None, version_tag_style=None, amend=False, bump_only=False): if bump_only: return target_version = new_version or version if not target_version: raise exception.RequiredActionArgumentNotAvailable( action='update_patches', arg='version or new_version') tag = guess.version2tag(target_version, version_tag_style) _ensure_branch(local_patches_branch) patches = git.get_commits(tag, local_patches_branch) n_patches = len(patches) _ensure_branch(branch) spec = specfile.Spec() spec.sanity_check() patches_base, n_excluded = spec.get_patches_base() ignore_regex = spec.get_patches_ignore_regex() if not ignore_regex: log.info('No valid patch filtering regex found in the spec file.') if ignore_regex and patches_base is None: raise exception.OnlyPatchesIgnoreUsed() patch_fns = spec.get_patch_fns() for pfn in patch_fns: git('rm', '--ignore-unmatch', pfn) patch_fns = [] if n_excluded > 0: patches = patches[:-n_excluded] patches.reverse() ranges = [patches] filtered_patches = patches if ignore_regex: ranges = _partition_patches(patches, ignore_regex) filtered_patches = flatten(ranges) n_filtered_out = len(patches) - len(filtered_patches) log.info( "\n{t.bold}{n} patches{t.normal} on top of {t.bold}{tag}{t.normal}" ", {t.bold}{ne}{t.normal} excluded by base" ", {t.bold}{nf}{t.normal} filtered out by regex.".format( t=log.term, n=n_patches, tag=tag, ne=n_excluded, nf=n_filtered_out)) if patches and filtered_patches: for hsh, title in reversed(filtered_patches): log.info("%s %s" % (log.term.green(hsh), title)) patch_fns = [] for patch_range in ranges: start_commit, _title = patch_range[0] end_commit, _title = patch_range[-1] start_number = len(patch_fns) + 1 rng = git.rev_range(start_commit + '~', end_commit) format_patch_cmd = ['format-patch', '--no-renames', '--no-signature', '-N', '--ignore-submodules', '--start-number', str(start_number), rng] o = git(*format_patch_cmd) range_files = git._parse_output(o) patch_fns.extend(range_files) for pfn in patch_fns: git('add', pfn) spec.set_new_patches(patch_fns) patches_branch_ref = git('rev-parse', local_patches_branch) spec.set_commit_ref_macro(patches_branch_ref) spec.save() if git.is_clean(): log.info('No new patches.') return msg = 'Updated patches from ' + local_patches_branch git('commit', '-a', '-m', msg) if amend: git.squash_last()
def show_package_env(package, version, branch, patches_branch, local_patches_branch, release_bump_index, version_tag_style=None, patches_style=None, gerrit_patches_chain=None): def _putv(title, val): print("{t.bold}{title}{t.normal} {val}" .format(title=title, val=val, t=log.term)) osdist = guess.osdist() upstream_branch = guess.upstream_branch() if not git.ref_exists('refs/remotes/%s' % upstream_branch): upstream_version = log.term.yellow('upstream remote/branch not found') else: upstream_version = guess.upstream_version(branch=upstream_branch) if not upstream_version: upstream_version = log.term.yellow('no version tag found') remote_hash = git.get_latest_commit_hash(patches_branch) local_hash = git.get_latest_commit_hash(local_patches_branch) upstream_hash = git.get_latest_commit_hash(upstream_branch) if remote_hash: remote_str = ("{t.green}{hash}{t.normal}" .format(hash=remote_hash[:6], t=log.term)) else: remote_str = log.term.red("not found") if local_hash: color = 'yellow' if local_hash == remote_hash: color = 'green' local_str = (("{t.%s}{hash}{t.normal}" % color) .format(hash=local_hash[:6], t=log.term)) else: local_str = log.term.yellow("not found") if upstream_hash: upstream_str = ("{t.green}{hash}{t.normal}" .format(hash=upstream_hash[:6], t=log.term)) else: upstream_str = log.term.yellow("not found") if patches_style == 'review': if not gerrit_patches_chain: gerrit_patches_chain = guess.gerrit_patches_chain(verbose=False) gerrit_review_url = rpmfactory.review_url(gerrit_patches_chain) or \ 'unknown' spec = specfile.Spec() vr = spec.get_vr() spec_version = spec.get_tag('Version') patches_apply_method = spec.patches_apply_method() patches_base, pbn = spec.get_patches_base() patches_base_str = patches_base or '' if pbn: patches_base_str += "{t.magenta}+{n}{t.normal}".format( n=pbn, t=log.term) if not patches_base_str: patches_base_str = "N/A" patches_base_tag = guess.version2tag(version, version_tag_style) patches_base_ref_str = patches_base_tag if git.ref_exists('refs/tags/' + patches_base_tag): pbref_exists = '{t.green}existing git tag{t.normal}' else: ot = git.object_type(patches_base_tag) if ot: pbref_exists = '{t.green}existing git %s{t.normal}' % ot else: pbref_exists = '{t.red}invalid git reference{t.normal}' patches_base_ref_str += ' : ' + pbref_exists.format(t=log.term) release = spec.get_tag('Release') release_style = guess.release_style() for name, i in specfile.RELEASE_PARTS_SEMVER.items(): if release_bump_index == str(i): # show release part name as well if available (MAJOR/MINOR/PATCH) release_bump_index = '%s / %s' % (release_bump_index, name) break print('') _putv('Package: ', package) _putv('VR: ', vr) _putv('Version: ', spec_version) _putv('Upstream: ', upstream_version) _putv('Release: ', release) _putv('Release style: ', release_style) _putv('Rls bump index:', release_bump_index) _putv('Tag style: ', version_tag_style or 'X.Y.Z') print('') _putv('Dist-git branch: ', branch) _putv('Patches style: ', patches_style) _putv('Patches base: ', patches_base_str) _putv('Patches base ref: ', patches_base_ref_str) _putv('Local patches branch: ', '%s : %s' % (local_patches_branch, local_str)) _putv('Remote patches branch: ', '%s : %s' % (patches_branch, remote_str)) _putv('Remote upstream branch:', '%s : %s' % (upstream_branch, upstream_str)) if patches_style == 'review': _putv('Patches chain: ', gerrit_review_url) print('') _putv('OS dist: ', osdist) _putv('Patches apply method: ', patches_apply_method)