Esempio n. 1
0
def run_annotate(args):
    patchfns.chdir_to_base_dir()
    args.opt_patch = patchfns.find_applied_patch(args.opt_patch)
    opt_file = os.path.join(patchfns.SUBDIR, args.filename)
    if not args.opt_patch:
        return cmd_result.ERROR
    patches = []
    files = []
    next_patch = None
    for patch in patchfns.applied_patches():
        old_file = patchfns.backup_file_name(patch, opt_file)
        if os.path.isfile(old_file):
            patches.append(patch)
            files.append(old_file)
        if patch == args.opt_patch:
            next_patch = patchfns.next_patch_for_file(patch, opt_file)
            break
    if not next_patch:
        files.append(opt_file)
    else:
        files.append(patchfns.backup_file_name(next_patch, opt_file))
    if len(patches) == 0:
        for line in open(files[-1]).readlines():
            output.write('\t%s\n' % line)
        return cmd_result.OK
    difftxt = ''
    for index in range(len(patches)):
        difftxt += annotation_for(files[index], files[index + 1], index + 1)
    template = patchfns.gen_tempfile()
    open(template, 'w').write('\n' * len(open(files[0]).readlines()))
    shell.run_cmd('patch %s' % template, difftxt)
    annotations = [line.rstrip() for line in open(template).readlines()]
    os.remove(template)
    output.start_pager()
    if os.path.exists(files[-1]):
        for annotation, line in zip(annotations, open(files[-1]).readlines()):
            output.write('%s\t%s' % (annotation, line))
    output.write('\n')
    for index, patch in zip(range(len(patches)), patches):
        output.write('%s\t%s\n' % (index + 1, patchfns.print_patch(patch)))
    output.wait_for_pager()
    return cmd_result.OK
Esempio n. 2
0
def run_fold(args):
    patchfns.chdir_to_base_dir()
    if not args.opt_strip_level:
        args.opt_strip_level = '1'
    opt_patch_args = '' if not args.opt_quiet else ' -s'
    if not args.opt_force or args.opt_quiet:
        opt_patch_args += ' -f'
    if args.opt_reverse:
        opt_patch_args += ' -R'
    top = patchfns.find_top_patch()
    if not top:
        return cmd_result.ERROR
    failed = suggest_force = False
    try:
        workdir = patchfns.gen_tempfile(template=os.getcwd(), asdir=True)
        if patchfns.SUBDIR:
            subdir = patchfns.SUBDIR
            prefix = os.path.join(workdir, patchfns.SUBDIR) + os.sep
        else:
            subdir = '.'
            prefix = workdir + os.sep
        patch_args = '-p%s --backup --prefix="%s" -E %s' % (args.opt_strip_level, prefix, opt_patch_args)
        patch_text = sys.stdin.read()
        result = putils.apply_patch_text(patch_text, indir=subdir, patch_args=patch_args)
        output.write(result.stdout)
        output.error(result.stderr)
        if result.eflags != 0 and not args.opt_force:
            suggest_force = True
            failed = True
        if not failed:
            for filename in fsutils.files_in_dir(workdir):
                backup_file = patchfns.backup_file_name(top, filename)
                if not os.path.exists(backup_file):
                    try:
                        backup_file_dir = os.path.dirname(backup_file)
                        if backup_file_dir and not os.path.exists(backup_file_dir):
                            os.makedirs(backup_file_dir)
                        os.link(os.path.join(workdir, filename), backup_file)
                    except OSError as edata:
                        failed = True
                        break
    except KeyboardInterrupt:
        failed = True
    if failed:
        for filename in fsutils.files_in_dir(workdir):
            try:
                shutil.move(os.path.join(workdir, filename), filename)
            except OSError:
                output.error('File %s may be corrupted\n' % filename)
    if os.path.exists(workdir):
        shutil.rmtree(workdir)
    return cmd_result.OK if not failed else cmd_result.ERROR_SUGGEST_FORCE if suggest_force else cmd_result.ERROR
