Arch

 view release on metacpan or  search on metacpan

perllib/Arch/Changeset.pm  view on Meta::CPAN


	if (!-f $patch_file) {
		my $patch_content = "*** Currently unsupported patch type, possibly metadata or symlink change ***";
		if ($type >= 2) {
			if (-l $patch_file) {
				$patch_content = readlink($patch_file);
			} else {
				die "No file $filepath patch in revision $self->{revision} changeset\n";
			}
		} else {
			$patch_file = "/dev/null";
			$change_type = "unsupported";
		}
		return wantarray? ($patch_content, $patch_file, $change_type, 1): $patch_content;
	}
	my $patch_content = load_file($patch_file);

	# create fake patch from full file if needed
	my $asis = 0;
	if ($change_type ne "" && !($asis = $full_file_asis || -B $patch_file)) {
		my $has_end_line = $patch_content =~ /\n$/;
		my $num_lines = $patch_content =~ s/\n/\n/g;
		$num_lines += $has_end_line? 0: 1;
		my $file = $patch_file;
		$file =~ s!^\Q$dir\E/[^/]+/!!s;
		my ($file1, $file2, $line1, $line2, $prefix);
		if ($change_type eq "new") {
			$file1 = "/dev/null";
			$file2 = $file;
			$line1 = "-0,0";
			$line2 = "+1,$num_lines";
			$prefix = "+";
		} else {
			$file1 = $file;
			$file2 = "/dev/null";
			$line1 = "-1,$num_lines";
			$line2 = "+0,0";
			$prefix = "-";
		}
		chop $patch_content if $has_end_line;
		$patch_content =~ s/(^|\012)/$1$prefix/g;
		$patch_content .= "\n\\ No newline at end of file" unless $has_end_line;
		$patch_content = "--- $file1\n+++ $file2\n@@ $line1 $line2 @@\n$patch_content\n";
		$change_type = "";
	}

	$change_type ||= "patch";
	return wantarray? ($patch_content, $patch_file, $change_type, $asis): $patch_content;
}

sub ancestor ($) {
	my $self = shift;
	my $ancestor = $self->{ancestor};
	return $ancestor if $ancestor;

	if (-f "$self->{dir}/=ancestor") {
		$ancestor = load_file("$self->{dir}/=ancestor");
		chomp($ancestor);
	}
	unless ($ancestor) {
		# just guess
		my $revision = $self->{revision};
		$ancestor = adjacent_revision($revision, -1) || $revision;
	}
	return $self->{ancestor} = $ancestor;
}

sub get_index ($$) {
	my $self  = shift;
	my $index = shift;

	return %{$self->{index_memo}->{$index}}
		if (exists $self->{index_memo}->{$index});

	my $index_hash = {};

	# TODO: add proper unescaping support
	foreach my $line (split /\n/, load_file($self->{dir} . '/' . $index)) {
		my ($path, $id) = split / /, $line, 2;

		$path =~ s,^\./,,;
		$index_hash->{$id} = $path;
	}

	$self->{index_memo}->{$index} = $index_hash;
	return %$index_hash;
}

sub get_changes ($) {
	my $self = shift;

	my %orig_dirs  = $self->get_index('orig-dirs-index');
	my %mod_dirs   = $self->get_index('mod-dirs-index');

	my %orig_files = $self->get_index('orig-files-index');
	my %mod_files  = $self->get_index('mod-files-index');

	my $changes = Arch::Changes->new;

	# added dirs
	foreach my $id (keys %mod_dirs) {
		$changes->add(ADD, 1, $mod_dirs{$id})
			unless (exists $orig_dirs{$id});
	}

	# added files
	foreach my $id (keys %mod_files) {
		$changes->add(ADD, 0, $mod_files{$id})
			unless (exists $orig_files{$id});
	}

	# deleted dirs
	foreach my $id (keys %orig_dirs) {
		$changes->add(DELETE, 1, $orig_dirs{$id})
			unless (exists $mod_dirs{$id});
	}

	# deleted files
	foreach my $id (keys %orig_files) {
		$changes->add(DELETE, 0, $orig_files{$id})
			unless (exists $mod_files{$id});

perllib/Arch/Changeset.pm  view on Meta::CPAN

B<ancestor>.

=over 4

=item B<new> I<revision-spec> I<dir-name>

Construct the Arch::Changeset object associated with the given
fully-qualified I<revision-spec> and the existing directory I<dir-name>.

=item B<get_patch> I<file-path>

=item B<get_patch> I<file-path> I<type>

=item B<get_patch> I<file-path> I<type> I<full-file-asis>

Return the patch (or otherwise content) of the given I<file-path> in the
changeset.

I<type> is integer: 0 (unknown, try to autodetect, this is the default),
1 (modified file, or metadata change), 2 (new file), 3 (removed file).

The default behaviour is to create a fake diff against I</dev/null> for
non-binary new and removed files; the I<full-file-asis> flag, if set to
true, changes this behaviour and causes to return the content of such file
as-is. Binary new and removed files are always returned as-is regardless
of the flag. This flag is also ignored if I<type> is 1.

In the scalar content return the patch in diff(1) format (or the whole file
content as described above). In the list content return 4 scalars: the
patch, the file name on the disk containing this patch (or the whole file),
the change type (that is "patch", "new" or "removed") and the as-is flag.

The returned values that follow the first one (the patch/file content)
share the order of the corresponding parameters; the parameters are
more hints, while the returned values accurately describe the content.

=item B<get_index> I<name>

Returns the content of the index file I<name> as an B<ID> => B<path> hash.

Valid I<name>s are 'orig-dirs-index', 'orig-files-index', 'mod-dirs-index' and
'mod-files-index'.

=item B<get_changes>

Returns a list of changes in the changeset.

=item B<get_all_diffs>

Returns all diffs in the changeset (array or arrayref). This includes
changes of types I<MODIFY>, I<ADD> and I<DELETE>.

=item B<join_all_diffs>

Returns concatenated output of all diffs in the changeset.

=item B<ancestor>

Return the ancestor of the changeset. If I<=ancestor> file is found (that is
the case for library changesets) its content is returned, otherwise try to
guess the ancestor of the revision using B<Arch::Util::adjacent_revision>.

=back

=head1 BUGS

Awaiting for your reports.

=head1 AUTHORS

Mikhael Goikhman (migo@homemail.com--Perl-GPL/arch-perl--devel).

=head1 SEE ALSO

For more information, see L<tla>, L<Arch::Session>, L<Arch::Library>,
L<Arch::Util>.

=cut



( run in 1.166 second using v1.01-cache-2.11-cpan-5c0b1e786e0 )