.\" Automatically generated by Pod::Man 4.07 (Pod::Simple 3.32) .\" .\" Standard preamble: .\" ======================================================================== .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" Set up some character translations and predefined strings. \*(-- will .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left .\" double quote, and \*(R" will give a right double quote. \*(C+ will .\" give a nicer C++. Capital omega is used to do unbreakable dashes and .\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, .\" nothing in troff, for use with C<>. .tr \(*W- .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' .ie n \{\ . ds -- \(*W- . ds PI pi . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch . ds L" "" . ds R" "" . ds C` "" . ds C' "" 'br\} .el\{\ . ds -- \|\(em\| . ds PI \(*p . ds L" `` . ds R" '' . ds C` . ds C' 'br\} .\" .\" Escape single quotes in literal strings from groff's Unicode transform. .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" .\" If the F register is >0, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .\" .\" Avoid warning from groff about undefined register 'F'. .de IX .. .if !\nF .nr F 0 .if \nF>0 \{\ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . if !\nF==2 \{\ . nr % 0 . nr F 2 . \} .\} .\" ======================================================================== .\" .IX Title "SVN::Hooks::CheckStructure 3pm" .TH SVN::Hooks::CheckStructure 3pm "2017-06-24" "perl v5.24.1" "User Contributed Perl Documentation" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" SVN::Hooks::CheckStructure \- Check the structure of a repository. .SH "VERSION" .IX Header "VERSION" version 1.34 .SH "SYNOPSIS" .IX Header "SYNOPSIS" This SVN::Hooks plugin checks if the files and directories added to the repository are allowed by its structure definition. If they don't, the commit is aborted. .PP It's active in the \f(CW\*(C`pre\-commit\*(C'\fR hook. .PP It's configured by the following directive. .SS "\s-1CHECK_STRUCTURE\s0(\s-1STRUCT_DEF\s0)" .IX Subsection "CHECK_STRUCTURE(STRUCT_DEF)" This directive enables the checking, causing the commit to abort if it doesn't comply. .PP The \s-1STRUCT_DEF\s0 argument specify the repository strucure with a recursive data structure consisting of one of: .IP "\s-1ARRAY REF\s0" 4 .IX Item "ARRAY REF" An array ref specifies the contents of a directory. The referenced array must contain a pair number of elements. Each pair consists of a \&\s-1NAME_DEF\s0 and a \s-1STRUCT_DEF.\s0 The \s-1NAME_DEF\s0 specifies the name of the component contained in the directory and the \s-1STRUCT_DEF\s0 specifies recursively what it must be. .Sp The \s-1NAME_DEF\s0 specifies a name in one of these ways: .RS 4 .IP "\s-1STRING\s0" 4 .IX Item "STRING" A string specifies a name directly. .IP "\s-1REGEXP\s0" 4 .IX Item "REGEXP" A regexp specifies the class of names that match it. .IP "\s-1NUMBER\s0" 4 .IX Item "NUMBER" A number may be used as an else-clause. A non-zero number means that any name not yet matched by the previous pair must conform to the associated \s-1STRUCT_DEF.\s0 .Sp A zero means that no name will do and signals an error. In this case, if the \s-1STRUCT_DEF\s0 is a string it is used as a help message shown to the user. .RE .RS 4 .Sp If no \s-1NAME_DEF\s0 matches the component being looked for, then it is a structure violation and the commit fails. .RE .IP "\s-1STRING\s0" 4 .IX Item "STRING" A string must be one of '\s-1FILE\s0' and '\s-1DIR\s0', specifying what the current component must be. .IP "\s-1NUMBER\s0" 4 .IX Item "NUMBER" A non-zero number simply tells that whatever the current component is is ok and finishes the check successfully. .Sp A zero tells that whatever the current component is is a structure violation and aborts the commit. .PP Now that we have this semi-formal definition off the way, let's try to understand it with some examples. .PP .Vb 10 \& my $tag_rx = qr/^[a\-z]+\-\ed+\e.\ed+$/; # e.g. project\-1.0 \& my $branch_rx = qr/^[a\-z]+\-/; # must start with letters and hifen \& my $project_struct = [ \& \*(AqMETA.yml\*(Aq => \*(AqFILE\*(Aq, \& \*(AqMakefile.PL\*(Aq => \*(AqFILE\*(Aq, \& ChangeLog => \*(AqFILE\*(Aq, \& LICENSE => \*(AqFILE\*(Aq, \& MANIFEST => \*(AqFILE\*(Aq, \& README => \*(AqFILE\*(Aq, \& t => [ \& qr/\e.t$/ => \*(AqFILE\*(Aq, \& ], \& lib => \*(AqDIR\*(Aq, \& ]; \& \& CHECK_STRUCTURE( \& [ \& trunk => $project_struct, \& branches => [ \& $branch_rx => $project_rx, \& ], \& tags => [ \& $tag_rx => $project_rx, \& ], \& ], \& ); .Ve .PP The structure's first level consists of the three usual directories: \&\f(CW\*(C`trunk\*(C'\fR, \f(CW\*(C`tags\*(C'\fR, and \f(CW\*(C`branches\*(C'\fR. Anything else in this level is denied. .PP Below the \f(CW\*(C`trunk\*(C'\fR we allow some usual files and two directories only: \&\f(CW\*(C`lib\*(C'\fR and \f(CW\*(C`t\*(C'\fR. Below \f(CW\*(C`trunk/t\*(C'\fR we may allow only test files with the \f(CW\*(C`.t\*(C'\fR extension and below \f(CW\*(C`lib\*(C'\fR we allow anything. .PP We require that each branch and tag have the same structure as the \&\f(CW\*(C`trunk\*(C'\fR, which is made easier by the use of the \f(CW$project_struct\fR variable. Moreover, we impose some restrictions on the names of the tags and the branches. .SH "EXPORT" .IX Header "EXPORT" .SS "check_structure(\s-1STRUCT_DEF, PATH\s0)" .IX Subsection "check_structure(STRUCT_DEF, PATH)" SVN::Hooks::CheckStructure exports a function to allow for the verification of path structures outside the context of a Subversion hook. (It would probably be better to take this function to its own module and use that module here. We'll take care of that eventually.) .PP The function check_structure takes two arguments. The first is a \&\s-1STRUCT_DEF\s0 exactly the same as specified for the \s-1CHECK_STRUCTURE\s0 directive above. The second is a \s-1PATH\s0 to a file which will be checked against the \s-1STRUCT_DEF.\s0 .PP The function returns true if the check succeeds and dies with a proper message otherwise. .PP The function is intended to check paths as they're shown by the 'svn ls' command, i.e., with no leading slashes and with a trailing slash to indicate directories. The leading slash is assumed if it's missing, but the trailing slash is needed to indicate directories. .SH "AUTHOR" .IX Header "AUTHOR" Gustavo L. de M. Chaves .SH "COPYRIGHT AND LICENSE" .IX Header "COPYRIGHT AND LICENSE" This software is copyright (c) 2016 by CPqD . .PP This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.