Merge lp:~ev/apt-clone/python3 into lp:apt-clone

Proposed by Evan
Status: Merged
Merged at revision: 100
Proposed branch: lp:~ev/apt-clone/python3
Merge into: lp:apt-clone
Diff against target: 485 lines (+119/-83)
8 files modified
apt-clone (+10/-8)
apt_clone.py (+46/-40)
debian/changelog (+18/-1)
tests/Makefile (+3/-1)
tests/test_clone.py (+19/-11)
tests/test_clone_upgrade.py (+15/-16)
tests/test_in_chroot.py (+5/-3)
tests/test_merge_sources.py (+3/-3)
To merge this branch: bzr merge lp:~ev/apt-clone/python3
Reviewer Review Type Date Requested Status
Colin Watson Approve
Review via email: mp+109672@code.launchpad.net

Description of the change

Port to Python3.

To post a comment you must log in.
lp:~ev/apt-clone/python3 updated
109. By Evan

* Finish port to Python 3:
  - Handle unicode changes.
  - Do not leak file descriptors.
  - Test against both Python2.7 and Python3.
  - Do not use the deprecated failUnless.
  - Use the io module instead of StringIO.
  - Fix a failing test caused by acpi-support being in main.

110. By Evan

Actually use python3 :)

Revision history for this message
Colin Watson (cjwatson) wrote :

> === modified file 'apt_clone.py'
> --- apt_clone.py 2012-01-27 17:14:05 +0000
> +++ apt_clone.py 2012-06-11 15:50:47 +0000
> @@ -182,7 +184,8 @@
> tarinfo = tarfile.TarInfo("./var/lib/apt-clone/installed.pkgs")
> tarinfo.size = len(s)
> tarinfo.mtime = time.time()
> - tar.addfile(tarinfo, StringIO(s))
> + s = s.encode('utf-8')
> + tar.addfile(tarinfo, BytesIO(s))

tarinfo.size will be wrong if s isn't entirely ASCII. I think you need
to encode earlier.

> - #print tar.getnames()
> + print(tar.getnames())

Did you mean to uncomment this?

> === modified file 'debian/changelog'
> --- debian/changelog 2012-01-27 16:54:20 +0000
> +++ debian/changelog 2012-06-11 15:50:47 +0000
> @@ -8,6 +8,16 @@
>
> -- Michael Vogt <email address hidden> Fri, 27 Jan 2012 16:29:17 +0100
>
> +apt-clone (0.2.2ubuntu1) UNRELEASED; urgency=low
> +
> + * Port to Python 3:
> + - Use Python 3-style print functions.
> + - Use "raise Exception(value)" syntax rather than the old-style "raise
> + Exception, value".
> + - Use dict.items() rather than dict.iteritems().
> +
> + -- Colin Watson <email address hidden> Mon, 11 Jun 2012 09:12:14 +0100
> +
> apt-clone (0.2.2) unstable; urgency=low
>
> * fix extraction of no-longer downloadable debs, thanks
>

This might need updating :-)

The rest looks good to me.

 review needs-fixing

review: Needs Fixing
lp:~ev/apt-clone/python3 updated
111. By Evan

Encode earlier so tarinfo.size is accurate. Thanks Colin Watson!

112. By Evan

Re-comment debugging print statement.

113. By Evan

Fix changelog.

Revision history for this message
Evan (ev) wrote :

I've addressed the issues Colin raises as r111, r112, and r113.

Revision history for this message
Colin Watson (cjwatson) wrote :

Thanks, looks good to me now. I think this is Michael's upstream branch so he may want to flip the version back to 0.2.3 for upload to Debian.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'apt-clone'
--- apt-clone 2012-01-27 23:47:38 +0000
+++ apt-clone 2012-06-12 09:23:17 +0000
@@ -1,4 +1,4 @@
1#!/usr/bin/python1#!/usr/bin/python3
2# Copyright (C) 2011 Canonical2# Copyright (C) 2011 Canonical
3#3#
4# Authors:4# Authors:
@@ -17,6 +17,8 @@
17# this program; if not, write to the Free Software Foundation, Inc.,17# this program; if not, write to the Free Software Foundation, Inc.,
18# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA18# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
1919
20from __future__ import print_function
21
20import argparse22import argparse
21from apt_clone import AptClone23from apt_clone import AptClone
2224
@@ -79,19 +81,19 @@
79 clone = AptClone()81 clone = AptClone()
80 if args.command == "info":82 if args.command == "info":
81 info = clone.info(args.source)83 info = clone.info(args.source)
82 print info84 print(info)
83 if args.command == "clone":85 if args.command == "clone":
84 clone.save_state(args.source, args.destination, 86 clone.save_state(args.source, args.destination,
85 args.with_dpkg_repack, args.with_dpkg_status)87 args.with_dpkg_repack, args.with_dpkg_status)
86 print "not installable: %s" % ", ".join(clone.not_downloadable)88 print("not installable: %s" % ", ".join(clone.not_downloadable))
87 print "version mismatch: %s" % ", ".join(clone.version_mismatch)89 print("version mismatch: %s" % ", ".join(clone.version_mismatch))
88 if not args.with_dpkg_repack:90 if not args.with_dpkg_repack:
89 print "\nNote that you can use --with-dpkg-repack to include "\91 print("\nNote that you can use --with-dpkg-repack to include "
90 "those packages in the clone file."92 "those packges in the clone file.")
91 elif args.command == "restore":93 elif args.command == "restore":
92 if args.simulate:94 if args.simulate:
93 miss = clone.simulate_restore_state(args.source)95 miss = clone.simulate_restore_state(args.source)
94 print "missing: %s" % ",".join(sorted(list(miss)))96 print("missing: %s" % ",".join(sorted(list(miss))))
95 else:97 else:
96 clone.restore_state(args.source, args.destination)98 clone.restore_state(args.source, args.destination)
97 elif args.command == "restore-new-distro":99 elif args.command == "restore-new-distro":
@@ -111,7 +113,7 @@
111 if args.simulate:113 if args.simulate:
112 miss = clone.simulate_restore_state(114 miss = clone.simulate_restore_state(
113 args.source, args.new_distro_codename)115 args.source, args.new_distro_codename)
114 print "missing: %s" % ",".join(sorted(list(miss)))116 print("missing: %s" % ",".join(sorted(list(miss))))
115 else:117 else:
116 clone.restore_state(118 clone.restore_state(
117 args.source, args.destination, args.new_distro_codename, protect_installed)119 args.source, args.destination, args.new_distro_codename, protect_installed)
118120
=== modified file 'apt_clone.py'
--- apt_clone.py 2012-01-27 17:14:05 +0000
+++ apt_clone.py 2012-06-12 09:23:17 +0000
@@ -16,6 +16,8 @@
16# this program; if not, write to the Free Software Foundation, Inc.,16# this program; if not, write to the Free Software Foundation, Inc.,
17# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA17# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
1818
19from __future__ import print_function
20
19import apt21import apt
20from apt.cache import FetchFailedException22from apt.cache import FetchFailedException
21import apt_pkg23import apt_pkg
@@ -29,7 +31,7 @@
29import tempfile31import tempfile
30import time32import time
3133
32from StringIO import StringIO34from io import BytesIO
3335
34if "APT_CLONE_DEBUG_RESOLVER" in os.environ:36if "APT_CLONE_DEBUG_RESOLVER" in os.environ:
35 apt_pkg.config.set("Debug::pkgProblemResolver", "1")37 apt_pkg.config.set("Debug::pkgProblemResolver", "1")
@@ -158,9 +160,9 @@
158 'arch' : apt_pkg.config.find("APT::Architecture")160 'arch' : apt_pkg.config.find("APT::Architecture")
159 }161 }
160 # save it162 # save it
161 f = tempfile.NamedTemporaryFile()163 f = tempfile.NamedTemporaryFile(mode='w')
162 info = "\n".join(["%s: %s" % (key, value) 164 info = "\n".join(["%s: %s" % (key, value)
163 for (key, value) in host_info.iteritems()])165 for (key, value) in host_info.items()])
164 f.write(info+"\n")166 f.write(info+"\n")
165 f.flush()167 f.flush()
166 tar.add(f.name, arcname="./var/lib/apt-clone/uname")168 tar.add(f.name, arcname="./var/lib/apt-clone/uname")
@@ -180,9 +182,10 @@
180 self.version_mismatch.add(pkg.name)182 self.version_mismatch.add(pkg.name)
181 # store the installed.pkgs183 # store the installed.pkgs
182 tarinfo = tarfile.TarInfo("./var/lib/apt-clone/installed.pkgs")184 tarinfo = tarfile.TarInfo("./var/lib/apt-clone/installed.pkgs")
185 s = s.encode('utf-8')
183 tarinfo.size = len(s)186 tarinfo.size = len(s)
184 tarinfo.mtime = time.time()187 tarinfo.mtime = time.time()
185 tar.addfile(tarinfo, StringIO(s))188 tar.addfile(tarinfo, BytesIO(s))
186189
187 def _write_state_dpkg_status(self, tar):190 def _write_state_dpkg_status(self, tar):
188 # store dpkg-status, this is not strictly needed as installed.pkgs191 # store dpkg-status, this is not strictly needed as installed.pkgs
@@ -232,11 +235,11 @@
232 self.commands.repack_deb(pkgname, tdir)235 self.commands.repack_deb(pkgname, tdir)
233 tar.add(tdir, arcname="./var/lib/apt-clone/debs")236 tar.add(tdir, arcname="./var/lib/apt-clone/debs")
234 shutil.rmtree(tdir)237 shutil.rmtree(tdir)
235 #print tdir238 #print(tdir)
236239
237 # detect prefix240 # detect prefix
238 def _detect_tarprefix(self, tar):241 def _detect_tarprefix(self, tar):
239 #print tar.getnames()242 #print(tar.getnames())
240 if tar.getnames()[-1].startswith("./"):243 if tar.getnames()[-1].startswith("./"):
241 self.TARPREFIX = "./"244 self.TARPREFIX = "./"
242 else:245 else:
@@ -313,7 +316,7 @@
313 self._detect_tarprefix(tar)316 self._detect_tarprefix(tar)
314317
315 if not os.path.exists(targetdir):318 if not os.path.exists(targetdir):
316 print "Dir '%s' does not exist, need to bootstrap first" % targetdir319 print("Dir '%s' does not exist, need to bootstrap first" % targetdir)
317 distro = self._get_info_distro(statefile)320 distro = self._get_info_distro(statefile)
318 self.commands.debootstrap(targetdir, distro)321 self.commands.debootstrap(targetdir, distro)
319322
@@ -401,7 +404,7 @@
401 # the actiongroup will help libapt to speed up the following loop404 # the actiongroup will help libapt to speed up the following loop
402 with cache.actiongroup():405 with cache.actiongroup():
403 for line in f.readlines():406 for line in f.readlines():
404 line = line.strip()407 line = line.strip().decode('utf-8')
405 if line.startswith("#") or line == "":408 if line.startswith("#") or line == "":
406 continue409 continue
407 (name, version, auto) = line.split()410 (name, version, auto) = line.split()
@@ -416,7 +419,7 @@
416 if cache.broken_count > 0:419 if cache.broken_count > 0:
417 resolver.resolve()420 resolver.resolve()
418 if not cache[name].marked_install:421 if not cache[name].marked_install:
419 raise SystemError, "pkg %s not marked upgrade" % name422 raise SystemError("pkg %s not marked upgrade" % name)
420 else:423 else:
421 # normal mode, this assume the system is consistent424 # normal mode, this assume the system is consistent
422 cache[name].mark_install(from_user=from_user)425 cache[name].mark_install(from_user=from_user)
@@ -519,9 +522,10 @@
519 owned = set()522 owned = set()
520 dpkg_basedir = os.path.dirname(apt_pkg.config.get("Dir::State::status"))523 dpkg_basedir = os.path.dirname(apt_pkg.config.get("Dir::State::status"))
521 for f in glob.glob(os.path.join(dpkg_basedir, "info", "*.list")):524 for f in glob.glob(os.path.join(dpkg_basedir, "info", "*.list")):
522 for line in open(f):525 with open(f) as fp:
523 if line.startswith("/etc/"):526 for line in fp:
524 owned.add(line.strip())527 if line.startswith("/etc/"):
528 owned.add(line.strip())
525 # now go over etc529 # now go over etc
526 unowned = set()530 unowned = set()
527 for dirpath, dirnames, filenames in os.walk(etcdir):531 for dirpath, dirnames, filenames in os.walk(etcdir):
@@ -535,37 +539,39 @@
535 dpkg_status = sourcedir+apt_pkg.config.find("Dir::State::status")539 dpkg_status = sourcedir+apt_pkg.config.find("Dir::State::status")
536 modified = set()540 modified = set()
537 # iterate dpkg-status file541 # iterate dpkg-status file
538 tag = apt_pkg.TagFile(open(dpkg_status))542 with open(dpkg_status) as fp:
539 for entry in tag:543 tag = apt_pkg.TagFile(fp)
540 if "conffiles" in entry:544 for entry in tag:
541 for line in entry["conffiles"].split("\n"):545 if "conffiles" in entry:
542 obsolete = None546 for line in entry["conffiles"].split("\n"):
543 if len(line.split()) == 3:547 obsolete = None
544 name, md5sum, obsolete = line.split()548 if len(line.split()) == 3:
545 else:549 name, md5sum, obsolete = line.split()
546 name, md5sum = line.split()550 else:
547 # update551 name, md5sum = line.split()
548 path = sourcedir+name552 # update
549 md5sum = md5sum.strip()553 path = sourcedir+name
550 # ignore oboslete conffiles554 md5sum = md5sum.strip()
551 if obsolete == "obsolete":555 # ignore oboslete conffiles
552 continue556 if obsolete == "obsolete":
553 # user removed conffile557 continue
554 if not os.path.exists(path):558 # user removed conffile
555 logging.debug("conffile %s removed" % path)559 if not os.path.exists(path):
556 modified.add(path)560 logging.debug("conffile %s removed" % path)
557 continue561 modified.add(path)
558 # check content562 continue
559 md5 = hashlib.md5()563 # check content
560 md5.update(open(path).read())564 md5 = hashlib.md5()
561 if md5.hexdigest() != md5sum:565 with open(path, 'rb') as fp:
562 logging.debug("conffile %s (%s != %s)" % (566 md5.update(fp.read())
563 path, md5.hexdigest(), md5sum))567 if md5.hexdigest() != md5sum:
564 modified.add(path)568 logging.debug("conffile %s (%s != %s)" % (
569 path, md5.hexdigest(), md5sum))
570 modified.add(path)
565 return modified571 return modified
566572
567 def _dump_debconf_database(self, sourcedir):573 def _dump_debconf_database(self, sourcedir):
568 print "not implemented yet"574 print("not implemented yet")
569 # debconf-copydb configdb newdb --config=Name:newdb --config=Driver:File --config=Filename:/tmp/lala.db575 # debconf-copydb configdb newdb --config=Name:newdb --config=Driver:File --config=Filename:/tmp/lala.db
570 # 576 #
571 # debconf-copydb newdb configdb --config=Name:newdb --config=Driver:File --config=Filename:/tmp/lala.db577 # debconf-copydb newdb configdb --config=Name:newdb --config=Driver:File --config=Filename:/tmp/lala.db
572578
=== modified file 'debian/changelog'
--- debian/changelog 2012-01-27 16:54:20 +0000
+++ debian/changelog 2012-06-12 09:23:17 +0000
@@ -1,11 +1,28 @@
1apt-clone (0.2.3) UNRELEASED; urgency=low1apt-clone (0.2.2ubuntu1) UNRELEASED; urgency=low
22
3 [ Michael Vogt ]
3 * apt_clone.py:4 * apt_clone.py:
4 - fix restoring of the clone with later apt versions (thanks5 - fix restoring of the clone with later apt versions (thanks
5 to Colin Watson)6 to Colin Watson)
6 - bind mount /proc, /sys on restore to chroot (thanks to7 - bind mount /proc, /sys on restore to chroot (thanks to
7 Colin Watson)8 Colin Watson)
89
10 [ Colin Watson ]
11 * Port to Python 3:
12 - Use Python 3-style print functions.
13 - Use "raise Exception(value)" syntax rather than the old-style "raise
14 Exception, value".
15 - Use dict.items() rather than dict.iteritems().
16
17 [ Evan Dandrea ]
18 * Finish port to Python 3:
19 - Handle unicode changes.
20 - Do not leak file descriptors.
21 - Test against both Python2.7 and Python3.
22 - Do not use the deprecated failUnless.
23 - Use the io module instead of StringIO.
24 - Fix a failing test caused by acpi-support being in main.
25
9 -- Michael Vogt <michael.vogt@ubuntu.com> Fri, 27 Jan 2012 16:29:17 +010026 -- Michael Vogt <michael.vogt@ubuntu.com> Fri, 27 Jan 2012 16:29:17 +0100
1027
11apt-clone (0.2.2) unstable; urgency=low28apt-clone (0.2.2) unstable; urgency=low
1229
=== modified file 'tests/Makefile'
--- tests/Makefile 2011-04-08 14:36:22 +0000
+++ tests/Makefile 2012-06-12 09:23:17 +0000
@@ -4,7 +4,9 @@
4test:4test:
5 pyflakes ../apt-clone ../apt_clone.py5 pyflakes ../apt-clone ../apt_clone.py
6 set -e; for f in *.py; do \6 set -e; for f in *.py; do \
7 PYTHONPATH=.. python $$f; \7 for ver in python3 python2; do \
8 PYTHONPATH=.. $$ver $$f; \
9 done; \
8 done; \10 done; \
9 # cruft from the tests11 # cruft from the tests
10 rm -f ./data/mock-system/var/cache/apt/*.bin12 rm -f ./data/mock-system/var/cache/apt/*.bin
1113
=== modified file 'tests/test_clone.py'
--- tests/test_clone.py 2012-01-02 18:08:31 +0000
+++ tests/test_clone.py 2012-06-12 09:23:17 +0000
@@ -1,5 +1,7 @@
1#!/usr/bin/python1#!/usr/bin/python
22
3from __future__ import print_function
4
3import apt5import apt
4import apt_pkg6import apt_pkg
5import mock7import mock
@@ -10,7 +12,7 @@
10import tempfile12import tempfile
11import unittest13import unittest
1214
13from StringIO import StringIO15from io import StringIO
1416
15sys.path.insert(0, "..")17sys.path.insert(0, "..")
16import apt_clone18import apt_clone
@@ -31,7 +33,8 @@
31 os.makedirs(os.path.join(self.tempdir, "var/lib/dpkg/"))33 os.makedirs(os.path.join(self.tempdir, "var/lib/dpkg/"))
32 # ensure we are the right arch34 # ensure we are the right arch
33 os.makedirs(os.path.join(self.tempdir, "etc/apt"))35 os.makedirs(os.path.join(self.tempdir, "etc/apt"))
34 open(os.path.join(self.tempdir, "etc/apt/apt.conf"), "w").write('''36 with open(os.path.join(self.tempdir, "etc/apt/apt.conf"), "w") as fp:
37 fp.write('''
35#clear Dpkg::Post-Invoke;38#clear Dpkg::Post-Invoke;
36#clear Dpkg::Pre-Invoke;39#clear Dpkg::Pre-Invoke;
37#clear APT::Update;40#clear APT::Update;
@@ -59,7 +62,7 @@
59 tarname = os.path.join(targetdir, clone.CLONE_FILENAME)62 tarname = os.path.join(targetdir, clone.CLONE_FILENAME)
60 self.assertTrue(os.path.exists(tarname))63 self.assertTrue(os.path.exists(tarname))
61 tar = tarfile.open(tarname)64 tar = tarfile.open(tarname)
62 #print tar.getmembers()65 #print(tar.getmembers())
63 # verify members in tar66 # verify members in tar
64 members = [m.name for m in tar.getmembers()]67 members = [m.name for m in tar.getmembers()]
65 self.assertTrue("./etc/apt/sources.list" in members)68 self.assertTrue("./etc/apt/sources.list" in members)
@@ -108,11 +111,14 @@
108 # create target dir111 # create target dir
109 targetdir = self.tempdir112 targetdir = self.tempdir
110 # status file from maverick (to simulate running on a maverick live-cd)113 # status file from maverick (to simulate running on a maverick live-cd)
111 s=open("./data/dpkg-status/dpkg-status-ubuntu-maverick").read()114 with open("./data/dpkg-status/dpkg-status-ubuntu-maverick") as fp:
115 s = fp.read()
112 s = s.replace(116 s = s.replace(
113 "Architecture: i386",117 "Architecture: i386",
114 "Architecture: %s" % apt_pkg.config.find("Apt::Architecture"))118 "Architecture: %s" % apt_pkg.config.find("Apt::Architecture"))
115 open(os.path.join(targetdir, "var/lib/dpkg", "status"), "w").write(s)119 path = os.path.join(targetdir, "var/lib/dpkg", "status")
120 with open(path, "w") as fp:
121 fp.write(s)
116 # test upgrade clone from lucid system to maverick122 # test upgrade clone from lucid system to maverick
117 clone = AptClone(cache_cls=MockAptCache)123 clone = AptClone(cache_cls=MockAptCache)
118 clone.restore_state(124 clone.restore_state(
@@ -121,14 +127,16 @@
121 "maverick")127 "maverick")
122 sources_list = os.path.join(targetdir, "etc","apt","sources.list")128 sources_list = os.path.join(targetdir, "etc","apt","sources.list")
123 self.assertTrue(os.path.exists(sources_list))129 self.assertTrue(os.path.exists(sources_list))
124 self.assertTrue("maverick" in open(sources_list).read())130 with open(sources_list) as fp:
125 self.assertFalse("lucid" in open(sources_list).read())131 self.assertTrue("maverick" in fp.read())
132 with open(sources_list) as fp:
133 self.assertFalse("lucid" in fp.read())
126 134
127 def test_restore_state_simulate(self):135 def test_restore_state_simulate(self):
128 clone = AptClone()136 clone = AptClone()
129 missing = clone.simulate_restore_state("./data/apt-state.tar.gz")137 missing = clone.simulate_restore_state("./data/apt-state.tar.gz")
130 # missing, because clone does not have universe enabled138 # missing, because clone does not have universe enabled
131 self.assertEqual(list(missing), ["accerciser", "acpi-support"])139 self.assertEqual(list(missing), ["accerciser"])
132140
133 def test_restore_state_simulate_with_new_release(self):141 def test_restore_state_simulate_with_new_release(self):
134 #apt_pkg.config.set("Debug::PkgProblemResolver", "1")142 #apt_pkg.config.set("Debug::PkgProblemResolver", "1")
@@ -139,7 +147,7 @@
139 missing = clone.simulate_restore_state(147 missing = clone.simulate_restore_state(
140 "./data/apt-state-ubuntu-lucid.tar.gz", "maverick") 148 "./data/apt-state-ubuntu-lucid.tar.gz", "maverick")
141 # FIXME: check that the stuff in missing is ok149 # FIXME: check that the stuff in missing is ok
142 print missing150 print(missing)
143151
144 def test_modified_conffiles(self):152 def test_modified_conffiles(self):
145 clone = AptClone()153 clone = AptClone()
@@ -162,13 +170,13 @@
162 "Dir::state::status", 170 "Dir::state::status",
163 "/var/lib/dpkg/status")171 "/var/lib/dpkg/status")
164 unowned = clone._find_unowned_in_etc()172 unowned = clone._find_unowned_in_etc()
165 #print unowned173 #print(unowned)
166 self.assertNotEqual(unowned, set())174 self.assertNotEqual(unowned, set())
167 # negative test, is created by the installer175 # negative test, is created by the installer
168 self.assertTrue("/etc/apt/sources.list" in unowned)176 self.assertTrue("/etc/apt/sources.list" in unowned)
169 # postivie test, belongs to base-files177 # postivie test, belongs to base-files
170 self.assertFalse("/etc/issue" in unowned)178 self.assertFalse("/etc/issue" in unowned)
171 print "\n".join(sorted(unowned))179 print("\n".join(sorted(unowned)))
172180
173if __name__ == "__main__":181if __name__ == "__main__":
174 unittest.main()182 unittest.main()
175183
=== modified file 'tests/test_clone_upgrade.py'
--- tests/test_clone_upgrade.py 2011-04-07 13:02:27 +0000
+++ tests/test_clone_upgrade.py 2012-06-12 09:23:17 +0000
@@ -9,7 +9,7 @@
9import tempfile9import tempfile
10import unittest10import unittest
1111
12from StringIO import StringIO12from io import StringIO
1313
14sys.path.insert(0, "..")14sys.path.insert(0, "..")
15import apt_clone15import apt_clone
@@ -60,7 +60,8 @@
60 sources_list = os.path.join(tmpdir, "etc", "apt", "sources.list")60 sources_list = os.path.join(tmpdir, "etc", "apt", "sources.list")
61 if not os.path.exists(os.path.dirname(sources_list)):61 if not os.path.exists(os.path.dirname(sources_list)):
62 os.makedirs(os.path.dirname(sources_list))62 os.makedirs(os.path.dirname(sources_list))
63 open(os.path.join(sources_list), "w").write("""63 with open(os.path.join(sources_list), "w") as fp:
64 fp.write("""
64deb http://archive.ubuntu.com/ubuntu %s main restricted universe multiverse65deb http://archive.ubuntu.com/ubuntu %s main restricted universe multiverse
65""" % from_dist)66""" % from_dist)
66 cache = apt.Cache(rootdir=tmpdir)67 cache = apt.Cache(rootdir=tmpdir)
@@ -74,20 +75,18 @@
74 dpkg_status = os.path.join(tmpdir, "var", "lib", "dpkg", "status")75 dpkg_status = os.path.join(tmpdir, "var", "lib", "dpkg", "status")
75 if not os.path.exists(os.path.dirname(dpkg_status)):76 if not os.path.exists(os.path.dirname(dpkg_status)):
76 os.makedirs(os.path.dirname(dpkg_status))77 os.makedirs(os.path.dirname(dpkg_status))
77 dpkg = open(dpkg_status, "w")78 with open(dpkg_status, "w") as dpkg:
78 installed = open(installed_pkgs, "w")79 with open(installed_pkgs, "w") as installed:
79 for pkg in cache:80 for pkg in cache:
80 if pkg.marked_install:81 if pkg.marked_install:
81 s = str(pkg.candidate.record)82 s = str(pkg.candidate.record)
82 s = s.replace("Package: %s\n" % pkg.name,83 s = s.replace("Package: %s\n" % pkg.name,
83 "Package: %s\n%s\n" % (84 "Package: %s\n%s\n" % (
84 pkg.name, "Status: install ok installed"))85 pkg.name, "Status: install ok installed"))
85 dpkg.write("%s\n" % s)86 dpkg.write("%s\n" % s)
86 installed.write("%s %s %s\n" % (pkg.name,87 installed.write("%s %s %s\n" % (pkg.name,
87 pkg.candidate.version,88 pkg.candidate.version,
88 int(pkg.is_auto_installed)))89 int(pkg.is_auto_installed)))
89 dpkg.close()
90 installed.close()
91 return tmpdir90 return tmpdir
9291
9392
9493
=== modified file 'tests/test_in_chroot.py'
--- tests/test_in_chroot.py 2012-01-27 17:14:05 +0000
+++ tests/test_in_chroot.py 2012-06-12 09:23:17 +0000
@@ -1,5 +1,7 @@
1#!/usr/bin/python1#!/usr/bin/python
22
3from __future__ import print_function
4
3import apt5import apt
4import logging6import logging
5import os7import os
@@ -25,7 +27,7 @@
2527
26 def test_real(self):28 def test_real(self):
27 if os.getuid() != 0:29 if os.getuid() != 0:
28 print "Skipping because uid != 0"30 print("Skipping because uid != 0")
29 return31 return
30 # do it32 # do it
31 target = "./test-chroot"33 target = "./test-chroot"
@@ -34,8 +36,8 @@
34 subprocess.call(["debootstrap", "--arch=i386",36 subprocess.call(["debootstrap", "--arch=i386",
35 "maverick", target])37 "maverick", target])
36 # force i38638 # force i386
37 open(os.path.join(target, "etc/apt/apt.conf"), "w").write(39 with open(os.path.join(target, "etc/apt/apt.conf"), "w") as fp:
38 'APT::Architecture "i386";')40 fp.write('APT::Architecture "i386";')
3941
40 # restore42 # restore
41 clone = AptClone()43 clone = AptClone()
4244
=== modified file 'tests/test_merge_sources.py'
--- tests/test_merge_sources.py 2011-04-06 14:06:31 +0000
+++ tests/test_merge_sources.py 2012-06-12 09:23:17 +0000
@@ -26,8 +26,8 @@
26 if line != '\n' and not line.startswith('#'):26 if line != '\n' and not line.startswith('#'):
27 tally[line] += 127 tally[line] += 1
28 # There should not be any duplicate source lines.28 # There should not be any duplicate source lines.
29 for line, count in tally.iteritems():29 for line, count in tally.items():
30 self.failUnless(count == 1, '"%s" occurred %d times.'30 self.assertTrue(count == 1, '"%s" occurred %d times.'
31 % (line, count))31 % (line, count))
3232
33 # Check for extras, others...33 # Check for extras, others...
@@ -43,7 +43,7 @@
43 for line in fp:43 for line in fp:
44 if line == match:44 if line == match:
45 found = True45 found = True
46 self.failUnless(found,46 self.assertTrue(found,
47 '%s repository not present or disabled.' % pocket)47 '%s repository not present or disabled.' % pocket)
4848
49if __name__ == "__main__":49if __name__ == "__main__":

Subscribers

People subscribed via source and target branches

to all changes: