Scripting in Meta-CVS

The -i and -x options can be used to do some useful things. They allows the
users of Meta-CVS to write arbitrary scripts which make direct calls to the
Meta-CVS internals, taking advantage of its functions and macros.

Scripts are read and evaluated in the META-CVS package, and so may conveniently
make unqualified references to the software's internal symbols.

After scripts are evaluated, Meta-CVS still dispatches a command, if one was
specified.


Example 1.

  Here is a script which lists all of the files which have an :EXEC property;
  i.e. are executable:

    (in-sandbox-root-dir
      (let ((map (mapping-read *map-path*)))
       (dolist (entry map)
	 (with-slots (raw-plist path) entry
	   (when (getf raw-plist :exec)
	     (princ path) (terpri))))))

  If this is stored in a file called print-exec, then

    mcvs -i print-exec

  will run it.


Example 2.

  Script to make an archive of files tagged with :ARCHIVE property,
  using GNU tar:

    (in-sandbox-root-dir
      (let* ((map (mapping-read *map-path*))
             (paths (loop for entry in map
                          when (getf (slot-value entry 'raw-plist) :archive)
                            collect (slot-value entry 'path))))
        (execute-program `("tar" "czf" "foo.tar.gz" ,@paths))))


  But this contains a bug! More than one, in fact! 

  It, or rather tar, fails when the paths list is empty. But let's
  regard that as a feature.

  More importantly, it will not work in partial sandboxes, because it will feed
  GNU tar the abstract paths from the mapping file, rather than the real paths.

  In a partial sandbox, some, or even all of these files might not be
  visible, since they are in sibling or parent parts of the tree, outside
  of the subtree that was checked out. 

  So, for each abstract path, a test must be applied whether it is in fact
  mapped into the sandbox. And if so, the path must be translated.

  Meta-CVS has functions for dealing with this: REAL-PATH-EXISTS,
  ABSTRACT-TO-REAL-PATH and REAL-TO-ABSTRACT-PATH. They only work within
  the dynamic contour of an IN-SANDBOX-ROOT-DIR form.

    (in-sandbox-root-dir
      (let* ((map (mapping-read *map-path*))
             (paths (loop for entry in map
                          when 
			    (getf (slot-value entry 'raw-plist) :archive) 
			  when
			    (real-path-exists (slot-value entry 'path))
                          collect (abstract-to-real-path
				    (slot-value entry 'path)))))
        (execute-program `("tar" "czf" "foo.tar.gz" ,@paths))))


