use
5.12.0;
use
List::Util 1.29
qw'first reduce pairmap pairgrep pairfirst'
;
has
'manifest'
,
is
=>
'rw'
,
default
=>
sub
{ {} };
has
'isDeletion'
,
is
=>
'ro'
;
has
'srcDir'
,
is
=>
'rw'
,
default
=>
'src'
;
has
'apiVersion'
,
is
=>
'rw'
,
default
=> 33;
sub
_splitLine {
my
(
$self
,
$line
) =
@_
;
LOGDIE
"Called _splitLine with no argument!"
unless
$line
;
$line
=~ s/.
*src
\///;
$line
=~ s/[\n\r]//g;
my
%result
= (
"extension"
=>
""
);
(
$result
{
"type"
}) =
$line
=~ /^(\w+)\//
or LOGDIE
"Line $line doesn't have a type."
;
$result
{
"folder"
} = $1
if
$line
=~ /\/(\w+)\//;
my
$extension
= getEnding(
$result
{
"type"
});
if
(
$line
=~ /\/(\w+)-meta.xml/) {
$result
{
"name"
} = $1
}
elsif
(!
defined
$extension
) {
(
$result
{
"name"
}) =
$line
=~ /\/([^\/]*?)(-meta\.xml)?$/;
$result
{
"name"
} =~ s/:/./;
}
elsif
(
$line
=~ /\/([^\/]*?)(
$extension
)(-meta\.xml)?$/) {
$result
{
"name"
} = $1;
$result
{
"extension"
} = $2;
}
LOGDIE
"Line $line doesn't have a name."
unless
$result
{
"name"
};
return
\
%result
;
}
sub
_getFilesForLine {
my
(
$self
,
$line
) =
@_
;
return
()
unless
$line
;
my
%split
= %{
$self
->_splitLine(
$line
)};
return
map
{
"$split{type}/$_"
} (
$split
{
"folder"
}
?(
"$split{folder}-meta.xml"
,
"$split{folder}/$split{name}$split{extension}"
,
(needsMetaFile(
$split
{
"type"
}) ?
"$split{folder}/$split{name}$split{extension}-meta.xml"
: ())
)
:(
"$split{name}$split{extension}"
,
(needsMetaFile(
$split
{
"type"
}) ?
"$split{name}$split{extension}-meta.xml"
: ())
)
)
}
sub
_dedupe {
my
(
$self
) =
@_
;
my
%result
;
for
my
$key
(
keys
%{
$self
->manifest}) {
my
%_deduped
=
map
{
$_
=> 1} @{
$self
->manifest->{
$key
}};
$result
{
$key
} = [
sort
keys
%_deduped
];
}
$self
->manifest(\
%result
);
return
$self
;
}
sub
getFileList {
my
$self
=
shift
;
return
map
{
my
$type
= getDiskName(
$_
);
my
$ending
= getEnding(
$type
) ||
""
;
map
{
if
(hasFolders(
$type
) and
$_
!~ /\//) {
"$type/$_-meta.xml"
;
}
else
{
"$type/$_$ending"
, (needsMetaFile(
$type
) ?
"$type/$_$ending-meta.xml"
: () );
}
} @{
$self
->manifest->{
$_
} }
}
keys
%{
$self
->manifest};
}
sub
add {
my
(
$self
,
$new
) =
@_
;
if
(
defined
blessed
$new
and blessed
$new
eq blessed
$self
) {
push
@{
$self
->manifest->{
$_
}}, @{
$new
->manifest->{
$_
}}
for
keys
%{
$new
->manifest};
}
else
{
push
@{
$self
->manifest->{
$_
}}, @{
$new
->{
$_
}}
for
keys
%$new
;
}
return
$self
->_dedupe();
}
sub
addList {
my
$self
=
shift
;
return
reduce {
$a
->add(
$b
)}
$self
,
map
{
DEBUG
"Adding $_ to manifest"
;
+{
getName(
$$_
{type}) => [
defined
$$_
{folder}
? (
(
$self
->isDeletion ? () :
$$_
{folder}),
"$$_{folder}/$$_{name}"
)
: (
$$_
{name})
]
}
}
map
{
$self
->_splitLine(
$_
)}
@_
;
}
sub
readFromFile {
my
(
$self
,
$fileName
) =
@_
;
return
reduce {
$a
->add(
$b
)}
$self
,
map
{+{
do
{
pairmap {
$b
->[2]} pairfirst {
$a
eq
'name'
}
@$_
} => [
pairmap {
$b
->[2]} pairgrep {
$a
eq
'members'
}
@$_
]
}}
pairmap {[
splice
@{
$b
}, 1]} pairgrep {
$a
eq
'types'
}
splice
@{
XML::Parser->new(
Style
=>
"Tree"
)->parsefile(
$fileName
)->[1]
}, 1;
}
sub
writeToFile {
my
(
$self
,
$fileName
) =
@_
;
open
my
$fh
,
">"
,
$fileName
or LOGDIE
"Couldn't open $fileName to write manifest to disk"
;
print
$fh
$self
->getXML();
return
$self
;
}
sub
getXML {
my
(
$self
) =
@_
;
return
join
""
, (
"<?xml version='1.0' encoding='UTF-8'?>"
,
(
map
{(
"<types>"
,
"<name>$_</name>"
,
(
map
{
"<members>$_</members>"
} @{
$self
->manifest->{
$_
}} ),
"</types>"
,
)}
sort
keys
%{
$self
->manifest}
),
"<version>"
,
$self
->apiVersion,
"</version></Package>"
);
}
1;