Merge lp:~jelmer/bzr-builddeb/lazy-1 into lp:~bzr-builddeb-hackers/bzr-builddeb/trunk-old

Proposed by Jelmer Vernooij
Status: Merged
Merge reported by: James Westby
Merged at revision: not available
Proposed branch: lp:~jelmer/bzr-builddeb/lazy-1
Merge into: lp:~bzr-builddeb-hackers/bzr-builddeb/trunk-old
Diff against target: None lines
To merge this branch: bzr merge lp:~jelmer/bzr-builddeb/lazy-1
To post a comment you must log in.
Revision history for this message
Jelmer Vernooij (jelmer) wrote :

The attached patch improves the import overhead of bzr-builddeb by:

 * lazily registering all commands (moved to cmds.py)
 * using absolute imports everywhere, and no longer updating sys.path to
   include "bzrlib.plugins.builddeb"

It seems intrusive, but mainly just moves code from __init__.py to cmds.py.

In practice, this means having bzr-builddeb enabled will only load the
__init__.py file if you're not using it.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file '__init__.py'
2--- __init__.py 2008-12-02 16:42:32 +0000
3+++ __init__.py 2009-02-12 14:45:56 +0000
4@@ -24,84 +24,24 @@
5 """bzr-builddeb - manage packages in a Bazaar branch."""
6
7 import os
8-import shutil
9-import subprocess
10-import tempfile
11-import urlparse
12-
13-from debian_bundle.changelog import Version
14-
15-from bzrlib import bzrdir
16-from bzrlib.branch import Branch
17-from bzrlib.commands import Command, register_command
18-from bzrlib.config import ConfigObj
19+
20+from bzrlib.commands import plugin_cmds
21 from bzrlib.directory_service import directories
22-from bzrlib.errors import (BzrCommandError,
23- NoSuchFile,
24- NoWorkingTree,
25- NotBranchError,
26- FileExists,
27- AlreadyBranchError,
28- )
29-from bzrlib.option import Option
30-from bzrlib.trace import info, warning
31-from bzrlib.transport import get_transport
32-from bzrlib import urlutils
33-from bzrlib.workingtree import WorkingTree
34
35-from bzrlib.plugins.builddeb.builder import (DebBuild,
36- DebMergeBuild,
37- DebNativeBuild,
38- DebSplitBuild,
39- DebMergeExportUpstreamBuild,
40- DebExportUpstreamBuild,
41- )
42-from bzrlib.plugins.builddeb.config import DebBuildConfig
43-from bzrlib.plugins.builddeb.errors import (StopBuild,
44- )
45-from bzrlib.plugins.builddeb.hooks import run_hook
46-from bzrlib.plugins.builddeb.import_dsc import (
47- DistributionBranch,
48- DistributionBranchSet,
49- DscCache,
50- DscComp,
51- )
52-from bzrlib.plugins.builddeb.properties import BuildProperties
53-from bzrlib.plugins.builddeb import revspec
54-from bzrlib.plugins.builddeb.util import (find_changelog,
55- lookup_distribution,
56- suite_to_distribution,
57- tarball_name,
58- )
59 from bzrlib.plugins.builddeb.version import version_info
60
61+commands = {
62+ "test_builddeb": [],
63+ "builddeb": ["bd"],
64+ "merge_upstream": ["mu"],
65+ "import_dsc": [],
66+ "bd_do": [],
67+ "mark_uploaded": []
68+ }
69
70-dont_purge_opt = Option('dont-purge',
71- help="Don't purge the build directory after building")
72-result_opt = Option('result-dir',
73- help="Directory in which to place the resulting package files", type=str)
74-builder_opt = Option('builder',
75- help="Command to build the package", type=str)
76-merge_opt = Option('merge',
77- help='Merge the debian part of the source in to the upstream tarball')
78-build_dir_opt = Option('build-dir',
79- help="The dir to use for building", type=str)
80-orig_dir_opt = Option('orig-dir',
81- help="Directory containing the .orig.tar.gz files. For use when only"
82- +"debian/ is versioned", type=str)
83-native_opt = Option('native',
84- help="Build a native package")
85-split_opt = Option('split',
86- help="Automatically create an .orig.tar.gz from a full source branch")
87-export_upstream_opt = Option('export-upstream',
88- help="Create the .orig.tar.gz from a bzr branch before building",
89- type=unicode)
90-export_upstream_revision_opt = Option('export-upstream-revision',
91- help="Select the upstream revision that will be exported",
92- type=str)
93-no_user_conf_opt = Option('no-user-config',
94- help="Stop builddeb from reading the user's config file. Used mainly "
95- "for tests")
96+for command, aliases in commands.iteritems():
97+ plugin_cmds.register_lazy('cmd_' + command, aliases,
98+ "bzrlib.plugins.builddeb.cmds")
99
100 builddeb_dir = '.bzr-builddeb'
101 default_conf = os.path.join(builddeb_dir, 'default.conf')
102@@ -113,680 +53,17 @@
103 default_result_dir = '..'
104
105
106-def debuild_config(tree, working_tree, no_user_config):
107- """Obtain the Debuild configuration object.
108-
109- :param tree: A Tree object, can be a WorkingTree or RevisionTree.
110- :param working_tree: Whether the tree is a working tree.
111- :param no_user_config: Whether to skip the user configuration
112- """
113- config_files = []
114- user_config = None
115- if (working_tree and
116- tree.has_filename(local_conf) and tree.path2id(local_conf) is None):
117- config_files.append((tree.get_file_byname(local_conf), True))
118- if not no_user_config:
119- config_files.append((global_conf, True))
120- user_config = global_conf
121- if tree.path2id(default_conf):
122- config_files.append((tree.get_file(tree.path2id(default_conf)), False))
123- config = DebBuildConfig(config_files)
124- config.set_user_config(user_config)
125- return config
126-
127-
128-class cmd_builddeb(Command):
129- """Builds a Debian package from a branch.
130-
131- If BRANCH is specified it is assumed that the branch you wish to build is
132- located there. If it is not specified then the current directory is used.
133-
134- By default the if a working tree is found it is used to build and otherwise
135- the last committed revision was used. To force building the last committed
136- revision use --revision -1. You can specify any other revision using the
137- --revision option.
138-
139- If you only wish to export the package, and not build it (especially useful
140- for merge mode), use --export-only.
141-
142- To leave the build directory when the build is completed use --dont-purge.
143-
144- Specify the command to use when building using the --builder option,
145-
146- You can also specify directories to use for different things. --build-dir
147- is the directory to build the packages beneath, which defaults to
148- '../build-area'. '--orig-dir' specifies the directory that contains the
149- .orig.tar.gz files , which defaults to '..'. '--result-dir' specifies where
150- the resulting package files should be placed, which defaults to '..'.
151- --result-dir will have problems if you use a build command that places
152- the results in a different directory.
153-
154- The --reuse option will be useful if you are in merge mode, and the upstream
155- tarball is very large. It attempts to reuse a build directory from an earlier
156- build. It will fail if one doesn't exist, but you can create one by using
157- --export-only.
158-
159- --quick allows you to define a quick-builder in your configuration files,
160- which will be used when this option is passed. It defaults to 'fakeroot
161- debian/rules binary'. It is overriden if --builder is passed. Using this
162- and --reuse allows for fast rebuilds.
163-
164- --source allows you to build a source package without having to
165- specify a builder to do so with --builder. It uses the source-builder
166- option from your configuration files, and defaults to 'dpkg-buildpackage
167- -rfakeroot -uc -us -S'. It is overriden if either --builder or --quick are
168- used.
169-
170- """
171- working_tree_opt = Option('working-tree', help="This option has no effect",
172- short_name='w')
173- export_only_opt = Option('export-only', help="Export only, don't build",
174- short_name='e')
175- use_existing_opt = Option('use-existing',
176- help="Use an existing build directory")
177- ignore_changes_opt = Option('ignore-changes',
178- help="This option has no effect")
179- ignore_unknowns_opt = Option('ignore-unknowns',
180- help="Ignore any unknown files, but still fail if there are any changes"
181- +", the default is to fail if there are unknowns as well.")
182- quick_opt = Option('quick', help="Quickly build the package, uses "
183- +"quick-builder, which defaults to \"fakeroot "
184- +"debian/rules binary\"")
185- reuse_opt = Option('reuse', help="Try to avoid expoting too much on each "
186- +"build. Only works in merge mode; it saves unpacking "
187- +"the upstream tarball each time. Implies --dont-purge "
188- +"and --use-existing")
189- source_opt = Option('source', help="Build a source package, uses "
190- +"source-builder, which defaults to \"dpkg-buildpackage "
191- +"-rfakeroot -uc -us -S\"", short_name='S')
192- result_compat_opt = Option('result', help="Present only for compatibility "
193- "with bzr-builddeb <= 2.0. Use --result-dir instead.")
194- takes_args = ['branch?']
195- aliases = ['bd']
196- takes_options = [working_tree_opt, export_only_opt,
197- dont_purge_opt, use_existing_opt, result_opt, builder_opt, merge_opt,
198- build_dir_opt, orig_dir_opt, ignore_changes_opt, ignore_unknowns_opt,
199- quick_opt, reuse_opt, native_opt, split_opt, export_upstream_opt,
200- export_upstream_revision_opt, source_opt, 'revision',
201- no_user_conf_opt, result_compat_opt]
202-
203- def run(self, branch=None, verbose=False, working_tree=False,
204- export_only=False, dont_purge=False, use_existing=False,
205- result_dir=None, builder=None, merge=False, build_dir=None,
206- orig_dir=None, ignore_changes=False, ignore_unknowns=False,
207- quick=False, reuse=False, native=False, split=False,
208- export_upstream=None, export_upstream_revision=None,
209- source=False, revision=None, no_user_config=False, result=None):
210-
211- if branch is None:
212- branch = "."
213-
214- # Find out if we were passed a local or remote branch
215- is_local = urlparse.urlsplit(branch)[0] in ('', 'file')
216- if is_local:
217- os.chdir(branch)
218-
219- try:
220- tree, _ = WorkingTree.open_containing(branch)
221- branch = tree.branch
222- except NoWorkingTree:
223- tree = None
224- branch, _ = Branch.open_containing(branch)
225-
226- if revision is None and tree is not None:
227- info("Building using working tree")
228- working_tree = True
229- else:
230- if revision is None:
231- revid = branch.last_revision()
232- elif len(revision) == 1:
233- revid = revision[0].in_history(branch).rev_id
234- else:
235- raise BzrCommandError('bzr builddeb --revision takes exactly one '
236- 'revision specifier.')
237- info("Building branch from revision %s", revid)
238- tree = branch.repository.revision_tree(revid)
239- working_tree = False
240-
241- tree.lock_read()
242- try:
243- config = debuild_config(tree, working_tree, no_user_config)
244-
245- if reuse:
246- info("Reusing existing build dir")
247- dont_purge = True
248- use_existing = True
249-
250- if not merge:
251- merge = config.merge
252-
253- if merge:
254- info("Running in merge mode")
255- else:
256- if not native:
257- native = config.native
258- if native:
259- info("Running in native mode")
260- else:
261- if not split:
262- split = config.split
263- if split:
264- info("Running in split mode")
265-
266- if builder is None:
267- if quick:
268- builder = config.quick_builder
269- if builder is None:
270- builder = "fakeroot debian/rules binary"
271- else:
272- if source:
273- builder = config.source_builder
274- if builder is None:
275- builder = "dpkg-buildpackage -rfakeroot -uc -us -S"
276- else:
277- builder = config.builder
278- if builder is None:
279- builder = "dpkg-buildpackage -uc -us -rfakeroot"
280-
281- (changelog, larstiq) = find_changelog(tree, merge)
282-
283- config.set_version(changelog.version)
284-
285- if export_upstream is None:
286- export_upstream = config.export_upstream
287-
288- if export_upstream_revision is None:
289- export_upstream_revision = config.export_upstream_revision
290-
291- if result_dir is None:
292- result_dir = result
293-
294- if result_dir is None:
295- if is_local:
296- result_dir = config.result_dir
297- else:
298- result_dir = config.user_result_dir
299- if result_dir is not None:
300- result_dir = os.path.realpath(result_dir)
301-
302- if build_dir is None:
303- if is_local:
304- build_dir = config.build_dir or default_build_dir
305- else:
306- build_dir = config.user_build_dir or 'build-area'
307-
308- if orig_dir is None:
309- if is_local:
310- orig_dir = config.orig_dir or default_orig_dir
311- else:
312- orig_dir = config.user_orig_dir or 'build-area'
313-
314- properties = BuildProperties(changelog, build_dir, orig_dir, larstiq)
315-
316- if merge:
317- if export_upstream is None:
318- build = DebMergeBuild(properties, tree, _is_working_tree=working_tree)
319- else:
320- prepull_upstream = config.prepull_upstream
321- stop_on_no_change = config.prepull_upstream_stop
322- build = DebMergeExportUpstreamBuild(properties, tree, export_upstream,
323- export_upstream_revision,
324- prepull_upstream,
325- stop_on_no_change,
326- _is_working_tree=working_tree)
327- elif native:
328- build = DebNativeBuild(properties, tree, _is_working_tree=working_tree)
329- elif split:
330- build = DebSplitBuild(properties, tree, _is_working_tree=working_tree)
331- else:
332- if export_upstream is None:
333- build = DebBuild(properties, tree, _is_working_tree=working_tree)
334- else:
335- prepull_upstream = config.prepull_upstream
336- stop_on_no_change = config.prepull_upstream_stop
337- build = DebExportUpstreamBuild(properties, tree, export_upstream,
338- export_upstream_revision,
339- prepull_upstream,
340- stop_on_no_change,
341- _is_working_tree=working_tree)
342-
343- build.prepare(use_existing)
344-
345- run_hook(tree, 'pre-export', config)
346-
347- try:
348- build.export(use_existing)
349- except StopBuild, e:
350- warning('Stopping the build: %s.', e.reason)
351- return
352-
353- if not export_only:
354- run_hook(tree, 'pre-build', config, wd=properties.source_dir())
355- build.build(builder)
356- run_hook(tree, 'post-build', config, wd=properties.source_dir())
357- if not dont_purge:
358- build.clean()
359- arch = None
360- if source:
361- arch = "source"
362- if result_dir is not None:
363- build.move_result(result_dir, arch=arch)
364- else:
365- build.move_result(default_result_dir, allow_missing=True, arch=arch)
366- finally:
367- tree.unlock()
368-
369-
370-register_command(cmd_builddeb)
371-
372-
373-class cmd_merge_upstream(Command):
374- """Merges a new upstream version into the current branch.
375-
376- Takes a new upstream version and merges it in to your branch, so that your
377- packaging changes are applied to the new version.
378-
379- You must supply the source to import from, and the version number of the
380- new release. The source can be a .tar.gz, .tar, .tar.bz2, .tgz or .zip
381- archive, or a directory. The source may also be a remote file.
382-
383- You must supply the version number of the new upstream release
384- using --version, and the target distribution using --distribution.
385- The target distribtution is the distribution that you aim to upload to,
386- one of "debian" or "ubuntu". You can also specify the target used in
387- the changelog, e.g. "unstable", and it will be resolved automatically.
388-
389- If there is no debian changelog in the branch to retrieve the package
390- name from then you must pass the --package option. If this version
391- will change the name of the source package then you can use this option
392- to set the new name.
393- """
394- takes_args = ['location?']
395- aliases = ['mu']
396-
397- package_opt = Option('package', help="The name of the source package.",
398- type=str)
399- version_opt = Option('version', help="The version number of this release.",
400- type=str)
401- distribution_opt = Option('distribution', help="The distribution that "
402- "this release is targetted at", type=str)
403- directory_opt = Option('directory', help='Working tree into which to merge.',
404- short_name='d', type=unicode)
405-
406- takes_options = [package_opt, no_user_conf_opt, version_opt,
407- distribution_opt, directory_opt, 'revision']
408-
409- def run(self, location=None, version=None, distribution=None, package=None,
410- no_user_config=None, directory=".", revision=None):
411- from bzrlib.plugins.builddeb.errors import MissingChangelogError
412- from bzrlib.plugins.builddeb.repack_tarball import repack_tarball
413- from bzrlib.plugins.builddeb.merge_upstream import merge_upstream_branch
414- tree, _ = WorkingTree.open_containing(directory)
415- tree.lock_write()
416- try:
417- # Check for uncommitted changes.
418- if tree.changes_from(tree.basis_tree()).has_changed():
419- raise BzrCommandError("There are uncommitted changes in the "
420- "working tree. You must commit before using this "
421- "command.")
422- config = debuild_config(tree, tree, no_user_config)
423- if config.merge:
424- raise BzrCommandError("Merge upstream in merge mode is not "
425- "yet supported.")
426- if config.native:
427- raise BzrCommandError("Merge upstream in native mode is not "
428- "yet supported.")
429- if config.export_upstream and location is None:
430- location = config.export_upstream
431- if config.split:
432- raise BzrCommandError("Split mode is not yet supported.")
433-
434- if location is None:
435- raise BzrCommandError("No location specified to merge")
436- try:
437- changelog = find_changelog(tree, False)[0]
438- current_version = changelog.version
439- if package is None:
440- package = changelog.package
441- except MissingChangelogError:
442- current_version = None
443-
444- if package is None:
445- raise BzrCommandError("You did not specify --package, and "
446- "there is no changelog from which to determine the "
447- "package name, which is needed to know the name to "
448- "give the .orig.tar.gz. Please specify --package.")
449-
450- try:
451- upstream_branch = Branch.open(location)
452- except NotBranchError:
453- upstream_branch = None
454-
455- if upstream_branch is None:
456- if version is None:
457- raise BzrCommandError("You must specify the version number using "
458- "--version.")
459- version = Version(version)
460- if distribution is None:
461- raise BzrCommandError("You must specify the target distribution "
462- "using --distribution.")
463- if revision is not None:
464- raise BzrCommandError("--revision is not allowed when merging a tarball")
465-
466- orig_dir = config.orig_dir or default_orig_dir
467- orig_dir = os.path.join(tree.basedir, orig_dir)
468- dest_name = tarball_name(package, version.upstream_version)
469- try:
470- repack_tarball(location, dest_name, target_dir=orig_dir)
471- except FileExists:
472- raise BzrCommandError("The target file %s already exists, and is either "
473- "different to the new upstream tarball, or they "
474- "are of different formats. Either delete the target "
475- "file, or use it as the argument to import.")
476- tarball_filename = os.path.join(orig_dir, dest_name)
477- distribution = distribution.lower()
478- distribution_name = lookup_distribution(distribution)
479- if distribution_name is None:
480- raise BzrCommandError("Unknown target distribution: %s" \
481- % distribution)
482- db = DistributionBranch(distribution_name, tree.branch, None,
483- tree=tree)
484- dbs = DistributionBranchSet()
485- dbs.add_branch(db)
486- conflicts = db.merge_upstream(tarball_filename, version,
487- current_version)
488- else:
489- if revision is not None:
490- if len(revision) > 1:
491- raise BzrCommandError("merge-upstream takes only a single --revision")
492- upstream_revspec = revision[0]
493- else:
494- upstream_revspec = None
495- version = merge_upstream_branch(tree, upstream_branch, package,
496- upstream_revspec, version)
497- info("Using version string %s for upstream branch." % (version))
498- finally:
499- tree.unlock()
500-
501- if "~bzr" in str(version) or "+bzr" in str(version):
502- entry_description = "New upstream snapshot."
503- else:
504- entry_description = "New upstream release."
505-
506- info("The new upstream version has been imported. You should "
507- "now update the changelog (try dch -v %s-1 \"%s\"), resolve any "
508- "conflicts, and then commit." % (str(version), entry_description))
509-
510-
511-register_command(cmd_merge_upstream)
512-
513-
514-class cmd_import_dsc(Command):
515- """Import a series of source packages.
516-
517- Provide a number of source packages (.dsc files), and they will
518- be imported to create a branch with history that reflects those
519- packages.
520-
521- The first argument is the distribution that these source packages
522- were uploaded to, one of "debian" or "ubuntu". It can also
523- be the target distribution from the changelog, e.g. "unstable",
524- which will be resolved to the correct distribution.
525-
526- You can also specify a file (possibly remote) that contains a
527- list of source packages (.dsc files) to import using the --file
528- option. Each line is taken to be a URI or path to import. The
529- sources specified in the file are used in addition to those
530- specified on the command line.
531-
532- If you have an existing branch containing packaging and you want to
533- import a .dsc from an upload done from outside the version control
534- system you can use this command.
535- """
536-
537- takes_args = ['files*']
538-
539- filename_opt = Option('file', help="File containing URIs of source "
540- "packages to import.", type=str, argname="filename",
541- short_name='F')
542- distribution_opt = Option('distribution', help="The distribution that "
543- "these packages were uploaded to.", type=str)
544-
545- takes_options = [filename_opt, distribution_opt]
546-
547- def import_many(self, db, files_list, orig_target):
548- cache = DscCache()
549- files_list.sort(cmp=DscComp(cache).cmp)
550- if not os.path.exists(orig_target):
551- os.makedirs(orig_target)
552- for dscname in files_list:
553- dsc = cache.get_dsc(dscname)
554- def get_dsc_part(from_transport, filename):
555- from_f = from_transport.get(filename)
556- contents = from_f.read()
557- to_f = open(os.path.join(orig_target, filename), 'wb')
558- try:
559- to_f.write(contents)
560- finally:
561- to_f.close()
562- base, filename = urlutils.split(dscname)
563- from_transport = cache.get_transport(dscname)
564- get_dsc_part(from_transport, filename)
565- for file_details in dsc['files']:
566- name = file_details['name']
567- get_dsc_part(from_transport, name)
568- db.import_package(os.path.join(orig_target, filename))
569-
570- def run(self, files_list, distribution=None, filename=None):
571- from bzrlib.plugins.builddeb.errors import MissingChangelogError
572- if distribution is None:
573- raise BzrCommandError("You must specify the distribution "
574- "these packages were uploaded to using --distribution.")
575- distribution = distribution.lower()
576- distribution_name = lookup_distribution(distribution)
577- if distribution_name is None:
578- raise BzrCommandError("Unknown target distribution: %s" \
579- % distribution)
580- try:
581- tree = WorkingTree.open_containing('.')[0]
582- except NotBranchError:
583- raise BzrCommandError("There is no tree to import the packages in to")
584- tree.lock_write()
585- try:
586- if tree.changes_from(tree.basis_tree()).has_changed():
587- raise BzrCommandError("There are uncommitted changes in the "
588- "working tree. You must commit before using this "
589- "command")
590- if files_list is None:
591- files_list = []
592- if filename is not None:
593- if isinstance(filename, unicode):
594- filename = filename.encode('utf-8')
595- base_dir, path = urlutils.split(filename)
596- sources_file = get_transport(base_dir).get(path)
597- for line in sources_file:
598- line.strip()
599- files_list.append(line)
600- if len(files_list) < 1:
601- raise BzrCommandError("You must give the location of at least one "
602- "source package to install, or use the "
603- "--file option.")
604- config = debuild_config(tree, tree, False)
605- orig_dir = config.orig_dir or default_orig_dir
606- orig_target = os.path.join(tree.basedir, default_orig_dir)
607- db = DistributionBranch(distribution_name, tree.branch,
608- None, tree=tree)
609- dbs = DistributionBranchSet()
610- dbs.add_branch(db)
611- try:
612- (changelog, larstiq) = find_changelog(tree, False)
613- last_version = changelog.version
614- except MissingChangelogError:
615- last_version = None
616- tempdir = tempfile.mkdtemp(dir=os.path.join(tree.basedir,
617- '..'))
618- try:
619- if last_version is not None:
620- upstream_tip = db._revid_of_upstream_version_from_branch(
621- last_version)
622- db._extract_upstream_tree(upstream_tip, tempdir)
623- else:
624- db._create_empty_upstream_tree(tempdir)
625- self.import_many(db, files_list, orig_target)
626- finally:
627- shutil.rmtree(tempdir)
628- finally:
629- tree.unlock()
630-
631-register_command(cmd_import_dsc)
632-
633-
634-class cmd_bd_do(Command):
635- """Run a command in an exported package, copying the result back.
636-
637- For a merge mode package the full source is not available, making some
638- operations difficult. This command allows you to run any command in an
639- exported source directory, copying the resulting debian/ directory back
640- to your branch if the command is successful.
641-
642- For instance:
643-
644- bzr bd-do
645-
646- will run a shell in the unpacked source. Any changes you make in the
647- ``debian/`` directory (and only those made in that directory) will be copied
648- back to the branch. If you exit with a non-zero exit code (e.g. "exit 1"),
649- then the changes will not be copied back.
650-
651- You can also specify single commands to be run, e.g.
652-
653- bzr bd-do "dpatch-edit-patch 01-fix-build"
654-
655- Note that only the first argument is used as the command, and so the above
656- example had to be quoted.
657- """
658-
659- takes_args = ['command?']
660-
661- def run(self, command=None):
662- t = WorkingTree.open_containing('.')[0]
663- config = debuild_config(t, t, False)
664-
665- if not config.merge:
666- raise BzrCommandError("This command only works for merge mode "
667- "packages. See /usr/share/doc/bzr-builddeb"
668- "/user_manual/merge.html for more information.")
669-
670- give_instruction = False
671- if command is None:
672- try:
673- command = os.environ['SHELL']
674- except KeyError:
675- command = "/bin/sh"
676- give_instruction = True
677- (changelog, larstiq) = find_changelog(t, True)
678- build_dir = config.build_dir
679- if build_dir is None:
680- build_dir = default_build_dir
681- orig_dir = config.orig_dir
682- if orig_dir is None:
683- orig_dir = default_orig_dir
684- properties = BuildProperties(changelog, build_dir, orig_dir, larstiq)
685- export_upstream = config.export_upstream
686- export_upstream_revision = config.export_upstream_revision
687-
688- if export_upstream is None:
689- build = DebMergeBuild(properties, t, _is_working_tree=True)
690- else:
691- prepull_upstream = config.prepull_upstream
692- stop_on_no_change = config.prepull_upstream_stop
693- build = DebMergeExportUpstreamBuild(properties, t, export_upstream,
694- export_upstream_revision,
695- prepull_upstream,
696- stop_on_no_change,
697- _is_working_tree=True)
698-
699- build.prepare()
700- try:
701- build.export()
702- except StopBuild, e:
703- warning('Stopping the build: %s.', e.reason)
704- info('Running "%s" in the exported directory.' % (command))
705- if give_instruction:
706- info('If you want to cancel your changes then exit with a non-zero '
707- 'exit code, e.g. run "exit 1".')
708- proc = subprocess.Popen(command, shell=True,
709- cwd=properties.source_dir())
710- proc.wait()
711- if proc.returncode != 0:
712- raise BzrCommandError('Not updating the working tree as the command '
713- 'failed.')
714- info("Copying debian/ back")
715- if larstiq:
716- destination = '.'
717- else:
718- destination = 'debian/'
719- source_debian = os.path.join(properties.source_dir(), 'debian')
720- for filename in os.listdir(source_debian):
721- proc = subprocess.Popen('cp -apf "%s" "%s"' % (
722- os.path.join(source_debian, filename), destination),
723- shell=True)
724- proc.wait()
725- if proc.returncode != 0:
726- raise BzrCommandError('Copying back debian/ failed')
727- build.clean()
728- info('If any files were added or removed you should run "bzr add" or '
729- '"bzr rm" as appropriate.')
730-
731-
732-register_command(cmd_bd_do)
733-
734-
735-class cmd_mark_uploaded(Command):
736- """Mark that this branch has been uploaded, prior to pushing it.
737-
738- When a package has been uploaded we want to mark the revision
739- that it was uploaded in. This command automates doing that
740- by marking the current tip revision with the version indicated
741- in debian/changelog.
742- """
743- force = Option('force', help="Mark the upload even if it is already "
744- "marked.")
745-
746- takes_options = [merge_opt, no_user_conf_opt, force]
747-
748- def run(self, merge=False, no_user_config=False, force=None):
749- t = WorkingTree.open_containing('.')[0]
750- t.lock_write()
751- try:
752- if t.changes_from(t.basis_tree()).has_changed():
753- raise BzrCommandError("There are uncommitted changes in the "
754- "working tree. You must commit before using this "
755- "command")
756- config = debuild_config(t, t, no_user_config)
757- if not merge:
758- merge = config.merge
759- (changelog, larstiq) = find_changelog(t, merge)
760- distributions = changelog.distributions.strip()
761- target_dist = distributions.split()[0]
762- distribution_name = suite_to_distribution(target_dist)
763- if distribution_name is None:
764- raise BzrCommandError("Unknown target distribution: %s" \
765- % target_dist)
766- db = DistributionBranch(distribution_name, t.branch, None)
767- dbs = DistributionBranchSet()
768- dbs.add_branch(db)
769- if db.has_version(changelog.version):
770- if not force:
771- raise BzrCommandError("This version has already been "
772- "marked uploaded. Use --force to force marking "
773- "this new version.")
774- db.tag_version(changelog.version)
775- finally:
776- t.unlock()
777-
778-
779-register_command(cmd_mark_uploaded)
780+directories.register_lazy("deb:", 'bzrlib.plugins.builddeb.directory',
781+ 'VcsDirectory',
782+ "Directory that uses Debian Vcs-* control fields to look up branches")
783+
784+try:
785+ from bzrlib.revisionspec import revspec_registry
786+ revspec_registry.register_lazy("package:", "bzrlib.plugins.builddeb.revspec", "RevisionSpec_package")
787+except ImportError:
788+ from bzrlib.revisionspec import SPEC_TYPES
789+ from bzrlib.plugins.builddeb.revspec import RevisionSpec_package
790+ SPEC_TYPES.append(RevisionSpec_package)
791
792
793 def test_suite():
794@@ -797,30 +74,9 @@
795 return result
796
797
798-class cmd_test_builddeb(Command):
799- """Run the builddeb test suite"""
800-
801- hidden = True
802-
803- def run(self):
804- from bzrlib.tests import selftest
805- passed = selftest(test_suite_factory=test_suite)
806- # invert for shell exit code rules
807- return not passed
808-
809-
810-register_command(cmd_test_builddeb)
811-
812-directories.register_lazy("deb:", 'bzrlib.plugins.builddeb.directory',
813- 'VcsDirectory',
814- "Directory that uses Debian Vcs-* control fields to look up branches")
815-
816 if __name__ == '__main__':
817 print ("This is a Bazaar plugin. Copy this directory to ~/.bazaar/plugins "
818 "to use it.\n")
819 import unittest
820 runner = unittest.TextTestRunner()
821 runner.run(test_suite())
822-else:
823- import sys
824- sys.path.append(os.path.dirname(os.path.abspath(__file__)))
825
826=== added file 'cmds.py'
827--- cmds.py 1970-01-01 00:00:00 +0000
828+++ cmds.py 2009-02-12 14:45:56 +0000
829@@ -0,0 +1,788 @@
830+# __init__.py -- The plugin for bzr
831+# Copyright (C) 2005 Jamie Wilkinson <jaq@debian.org>
832+# 2006, 2007 James Westby <jw+debian@jameswestby.net>
833+# 2007 Reinhard Tartler <siretart@tauware.de>
834+# 2008 Canonical Ltd.
835+#
836+# This file is part of bzr-builddeb.
837+#
838+# bzr-builddeb is free software; you can redistribute it and/or modify
839+# it under the terms of the GNU General Public License as published by
840+# the Free Software Foundation; either version 2 of the License, or
841+# (at your option) any later version.
842+#
843+# bzr-builddeb is distributed in the hope that it will be useful,
844+# but WITHOUT ANY WARRANTY; without even the implied warranty of
845+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
846+# GNU General Public License for more details.
847+#
848+# You should have received a copy of the GNU General Public License
849+# along with bzr-builddeb; if not, write to the Free Software
850+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
851+#
852+import os
853+import shutil
854+import subprocess
855+import tempfile
856+import urlparse
857+
858+from debian_bundle.changelog import Version
859+
860+from bzrlib import (
861+ bzrdir,
862+ urlutils,
863+ )
864+from bzrlib.branch import Branch
865+from bzrlib.commands import Command
866+from bzrlib.errors import (BzrCommandError,
867+ NoWorkingTree,
868+ NotBranchError,
869+ FileExists,
870+ )
871+from bzrlib.option import Option
872+from bzrlib.trace import info, warning
873+from bzrlib.transport import get_transport
874+from bzrlib.workingtree import WorkingTree
875+
876+from bzrlib.plugins.builddeb import (
877+ default_build_dir,
878+ default_orig_dir,
879+ default_result_dir,
880+ default_conf,
881+ local_conf,
882+ global_conf,
883+ test_suite,
884+ )
885+from bzrlib.plugins.builddeb.builder import (
886+ DebBuild,
887+ DebMergeBuild,
888+ DebNativeBuild,
889+ DebSplitBuild,
890+ DebMergeExportUpstreamBuild,
891+ DebExportUpstreamBuild,
892+ )
893+from bzrlib.plugins.builddeb.config import DebBuildConfig
894+from bzrlib.plugins.builddeb.errors import (StopBuild,
895+ )
896+from bzrlib.plugins.builddeb.hooks import run_hook
897+from bzrlib.plugins.builddeb.import_dsc import (
898+ DistributionBranch,
899+ DistributionBranchSet,
900+ DscCache,
901+ DscComp,
902+ )
903+from bzrlib.plugins.builddeb.properties import BuildProperties
904+from bzrlib.plugins.builddeb.util import (find_changelog,
905+ lookup_distribution,
906+ suite_to_distribution,
907+ tarball_name,
908+ )
909+
910+dont_purge_opt = Option('dont-purge',
911+ help="Don't purge the build directory after building")
912+result_opt = Option('result-dir',
913+ help="Directory in which to place the resulting package files", type=str)
914+builder_opt = Option('builder',
915+ help="Command to build the package", type=str)
916+merge_opt = Option('merge',
917+ help='Merge the debian part of the source in to the upstream tarball')
918+build_dir_opt = Option('build-dir',
919+ help="The dir to use for building", type=str)
920+orig_dir_opt = Option('orig-dir',
921+ help="Directory containing the .orig.tar.gz files. For use when only"
922+ +"debian/ is versioned", type=str)
923+native_opt = Option('native',
924+ help="Build a native package")
925+split_opt = Option('split',
926+ help="Automatically create an .orig.tar.gz from a full source branch")
927+export_upstream_opt = Option('export-upstream',
928+ help="Create the .orig.tar.gz from a bzr branch before building",
929+ type=unicode)
930+export_upstream_revision_opt = Option('export-upstream-revision',
931+ help="Select the upstream revision that will be exported",
932+ type=str)
933+no_user_conf_opt = Option('no-user-config',
934+ help="Stop builddeb from reading the user's config file. Used mainly "
935+ "for tests")
936+
937+
938+def debuild_config(tree, working_tree, no_user_config):
939+ """Obtain the Debuild configuration object.
940+
941+ :param tree: A Tree object, can be a WorkingTree or RevisionTree.
942+ :param working_tree: Whether the tree is a working tree.
943+ :param no_user_config: Whether to skip the user configuration
944+ """
945+ config_files = []
946+ user_config = None
947+ if (working_tree and
948+ tree.has_filename(local_conf) and tree.path2id(local_conf) is None):
949+ config_files.append((tree.get_file_byname(local_conf), True))
950+ if not no_user_config:
951+ config_files.append((global_conf, True))
952+ user_config = global_conf
953+ if tree.path2id(default_conf):
954+ config_files.append((tree.get_file(tree.path2id(default_conf)), False))
955+ config = DebBuildConfig(config_files)
956+ config.set_user_config(user_config)
957+ return config
958+
959+
960+class cmd_builddeb(Command):
961+ """Builds a Debian package from a branch.
962+
963+ If BRANCH is specified it is assumed that the branch you wish to build is
964+ located there. If it is not specified then the current directory is used.
965+
966+ By default the if a working tree is found it is used to build and otherwise
967+ the last committed revision was used. To force building the last committed
968+ revision use --revision -1. You can specify any other revision using the
969+ --revision option.
970+
971+ If you only wish to export the package, and not build it (especially useful
972+ for merge mode), use --export-only.
973+
974+ To leave the build directory when the build is completed use --dont-purge.
975+
976+ Specify the command to use when building using the --builder option,
977+
978+ You can also specify directories to use for different things. --build-dir
979+ is the directory to build the packages beneath, which defaults to
980+ '../build-area'. '--orig-dir' specifies the directory that contains the
981+ .orig.tar.gz files , which defaults to '..'. '--result-dir' specifies where
982+ the resulting package files should be placed, which defaults to '..'.
983+ --result-dir will have problems if you use a build command that places
984+ the results in a different directory.
985+
986+ The --reuse option will be useful if you are in merge mode, and the upstream
987+ tarball is very large. It attempts to reuse a build directory from an earlier
988+ build. It will fail if one doesn't exist, but you can create one by using
989+ --export-only.
990+
991+ --quick allows you to define a quick-builder in your configuration files,
992+ which will be used when this option is passed. It defaults to 'fakeroot
993+ debian/rules binary'. It is overriden if --builder is passed. Using this
994+ and --reuse allows for fast rebuilds.
995+
996+ --source allows you to build a source package without having to
997+ specify a builder to do so with --builder. It uses the source-builder
998+ option from your configuration files, and defaults to 'dpkg-buildpackage
999+ -rfakeroot -uc -us -S'. It is overriden if either --builder or --quick are
1000+ used.
1001+
1002+ """
1003+ working_tree_opt = Option('working-tree', help="This option has no effect",
1004+ short_name='w')
1005+ export_only_opt = Option('export-only', help="Export only, don't build",
1006+ short_name='e')
1007+ use_existing_opt = Option('use-existing',
1008+ help="Use an existing build directory")
1009+ ignore_changes_opt = Option('ignore-changes',
1010+ help="This option has no effect")
1011+ ignore_unknowns_opt = Option('ignore-unknowns',
1012+ help="Ignore any unknown files, but still fail if there are any changes"
1013+ +", the default is to fail if there are unknowns as well.")
1014+ quick_opt = Option('quick', help="Quickly build the package, uses "
1015+ +"quick-builder, which defaults to \"fakeroot "
1016+ +"debian/rules binary\"")
1017+ reuse_opt = Option('reuse', help="Try to avoid expoting too much on each "
1018+ +"build. Only works in merge mode; it saves unpacking "
1019+ +"the upstream tarball each time. Implies --dont-purge "
1020+ +"and --use-existing")
1021+ source_opt = Option('source', help="Build a source package, uses "
1022+ +"source-builder, which defaults to \"dpkg-buildpackage "
1023+ +"-rfakeroot -uc -us -S\"", short_name='S')
1024+ result_compat_opt = Option('result', help="Present only for compatibility "
1025+ "with bzr-builddeb <= 2.0. Use --result-dir instead.")
1026+ takes_args = ['branch?']
1027+ aliases = ['bd']
1028+ takes_options = [working_tree_opt, export_only_opt,
1029+ dont_purge_opt, use_existing_opt, result_opt, builder_opt, merge_opt,
1030+ build_dir_opt, orig_dir_opt, ignore_changes_opt, ignore_unknowns_opt,
1031+ quick_opt, reuse_opt, native_opt, split_opt, export_upstream_opt,
1032+ export_upstream_revision_opt, source_opt, 'revision',
1033+ no_user_conf_opt, result_compat_opt]
1034+
1035+ def run(self, branch=None, verbose=False, working_tree=False,
1036+ export_only=False, dont_purge=False, use_existing=False,
1037+ result_dir=None, builder=None, merge=False, build_dir=None,
1038+ orig_dir=None, ignore_changes=False, ignore_unknowns=False,
1039+ quick=False, reuse=False, native=False, split=False,
1040+ export_upstream=None, export_upstream_revision=None,
1041+ source=False, revision=None, no_user_config=False, result=None):
1042+
1043+ if branch is None:
1044+ branch = "."
1045+
1046+ # Find out if we were passed a local or remote branch
1047+ is_local = urlparse.urlsplit(branch)[0] in ('', 'file')
1048+ if is_local:
1049+ os.chdir(branch)
1050+
1051+ try:
1052+ tree, _ = WorkingTree.open_containing(branch)
1053+ branch = tree.branch
1054+ except NoWorkingTree:
1055+ tree = None
1056+ branch, _ = Branch.open_containing(branch)
1057+
1058+ if revision is None and tree is not None:
1059+ info("Building using working tree")
1060+ working_tree = True
1061+ else:
1062+ if revision is None:
1063+ revid = branch.last_revision()
1064+ elif len(revision) == 1:
1065+ revid = revision[0].in_history(branch).rev_id
1066+ else:
1067+ raise BzrCommandError('bzr builddeb --revision takes exactly one '
1068+ 'revision specifier.')
1069+ info("Building branch from revision %s", revid)
1070+ tree = branch.repository.revision_tree(revid)
1071+ working_tree = False
1072+
1073+ tree.lock_read()
1074+ try:
1075+ config = debuild_config(tree, working_tree, no_user_config)
1076+
1077+ if reuse:
1078+ info("Reusing existing build dir")
1079+ dont_purge = True
1080+ use_existing = True
1081+
1082+ if not merge:
1083+ merge = config.merge
1084+
1085+ if merge:
1086+ info("Running in merge mode")
1087+ else:
1088+ if not native:
1089+ native = config.native
1090+ if native:
1091+ info("Running in native mode")
1092+ else:
1093+ if not split:
1094+ split = config.split
1095+ if split:
1096+ info("Running in split mode")
1097+
1098+ if builder is None:
1099+ if quick:
1100+ builder = config.quick_builder
1101+ if builder is None:
1102+ builder = "fakeroot debian/rules binary"
1103+ else:
1104+ if source:
1105+ builder = config.source_builder
1106+ if builder is None:
1107+ builder = "dpkg-buildpackage -rfakeroot -uc -us -S"
1108+ else:
1109+ builder = config.builder
1110+ if builder is None:
1111+ builder = "dpkg-buildpackage -uc -us -rfakeroot"
1112+
1113+ (changelog, larstiq) = find_changelog(tree, merge)
1114+
1115+ config.set_version(changelog.version)
1116+
1117+ if export_upstream is None:
1118+ export_upstream = config.export_upstream
1119+
1120+ if export_upstream_revision is None:
1121+ export_upstream_revision = config.export_upstream_revision
1122+
1123+ if result_dir is None:
1124+ result_dir = result
1125+
1126+ if result_dir is None:
1127+ if is_local:
1128+ result_dir = config.result_dir
1129+ else:
1130+ result_dir = config.user_result_dir
1131+ if result_dir is not None:
1132+ result_dir = os.path.realpath(result_dir)
1133+
1134+ if build_dir is None:
1135+ if is_local:
1136+ build_dir = config.build_dir or default_build_dir
1137+ else:
1138+ build_dir = config.user_build_dir or 'build-area'
1139+
1140+ if orig_dir is None:
1141+ if is_local:
1142+ orig_dir = config.orig_dir or default_orig_dir
1143+ else:
1144+ orig_dir = config.user_orig_dir or 'build-area'
1145+
1146+ properties = BuildProperties(changelog, build_dir, orig_dir, larstiq)
1147+
1148+ if merge:
1149+ if export_upstream is None:
1150+ build = DebMergeBuild(properties, tree, _is_working_tree=working_tree)
1151+ else:
1152+ prepull_upstream = config.prepull_upstream
1153+ stop_on_no_change = config.prepull_upstream_stop
1154+ build = DebMergeExportUpstreamBuild(properties, tree, export_upstream,
1155+ export_upstream_revision,
1156+ prepull_upstream,
1157+ stop_on_no_change,
1158+ _is_working_tree=working_tree)
1159+ elif native:
1160+ build = DebNativeBuild(properties, tree, _is_working_tree=working_tree)
1161+ elif split:
1162+ build = DebSplitBuild(properties, tree, _is_working_tree=working_tree)
1163+ else:
1164+ if export_upstream is None:
1165+ build = DebBuild(properties, tree, _is_working_tree=working_tree)
1166+ else:
1167+ prepull_upstream = config.prepull_upstream
1168+ stop_on_no_change = config.prepull_upstream_stop
1169+ build = DebExportUpstreamBuild(properties, tree, export_upstream,
1170+ export_upstream_revision,
1171+ prepull_upstream,
1172+ stop_on_no_change,
1173+ _is_working_tree=working_tree)
1174+
1175+ build.prepare(use_existing)
1176+
1177+ run_hook(tree, 'pre-export', config)
1178+
1179+ try:
1180+ build.export(use_existing)
1181+ except StopBuild, e:
1182+ warning('Stopping the build: %s.', e.reason)
1183+ return
1184+
1185+ if not export_only:
1186+ run_hook(tree, 'pre-build', config, wd=properties.source_dir())
1187+ build.build(builder)
1188+ run_hook(tree, 'post-build', config, wd=properties.source_dir())
1189+ if not dont_purge:
1190+ build.clean()
1191+ arch = None
1192+ if source:
1193+ arch = "source"
1194+ if result_dir is not None:
1195+ build.move_result(result_dir, arch=arch)
1196+ else:
1197+ build.move_result(default_result_dir, allow_missing=True, arch=arch)
1198+ finally:
1199+ tree.unlock()
1200+
1201+
1202+
1203+
1204+class cmd_merge_upstream(Command):
1205+ """Merges a new upstream version into the current branch.
1206+
1207+ Takes a new upstream version and merges it in to your branch, so that your
1208+ packaging changes are applied to the new version.
1209+
1210+ You must supply the source to import from, and the version number of the
1211+ new release. The source can be a .tar.gz, .tar, .tar.bz2, .tgz or .zip
1212+ archive, or a directory. The source may also be a remote file.
1213+
1214+ You must supply the version number of the new upstream release
1215+ using --version, and the target distribution using --distribution.
1216+ The target distribtution is the distribution that you aim to upload to,
1217+ one of "debian" or "ubuntu". You can also specify the target used in
1218+ the changelog, e.g. "unstable", and it will be resolved automatically.
1219+
1220+ If there is no debian changelog in the branch to retrieve the package
1221+ name from then you must pass the --package option. If this version
1222+ will change the name of the source package then you can use this option
1223+ to set the new name.
1224+ """
1225+ takes_args = ['location?']
1226+ aliases = ['mu']
1227+
1228+ package_opt = Option('package', help="The name of the source package.",
1229+ type=str)
1230+ version_opt = Option('version', help="The version number of this release.",
1231+ type=str)
1232+ distribution_opt = Option('distribution', help="The distribution that "
1233+ "this release is targetted at", type=str)
1234+ directory_opt = Option('directory', help='Working tree into which to merge.',
1235+ short_name='d', type=unicode)
1236+
1237+ takes_options = [package_opt, no_user_conf_opt, version_opt,
1238+ distribution_opt, directory_opt, 'revision']
1239+
1240+ def run(self, location=None, version=None, distribution=None, package=None,
1241+ no_user_config=None, directory=".", revision=None):
1242+ from bzrlib.plugins.builddeb.errors import MissingChangelogError
1243+ from bzrlib.plugins.builddeb.repack_tarball import repack_tarball
1244+ from bzrlib.plugins.builddeb.merge_upstream import merge_upstream_branch
1245+ tree, _ = WorkingTree.open_containing(directory)
1246+ tree.lock_write()
1247+ try:
1248+ # Check for uncommitted changes.
1249+ if tree.changes_from(tree.basis_tree()).has_changed():
1250+ raise BzrCommandError("There are uncommitted changes in the "
1251+ "working tree. You must commit before using this "
1252+ "command.")
1253+ config = debuild_config(tree, tree, no_user_config)
1254+ if config.merge:
1255+ raise BzrCommandError("Merge upstream in merge mode is not "
1256+ "yet supported.")
1257+ if config.native:
1258+ raise BzrCommandError("Merge upstream in native mode is not "
1259+ "yet supported.")
1260+ if config.export_upstream and location is None:
1261+ location = config.export_upstream
1262+ if config.split:
1263+ raise BzrCommandError("Split mode is not yet supported.")
1264+
1265+ if location is None:
1266+ raise BzrCommandError("No location specified to merge")
1267+ try:
1268+ changelog = find_changelog(tree, False)[0]
1269+ current_version = changelog.version
1270+ if package is None:
1271+ package = changelog.package
1272+ except MissingChangelogError:
1273+ current_version = None
1274+
1275+ if package is None:
1276+ raise BzrCommandError("You did not specify --package, and "
1277+ "there is no changelog from which to determine the "
1278+ "package name, which is needed to know the name to "
1279+ "give the .orig.tar.gz. Please specify --package.")
1280+
1281+ try:
1282+ upstream_branch = Branch.open(location)
1283+ except NotBranchError:
1284+ upstream_branch = None
1285+
1286+ if upstream_branch is None:
1287+ if version is None:
1288+ raise BzrCommandError("You must specify the version number using "
1289+ "--version.")
1290+ version = Version(version)
1291+ if distribution is None:
1292+ raise BzrCommandError("You must specify the target distribution "
1293+ "using --distribution.")
1294+ if revision is not None:
1295+ raise BzrCommandError("--revision is not allowed when merging a tarball")
1296+
1297+ orig_dir = config.orig_dir or default_orig_dir
1298+ orig_dir = os.path.join(tree.basedir, orig_dir)
1299+ dest_name = tarball_name(package, version.upstream_version)
1300+ try:
1301+ repack_tarball(location, dest_name, target_dir=orig_dir)
1302+ except FileExists:
1303+ raise BzrCommandError("The target file %s already exists, and is either "
1304+ "different to the new upstream tarball, or they "
1305+ "are of different formats. Either delete the target "
1306+ "file, or use it as the argument to import.")
1307+ tarball_filename = os.path.join(orig_dir, dest_name)
1308+ distribution = distribution.lower()
1309+ distribution_name = lookup_distribution(distribution)
1310+ if distribution_name is None:
1311+ raise BzrCommandError("Unknown target distribution: %s" \
1312+ % distribution)
1313+ db = DistributionBranch(distribution_name, tree.branch, None,
1314+ tree=tree)
1315+ dbs = DistributionBranchSet()
1316+ dbs.add_branch(db)
1317+ conflicts = db.merge_upstream(tarball_filename, version,
1318+ current_version)
1319+ else:
1320+ if revision is not None:
1321+ if len(revision) > 1:
1322+ raise BzrCommandError("merge-upstream takes only a single --revision")
1323+ upstream_revspec = revision[0]
1324+ else:
1325+ upstream_revspec = None
1326+ version = merge_upstream_branch(tree, upstream_branch, package,
1327+ upstream_revspec, version)
1328+ info("Using version string %s for upstream branch." % (version))
1329+ finally:
1330+ tree.unlock()
1331+
1332+ if "~bzr" in str(version) or "+bzr" in str(version):
1333+ entry_description = "New upstream snapshot."
1334+ else:
1335+ entry_description = "New upstream release."
1336+
1337+ info("The new upstream version has been imported. You should "
1338+ "now update the changelog (try dch -v %s-1 \"%s\"), resolve any "
1339+ "conflicts, and then commit." % (str(version), entry_description))
1340+
1341+
1342+
1343+
1344+class cmd_import_dsc(Command):
1345+ """Import a series of source packages.
1346+
1347+ Provide a number of source packages (.dsc files), and they will
1348+ be imported to create a branch with history that reflects those
1349+ packages.
1350+
1351+ The first argument is the distribution that these source packages
1352+ were uploaded to, one of "debian" or "ubuntu". It can also
1353+ be the target distribution from the changelog, e.g. "unstable",
1354+ which will be resolved to the correct distribution.
1355+
1356+ You can also specify a file (possibly remote) that contains a
1357+ list of source packages (.dsc files) to import using the --file
1358+ option. Each line is taken to be a URI or path to import. The
1359+ sources specified in the file are used in addition to those
1360+ specified on the command line.
1361+
1362+ If you have an existing branch containing packaging and you want to
1363+ import a .dsc from an upload done from outside the version control
1364+ system you can use this command.
1365+ """
1366+
1367+ takes_args = ['files*']
1368+
1369+ filename_opt = Option('file', help="File containing URIs of source "
1370+ "packages to import.", type=str, argname="filename",
1371+ short_name='F')
1372+ distribution_opt = Option('distribution', help="The distribution that "
1373+ "these packages were uploaded to.", type=str)
1374+
1375+ takes_options = [filename_opt, distribution_opt]
1376+
1377+ def import_many(self, db, files_list, orig_target):
1378+ cache = DscCache()
1379+ files_list.sort(cmp=DscComp(cache).cmp)
1380+ if not os.path.exists(orig_target):
1381+ os.makedirs(orig_target)
1382+ for dscname in files_list:
1383+ dsc = cache.get_dsc(dscname)
1384+ def get_dsc_part(from_transport, filename):
1385+ from_f = from_transport.get(filename)
1386+ contents = from_f.read()
1387+ to_f = open(os.path.join(orig_target, filename), 'wb')
1388+ try:
1389+ to_f.write(contents)
1390+ finally:
1391+ to_f.close()
1392+ base, filename = urlutils.split(dscname)
1393+ from_transport = cache.get_transport(dscname)
1394+ get_dsc_part(from_transport, filename)
1395+ for file_details in dsc['files']:
1396+ name = file_details['name']
1397+ get_dsc_part(from_transport, name)
1398+ db.import_package(os.path.join(orig_target, filename))
1399+
1400+ def run(self, files_list, distribution=None, filename=None):
1401+ from bzrlib.plugins.builddeb.errors import MissingChangelogError
1402+ if distribution is None:
1403+ raise BzrCommandError("You must specify the distribution "
1404+ "these packages were uploaded to using --distribution.")
1405+ distribution = distribution.lower()
1406+ distribution_name = lookup_distribution(distribution)
1407+ if distribution_name is None:
1408+ raise BzrCommandError("Unknown target distribution: %s" \
1409+ % distribution)
1410+ try:
1411+ tree = WorkingTree.open_containing('.')[0]
1412+ except NotBranchError:
1413+ raise BzrCommandError("There is no tree to import the packages in to")
1414+ tree.lock_write()
1415+ try:
1416+ if tree.changes_from(tree.basis_tree()).has_changed():
1417+ raise BzrCommandError("There are uncommitted changes in the "
1418+ "working tree. You must commit before using this "
1419+ "command")
1420+ if files_list is None:
1421+ files_list = []
1422+ if filename is not None:
1423+ if isinstance(filename, unicode):
1424+ filename = filename.encode('utf-8')
1425+ base_dir, path = urlutils.split(filename)
1426+ sources_file = get_transport(base_dir).get(path)
1427+ for line in sources_file:
1428+ line.strip()
1429+ files_list.append(line)
1430+ if len(files_list) < 1:
1431+ raise BzrCommandError("You must give the location of at least one "
1432+ "source package to install, or use the "
1433+ "--file option.")
1434+ config = debuild_config(tree, tree, False)
1435+ orig_dir = config.orig_dir or default_orig_dir
1436+ orig_target = os.path.join(tree.basedir, default_orig_dir)
1437+ db = DistributionBranch(distribution_name, tree.branch,
1438+ None, tree=tree)
1439+ dbs = DistributionBranchSet()
1440+ dbs.add_branch(db)
1441+ try:
1442+ (changelog, larstiq) = find_changelog(tree, False)
1443+ last_version = changelog.version
1444+ except MissingChangelogError:
1445+ last_version = None
1446+ tempdir = tempfile.mkdtemp(dir=os.path.join(tree.basedir,
1447+ '..'))
1448+ try:
1449+ if last_version is not None:
1450+ upstream_tip = db._revid_of_upstream_version_from_branch(
1451+ last_version)
1452+ db._extract_upstream_tree(upstream_tip, tempdir)
1453+ else:
1454+ db._create_empty_upstream_tree(tempdir)
1455+ self.import_many(db, files_list, orig_target)
1456+ finally:
1457+ shutil.rmtree(tempdir)
1458+ finally:
1459+ tree.unlock()
1460+
1461+
1462+
1463+class cmd_bd_do(Command):
1464+ """Run a command in an exported package, copying the result back.
1465+
1466+ For a merge mode package the full source is not available, making some
1467+ operations difficult. This command allows you to run any command in an
1468+ exported source directory, copying the resulting debian/ directory back
1469+ to your branch if the command is successful.
1470+
1471+ For instance:
1472+
1473+ bzr bd-do
1474+
1475+ will run a shell in the unpacked source. Any changes you make in the
1476+ ``debian/`` directory (and only those made in that directory) will be copied
1477+ back to the branch. If you exit with a non-zero exit code (e.g. "exit 1"),
1478+ then the changes will not be copied back.
1479+
1480+ You can also specify single commands to be run, e.g.
1481+
1482+ bzr bd-do "dpatch-edit-patch 01-fix-build"
1483+
1484+ Note that only the first argument is used as the command, and so the above
1485+ example had to be quoted.
1486+ """
1487+
1488+ takes_args = ['command?']
1489+
1490+ def run(self, command=None):
1491+ t = WorkingTree.open_containing('.')[0]
1492+ config = debuild_config(t, t, False)
1493+
1494+ if not config.merge:
1495+ raise BzrCommandError("This command only works for merge mode "
1496+ "packages. See /usr/share/doc/bzr-builddeb"
1497+ "/user_manual/merge.html for more information.")
1498+
1499+ give_instruction = False
1500+ if command is None:
1501+ try:
1502+ command = os.environ['SHELL']
1503+ except KeyError:
1504+ command = "/bin/sh"
1505+ give_instruction = True
1506+ (changelog, larstiq) = find_changelog(t, True)
1507+ build_dir = config.build_dir
1508+ if build_dir is None:
1509+ build_dir = default_build_dir
1510+ orig_dir = config.orig_dir
1511+ if orig_dir is None:
1512+ orig_dir = default_orig_dir
1513+ properties = BuildProperties(changelog, build_dir, orig_dir, larstiq)
1514+ export_upstream = config.export_upstream
1515+ export_upstream_revision = config.export_upstream_revision
1516+
1517+ if export_upstream is None:
1518+ build = DebMergeBuild(properties, t, _is_working_tree=True)
1519+ else:
1520+ prepull_upstream = config.prepull_upstream
1521+ stop_on_no_change = config.prepull_upstream_stop
1522+ build = DebMergeExportUpstreamBuild(properties, t, export_upstream,
1523+ export_upstream_revision,
1524+ prepull_upstream,
1525+ stop_on_no_change,
1526+ _is_working_tree=True)
1527+
1528+ build.prepare()
1529+ try:
1530+ build.export()
1531+ except StopBuild, e:
1532+ warning('Stopping the build: %s.', e.reason)
1533+ info('Running "%s" in the exported directory.' % (command))
1534+ if give_instruction:
1535+ info('If you want to cancel your changes then exit with a non-zero '
1536+ 'exit code, e.g. run "exit 1".')
1537+ proc = subprocess.Popen(command, shell=True,
1538+ cwd=properties.source_dir())
1539+ proc.wait()
1540+ if proc.returncode != 0:
1541+ raise BzrCommandError('Not updating the working tree as the command '
1542+ 'failed.')
1543+ info("Copying debian/ back")
1544+ if larstiq:
1545+ destination = '.'
1546+ else:
1547+ destination = 'debian/'
1548+ source_debian = os.path.join(properties.source_dir(), 'debian')
1549+ for filename in os.listdir(source_debian):
1550+ proc = subprocess.Popen('cp -apf "%s" "%s"' % (
1551+ os.path.join(source_debian, filename), destination),
1552+ shell=True)
1553+ proc.wait()
1554+ if proc.returncode != 0:
1555+ raise BzrCommandError('Copying back debian/ failed')
1556+ build.clean()
1557+ info('If any files were added or removed you should run "bzr add" or '
1558+ '"bzr rm" as appropriate.')
1559+
1560+
1561+
1562+
1563+class cmd_mark_uploaded(Command):
1564+ """Mark that this branch has been uploaded, prior to pushing it.
1565+
1566+ When a package has been uploaded we want to mark the revision
1567+ that it was uploaded in. This command automates doing that
1568+ by marking the current tip revision with the version indicated
1569+ in debian/changelog.
1570+ """
1571+ force = Option('force', help="Mark the upload even if it is already "
1572+ "marked.")
1573+
1574+ takes_options = [merge_opt, no_user_conf_opt, force]
1575+
1576+ def run(self, merge=False, no_user_config=False, force=None):
1577+ t = WorkingTree.open_containing('.')[0]
1578+ t.lock_write()
1579+ try:
1580+ if t.changes_from(t.basis_tree()).has_changed():
1581+ raise BzrCommandError("There are uncommitted changes in the "
1582+ "working tree. You must commit before using this "
1583+ "command")
1584+ config = debuild_config(t, t, no_user_config)
1585+ if not merge:
1586+ merge = config.merge
1587+ (changelog, larstiq) = find_changelog(t, merge)
1588+ distributions = changelog.distributions.strip()
1589+ target_dist = distributions.split()[0]
1590+ distribution_name = suite_to_distribution(target_dist)
1591+ if distribution_name is None:
1592+ raise BzrCommandError("Unknown target distribution: %s" \
1593+ % target_dist)
1594+ db = DistributionBranch(distribution_name, t.branch, None)
1595+ dbs = DistributionBranchSet()
1596+ dbs.add_branch(db)
1597+ if db.has_version(changelog.version):
1598+ if not force:
1599+ raise BzrCommandError("This version has already been "
1600+ "marked uploaded. Use --force to force marking "
1601+ "this new version.")
1602+ db.tag_version(changelog.version)
1603+ finally:
1604+ t.unlock()
1605+
1606+
1607+class cmd_test_builddeb(Command):
1608+ """Run the builddeb test suite"""
1609+
1610+ hidden = True
1611+
1612+ def run(self):
1613+ from bzrlib.tests import selftest
1614+ passed = selftest(test_suite_factory=test_suite)
1615+ # invert for shell exit code rules
1616+ return not passed
1617+
1618
1619=== modified file 'revspec.py'
1620--- revspec.py 2008-11-27 15:30:30 +0000
1621+++ revspec.py 2009-01-29 23:47:05 +0000
1622@@ -19,7 +19,7 @@
1623 #
1624
1625 from bzrlib.errors import NoSuchTag
1626-from bzrlib.revisionspec import RevisionSpec, RevisionInfo, SPEC_TYPES
1627+from bzrlib.revisionspec import RevisionSpec, RevisionInfo
1628
1629 from bzrlib.plugins.builddeb.errors import (
1630 AmbiguousPackageSpecification,
1631@@ -84,5 +84,4 @@
1632 return RevisionInfo.from_revision_id(branch,
1633 revision_id, revs)
1634
1635-SPEC_TYPES.append(RevisionSpec_package)
1636
1637
1638=== modified file 'tests/__init__.py'
1639--- tests/__init__.py 2008-09-03 12:07:07 +0000
1640+++ tests/__init__.py 2009-02-12 14:45:56 +0000
1641@@ -134,7 +134,7 @@
1642 'config'
1643 ]
1644 for mod in doctest_mod_names:
1645- suite.addTest(doctest.DocTestSuite(mod))
1646+ suite.addTest(doctest.DocTestSuite("bzrlib.plugins.builddeb." + mod))
1647
1648 adapt_modules(['%s.test_repack_tarball' % __name__],
1649 RepackTarballAdaptor(), loader, suite)
1650
1651=== modified file 'tests/test_repack_tarball_extra.py'
1652--- tests/test_repack_tarball_extra.py 2008-12-02 16:25:25 +0000
1653+++ tests/test_repack_tarball_extra.py 2009-02-12 14:45:56 +0000
1654@@ -22,7 +22,7 @@
1655 import shutil
1656 import tarfile
1657
1658-from repack_tarball import repack_tarball
1659+from bzrlib.plugins.builddeb.repack_tarball import repack_tarball
1660
1661 from bzrlib.errors import BzrCommandError, FileExists
1662 from bzrlib.tests import TestCaseInTempDir

Subscribers

People subscribed via source and target branches