#!/usr/bin/perl -w
END {
close
STDOUT;
close
STDERR;
POSIX::_exit $?;
}
our
$datadir
;
BEGIN {
our
$VERSION
=
'@VERSION@'
;
$datadir
= $0;
unless
(
$datadir
=~ s@/[^/]+$@@ ) {
foreach
(
split
( /:/,
$ENV
{
'PATH'
} ),
'.'
) {
if
( -d
"$_/Mpp"
) {
$datadir
=
$_
;
last
;
}
}
}
$datadir
or
die
"makepp: can't find library files\n"
;
$datadir
=
eval
"use Cwd; cwd . '/$datadir'"
if
$datadir
=~ /^\./;
unshift
@INC
,
$datadir
;
}
my
$verbose
;
sub
print_msg {
foreach
my
$str
(
@_
, (
$_
[-1] =~ /\n\z/) ? () :
"\n"
) {
my
$str_to_print
=
$str
;
ref
$str_to_print
and
$str_to_print
= absolute_filename
$str
;
print
STDERR
$str_to_print
;
}
}
sub
print_error {
print
STDERR
"$Mpp::progname: error: "
;
&print_msg
;
}
sub
print_warning {
print
STDERR
"$Mpp::progname: warning: "
;
&print_msg
;
}
sub
print_log {
&print_msg
if
$verbose
;
}
my
$n_files_removed
= 0;
my
$recurse
;
sub
perform(&) {
my
$code
=
$_
[0];
eval
{
&$code
; };
if
($@) {
print_error $@;
close
STDOUT;
close
STDERR;
exit
1;
}
if
(
$verbose
) {
print
"$Mpp::progname: $n_files_removed file"
. (
$n_files_removed
== 1 ?
''
:
's'
) .
" removed\n"
;
}
elsif
( !
$n_files_removed
) {
print
"$Mpp::progname: no files removed\n"
;
}
exit
0;
}
my
@info_strings
;
my
@deletable
;
my
(
$dirs
,
@deletable_dirs
);
my
(
$logs
,
$meta
);
sub
deletable {
return
1
if
-l
&Mpp::File::build_info_fname
&& !-e _;
defined
and
return
1
for
Mpp::File::build_info_string
$_
[0],
@info_strings
;
if
(
$_
[0]{TEMP_BUILD_INFO} ) {
return
if
$_
[0]{TEMP_BUILD_INFO}{SYMLINK} ne (
readlink
&Mpp::File::absolute_filename
or
''
);
defined
and
return
1
for
@{
$_
[0]{TEMP_BUILD_INFO}}{
@info_strings
};
}
$_
[0]{NAME} =~ /^\.makepp_(?:
log
|testfile)/;
}
sub
remove_if_built_file {
if
(
&deletable
) {
if
(
&is_dir
) {
unshift
@deletable_dirs
,
$_
[0];
}
else
{
print_log
"Removing "
,
$_
[0];
++
$n_files_removed
;
push
@deletable
,
&relative_filename
,
&Mpp::File::build_info_fname
;
}
unless
(
exists
$_
[0]{
'..'
}{xMAKEPP_DELETABLE} ) {
undef
$_
[0]{
'..'
}{xMAKEPP_DELETABLE};
my
$makepp
= file_info
$Mpp::File::build_info_subdir
,
$_
[0]{
'..'
};
unshift
@deletable_dirs
,
$makepp
if
is_dir
$makepp
;
}
}
}
my
$keep_src_info
;
sub
remove_contents_if_built {
my
(
$dinfo
) =
@_
;
&Mpp::File::read_directory
;
my
$has_build_info
;
for
my
$name
(
keys
%{
$dinfo
->{DIRCONTENTS}}) {
my
$finfo
=
$dinfo
->{DIRCONTENTS}{
$name
};
if
(
$name
eq
$Mpp::File::build_info_subdir
) {
$has_build_info
= 1;
if
(
$meta
) {
++
$n_files_removed
;
}
elsif
(
$logs
and is_dir
$finfo
) {
Mpp::File::read_directory
$finfo
;
for
my
$rm
( @{
$finfo
->{DIRCONTENTS}}{
grep
/^
log
(?!.*\.mk$)/s,
keys
%{
$finfo
->{DIRCONTENTS}}} ) {
print_log
"Removing "
,
$rm
;
++
$n_files_removed
;
push
@deletable
, relative_filename
$rm
;
}
}
next
;
}
remove_if_built_file
$finfo
if
@info_strings
;
remove_contents_if_built(
$finfo
)
if
$recurse
and is_dir
$finfo
;
}
unshift
@deletable_dirs
,
$dinfo
if
$dirs
&&
$has_build_info
;
unless
(
$keep_src_info
) {
my
$makepp
= file_info
$Mpp::File::build_info_subdir
,
$dinfo
;
if
( is_dir
$makepp
) {
unless
(
exists
$dinfo
->{xMAKEPP_DELETABLE} ) {
undef
$dinfo
->{xMAKEPP_DELETABLE};
unshift
@deletable_dirs
,
$makepp
;
}
undef
$makepp
->{xDELETABLE};
}
}
}
perform {
Mpp::Text::getopts
[
'b'
,
qr/(?:only[-_]?)?(?:build[-_]?)?cache[-_]?(?:link|file)s/
,
undef
, 0,
sub
{
push
@info_strings
,
'LINKED_TO_CACHE'
}],
[
'd'
,
qr/(?:ampty[-_]?)?director(?:ies|y)/
, \
$dirs
],
[
'k'
,
qr/(?:keep|leave)[-_]?src[-_]?info/
, \
$keep_src_info
],
[
'l'
,
qr/(?:only[-_]?)?logs?/
, \
$logs
],
[
'm'
,
qr/(?:only[-_]?)?meta|makepp/
, \
$meta
],
[
'R'
,
qr/(?:only[-_]?)?repository[-_]?links/
,
undef
, 0,
sub
{
push
@info_strings
,
'FROM_REPOSITORY'
}],
[
'r'
,
qr/recurs(?:iv)?e/
, \
$recurse
],
[
qw(v verbose)
, \
$verbose
],
splice
@Mpp::Text::common_opts
;
if
(
$meta
&&
$keep_src_info
) {
print_error
"-m|--only-meta contradicts -k|--keep-src-info"
;
exit
1;
}
if
(
@info_strings
||
$logs
) {
$keep_src_info
= 1;
}
elsif
( !
$meta
) {
@info_strings
=
qw(BUILD_SIGNATURE FROM_REPOSITORY)
;
}
if
(
@ARGV
) {
for
my
$arg
(
@ARGV
) {
my
$finfo
= file_info
$arg
;
remove_if_built_file
$finfo
;
remove_contents_if_built
$finfo
if
is_dir
$finfo
;
}
}
else
{
remove_contents_if_built file_info
'.'
;
}
unlink
@deletable
;
for
(
@deletable_dirs
) {
unless
(
exists
$_
->{xDELETABLE} ) {
$_
->{DIRCONTENTS} = {};
Mpp::File::read_directory
$_
;
delete
$_
->{DIRCONTENTS}{
$Mpp::File::build_info_subdir
};
next
if
keys
%{
$_
->{DIRCONTENTS}};
}
print_log
"Removing "
,
$_
,
'/'
if
$meta
||
$_
->{NAME} ne
$Mpp::File::build_info_subdir
;
rmtree relative_filename
$_
;
}
};