Ejemplo n.º 1
0
    def run(self, args):
        db = Db(self.get_pc_dir())
        top = db.top_patch()
        if not top:
            self.exit_error("No patches applied.")

        print(top)
Ejemplo n.º 2
0
 def __init__(self, cwd, quilt_pc, quilt_patches):
     super(Delete, self).__init__(cwd)
     self.quilt_pc = Directory(quilt_pc)
     self.quilt_patches = Directory(quilt_patches)
     self.db = Db(quilt_pc)
     self.series = Series(quilt_patches)
     self.pop = Pop(cwd, quilt_pc)
Ejemplo n.º 3
0
    def run(self, args):
        series = Series(self.get_patches_dir())
        if not series.exists():
            self.exit_error("No series file found.")

        db = Db(self.get_pc_dir())

        top = None
        if args.patch:
            patch_name = args.patch
            top = Patch(patch_name)
        else:
            if db.exists():
                top = db.top_patch()

        if not top:
            top = series.first_patch()
            if not top:
                self.exit_error("No patch in series.")
            else:
                print(top)
        else:
            patch = series.patch_after(top)
            if not patch:
                self.exit_error("No patch available after %s." % top)
            else:
                print(patch)
Ejemplo n.º 4
0
 def test_unreverted(self):
     """ Test when the patch modifies unreverted files """
     with tmp_series() as [dir, series]:
         old_dir = os.getcwd()
         try:
             os.chdir(dir)
             db = Db(dir)
             db.add_patch(Patch("patch"))
             db.save()
             originals = os.path.join(db.dirname, "patch")
             os.mkdir(originals)
             make_file(b"unreverted original\n", originals, "unreverted")
             make_file(b"reverted original\n", originals, "reverted")
             make_file(b"unreverted patched\n", dir, "unreverted")
             make_file(b"reverted patched\n", dir, "reverted")
             Refresh(dir, db.dirname, series.dirname).refresh()
             make_file(b"unreverted change\n", dir, "unreverted")
             make_file(b"reverted change\n", dir, "reverted")
             cmd = quilt.revert.Revert(dir, db.dirname, series.dirname)
             cmd.revert_file("reverted")
             with open(os.path.join(dir, "reverted"), "rb") as file:
                 self.assertEqual(file.read(), b"reverted patched\n")
             with open(os.path.join(dir, "unreverted"), "rb") as file:
                 self.assertEqual(file.read(), b"unreverted change\n")
         finally:
             os.chdir(old_dir)
Ejemplo n.º 5
0
 def run(self, args):
     db = Db(self.get_pc_dir())
     top = db.top_patch()
     series = Series(self.get_patches_dir())
     if top is None:
         patches = series.patches()
     else:
         patches = series.patches_after(top)
     for patch in patches:
         print(patch)
Ejemplo n.º 6
0
 def run(self, options, args):
     db = Db(self.get_pc_dir())
     top = db.top_patch()
     series = Series(self.get_patches_dir())
     if top is None:
         patches = series.patches()
     else:
         patches = series.patches_after(top)
     for patch in patches:
         print patch
Ejemplo n.º 7
0
 def __init__(self, cwd, quilt_pc, quilt_patches):
     super(Delete, self).__init__(cwd)
     self.quilt_pc = Directory(quilt_pc)
     self.quilt_patches = Directory(quilt_patches)
     self.db = Db(quilt_pc)
     self.series = Series(quilt_patches)
     self.pop = Pop(cwd, quilt_pc)
Ejemplo n.º 8
0
class New(Command):

    patch_created = Signal()

    """ Creates a new patch in the queue """
    def __init__(self, cwd, quilt_pc, quilt_patches):
        super(New, self).__init__(cwd)
        self.quilt_pc = Directory(quilt_pc)
        self.quilt_patches = Directory(quilt_patches)
        self.db = Db(quilt_pc)
        self.series = Series(quilt_patches)

    def create(self, patchname):
        """ Adds a new patch with patchname to the queue

        The new patch will be added as the topmost applied patch.
        """
        patch = Patch(patchname)
        if self.series.is_patch(patch):
            raise PatchAlreadyExists(self.series, patchname)

        patch_dir = self.quilt_patches
        patch_dir.create()
        patchfile = patch_dir + File(patchname)
        patchfile.touch()

        pc_dir = self.quilt_pc + patchname
        if pc_dir.exists():
            # be sure that the directory is clear
            pc_dir.delete()

        # create empty .pc/<patchname> directory as quilt does too
        pc_dir.create()

        top = self.db.top_patch()
        # add new patch after the current topmost applied patch
        self.series.add_patches([patch], top)
        # "apply" patch
        self.db.add_patch(patch)

        # create patches/series files
        self.series.save()
        # create .pc/.version and .pc/applied-patches files
        self.db.save()

        self.patch_created(patch)
