2
# $Id: slack-rolediff,v 1.6 2006/09/27 07:50:07 alan Exp $
5
# Copyright (C) 2004-2006 Alan Sundell <alan@sundell.net>
6
# All Rights Reserved. This program comes with ABSOLUTELY NO WARRANTY.
7
# See the file COPYING for details.
9
# This script provides a preview of scripts or files about to be installed.
10
# Basically, it calls diff -- its smarts are in knowing where things are.
13
use warnings FATAL => qw(all);
15
use sigtrap qw(die untrapped normal-signals
16
stack-trace any error-signals);
21
use constant LIB_DIR => '/usr/lib/slack';
25
my @diff = ('slack-diff',
29
# directories to compare
35
(my $PROG = $0) =~ s#.*/##;
39
########################################
41
# Helpful prefix to die messages
42
$SIG{__DIE__} = sub { die "FATAL[$PROG]: @_"; };
43
# Set a reasonable umask
45
# Get out of wherever (possibly NFS-mounted) we were
47
or die "Could not chdir /: $!";
49
select((select(STDERR), $|=1)[0]);
51
########################################
52
# Config and option parsing {{{
53
my $usage = Slack::default_usage("$PROG [options] <role> [<role>...]");
57
Check this subdir only. Possible values for DIR are 'files' and
61
Use this program to do diffs. [@diff]
67
command_line_options => [
72
required_options => [ qw(cache stage root) ],
75
# Arguments are required
76
die "No roles given!\n\n$usage" unless @ARGV;
78
# We only allow certain values for this option
80
unless ($opt{subdir} eq 'files' or $opt{subdir} eq 'scripts') {
81
die "--subdir option must be 'files' or 'scripts'\n\n$usage";
84
%subdir = ( $opt{subdir} => 1 );
87
# Let people override our diff. Split on spaces so they can pass args.
89
@diff = split(/\s+/, $opt{diff});
96
for my $full_role (@ARGV) {
97
# Split the full role (e.g. google.foogle.woogle) into components
98
my @role = split(/\./, $full_role);
100
if ($subdir{scripts}) {
101
# Then we compare the cache vs the stage
102
my $old = $opt{stage} . "/roles/" . $full_role . "/scripts";
103
my $new = $opt{cache} . "/roles/" . $role[0] . "/scripts";
104
# For scripts, we don't care so much about mode and owner (since those are
105
# inherited in the CACHE from the SOURCE), so --noperms.
106
$exit |= diff($old, $new, '--noperms');
109
if ($subdir{files}) {
110
# Then we compare the stage vs the root
111
my $old = $opt{root};
112
my $new = $opt{stage} . "/roles/" . $full_role . "/files";
113
# For files, we don't care about files that exist in $old but not $new
114
$exit |= diff($old, $new, '--unidirectional-new-file');
120
my ($old, $new, @options) = @_;
122
my @command = (@diff, @options);
124
# return if there's nothing to do
125
return 0 if (not -d $old and not -d $new);
127
($opt{verbose} > 0) and print STDERR "$PROG: Previewing with '@command'\n";
132
my $old_file = $new_file;
133
($old_file =~ s#^$new#$old#)
134
or die "sub failed: $new|$new_file";
135
if (system(@command, $old_file, $new_file) != 0) {
136
$return |= Slack::get_system_exit(@command);
140
# We have to use this function, rather than recursive mode for slack-diff,
141
# because otherwise we'll print a bunch of bogus stuff about directories
142
# that exist in $ROOT and therefore aren't being synced.
143
Slack::find_files_to_install($new, $old, $callback);