larger chunks
[rersyncrecent.git] / bin / rrr-news
bloba49723cf466ebafb36b18283ebec5f98416e3750
1 #!/usr/bin/perl -- -*- mode: cperl -*-
3 =head1 NAME
5 rrr-news - list files added to the dataset
7 =head1 SYNOPSIS
9 rrr-news [options]
11 =head1 OPTIONS
13 =over 8
15 =cut
17 my @opt = <<'=back' =~ /B<--(\S+)>/g;
19 =item B<--after=s>
21 List all new files after this point in time. The format of the
22 timestamp is the unix epoch in floating point notation as used by
23 recentfiles in general.
25 =item B<--before=s>
27 List all new files before this point in time. The format of the
28 timestamp is the unix epoch in floating point notation as used by
29 recentfiles in general.
31 =item B<--contains_path=s>
33 List this file if it is in the collection
35 =item B<--dry-run!>
37 (TBD) Do not really run the command, ...
39 =item B<--help|h>
41 Prints a brief message and exists.
43 =item B<--local=s>
45 Specifies a local principal file. Nothing is mirrored, the list is
46 constructed from local resources. Cannot be combined with the
47 C<--remote> option.
49 =item B<--localroot=s>
51 Specifies the local root directory. C<--remote> must also be specified
52 and mirroring is happening implicitly. If missing, a temporary
53 directory is created to hold the data before constructing the list
54 (but this is inefficient in case the program is called again later
55 because the temporary directory is not persistent).
57 =item B<--max=i>
59 Limit the list to at max this many items.
61 =item B<--remote=s>
63 Specifies the remote principal file in rsync notation. This implies
64 that the necessary remote files will be mirrored before constructing
65 the list.
67 =item B<--rsync_options|rsync=s@>
69 Multiple options in the form of key=value pairs. E.g.
71 --rsync=compress=1 --rsync=links=1
73 The options are passed to the underlying L<File::Rsync> objects.
75 =item B<--skip-deletes!>
77 Boolean. If true then delete events are skipped.
79 =item B<--verbose|v+>
81 More feedback.
83 =back
85 =head1 DESCRIPTION
87 rersyncrecent is a project to get speedy rsync operation on large
88 trees over multiple hosts. It maintains a collection of files with
89 metadata (so called recentfiles) that represent adjacent overlapping
90 timespans of file change events.
92 rrr-news extracts from the recentfiles the new files added or
93 modified. The remote-principal-file is the rsync-notation for the
94 remote recentfile. The second argument is the path to the local mirror
95 directory. If you omit the second argument, a temporary directory is
96 taken instead.
98 =cut
101 use strict;
102 use warnings;
104 use File::Rsync::Mirror::Recent;
105 use Getopt::Long;
106 use Pod::Usage qw(pod2usage);
108 our %Opt;
109 GetOptions(\%Opt,
110 @opt,
111 ) or pod2usage(2);
113 if ($Opt{help}) {
114 pod2usage(0);
117 if (@ARGV) {
118 pod2usage(2);
121 if ($Opt{'dry-run'}) {
122 die "FIXME: not yet implemented";
125 my @constr;
126 for my $opt (qw(local remote localroot)) {
127 if (defined $Opt{$opt}) {
128 push @constr, $opt => $Opt{$opt};
131 my $rf = File::Rsync::Mirror::Recent->new
133 @constr,
134 # stupid, need no rsync options when running with -local!
135 rsync_options => {
136 compress => 1,
137 links => 1,
138 times => 1,
139 checksum => 1,
142 if ($rf->remote) {
143 unless ($rf->localroot) {
144 require File::Temp;
145 my $ldir = File::Temp::tempdir(
146 "rrr-news-XXXXXX",
147 TMPDIR => 1,
149 $rf->localroot($ldir);
151 } elsif ($rf->local) {
152 } else {
153 die "need either --local option or both of --remote and --localroot";
155 for my $passthrough (
156 "locktimeout",
157 "verbose",
159 if (my $x = $Opt{$passthrough}) {
160 $rf->$passthrough($x);
164 my %rsopt;
165 for my $rsopt (@{$Opt{rsync_options}||[]}) {
166 my($key,$value) = $rsopt =~ /([^=]+)=(.+)/s;
167 $rsopt{$key} = $value;
169 $rf->rsync_options(\%rsopt);
171 my @nopt;
172 for my $opt (qw(after before max skip-deletes)) {
173 if (defined $Opt{$opt}) {
174 push @nopt, $opt => $Opt{$opt}
177 my $contains;
178 for my $opt (qw(contains_path)) {
179 if (defined $Opt{$opt}) {
180 my($short) = $opt =~ /^contains_(.+)/;
181 $contains->{$short} = $Opt{$opt};
184 if ($contains) {
185 push @nopt, max => 1, contains => $contains;
187 print map { sprintf "%-20s %s\n", scalar localtime($_->{epoch}), substr($_->{path},8) } @{ $rf->news(@nopt) };
189 __END__
192 # Local Variables:
193 # mode: cperl
194 # coding: utf-8
195 # cperl-indent-level: 4
196 # End: