Merge lp:~jml/pkgme/build-source-package into lp:pkgme

Proposed by Jonathan Lange
Status: Merged
Approved by: James Westby
Approved revision: 92
Merged at revision: 72
Proposed branch: lp:~jml/pkgme/build-source-package
Merge into: lp:pkgme
Diff against target: 179 lines (+101/-10)
5 files modified
pkgme/bin/main.py (+23/-5)
pkgme/debuild.py (+34/-0)
pkgme/errors.py (+5/-0)
pkgme/testing.py (+15/-0)
pkgme/tests/test_script.py (+24/-5)
To merge this branch: bzr merge lp:~jml/pkgme/build-source-package
Reviewer Review Type Date Requested Status
James Westby Approve
Review via email: mp+69498@code.launchpad.net

Description of the change

Does what it says on the packet.

To post a comment you must log in.
Revision history for this message
James Westby (james-w) wrote :

6 -test_command=python -m subunit.run $IDLIST
7 +test_command=PYTHONPATH=`pwd` python -m subunit.run $IDLIST

Is that not implicit?

41 + stdout, stderr = proc.communicate()

Perhaps we want to do something with the returncode? Also reporting the
stdout, stderr if it fails?

Also, I think it should use that new logging framework that some bright spark
wrote to log a message about what it is doing.

We're going to want to do something with GPG keys as well, but I'm fine deferring
that for now.

Thanks,

James

review: Needs Fixing
Revision history for this message
Jonathan Lange (jml) wrote :

On Wed, Jul 27, 2011 at 5:42 PM, James Westby <email address hidden> wrote:
> Review: Needs Fixing
> 6       -test_command=python -m subunit.run $IDLIST
> 7       +test_command=PYTHONPATH=`pwd` python -m subunit.run $IDLIST
>
> Is that not implicit?
>

Well, sort of. It's there so that the spawned backend scripts will
have the top-level of the tree in their PYTHONPATH, so that they will
use the development version of pkgme libs instead of the system
installed one.

> 41      + stdout, stderr = proc.communicate()
>
> Perhaps we want to do something with the returncode? Also reporting the
> stdout, stderr if it fails?
>
> Also, I think it should use that new logging framework that some bright spark
> wrote to log a message about what it is doing.
>

Good calls both. Will address.

> We're going to want to do something with GPG keys as well, but I'm fine deferring
> that for now.
>

Agreed. Was thinking that. Should have said it.

jml

Revision history for this message
James Westby (james-w) wrote :

> On Wed, Jul 27, 2011 at 5:42 PM, James Westby <email address hidden>
> wrote:
> > Review: Needs Fixing
> > 6       -test_command=python -m subunit.run $IDLIST
> > 7       +test_command=PYTHONPATH=`pwd` python -m subunit.run $IDLIST
> >
> > Is that not implicit?
> >
>
> Well, sort of. It's there so that the spawned backend scripts will
> have the top-level of the tree in their PYTHONPATH, so that they will
> use the development version of pkgme libs instead of the system
> installed one.

Does that only apply if not using virtualenv + setup.py develop?

Thanks,

James

Revision history for this message
Jonathan Lange (jml) wrote :

 * debug stuff done in another branch, merged to trunk
 * don't prompt for gpg passphrase during test run
 * actual tests to show we create these files
 * don't run lintian, because, you know, why bother?
 * raise an error if retcode is non-zero
 * basic infrastructure for showing nice errors, rather than stack traces
 * lots of debugging stuff

Revision history for this message
James Westby (james-w) wrote :

37 + except PkgmeError, e:
38 + sys.stderr.write("ERROR: %s" % (e,))
39 + return 3

Don't we have a --debug option now? Could it turn this in to a "raise" or something?

78 + if stdout:
79 + trace.debug('D: %s' % (stdout.rstrip('\n'),))

Why the prefix on the message there?

Otherwise this looks great, thanks. It's certainly a valuable feature to have, even
if there are some more details to work out later.

Thanks,

James

review: Approve
Revision history for this message
Jonathan Lange (jml) wrote :

Changed the error to raise when debug is set.

The prefix is to make the output more readable. I started without a prefix, then added one and thought the output was more useful.

lp:~jml/pkgme/build-source-package updated
93. By Jonathan Lange

Raise on debug.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'pkgme/bin/main.py'
--- pkgme/bin/main.py 2011-07-29 14:40:05 +0000
+++ pkgme/bin/main.py 2011-08-01 09:02:27 +0000
@@ -5,10 +5,22 @@
5import sys5import sys
66
7from pkgme import __version__, write_packaging7from pkgme import __version__, write_packaging
8from pkgme.debuild import build_source_package
9from pkgme.errors import PkgmeError
8from pkgme import trace10from pkgme import trace
911
1012
11def main(argv=None, target_dir=None):13def build_package(target_dir, interactive):
14 """Where the magic happens."""
15 trace.debug("Building packaging for %s" % (target_dir,))
16 write_packaging(target_dir)
17 trace.debug("Built packaging for %s" % (target_dir,))
18 trace.debug("Building source package for %s" % (target_dir,))
19 build_source_package(target_dir, sign=interactive)
20 trace.debug("Built source package for %s" % (target_dir,))
21
22
23def main(argv=None, target_dir=None, interactive=True):
12 if argv is None:24 if argv is None:
13 argv = sys.argv[1:]25 argv = sys.argv[1:]
14 parser = argparse.ArgumentParser(26 parser = argparse.ArgumentParser(
@@ -23,10 +35,16 @@
23 trace.set_debug()35 trace.set_debug()
24 if target_dir is None:36 if target_dir is None:
25 target_dir = os.getcwd()37 target_dir = os.getcwd()
26 trace.debug("Building packaging for %s" % (target_dir,))38 try:
27 write_packaging(target_dir)39 build_package(target_dir, interactive=interactive)
28 trace.debug("Built packaging for %s" % (target_dir,))40 except PkgmeError, e:
41 if options.debug:
42 raise
43 else:
44 sys.stderr.write("ERROR: %s" % (e,))
45 return 3
46 return 0
2947
3048
31if __name__ == '__main__':49if __name__ == '__main__':
32 main()50 sys.exit(main())
3351
=== added file 'pkgme/debuild.py'
--- pkgme/debuild.py 1970-01-01 00:00:00 +0000
+++ pkgme/debuild.py 2011-08-01 09:02:27 +0000
@@ -0,0 +1,34 @@
1import subprocess
2
3from pkgme.errors import PkgmeError
4from pkgme import trace
5
6
7class DebuildError(PkgmeError):
8
9 def __init__(self, command, retcode, output_lines):
10 super(DebuildError, self).__init__(
11 "%s failed with %s. Output:\n%s" % (
12 ' '.join(command),
13 retcode,
14 ''.join(' | %s' % (line,) for line in output_lines if line)))
15
16
17def build_source_package(directory, sign=True):
18 cmd = ['debuild', '--no-lintian', '-S']
19 if not sign:
20 cmd.extend(['-uc', '-us'])
21 trace.debug("Running %s" % ' '.join(cmd))
22 proc = subprocess.Popen(
23 cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, cwd=directory)
24 output = []
25 while True:
26 stdout = proc.stdout.readline()
27 output.append(stdout)
28 if stdout:
29 trace.debug('D: %s' % (stdout.rstrip('\n'),))
30 else:
31 break
32 retcode = proc.wait()
33 if retcode != 0:
34 raise DebuildError(cmd, retcode, output)
035
=== added file 'pkgme/errors.py'
--- pkgme/errors.py 1970-01-01 00:00:00 +0000
+++ pkgme/errors.py 2011-08-01 09:02:27 +0000
@@ -0,0 +1,5 @@
1"""Exceptions raised by pkgme."""
2
3
4class PkgmeError(Exception):
5 """Base pkgme error."""
06
=== modified file 'pkgme/testing.py'
--- pkgme/testing.py 2011-07-15 09:22:59 +0000
+++ pkgme/testing.py 2011-08-01 09:02:27 +0000
@@ -64,6 +64,21 @@
64 return "Path exists and is a directory"64 return "Path exists and is a directory"
6565
6666
67class DirContains(Matcher):
68
69 def __init__(self, filenames):
70 self.filenames = filenames
71
72 def match(self, path):
73 mismatch = PathExists().match(path)
74 if mismatch is not None:
75 return mismatch
76 mismatch = IsDirectory().match(path)
77 if mismatch is not None:
78 return mismatch
79 return Equals(sorted(self.filenames)).match(sorted(os.listdir(path)))
80
81
67class FileContains(Matcher):82class FileContains(Matcher):
6883
69 def __init__(self, contents):84 def __init__(self, contents):
7085
=== modified file 'pkgme/tests/test_script.py'
--- pkgme/tests/test_script.py 2011-07-15 09:22:47 +0000
+++ pkgme/tests/test_script.py 2011-08-01 09:02:27 +0000
@@ -1,23 +1,26 @@
1import os
2
3import pkg_resources1import pkg_resources
2from StringIO import StringIO
43
5from fixtures import TestWithFixtures4from fixtures import MonkeyPatch
6from testtools import TestCase5from testtools import TestCase
76
8from pkgme.testing import (7from pkgme.testing import (
8 DirContains,
9 DirExists,9 DirExists,
10 TempdirFixture,10 TempdirFixture,
11 )11 )
1212
1313
14class ScriptTests(TestCase, TestWithFixtures):14class ScriptTests(TestCase):
15 """Smoke tests for the top-level pkgme script."""15 """Smoke tests for the top-level pkgme script."""
1616
17 def run_script(self, cwd):17 def run_script(self, cwd):
18 ep = pkg_resources.load_entry_point(18 ep = pkg_resources.load_entry_point(
19 "pkgme", "console_scripts", "pkgme")19 "pkgme", "console_scripts", "pkgme")
20 ep(argv=[], target_dir=cwd)20 stderr = StringIO()
21 with MonkeyPatch('sys.stderr', stderr):
22 ep(argv=[], target_dir=cwd, interactive=False)
23 self.assertEqual('', stderr.getvalue())
2124
22 def test_writes_files(self):25 def test_writes_files(self):
23 tempdir = self.useFixture(TempdirFixture())26 tempdir = self.useFixture(TempdirFixture())
@@ -28,3 +31,19 @@
28""")31""")
29 self.run_script(tempdir.path)32 self.run_script(tempdir.path)
30 self.assertThat(tempdir.abspath("debian"), DirExists())33 self.assertThat(tempdir.abspath("debian"), DirExists())
34
35 def test_builds_source_package(self):
36 tempdir = self.useFixture(TempdirFixture())
37 tempdir.create_file(
38 "foo/setup.py", """from distutils.core import setup
39
40setup(name="foo")
41""")
42 self.run_script(tempdir.abspath('foo'))
43 self.assertThat(tempdir.path, DirContains(
44 ["foo_0.0.0.tar.gz",
45 "foo_0.0.0.dsc",
46 "foo_0.0.0_source.build",
47 "foo_0.0.0_source.changes",
48 "foo",
49 ]))

Subscribers

People subscribed via source and target branches