Ejemplo n.º 9
0
class New(Command):

    patch_created = Signal()
    """ Creates a new patch in the queue """
    def __init__(self, cwd, quilt_pc, quilt_patches):
        super(New, self).__init__(cwd)
        self.quilt_pc = Directory(quilt_pc)
        self.quilt_patches = Directory(quilt_patches)
        self.db = Db(quilt_pc)
        self.series = Series(quilt_patches)

    def create(self, patchname):
        """ Adds a new patch with patchname to the queue

        The new patch will be added as the topmost applied patch.
        """
        patch = Patch(patchname)
        if self.series.is_patch(patch):
            raise PatchAlreadyExists(self.series, patchname)

        patch_dir = self.quilt_patches
        patch_dir.create()
        patchfile = patch_dir + File(patchname)
        patchfile.touch()

        pc_dir = self.quilt_pc + patchname
        if pc_dir.exists():
            # be sure that the directory is clear
            pc_dir.delete()

        # create empty .pc/<patchname> directory as quilt does too
        pc_dir.create()

        top = self.db.top_patch()
        # add new patch after the current topmost applied patch
        self.series.add_patches([patch], top)
        # "apply" patch
        self.db.add_patch(patch)

        # create patches/series files
        self.series.save()
        # create .pc/.version and .pc/applied-patches files
        self.db.save()

        self.patch_created(patch)
Ejemplo n.º 10
0
    def run(self, args):
        series = Series(self.get_patches_dir())
        db = Db(self.get_pc_dir())

        top = None
        if args.patch:
            top = Patch(args.patch)
        else:
            if db.exists():
                top = db.top_patch()

        if not top:
            self.exit_error("No patches applied.")
        else:
            patch = series.patch_before(top)
            if not patch:
                self.exit_error("No patch available before %s." % top)
            else:
                print(patch)
Ejemplo n.º 11
0
 def test_unreverted(self):
     """ Test when the patch modifies unreverted files """
     with tmp_series() as [dir, series]:
         old_dir = os.getcwd()
         try:
             os.chdir(dir)
             db = Db(dir)
             db.add_patch(Patch("patch"))
             db.save()
             originals = os.path.join(db.dirname, "patch")
             os.mkdir(originals)
             make_file(b"unreverted original\n", originals, "unreverted")
             make_file(b"reverted original\n", originals, "reverted")
             make_file(b"unreverted patched\n", dir, "unreverted")
             make_file(b"reverted patched\n", dir, "reverted")
             Refresh(dir, db.dirname, series.dirname).refresh()
             make_file(b"unreverted change\n", dir, "unreverted")
             make_file(b"reverted change\n", dir, "reverted")
             cmd = quilt.revert.Revert(dir, db.dirname, series.dirname)
             cmd.revert_file("reverted")
             with open(os.path.join(dir, "reverted"), "rb") as file:
                 self.assertEqual(file.read(), b"reverted patched\n")
             with open(os.path.join(dir, "unreverted"), "rb") as file:
                 self.assertEqual(file.read(), b"unreverted change\n")
         finally:
             os.chdir(old_dir)
Ejemplo n.º 12
0
    def run(self, options, args):
        series = Series(self.get_patches_dir())
        db = Db(self.get_pc_dir())

        top = None
        if len(args) > 0:
            top = Patch(args[0])
        else:
            if db.exists():
                top = db.top_patch()

        if not top:
            top = series.first_patch()
            if not top:
                self.exit_error("No patch in series.")
            else:
                print top
        else:
            patch = series.patch_before(top)
            if not patch:
                self.exit_error("No patch available after %s." % patch)
            else:
                print patch
Ejemplo n.º 13
0
class Import(Command):
    """ Command class to import patches into the patch queue """

    def __init__(self, cwd, quilt_pc, quilt_patches):
        super(Import, self).__init__(cwd)
        self.quilt_pc = Directory(quilt_pc)
        self.quilt_patches = Directory(quilt_patches)
        self.db = Db(quilt_pc)
        self.series = Series(quilt_patches)

    def _import_patches(self, patches, reverse=False, strip=None):
        top = self.db.top_patch()
        patchlist = []
        for patch in patches:
            patchlist.append(Patch(patch, reverse=reverse, strip=strip))
        self.series.add_patches(patchlist, top)
        self.series.save()

    def import_patch(self, patch_name, new_name=None):
        """ Import patch into the patch queue
        The patch is inserted after the current top applied patch
        """
        if new_name:
            dir_name = os.path.dirname(new_name)
            name = os.path.basename(new_name)
            dest_dir = self.quilt_patches + Directory(dir_name)
            dest_dir.create()
        else:
            name = os.path.basename(patch_name)
            dest_dir = self.quilt_patches

        patch_file = File(patch_name)
        dest_file = dest_dir + File(name)
        patch_file.copy(dest_file)
        self._import_patches([name])

    def import_patches(self, patches):
        """ Import several patches into the patch queue """

        dest_dir = self.quilt_patches
        patch_names = []

        for patch in patches:
            patch_name = os.path.basename(patch)
            patch_file = File(patch)
            dest_file = dest_dir + File(patch_name)
            patch_file.copy(dest_file)
            patch_names.append(patch_name)

        self._import_patches(patch_names)
Ejemplo n.º 14
0
 def test_unrefreshed(self):
     with TmpDirectory() as dir:
         db = Db(dir.get_name())
         db.add_patch(Patch("unrefreshed.patch"))
         db.save()
         make_file(b"", db.dirname, "unrefreshed.patch~refresh")
         cmd = Pop(dir.get_name(), db.dirname)
         with six.assertRaisesRegex(self, QuiltError,
                 r"needs to be refreshed"):
             cmd.unapply_top_patch()
Ejemplo n.º 15
0
 def run(self, args):
     series = Series(self.get_patches_dir())
     if args.v:
         applied = Db(self.get_pc_dir()).patches()
         for patch in applied[:-1]:
             print("+ " + patch.get_name())
         if applied:
             print("= " + applied[-1].get_name())
             patches = series.patches_after(applied[-1])
         else:
             patches = series.patches()
         for patch in patches:
             print("  " + patch.get_name())
     else:
         for patch in series.patches():
             print(patch.get_name())
Ejemplo n.º 16
0
 def test_series_v(self):
     with tmp_series() as [dir, series]:
         applied = Db(dir)
         applied.add_patch(Patch("applied.patch"))
         applied.add_patch(Patch("topmost.patch"))
         applied.save()
         series.add_patches(applied.applied_patches())
         series.add_patch(Patch("unapplied.patch"))
         series.save()
         output = run_cli(SeriesCommand, dict(v=True),
             series.dirname, applied.dirname)
     self.assertMultiLineEqual(output,
         "+ applied.patch\n"
         "= topmost.patch\n"
         "  unapplied.patch\n")
Ejemplo n.º 17
0
 def test_refresh(self):
     with TmpDirectory() as dir:
         old_dir = os.getcwd()
         try:
             os.chdir(dir.get_name())
             db = Db(".pc")
             db.create()
             backup = os.path.join(".pc", "patch")
             os.mkdir(backup)
             make_file(b"", backup, "file")
             db.add_patch(Patch("patch"))
             db.save()
             make_file(b"", "patch")
             make_file(b"added\n", "file")
             cmd = quilt.refresh.Refresh(".", ".pc", ".")
             cmd.refresh()
             with open("patch", "r") as patch:
                 self.assertTrue(patch.read(30))
         finally:
             os.chdir(old_dir)
Ejemplo n.º 18
0
 def test_next_after(self):
     """ Delete the successor to the topmost patch """
     with tmp_series() as [dir, series]:
         series.add_patch(Patch("topmost"))
         series.add_patch(Patch("unapplied"))
         series.save()
         db = Db(dir)
         db.add_patch(Patch("topmost"))
         db.save()
         cmd = Delete(dir, db.dirname, series.dirname)
         cmd.delete_next()
         series.read()
         [patch] = series.patches()
         self.assertEqual(patch, Patch("topmost"))
Ejemplo n.º 19
0
 def test_refresh(self):
     with TmpDirectory() as dir:
         old_dir = os.getcwd()
         try:
             os.chdir(dir.get_name())
             db = Db(".pc")
             db.create()
             backup = os.path.join(".pc", "patch")
             os.mkdir(backup)
             make_file(b"", backup, "file")
             db.add_patch(Patch("patch"))
             db.save()
             make_file(b"", "patch")
             make_file(b"added\n", "file")
             cmd = quilt.refresh.Refresh(".", ".pc", ".")
             cmd.refresh()
             with open("patch", "r") as patch:
                 self.assertTrue(patch.read(30))
         finally:
             os.chdir(old_dir)
Ejemplo n.º 20
0
class New(Command):

    patch_created = Signal()

    """ Creates a new patch in the queue """

    def __init__(self, cwd, quilt_pc, quilt_patches):
        super(New, self).__init__(cwd)
        self.quilt_pc = Directory(quilt_pc)
        self.quilt_patches = Directory(quilt_patches)
        self.db = Db(quilt_pc)
        self.series = Series(quilt_patches)

    def create(self, patchname):
        """ Adds a new patch with patchname to the queue

        The new patch will be added after the top patch
        """
        patch = Patch(patchname)
        if self.series.is_patch(patch):
            raise PatchAlreadyExists(self.series, patchname)

        patch_dir = self.quilt_patches
        patch_dir.create()
        patchfile = patch_dir + File(patchname)
        patchfile.touch()

        pc_dir = self.quilt_pc + patchname
        if pc_dir.exists():
            # be sure that the directory is clear
            pc_dir.delete()
        else:
            pc_dir.create()

        top = self.db.top_patch()
        self.series.add_patches([patch], top)
        self.series.save()

        self.patch_created(patch)
Ejemplo n.º 21
0
 def test_fail_after_success(self):
     """ Test where the first patch applies but a later patch fails """
     with tmp_series() as [dir, series]:
         make_file(
             b"--- /dev/null\n"
             b"+++ dir/new-file\n"
             b"@@ -0,0 +1,1 @@\n"
             b"+new file\n", series.dirname, "good.patch")
         series.add_patch(Patch("good.patch"))
         
         self._make_conflict(dir, series)
         series.save()
         cmd = Push(dir, quilt_pc=dir, quilt_patches=series.dirname)
         with six.assertRaisesRegex(self, QuiltError,
                     r"conflict\.patch does not apply"), \
                 self._suppress_output():
             cmd.apply_all()
         [applied] = Db(dir).patches()
         self.assertEqual(applied.get_name(), "good.patch")
         with open(os.path.join(dir, "new-file"), "rb") as file:
             self.assertEqual(file.read(), b"new file\n")
         with open(os.path.join(dir, "file"), "rb") as file:
             self.assertEqual(file.read(), b"conflict\n")
Ejemplo n.º 22
0
class Delete(Command):

    """Command class to delete patches
    """

    deleting_patch = Signal()
    deleted_patch = Signal()

    def __init__(self, cwd, quilt_pc, quilt_patches):
        super(Delete, self).__init__(cwd)
        self.quilt_pc = Directory(quilt_pc)
        self.quilt_patches = Directory(quilt_patches)
        self.db = Db(quilt_pc)
        self.series = Series(quilt_patches)
        self.pop = Pop(cwd, quilt_pc)

    def _delete_patch(self, patch, remove=False, backup=False):
        if self.series.is_empty():
            raise NoPatchesInSeries(self.series)
        if not self.series.is_patch(patch):
            raise UnknownPatch(self.series, patch)

        applied = self.db.top_patch() == patch
        self.deleting_patch(patch, applied)

        if applied:
            self.pop._unapply_patch(patch)
            self.db = self.pop.db
            self.db.save()

        self.series.remove_patch(patch)
        self.series.save()

        patch_file = self.quilt_patches + File(patch.get_name())

        if remove:
            if backup:
                patch_file.copy(File(patch_file.get_name() + "~"))

            patch_file.delete_if_exists()

        self.deleted_patch(patch)

    def delete_next(self, remove=False, backup=False):
        """ Delete next unapplied patch
        If remove is True the patch file will also be removed. If remove and
        backup are True a copy of the deleted patch file will be made.
        """
        patch = self.db.top_patch()
        if patch:
            after = self.series.patch_after(patch)
        else:
            after = self.series.first_patch()
        if not after:
            raise QuiltError("No next patch")

        self._delete_patch(after, remove=remove, backup=backup)

    def delete_patch(self, patch_name=None, remove=False, backup=False):
        """ Delete specified patch from the series
        If remove is True the patch file will also be removed. If remove and
        backup are True a copy of the deleted patch file will be made.
        """
        if patch_name:
            patch = Patch(patch_name)
        else:
            patch = self.db.top_patch()
            if not patch:
                raise NoAppliedPatch(self.db)

        self._delete_patch(patch, remove=remove, backup=backup)
Ejemplo n.º 23
0
 def __init__(self, cwd, quilt_pc, quilt_patches):
     super(Refresh, self).__init__(cwd)
     self.quilt_pc = Directory(quilt_pc)
     self.quilt_patches = Directory(quilt_patches)
     self.db = Db(quilt_pc)
     self.series = Series(quilt_patches)
Ejemplo n.º 24
0
class Refresh(Command):
    """ Command class to refresh (add or remove chunks) a patch
    """

    edit_patch = Signal()
    refreshed = Signal()

    def __init__(self, cwd, quilt_pc, quilt_patches):
        super(Refresh, self).__init__(cwd)
        self.quilt_pc = Directory(quilt_pc)
        self.quilt_patches = Directory(quilt_patches)
        self.db = Db(quilt_pc)
        self.series = Series(quilt_patches)

    def refresh(self, patch_name=None, edit=False):
        """ Refresh patch with patch_name or applied top patch if patch_name is
        None
        """
        if patch_name:
            patch = Patch(patch_name)
        else:
            patch = self.db.top_patch()

            if not patch:
                raise QuiltError("No patch applied. Nothing to refresh.")

        pc_dir = self.quilt_pc + patch.get_name()
        patch_file = self.quilt_patches + File(patch.get_name())
        files = pc_dir.content()[1]

        with TmpFile(prefix="pquilt-") as tmpfile:
            f = tmpfile.open()

            if patch_file.exists():
                header = patch.get_header(self.quilt_patches)
                tmpfile.write(header)

            for file_name in files:
                if file_name == ".timestamp":
                    continue
                orig_file = pc_dir + File(file_name)
                new_file = File(file_name)
                left_label, right_label, index = self._get_labels(file_name,
                                                                  orig_file,
                                                                  new_file)
                self._write_index(tmpfile, index)

                diff = Diff(orig_file, new_file)
                diff.run(self.cwd, fd=f, left_label=left_label,
                         right_label=right_label)

            if tmpfile.is_empty():
                raise QuiltError("Nothing to refresh.")

            if edit:
                self.edit_patch(tmpfile)
                tpatch = Patch(tmpfile.get_name())
                tpatch.run(pc_dir.get_name(), dry_run=True, quiet=True)

            if patch_file.exists():
                diff = Diff(patch_file, tmpfile)
                if diff.equal(self.cwd):
                    raise QuiltError("Nothing to refresh.")

            tmpfile.copy(patch_file)

        timestamp = pc_dir + File(".timestamp")
        timestamp.touch()

        refresh = self.quilt_pc + File(patch.get_name() + "~refresh")
        refresh.delete_if_exists()

        self.refreshed(patch)

    def _get_labels(self, file_name, old_file, new_file):
        dir = os.path.basename(self.cwd)

        old_hdr = dir + ".orig/" + file_name
        new_hdr = dir + "/" + file_name

        index = new_hdr

        if not old_file.exists() or old_file.is_empty():
            old_hdr = "/dev/null"

        if not new_file.exists() or new_file.is_empty():
            old_hdr = new_hdr
            new_hdr = "/dev/null"

        return (old_hdr, new_hdr, index)

    def _write_index(self, f, index):
        f.write("Index: ")
        f.write(index)
        f.write("\n")
        f.write(INDEX_LINE)
        f.write("\n")
Ejemplo n.º 25
0
class Add(Command):

    """Command class to add files to the current patch
    """

    file_added = Signal()

    def __init__(self, cwd, quilt_pc, quilt_patches):
        super(Add, self).__init__(cwd)
        self.quilt_pc = Directory(quilt_pc)
        self.quilt_patches = Directory(quilt_patches)
        self.db = Db(quilt_pc)
        self.series = Series(quilt_patches)

    def _file_in_patch(self, filename, patch, ignore):
        """ Checks if a backup file of the filename in the current patch
        exists """
        file = self.quilt_pc + File(os.path.join(patch.get_name(), filename))
        if file.exists():
            if ignore:
                return True
            else:
                raise QuiltError("File %s is already in patch %s" % (filename,
                                 patch.get_name()))
        return False

    def _file_in_next_patches(self, filename, patch):
        """ Checks if a backup file of the filename in the applied patches after
        patch exists """

        if not self.db.is_patch(patch):
            # no patches applied
            return

        patches = self.db.patches_after(patch)
        for patch in patches:
            file = self.quilt_pc + File(os.path.join(patch.get_name(),
                                                     filename))
            if file.exists():
                raise QuiltError("File %s is already modified by patch %s" %
                                 (filename, patch.get_name()))

    def _backup_file(self, file, patch):
        """ Creates a backup of file """
        dest_dir = self.quilt_pc + patch.get_name()
        file_dir = file.get_directory()
        if file_dir:
            #TODO get relative path
            dest_dir = dest_dir + file_dir
        backup = Backup()
        backup.backup_file(file, dest_dir, copy_empty=True)

    def add_file(self, filename, patch_name=None, ignore=False):
        """ Add file to the patch with patch_name.
        If patch_name is None or empty the topmost patch will be used.
        Adding an already added patch will raise an QuiltError if ignore is
        False.
        """
        file = File(filename)

        if patch_name:
            patch = Patch(patch_name)
        else:
            patch = self.db.top_patch()
            if not patch:
                raise NoAppliedPatch(self.db)

        exists = self._file_in_patch(filename, patch, ignore)
        if exists:
            return

        self._file_in_next_patches(filename, patch)

        if file.is_link():
            raise QuiltError("Cannot add symbolic link %s" % filename)

        self._backup_file(file, patch)

        if file.exists():
            # be sure user can write original file
            os.chmod(filename, file.get_mode() | stat.S_IWUSR | stat.S_IRUSR)

        self.file_added(file, patch)

    def add_files(self, filenames, patch_name=None, ignore=False):
        for filename in filenames:
            self.add_file(filename, patch_name, ignore)
Ejemplo n.º 26
0
class Refresh(Command):
    """ Command class to refresh (add or remove chunks) a patch
    """

    edit_patch = Signal()
    refreshed = Signal()

    def __init__(self, cwd, quilt_pc, quilt_patches):
        super(Refresh, self).__init__(cwd)
        self.quilt_pc = Directory(quilt_pc)
        self.quilt_patches = Directory(quilt_patches)
        self.db = Db(quilt_pc)
        self.series = Series(quilt_patches)

    def refresh(self, patch_name=None, edit=False):
        """ Refresh patch with patch_name or applied top patch if patch_name is
        None
        """
        if patch_name:
            patch = Patch(patch_name)
        else:
            patch = self.db.top_patch()

            if not patch:
                raise QuiltError("No patch applied. Nothing to refresh.")

        pc_dir = self.quilt_pc + patch.get_name()
        patch_file = self.quilt_patches + File(patch.get_name())
        files = pc_dir.content()[1]

        with TmpFile(prefix="pquilt-") as tmpfile:
            f = tmpfile.open()

            if patch_file.exists():
                header = patch.get_header(self.quilt_patches)
                tmpfile.write(header)

            for file_name in files:
                if file_name == ".timestamp":
                    continue
                orig_file = pc_dir + File(file_name)
                new_file = File(file_name)
                left_label, right_label, index = self._get_labels(
                    file_name, orig_file, new_file)
                self._write_index(tmpfile, index)

                diff = Diff(orig_file, new_file)
                diff.run(self.cwd,
                         fd=f,
                         left_label=left_label,
                         right_label=right_label)

            if tmpfile.is_empty():
                raise QuiltError("Nothing to refresh.")

            if edit:
                self.edit_patch(tmpfile)
                tpatch = Patch(tmpfile.get_name())
                tpatch.run(pc_dir.get_name(), dry_run=True, quiet=True)

            if patch_file.exists():
                diff = Diff(patch_file, tmpfile)
                if diff.equal(self.cwd):
                    raise QuiltError("Nothing to refresh.")

            tmpfile.copy(patch_file)

        timestamp = pc_dir + File(".timestamp")
        timestamp.touch()

        refresh = self.quilt_pc + File(patch.get_name() + "~refresh")
        refresh.delete_if_exists()

        self.refreshed(patch)

    def _get_labels(self, file_name, old_file, new_file):
        dir = os.path.basename(self.cwd)

        old_hdr = dir + ".orig/" + file_name
        new_hdr = dir + "/" + file_name

        index = new_hdr

        if not old_file.exists() or old_file.is_empty():
            old_hdr = "/dev/null"

        if not new_file.exists() or new_file.is_empty():
            old_hdr = new_hdr
            new_hdr = "/dev/null"

        return (old_hdr, new_hdr, index)

    def _write_index(self, f, index):
        f.write(b"Index: ")
        f.write(_encode_str(index))
        f.write(b"\n")
        f.write(INDEX_LINE)
        f.write(b"\n")
Ejemplo n.º 27
0
class Revert(Command):
    """Command class to remove files from the current patch
    """

    file_reverted = Signal()
    file_unchanged = Signal()

    def __init__(self, cwd, quilt_pc, quilt_patches):
        super(Revert, self).__init__(cwd)
        self.quilt_pc = Directory(quilt_pc)
        self.quilt_patches = Directory(quilt_patches)
        self.db = Db(quilt_pc)
        self.series = Series(quilt_patches)

    def _file_in_patch(self, filename, patch):
        """ Checks if a backup file of the filename in the current patch
        exists and raises a QuiltError if not.
        """
        pc_dir = self.quilt_pc + patch.get_name()
        file = pc_dir + File(filename)
        if not file.exists():
            raise QuiltError("File %s is not in patch %s" %
                             (filename, patch.get_name()))

    def _file_in_next_patches(self, filename, patch):
        """ Checks if a backup file of the filename in the applied patches after
        patch exists """

        if not self.db.is_patch(patch):
            # no patches applied
            return

        patches = self.db.patches_after(patch)
        for patch in patches:
            file = self.quilt_pc + File(
                os.path.join(patch.get_name(), filename))
            if file.exists():
                raise QuiltError("File %s is modified by patch %s" %
                                 (filename, patch.get_name()))

    def _apply_patch_temporary(self, tmpdir, file, patch):
        backup = Backup()
        backup_file = backup.backup_file(file, tmpdir)
        patch_file = self.quilt_patches + File(patch.get_name())

        if patch_file.exists() and not patch_file.is_empty():
            try:
                patch.run(
                    self.cwd,
                    self.quilt_patches.get_absdir(),
                    work_dir=tmpdir,
                    no_backup_if_mismatch=True,
                    remove_empty_files=True,
                    force=True,
                    quiet=True,
                    suppress_output=True,
                )
            except SubprocessError:
                pass  # Expected to fail if there are other files in patch
        return backup_file

    def revert_file(self, filename, patch_name=None):
        """ Revert not added changes of filename.
        If patch_name is None or empty the topmost patch will be used.
        """
        file = File(filename)

        if patch_name:
            patch = Patch(patch_name)
        else:
            patch = self.db.top_patch()

            if not patch:
                raise QuiltError("No patch available. Nothing to revert.")

        self._file_in_patch(filename, patch)
        self._file_in_next_patches(filename, patch)
        pc_dir = self.quilt_pc + patch.get_name()
        pc_file = pc_dir + file

        if not file.exists() and pc_file.is_empty():
            # new and empty file will be reverted
            pc_file.delete()
            self.file_reverted(file, patch)
            return

        with TmpDirectory(prefix="pquilt-") as tmpdir:
            # apply current patch in temporary directory to revert changes of
            # file that aren't committed in the patch
            tmp_file = self._apply_patch_temporary(tmpdir, pc_file, patch)
            if tmp_file and tmp_file.exists() and not tmp_file.is_empty():

                diff = Diff(file, tmp_file)
                if diff.equal(self.cwd):
                    self.file_unchanged(file, patch)
                    return

                dir = file.get_directory()
                if not dir:
                    dir = Directory(os.getcwd())
                else:
                    dir.create()
                tmp_file.copy(dir)
                self.file_reverted(file, patch)
            else:
                self.file_unchanged(file, patch)

    def revert_files(self, filenames, patch_name=None):
        for filename in filenames:
            self.revert_file(filename, patch_name)
Ejemplo n.º 28
0
class Push(Command):

    applying = Signal()
    applying_patch = Signal()
    applied = Signal()
    applied_patch = Signal()
    applied_empty_patch = Signal()

    def __init__(self, cwd, quilt_pc, quilt_patches):
        super(Push, self).__init__(cwd)
        self.quilt_pc = Directory(quilt_pc)
        self.quilt_patches = Directory(quilt_patches)
        self.db = Db(quilt_pc)
        self.series = Series(quilt_patches)

    def _apply_patch(self, patch, force=False, quiet=False):
        patch_name = patch.get_name()
        pc_dir = self.quilt_pc + patch_name
        patch_file = self.quilt_patches + File(patch_name)
        refresh = File(pc_dir.get_name() + "~refresh")

        forced = False
        self.applying_patch(patch)

        if patch_file.exists():
            try:
                patch.run(self.cwd, patch_dir=self.quilt_patches, backup=True,
                          prefix=pc_dir.get_name(), quiet=quiet)
            except SubprocessError as e:
                if not force:
                    patch = RollbackPatch(self.cwd, pc_dir)
                    patch.rollback()
                    patch.delete_backup()
                    raise QuiltError("Patch %s does not apply" % patch_name)
                else:
                    refresh.touch()
                    forced = True

        self.db.add_patch(patch)

        if pc_dir.exists():
            timestamp = pc_dir + File(".timestamp")
            timestamp.touch()
        else:
            pc_dir.create()

        if not patch_file.exists():
            self.applied_empty_patch(patch, False)
        elif pc_dir.is_empty():
            self.applied_empty_patch(patch, True)
        elif forced:
            raise QuiltError("Applied patch %s (forced; needs refresh)" %
                             patch.get_name())
        else:
            self.applied_patch(patch)

    def _check(self):
        if not self.series.exists() or not self.series.patches():
            raise NoPatchesInSeries(self.series)
        
        top = self.db.top_patch()
        if top is not None:
            refresh = top.get_name() + "~refresh"
            refresh = os.path.join(self.quilt_pc.get_name(), refresh)
            if os.path.exists(refresh):
                raise QuiltError("Patch %s needs to be refreshed" % \
                                      top.get_name())

    def apply_patch(self, patch_name, force=False, quiet=False):
        """ Apply all patches up to patch_name """
        self._check()
        patch = Patch(patch_name)
        patches = self.series.patches_until(patch)[:]

        applied = self.db.applied_patches()
        for patch in applied:
            if patch in patches:
                patches.remove(patch)

        if not patches:
            raise AllPatchesApplied(self.series, self.db.top_patch())

        self.applying(patch)

        try:
            for cur_patch in patches:
                self._apply_patch(cur_patch, force, quiet)
        finally:
            self.db.save()

        self.applied(self.db.top_patch())

    def apply_next_patch(self, force=False, quiet=False):
        """ Apply next patch in series file """
        self._check()
        top = self.db.top_patch()
        if not top:
            patch = self.series.first_patch()
        else:
            patch = self.series.patch_after(top)

        if not patch:
            raise AllPatchesApplied(self.series, top)

        self.applying(patch)

        self._apply_patch(patch, force, quiet)

        self.db.save()

        self.applied(self.db.top_patch())

    def apply_all(self, force=False, quiet=False):
        """ Apply all patches in series file """
        self._check()
        top = self.db.top_patch()
        if top:
            patches = self.series.patches_after(top)
        else:
            patches = self.series.patches()

        if not patches:
            raise AllPatchesApplied(self.series, top)

        try:
            for patch in patches:
                self.applying(patch)
                self._apply_patch(patch, force, quiet)
        finally:
            self.db.save()

        self.applied(self.db.top_patch())
Ejemplo n.º 29
0
 def __init__(self, cwd, quilt_pc):
     super(Pop, self).__init__(cwd)
     self.quilt_pc = Directory(quilt_pc)
     self.db = Db(quilt_pc)
Ejemplo n.º 30
0
class Pop(Command):

    unapplying = Signal()
    unapplied = Signal()
    unapplied_patch = Signal()
    empty_patch = Signal()

    def __init__(self, cwd, quilt_pc):
        super(Pop, self).__init__(cwd)
        self.quilt_pc = Directory(quilt_pc)
        self.db = Db(quilt_pc)

    def _check(self, force=False):
        if not self.db.exists() or not self.db.patches():
            raise NoAppliedPatch(self.db)
        if not force:
            patch = self.db.top_patch()
            pc_dir = self.quilt_pc + patch.get_name()
            refresh = File(pc_dir.get_name() + "~refresh")
            if refresh.exists():
                raise QuiltError("Patch %s needs to be refreshed first." %
                                 patch.get_name())

    def _unapply_patch(self, patch):
        self.unapplying(patch)

        patch_name = patch.get_name()
        pc_dir = self.quilt_pc + patch_name
        timestamp = pc_dir + File(".timestamp")
        timestamp.delete_if_exists()

        if pc_dir.is_empty():
            pc_dir.delete()
            self.empty_patch(patch)
        else:
            unpatch = RollbackPatch(self.cwd, pc_dir)
            unpatch.rollback()
            unpatch.delete_backup()

        self.db.remove_patch(patch)

        refresh = File(pc_dir.get_name() + "~refresh")
        refresh.delete_if_exists()

        self.unapplied_patch(patch)

    def unapply_patch(self, patch_name, force=False):
        """ Unapply patches up to patch_name. patch_name will end up as top
            patch """
        self._check(force)

        patches = self.db.patches_after(Patch(patch_name))
        for patch in reversed(patches):
            self._unapply_patch(patch)

        self.db.save()

        self.unapplied(self.db.top_patch())

    def unapply_top_patch(self, force=False):
        """ Unapply top patch """
        self._check(force)

        patch = self.db.top_patch()
        self._unapply_patch(patch)

        self.db.save()

        self.unapplied(self.db.top_patch())

    def unapply_all(self, force=False):
        """ Unapply all patches """
        self._check(force)

        for patch in reversed(self.db.applied_patches()):
            self._unapply_patch(patch)

        self.db.save()

        self.unapplied(self.db.top_patch())
Ejemplo n.º 31
0
class Delete(Command):
    """Command class to delete patches
    """

    deleting_patch = Signal()
    deleted_patch = Signal()

    def __init__(self, cwd, quilt_pc, quilt_patches):
        super(Delete, self).__init__(cwd)
        self.quilt_pc = Directory(quilt_pc)
        self.quilt_patches = Directory(quilt_patches)
        self.db = Db(quilt_pc)
        self.series = Series(quilt_patches)
        self.pop = Pop(cwd, quilt_pc)

    def _delete_patch(self, patch, remove=False, backup=False):
        if self.series.is_empty():
            raise NoPatchesInSeries(self.series)
        if not self.series.is_patch(patch):
            raise UnknownPatch(self.series, patch)

        applied = self.db.top_patch() == patch
        self.deleting_patch(patch, applied)

        if applied:
            self.pop._unapply_patch(patch)
            self.db = self.pop.db
            self.db.save()

        self.series.remove_patch(patch)
        self.series.save()

        patch_file = self.quilt_patches + File(patch.get_name())

        if remove:
            if backup:
                patch_file.copy(File(patch_file.get_name() + "~"))

            patch_file.delete_if_exists()

        self.deleted_patch(patch)

    def delete_next(self, remove=False, backup=False):
        """ Delete next unapplied patch
        If remove is True the patch file will also be removed. If remove and
        backup are True a copy of the deleted patch file will be made.
        """
        patch = self.db.top_patch()
        if patch:
            after = self.series.patch_after(patch)
        else:
            after = self.series.first_patch()
        if not after:
            raise QuiltError("No next patch")

        self._delete_patch(after, remove=remove, backup=backup)

    def delete_patch(self, patch_name=None, remove=False, backup=False):
        """ Delete specified patch from the series
        If remove is True the patch file will also be removed. If remove and
        backup are True a copy of the deleted patch file will be made.
        """
        if patch_name:
            patch = Patch(patch_name)
        else:
            patch = self.db.top_patch()
            if not patch:
                raise NoAppliedPatch(self.db)

        self._delete_patch(patch, remove=remove, backup=backup)
Ejemplo n.º 32
0
class Revert(Command):

    """Command class to remove files from the current patch
    """

    file_reverted = Signal()
    file_unchanged = Signal()

    def __init__(self, cwd, quilt_pc, quilt_patches):
        super(Revert, self).__init__(cwd)
        self.quilt_pc = Directory(quilt_pc)
        self.quilt_patches = Directory(quilt_patches)
        self.db = Db(quilt_pc)
        self.series = Series(quilt_patches)

    def _file_in_patch(self, filename, patch):
        """ Checks if a backup file of the filename in the current patch
        exists and raises a QuiltError if not.
        """
        pc_dir = self.quilt_pc + patch.get_name()
        file = pc_dir + File(filename)
        if not file.exists():
            raise QuiltError("File %s is not in patch %s" % (filename,
                             patch.get_name()))

    def _file_in_next_patches(self, filename, patch):
        """ Checks if a backup file of the filename in the applied patches after
        patch exists """

        if not self.db.is_patch(patch):
            # no patches applied
            return

        patches = self.db.patches_after(patch)
        for patch in patches:
            file = self.quilt_pc + File(os.path.join(patch.get_name(),
                                                     filename))
            if file.exists():
                raise QuiltError("File %s is modified by patch %s" %
                                 (filename, patch.get_name()))

    def _apply_patch_temporary(self, tmpdir, file, patch):
        backup = Backup()
        backup_file = backup.backup_file(file, tmpdir)
        patch_file = self.quilt_patches + File(patch.get_name())

        if patch_file.exists() and not patch_file.is_empty():
            try:
                patch.run(self.cwd, self.quilt_patches.get_absdir(),
                          work_dir=tmpdir, no_backup_if_mismatch=True,
                          remove_empty_files=True, force=True,
                          quiet=True, suppress_output=True,
                )
            except SubprocessError:
                pass  # Expected to fail if there are other files in patch
        return backup_file

    def revert_file(self, filename, patch_name=None):
        """ Revert not added changes of filename.
        If patch_name is None or empty the topmost patch will be used.
        """
        file = File(filename)

        if patch_name:
            patch = Patch(patch_name)
        else:
            patch = self.db.top_patch()

            if not patch:
                raise QuiltError("No patch available. Nothing to revert.")

        self._file_in_patch(filename, patch)
        self._file_in_next_patches(filename, patch)
        pc_dir = self.quilt_pc + patch.get_name()
        pc_file = pc_dir + file

        if not file.exists() and pc_file.is_empty():
            # new and empty file will be reverted
            pc_file.delete()
            self.file_reverted(file, patch)
            return

        with TmpDirectory(prefix="pquilt-") as tmpdir:
            # apply current patch in temporary directory to revert changes of
            # file that aren't committed in the patch
            tmp_file = self._apply_patch_temporary(tmpdir, pc_file, patch)
            if tmp_file and tmp_file.exists() and not tmp_file.is_empty():

                diff = Diff(file, tmp_file)
                if diff.equal(self.cwd):
                    self.file_unchanged(file, patch)
                    return

                dir = file.get_directory()
                if not dir:
                    dir = Directory(os.getcwd())
                else:
                    dir.create()
                tmp_file.copy(dir)
                self.file_reverted(file, patch)
            else:
                self.file_unchanged(file, patch)

    def revert_files(self, filenames, patch_name=None):
        for filename in filenames:
            self.revert_file(filename, patch_name)
Ejemplo n.º 33
0
 def __init__(self, cwd, quilt_pc, quilt_patches):
     super(Revert, self).__init__(cwd)
     self.quilt_pc = Directory(quilt_pc)
     self.quilt_patches = Directory(quilt_patches)
     self.db = Db(quilt_pc)
     self.series = Series(quilt_patches)