Esempio n. 3
0
def run_files(args):
    patchfns.chdir_to_base_dir()
    first_patch = None
    if args.opt_combine:
        args.opt_all = True
        if args.opt_combine != '-':
            first_patch = patchfns.find_patch_in_series(args.opt_combine)
            if not first_patch:
                return cmd_result.ERROR
    last_patch = patchfns.find_applied_patch(args.patch)
    if not last_patch:
        return cmd_result.ERROR
    if args.opt_all:
        if not first_patch:
            first_patch = patchfns.applied_patches()[0]
        patches = patchfns.patches_before(last_patch) + [last_patch]
        if first_patch not in patches:
            output.error('Patch %s not applied before patch %s\n' % (patchfns.print_patch(first_patch), patchfns.print_patch(last_patch)))
            return cmd_result.ERROR
        patches = patches[patches.index(first_patch):]
    else:
        patches = [last_patch]
    use_status = args.opt_verbose and not args.opt_labels
    # Note: If opt_labels is set, then use_status is not set.
    output.start_pager()
    for patch in patches:
        if args.opt_all and args.opt_verbose and not args.opt_labels:
            output.write('%s\n' % patch)
        for filename in sorted(patchfns.files_in_patch(patch)):
            if args.opt_labels:
                if args.opt_verbose:
                    output.write('[%s] ' % patch)
                else:
                    output.write('%s ' % patch)
            if not use_status:
                output.write('%s\n' % filename)
            else:
                status = ' '
                buname = patchfns.backup_file_name(patch, filename)
                if os.path.exists(buname) and os.path.getsize(buname) > 0:
                    if not os.path.exists(filename) or os.path.getsize(filename) == 0:
                        status = '-'
                elif os.path.exists(filename) or os.path.getsize(filename) > 0:
                    status = '+'
                output.write('%s %s\n' % (status, filename))
    output.wait_for_pager()
    return cmd_result.OK
Esempio n. 4
0
def scan_applied(category, prefix, file_paths, patches):
    for patch in patches:
        for file_path in file_paths:
            if os.path.isfile(patchfns.backup_file_name(patch, file_path)):
                output.write(colour.wrap('%s%s\n' % (prefix, patchfns.print_patch(patch)), category))
Esempio n. 5
0
def run_refresh(args):
    workdir = None
    def clean_up(status):
        if workdir and os.path.isdir(workdir):
            shutil.rmtree(workdir)
        return status
    patchfns.chdir_to_base_dir()
    patch = patchfns.find_applied_patch(args.patchname)
    if not patch:
        return cmd_result.ERROR
    if not args.opt_sort:
        files = patchfns.files_in_patch_ordered(patch)
    else:
        files = patchfns.files_in_patch(patch)
    if args.opt_new_name:
        if args.patchname:
            output.error('Can only refresh the topmost patch with -z currently\n')
            return cmd_result.ERROR
        old_patch = patch
        old_patch_args = patchfns.patch_args(old_patch)
        if args.opt_new_name is True:
            patch = patchfns.next_filename(patch)
        else:
            patch = args.opt_new_name
        if os.path.exists(patchfns.patch_file_name(patch)):
            output.error('Patch %s exists already\n' % patchfns.print_patch(patch))
            return cmd_result.ERROR
    if args.opt_strip_level is None:
        args.opt_strip_level = patchfns.patch_strip_level(patch)
    if args.opt_strip_level in ['0', '1']:
        num_strip_level = args.opt_strip_level
    elif args.opt_strip_level == 'ab':
        num_strip_level = '1'
    else:
        output.error('Cannot refresh patches with -p%s, please specify -p0 or -p1 instead\n' % args.opt_strip_level)
        return cmd_result.ERROR
    if args.opt_new_name:
        workdir = patchfns.gen_tempfile(asdir=True, template=os.path.join(os.getcwd(), 'quilt'))
        if not patchfns.apply_patch_temporarily(workdir, old_patch):
            return clean_up(cmd_result.ERROR)
    patch_content = ''
    files_were_shadowed = False
    for filn in files:
        if args.opt_new_name:
            old_file = os.path.join(workdir, filn)
            new_file = filn
        else:
            old_file = patchfns.backup_file_name(patch, filn)
            next_patch = patchfns.next_patch_for_file(patch, filn)
            if not next_patch:
                new_file = filn
            else:
                new_file = patchfns.backup_file_name(next_patch, filn)
                files_were_shadowed = True
        result = diff.diff_file(filn, old_file, new_file, args)
        if result.eflags > 1:
            output.error('\n'.join(result.stderr, 'Diff failed, aborting\n'))
            return clean_up(cmd_result.ERROR)
        elif result.eflags == 0 or not result.stdout:
            continue
        else:
            patch_content += result.stdout
    patch_file = patchfns.patch_file_name(patch)
    prev_patch_file = patch_file if os.path.isfile(patch_file) else '/dev/null'
    result_content = patchfns.patch_header(prev_patch_file)
    if not patch_content:
        output.error('Nothing in patch %s\n' % patchfns.print_patch(patch))
    else:
        if files_were_shadowed:
            if not args.opt_force:
                output.error('More recent patches modify files in patch %s. Enforce refresh with -f.\n' % patchfns.print_patch(patch))
                return clean_up(cmd_result.ERROR_SUGGEST_FORCE)
            if args.opt_strip_trailing_whitespace:
                output.error('Cannot use --strip-trailing-whitespace on a patch that has shadowed files.\n')
        if args.opt_strip_trailing_whitespace and not files_were_shadowed:
            result = putils.remove_trailing_ws(patch_content, num_strip_level)
            if result.eflags == cmd_result.OK:
                patch_content = result.stdout
            if result.stderr:
                output.error(result.stderr)
        else:
            result = putils.remove_trailing_ws(patch_content, num_strip_level, dry_run=True)
            if result.stderr:
                output.error(result.stderr)
        if args.opt_diffstat:
            diffstat_text = diffstat.get_diffstat(patch_content, num_strip_level)
            result_content += diffstat_text
        result_content += patch_content
    patch_file_dir = os.path.dirname(patch_file)
    if not os.path.exists(patch_file_dir):
        os.makedirs(patch_file_dir)
    is_ok = True
    QUILT_PC = customization.get_config('QUILT_PC')
    if fsutils.file_contents_equal(patch_file, result_content):
        output.write('Patch %s is unchanged\n' % patchfns.print_patch(patch))
    else:
        if args.opt_backup and os.path.isfile(patch_file):
            try:
                os.rename(patch_file, patch_file + '~')
            except OSError:
                output.error('Failed to create backup %s\n' % patch_file + '~')
                is_ok = False
        if is_ok:
            is_ok = fsutils.set_file_contents(patch_file, result_content)
        if is_ok and args.opt_new_name:
            insert_ok = patchfns.insert_in_series(patch, old_patch_args)
            if not insert_ok:
                output.error('Failed to insert patch %s into file series\n' % patchfns.print_patch(patch))
                return clean_up(cmd_result.ERROR)
            try:
                patch_dir = os.path.join(QUILT_PC, patch)
                if os.path.exists(patch_dir):
                    shutil.rmtree(patch_dir)
                os.rename(workdir, patch_dir)
                open(patchfns.DB, 'a').write(patch + '\n')
            except:
                output.error('Failed to create patch %s\n' % patchfns.print_patch(patch))
                return clean_up(cmd_result.ERROR)
            output.write('Fork of patch %s created as %s\n' % (patchfns.print_patch(old_patch), patchfns.print_patch(patch)))
        elif is_ok and patch_content:
            output.write('Refreshed patch %s\n' % patchfns.print_patch(patch))
        fsutils.touch(os.path.join(QUILT_PC, patch, '.timestamp'))
    if is_ok:
        tagf = os.path.join(QUILT_PC, patch + '~refresh')
        if os.path.exists(tagf):
            os.remove(tagf)
        is_ok = patchfns.change_db_strip_level('-p%s' % num_strip_level, patch)
    return clean_up(cmd_result.OK if is_ok and patch_content else cmd_result.ERROR)
Esempio n. 6
0
def run_diff(args):
    patchfns.chdir_to_base_dir()
    snap_subdir = os.path.join(patchfns.QUILT_PC, '.snap') if args.opt_snapshot else None
    if args.opt_combine:
        first_patch = '-' if args.opt_combine == '-' else patchfns.find_applied_patch(args.opt_combine)
        if not first_patch:
            return cmd_result.ERROR
    else:
        first_patch = None
    if len([opt for opt in [args.opt_combine, args.opt_snapshot, args.opt_relative] if opt]) > 1:
        output.error('Options `--combine\', `--snapshot\', and `-z\' cannot be combined.\n')
        return cmd_result.ERROR
    last_patch = patchfns.find_applied_patch(args.last_patch)
    if not last_patch:
        return cmd_result.ERROR
    if args.opt_strip_level is None:
        args.opt_strip_level = patchfns.patch_strip_level(last_patch)
    if args.opt_strip_level not in ['0', '1', 'ab']:
        output.error('Cannot diff patches with -p%s, please specify -p0, -p1, or -pab instead\n' % args.opt_strip_level)
        return cmd_result.ERROR
    files = []
    if args.opt_snapshot and len(args.opt_files) == 0:
        for path, _dirs, bases in os.walk(snap_subdir):
            rpath = '' if path == snap_subdir else os.path.relpath(path, snap_subdir)
            files += [os.path.join(rpath, base) for base in bases]
        files.sort()
        args.opt_combine = True
        first_patch = patchfns.applied_patches()[0]
    if args.opt_combine:
        patches = patchfns.patches_before(last_patch) + [last_patch]
        if first_patch != '-':
            try:
                patches = patches[patches.index(first_patch):]
            except ValueError:
                output.error('Patch %s not applied before patch %s\n' % (patchfns.print_patch(first_patch), patchfns.print_patch(last_patch)))
                return cmd_result.ERROR
    else:
        patches = [last_patch]
    if len(args.opt_files) > 0:
        # use a set as it should be more efficient
        ofiles = set()
        for ofile in args.opt_files:
            if ofile.startswith('.' + os.sep):
                ofile = ofile[2:]
            if patchfns.SUBDIR:
                ofile = os.path.join(patchfns.SUBDIR, ofile)
            ofiles.add(ofile)
        for patch in patches:
            for fname in patchfns.files_in_patch_ordered(patch):
                if fname in ofiles and fname not in files:
                    files.append(fname)
    else:
        for patch in patches:
            for fname in patchfns.files_in_patch_ordered(patch):
                if fname not in files:
                    files.append(fname)
    if args.opt_sort:
        files.sort()
    if args.opt_relative:
        workdir = patchfns.gen_tempfile(os.path.join(os.getcwd(), 'quilt'), asdir=True)
        atexit.register(clean_up, workdir)
        if not patchfns.apply_patch_temporarily(workdir, last_patch, files):
            return cmd_result.ERROR
    is_ok = True
    files_were_shadowed = False
    if args.opt_color:
        colour.set_up()
    output.start_pager()
    for filename in files:
        snapshot_path = os.path.join(snap_subdir, filename) if snap_subdir else None
        if snapshot_path and os.path.exists(snapshot_path):
            old_file = snapshot_path
        elif args.opt_relative:
            old_file = os.path.join(workdir, filename)
        else:
            patch = patchfns.first_modified_by(filename, patches)
            if not patch:
                if not args.opt_snapshot:
                    output.error('File %s is not being modified\n' % filename)
                continue
            old_file = patchfns.backup_file_name(patch, filename)
        next_patch = patchfns.next_patch_for_file(last_patch, filename)
        if not next_patch:
            new_file = filename
        else:
            new_file = patchfns.backup_file_name(next_patch, filename)
            files_were_shadowed = True
        if not do_diff(filename, old_file, new_file, args):
            output.error('Diff failed, aborting\n')
            return cmd_result.ERROR
    if files_were_shadowed:
        output.error('Warning: more recent patches modify files in patch %s\n' % patchfns.print_patch(last_patch))
    output.wait_for_pager()
    return cmd_result.OK