[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: [sourcev3] Mapping between Format and Dpkg::Source::Package object

On Fri, Feb 29, 2008 at 06:23:03PM +0100, Raphael Hertzog wrote:
> The logic of the mapping is quite simple, explanation by example:
> Format: 1.0       => Dpkg::Source::Package::V1_0
> Format: 3.0 (git) => Dpkg::Source::Package::V3_0::git

> Ideally I'd like each object to implement a single logic of
> extraction/build of the source package. However "Format: 1.0" contains
> two logics: native (single tar) and non-native (orig.tar + diff)
> and it's restrained to gzip compression for everything.

Sounds like you shouldn't be naming them after the version number then.

Having Dpkg::Source::Package include `native', `origdiff', `wignpen',
`git', `bzr', would seem more sensible; then you'd just need to delegate
to them directly.

Personally, I'd be inclined to go with something asking each known format
if they can extract the package, with something like:

package Dpkg::Source::Package::wignpen;
sub can_extract {
	my $dsc = shift;
	my $src = $dsc->{"Source"};
	my $ver = $dsc->{"Version"};
	my $up;

	my $formats = "tar\.bz2|tar\.gz|zip";

	$up = $ver;
	$up = s/-[^-]*$//;
	return 0 if (format_at_least($dsc->{"Format"}, 2, 0));

	# Valid file formats for foo 1.0-2 are:
	#   foo_1.0.orig.tar.gz
	#   foo_1.0.orig-blah.tar.gz
	#   foo_1.0-2.debian.tar.gz

	my $foundfile = 0;
	foreach my $f ($dsc->{"Files"}) {
		$f =~ s/^.* //;
		$foundfile = 1;
		next if ($f !~ m/^\Q$src\E_\Q$up\E\.orig\.($format)$/);
		   if ($f !~ m/^\Q$src\E_\Q$up\E\.orig-[a-z0-9]+\.($format)$/);
		next if ($f !~ m/^\Q$src\E_\Q$ver\E\.debian\.($format)$/);

		return 0;  # invalid filename

	return $foundfile;

Putting the logic in the format like that, rather than in the dispatcher
means you can have your "origdiff" unpacker have the logic:

	if Format == 1.0
		extensions = ("tar.gz", "gz")
	else if Format == 3.0
		extensions = ("tar.gz|tar.bz2|zip", "gz|bz2")

and then use a single bit of code to decode 1.0 .orig.tar.gz+diff.gz
packages and 3.0 .zip+.diff.bz2 packages, eg.

> Then by default the stack of formats to try would contain (DSP::V1_0,
> DSP::V1_0::native) and the user could push other format on top of the
> stack (dpkg-source --format "3.0 (git)" ...). The can_build() method of
> V3_0::git would check for example if there's a .git in the directory.

AFAICS, there are only two questions for a source format to answer:
can_extract and can_create; with native always able to create (since
it just involves tarring everything up), origdiff only being able to
if there's an orig.tgz in ../, git only being able to if there's a
./.git, etc.

> I'd be satisfied with that but I'm wondering if we have to handle
> native packages in Format: 2.0 too ... 

Hrm, I can't find any indication what the minor part of the Format: is
meant to mean, even historically. I thought I remembered it being pretty
pointless -- ie, if you can unpack X.y, you can unpack X.z for all y,
z; which means there's not actually any value to having it in the .dsc
at all.

Note that there's a conflict between native & wignpen formats, in that:


could be foo version 1.0 with all its source in a "debian" directory,
or foo version 1.0.orig-debian in native format. That is, if that was
the only thing present in Files:, both could reasonably think they
could extract it, but if they did so, they'd end up with different
results. Looking at either the Format: field (2.0 for wignpen, 1.0 or
3.0 for native), or the Version: field could disambiguate it though.


Attachment: signature.asc
Description: Digital signature

Reply to: