Svn.pl

From CDOT Wiki
Revision as of 14:36, 14 December 2006 by Elichak (talk | contribs)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search
  1. !/usr/bin/perl
  2. blah blah... license info blah blah seems most other source files have this header comment format
  3. The Original Code was written for:
  4. Delta Debugging Framework.
  5. The Initial Developer of the Original Code:
  6. Richard Chu
  7. Contributor(s):
  8. Elizabeth Chak - Documentation
  9. Date Created: October 09, 2006
  10. Date Last Modified: October 24, 2006
  11. Version: 0.03
  12. Description:
  13. Light Wrapper around SVN commands used to manage, update, manipulate the SVN source repository.
  14. The wrapper assumes the most common usage of each command. It can perform the following commands:
  15. svn checkout
  16. svn update
  17. svn commit
  18. svn diff
  19. One thing I haven't figured out yet is if the svn commands return a return code to indicate
  20. whether or not the command executed successfully or not. If the svn commands do, then I
  21. would probably perform a check on whether or not the commands executed successfully or not.
  22. NOTE/FIXME: Currently (Oct. 24, 2006 version), the subroutines that take in revision numbers
  23. (update, diff) require that the argument be numerical. There is no support for
  24. revision keywords (HEAD, BASE, COMMITED, PREV), or revision dates as described
  25. here: http://svnbook.red-bean.com/nightly/en/svn.tour.revs.html
  26. Change History:
  27. October 09, 2006:
  28. - svn class created. Initial support for most common usage of checkout, update, and commit commands
  29. October 15, 2006:
  30. - added support for most common usage of diff command.
  31. - updated the update subroutine to receive another parameter for file/directory path.
  32. arguments in update subroutine are all optional now. 1st argument default is "HEAD".
  33. October 24, 2006:
  34. - fixed conditional statement in diff subroutine from < $nRevisions to <= $nRevisions

use warnings; use strict; package RCS::SVN;

  1. Create an generic RCS element. The hash ($self) holds the values for svn
  2. url, username and password passed into the subroutine. Data type of
  3. hash is then changed to $class.
  4. @param url svn url
  5. @param username svn username
  6. @param password svn password
  7. Developer's comments:
  8. I think this class should ideally be designed as a singleton but I haven't figured
  9. out how to do that in Perl. Yet.

sub new ($$$) {

   my $class = shift; # first element in @_ is class name
   my ($url, $username, $password) = @_; # the rest are arguments passed in to subroutine
   my $self = {
       _url => $url,
       _username => $username,
       _password => $password
   };
   bless ($self, $class);
   return $self;

};

  1. This is the destructor. It deletes the class variables that
  2. consist of svn url, svn username and svn password

sub destroy () {

   my $self = shift;
   delete $self->{_url};
   delete $self->{_username};
   delete $self->{_password};

}

  1. Checkout subroutine checks out the source tree from the svn source repository.
  2. @param directory Optional; Allows you to change the top-level directory of your
  3. working copy to be different than that in the SVN repository.
  4. The value must be relative position from your present working directory
  5. If it is undefined, it will default to empty string (top-level directory
  6. of working copy same as repository)
  7. Some interesting values:
  8. "." will make the top-level directory your present working directory
  9. "../" will make the top-level directory the parent directory of your present working directory.
  10. "C:\<directory>" will not work as expected as the value must be relative to present working directory.

sub checkout (;$) {

   my $self = shift;
   my $directory = pop(@_);
   if (defined($self->{_url})) {
       if (!defined($directory)) {
           $directory = "";
       }
       my $rc = `svn checkout $self->{_url} $directory`;
   }

}

  1. Commit subroutine that commits changes to the source repository if the
  2. class variables for the svn username and svn password are defined.
  3. Argument passed in is the svn log message; can be an empty string but it's
  4. not recommended for logging purposes.
  5. @param message svn log message, describing the change

sub commit ($) {

   my $message = pop(@_);
   my $self = shift;
   if (defined($self->{_username}) && defined($self->{_password})) {
       my $rc = `svn commit -m \"$message\" --username $self->{_username} --password $self->{_password}`;
   }
   else {
       print "No username or password defined.";
   }

}

  1. Update subroutine that updates your working copy to the source repository to receive changes
  2. made by other developers since your last update. An update will take files/ directories etc.
  3. on the server and copy it to your local copy. Update is only done if the username and password
  4. are defined and if revision numbers are not out of range. Otherwise, the user will be alerted about
  5. the error.
  6. @param revision Specified by argument passed in as long as it's valid (default is HEAD revision)
  7. Possible revision keywords: HEAD, (BASE?, COMMITTED?, PREV?) and numbers
  8. The number has to be less or equal to the number of revisions in the SVN source repository
  9. and can be acquired through getNumberOfRevisions() subroutine
  10. Revision keywords and definitions:
  11. HEAD
  12. The latest (or "youngest") revision in the repository.
  13. BASE
  14. The revision number of an item in a working copy. If the item has been locally modified, the
  15. "BASE version" refers to the way the item appears without those local modifications.
  16. COMMITTED
  17. The most recent revision prior to, or equal to, BASE, in which an item changed.
  18. PREV
  19. The revision immediately before the last revision in which an item changed.
  20. (Technically, COMMITTED - 1.)
  21. NOTE: PREV, BASE, and COMMITTED can be used to refer to local paths, but not to URLs.
  22. @param file Specified by second argument; file or directory is only updated if defined.
  23. @return rc svn update command

sub update (;$$) {

   my $self = shift;
   my ($revision, $file) = @_;
   if (!defined($revision)) { $revision = "HEAD"; }
   if (!defined($file)) { $file = ""; }
   my $nRevisions = $self->getNumberOfRevisions();
   if (defined($self->{_username}) && defined($self->{_password})
       && ($revision eq "HEAD" ||
           $revision eq "BASE" ||
           $revision eq "COMMITTED" ||
           $revision eq "PREV" ||
          ($revision > 0 && $revision <= $nRevisions))) {
       my $rc = `svn update -r $revision  --username $self->{"_username"} --password $self->{"_password"} $file`;
   }
   else {
       print "username or password undefined or revision number out of range. Must be between 1 and $nRevisions";
   }

}

  1. Diff subroutine gets the differences between two paths ; optionally takes 3 parameters.
  2. If no arguments are given, then the user's working copy will be compared with the latest revision.
  3. If one argument is given (a revision number), then the working copy is compared with the passed in revision.
  4. If two arguments are given (2 revision numbers), then the first and second revision numbers passed in are compared.
  5. If a third option is given, then the differences between the file given is returned.
  6. The svn diff command will only perform if the username and password are defined.
  7. @param rev1 Revision number, working copy is compared with the passed in revision, has to be more than 0 and
  8. less or equal to the revision number retrieved from the number of revisions in the SVN source
  9. repository retrieved from getNumberOfRevisions subroutine
  10. @param rev2 Second revision number, first and second revision numbers passed in are compared, has to be more
  11. than 0 and less or equal to the revision number retrieved from the number of revisions in the SVN
  12. source repository retrieved from getNumberOfRevisions subroutine
  13. @param file Filename, differences between the file given is returned if this is defined
  14. @return rc svn diff command

sub diff (;$$$) {

   my $self = shift;
   my ($rev1, $rev2, $file) = @_;
   my $rc;
   my $nRevisions = $self->getNumberOfRevisions();
   if (!defined($rev1)) { $rev1 = ""; }
   if (!defined($rev2)) { $rev2 = ""; }
   if (!defined($file)) { $file = ""; }
   if (defined($self->{_username}) && defined($self->{_password})
       && ($rev1 eq "" || ($rev1 > 0 && $rev1 <= $nRevisions))
       && ($rev2 eq "" || ($rev2 > 0 && $rev2 <= $nRevisions))) {
       if ($rev2 ne "") { $rev2 = ":" . $rev2; }
       $rc = `svn diff -r $rev1$rev2 --username $self->{_username} --password $self->{_password} $file`;
   }
   else {
       print "No username or password defined. Or revision number out of range.";
   }
   return $rc;

}

  1. getNumberOfRevisions subroutine returns the number of revisions in the SVN source repository
  2. if the class variables username and password are defined
  3. @return rc number of revisions in the SVN source repository
  4. Comments from developer:
  5. Did not find an svn command that returns the number of revisions so this is
  6. like a work around. May not be the best way but it is one way.
  7. This is supposed to be a private method. However, I have not figured out how to
  8. properly create private methods in perl (if it's even possible). Yet.

sub getNumberOfRevisions () {

   my $self = shift;
   my $rc = -1;
   if (defined($self->{_username}) && defined($self->{_password})) {
       my $log = `svn log -r HEAD --username $self->{"_username"} --password $self->{"_password"}`;
       $log =~ m/r[0-9]+/;
       my $r = $&;
       $r =~ m/[0-9]+/;
       $rc = $&;
   }
   return $rc;

}

1; # last expression of file must return true