Skip site navigation (1)Skip section navigation (2)

FreeBSD Manual Pages


home | help
VCP::Maintenance(3)   User Contributed Perl Documentation  VCP::Maintenance(3)

       VCP::Maintenance	- VCP code maintenance tips & tricks



	vcp revml: --dtd <dtd file name> --save_dtd <how>

   The distribution hierarchy
       As untarred, the	distribution hierarchy looks like (some	files not
       shown for brevity):

	  +--- Makefile.PL     ## Generates the	Makefile
	  +--- MANIFEST	       ## what files to	ship, built with `make manifest`
	  +--- MANIFEST.SKIP   ## what filenames `make manifest` should	ignore
	  +--- CHANGES	       ## A detailed summary of	all edits
	  +--- TODO	       ## Things we can't get to quite yet
	  +--- LICENSE
	  +--- README
	  +--- revml.dtd       ## Defines legal	RevML
	  +--+ bin/	       ## Executable files
	  |  +---- vcp	       ## The command line interface
	  |  +---- gentrevml   ## builds RevML files for the test suite
	  |  +----  ## dumps	files in hex, a	debugging aid
	  +--+ lib/	       ## All modules that comprise VCP	itself
	  |  +---       ## Drives the VCP process
	  |  +--- *.pod	       ## Supplemental documentation
	  |  +---    ## Base class for all sources & destinations
	  |  |
	  |  +---    ## Base class for all sources
	  |  +--+ Source/
	  |  |	+---    ## A backend to read from repo. type "foo"
	  |  |
	  |  +---      ## Base class for all destinations
	  |  +--+ Dest/
	  |  |	+---    ## A backend to write to	repo. type "foo"
	  |  |
	  |  +--+ Utils/
	  |  |	+---    ## Routines shared by Source/ and Dest/'s
	  |  |
	  |  +---       ## VCP's	concept	of a revision
	  |  +---      ## A collection of VCP::Rev instances
	  |  |
	  |  +--- RevML/       ## Files	defining RevML
	  +--+ t/	       ## The test suite
	     +--- *.t	       ## Test scripts
	     +--- test-*.revml ## Fodder for test scripts

       In addition, the	following files	are created:

	  +--- vcp_html	       ## By running the `vcp html` command
	  +--- pod2htm*	       ## Gunk left over from `vcp html`
	  +--- blib/	       ## By running `make`

   Useful command line idioms
       perl -Ilib -cw %
	   (in your editor's key mapping).

	   Useful to map an editor key to this.	 Use whatever path for -I
	   works given your cwd	usage habit, and replace the "%" with whatever
	   macro your editor replaces with the path to the current file.

       make test TEST_FILES=t/90foo.t TEST_VERBOSE=1
	   Runs	just the listed	test files (space separated list; use quotes)
	   and shows STDOUT.

       perl -Ilib bin/vcp ...
	   Run "vcp" manually without setting PERL5LIB or installing it.

       export PERL5LIB=lib
	   Allows "vcp"	and "gentrevml"	to be run from command line

       make test
	   Runs	all tests, generating "t/test-*.revml" if need be.

   Environment Variables
       Some environment	variables that are useful in debugging:

	   Set this to a TRUE value to force "VCP::*" modules emit debugging

	   See also VCP::Debug for more	details.

	   Set this to "yes" to	tell "vcp" not to delete it's working
	   directories.	 This allows you to take a look	at them	and see	what
	   the source and dest command lines saw.

	   Set this to some number from	0..10 to see how "vcp" (via IPC::Run3)
	   is treating it's subprocesses.

	   If this is present and pointing to a	readable file when a p4	daemon
	   is started via vcp, a symlink will be created in the	(possibly
	   newly created) p4root directory to point to the p4 license file
	   pointed to by VCPP4LICENSE.	The 'make' target test_all_p4_versions
	   will	cycle through each version of p4 and p4d contained in the
	   'p4versions'	directory, in both unlicensed and (if VCPP4LICENSE
	   present) licensed mode.

       In addition, both CVS and Perforce backends pay attention to the
       relevant	environment variables.

       "bin/"	is useful for debugging	issues involving line endings,
       embedded	control	code (esp. ^Z on Win32 and NULL	on every platform,
       since most C programs die when encountering NULL	in a text file).

   The tests
       The t/*.t files in the source distribution contain a large number of
       tests.  The tests begin with a two digit	number that orders them	so
       that more primitive tests run first, followed by	higher level "end-to-
       end" tests in "t/90*.t".

       The more	primitive tests	are pretty standard fare for Perl test suites.
       Where things get	interesting is the "t/90*.t" tests.  These tests use
       the command-line	"vcp" interface	to move	reasonably sized chunks	of
       RevML (up to about 65k currently; pretty	small in comparison to "real"
       exports)	in to, out of, and between various repositories.

       The RevML extracted from	the repositories is compared to	the RevML that
       was fed in to them, after sanitizing both of data that is known to not
       make it through ok.

       The module VCP::TestUtils contains support routines for initializing
       repositories and	shutting them down (when a server is needed).
       Existing	repositories are not used in the test suite; they'd be useless
       and in danger if	we did.

       The file	"bin/gentrevml"	is used	to generate the	RevML files
       ("t/test*.revml") from scratch using hand written code instead of
       VCP::Dest::revml	in order to reduce the chances of a bug	in
       VCP::Dest::revml	causing	false positives	in the test results.

       It's highly likely that new back	ends will require new test RevML
       files.  "bin/gentrevml" should be hacked	up to generate these and new
       rules should be added to	the "Makefile" by editing "Makefile.PL".

       The structure of	a test script.

       The t/*.t scripts generally all follow the same structure.

       First, they import all necessary	modules	and init themselves.

       Then they build a

	  my @tests = (
	  sub {

       array that contain the actual tests.  Each test is a single anonymous
       "sub {...}", every once in a while a single "sub	{...}" will contain
       two tests; it is	preceded by an empty (or nearly	empty) "sub {}"	in
       these cases.

       At the bottom, some final checks	are run	to see if all tests should be
       skipped,	then

	  plan tests =>	scalar @tests;

       emits how many tests are	to be run, and

	  $_->() for @tests;

       runs the	tests.

       This structure is used for several reasons:

       1. No counting tests
	   Tests are counted automatically for you this	way, the "scalar
	   @tests" does	this.  Otherwise you end up having to remember to
	   manually fudge this every time a test is adding or removed.

       2. Clear	demarcation
	   Tests tend to use local variables a lot; this structure keeps them
	   from	"leaking" from one test	to another.  Things that are shared
	   between tests are usually declared right above the "my @tests ="
	   line	and are	pretty obvious.

       3. Commenting out tests
	   In situations where you want	to focus on one	or a few tests,	just
	   put a line like:

	       ); @tests = (

	   before the first test "sub" you want	to run,	and a line like

	      sub { last },

	   after the last one.	This is	especially important.

       4. Test line numbers
	   Failing tests, when run with	"TEST_VERBOSE=1" as shown above, will
	   report their	line numbers.  This is the fastest way to find out
	   what's failing.  The	list-of-subs approach is used even when	@tests
	   could actually contain just test vectors and	the "for @tests	" loop
	   could check the vectors because we want line	numbers	to tell	us
	   where to look.  If we used test vectors, then the call to "ok()"
	   would report	some line number in the	"for @tests" loop, not the
	   line	number of the test.

       5.  If you want to enable "vcp" or IPC::Run3 debugging (see VCP::Debug,
	   too), you can put a

	      local $ENV{IPCRUN3DEBUG} = 1;  ##	1..10

	   in the appropriate "sub {...}" and it won't cause all the other
	   tests to spew a lot of noise.

   Developing a	new backend
       In general, backends are	created	in pairs so that a "t/90foo.t" can be
       written to import the RevML files in to the backend repository, extract
       new RevML from it, and compare the two.

       A backend usually consists of 3 Perl classes: VCP::Source::foo,
       VCP::Dest::foo, and VCP::Utils::foo.  The reason	for the	lowercase
       final name is so	that the "vcp" command can translate from the scheme
       name ("cvs:") to	a source or destination	module name trivially.

       The VCP::Source::foo generally contains a parser	to extract metadata
       from repository log reports and a routine to drive the copying process.
       The VCP module ("/lib/")

   Updating the	RevML DTD
       Run the command "compile_dtd", which by default will look for the file
       'revml.dtd'.  This should be done each time the dtd changes.
       Optionally you may pass in a dtd	file name as the argument to

       The generated file is placed in "./lib/RevML/Doctype/" or
       "./RevML/Doctype/" or "./", whichever is	found first.  No directories
       will be created.

       This does not update the	VCP::Source::revml or VCP::Dest::revml drivers
       to match	the DTD, nor does it affect "bin/gentrevml", which is used by
       the test	suite to build the RevML files used for	testing.

       Barrie Slaymaker	<>

       Copyright (c) 2000, 2001, Perforce Software, Inc.  All rights reserved.

       See VCP::License	("vcp help license") for the terms of use.

       Hey! The	above document had some	coding errors, which are explained

       Around line 243:
	   Expected text after =item, not a number

perl v5.32.0			  2004-11-04		   VCP::Maintenance(3)


Want to link to this manual page? Use this URL:

home | help