enable cpansign to work on a relocated perl
[rersyncrecent.git] / bin / rrr-news
blob262773942de5ba2e0026039b339e754de7f3a343
1 #!/usr/bin/perl
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_epoch=s>
33 List this file if the epoch is in the collection. Implies --max=1. Can
34 be combined with the other contains_* options to form a logical AND.
36 =item B<--contains_path=s>
38 List this file if the path is in the collection. Implies --max=1. Can
39 be combined with the other contains_* options to form a logical AND.
41 =item B<--contains_type=s>
43 List this file if the type is in the collection. Implies --max=1. Can
44 be combined with the other contains_* options to form a logical AND.
46 =item B<--dry-run!>
48 (TBD) Do not really run the command, ...
50 =item B<--help|h>
52 Prints a brief message and exists.
54 =item B<--local=s>
56 Specifies a local principal file. Nothing is mirrored, the list is
57 constructed from local resources. Cannot be combined with the
58 C<--remote> option.
60 =item B<--localroot=s>
62 Specifies the local root directory. C<--remote> must also be specified
63 and mirroring is happening implicitly. If missing, a temporary
64 directory is created to hold the data before constructing the list
65 (but this is inefficient in case the program is called again later
66 because the temporary directory is not persistent).
68 =item B<--max=i>
70 Limit the list to at max this many items.
72 =item B<--remote=s>
74 Specifies the remote principal file in rsync notation. This implies
75 that the necessary remote files will be mirrored before constructing
76 the list.
78 =item B<--rsync_options|rsync=s@>
80 Multiple options in the form of key=value pairs. E.g.
82 --rsync=compress=1 --rsync=links=1
84 The options are passed to the underlying L<File::Rsync> objects.
86 =item B<--skip-deletes!>
88 Boolean. If true then delete events are skipped.
90 =item B<--verbose|v+>
92 More feedback.
94 =back
96 =head1 DESCRIPTION
98 rersyncrecent is a project to get speedy rsync operation on large
99 trees over multiple hosts. It maintains a collection of files with
100 metadata (so called recentfiles) that represent adjacent overlapping
101 timespans of file change events.
103 rrr-news extracts from the recentfiles the new files added or
104 modified. The remote-principal-file is the rsync-notation for the
105 remote recentfile. The second argument is the path to the local mirror
106 directory. If you omit the second argument, a temporary directory is
107 taken instead.
109 =cut
112 use strict;
113 use warnings;
115 use lib "/home/k/sources/rersyncrecent/lib";
116 use File::Rsync::Mirror::Recent;
117 use Getopt::Long;
118 use Pod::Usage qw(pod2usage);
120 our %Opt;
121 GetOptions(\%Opt,
122 @opt,
123 ) or pod2usage(2);
125 if ($Opt{help}) {
126 pod2usage(0);
129 if (@ARGV) {
130 pod2usage(2);
133 if ($Opt{'dry-run'}) {
134 die "FIXME: not yet implemented";
137 my @constr;
138 for my $opt (qw(local remote localroot)) {
139 if (defined $Opt{$opt}) {
140 push @constr, $opt => $Opt{$opt};
143 my $rf = File::Rsync::Mirror::Recent->new
145 @constr,
146 # stupid, need no rsync options when running with -local!
147 rsync_options => {
148 compress => 1,
149 links => 1,
150 times => 1,
151 checksum => 1,
154 if ($rf->remote) {
155 unless ($rf->localroot) {
156 require File::Temp;
157 my $ldir = File::Temp::tempdir(
158 "rrr-news-XXXXXX",
159 TMPDIR => 1,
161 $rf->localroot($ldir);
163 } elsif ($rf->local) {
164 } else {
165 die "need either --local option or both of --remote and --localroot";
167 for my $passthrough (
168 "locktimeout",
169 "verbose",
171 if (my $x = $Opt{$passthrough}) {
172 $rf->$passthrough($x);
176 my %rsopt;
177 for my $rsopt (@{$Opt{rsync_options}||[]}) {
178 my($key,$value) = $rsopt =~ /([^=]+)=(.+)/s;
179 $rsopt{$key} = $value;
181 $rf->rsync_options(\%rsopt);
183 my @nopt;
184 for my $opt (qw(after before max skip-deletes)) {
185 if (defined $Opt{$opt}) {
186 push @nopt, $opt => $Opt{$opt}
189 my $contains;
190 for my $opt (qw(path epoch type)) {
191 if (defined $Opt{"contains_$opt"}) {
192 $contains->{$opt} = $Opt{"contains_$opt"};
195 if ($contains) {
196 push @nopt, max => 1, contains => $contains;
198 print map {
199 sprintf
201 "%-20s %s\n",
202 scalar localtime($_->{epoch}),
203 $_->{path},
204 )} @{ $rf->news(@nopt) };
206 __END__
209 # Local Variables:
210 # mode: cperl
211 # coding: utf-8
212 # cperl-indent-level: 4
213 # End: